svn commit: r255732 - in head/sys: amd64/include vm
Neel Natu
neel at FreeBSD.org
Fri Sep 20 17:06:50 UTC 2013
Author: neel
Date: Fri Sep 20 17:06:49 2013
New Revision: 255732
URL: http://svnweb.freebsd.org/changeset/base/255732
Log:
Merge the following changes from projects/bhyve_npt_pmap:
- add fields to 'struct pmap' that are required to manage nested page tables.
- add a parameter to 'vmspace_alloc()' that can be used to override the
default pmap initialization routine 'pmap_pinit()'.
These changes are pushed ahead of the remaining changes in 'bhyve_npt_pmap'
in anticipation of the upcoming KBI freeze for 10.0.
Reviewed by: kib@, alc@
Approved by: re (glebius)
Modified:
head/sys/amd64/include/pmap.h
head/sys/vm/vm_extern.h
head/sys/vm/vm_map.c
Modified: head/sys/amd64/include/pmap.h
==============================================================================
--- head/sys/amd64/include/pmap.h Fri Sep 20 16:05:09 2013 (r255731)
+++ head/sys/amd64/include/pmap.h Fri Sep 20 17:06:49 2013 (r255732)
@@ -231,6 +231,12 @@ struct md_page {
int pat_mode;
};
+enum pmap_type {
+ PT_X86, /* regular x86 page tables */
+ PT_EPT, /* Intel's nested page tables */
+ PT_RVI, /* AMD's nested page tables */
+};
+
/*
* The kernel virtual address (KVA) of the level 4 page table page is always
* within the direct map (DMAP) region.
@@ -243,9 +249,11 @@ struct pmap {
cpuset_t pm_active; /* active on cpus */
cpuset_t pm_save; /* Context valid on cpus mask */
int pm_pcid; /* context id */
- /* spare u_int here due to padding */
+ enum pmap_type pm_type; /* regular or nested tables */
struct pmap_statistics pm_stats; /* pmap statistics */
struct vm_radix pm_root; /* spare page table pages */
+ long pm_eptgen; /* EPT pmap generation id */
+ int pm_flags;
};
typedef struct pmap *pmap_t;
Modified: head/sys/vm/vm_extern.h
==============================================================================
--- head/sys/vm/vm_extern.h Fri Sep 20 16:05:09 2013 (r255731)
+++ head/sys/vm/vm_extern.h Fri Sep 20 17:06:49 2013 (r255732)
@@ -33,6 +33,7 @@
#ifndef _VM_EXTERN_H_
#define _VM_EXTERN_H_
+struct pmap;
struct proc;
struct vmspace;
struct vnode;
@@ -88,7 +89,8 @@ int vm_mmap(vm_map_t, vm_offset_t *, vm_
int vm_mmap_to_errno(int rv);
void vm_set_page_size(void);
void vm_sync_icache(vm_map_t, vm_offset_t, vm_size_t);
-struct vmspace *vmspace_alloc(vm_offset_t, vm_offset_t);
+typedef int (*pmap_pinit_t)(struct pmap *pmap);
+struct vmspace *vmspace_alloc(vm_offset_t, vm_offset_t, pmap_pinit_t);
struct vmspace *vmspace_fork(struct vmspace *, vm_ooffset_t *);
int vmspace_exec(struct proc *, vm_offset_t, vm_offset_t);
int vmspace_unshare(struct proc *);
Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c Fri Sep 20 16:05:09 2013 (r255731)
+++ head/sys/vm/vm_map.c Fri Sep 20 17:06:49 2013 (r255732)
@@ -280,15 +280,22 @@ vm_map_zdtor(void *mem, int size, void *
/*
* Allocate a vmspace structure, including a vm_map and pmap,
* and initialize those structures. The refcnt is set to 1.
+ *
+ * If 'pinit' is NULL then the embedded pmap is initialized via pmap_pinit().
*/
struct vmspace *
-vmspace_alloc(min, max)
- vm_offset_t min, max;
+vmspace_alloc(vm_offset_t min, vm_offset_t max, pmap_pinit_t pinit)
{
struct vmspace *vm;
vm = uma_zalloc(vmspace_zone, M_WAITOK);
- if (vm->vm_map.pmap == NULL && !pmap_pinit(vmspace_pmap(vm))) {
+
+ KASSERT(vm->vm_map.pmap == NULL, ("vm_map.pmap must be NULL"));
+
+ if (pinit == NULL)
+ pinit = &pmap_pinit;
+
+ if (!pinit(vmspace_pmap(vm))) {
uma_zfree(vmspace_zone, vm);
return (NULL);
}
@@ -3157,7 +3164,7 @@ vmspace_fork(struct vmspace *vm1, vm_oof
old_map = &vm1->vm_map;
/* Copy immutable fields of vm1 to vm2. */
- vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset);
+ vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset, NULL);
if (vm2 == NULL)
return (NULL);
vm2->vm_taddr = vm1->vm_taddr;
@@ -3739,7 +3746,7 @@ vmspace_exec(struct proc *p, vm_offset_t
struct vmspace *oldvmspace = p->p_vmspace;
struct vmspace *newvmspace;
- newvmspace = vmspace_alloc(minuser, maxuser);
+ newvmspace = vmspace_alloc(minuser, maxuser, NULL);
if (newvmspace == NULL)
return (ENOMEM);
newvmspace->vm_swrss = oldvmspace->vm_swrss;
More information about the svn-src-head
mailing list