diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/Makefile | 4 | ||||
-rw-r--r-- | arch/x86/events/intel/uncore.h | 33 | ||||
-rw-r--r-- | arch/x86/events/intel/uncore_snb.c | 121 | ||||
-rw-r--r-- | arch/x86/include/asm/mce.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/mshyperv.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/page_64_types.h | 12 | ||||
-rw-r--r-- | arch/x86/include/asm/pgtable_64_types.h | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/qspinlock.h | 13 | ||||
-rw-r--r-- | arch/x86/include/asm/xen/page.h | 35 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mshyperv.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/vmware.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/ldt.c | 59 | ||||
-rw-r--r-- | arch/x86/kernel/vsmp_64.c | 84 | ||||
-rw-r--r-- | arch/x86/xen/mmu_pv.c | 6 | ||||
-rw-r--r-- | arch/x86/xen/p2m.c | 3 | ||||
-rw-r--r-- | arch/x86/xen/spinlock.c | 14 |
18 files changed, 268 insertions, 144 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ba7e3464ee92..9d734f3c8234 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -525,7 +525,6 @@ config X86_VSMP | |||
525 | bool "ScaleMP vSMP" | 525 | bool "ScaleMP vSMP" |
526 | select HYPERVISOR_GUEST | 526 | select HYPERVISOR_GUEST |
527 | select PARAVIRT | 527 | select PARAVIRT |
528 | select PARAVIRT_XXL | ||
529 | depends on X86_64 && PCI | 528 | depends on X86_64 && PCI |
530 | depends on X86_EXTENDED_PLATFORM | 529 | depends on X86_EXTENDED_PLATFORM |
531 | depends on SMP | 530 | depends on SMP |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 5b562e464009..88398fdf8129 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -213,8 +213,6 @@ ifdef CONFIG_X86_64 | |||
213 | KBUILD_LDFLAGS += $(call ld-option, -z max-page-size=0x200000) | 213 | KBUILD_LDFLAGS += $(call ld-option, -z max-page-size=0x200000) |
214 | endif | 214 | endif |
215 | 215 | ||
216 | # Speed up the build | ||
217 | KBUILD_CFLAGS += -pipe | ||
218 | # Workaround for a gcc prelease that unfortunately was shipped in a suse release | 216 | # Workaround for a gcc prelease that unfortunately was shipped in a suse release |
219 | KBUILD_CFLAGS += -Wno-sign-compare | 217 | KBUILD_CFLAGS += -Wno-sign-compare |
220 | # | 218 | # |
@@ -239,7 +237,7 @@ archheaders: | |||
239 | archmacros: | 237 | archmacros: |
240 | $(Q)$(MAKE) $(build)=arch/x86/kernel arch/x86/kernel/macros.s | 238 | $(Q)$(MAKE) $(build)=arch/x86/kernel arch/x86/kernel/macros.s |
241 | 239 | ||
242 | ASM_MACRO_FLAGS = -Wa,arch/x86/kernel/macros.s -Wa,- | 240 | ASM_MACRO_FLAGS = -Wa,arch/x86/kernel/macros.s |
243 | export ASM_MACRO_FLAGS | 241 | export ASM_MACRO_FLAGS |
244 | KBUILD_CFLAGS += $(ASM_MACRO_FLAGS) | 242 | KBUILD_CFLAGS += $(ASM_MACRO_FLAGS) |
245 | 243 | ||
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h index e17ab885b1e9..cb46d602a6b8 100644 --- a/arch/x86/events/intel/uncore.h +++ b/arch/x86/events/intel/uncore.h | |||
@@ -129,8 +129,15 @@ struct intel_uncore_box { | |||
129 | struct intel_uncore_extra_reg shared_regs[0]; | 129 | struct intel_uncore_extra_reg shared_regs[0]; |
130 | }; | 130 | }; |
131 | 131 | ||
132 | #define UNCORE_BOX_FLAG_INITIATED 0 | 132 | /* CFL uncore 8th cbox MSRs */ |
133 | #define UNCORE_BOX_FLAG_CTL_OFFS8 1 /* event config registers are 8-byte apart */ | 133 | #define CFL_UNC_CBO_7_PERFEVTSEL0 0xf70 |
134 | #define CFL_UNC_CBO_7_PER_CTR0 0xf76 | ||
135 | |||
136 | #define UNCORE_BOX_FLAG_INITIATED 0 | ||
137 | /* event config registers are 8-byte apart */ | ||
138 | #define UNCORE_BOX_FLAG_CTL_OFFS8 1 | ||
139 | /* CFL 8th CBOX has different MSR space */ | ||
140 | #define UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS 2 | ||
134 | 141 | ||
135 | struct uncore_event_desc { | 142 | struct uncore_event_desc { |
136 | struct kobj_attribute attr; | 143 | struct kobj_attribute attr; |
@@ -297,17 +304,27 @@ unsigned int uncore_freerunning_counter(struct intel_uncore_box *box, | |||
297 | static inline | 304 | static inline |
298 | unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) | 305 | unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) |
299 | { | 306 | { |
300 | return box->pmu->type->event_ctl + | 307 | if (test_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags)) { |
301 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | 308 | return CFL_UNC_CBO_7_PERFEVTSEL0 + |
302 | uncore_msr_box_offset(box); | 309 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx); |
310 | } else { | ||
311 | return box->pmu->type->event_ctl + | ||
312 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | ||
313 | uncore_msr_box_offset(box); | ||
314 | } | ||
303 | } | 315 | } |
304 | 316 | ||
305 | static inline | 317 | static inline |
306 | unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) | 318 | unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) |
307 | { | 319 | { |
308 | return box->pmu->type->perf_ctr + | 320 | if (test_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags)) { |
309 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | 321 | return CFL_UNC_CBO_7_PER_CTR0 + |
310 | uncore_msr_box_offset(box); | 322 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx); |
323 | } else { | ||
324 | return box->pmu->type->perf_ctr + | ||
325 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | ||
326 | uncore_msr_box_offset(box); | ||
327 | } | ||
311 | } | 328 | } |
312 | 329 | ||
313 | static inline | 330 | static inline |
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c index 8527c3e1038b..2593b0d7aeee 100644 --- a/arch/x86/events/intel/uncore_snb.c +++ b/arch/x86/events/intel/uncore_snb.c | |||
@@ -15,6 +15,25 @@ | |||
15 | #define PCI_DEVICE_ID_INTEL_SKL_HQ_IMC 0x1910 | 15 | #define PCI_DEVICE_ID_INTEL_SKL_HQ_IMC 0x1910 |
16 | #define PCI_DEVICE_ID_INTEL_SKL_SD_IMC 0x190f | 16 | #define PCI_DEVICE_ID_INTEL_SKL_SD_IMC 0x190f |
17 | #define PCI_DEVICE_ID_INTEL_SKL_SQ_IMC 0x191f | 17 | #define PCI_DEVICE_ID_INTEL_SKL_SQ_IMC 0x191f |
18 | #define PCI_DEVICE_ID_INTEL_KBL_Y_IMC 0x590c | ||
19 | #define PCI_DEVICE_ID_INTEL_KBL_U_IMC 0x5904 | ||
20 | #define PCI_DEVICE_ID_INTEL_KBL_UQ_IMC 0x5914 | ||
21 | #define PCI_DEVICE_ID_INTEL_KBL_SD_IMC 0x590f | ||
22 | #define PCI_DEVICE_ID_INTEL_KBL_SQ_IMC 0x591f | ||
23 | #define PCI_DEVICE_ID_INTEL_CFL_2U_IMC 0x3ecc | ||
24 | #define PCI_DEVICE_ID_INTEL_CFL_4U_IMC 0x3ed0 | ||
25 | #define PCI_DEVICE_ID_INTEL_CFL_4H_IMC 0x3e10 | ||
26 | #define PCI_DEVICE_ID_INTEL_CFL_6H_IMC 0x3ec4 | ||
27 | #define PCI_DEVICE_ID_INTEL_CFL_2S_D_IMC 0x3e0f | ||
28 | #define PCI_DEVICE_ID_INTEL_CFL_4S_D_IMC 0x3e1f | ||
29 | #define PCI_DEVICE_ID_INTEL_CFL_6S_D_IMC 0x3ec2 | ||
30 | #define PCI_DEVICE_ID_INTEL_CFL_8S_D_IMC 0x3e30 | ||
31 | #define PCI_DEVICE_ID_INTEL_CFL_4S_W_IMC 0x3e18 | ||
32 | #define PCI_DEVICE_ID_INTEL_CFL_6S_W_IMC 0x3ec6 | ||
33 | #define PCI_DEVICE_ID_INTEL_CFL_8S_W_IMC 0x3e31 | ||
34 | #define PCI_DEVICE_ID_INTEL_CFL_4S_S_IMC 0x3e33 | ||
35 | #define PCI_DEVICE_ID_INTEL_CFL_6S_S_IMC 0x3eca | ||
36 | #define PCI_DEVICE_ID_INTEL_CFL_8S_S_IMC 0x3e32 | ||
18 | 37 | ||
19 | /* SNB event control */ | 38 | /* SNB event control */ |
20 | #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff | 39 | #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff |
@@ -202,6 +221,10 @@ static void skl_uncore_msr_init_box(struct intel_uncore_box *box) | |||
202 | wrmsrl(SKL_UNC_PERF_GLOBAL_CTL, | 221 | wrmsrl(SKL_UNC_PERF_GLOBAL_CTL, |
203 | SNB_UNC_GLOBAL_CTL_EN | SKL_UNC_GLOBAL_CTL_CORE_ALL); | 222 | SNB_UNC_GLOBAL_CTL_EN | SKL_UNC_GLOBAL_CTL_CORE_ALL); |
204 | } | 223 | } |
224 | |||
225 | /* The 8th CBOX has different MSR space */ | ||
226 | if (box->pmu->pmu_idx == 7) | ||
227 | __set_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags); | ||
205 | } | 228 | } |
206 | 229 | ||
207 | static void skl_uncore_msr_enable_box(struct intel_uncore_box *box) | 230 | static void skl_uncore_msr_enable_box(struct intel_uncore_box *box) |
@@ -228,7 +251,7 @@ static struct intel_uncore_ops skl_uncore_msr_ops = { | |||
228 | static struct intel_uncore_type skl_uncore_cbox = { | 251 | static struct intel_uncore_type skl_uncore_cbox = { |
229 | .name = "cbox", | 252 | .name = "cbox", |
230 | .num_counters = 4, | 253 | .num_counters = 4, |
231 | .num_boxes = 5, | 254 | .num_boxes = 8, |
232 | .perf_ctr_bits = 44, | 255 | .perf_ctr_bits = 44, |
233 | .fixed_ctr_bits = 48, | 256 | .fixed_ctr_bits = 48, |
234 | .perf_ctr = SNB_UNC_CBO_0_PER_CTR0, | 257 | .perf_ctr = SNB_UNC_CBO_0_PER_CTR0, |
@@ -569,7 +592,82 @@ static const struct pci_device_id skl_uncore_pci_ids[] = { | |||
569 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_SQ_IMC), | 592 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_SQ_IMC), |
570 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | 593 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), |
571 | }, | 594 | }, |
572 | 595 | { /* IMC */ | |
596 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_Y_IMC), | ||
597 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
598 | }, | ||
599 | { /* IMC */ | ||
600 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_U_IMC), | ||
601 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
602 | }, | ||
603 | { /* IMC */ | ||
604 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_UQ_IMC), | ||
605 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
606 | }, | ||
607 | { /* IMC */ | ||
608 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_SD_IMC), | ||
609 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
610 | }, | ||
611 | { /* IMC */ | ||
612 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_SQ_IMC), | ||
613 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
614 | }, | ||
615 | { /* IMC */ | ||
616 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_2U_IMC), | ||
617 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
618 | }, | ||
619 | { /* IMC */ | ||
620 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4U_IMC), | ||
621 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
622 | }, | ||
623 | { /* IMC */ | ||
624 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4H_IMC), | ||
625 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
626 | }, | ||
627 | { /* IMC */ | ||
628 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_6H_IMC), | ||
629 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
630 | }, | ||
631 | { /* IMC */ | ||
632 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_2S_D_IMC), | ||
633 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
634 | }, | ||
635 | { /* IMC */ | ||
636 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4S_D_IMC), | ||
637 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
638 | }, | ||
639 | { /* IMC */ | ||
640 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_6S_D_IMC), | ||
641 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
642 | }, | ||
643 | { /* IMC */ | ||
644 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_8S_D_IMC), | ||
645 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
646 | }, | ||
647 | { /* IMC */ | ||
648 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4S_W_IMC), | ||
649 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
650 | }, | ||
651 | { /* IMC */ | ||
652 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_6S_W_IMC), | ||
653 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
654 | }, | ||
655 | { /* IMC */ | ||
656 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_8S_W_IMC), | ||
657 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
658 | }, | ||
659 | { /* IMC */ | ||
660 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4S_S_IMC), | ||
661 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
662 | }, | ||
663 | { /* IMC */ | ||
664 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_6S_S_IMC), | ||
665 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
666 | }, | ||
667 | { /* IMC */ | ||
668 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_8S_S_IMC), | ||
669 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | ||
670 | }, | ||
573 | { /* end: all zeroes */ }, | 671 | { /* end: all zeroes */ }, |
574 | }; | 672 | }; |
575 | 673 | ||
@@ -618,6 +716,25 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = { | |||
618 | IMC_DEV(SKL_HQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core H Quad Core */ | 716 | IMC_DEV(SKL_HQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core H Quad Core */ |
619 | IMC_DEV(SKL_SD_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Dual Core */ | 717 | IMC_DEV(SKL_SD_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Dual Core */ |
620 | IMC_DEV(SKL_SQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Quad Core */ | 718 | IMC_DEV(SKL_SQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Quad Core */ |
719 | IMC_DEV(KBL_Y_IMC, &skl_uncore_pci_driver), /* 7th Gen Core Y */ | ||
720 | IMC_DEV(KBL_U_IMC, &skl_uncore_pci_driver), /* 7th Gen Core U */ | ||
721 | IMC_DEV(KBL_UQ_IMC, &skl_uncore_pci_driver), /* 7th Gen Core U Quad Core */ | ||
722 | IMC_DEV(KBL_SD_IMC, &skl_uncore_pci_driver), /* 7th Gen Core S Dual Core */ | ||
723 | IMC_DEV(KBL_SQ_IMC, &skl_uncore_pci_driver), /* 7th Gen Core S Quad Core */ | ||
724 | IMC_DEV(CFL_2U_IMC, &skl_uncore_pci_driver), /* 8th Gen Core U 2 Cores */ | ||
725 | IMC_DEV(CFL_4U_IMC, &skl_uncore_pci_driver), /* 8th Gen Core U 4 Cores */ | ||
726 | IMC_DEV(CFL_4H_IMC, &skl_uncore_pci_driver), /* 8th Gen Core H 4 Cores */ | ||
727 | IMC_DEV(CFL_6H_IMC, &skl_uncore_pci_driver), /* 8th Gen Core H 6 Cores */ | ||
728 | IMC_DEV(CFL_2S_D_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 2 Cores Desktop */ | ||
729 | IMC_DEV(CFL_4S_D_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 4 Cores Desktop */ | ||
730 | IMC_DEV(CFL_6S_D_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 6 Cores Desktop */ | ||
731 | IMC_DEV(CFL_8S_D_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 8 Cores Desktop */ | ||
732 | IMC_DEV(CFL_4S_W_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 4 Cores Work Station */ | ||
733 | IMC_DEV(CFL_6S_W_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 6 Cores Work Station */ | ||
734 | IMC_DEV(CFL_8S_W_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 8 Cores Work Station */ | ||
735 | IMC_DEV(CFL_4S_S_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 4 Cores Server */ | ||
736 | IMC_DEV(CFL_6S_S_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 6 Cores Server */ | ||
737 | IMC_DEV(CFL_8S_S_IMC, &skl_uncore_pci_driver), /* 8th Gen Core S 8 Cores Server */ | ||
621 | { /* end marker */ } | 738 | { /* end marker */ } |
622 | }; | 739 | }; |
623 | 740 | ||
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 4da9b1c58d28..c1a812bd5a27 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -221,6 +221,8 @@ static inline void mce_hygon_feature_init(struct cpuinfo_x86 *c) { return mce_am | |||
221 | 221 | ||
222 | int mce_available(struct cpuinfo_x86 *c); | 222 | int mce_available(struct cpuinfo_x86 *c); |
223 | bool mce_is_memory_error(struct mce *m); | 223 | bool mce_is_memory_error(struct mce *m); |
224 | bool mce_is_correctable(struct mce *m); | ||
225 | int mce_usable_address(struct mce *m); | ||
224 | 226 | ||
225 | DECLARE_PER_CPU(unsigned, mce_exception_count); | 227 | DECLARE_PER_CPU(unsigned, mce_exception_count); |
226 | DECLARE_PER_CPU(unsigned, mce_poll_count); | 228 | DECLARE_PER_CPU(unsigned, mce_poll_count); |
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 0d6271cce198..1d0a7778e163 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h | |||
@@ -232,7 +232,7 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2) | |||
232 | : "cc"); | 232 | : "cc"); |
233 | } | 233 | } |
234 | #endif | 234 | #endif |
235 | return hv_status; | 235 | return hv_status; |
236 | } | 236 | } |
237 | 237 | ||
238 | /* | 238 | /* |
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index cd0cf1c568b4..8f657286d599 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h | |||
@@ -33,12 +33,14 @@ | |||
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Set __PAGE_OFFSET to the most negative possible address + | 35 | * Set __PAGE_OFFSET to the most negative possible address + |
36 | * PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a | 36 | * PGDIR_SIZE*17 (pgd slot 273). |
37 | * hypervisor to fit. Choosing 16 slots here is arbitrary, but it's | 37 | * |
38 | * what Xen requires. | 38 | * The gap is to allow a space for LDT remap for PTI (1 pgd slot) and space for |
39 | * a hypervisor (16 slots). Choosing 16 slots for a hypervisor is arbitrary, | ||
40 | * but it's what Xen requires. | ||
39 | */ | 41 | */ |
40 | #define __PAGE_OFFSET_BASE_L5 _AC(0xff10000000000000, UL) | 42 | #define __PAGE_OFFSET_BASE_L5 _AC(0xff11000000000000, UL) |
41 | #define __PAGE_OFFSET_BASE_L4 _AC(0xffff880000000000, UL) | 43 | #define __PAGE_OFFSET_BASE_L4 _AC(0xffff888000000000, UL) |
42 | 44 | ||
43 | #ifdef CONFIG_DYNAMIC_MEMORY_LAYOUT | 45 | #ifdef CONFIG_DYNAMIC_MEMORY_LAYOUT |
44 | #define __PAGE_OFFSET page_offset_base | 46 | #define __PAGE_OFFSET page_offset_base |
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index 04edd2d58211..84bd9bdc1987 100644 --- a/arch/x86/include/asm/pgtable_64_types.h +++ b/arch/x86/include/asm/pgtable_64_types.h | |||
@@ -111,9 +111,7 @@ extern unsigned int ptrs_per_p4d; | |||
111 | */ | 111 | */ |
112 | #define MAXMEM (1UL << MAX_PHYSMEM_BITS) | 112 | #define MAXMEM (1UL << MAX_PHYSMEM_BITS) |
113 | 113 | ||
114 | #define LDT_PGD_ENTRY_L4 -3UL | 114 | #define LDT_PGD_ENTRY -240UL |
115 | #define LDT_PGD_ENTRY_L5 -112UL | ||
116 | #define LDT_PGD_ENTRY (pgtable_l5_enabled() ? LDT_PGD_ENTRY_L5 : LDT_PGD_ENTRY_L4) | ||
117 | #define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT) | 115 | #define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT) |
118 | #define LDT_END_ADDR (LDT_BASE_ADDR + PGDIR_SIZE) | 116 | #define LDT_END_ADDR (LDT_BASE_ADDR + PGDIR_SIZE) |
119 | 117 | ||
diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h index 87623c6b13db..bd5ac6cc37db 100644 --- a/arch/x86/include/asm/qspinlock.h +++ b/arch/x86/include/asm/qspinlock.h | |||
@@ -13,12 +13,15 @@ | |||
13 | #define queued_fetch_set_pending_acquire queued_fetch_set_pending_acquire | 13 | #define queued_fetch_set_pending_acquire queued_fetch_set_pending_acquire |
14 | static __always_inline u32 queued_fetch_set_pending_acquire(struct qspinlock *lock) | 14 | static __always_inline u32 queued_fetch_set_pending_acquire(struct qspinlock *lock) |
15 | { | 15 | { |
16 | u32 val = 0; | 16 | u32 val; |
17 | |||
18 | if (GEN_BINARY_RMWcc(LOCK_PREFIX "btsl", lock->val.counter, c, | ||
19 | "I", _Q_PENDING_OFFSET)) | ||
20 | val |= _Q_PENDING_VAL; | ||
21 | 17 | ||
18 | /* | ||
19 | * We can't use GEN_BINARY_RMWcc() inside an if() stmt because asm goto | ||
20 | * and CONFIG_PROFILE_ALL_BRANCHES=y results in a label inside a | ||
21 | * statement expression, which GCC doesn't like. | ||
22 | */ | ||
23 | val = GEN_BINARY_RMWcc(LOCK_PREFIX "btsl", lock->val.counter, c, | ||
24 | "I", _Q_PENDING_OFFSET) * _Q_PENDING_VAL; | ||
22 | val |= atomic_read(&lock->val) & ~_Q_PENDING_MASK; | 25 | val |= atomic_read(&lock->val) & ~_Q_PENDING_MASK; |
23 | 26 | ||
24 | return val; | 27 | return val; |
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 123e669bf363..790ce08e41f2 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
11 | 11 | ||
12 | #include <linux/uaccess.h> | 12 | #include <asm/extable.h> |
13 | #include <asm/page.h> | 13 | #include <asm/page.h> |
14 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
15 | 15 | ||
@@ -93,12 +93,39 @@ clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, | |||
93 | */ | 93 | */ |
94 | static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val) | 94 | static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val) |
95 | { | 95 | { |
96 | return __put_user(val, (unsigned long __user *)addr); | 96 | int ret = 0; |
97 | |||
98 | asm volatile("1: mov %[val], %[ptr]\n" | ||
99 | "2:\n" | ||
100 | ".section .fixup, \"ax\"\n" | ||
101 | "3: sub $1, %[ret]\n" | ||
102 | " jmp 2b\n" | ||
103 | ".previous\n" | ||
104 | _ASM_EXTABLE(1b, 3b) | ||
105 | : [ret] "+r" (ret), [ptr] "=m" (*addr) | ||
106 | : [val] "r" (val)); | ||
107 | |||
108 | return ret; | ||
97 | } | 109 | } |
98 | 110 | ||
99 | static inline int xen_safe_read_ulong(unsigned long *addr, unsigned long *val) | 111 | static inline int xen_safe_read_ulong(const unsigned long *addr, |
112 | unsigned long *val) | ||
100 | { | 113 | { |
101 | return __get_user(*val, (unsigned long __user *)addr); | 114 | int ret = 0; |
115 | unsigned long rval = ~0ul; | ||
116 | |||
117 | asm volatile("1: mov %[ptr], %[rval]\n" | ||
118 | "2:\n" | ||
119 | ".section .fixup, \"ax\"\n" | ||
120 | "3: sub $1, %[ret]\n" | ||
121 | " jmp 2b\n" | ||
122 | ".previous\n" | ||
123 | _ASM_EXTABLE(1b, 3b) | ||
124 | : [ret] "+r" (ret), [rval] "+r" (rval) | ||
125 | : [ptr] "m" (*addr)); | ||
126 | *val = rval; | ||
127 | |||
128 | return ret; | ||
102 | } | 129 | } |
103 | 130 | ||
104 | #ifdef CONFIG_XEN_PV | 131 | #ifdef CONFIG_XEN_PV |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 8c66d2fc8f81..36d2696c9563 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -485,7 +485,7 @@ static void mce_report_event(struct pt_regs *regs) | |||
485 | * be somewhat complicated (e.g. segment offset would require an instruction | 485 | * be somewhat complicated (e.g. segment offset would require an instruction |
486 | * parser). So only support physical addresses up to page granuality for now. | 486 | * parser). So only support physical addresses up to page granuality for now. |
487 | */ | 487 | */ |
488 | static int mce_usable_address(struct mce *m) | 488 | int mce_usable_address(struct mce *m) |
489 | { | 489 | { |
490 | if (!(m->status & MCI_STATUS_ADDRV)) | 490 | if (!(m->status & MCI_STATUS_ADDRV)) |
491 | return 0; | 491 | return 0; |
@@ -505,6 +505,7 @@ static int mce_usable_address(struct mce *m) | |||
505 | 505 | ||
506 | return 1; | 506 | return 1; |
507 | } | 507 | } |
508 | EXPORT_SYMBOL_GPL(mce_usable_address); | ||
508 | 509 | ||
509 | bool mce_is_memory_error(struct mce *m) | 510 | bool mce_is_memory_error(struct mce *m) |
510 | { | 511 | { |
@@ -534,7 +535,7 @@ bool mce_is_memory_error(struct mce *m) | |||
534 | } | 535 | } |
535 | EXPORT_SYMBOL_GPL(mce_is_memory_error); | 536 | EXPORT_SYMBOL_GPL(mce_is_memory_error); |
536 | 537 | ||
537 | static bool mce_is_correctable(struct mce *m) | 538 | bool mce_is_correctable(struct mce *m) |
538 | { | 539 | { |
539 | if (m->cpuvendor == X86_VENDOR_AMD && m->status & MCI_STATUS_DEFERRED) | 540 | if (m->cpuvendor == X86_VENDOR_AMD && m->status & MCI_STATUS_DEFERRED) |
540 | return false; | 541 | return false; |
@@ -547,6 +548,7 @@ static bool mce_is_correctable(struct mce *m) | |||
547 | 548 | ||
548 | return true; | 549 | return true; |
549 | } | 550 | } |
551 | EXPORT_SYMBOL_GPL(mce_is_correctable); | ||
550 | 552 | ||
551 | static bool cec_add_mce(struct mce *m) | 553 | static bool cec_add_mce(struct mce *m) |
552 | { | 554 | { |
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 1c72f3819eb1..e81a2db42df7 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/kexec.h> | 22 | #include <linux/kexec.h> |
23 | #include <linux/i8253.h> | ||
23 | #include <asm/processor.h> | 24 | #include <asm/processor.h> |
24 | #include <asm/hypervisor.h> | 25 | #include <asm/hypervisor.h> |
25 | #include <asm/hyperv-tlfs.h> | 26 | #include <asm/hyperv-tlfs.h> |
@@ -295,6 +296,16 @@ static void __init ms_hyperv_init_platform(void) | |||
295 | if (efi_enabled(EFI_BOOT)) | 296 | if (efi_enabled(EFI_BOOT)) |
296 | x86_platform.get_nmi_reason = hv_get_nmi_reason; | 297 | x86_platform.get_nmi_reason = hv_get_nmi_reason; |
297 | 298 | ||
299 | /* | ||
300 | * Hyper-V VMs have a PIT emulation quirk such that zeroing the | ||
301 | * counter register during PIT shutdown restarts the PIT. So it | ||
302 | * continues to interrupt @18.2 HZ. Setting i8253_clear_counter | ||
303 | * to false tells pit_shutdown() not to zero the counter so that | ||
304 | * the PIT really is shutdown. Generation 2 VMs don't have a PIT, | ||
305 | * and setting this value has no effect. | ||
306 | */ | ||
307 | i8253_clear_counter_on_shutdown = false; | ||
308 | |||
298 | #if IS_ENABLED(CONFIG_HYPERV) | 309 | #if IS_ENABLED(CONFIG_HYPERV) |
299 | /* | 310 | /* |
300 | * Setup the hook to get control post apic initialization. | 311 | * Setup the hook to get control post apic initialization. |
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index d9ab49bed8af..0eda91f8eeac 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
@@ -77,7 +77,7 @@ static __init int setup_vmw_sched_clock(char *s) | |||
77 | } | 77 | } |
78 | early_param("no-vmw-sched-clock", setup_vmw_sched_clock); | 78 | early_param("no-vmw-sched-clock", setup_vmw_sched_clock); |
79 | 79 | ||
80 | static unsigned long long vmware_sched_clock(void) | 80 | static unsigned long long notrace vmware_sched_clock(void) |
81 | { | 81 | { |
82 | unsigned long long ns; | 82 | unsigned long long ns; |
83 | 83 | ||
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index ab18e0884dc6..6135ae8ce036 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
@@ -199,14 +199,6 @@ static void sanity_check_ldt_mapping(struct mm_struct *mm) | |||
199 | /* | 199 | /* |
200 | * If PTI is enabled, this maps the LDT into the kernelmode and | 200 | * If PTI is enabled, this maps the LDT into the kernelmode and |
201 | * usermode tables for the given mm. | 201 | * usermode tables for the given mm. |
202 | * | ||
203 | * There is no corresponding unmap function. Even if the LDT is freed, we | ||
204 | * leave the PTEs around until the slot is reused or the mm is destroyed. | ||
205 | * This is harmless: the LDT is always in ordinary memory, and no one will | ||
206 | * access the freed slot. | ||
207 | * | ||
208 | * If we wanted to unmap freed LDTs, we'd also need to do a flush to make | ||
209 | * it useful, and the flush would slow down modify_ldt(). | ||
210 | */ | 202 | */ |
211 | static int | 203 | static int |
212 | map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) | 204 | map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) |
@@ -214,8 +206,7 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) | |||
214 | unsigned long va; | 206 | unsigned long va; |
215 | bool is_vmalloc; | 207 | bool is_vmalloc; |
216 | spinlock_t *ptl; | 208 | spinlock_t *ptl; |
217 | pgd_t *pgd; | 209 | int i, nr_pages; |
218 | int i; | ||
219 | 210 | ||
220 | if (!static_cpu_has(X86_FEATURE_PTI)) | 211 | if (!static_cpu_has(X86_FEATURE_PTI)) |
221 | return 0; | 212 | return 0; |
@@ -229,16 +220,11 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) | |||
229 | /* Check if the current mappings are sane */ | 220 | /* Check if the current mappings are sane */ |
230 | sanity_check_ldt_mapping(mm); | 221 | sanity_check_ldt_mapping(mm); |
231 | 222 | ||
232 | /* | ||
233 | * Did we already have the top level entry allocated? We can't | ||
234 | * use pgd_none() for this because it doens't do anything on | ||
235 | * 4-level page table kernels. | ||
236 | */ | ||
237 | pgd = pgd_offset(mm, LDT_BASE_ADDR); | ||
238 | |||
239 | is_vmalloc = is_vmalloc_addr(ldt->entries); | 223 | is_vmalloc = is_vmalloc_addr(ldt->entries); |
240 | 224 | ||
241 | for (i = 0; i * PAGE_SIZE < ldt->nr_entries * LDT_ENTRY_SIZE; i++) { | 225 | nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE); |
226 | |||
227 | for (i = 0; i < nr_pages; i++) { | ||
242 | unsigned long offset = i << PAGE_SHIFT; | 228 | unsigned long offset = i << PAGE_SHIFT; |
243 | const void *src = (char *)ldt->entries + offset; | 229 | const void *src = (char *)ldt->entries + offset; |
244 | unsigned long pfn; | 230 | unsigned long pfn; |
@@ -272,13 +258,39 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) | |||
272 | /* Propagate LDT mapping to the user page-table */ | 258 | /* Propagate LDT mapping to the user page-table */ |
273 | map_ldt_struct_to_user(mm); | 259 | map_ldt_struct_to_user(mm); |
274 | 260 | ||
275 | va = (unsigned long)ldt_slot_va(slot); | ||
276 | flush_tlb_mm_range(mm, va, va + LDT_SLOT_STRIDE, PAGE_SHIFT, false); | ||
277 | |||
278 | ldt->slot = slot; | 261 | ldt->slot = slot; |
279 | return 0; | 262 | return 0; |
280 | } | 263 | } |
281 | 264 | ||
265 | static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt) | ||
266 | { | ||
267 | unsigned long va; | ||
268 | int i, nr_pages; | ||
269 | |||
270 | if (!ldt) | ||
271 | return; | ||
272 | |||
273 | /* LDT map/unmap is only required for PTI */ | ||
274 | if (!static_cpu_has(X86_FEATURE_PTI)) | ||
275 | return; | ||
276 | |||
277 | nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE); | ||
278 | |||
279 | for (i = 0; i < nr_pages; i++) { | ||
280 | unsigned long offset = i << PAGE_SHIFT; | ||
281 | spinlock_t *ptl; | ||
282 | pte_t *ptep; | ||
283 | |||
284 | va = (unsigned long)ldt_slot_va(ldt->slot) + offset; | ||
285 | ptep = get_locked_pte(mm, va, &ptl); | ||
286 | pte_clear(mm, va, ptep); | ||
287 | pte_unmap_unlock(ptep, ptl); | ||
288 | } | ||
289 | |||
290 | va = (unsigned long)ldt_slot_va(ldt->slot); | ||
291 | flush_tlb_mm_range(mm, va, va + nr_pages * PAGE_SIZE, PAGE_SHIFT, false); | ||
292 | } | ||
293 | |||
282 | #else /* !CONFIG_PAGE_TABLE_ISOLATION */ | 294 | #else /* !CONFIG_PAGE_TABLE_ISOLATION */ |
283 | 295 | ||
284 | static int | 296 | static int |
@@ -286,6 +298,10 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) | |||
286 | { | 298 | { |
287 | return 0; | 299 | return 0; |
288 | } | 300 | } |
301 | |||
302 | static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt) | ||
303 | { | ||
304 | } | ||
289 | #endif /* CONFIG_PAGE_TABLE_ISOLATION */ | 305 | #endif /* CONFIG_PAGE_TABLE_ISOLATION */ |
290 | 306 | ||
291 | static void free_ldt_pgtables(struct mm_struct *mm) | 307 | static void free_ldt_pgtables(struct mm_struct *mm) |
@@ -524,6 +540,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) | |||
524 | } | 540 | } |
525 | 541 | ||
526 | install_ldt(mm, new_ldt); | 542 | install_ldt(mm, new_ldt); |
543 | unmap_ldt_struct(mm, old_ldt); | ||
527 | free_ldt_struct(old_ldt); | 544 | free_ldt_struct(old_ldt); |
528 | error = 0; | 545 | error = 0; |
529 | 546 | ||
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 1eae5af491c2..891a75dbc131 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
@@ -26,65 +26,8 @@ | |||
26 | 26 | ||
27 | #define TOPOLOGY_REGISTER_OFFSET 0x10 | 27 | #define TOPOLOGY_REGISTER_OFFSET 0x10 |
28 | 28 | ||
29 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT_XXL | 29 | #ifdef CONFIG_PCI |
30 | /* | 30 | static void __init set_vsmp_ctl(void) |
31 | * Interrupt control on vSMPowered systems: | ||
32 | * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' | ||
33 | * and vice versa. | ||
34 | */ | ||
35 | |||
36 | asmlinkage __visible unsigned long vsmp_save_fl(void) | ||
37 | { | ||
38 | unsigned long flags = native_save_fl(); | ||
39 | |||
40 | if (!(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC)) | ||
41 | flags &= ~X86_EFLAGS_IF; | ||
42 | return flags; | ||
43 | } | ||
44 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_save_fl); | ||
45 | |||
46 | __visible void vsmp_restore_fl(unsigned long flags) | ||
47 | { | ||
48 | if (flags & X86_EFLAGS_IF) | ||
49 | flags &= ~X86_EFLAGS_AC; | ||
50 | else | ||
51 | flags |= X86_EFLAGS_AC; | ||
52 | native_restore_fl(flags); | ||
53 | } | ||
54 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl); | ||
55 | |||
56 | asmlinkage __visible void vsmp_irq_disable(void) | ||
57 | { | ||
58 | unsigned long flags = native_save_fl(); | ||
59 | |||
60 | native_restore_fl((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC); | ||
61 | } | ||
62 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable); | ||
63 | |||
64 | asmlinkage __visible void vsmp_irq_enable(void) | ||
65 | { | ||
66 | unsigned long flags = native_save_fl(); | ||
67 | |||
68 | native_restore_fl((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC)); | ||
69 | } | ||
70 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_enable); | ||
71 | |||
72 | static unsigned __init vsmp_patch(u8 type, void *ibuf, | ||
73 | unsigned long addr, unsigned len) | ||
74 | { | ||
75 | switch (type) { | ||
76 | case PARAVIRT_PATCH(irq.irq_enable): | ||
77 | case PARAVIRT_PATCH(irq.irq_disable): | ||
78 | case PARAVIRT_PATCH(irq.save_fl): | ||
79 | case PARAVIRT_PATCH(irq.restore_fl): | ||
80 | return paravirt_patch_default(type, ibuf, addr, len); | ||
81 | default: | ||
82 | return native_patch(type, ibuf, addr, len); | ||
83 | } | ||
84 | |||
85 | } | ||
86 | |||
87 | static void __init set_vsmp_pv_ops(void) | ||
88 | { | 31 | { |
89 | void __iomem *address; | 32 | void __iomem *address; |
90 | unsigned int cap, ctl, cfg; | 33 | unsigned int cap, ctl, cfg; |
@@ -109,28 +52,12 @@ static void __init set_vsmp_pv_ops(void) | |||
109 | } | 52 | } |
110 | #endif | 53 | #endif |
111 | 54 | ||
112 | if (cap & ctl & (1 << 4)) { | ||
113 | /* Setup irq ops and turn on vSMP IRQ fastpath handling */ | ||
114 | pv_ops.irq.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); | ||
115 | pv_ops.irq.irq_enable = PV_CALLEE_SAVE(vsmp_irq_enable); | ||
116 | pv_ops.irq.save_fl = PV_CALLEE_SAVE(vsmp_save_fl); | ||
117 | pv_ops.irq.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl); | ||
118 | pv_ops.init.patch = vsmp_patch; | ||
119 | ctl &= ~(1 << 4); | ||
120 | } | ||
121 | writel(ctl, address + 4); | 55 | writel(ctl, address + 4); |
122 | ctl = readl(address + 4); | 56 | ctl = readl(address + 4); |
123 | pr_info("vSMP CTL: control set to:0x%08x\n", ctl); | 57 | pr_info("vSMP CTL: control set to:0x%08x\n", ctl); |
124 | 58 | ||
125 | early_iounmap(address, 8); | 59 | early_iounmap(address, 8); |
126 | } | 60 | } |
127 | #else | ||
128 | static void __init set_vsmp_pv_ops(void) | ||
129 | { | ||
130 | } | ||
131 | #endif | ||
132 | |||
133 | #ifdef CONFIG_PCI | ||
134 | static int is_vsmp = -1; | 61 | static int is_vsmp = -1; |
135 | 62 | ||
136 | static void __init detect_vsmp_box(void) | 63 | static void __init detect_vsmp_box(void) |
@@ -164,11 +91,14 @@ static int is_vsmp_box(void) | |||
164 | { | 91 | { |
165 | return 0; | 92 | return 0; |
166 | } | 93 | } |
94 | static void __init set_vsmp_ctl(void) | ||
95 | { | ||
96 | } | ||
167 | #endif | 97 | #endif |
168 | 98 | ||
169 | static void __init vsmp_cap_cpus(void) | 99 | static void __init vsmp_cap_cpus(void) |
170 | { | 100 | { |
171 | #if !defined(CONFIG_X86_VSMP) && defined(CONFIG_SMP) | 101 | #if !defined(CONFIG_X86_VSMP) && defined(CONFIG_SMP) && defined(CONFIG_PCI) |
172 | void __iomem *address; | 102 | void __iomem *address; |
173 | unsigned int cfg, topology, node_shift, maxcpus; | 103 | unsigned int cfg, topology, node_shift, maxcpus; |
174 | 104 | ||
@@ -221,6 +151,6 @@ void __init vsmp_init(void) | |||
221 | 151 | ||
222 | vsmp_cap_cpus(); | 152 | vsmp_cap_cpus(); |
223 | 153 | ||
224 | set_vsmp_pv_ops(); | 154 | set_vsmp_ctl(); |
225 | return; | 155 | return; |
226 | } | 156 | } |
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 0d7b3ae4960b..a5d7ed125337 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c | |||
@@ -1905,7 +1905,7 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) | |||
1905 | init_top_pgt[0] = __pgd(0); | 1905 | init_top_pgt[0] = __pgd(0); |
1906 | 1906 | ||
1907 | /* Pre-constructed entries are in pfn, so convert to mfn */ | 1907 | /* Pre-constructed entries are in pfn, so convert to mfn */ |
1908 | /* L4[272] -> level3_ident_pgt */ | 1908 | /* L4[273] -> level3_ident_pgt */ |
1909 | /* L4[511] -> level3_kernel_pgt */ | 1909 | /* L4[511] -> level3_kernel_pgt */ |
1910 | convert_pfn_mfn(init_top_pgt); | 1910 | convert_pfn_mfn(init_top_pgt); |
1911 | 1911 | ||
@@ -1925,8 +1925,8 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) | |||
1925 | addr[0] = (unsigned long)pgd; | 1925 | addr[0] = (unsigned long)pgd; |
1926 | addr[1] = (unsigned long)l3; | 1926 | addr[1] = (unsigned long)l3; |
1927 | addr[2] = (unsigned long)l2; | 1927 | addr[2] = (unsigned long)l2; |
1928 | /* Graft it onto L4[272][0]. Note that we creating an aliasing problem: | 1928 | /* Graft it onto L4[273][0]. Note that we creating an aliasing problem: |
1929 | * Both L4[272][0] and L4[511][510] have entries that point to the same | 1929 | * Both L4[273][0] and L4[511][510] have entries that point to the same |
1930 | * L2 (PMD) tables. Meaning that if you modify it in __va space | 1930 | * L2 (PMD) tables. Meaning that if you modify it in __va space |
1931 | * it will be also modified in the __ka space! (But if you just | 1931 | * it will be also modified in the __ka space! (But if you just |
1932 | * modify the PMD table to point to other PTE's or none, then you | 1932 | * modify the PMD table to point to other PTE's or none, then you |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index b06731705529..055e37e43541 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -656,8 +656,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) | |||
656 | 656 | ||
657 | /* | 657 | /* |
658 | * The interface requires atomic updates on p2m elements. | 658 | * The interface requires atomic updates on p2m elements. |
659 | * xen_safe_write_ulong() is using __put_user which does an atomic | 659 | * xen_safe_write_ulong() is using an atomic store via asm(). |
660 | * store via asm(). | ||
661 | */ | 660 | */ |
662 | if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn))) | 661 | if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn))) |
663 | return true; | 662 | return true; |
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 441c88262169..1c8a8816a402 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/log2.h> | 9 | #include <linux/log2.h> |
10 | #include <linux/gfp.h> | 10 | #include <linux/gfp.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/atomic.h> | ||
12 | 13 | ||
13 | #include <asm/paravirt.h> | 14 | #include <asm/paravirt.h> |
14 | #include <asm/qspinlock.h> | 15 | #include <asm/qspinlock.h> |
@@ -21,6 +22,7 @@ | |||
21 | 22 | ||
22 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; | 23 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; |
23 | static DEFINE_PER_CPU(char *, irq_name); | 24 | static DEFINE_PER_CPU(char *, irq_name); |
25 | static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest); | ||
24 | static bool xen_pvspin = true; | 26 | static bool xen_pvspin = true; |
25 | 27 | ||
26 | static void xen_qlock_kick(int cpu) | 28 | static void xen_qlock_kick(int cpu) |
@@ -39,25 +41,25 @@ static void xen_qlock_kick(int cpu) | |||
39 | */ | 41 | */ |
40 | static void xen_qlock_wait(u8 *byte, u8 val) | 42 | static void xen_qlock_wait(u8 *byte, u8 val) |
41 | { | 43 | { |
42 | unsigned long flags; | ||
43 | int irq = __this_cpu_read(lock_kicker_irq); | 44 | int irq = __this_cpu_read(lock_kicker_irq); |
45 | atomic_t *nest_cnt = this_cpu_ptr(&xen_qlock_wait_nest); | ||
44 | 46 | ||
45 | /* If kicker interrupts not initialized yet, just spin */ | 47 | /* If kicker interrupts not initialized yet, just spin */ |
46 | if (irq == -1 || in_nmi()) | 48 | if (irq == -1 || in_nmi()) |
47 | return; | 49 | return; |
48 | 50 | ||
49 | /* Guard against reentry. */ | 51 | /* Detect reentry. */ |
50 | local_irq_save(flags); | 52 | atomic_inc(nest_cnt); |
51 | 53 | ||
52 | /* If irq pending already clear it. */ | 54 | /* If irq pending already and no nested call clear it. */ |
53 | if (xen_test_irq_pending(irq)) { | 55 | if (atomic_read(nest_cnt) == 1 && xen_test_irq_pending(irq)) { |
54 | xen_clear_irq_pending(irq); | 56 | xen_clear_irq_pending(irq); |
55 | } else if (READ_ONCE(*byte) == val) { | 57 | } else if (READ_ONCE(*byte) == val) { |
56 | /* Block until irq becomes pending (or a spurious wakeup) */ | 58 | /* Block until irq becomes pending (or a spurious wakeup) */ |
57 | xen_poll_irq(irq); | 59 | xen_poll_irq(irq); |
58 | } | 60 | } |
59 | 61 | ||
60 | local_irq_restore(flags); | 62 | atomic_dec(nest_cnt); |
61 | } | 63 | } |
62 | 64 | ||
63 | static irqreturn_t dummy_handler(int irq, void *dev_id) | 65 | static irqreturn_t dummy_handler(int irq, void *dev_id) |