-/* $OpenBSD: locore.S,v 1.92 2018/01/06 22:03:12 guenther Exp $ */
+/* $OpenBSD: locore.S,v 1.93 2018/01/07 19:56:19 mlarkin Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
.globl _C_LABEL(biosbasemem)
.globl _C_LABEL(bootapiver)
.globl _C_LABEL(pg_nx)
+ .globl _C_LABEL(pg_g_kern)
_C_LABEL(cpu_id): .long 0 # saved from `cpuid' instruction
_C_LABEL(cpu_feature): .long 0 # feature flags from 'cpuid'
# instruction
_C_LABEL(biosextmem): .long REALEXTMEM
#endif
_C_LABEL(pg_nx): .quad 0 # NX PTE bit (if CPU supports)
+_C_LABEL(pg_g_kern): .quad 0 # 0x100 if global pages should be used
+ # in kernel mappings, 0 otherwise (for
+ # Intel)
#define _RELOC(x) ((x) - KERNBASE)
#define RELOC(x) _RELOC(_C_LABEL(x))
-/* $OpenBSD: locore0.S,v 1.5 2017/10/14 21:42:17 mlarkin Exp $ */
+/* $OpenBSD: locore0.S,v 1.6 2018/01/07 19:56:19 mlarkin Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
movl %ecx,8(%ebp)
movl $0, 12(%ebp)
+ /*
+ * Determine if CPU is Intel. Intel CPUs cannot use PG_G (global
+ * pages) in kernel mappings. If CPU is not Intel, this is safe.
+ * Cache the result in pg_g_kern - 0 if not supported or PG_G (0x100)
+ * if supported.
+ *
+ * This treatment is required for the meltdown CVE mitigation.
+ */
+ cmpl $0x756e6547, %ebx # "Genu"
+ jne not_intel
+ cmpl $0x6c65746e, %ecx # "ntel"
+ jne not_intel
+ cmpl $0x49656e69, %edx # "ineI"
+ jne not_intel
+
+ jmp pg_g_check_finished
+
+not_intel:
+ movl $PG_G, RELOC(pg_g_kern)
+
+pg_g_check_finished:
movl $1,%eax
cpuid
movl %eax,RELOC(cpu_id)
leal (PROC0_DMP2_OFF)(%esi), %ebx
xorl %eax, %eax
movl $(NDML2_ENTRIES * NPDPG), %ecx
-1: orl $(PG_V|PG_KW|PG_PS|PG_G), %eax
+1: orl $(PG_V|PG_KW|PG_PS), %eax
+ orl RELOC(pg_g_kern), %eax
cmpl $__kernel_base_phys, %eax
jl store_pte
cmpl $__kernel_end_phys, %eax
-/* $OpenBSD: pmap.c,v 1.107 2018/01/07 05:35:10 mlarkin Exp $ */
+/* $OpenBSD: pmap.c,v 1.108 2018/01/07 19:56:19 mlarkin Exp $ */
/* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */
/*
/* special 1:1 mappings in the first 2MB must not be global */
if (va >= (vaddr_t)NBPD_L2)
- npte |= PG_G;
+ npte |= pg_g_kern;
if (!(prot & PROT_EXEC))
npte |= pg_nx;
kva += PAGE_SIZE) {
p1i = pl1_i(kva);
if (pmap_valid_entry(PTE_BASE[p1i]))
- PTE_BASE[p1i] |= PG_G;
+ PTE_BASE[p1i] |= pg_g_kern;
}
/*
va = PMAP_DIRECT_MAP(pdp);
*((pd_entry_t *)va) = ((paddr_t)i << L2_SHIFT);
- *((pd_entry_t *)va) |= PG_RW | PG_V | PG_PS | PG_G | PG_U |
+ *((pd_entry_t *)va) |= PG_RW | PG_V | PG_PS | pg_g_kern | PG_U |
PG_M | pg_nx;
}
else if (va < VM_MAX_ADDRESS)
npte |= (PG_u | PG_RW); /* XXXCDC: no longer needed? */
if (pmap == pmap_kernel())
- npte |= PG_G;
+ npte |= pg_g_kern;
ptes[pl1_i(va)] = npte; /* zap! */
-/* $OpenBSD: pte.h,v 1.13 2015/11/09 00:49:33 mlarkin Exp $ */
+/* $OpenBSD: pte.h,v 1.14 2018/01/07 19:56:19 mlarkin Exp $ */
/* $NetBSD: pte.h,v 1.1 2003/04/26 18:39:47 fvdl Exp $ */
/*
#ifdef _KERNEL
extern pt_entry_t pg_nx; /* NX pte bit */
+extern pt_entry_t pg_g_kern; /* PG_G if glbl mappings can be used in kern */
#endif /* _KERNEL */
#endif /* _MACHINE_PTE_H_ */