pc64: implement NX bit discovery, map kernel mappings no-execute
This commit is contained in:
parent
49411b2ca1
commit
1e773c97e7
5 changed files with 35 additions and 21 deletions
|
@ -244,6 +244,7 @@ struct Mach
|
|||
int havetsc;
|
||||
int havepge;
|
||||
int havewatchpt8;
|
||||
int havenx;
|
||||
uvlong tscticks;
|
||||
int pdballoc;
|
||||
int pdbfree;
|
||||
|
|
|
@ -899,10 +899,26 @@ cpuidentify(void)
|
|||
else
|
||||
hwrandbuf = nil;
|
||||
|
||||
/* 8-byte watchpoints are supported in Long Mode */
|
||||
if(sizeof(uintptr) == 8)
|
||||
if(sizeof(uintptr) == 8) {
|
||||
/* 8-byte watchpoints are supported in Long Mode */
|
||||
m->havewatchpt8 = 1;
|
||||
else if(strcmp(m->cpuidid, "GenuineIntel") == 0){
|
||||
|
||||
/* check and enable NX bit */
|
||||
cpuid(Highextfunc, regs);
|
||||
if(regs[0] >= Procextfeat){
|
||||
cpuid(Procextfeat, regs);
|
||||
if((regs[3] & (1<<20)) != 0){
|
||||
vlong efer;
|
||||
|
||||
/* enable no-execute feature */
|
||||
if(rdmsr(Efer, &efer) != -1){
|
||||
efer |= 1ull<<11;
|
||||
if(wrmsr(Efer, efer) != -1)
|
||||
m->havenx = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(strcmp(m->cpuidid, "GenuineIntel") == 0){
|
||||
/* some random CPUs that support 8-byte watchpoints */
|
||||
if(family == 15 && (model == 3 || model == 4 || model == 6)
|
||||
|| family == 6 && (model == 15 || model == 23 || model == 28))
|
||||
|
|
|
@ -222,6 +222,7 @@ struct Mach
|
|||
int havetsc;
|
||||
int havepge;
|
||||
int havewatchpt8;
|
||||
int havenx;
|
||||
uvlong tscticks;
|
||||
|
||||
u64int dr7; /* shadow copy of dr7 */
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
#define PTEPERTAB (PTEMAPMEM/BY2PG)
|
||||
#define SEGMAPSIZE 65536
|
||||
#define SSEGMAPSIZE 16
|
||||
#define PPN(x) ((x)&~(BY2PG-1))
|
||||
#define PPN(x) ((x)&~(1ull<<63 | BY2PG-1))
|
||||
|
||||
/*
|
||||
* physical MMU
|
||||
|
@ -158,6 +158,7 @@
|
|||
#define PTEUSER (1ull<<2)
|
||||
#define PTESIZE (1ull<<7)
|
||||
#define PTEGLOBAL (1ull<<8)
|
||||
#define PTENOEXEC ((uvlong)m->havenx<<63)
|
||||
|
||||
/*
|
||||
* Hierarchical Page Tables.
|
||||
|
|
|
@ -116,23 +116,18 @@ mmuinit(void)
|
|||
taskswitch((uintptr)m + MACHSIZE);
|
||||
ltr(TSSSEL);
|
||||
|
||||
wrmsr(0xc0000100, 0ull); /* 64 bit fsbase */
|
||||
wrmsr(0xc0000101, (uvlong)&machp[m->machno]); /* 64 bit gsbase */
|
||||
wrmsr(0xc0000102, 0ull); /* kernel gs base */
|
||||
wrmsr(FSbase, 0ull);
|
||||
wrmsr(GSbase, (uvlong)&machp[m->machno]);
|
||||
wrmsr(KernelGSbase, 0ull);
|
||||
|
||||
/* enable syscall extension */
|
||||
rdmsr(0xc0000080, &v);
|
||||
rdmsr(Efer, &v);
|
||||
v |= 1ull;
|
||||
wrmsr(0xc0000080, v);
|
||||
wrmsr(Efer, v);
|
||||
|
||||
/* IA32_STAR */
|
||||
wrmsr(0xc0000081, ((uvlong)UE32SEL << 48) | ((uvlong)KESEL << 32));
|
||||
|
||||
/* IA32_LSTAR */
|
||||
wrmsr(0xc0000082, (uvlong)syscallentry);
|
||||
|
||||
/* SYSCALL flags mask */
|
||||
wrmsr(0xc0000084, 0x200);
|
||||
wrmsr(Star, ((uvlong)UE32SEL << 48) | ((uvlong)KESEL << 32));
|
||||
wrmsr(Lstar, (uvlong)syscallentry);
|
||||
wrmsr(Sfmask, 0x200);
|
||||
|
||||
/* IA32_PAT write combining */
|
||||
if((MACHP(0)->cpuiddx & Pat) != 0
|
||||
|
@ -443,7 +438,7 @@ putmmu(uintptr va, uintptr pa, Page *)
|
|||
if(pte == 0)
|
||||
panic("putmmu: bug: va=%#p pa=%#p", va, pa);
|
||||
old = *pte;
|
||||
*pte = pa | PTEVALID|PTEUSER;
|
||||
*pte = pa | PTEUSER;
|
||||
splx(x);
|
||||
if(old & PTEVALID)
|
||||
invlpg(va);
|
||||
|
@ -487,7 +482,7 @@ kmap(Page *page)
|
|||
pte = mmuwalk(m->pml4, va, 0, 1);
|
||||
if(pte == 0 || (*pte & PTEVALID) != 0)
|
||||
panic("kmap: pa=%#p va=%#p", pa, va);
|
||||
*pte = pa | PTEWRITE|PTEVALID;
|
||||
*pte = pa | PTEWRITE|PTENOEXEC|PTEVALID;
|
||||
splx(x);
|
||||
invlpg(va);
|
||||
return (KMap*)va;
|
||||
|
@ -533,7 +528,7 @@ vmap(uintptr pa, int size)
|
|||
pa -= o;
|
||||
va -= o;
|
||||
size += o;
|
||||
pmap(m->pml4, pa | PTEUNCACHED|PTEWRITE|PTEVALID, va, size);
|
||||
pmap(m->pml4, pa | PTEUNCACHED|PTEWRITE|PTENOEXEC|PTEVALID, va, size);
|
||||
return (void*)(va+o);
|
||||
}
|
||||
|
||||
|
@ -616,7 +611,7 @@ preallocpages(void)
|
|||
pm->npage = (top - pm->base)/BY2PG;
|
||||
|
||||
va = base + VMAP;
|
||||
pmap(m->pml4, base | PTEGLOBAL|PTEWRITE|PTEVALID, va, psize);
|
||||
pmap(m->pml4, base | PTEGLOBAL|PTEWRITE|PTENOEXEC|PTEVALID, va, psize);
|
||||
|
||||
palloc.pages = (void*)(va + tsize);
|
||||
|
||||
|
|
Loading…
Reference in a new issue