diff options
Diffstat (limited to 'arch/x86/mm/cpu_entry_area.c')
| -rw-r--r-- | arch/x86/mm/cpu_entry_area.c | 26 | 
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c index 752ad11d6868..56f9189bbadb 100644 --- a/arch/x86/mm/cpu_entry_area.c +++ b/arch/x86/mm/cpu_entry_area.c @@ -17,6 +17,10 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(struct exception_stacks, exception_stacks);  DEFINE_PER_CPU(struct cea_exception_stacks*, cea_exception_stacks);  #endif +#if defined(CONFIG_X86_32) && defined(CONFIG_DOUBLEFAULT) +DECLARE_PER_CPU_PAGE_ALIGNED(struct doublefault_stack, doublefault_stack); +#endif +  struct cpu_entry_area *get_cpu_entry_area(int cpu)  {  	unsigned long va = CPU_ENTRY_AREA_PER_CPU + cpu * CPU_ENTRY_AREA_SIZE; @@ -108,7 +112,15 @@ static void __init percpu_setup_exception_stacks(unsigned int cpu)  	cea_map_stack(MCE);  }  #else -static inline void percpu_setup_exception_stacks(unsigned int cpu) {} +static inline void percpu_setup_exception_stacks(unsigned int cpu) +{ +#ifdef CONFIG_DOUBLEFAULT +	struct cpu_entry_area *cea = get_cpu_entry_area(cpu); + +	cea_map_percpu_pages(&cea->doublefault_stack, +			     &per_cpu(doublefault_stack, cpu), 1, PAGE_KERNEL); +#endif +}  #endif  /* Setup the fixmap mappings only once per-processor */ @@ -161,6 +173,14 @@ static void __init setup_cpu_entry_area(unsigned int cpu)  	BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^  		      offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK);  	BUILD_BUG_ON(sizeof(struct tss_struct) % PAGE_SIZE != 0); +	/* +	 * VMX changes the host TR limit to 0x67 after a VM exit. This is +	 * okay, since 0x67 covers the size of struct x86_hw_tss. Make sure +	 * that this is correct. +	 */ +	BUILD_BUG_ON(offsetof(struct tss_struct, x86_tss) != 0); +	BUILD_BUG_ON(sizeof(struct x86_hw_tss) != 0x68); +  	cea_map_percpu_pages(&cea->tss, &per_cpu(cpu_tss_rw, cpu),  			     sizeof(struct tss_struct) / PAGE_SIZE, tss_prot); @@ -178,7 +198,9 @@ static __init void setup_cpu_entry_area_ptes(void)  #ifdef CONFIG_X86_32  	unsigned long start, end; -	BUILD_BUG_ON(CPU_ENTRY_AREA_PAGES * PAGE_SIZE < CPU_ENTRY_AREA_MAP_SIZE); +	/* The +1 is for the readonly IDT: */ +	BUILD_BUG_ON((CPU_ENTRY_AREA_PAGES+1)*PAGE_SIZE != CPU_ENTRY_AREA_MAP_SIZE); +	BUILD_BUG_ON(CPU_ENTRY_AREA_TOTAL_SIZE != CPU_ENTRY_AREA_MAP_SIZE);  	BUG_ON(CPU_ENTRY_AREA_BASE & ~PMD_MASK);  	start = CPU_ENTRY_AREA_BASE;  |