Add the PG_NX support for i386/PAE.
Reviewed by: alc
This commit is contained in:
parent
cedf5f9b38
commit
2e137367b4
@ -188,20 +188,6 @@ printcpuinfo(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect AMD features (PTE no-execute bit, 3dnow, 64 bit mode etc) */
|
|
||||||
if (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
|
|
||||||
strcmp(cpu_vendor, "AuthenticAMD") == 0) {
|
|
||||||
if (cpu_exthigh >= 0x80000001) {
|
|
||||||
do_cpuid(0x80000001, regs);
|
|
||||||
amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
|
|
||||||
amd_feature2 = regs[2];
|
|
||||||
}
|
|
||||||
if (cpu_exthigh >= 0x80000008) {
|
|
||||||
do_cpuid(0x80000008, regs);
|
|
||||||
cpu_procinfo2 = regs[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
|
if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
|
||||||
if ((cpu_id & 0xf00) > 0x300) {
|
if ((cpu_id & 0xf00) > 0x300) {
|
||||||
u_int brand_index;
|
u_int brand_index;
|
||||||
@ -1104,7 +1090,20 @@ finishidentcpu(void)
|
|||||||
u_char ccr3;
|
u_char ccr3;
|
||||||
u_int regs[4];
|
u_int regs[4];
|
||||||
|
|
||||||
if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
|
/* Detect AMD features (PTE no-execute bit, 3dnow, 64 bit mode etc) */
|
||||||
|
if (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
|
||||||
|
strcmp(cpu_vendor, "AuthenticAMD") == 0) {
|
||||||
|
init_exthigh();
|
||||||
|
if (cpu_exthigh >= 0x80000001) {
|
||||||
|
do_cpuid(0x80000001, regs);
|
||||||
|
amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
|
||||||
|
amd_feature2 = regs[2];
|
||||||
|
}
|
||||||
|
if (cpu_exthigh >= 0x80000008) {
|
||||||
|
do_cpuid(0x80000008, regs);
|
||||||
|
cpu_procinfo2 = regs[2];
|
||||||
|
}
|
||||||
|
} else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
|
||||||
if (cpu == CPU_486) {
|
if (cpu == CPU_486) {
|
||||||
/*
|
/*
|
||||||
* These conditions are equivalent to:
|
* These conditions are equivalent to:
|
||||||
|
@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <machine/md_var.h>
|
#include <machine/md_var.h>
|
||||||
#include <machine/specialreg.h>
|
#include <machine/specialreg.h>
|
||||||
|
|
||||||
|
#include <vm/vm.h>
|
||||||
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
#if !defined(CPU_DISABLE_SSE) && defined(I686_CPU)
|
#if !defined(CPU_DISABLE_SSE) && defined(I686_CPU)
|
||||||
#define CPU_ENABLE_SSE
|
#define CPU_ENABLE_SSE
|
||||||
#endif
|
#endif
|
||||||
@ -686,6 +689,15 @@ initializecpu(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef PAE
|
||||||
|
if ((amd_feature & AMDID_NX) != 0) {
|
||||||
|
uint64_t msr;
|
||||||
|
|
||||||
|
msr = rdmsr(MSR_EFER) | EFER_NXE;
|
||||||
|
wrmsr(MSR_EFER, msr);
|
||||||
|
pg_nx = PG_NX;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -211,7 +211,7 @@ minidumpsys(struct dumperinfo *di)
|
|||||||
j = va >> PDRSHIFT;
|
j = va >> PDRSHIFT;
|
||||||
if ((pd[j] & (PG_PS | PG_V)) == (PG_PS | PG_V)) {
|
if ((pd[j] & (PG_PS | PG_V)) == (PG_PS | PG_V)) {
|
||||||
/* This is an entire 2M page. */
|
/* This is an entire 2M page. */
|
||||||
pa = pd[j] & PG_FRAME & ~PDRMASK;
|
pa = pd[j] & PG_PS_FRAME;
|
||||||
for (k = 0; k < NPTEPG; k++) {
|
for (k = 0; k < NPTEPG; k++) {
|
||||||
if (is_dumpable(pa))
|
if (is_dumpable(pa))
|
||||||
dump_add_page(pa);
|
dump_add_page(pa);
|
||||||
@ -310,7 +310,7 @@ minidumpsys(struct dumperinfo *di)
|
|||||||
j = va >> PDRSHIFT;
|
j = va >> PDRSHIFT;
|
||||||
if ((pd[j] & (PG_PS | PG_V)) == (PG_PS | PG_V)) {
|
if ((pd[j] & (PG_PS | PG_V)) == (PG_PS | PG_V)) {
|
||||||
/* This is a single 2M block. Generate a fake PTP */
|
/* This is a single 2M block. Generate a fake PTP */
|
||||||
pa = pd[j] & PG_FRAME & ~PDRMASK;
|
pa = pd[j] & PG_PS_FRAME;
|
||||||
for (k = 0; k < NPTEPG; k++) {
|
for (k = 0; k < NPTEPG; k++) {
|
||||||
fakept[k] = (pa + (k * PAGE_SIZE)) | PG_V | PG_RW | PG_A | PG_M;
|
fakept[k] = (pa + (k * PAGE_SIZE)) | PG_V | PG_RW | PG_A | PG_M;
|
||||||
}
|
}
|
||||||
|
@ -206,6 +206,7 @@ vm_offset_t kernel_vm_end;
|
|||||||
extern u_int32_t KERNend;
|
extern u_int32_t KERNend;
|
||||||
|
|
||||||
#ifdef PAE
|
#ifdef PAE
|
||||||
|
pt_entry_t pg_nx;
|
||||||
static uma_zone_t pdptzone;
|
static uma_zone_t pdptzone;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -958,7 +959,7 @@ pmap_extract(pmap_t pmap, vm_offset_t va)
|
|||||||
pde = pmap->pm_pdir[va >> PDRSHIFT];
|
pde = pmap->pm_pdir[va >> PDRSHIFT];
|
||||||
if (pde != 0) {
|
if (pde != 0) {
|
||||||
if ((pde & PG_PS) != 0) {
|
if ((pde & PG_PS) != 0) {
|
||||||
rtval = (pde & ~PDRMASK) | (va & PDRMASK);
|
rtval = (pde & PG_PS_FRAME) | (va & PDRMASK);
|
||||||
PMAP_UNLOCK(pmap);
|
PMAP_UNLOCK(pmap);
|
||||||
return rtval;
|
return rtval;
|
||||||
}
|
}
|
||||||
@ -991,7 +992,7 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
|
|||||||
if (pde != 0) {
|
if (pde != 0) {
|
||||||
if (pde & PG_PS) {
|
if (pde & PG_PS) {
|
||||||
if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
|
if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
|
||||||
m = PHYS_TO_VM_PAGE((pde & ~PDRMASK) |
|
m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) |
|
||||||
(va & PDRMASK));
|
(va & PDRMASK));
|
||||||
vm_page_hold(m);
|
vm_page_hold(m);
|
||||||
}
|
}
|
||||||
@ -1365,7 +1366,7 @@ retry:
|
|||||||
* hold count, and activate it.
|
* hold count, and activate it.
|
||||||
*/
|
*/
|
||||||
if (ptepa) {
|
if (ptepa) {
|
||||||
m = PHYS_TO_VM_PAGE(ptepa);
|
m = PHYS_TO_VM_PAGE(ptepa & PG_FRAME);
|
||||||
m->wire_count++;
|
m->wire_count++;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -1498,7 +1499,8 @@ pmap_release(pmap_t pmap)
|
|||||||
mtx_unlock_spin(&allpmaps_lock);
|
mtx_unlock_spin(&allpmaps_lock);
|
||||||
|
|
||||||
for (i = 0; i < NPGPTD; i++)
|
for (i = 0; i < NPGPTD; i++)
|
||||||
ptdpg[i] = PHYS_TO_VM_PAGE(pmap->pm_pdir[PTDPTDI + i]);
|
ptdpg[i] = PHYS_TO_VM_PAGE(pmap->pm_pdir[PTDPTDI + i] &
|
||||||
|
PG_FRAME);
|
||||||
|
|
||||||
bzero(pmap->pm_pdir + PTDPTDI, (nkpt + NPGPTD) *
|
bzero(pmap->pm_pdir + PTDPTDI, (nkpt + NPGPTD) *
|
||||||
sizeof(*pmap->pm_pdir));
|
sizeof(*pmap->pm_pdir));
|
||||||
@ -1946,7 +1948,7 @@ pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va)
|
|||||||
pmap_invalidate_page(kernel_pmap, va);
|
pmap_invalidate_page(kernel_pmap, va);
|
||||||
pmap->pm_stats.resident_count -= 1;
|
pmap->pm_stats.resident_count -= 1;
|
||||||
if (oldpte & PG_MANAGED) {
|
if (oldpte & PG_MANAGED) {
|
||||||
m = PHYS_TO_VM_PAGE(oldpte);
|
m = PHYS_TO_VM_PAGE(oldpte & PG_FRAME);
|
||||||
if (oldpte & PG_M) {
|
if (oldpte & PG_M) {
|
||||||
KASSERT((oldpte & PG_RW),
|
KASSERT((oldpte & PG_RW),
|
||||||
("pmap_remove_pte: modified page not writable: va: %#x, pte: %#jx",
|
("pmap_remove_pte: modified page not writable: va: %#x, pte: %#jx",
|
||||||
@ -2154,8 +2156,14 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PAE
|
||||||
|
if ((prot & (VM_PROT_WRITE|VM_PROT_EXECUTE)) ==
|
||||||
|
(VM_PROT_WRITE|VM_PROT_EXECUTE))
|
||||||
|
return;
|
||||||
|
#else
|
||||||
if (prot & VM_PROT_WRITE)
|
if (prot & VM_PROT_WRITE)
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
anychanged = 0;
|
anychanged = 0;
|
||||||
|
|
||||||
@ -2163,7 +2171,8 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
|
|||||||
sched_pin();
|
sched_pin();
|
||||||
PMAP_LOCK(pmap);
|
PMAP_LOCK(pmap);
|
||||||
for (; sva < eva; sva = pdnxt) {
|
for (; sva < eva; sva = pdnxt) {
|
||||||
unsigned obits, pbits, pdirindex;
|
pt_entry_t obits, pbits;
|
||||||
|
unsigned pdirindex;
|
||||||
|
|
||||||
pdnxt = (sva + NBPDR) & ~PDRMASK;
|
pdnxt = (sva + NBPDR) & ~PDRMASK;
|
||||||
|
|
||||||
@ -2181,7 +2190,12 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
|
|||||||
* Check for large page.
|
* Check for large page.
|
||||||
*/
|
*/
|
||||||
if ((ptpaddr & PG_PS) != 0) {
|
if ((ptpaddr & PG_PS) != 0) {
|
||||||
pmap->pm_pdir[pdirindex] &= ~(PG_M|PG_RW);
|
if ((prot & VM_PROT_WRITE) == 0)
|
||||||
|
pmap->pm_pdir[pdirindex] &= ~(PG_M|PG_RW);
|
||||||
|
#ifdef PAE
|
||||||
|
if ((prot & VM_PROT_EXECUTE) == 0)
|
||||||
|
pmap->pm_pdir[pdirindex] |= pg_nx;
|
||||||
|
#endif
|
||||||
anychanged = 1;
|
anychanged = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2199,27 +2213,39 @@ retry:
|
|||||||
* size, PG_RW, PG_A, and PG_M are among the least
|
* size, PG_RW, PG_A, and PG_M are among the least
|
||||||
* significant 32 bits.
|
* significant 32 bits.
|
||||||
*/
|
*/
|
||||||
obits = pbits = *(u_int *)pte;
|
obits = pbits = *pte;
|
||||||
|
if ((pbits & PG_V) == 0)
|
||||||
|
continue;
|
||||||
if (pbits & PG_MANAGED) {
|
if (pbits & PG_MANAGED) {
|
||||||
m = NULL;
|
m = NULL;
|
||||||
if (pbits & PG_A) {
|
if (pbits & PG_A) {
|
||||||
m = PHYS_TO_VM_PAGE(*pte);
|
m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
|
||||||
vm_page_flag_set(m, PG_REFERENCED);
|
vm_page_flag_set(m, PG_REFERENCED);
|
||||||
pbits &= ~PG_A;
|
pbits &= ~PG_A;
|
||||||
}
|
}
|
||||||
if ((pbits & PG_M) != 0) {
|
if ((pbits & PG_M) != 0) {
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
m = PHYS_TO_VM_PAGE(*pte);
|
m = PHYS_TO_VM_PAGE(pbits & PG_FRAME);
|
||||||
vm_page_dirty(m);
|
vm_page_dirty(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pbits &= ~(PG_RW | PG_M);
|
if ((prot & VM_PROT_WRITE) == 0)
|
||||||
|
pbits &= ~(PG_RW | PG_M);
|
||||||
|
#ifdef PAE
|
||||||
|
if ((prot & VM_PROT_EXECUTE) == 0)
|
||||||
|
pbits |= pg_nx;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pbits != obits) {
|
if (pbits != obits) {
|
||||||
|
#ifdef PAE
|
||||||
|
if (!atomic_cmpset_64(pte, obits, pbits))
|
||||||
|
goto retry;
|
||||||
|
#else
|
||||||
if (!atomic_cmpset_int((u_int *)pte, obits,
|
if (!atomic_cmpset_int((u_int *)pte, obits,
|
||||||
pbits))
|
pbits))
|
||||||
goto retry;
|
goto retry;
|
||||||
|
#endif
|
||||||
if (obits & PG_G)
|
if (obits & PG_G)
|
||||||
pmap_invalidate_page(pmap, sva);
|
pmap_invalidate_page(pmap, sva);
|
||||||
else
|
else
|
||||||
@ -2384,6 +2410,10 @@ validate:
|
|||||||
newpte |= PG_RW;
|
newpte |= PG_RW;
|
||||||
vm_page_flag_set(m, PG_WRITEABLE);
|
vm_page_flag_set(m, PG_WRITEABLE);
|
||||||
}
|
}
|
||||||
|
#ifdef PAE
|
||||||
|
if ((prot & VM_PROT_EXECUTE) == 0)
|
||||||
|
newpte |= pg_nx;
|
||||||
|
#endif
|
||||||
if (wired)
|
if (wired)
|
||||||
newpte |= PG_W;
|
newpte |= PG_W;
|
||||||
if (va < VM_MAXUSER_ADDRESS)
|
if (va < VM_MAXUSER_ADDRESS)
|
||||||
@ -2404,6 +2434,11 @@ validate:
|
|||||||
vm_page_flag_set(om, PG_REFERENCED);
|
vm_page_flag_set(om, PG_REFERENCED);
|
||||||
if (opa != VM_PAGE_TO_PHYS(m))
|
if (opa != VM_PAGE_TO_PHYS(m))
|
||||||
invlva = TRUE;
|
invlva = TRUE;
|
||||||
|
#ifdef PAE
|
||||||
|
if ((origpte & PG_NX) == 0 &&
|
||||||
|
(newpte & PG_NX) != 0)
|
||||||
|
invlva = TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (origpte & PG_M) {
|
if (origpte & PG_M) {
|
||||||
KASSERT((origpte & PG_RW),
|
KASSERT((origpte & PG_RW),
|
||||||
@ -2514,7 +2549,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
|
|||||||
if (ptepa) {
|
if (ptepa) {
|
||||||
if (ptepa & PG_PS)
|
if (ptepa & PG_PS)
|
||||||
panic("pmap_enter_quick: unexpected mapping into 4MB page");
|
panic("pmap_enter_quick: unexpected mapping into 4MB page");
|
||||||
mpte = PHYS_TO_VM_PAGE(ptepa);
|
mpte = PHYS_TO_VM_PAGE(ptepa & PG_FRAME);
|
||||||
mpte->wire_count++;
|
mpte->wire_count++;
|
||||||
} else {
|
} else {
|
||||||
mpte = _pmap_allocpte(pmap, ptepindex,
|
mpte = _pmap_allocpte(pmap, ptepindex,
|
||||||
@ -2560,6 +2595,10 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
|
|||||||
pmap->pm_stats.resident_count++;
|
pmap->pm_stats.resident_count++;
|
||||||
|
|
||||||
pa = VM_PAGE_TO_PHYS(m);
|
pa = VM_PAGE_TO_PHYS(m);
|
||||||
|
#ifdef PAE
|
||||||
|
if ((prot & VM_PROT_EXECUTE) == 0)
|
||||||
|
pa |= pg_nx;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now validate mapping with RO protection
|
* Now validate mapping with RO protection
|
||||||
@ -2746,7 +2785,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
srcmpte = PHYS_TO_VM_PAGE(srcptepaddr);
|
srcmpte = PHYS_TO_VM_PAGE(srcptepaddr & PG_FRAME);
|
||||||
if (srcmpte->wire_count == 0)
|
if (srcmpte->wire_count == 0)
|
||||||
panic("pmap_copy: source page table page is unused");
|
panic("pmap_copy: source page table page is unused");
|
||||||
|
|
||||||
@ -2990,7 +3029,7 @@ pmap_remove_pages(pmap_t pmap)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = PHYS_TO_VM_PAGE(tpte);
|
m = PHYS_TO_VM_PAGE(tpte & PG_FRAME);
|
||||||
KASSERT(m->phys_addr == (tpte & PG_FRAME),
|
KASSERT(m->phys_addr == (tpte & PG_FRAME),
|
||||||
("vm_page_t %p phys_addr mismatch %016jx %016jx",
|
("vm_page_t %p phys_addr mismatch %016jx %016jx",
|
||||||
m, (uintmax_t)m->phys_addr,
|
m, (uintmax_t)m->phys_addr,
|
||||||
@ -3521,7 +3560,7 @@ pmap_pid_dump(int pid)
|
|||||||
pt_entry_t pa;
|
pt_entry_t pa;
|
||||||
vm_page_t m;
|
vm_page_t m;
|
||||||
pa = *pte;
|
pa = *pte;
|
||||||
m = PHYS_TO_VM_PAGE(pa);
|
m = PHYS_TO_VM_PAGE(pa & PG_FRAME);
|
||||||
printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x",
|
printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x",
|
||||||
va, pa, m->hold_count, m->wire_count, m->flags);
|
va, pa, m->hold_count, m->wire_count, m->flags);
|
||||||
npte++;
|
npte++;
|
||||||
|
@ -736,8 +736,16 @@ trap_pfault(frame, usermode, eva)
|
|||||||
map = &vm->vm_map;
|
map = &vm->vm_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PGEX_I is defined only if the execute disable bit capability is
|
||||||
|
* supported and enabled.
|
||||||
|
*/
|
||||||
if (frame->tf_err & PGEX_W)
|
if (frame->tf_err & PGEX_W)
|
||||||
ftype = VM_PROT_WRITE;
|
ftype = VM_PROT_WRITE;
|
||||||
|
#ifdef PAE
|
||||||
|
else if ((frame->tf_err & PGEX_I) && pg_nx != 0)
|
||||||
|
ftype = VM_PROT_EXECUTE;
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
ftype = VM_PROT_READ;
|
ftype = VM_PROT_READ;
|
||||||
|
|
||||||
|
@ -63,12 +63,21 @@
|
|||||||
#define PG_AVAIL2 0x400 /* < programmers use */
|
#define PG_AVAIL2 0x400 /* < programmers use */
|
||||||
#define PG_AVAIL3 0x800 /* \ */
|
#define PG_AVAIL3 0x800 /* \ */
|
||||||
#define PG_PDE_PAT 0x1000 /* PAT PAT index */
|
#define PG_PDE_PAT 0x1000 /* PAT PAT index */
|
||||||
|
#ifdef PAE
|
||||||
|
#define PG_NX (1ull<<63) /* No-execute */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Our various interpretations of the above */
|
/* Our various interpretations of the above */
|
||||||
#define PG_W PG_AVAIL1 /* "Wired" pseudoflag */
|
#define PG_W PG_AVAIL1 /* "Wired" pseudoflag */
|
||||||
#define PG_MANAGED PG_AVAIL2
|
#define PG_MANAGED PG_AVAIL2
|
||||||
#define PG_FRAME (~((vm_paddr_t)PAGE_MASK))
|
#ifdef PAE
|
||||||
|
#define PG_FRAME (0x000ffffffffff000ull)
|
||||||
|
#define PG_PS_FRAME (0x000fffffffe00000ull)
|
||||||
|
#else
|
||||||
|
#define PG_FRAME (~PAGE_MASK)
|
||||||
|
#define PG_PS_FRAME (0xffc00000)
|
||||||
|
#endif
|
||||||
#define PG_PROT (PG_RW|PG_U) /* all protection bits . */
|
#define PG_PROT (PG_RW|PG_U) /* all protection bits . */
|
||||||
#define PG_N (PG_NC_PWT|PG_NC_PCD) /* Non-cacheable */
|
#define PG_N (PG_NC_PWT|PG_NC_PCD) /* Non-cacheable */
|
||||||
|
|
||||||
@ -79,6 +88,7 @@
|
|||||||
#define PGEX_P 0x01 /* Protection violation vs. not present */
|
#define PGEX_P 0x01 /* Protection violation vs. not present */
|
||||||
#define PGEX_W 0x02 /* during a Write cycle */
|
#define PGEX_W 0x02 /* during a Write cycle */
|
||||||
#define PGEX_U 0x04 /* access from User mode (UPL) */
|
#define PGEX_U 0x04 /* access from User mode (UPL) */
|
||||||
|
#define PGEX_I 0x10 /* during an instruction fetch */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Size of Kernel address space. This is the number of page table pages
|
* Size of Kernel address space. This is the number of page table pages
|
||||||
@ -201,7 +211,7 @@ pmap_kextract(vm_offset_t va)
|
|||||||
vm_paddr_t pa;
|
vm_paddr_t pa;
|
||||||
|
|
||||||
if ((pa = PTD[va >> PDRSHIFT]) & PG_PS) {
|
if ((pa = PTD[va >> PDRSHIFT]) & PG_PS) {
|
||||||
pa = (pa & ~(NBPDR - 1)) | (va & (NBPDR - 1));
|
pa = (pa & PG_PS_FRAME) | (va & PDRMASK);
|
||||||
} else {
|
} else {
|
||||||
pa = *vtopte(va);
|
pa = *vtopte(va);
|
||||||
pa = (pa & PG_FRAME) | (va & PAGE_MASK);
|
pa = (pa & PG_FRAME) | (va & PAGE_MASK);
|
||||||
@ -238,10 +248,33 @@ pte_load_store(pt_entry_t *ptep, pt_entry_t v)
|
|||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXXRU move to atomic.h? */
|
||||||
|
static __inline int
|
||||||
|
atomic_cmpset_64(volatile uint64_t *dst, uint64_t exp, uint64_t src)
|
||||||
|
{
|
||||||
|
int64_t res = exp;
|
||||||
|
|
||||||
|
__asm __volatile (
|
||||||
|
" lock ; "
|
||||||
|
" cmpxchg8b %2 ; "
|
||||||
|
" setz %%al ; "
|
||||||
|
" movzbl %%al,%0 ; "
|
||||||
|
"# atomic_cmpset_64"
|
||||||
|
: "+A" (res), /* 0 (result) */
|
||||||
|
"=m" (*dst) /* 1 */
|
||||||
|
: "m" (*dst), /* 2 */
|
||||||
|
"b" ((uint32_t)src),
|
||||||
|
"c" ((uint32_t)(src >> 32)));
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
#define pte_load_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL)
|
#define pte_load_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL)
|
||||||
|
|
||||||
#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte)
|
#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte)
|
||||||
|
|
||||||
|
extern pt_entry_t pg_nx;
|
||||||
|
|
||||||
#else /* PAE */
|
#else /* PAE */
|
||||||
|
|
||||||
static __inline pt_entry_t
|
static __inline pt_entry_t
|
||||||
|
@ -67,6 +67,11 @@
|
|||||||
#define CR4_FXSR 0x00000200 /* Fast FPU save/restore used by OS */
|
#define CR4_FXSR 0x00000200 /* Fast FPU save/restore used by OS */
|
||||||
#define CR4_XMM 0x00000400 /* enable SIMD/MMX2 to use except 16 */
|
#define CR4_XMM 0x00000400 /* enable SIMD/MMX2 to use except 16 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in AMD64 special registers. EFER is 64 bits wide.
|
||||||
|
*/
|
||||||
|
#define EFER_NXE 0x000000800 /* PTE No-Execute bit enable (R/W) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CPUID instruction features register
|
* CPUID instruction features register
|
||||||
*/
|
*/
|
||||||
@ -420,6 +425,9 @@
|
|||||||
#define AMD_WT_ALLOC_PRE 0x20000 /* programmable range enable */
|
#define AMD_WT_ALLOC_PRE 0x20000 /* programmable range enable */
|
||||||
#define AMD_WT_ALLOC_FRE 0x10000 /* fixed (A0000-FFFFF) range enable */
|
#define AMD_WT_ALLOC_FRE 0x10000 /* fixed (A0000-FFFFF) range enable */
|
||||||
|
|
||||||
|
/* AMD64 MSR's */
|
||||||
|
#define MSR_EFER 0xc0000080 /* extended features */
|
||||||
|
|
||||||
/* VIA ACE crypto featureset: for via_feature_rng */
|
/* VIA ACE crypto featureset: for via_feature_rng */
|
||||||
#define VIA_HAS_RNG 1 /* cpu has RNG */
|
#define VIA_HAS_RNG 1 /* cpu has RNG */
|
||||||
|
|
||||||
|
@ -43,7 +43,9 @@
|
|||||||
* Machine dependent constants for 386.
|
* Machine dependent constants for 386.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef PAE
|
||||||
#define VM_PROT_READ_IS_EXEC /* if you can read -- then you can exec */
|
#define VM_PROT_READ_IS_EXEC /* if you can read -- then you can exec */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Virtual memory related constants, all in bytes
|
* Virtual memory related constants, all in bytes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user