diff options
Diffstat (limited to 'usr/src/uts/i86pc/os/startup.c')
| -rw-r--r-- | usr/src/uts/i86pc/os/startup.c | 63 | 
1 files changed, 62 insertions, 1 deletions
| diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c index 700b3456ae..a9a7dd57a3 100644 --- a/usr/src/uts/i86pc/os/startup.c +++ b/usr/src/uts/i86pc/os/startup.c @@ -22,7 +22,7 @@   * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.   * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.   * Copyright 2013 Nexenta Systems, Inc. All rights reserved. - * Copyright 2013 Joyent, Inc.  All rights reserved. + * Copyright 2015 Joyent, Inc.   */  /*   * Copyright (c) 2010, Intel Corporation. @@ -284,6 +284,12 @@ int segzio_fromheap = 1;  #endif  /* + * Give folks an escape hatch for disabling SMAP via kmdb. Doesn't work + * post-boot. + */ +int disable_smap = 0; + +/*   * new memory fragmentations are possible in startup() due to BOP_ALLOCs. this   * depends on number of BOP_ALLOC calls made and requested size, memory size   * combination and whether boot.bin memory needs to be freed. @@ -673,6 +679,60 @@ perform_allocations(void)  }  /* + * Set up and enable SMAP now before we start other CPUs, but after the kernel's + * VM has been set up so we can use hot_patch_kernel_text(). + * + * We can only patch 1, 2, or 4 bytes, but not three bytes. So instead, we + * replace the four byte word at the patch point. See uts/intel/ia32/ml/copy.s + * for more information on what's going on here. + */ +static void +startup_smap(void) +{ +	int i; +	uint32_t inst; +	uint8_t *instp; +	char sym[128]; + +	extern int _smap_enable_patch_count; +	extern int _smap_disable_patch_count; + +	if (disable_smap != 0) +		remove_x86_feature(x86_featureset, X86FSET_SMAP); + +	if (is_x86_feature(x86_featureset, X86FSET_SMAP) == B_FALSE) +		return; + +	for (i = 0; i < _smap_enable_patch_count; i++) { +		int sizep; + +		VERIFY3U(i, <, _smap_enable_patch_count); +		VERIFY(snprintf(sym, sizeof (sym), "_smap_enable_patch_%d", i) < +		    sizeof (sym)); +		instp = (uint8_t *)(void *)kobj_getelfsym(sym, NULL, &sizep); +		VERIFY(instp != 0); +		inst = (instp[3] << 24) | (SMAP_CLAC_INSTR & 0x00ffffff); +		hot_patch_kernel_text((caddr_t)instp, inst, 4); +	} + +	for (i = 0; i < _smap_disable_patch_count; i++) { +		int sizep; + +		VERIFY(snprintf(sym, sizeof (sym), "_smap_disable_patch_%d", +		    i) < sizeof (sym)); +		instp = (uint8_t *)(void *)kobj_getelfsym(sym, NULL, &sizep); +		VERIFY(instp != 0); +		inst = (instp[3] << 24) | (SMAP_STAC_INSTR & 0x00ffffff); +		hot_patch_kernel_text((caddr_t)instp, inst, 4); +	} + +	hot_patch_kernel_text((caddr_t)smap_enable, SMAP_CLAC_INSTR, 4); +	hot_patch_kernel_text((caddr_t)smap_disable, SMAP_STAC_INSTR, 4); +	setcr4(getcr4() | CR4_SMAP); +	smap_enable(); +} + +/*   * Our world looks like this at startup time.   *   * In a 32-bit OS, boot loads the kernel text at 0xfe800000 and kernel data @@ -727,6 +787,7 @@ startup(void)  	 * the irq routing table (used for pci labels).  	 */  	startup_pci_bios(); +	startup_smap();  #endif  #if defined(__xpv)  	startup_xen_mca(); | 
