diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/boot/compressed/Makefile | 5 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 47 | ||||
-rw-r--r-- | arch/x86/include/asm/efi.h | 7 | ||||
-rw-r--r-- | arch/x86/include/asm/paravirt.h | 5 | ||||
-rw-r--r-- | arch/x86/include/asm/paravirt_types.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/syscall.h | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/tlb.h | 2 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/bootparam.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mshyperv.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 20 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_ds.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/microcode_core_early.c | 38 | ||||
-rw-r--r-- | arch/x86/kernel/paravirt.c | 25 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 45 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 13 | ||||
-rw-r--r-- | arch/x86/lguest/boot.c | 1 | ||||
-rw-r--r-- | arch/x86/mm/fault.c | 6 | ||||
-rw-r--r-- | arch/x86/mm/pageattr-test.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/pageattr.c | 12 | ||||
-rw-r--r-- | arch/x86/mm/pgtable.c | 7 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 168 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 13 |
24 files changed, 370 insertions, 77 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 70c0f3da0476..15b5cef4aa38 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1549,6 +1549,7 @@ config X86_SMAP | |||
1549 | config EFI | 1549 | config EFI |
1550 | bool "EFI runtime service support" | 1550 | bool "EFI runtime service support" |
1551 | depends on ACPI | 1551 | depends on ACPI |
1552 | select UCS2_STRING | ||
1552 | ---help--- | 1553 | ---help--- |
1553 | This enables the kernel to use EFI runtime services that are | 1554 | This enables the kernel to use EFI runtime services that are |
1554 | available (such as the EFI variable services). | 1555 | available (such as the EFI variable services). |
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 8a84501acb1b..5ef205c5f37b 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | # create a compressed vmlinux image from the original vmlinux | 4 | # create a compressed vmlinux image from the original vmlinux |
5 | # | 5 | # |
6 | 6 | ||
7 | targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo head_$(BITS).o misc.o string.o cmdline.o early_serial_console.o piggy.o | 7 | targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo |
8 | 8 | ||
9 | KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 | 9 | KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 |
10 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIC | 10 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIC |
@@ -29,7 +29,6 @@ VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ | |||
29 | $(obj)/piggy.o | 29 | $(obj)/piggy.o |
30 | 30 | ||
31 | $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone | 31 | $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone |
32 | $(obj)/efi_stub_$(BITS).o: KBUILD_CLFAGS += -fshort-wchar -mno-red-zone | ||
33 | 32 | ||
34 | ifeq ($(CONFIG_EFI_STUB), y) | 33 | ifeq ($(CONFIG_EFI_STUB), y) |
35 | VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o | 34 | VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o |
@@ -43,7 +42,7 @@ OBJCOPYFLAGS_vmlinux.bin := -R .comment -S | |||
43 | $(obj)/vmlinux.bin: vmlinux FORCE | 42 | $(obj)/vmlinux.bin: vmlinux FORCE |
44 | $(call if_changed,objcopy) | 43 | $(call if_changed,objcopy) |
45 | 44 | ||
46 | targets += vmlinux.bin.all vmlinux.relocs | 45 | targets += $(patsubst $(obj)/%,%,$(VMLINUX_OBJS)) vmlinux.bin.all vmlinux.relocs |
47 | 46 | ||
48 | CMD_RELOCS = arch/x86/tools/relocs | 47 | CMD_RELOCS = arch/x86/tools/relocs |
49 | quiet_cmd_relocs = RELOCS $@ | 48 | quiet_cmd_relocs = RELOCS $@ |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c205035a6b96..8615f7581820 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -251,6 +251,51 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) | |||
251 | *size = len; | 251 | *size = len; |
252 | } | 252 | } |
253 | 253 | ||
254 | static efi_status_t setup_efi_vars(struct boot_params *params) | ||
255 | { | ||
256 | struct setup_data *data; | ||
257 | struct efi_var_bootdata *efidata; | ||
258 | u64 store_size, remaining_size, var_size; | ||
259 | efi_status_t status; | ||
260 | |||
261 | if (!sys_table->runtime->query_variable_info) | ||
262 | return EFI_UNSUPPORTED; | ||
263 | |||
264 | data = (struct setup_data *)(unsigned long)params->hdr.setup_data; | ||
265 | |||
266 | while (data && data->next) | ||
267 | data = (struct setup_data *)(unsigned long)data->next; | ||
268 | |||
269 | status = efi_call_phys4(sys_table->runtime->query_variable_info, | ||
270 | EFI_VARIABLE_NON_VOLATILE | | ||
271 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
272 | EFI_VARIABLE_RUNTIME_ACCESS, &store_size, | ||
273 | &remaining_size, &var_size); | ||
274 | |||
275 | if (status != EFI_SUCCESS) | ||
276 | return status; | ||
277 | |||
278 | status = efi_call_phys3(sys_table->boottime->allocate_pool, | ||
279 | EFI_LOADER_DATA, sizeof(*efidata), &efidata); | ||
280 | |||
281 | if (status != EFI_SUCCESS) | ||
282 | return status; | ||
283 | |||
284 | efidata->data.type = SETUP_EFI_VARS; | ||
285 | efidata->data.len = sizeof(struct efi_var_bootdata) - | ||
286 | sizeof(struct setup_data); | ||
287 | efidata->data.next = 0; | ||
288 | efidata->store_size = store_size; | ||
289 | efidata->remaining_size = remaining_size; | ||
290 | efidata->max_var_size = var_size; | ||
291 | |||
292 | if (data) | ||
293 | data->next = (unsigned long)efidata; | ||
294 | else | ||
295 | params->hdr.setup_data = (unsigned long)efidata; | ||
296 | |||
297 | } | ||
298 | |||
254 | static efi_status_t setup_efi_pci(struct boot_params *params) | 299 | static efi_status_t setup_efi_pci(struct boot_params *params) |
255 | { | 300 | { |
256 | efi_pci_io_protocol *pci; | 301 | efi_pci_io_protocol *pci; |
@@ -1157,6 +1202,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, | |||
1157 | 1202 | ||
1158 | setup_graphics(boot_params); | 1203 | setup_graphics(boot_params); |
1159 | 1204 | ||
1205 | setup_efi_vars(boot_params); | ||
1206 | |||
1160 | setup_efi_pci(boot_params); | 1207 | setup_efi_pci(boot_params); |
1161 | 1208 | ||
1162 | status = efi_call_phys3(sys_table->boottime->allocate_pool, | 1209 | status = efi_call_phys3(sys_table->boottime->allocate_pool, |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 60c89f30c727..2fb5d5884e23 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -102,6 +102,13 @@ extern void efi_call_phys_epilog(void); | |||
102 | extern void efi_unmap_memmap(void); | 102 | extern void efi_unmap_memmap(void); |
103 | extern void efi_memory_uc(u64 addr, unsigned long size); | 103 | extern void efi_memory_uc(u64 addr, unsigned long size); |
104 | 104 | ||
105 | struct efi_var_bootdata { | ||
106 | struct setup_data data; | ||
107 | u64 store_size; | ||
108 | u64 remaining_size; | ||
109 | u64 max_var_size; | ||
110 | }; | ||
111 | |||
105 | #ifdef CONFIG_EFI | 112 | #ifdef CONFIG_EFI |
106 | 113 | ||
107 | static inline bool efi_is_native(void) | 114 | static inline bool efi_is_native(void) |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 5edd1742cfd0..7361e47db79f 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -703,7 +703,10 @@ static inline void arch_leave_lazy_mmu_mode(void) | |||
703 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); | 703 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); |
704 | } | 704 | } |
705 | 705 | ||
706 | void arch_flush_lazy_mmu_mode(void); | 706 | static inline void arch_flush_lazy_mmu_mode(void) |
707 | { | ||
708 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush); | ||
709 | } | ||
707 | 710 | ||
708 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | 711 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, |
709 | phys_addr_t phys, pgprot_t flags) | 712 | phys_addr_t phys, pgprot_t flags) |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 142236ed83af..b3b0ec1dac86 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -91,6 +91,7 @@ struct pv_lazy_ops { | |||
91 | /* Set deferred update mode, used for batching operations. */ | 91 | /* Set deferred update mode, used for batching operations. */ |
92 | void (*enter)(void); | 92 | void (*enter)(void); |
93 | void (*leave)(void); | 93 | void (*leave)(void); |
94 | void (*flush)(void); | ||
94 | }; | 95 | }; |
95 | 96 | ||
96 | struct pv_time_ops { | 97 | struct pv_time_ops { |
@@ -679,6 +680,7 @@ void paravirt_end_context_switch(struct task_struct *next); | |||
679 | 680 | ||
680 | void paravirt_enter_lazy_mmu(void); | 681 | void paravirt_enter_lazy_mmu(void); |
681 | void paravirt_leave_lazy_mmu(void); | 682 | void paravirt_leave_lazy_mmu(void); |
683 | void paravirt_flush_lazy_mmu(void); | ||
682 | 684 | ||
683 | void _paravirt_nop(void); | 685 | void _paravirt_nop(void); |
684 | u32 _paravirt_ident_32(u32); | 686 | u32 _paravirt_ident_32(u32); |
diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h index 1ace47b62592..2e188d68397c 100644 --- a/arch/x86/include/asm/syscall.h +++ b/arch/x86/include/asm/syscall.h | |||
@@ -29,13 +29,13 @@ extern const unsigned long sys_call_table[]; | |||
29 | */ | 29 | */ |
30 | static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) | 30 | static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) |
31 | { | 31 | { |
32 | return regs->orig_ax & __SYSCALL_MASK; | 32 | return regs->orig_ax; |
33 | } | 33 | } |
34 | 34 | ||
35 | static inline void syscall_rollback(struct task_struct *task, | 35 | static inline void syscall_rollback(struct task_struct *task, |
36 | struct pt_regs *regs) | 36 | struct pt_regs *regs) |
37 | { | 37 | { |
38 | regs->ax = regs->orig_ax & __SYSCALL_MASK; | 38 | regs->ax = regs->orig_ax; |
39 | } | 39 | } |
40 | 40 | ||
41 | static inline long syscall_get_error(struct task_struct *task, | 41 | static inline long syscall_get_error(struct task_struct *task, |
diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index 4fef20773b8f..c7797307fc2b 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | #define tlb_flush(tlb) \ | 8 | #define tlb_flush(tlb) \ |
9 | { \ | 9 | { \ |
10 | if (tlb->fullmm == 0) \ | 10 | if (!tlb->fullmm && !tlb->need_flush_all) \ |
11 | flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \ | 11 | flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \ |
12 | else \ | 12 | else \ |
13 | flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL); \ | 13 | flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL); \ |
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index c15ddaf90710..08744242b8d2 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #define SETUP_E820_EXT 1 | 6 | #define SETUP_E820_EXT 1 |
7 | #define SETUP_DTB 2 | 7 | #define SETUP_DTB 2 |
8 | #define SETUP_PCI 3 | 8 | #define SETUP_PCI 3 |
9 | #define SETUP_EFI_VARS 4 | ||
9 | 10 | ||
10 | /* ram_size flags */ | 11 | /* ram_size flags */ |
11 | #define RAMDISK_IMAGE_START_MASK 0x07FF | 12 | #define RAMDISK_IMAGE_START_MASK 0x07FF |
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a7d26d83fb70..8f4be53ea04b 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
@@ -35,13 +35,6 @@ static bool __init ms_hyperv_platform(void) | |||
35 | if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) | 35 | if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) |
36 | return false; | 36 | return false; |
37 | 37 | ||
38 | /* | ||
39 | * Xen emulates Hyper-V to support enlightened Windows. | ||
40 | * Check to see first if we are on a Xen Hypervisor. | ||
41 | */ | ||
42 | if (xen_cpuid_base()) | ||
43 | return false; | ||
44 | |||
45 | cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, | 38 | cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, |
46 | &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); | 39 | &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); |
47 | 40 | ||
@@ -82,12 +75,6 @@ static void __init ms_hyperv_init_platform(void) | |||
82 | 75 | ||
83 | if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) | 76 | if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) |
84 | clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); | 77 | clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); |
85 | #if IS_ENABLED(CONFIG_HYPERV) | ||
86 | /* | ||
87 | * Setup the IDT for hypervisor callback. | ||
88 | */ | ||
89 | alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); | ||
90 | #endif | ||
91 | } | 78 | } |
92 | 79 | ||
93 | const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { | 80 | const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { |
@@ -103,6 +90,11 @@ static irq_handler_t vmbus_isr; | |||
103 | 90 | ||
104 | void hv_register_vmbus_handler(int irq, irq_handler_t handler) | 91 | void hv_register_vmbus_handler(int irq, irq_handler_t handler) |
105 | { | 92 | { |
93 | /* | ||
94 | * Setup the IDT for hypervisor callback. | ||
95 | */ | ||
96 | alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); | ||
97 | |||
106 | vmbus_irq = irq; | 98 | vmbus_irq = irq; |
107 | vmbus_isr = handler; | 99 | vmbus_isr = handler; |
108 | } | 100 | } |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index dab7580c47ae..cc45deb791b0 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -153,8 +153,14 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly = | |||
153 | }; | 153 | }; |
154 | 154 | ||
155 | static struct extra_reg intel_snb_extra_regs[] __read_mostly = { | 155 | static struct extra_reg intel_snb_extra_regs[] __read_mostly = { |
156 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0), | 156 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), |
157 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1), | 157 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), |
158 | EVENT_EXTRA_END | ||
159 | }; | ||
160 | |||
161 | static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { | ||
162 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), | ||
163 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), | ||
158 | EVENT_EXTRA_END | 164 | EVENT_EXTRA_END |
159 | }; | 165 | }; |
160 | 166 | ||
@@ -2097,7 +2103,10 @@ __init int intel_pmu_init(void) | |||
2097 | x86_pmu.event_constraints = intel_snb_event_constraints; | 2103 | x86_pmu.event_constraints = intel_snb_event_constraints; |
2098 | x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; | 2104 | x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; |
2099 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; | 2105 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; |
2100 | x86_pmu.extra_regs = intel_snb_extra_regs; | 2106 | if (boot_cpu_data.x86_model == 45) |
2107 | x86_pmu.extra_regs = intel_snbep_extra_regs; | ||
2108 | else | ||
2109 | x86_pmu.extra_regs = intel_snb_extra_regs; | ||
2101 | /* all extra regs are per-cpu when HT is on */ | 2110 | /* all extra regs are per-cpu when HT is on */ |
2102 | x86_pmu.er_flags |= ERF_HAS_RSP_1; | 2111 | x86_pmu.er_flags |= ERF_HAS_RSP_1; |
2103 | x86_pmu.er_flags |= ERF_NO_HT_SHARING; | 2112 | x86_pmu.er_flags |= ERF_NO_HT_SHARING; |
@@ -2123,7 +2132,10 @@ __init int intel_pmu_init(void) | |||
2123 | x86_pmu.event_constraints = intel_ivb_event_constraints; | 2132 | x86_pmu.event_constraints = intel_ivb_event_constraints; |
2124 | x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints; | 2133 | x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints; |
2125 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; | 2134 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; |
2126 | x86_pmu.extra_regs = intel_snb_extra_regs; | 2135 | if (boot_cpu_data.x86_model == 62) |
2136 | x86_pmu.extra_regs = intel_snbep_extra_regs; | ||
2137 | else | ||
2138 | x86_pmu.extra_regs = intel_snb_extra_regs; | ||
2127 | /* all extra regs are per-cpu when HT is on */ | 2139 | /* all extra regs are per-cpu when HT is on */ |
2128 | x86_pmu.er_flags |= ERF_HAS_RSP_1; | 2140 | x86_pmu.er_flags |= ERF_HAS_RSP_1; |
2129 | x86_pmu.er_flags |= ERF_NO_HT_SHARING; | 2141 | x86_pmu.er_flags |= ERF_NO_HT_SHARING; |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index b05a575d56f4..26830f3af0df 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -314,10 +314,11 @@ int intel_pmu_drain_bts_buffer(void) | |||
314 | if (top <= at) | 314 | if (top <= at) |
315 | return 0; | 315 | return 0; |
316 | 316 | ||
317 | memset(®s, 0, sizeof(regs)); | ||
318 | |||
317 | ds->bts_index = ds->bts_buffer_base; | 319 | ds->bts_index = ds->bts_buffer_base; |
318 | 320 | ||
319 | perf_sample_data_init(&data, 0, event->hw.last_period); | 321 | perf_sample_data_init(&data, 0, event->hw.last_period); |
320 | regs.ip = 0; | ||
321 | 322 | ||
322 | /* | 323 | /* |
323 | * Prepare a generic sample, i.e. fill in the invariant fields. | 324 | * Prepare a generic sample, i.e. fill in the invariant fields. |
diff --git a/arch/x86/kernel/microcode_core_early.c b/arch/x86/kernel/microcode_core_early.c index 577db8417d15..833d51d6ee06 100644 --- a/arch/x86/kernel/microcode_core_early.c +++ b/arch/x86/kernel/microcode_core_early.c | |||
@@ -45,9 +45,6 @@ static int __cpuinit x86_vendor(void) | |||
45 | u32 eax = 0x00000000; | 45 | u32 eax = 0x00000000; |
46 | u32 ebx, ecx = 0, edx; | 46 | u32 ebx, ecx = 0, edx; |
47 | 47 | ||
48 | if (!have_cpuid_p()) | ||
49 | return X86_VENDOR_UNKNOWN; | ||
50 | |||
51 | native_cpuid(&eax, &ebx, &ecx, &edx); | 48 | native_cpuid(&eax, &ebx, &ecx, &edx); |
52 | 49 | ||
53 | if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) | 50 | if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) |
@@ -59,18 +56,45 @@ static int __cpuinit x86_vendor(void) | |||
59 | return X86_VENDOR_UNKNOWN; | 56 | return X86_VENDOR_UNKNOWN; |
60 | } | 57 | } |
61 | 58 | ||
59 | static int __cpuinit x86_family(void) | ||
60 | { | ||
61 | u32 eax = 0x00000001; | ||
62 | u32 ebx, ecx = 0, edx; | ||
63 | int x86; | ||
64 | |||
65 | native_cpuid(&eax, &ebx, &ecx, &edx); | ||
66 | |||
67 | x86 = (eax >> 8) & 0xf; | ||
68 | if (x86 == 15) | ||
69 | x86 += (eax >> 20) & 0xff; | ||
70 | |||
71 | return x86; | ||
72 | } | ||
73 | |||
62 | void __init load_ucode_bsp(void) | 74 | void __init load_ucode_bsp(void) |
63 | { | 75 | { |
64 | int vendor = x86_vendor(); | 76 | int vendor, x86; |
77 | |||
78 | if (!have_cpuid_p()) | ||
79 | return; | ||
65 | 80 | ||
66 | if (vendor == X86_VENDOR_INTEL) | 81 | vendor = x86_vendor(); |
82 | x86 = x86_family(); | ||
83 | |||
84 | if (vendor == X86_VENDOR_INTEL && x86 >= 6) | ||
67 | load_ucode_intel_bsp(); | 85 | load_ucode_intel_bsp(); |
68 | } | 86 | } |
69 | 87 | ||
70 | void __cpuinit load_ucode_ap(void) | 88 | void __cpuinit load_ucode_ap(void) |
71 | { | 89 | { |
72 | int vendor = x86_vendor(); | 90 | int vendor, x86; |
91 | |||
92 | if (!have_cpuid_p()) | ||
93 | return; | ||
94 | |||
95 | vendor = x86_vendor(); | ||
96 | x86 = x86_family(); | ||
73 | 97 | ||
74 | if (vendor == X86_VENDOR_INTEL) | 98 | if (vendor == X86_VENDOR_INTEL && x86 >= 6) |
75 | load_ucode_intel_ap(); | 99 | load_ucode_intel_ap(); |
76 | } | 100 | } |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 17fff18a1031..8bfb335f74bb 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -263,6 +263,18 @@ void paravirt_leave_lazy_mmu(void) | |||
263 | leave_lazy(PARAVIRT_LAZY_MMU); | 263 | leave_lazy(PARAVIRT_LAZY_MMU); |
264 | } | 264 | } |
265 | 265 | ||
266 | void paravirt_flush_lazy_mmu(void) | ||
267 | { | ||
268 | preempt_disable(); | ||
269 | |||
270 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { | ||
271 | arch_leave_lazy_mmu_mode(); | ||
272 | arch_enter_lazy_mmu_mode(); | ||
273 | } | ||
274 | |||
275 | preempt_enable(); | ||
276 | } | ||
277 | |||
266 | void paravirt_start_context_switch(struct task_struct *prev) | 278 | void paravirt_start_context_switch(struct task_struct *prev) |
267 | { | 279 | { |
268 | BUG_ON(preemptible()); | 280 | BUG_ON(preemptible()); |
@@ -292,18 +304,6 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) | |||
292 | return this_cpu_read(paravirt_lazy_mode); | 304 | return this_cpu_read(paravirt_lazy_mode); |
293 | } | 305 | } |
294 | 306 | ||
295 | void arch_flush_lazy_mmu_mode(void) | ||
296 | { | ||
297 | preempt_disable(); | ||
298 | |||
299 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { | ||
300 | arch_leave_lazy_mmu_mode(); | ||
301 | arch_enter_lazy_mmu_mode(); | ||
302 | } | ||
303 | |||
304 | preempt_enable(); | ||
305 | } | ||
306 | |||
307 | struct pv_info pv_info = { | 307 | struct pv_info pv_info = { |
308 | .name = "bare hardware", | 308 | .name = "bare hardware", |
309 | .paravirt_enabled = 0, | 309 | .paravirt_enabled = 0, |
@@ -475,6 +475,7 @@ struct pv_mmu_ops pv_mmu_ops = { | |||
475 | .lazy_mode = { | 475 | .lazy_mode = { |
476 | .enter = paravirt_nop, | 476 | .enter = paravirt_nop, |
477 | .leave = paravirt_nop, | 477 | .leave = paravirt_nop, |
478 | .flush = paravirt_nop, | ||
478 | }, | 479 | }, |
479 | 480 | ||
480 | .set_fixmap = native_set_fixmap, | 481 | .set_fixmap = native_set_fixmap, |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 90d8cc930f5e..fae9134a2de9 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -507,11 +507,14 @@ static void __init memblock_x86_reserve_range_setup_data(void) | |||
507 | /* | 507 | /* |
508 | * Keep the crash kernel below this limit. On 32 bits earlier kernels | 508 | * Keep the crash kernel below this limit. On 32 bits earlier kernels |
509 | * would limit the kernel to the low 512 MiB due to mapping restrictions. | 509 | * would limit the kernel to the low 512 MiB due to mapping restrictions. |
510 | * On 64bit, old kexec-tools need to under 896MiB. | ||
510 | */ | 511 | */ |
511 | #ifdef CONFIG_X86_32 | 512 | #ifdef CONFIG_X86_32 |
512 | # define CRASH_KERNEL_ADDR_MAX (512 << 20) | 513 | # define CRASH_KERNEL_ADDR_LOW_MAX (512 << 20) |
514 | # define CRASH_KERNEL_ADDR_HIGH_MAX (512 << 20) | ||
513 | #else | 515 | #else |
514 | # define CRASH_KERNEL_ADDR_MAX MAXMEM | 516 | # define CRASH_KERNEL_ADDR_LOW_MAX (896UL<<20) |
517 | # define CRASH_KERNEL_ADDR_HIGH_MAX MAXMEM | ||
515 | #endif | 518 | #endif |
516 | 519 | ||
517 | static void __init reserve_crashkernel_low(void) | 520 | static void __init reserve_crashkernel_low(void) |
@@ -521,19 +524,35 @@ static void __init reserve_crashkernel_low(void) | |||
521 | unsigned long long low_base = 0, low_size = 0; | 524 | unsigned long long low_base = 0, low_size = 0; |
522 | unsigned long total_low_mem; | 525 | unsigned long total_low_mem; |
523 | unsigned long long base; | 526 | unsigned long long base; |
527 | bool auto_set = false; | ||
524 | int ret; | 528 | int ret; |
525 | 529 | ||
526 | total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); | 530 | total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); |
531 | /* crashkernel=Y,low */ | ||
527 | ret = parse_crashkernel_low(boot_command_line, total_low_mem, | 532 | ret = parse_crashkernel_low(boot_command_line, total_low_mem, |
528 | &low_size, &base); | 533 | &low_size, &base); |
529 | if (ret != 0 || low_size <= 0) | 534 | if (ret != 0) { |
530 | return; | 535 | /* |
536 | * two parts from lib/swiotlb.c: | ||
537 | * swiotlb size: user specified with swiotlb= or default. | ||
538 | * swiotlb overflow buffer: now is hardcoded to 32k. | ||
539 | * We round it to 8M for other buffers that | ||
540 | * may need to stay low too. | ||
541 | */ | ||
542 | low_size = swiotlb_size_or_default() + (8UL<<20); | ||
543 | auto_set = true; | ||
544 | } else { | ||
545 | /* passed with crashkernel=0,low ? */ | ||
546 | if (!low_size) | ||
547 | return; | ||
548 | } | ||
531 | 549 | ||
532 | low_base = memblock_find_in_range(low_size, (1ULL<<32), | 550 | low_base = memblock_find_in_range(low_size, (1ULL<<32), |
533 | low_size, alignment); | 551 | low_size, alignment); |
534 | 552 | ||
535 | if (!low_base) { | 553 | if (!low_base) { |
536 | pr_info("crashkernel low reservation failed - No suitable area found.\n"); | 554 | if (!auto_set) |
555 | pr_info("crashkernel low reservation failed - No suitable area found.\n"); | ||
537 | 556 | ||
538 | return; | 557 | return; |
539 | } | 558 | } |
@@ -554,14 +573,22 @@ static void __init reserve_crashkernel(void) | |||
554 | const unsigned long long alignment = 16<<20; /* 16M */ | 573 | const unsigned long long alignment = 16<<20; /* 16M */ |
555 | unsigned long long total_mem; | 574 | unsigned long long total_mem; |
556 | unsigned long long crash_size, crash_base; | 575 | unsigned long long crash_size, crash_base; |
576 | bool high = false; | ||
557 | int ret; | 577 | int ret; |
558 | 578 | ||
559 | total_mem = memblock_phys_mem_size(); | 579 | total_mem = memblock_phys_mem_size(); |
560 | 580 | ||
581 | /* crashkernel=XM */ | ||
561 | ret = parse_crashkernel(boot_command_line, total_mem, | 582 | ret = parse_crashkernel(boot_command_line, total_mem, |
562 | &crash_size, &crash_base); | 583 | &crash_size, &crash_base); |
563 | if (ret != 0 || crash_size <= 0) | 584 | if (ret != 0 || crash_size <= 0) { |
564 | return; | 585 | /* crashkernel=X,high */ |
586 | ret = parse_crashkernel_high(boot_command_line, total_mem, | ||
587 | &crash_size, &crash_base); | ||
588 | if (ret != 0 || crash_size <= 0) | ||
589 | return; | ||
590 | high = true; | ||
591 | } | ||
565 | 592 | ||
566 | /* 0 means: find the address automatically */ | 593 | /* 0 means: find the address automatically */ |
567 | if (crash_base <= 0) { | 594 | if (crash_base <= 0) { |
@@ -569,7 +596,9 @@ static void __init reserve_crashkernel(void) | |||
569 | * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX | 596 | * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX |
570 | */ | 597 | */ |
571 | crash_base = memblock_find_in_range(alignment, | 598 | crash_base = memblock_find_in_range(alignment, |
572 | CRASH_KERNEL_ADDR_MAX, crash_size, alignment); | 599 | high ? CRASH_KERNEL_ADDR_HIGH_MAX : |
600 | CRASH_KERNEL_ADDR_LOW_MAX, | ||
601 | crash_size, alignment); | ||
573 | 602 | ||
574 | if (!crash_base) { | 603 | if (!crash_base) { |
575 | pr_info("crashkernel reservation failed - No suitable area found.\n"); | 604 | pr_info("crashkernel reservation failed - No suitable area found.\n"); |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 02b51dd4e4ad..f77df1c5de6e 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -1857,7 +1857,7 @@ int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data) | |||
1857 | if (!pv_eoi_enabled(vcpu)) | 1857 | if (!pv_eoi_enabled(vcpu)) |
1858 | return 0; | 1858 | return 0; |
1859 | return kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_eoi.data, | 1859 | return kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_eoi.data, |
1860 | addr); | 1860 | addr, sizeof(u8)); |
1861 | } | 1861 | } |
1862 | 1862 | ||
1863 | void kvm_lapic_init(void) | 1863 | void kvm_lapic_init(void) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f19ac0aca60d..e1721324c271 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -1823,7 +1823,8 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) | |||
1823 | return 0; | 1823 | return 0; |
1824 | } | 1824 | } |
1825 | 1825 | ||
1826 | if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa)) | 1826 | if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa, |
1827 | sizeof(u32))) | ||
1827 | return 1; | 1828 | return 1; |
1828 | 1829 | ||
1829 | vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS); | 1830 | vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS); |
@@ -1952,12 +1953,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
1952 | 1953 | ||
1953 | gpa_offset = data & ~(PAGE_MASK | 1); | 1954 | gpa_offset = data & ~(PAGE_MASK | 1); |
1954 | 1955 | ||
1955 | /* Check that the address is 32-byte aligned. */ | ||
1956 | if (gpa_offset & (sizeof(struct pvclock_vcpu_time_info) - 1)) | ||
1957 | break; | ||
1958 | |||
1959 | if (kvm_gfn_to_hva_cache_init(vcpu->kvm, | 1956 | if (kvm_gfn_to_hva_cache_init(vcpu->kvm, |
1960 | &vcpu->arch.pv_time, data & ~1ULL)) | 1957 | &vcpu->arch.pv_time, data & ~1ULL, |
1958 | sizeof(struct pvclock_vcpu_time_info))) | ||
1961 | vcpu->arch.pv_time_enabled = false; | 1959 | vcpu->arch.pv_time_enabled = false; |
1962 | else | 1960 | else |
1963 | vcpu->arch.pv_time_enabled = true; | 1961 | vcpu->arch.pv_time_enabled = true; |
@@ -1977,7 +1975,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
1977 | return 1; | 1975 | return 1; |
1978 | 1976 | ||
1979 | if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime, | 1977 | if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime, |
1980 | data & KVM_STEAL_VALID_BITS)) | 1978 | data & KVM_STEAL_VALID_BITS, |
1979 | sizeof(struct kvm_steal_time))) | ||
1981 | return 1; | 1980 | return 1; |
1982 | 1981 | ||
1983 | vcpu->arch.st.msr_val = data; | 1982 | vcpu->arch.st.msr_val = data; |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 1cbd89ca5569..7114c63f047d 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -1334,6 +1334,7 @@ __init void lguest_init(void) | |||
1334 | pv_mmu_ops.read_cr3 = lguest_read_cr3; | 1334 | pv_mmu_ops.read_cr3 = lguest_read_cr3; |
1335 | pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; | 1335 | pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; |
1336 | pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode; | 1336 | pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode; |
1337 | pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu; | ||
1337 | pv_mmu_ops.pte_update = lguest_pte_update; | 1338 | pv_mmu_ops.pte_update = lguest_pte_update; |
1338 | pv_mmu_ops.pte_update_defer = lguest_pte_update; | 1339 | pv_mmu_ops.pte_update_defer = lguest_pte_update; |
1339 | 1340 | ||
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 2b97525246d4..0e883364abb5 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -378,10 +378,12 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) | |||
378 | if (pgd_none(*pgd_ref)) | 378 | if (pgd_none(*pgd_ref)) |
379 | return -1; | 379 | return -1; |
380 | 380 | ||
381 | if (pgd_none(*pgd)) | 381 | if (pgd_none(*pgd)) { |
382 | set_pgd(pgd, *pgd_ref); | 382 | set_pgd(pgd, *pgd_ref); |
383 | else | 383 | arch_flush_lazy_mmu_mode(); |
384 | } else { | ||
384 | BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); | 385 | BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); |
386 | } | ||
385 | 387 | ||
386 | /* | 388 | /* |
387 | * Below here mismatches are bugs because these lower tables | 389 | * Below here mismatches are bugs because these lower tables |
diff --git a/arch/x86/mm/pageattr-test.c b/arch/x86/mm/pageattr-test.c index b0086567271c..0e38951e65eb 100644 --- a/arch/x86/mm/pageattr-test.c +++ b/arch/x86/mm/pageattr-test.c | |||
@@ -68,7 +68,7 @@ static int print_split(struct split_state *s) | |||
68 | s->gpg++; | 68 | s->gpg++; |
69 | i += GPS/PAGE_SIZE; | 69 | i += GPS/PAGE_SIZE; |
70 | } else if (level == PG_LEVEL_2M) { | 70 | } else if (level == PG_LEVEL_2M) { |
71 | if (!(pte_val(*pte) & _PAGE_PSE)) { | 71 | if ((pte_val(*pte) & _PAGE_PRESENT) && !(pte_val(*pte) & _PAGE_PSE)) { |
72 | printk(KERN_ERR | 72 | printk(KERN_ERR |
73 | "%lx level %d but not PSE %Lx\n", | 73 | "%lx level %d but not PSE %Lx\n", |
74 | addr, level, (u64)pte_val(*pte)); | 74 | addr, level, (u64)pte_val(*pte)); |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 091934e1d0d9..fb4e73ec24d8 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -467,7 +467,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
467 | * We are safe now. Check whether the new pgprot is the same: | 467 | * We are safe now. Check whether the new pgprot is the same: |
468 | */ | 468 | */ |
469 | old_pte = *kpte; | 469 | old_pte = *kpte; |
470 | old_prot = new_prot = req_prot = pte_pgprot(old_pte); | 470 | old_prot = req_prot = pte_pgprot(old_pte); |
471 | 471 | ||
472 | pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); | 472 | pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); |
473 | pgprot_val(req_prot) |= pgprot_val(cpa->mask_set); | 473 | pgprot_val(req_prot) |= pgprot_val(cpa->mask_set); |
@@ -478,12 +478,12 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
478 | * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL | 478 | * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL |
479 | * for the ancient hardware that doesn't support it. | 479 | * for the ancient hardware that doesn't support it. |
480 | */ | 480 | */ |
481 | if (pgprot_val(new_prot) & _PAGE_PRESENT) | 481 | if (pgprot_val(req_prot) & _PAGE_PRESENT) |
482 | pgprot_val(new_prot) |= _PAGE_PSE | _PAGE_GLOBAL; | 482 | pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL; |
483 | else | 483 | else |
484 | pgprot_val(new_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); | 484 | pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); |
485 | 485 | ||
486 | new_prot = canon_pgprot(new_prot); | 486 | req_prot = canon_pgprot(req_prot); |
487 | 487 | ||
488 | /* | 488 | /* |
489 | * old_pte points to the large page base address. So we need | 489 | * old_pte points to the large page base address. So we need |
@@ -1413,6 +1413,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable) | |||
1413 | * but that can deadlock->flush only current cpu: | 1413 | * but that can deadlock->flush only current cpu: |
1414 | */ | 1414 | */ |
1415 | __flush_tlb_all(); | 1415 | __flush_tlb_all(); |
1416 | |||
1417 | arch_flush_lazy_mmu_mode(); | ||
1416 | } | 1418 | } |
1417 | 1419 | ||
1418 | #ifdef CONFIG_HIBERNATION | 1420 | #ifdef CONFIG_HIBERNATION |
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 193350b51f90..17fda6a8b3c2 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
@@ -58,6 +58,13 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) | |||
58 | void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) | 58 | void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) |
59 | { | 59 | { |
60 | paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); | 60 | paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); |
61 | /* | ||
62 | * NOTE! For PAE, any changes to the top page-directory-pointer-table | ||
63 | * entries need a full cr3 reload to flush. | ||
64 | */ | ||
65 | #ifdef CONFIG_X86_PAE | ||
66 | tlb->need_flush_all = 1; | ||
67 | #endif | ||
61 | tlb_remove_page(tlb, virt_to_page(pmd)); | 68 | tlb_remove_page(tlb, virt_to_page(pmd)); |
62 | } | 69 | } |
63 | 70 | ||
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 5f2ecaf3f9d8..e4a86a677ce1 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/io.h> | 41 | #include <linux/io.h> |
42 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
43 | #include <linux/bcd.h> | 43 | #include <linux/bcd.h> |
44 | #include <linux/ucs2_string.h> | ||
44 | 45 | ||
45 | #include <asm/setup.h> | 46 | #include <asm/setup.h> |
46 | #include <asm/efi.h> | 47 | #include <asm/efi.h> |
@@ -51,6 +52,13 @@ | |||
51 | 52 | ||
52 | #define EFI_DEBUG 1 | 53 | #define EFI_DEBUG 1 |
53 | 54 | ||
55 | /* | ||
56 | * There's some additional metadata associated with each | ||
57 | * variable. Intel's reference implementation is 60 bytes - bump that | ||
58 | * to account for potential alignment constraints | ||
59 | */ | ||
60 | #define VAR_METADATA_SIZE 64 | ||
61 | |||
54 | struct efi __read_mostly efi = { | 62 | struct efi __read_mostly efi = { |
55 | .mps = EFI_INVALID_TABLE_ADDR, | 63 | .mps = EFI_INVALID_TABLE_ADDR, |
56 | .acpi = EFI_INVALID_TABLE_ADDR, | 64 | .acpi = EFI_INVALID_TABLE_ADDR, |
@@ -69,6 +77,13 @@ struct efi_memory_map memmap; | |||
69 | static struct efi efi_phys __initdata; | 77 | static struct efi efi_phys __initdata; |
70 | static efi_system_table_t efi_systab __initdata; | 78 | static efi_system_table_t efi_systab __initdata; |
71 | 79 | ||
80 | static u64 efi_var_store_size; | ||
81 | static u64 efi_var_remaining_size; | ||
82 | static u64 efi_var_max_var_size; | ||
83 | static u64 boot_used_size; | ||
84 | static u64 boot_var_size; | ||
85 | static u64 active_size; | ||
86 | |||
72 | unsigned long x86_efi_facility; | 87 | unsigned long x86_efi_facility; |
73 | 88 | ||
74 | /* | 89 | /* |
@@ -98,6 +113,15 @@ static int __init setup_add_efi_memmap(char *arg) | |||
98 | } | 113 | } |
99 | early_param("add_efi_memmap", setup_add_efi_memmap); | 114 | early_param("add_efi_memmap", setup_add_efi_memmap); |
100 | 115 | ||
116 | static bool efi_no_storage_paranoia; | ||
117 | |||
118 | static int __init setup_storage_paranoia(char *arg) | ||
119 | { | ||
120 | efi_no_storage_paranoia = true; | ||
121 | return 0; | ||
122 | } | ||
123 | early_param("efi_no_storage_paranoia", setup_storage_paranoia); | ||
124 | |||
101 | 125 | ||
102 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | 126 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) |
103 | { | 127 | { |
@@ -162,8 +186,53 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, | |||
162 | efi_char16_t *name, | 186 | efi_char16_t *name, |
163 | efi_guid_t *vendor) | 187 | efi_guid_t *vendor) |
164 | { | 188 | { |
165 | return efi_call_virt3(get_next_variable, | 189 | efi_status_t status; |
166 | name_size, name, vendor); | 190 | static bool finished = false; |
191 | static u64 var_size; | ||
192 | |||
193 | status = efi_call_virt3(get_next_variable, | ||
194 | name_size, name, vendor); | ||
195 | |||
196 | if (status == EFI_NOT_FOUND) { | ||
197 | finished = true; | ||
198 | if (var_size < boot_used_size) { | ||
199 | boot_var_size = boot_used_size - var_size; | ||
200 | active_size += boot_var_size; | ||
201 | } else { | ||
202 | printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n"); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | if (boot_used_size && !finished) { | ||
207 | unsigned long size; | ||
208 | u32 attr; | ||
209 | efi_status_t s; | ||
210 | void *tmp; | ||
211 | |||
212 | s = virt_efi_get_variable(name, vendor, &attr, &size, NULL); | ||
213 | |||
214 | if (s != EFI_BUFFER_TOO_SMALL || !size) | ||
215 | return status; | ||
216 | |||
217 | tmp = kmalloc(size, GFP_ATOMIC); | ||
218 | |||
219 | if (!tmp) | ||
220 | return status; | ||
221 | |||
222 | s = virt_efi_get_variable(name, vendor, &attr, &size, tmp); | ||
223 | |||
224 | if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) { | ||
225 | var_size += size; | ||
226 | var_size += ucs2_strsize(name, 1024); | ||
227 | active_size += size; | ||
228 | active_size += VAR_METADATA_SIZE; | ||
229 | active_size += ucs2_strsize(name, 1024); | ||
230 | } | ||
231 | |||
232 | kfree(tmp); | ||
233 | } | ||
234 | |||
235 | return status; | ||
167 | } | 236 | } |
168 | 237 | ||
169 | static efi_status_t virt_efi_set_variable(efi_char16_t *name, | 238 | static efi_status_t virt_efi_set_variable(efi_char16_t *name, |
@@ -172,9 +241,34 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, | |||
172 | unsigned long data_size, | 241 | unsigned long data_size, |
173 | void *data) | 242 | void *data) |
174 | { | 243 | { |
175 | return efi_call_virt5(set_variable, | 244 | efi_status_t status; |
176 | name, vendor, attr, | 245 | u32 orig_attr = 0; |
177 | data_size, data); | 246 | unsigned long orig_size = 0; |
247 | |||
248 | status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size, | ||
249 | NULL); | ||
250 | |||
251 | if (status != EFI_BUFFER_TOO_SMALL) | ||
252 | orig_size = 0; | ||
253 | |||
254 | status = efi_call_virt5(set_variable, | ||
255 | name, vendor, attr, | ||
256 | data_size, data); | ||
257 | |||
258 | if (status == EFI_SUCCESS) { | ||
259 | if (orig_size) { | ||
260 | active_size -= orig_size; | ||
261 | active_size -= ucs2_strsize(name, 1024); | ||
262 | active_size -= VAR_METADATA_SIZE; | ||
263 | } | ||
264 | if (data_size) { | ||
265 | active_size += data_size; | ||
266 | active_size += ucs2_strsize(name, 1024); | ||
267 | active_size += VAR_METADATA_SIZE; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | return status; | ||
178 | } | 272 | } |
179 | 273 | ||
180 | static efi_status_t virt_efi_query_variable_info(u32 attr, | 274 | static efi_status_t virt_efi_query_variable_info(u32 attr, |
@@ -682,6 +776,9 @@ void __init efi_init(void) | |||
682 | char vendor[100] = "unknown"; | 776 | char vendor[100] = "unknown"; |
683 | int i = 0; | 777 | int i = 0; |
684 | void *tmp; | 778 | void *tmp; |
779 | struct setup_data *data; | ||
780 | struct efi_var_bootdata *efi_var_data; | ||
781 | u64 pa_data; | ||
685 | 782 | ||
686 | #ifdef CONFIG_X86_32 | 783 | #ifdef CONFIG_X86_32 |
687 | if (boot_params.efi_info.efi_systab_hi || | 784 | if (boot_params.efi_info.efi_systab_hi || |
@@ -699,6 +796,22 @@ void __init efi_init(void) | |||
699 | if (efi_systab_init(efi_phys.systab)) | 796 | if (efi_systab_init(efi_phys.systab)) |
700 | return; | 797 | return; |
701 | 798 | ||
799 | pa_data = boot_params.hdr.setup_data; | ||
800 | while (pa_data) { | ||
801 | data = early_ioremap(pa_data, sizeof(*efi_var_data)); | ||
802 | if (data->type == SETUP_EFI_VARS) { | ||
803 | efi_var_data = (struct efi_var_bootdata *)data; | ||
804 | |||
805 | efi_var_store_size = efi_var_data->store_size; | ||
806 | efi_var_remaining_size = efi_var_data->remaining_size; | ||
807 | efi_var_max_var_size = efi_var_data->max_var_size; | ||
808 | } | ||
809 | pa_data = data->next; | ||
810 | early_iounmap(data, sizeof(*efi_var_data)); | ||
811 | } | ||
812 | |||
813 | boot_used_size = efi_var_store_size - efi_var_remaining_size; | ||
814 | |||
702 | set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); | 815 | set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); |
703 | 816 | ||
704 | /* | 817 | /* |
@@ -999,3 +1112,48 @@ u64 efi_mem_attributes(unsigned long phys_addr) | |||
999 | } | 1112 | } |
1000 | return 0; | 1113 | return 0; |
1001 | } | 1114 | } |
1115 | |||
1116 | /* | ||
1117 | * Some firmware has serious problems when using more than 50% of the EFI | ||
1118 | * variable store, i.e. it triggers bugs that can brick machines. Ensure that | ||
1119 | * we never use more than this safe limit. | ||
1120 | * | ||
1121 | * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable | ||
1122 | * store. | ||
1123 | */ | ||
1124 | efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | ||
1125 | { | ||
1126 | efi_status_t status; | ||
1127 | u64 storage_size, remaining_size, max_size; | ||
1128 | |||
1129 | status = efi.query_variable_info(attributes, &storage_size, | ||
1130 | &remaining_size, &max_size); | ||
1131 | if (status != EFI_SUCCESS) | ||
1132 | return status; | ||
1133 | |||
1134 | if (!max_size && remaining_size > size) | ||
1135 | printk_once(KERN_ERR FW_BUG "Broken EFI implementation" | ||
1136 | " is returning MaxVariableSize=0\n"); | ||
1137 | /* | ||
1138 | * Some firmware implementations refuse to boot if there's insufficient | ||
1139 | * space in the variable store. We account for that by refusing the | ||
1140 | * write if permitting it would reduce the available space to under | ||
1141 | * 50%. However, some firmware won't reclaim variable space until | ||
1142 | * after the used (not merely the actively used) space drops below | ||
1143 | * a threshold. We can approximate that case with the value calculated | ||
1144 | * above. If both the firmware and our calculations indicate that the | ||
1145 | * available space would drop below 50%, refuse the write. | ||
1146 | */ | ||
1147 | |||
1148 | if (!storage_size || size > remaining_size || | ||
1149 | (max_size && size > max_size)) | ||
1150 | return EFI_OUT_OF_RESOURCES; | ||
1151 | |||
1152 | if (!efi_no_storage_paranoia && | ||
1153 | ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && | ||
1154 | (remaining_size - size < storage_size / 2))) | ||
1155 | return EFI_OUT_OF_RESOURCES; | ||
1156 | |||
1157 | return EFI_SUCCESS; | ||
1158 | } | ||
1159 | EXPORT_SYMBOL_GPL(efi_query_variable_store); | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 6afbb2ca9a0a..e006c18d288a 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1748,14 +1748,18 @@ static void *m2v(phys_addr_t maddr) | |||
1748 | } | 1748 | } |
1749 | 1749 | ||
1750 | /* Set the page permissions on an identity-mapped pages */ | 1750 | /* Set the page permissions on an identity-mapped pages */ |
1751 | static void set_page_prot(void *addr, pgprot_t prot) | 1751 | static void set_page_prot_flags(void *addr, pgprot_t prot, unsigned long flags) |
1752 | { | 1752 | { |
1753 | unsigned long pfn = __pa(addr) >> PAGE_SHIFT; | 1753 | unsigned long pfn = __pa(addr) >> PAGE_SHIFT; |
1754 | pte_t pte = pfn_pte(pfn, prot); | 1754 | pte_t pte = pfn_pte(pfn, prot); |
1755 | 1755 | ||
1756 | if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0)) | 1756 | if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, flags)) |
1757 | BUG(); | 1757 | BUG(); |
1758 | } | 1758 | } |
1759 | static void set_page_prot(void *addr, pgprot_t prot) | ||
1760 | { | ||
1761 | return set_page_prot_flags(addr, prot, UVMF_NONE); | ||
1762 | } | ||
1759 | #ifdef CONFIG_X86_32 | 1763 | #ifdef CONFIG_X86_32 |
1760 | static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) | 1764 | static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) |
1761 | { | 1765 | { |
@@ -1839,12 +1843,12 @@ static void __init check_pt_base(unsigned long *pt_base, unsigned long *pt_end, | |||
1839 | unsigned long addr) | 1843 | unsigned long addr) |
1840 | { | 1844 | { |
1841 | if (*pt_base == PFN_DOWN(__pa(addr))) { | 1845 | if (*pt_base == PFN_DOWN(__pa(addr))) { |
1842 | set_page_prot((void *)addr, PAGE_KERNEL); | 1846 | set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); |
1843 | clear_page((void *)addr); | 1847 | clear_page((void *)addr); |
1844 | (*pt_base)++; | 1848 | (*pt_base)++; |
1845 | } | 1849 | } |
1846 | if (*pt_end == PFN_DOWN(__pa(addr))) { | 1850 | if (*pt_end == PFN_DOWN(__pa(addr))) { |
1847 | set_page_prot((void *)addr, PAGE_KERNEL); | 1851 | set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); |
1848 | clear_page((void *)addr); | 1852 | clear_page((void *)addr); |
1849 | (*pt_end)--; | 1853 | (*pt_end)--; |
1850 | } | 1854 | } |
@@ -2196,6 +2200,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { | |||
2196 | .lazy_mode = { | 2200 | .lazy_mode = { |
2197 | .enter = paravirt_enter_lazy_mmu, | 2201 | .enter = paravirt_enter_lazy_mmu, |
2198 | .leave = xen_leave_lazy_mmu, | 2202 | .leave = xen_leave_lazy_mmu, |
2203 | .flush = paravirt_flush_lazy_mmu, | ||
2199 | }, | 2204 | }, |
2200 | 2205 | ||
2201 | .set_fixmap = xen_set_fixmap, | 2206 | .set_fixmap = xen_set_fixmap, |