diff options
Diffstat (limited to 'arch/x86')
| -rw-r--r-- | arch/x86/Makefile | 8 | ||||
| -rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_intel.c | 18 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_rapl.c | 46 | ||||
| -rw-r--r-- | arch/x86/kernel/early-quirks.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes/core.c | 16 | ||||
| -rw-r--r-- | arch/x86/kernel/reboot.c | 72 | ||||
| -rw-r--r-- | arch/x86/kernel/vsmp_64.c | 11 | ||||
| -rw-r--r-- | arch/x86/kvm/cpuid.c | 2 | ||||
| -rw-r--r-- | arch/x86/kvm/cpuid.h | 8 | ||||
| -rw-r--r-- | arch/x86/kvm/mmu.c | 38 | ||||
| -rw-r--r-- | arch/x86/kvm/mmu.h | 44 | ||||
| -rw-r--r-- | arch/x86/kvm/paging_tmpl.h | 2 | ||||
| -rw-r--r-- | arch/x86/kvm/vmx.c | 64 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 10 | ||||
| -rw-r--r-- | arch/x86/syscalls/Makefile | 2 | ||||
| -rw-r--r-- | arch/x86/syscalls/syscall_32.tbl | 1 | ||||
| -rw-r--r-- | arch/x86/tools/Makefile | 2 | ||||
| -rw-r--r-- | arch/x86/vdso/vdso-layout.lds.S | 19 | ||||
| -rw-r--r-- | arch/x86/xen/smp.c | 3 | ||||
| -rw-r--r-- | arch/x86/xen/spinlock.c | 5 | ||||
| -rw-r--r-- | arch/x86/xen/xen-asm_32.S | 25 |
24 files changed, 286 insertions, 123 deletions
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 602f57e590b5..ce6ad7e6a7d7 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
| @@ -83,7 +83,9 @@ else | |||
| 83 | KBUILD_CFLAGS += -m64 | 83 | KBUILD_CFLAGS += -m64 |
| 84 | 84 | ||
| 85 | # Don't autogenerate traditional x87, MMX or SSE instructions | 85 | # Don't autogenerate traditional x87, MMX or SSE instructions |
| 86 | KBUILD_CFLAGS += -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 | 86 | KBUILD_CFLAGS += -mno-mmx -mno-sse |
| 87 | KBUILD_CFLAGS += $(call cc-option,-mno-80387) | ||
| 88 | KBUILD_CFLAGS += $(call cc-option,-mno-fp-ret-in-387) | ||
| 87 | 89 | ||
| 88 | # Use -mpreferred-stack-boundary=3 if supported. | 90 | # Use -mpreferred-stack-boundary=3 if supported. |
| 89 | KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) | 91 | KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) |
| @@ -250,8 +252,8 @@ archclean: | |||
| 250 | PHONY += kvmconfig | 252 | PHONY += kvmconfig |
| 251 | kvmconfig: | 253 | kvmconfig: |
| 252 | $(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target)) | 254 | $(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target)) |
| 253 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config arch/x86/configs/kvm_guest.config | 255 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(srctree)/arch/x86/configs/kvm_guest.config |
| 254 | $(Q)yes "" | $(MAKE) oldconfig | 256 | $(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig |
| 255 | 257 | ||
| 256 | define archhelp | 258 | define archhelp |
| 257 | echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' | 259 | echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index fcaf9c961265..7de069afb382 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
| @@ -60,7 +60,7 @@ | |||
| 60 | | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ | 60 | | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ |
| 61 | | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \ | 61 | | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \ |
| 62 | | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ | 62 | | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ |
| 63 | | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE)) | 63 | | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE | X86_CR4_SMAP)) |
| 64 | 64 | ||
| 65 | #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) | 65 | #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) |
| 66 | 66 | ||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 6ad4658de705..d23aa82e7a7b 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -3425,6 +3425,11 @@ int get_nr_irqs_gsi(void) | |||
| 3425 | return nr_irqs_gsi; | 3425 | return nr_irqs_gsi; |
| 3426 | } | 3426 | } |
| 3427 | 3427 | ||
| 3428 | unsigned int arch_dynirq_lower_bound(unsigned int from) | ||
| 3429 | { | ||
| 3430 | return from < nr_irqs_gsi ? nr_irqs_gsi : from; | ||
| 3431 | } | ||
| 3432 | |||
| 3428 | int __init arch_probe_nr_irqs(void) | 3433 | int __init arch_probe_nr_irqs(void) |
| 3429 | { | 3434 | { |
| 3430 | int nr; | 3435 | int nr; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index eeee23ff75ef..68317c80de7f 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -598,7 +598,6 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) | |||
| 598 | { | 598 | { |
| 599 | struct mce m; | 599 | struct mce m; |
| 600 | int i; | 600 | int i; |
| 601 | unsigned long *v; | ||
| 602 | 601 | ||
| 603 | this_cpu_inc(mce_poll_count); | 602 | this_cpu_inc(mce_poll_count); |
| 604 | 603 | ||
| @@ -618,8 +617,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) | |||
| 618 | if (!(m.status & MCI_STATUS_VAL)) | 617 | if (!(m.status & MCI_STATUS_VAL)) |
| 619 | continue; | 618 | continue; |
| 620 | 619 | ||
| 621 | v = &get_cpu_var(mce_polled_error); | 620 | this_cpu_write(mce_polled_error, 1); |
| 622 | set_bit(0, v); | ||
| 623 | /* | 621 | /* |
| 624 | * Uncorrected or signalled events are handled by the exception | 622 | * Uncorrected or signalled events are handled by the exception |
| 625 | * handler when it is enabled, so don't process those here. | 623 | * handler when it is enabled, so don't process those here. |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 3bdb95ae8c43..9a316b21df8b 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c | |||
| @@ -42,7 +42,7 @@ static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned); | |||
| 42 | * cmci_discover_lock protects against parallel discovery attempts | 42 | * cmci_discover_lock protects against parallel discovery attempts |
| 43 | * which could race against each other. | 43 | * which could race against each other. |
| 44 | */ | 44 | */ |
| 45 | static DEFINE_RAW_SPINLOCK(cmci_discover_lock); | 45 | static DEFINE_SPINLOCK(cmci_discover_lock); |
| 46 | 46 | ||
| 47 | #define CMCI_THRESHOLD 1 | 47 | #define CMCI_THRESHOLD 1 |
| 48 | #define CMCI_POLL_INTERVAL (30 * HZ) | 48 | #define CMCI_POLL_INTERVAL (30 * HZ) |
| @@ -144,14 +144,14 @@ static void cmci_storm_disable_banks(void) | |||
| 144 | int bank; | 144 | int bank; |
| 145 | u64 val; | 145 | u64 val; |
| 146 | 146 | ||
| 147 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | 147 | spin_lock_irqsave(&cmci_discover_lock, flags); |
| 148 | owned = __get_cpu_var(mce_banks_owned); | 148 | owned = __get_cpu_var(mce_banks_owned); |
| 149 | for_each_set_bit(bank, owned, MAX_NR_BANKS) { | 149 | for_each_set_bit(bank, owned, MAX_NR_BANKS) { |
| 150 | rdmsrl(MSR_IA32_MCx_CTL2(bank), val); | 150 | rdmsrl(MSR_IA32_MCx_CTL2(bank), val); |
| 151 | val &= ~MCI_CTL2_CMCI_EN; | 151 | val &= ~MCI_CTL2_CMCI_EN; |
| 152 | wrmsrl(MSR_IA32_MCx_CTL2(bank), val); | 152 | wrmsrl(MSR_IA32_MCx_CTL2(bank), val); |
| 153 | } | 153 | } |
| 154 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | 154 | spin_unlock_irqrestore(&cmci_discover_lock, flags); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | static bool cmci_storm_detect(void) | 157 | static bool cmci_storm_detect(void) |
| @@ -211,7 +211,7 @@ static void cmci_discover(int banks) | |||
| 211 | int i; | 211 | int i; |
| 212 | int bios_wrong_thresh = 0; | 212 | int bios_wrong_thresh = 0; |
| 213 | 213 | ||
| 214 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | 214 | spin_lock_irqsave(&cmci_discover_lock, flags); |
| 215 | for (i = 0; i < banks; i++) { | 215 | for (i = 0; i < banks; i++) { |
| 216 | u64 val; | 216 | u64 val; |
| 217 | int bios_zero_thresh = 0; | 217 | int bios_zero_thresh = 0; |
| @@ -266,7 +266,7 @@ static void cmci_discover(int banks) | |||
| 266 | WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks))); | 266 | WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks))); |
| 267 | } | 267 | } |
| 268 | } | 268 | } |
| 269 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | 269 | spin_unlock_irqrestore(&cmci_discover_lock, flags); |
| 270 | if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) { | 270 | if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) { |
| 271 | pr_info_once( | 271 | pr_info_once( |
| 272 | "bios_cmci_threshold: Some banks do not have valid thresholds set\n"); | 272 | "bios_cmci_threshold: Some banks do not have valid thresholds set\n"); |
| @@ -316,10 +316,10 @@ void cmci_clear(void) | |||
| 316 | 316 | ||
| 317 | if (!cmci_supported(&banks)) | 317 | if (!cmci_supported(&banks)) |
| 318 | return; | 318 | return; |
| 319 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | 319 | spin_lock_irqsave(&cmci_discover_lock, flags); |
| 320 | for (i = 0; i < banks; i++) | 320 | for (i = 0; i < banks; i++) |
| 321 | __cmci_disable_bank(i); | 321 | __cmci_disable_bank(i); |
| 322 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | 322 | spin_unlock_irqrestore(&cmci_discover_lock, flags); |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | static void cmci_rediscover_work_func(void *arg) | 325 | static void cmci_rediscover_work_func(void *arg) |
| @@ -360,9 +360,9 @@ void cmci_disable_bank(int bank) | |||
| 360 | if (!cmci_supported(&banks)) | 360 | if (!cmci_supported(&banks)) |
| 361 | return; | 361 | return; |
| 362 | 362 | ||
| 363 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | 363 | spin_lock_irqsave(&cmci_discover_lock, flags); |
| 364 | __cmci_disable_bank(bank); | 364 | __cmci_disable_bank(bank); |
| 365 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | 365 | spin_unlock_irqrestore(&cmci_discover_lock, flags); |
| 366 | } | 366 | } |
| 367 | 367 | ||
| 368 | static void intel_init_cmci(void) | 368 | static void intel_init_cmci(void) |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 059218ed5208..619f7699487a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c | |||
| @@ -59,7 +59,7 @@ | |||
| 59 | #define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */ | 59 | #define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */ |
| 60 | #define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */ | 60 | #define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */ |
| 61 | #define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */ | 61 | #define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */ |
| 62 | #define RAPL_IDX_PP1_NRG_STAT 3 /* DRAM */ | 62 | #define RAPL_IDX_PP1_NRG_STAT 3 /* gpu */ |
| 63 | #define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */ | 63 | #define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */ |
| 64 | 64 | ||
| 65 | /* Clients have PP0, PKG */ | 65 | /* Clients have PP0, PKG */ |
| @@ -72,6 +72,12 @@ | |||
| 72 | 1<<RAPL_IDX_PKG_NRG_STAT|\ | 72 | 1<<RAPL_IDX_PKG_NRG_STAT|\ |
| 73 | 1<<RAPL_IDX_RAM_NRG_STAT) | 73 | 1<<RAPL_IDX_RAM_NRG_STAT) |
| 74 | 74 | ||
| 75 | /* Servers have PP0, PKG, RAM, PP1 */ | ||
| 76 | #define RAPL_IDX_HSW (1<<RAPL_IDX_PP0_NRG_STAT|\ | ||
| 77 | 1<<RAPL_IDX_PKG_NRG_STAT|\ | ||
| 78 | 1<<RAPL_IDX_RAM_NRG_STAT|\ | ||
| 79 | 1<<RAPL_IDX_PP1_NRG_STAT) | ||
| 80 | |||
| 75 | /* | 81 | /* |
| 76 | * event code: LSB 8 bits, passed in attr->config | 82 | * event code: LSB 8 bits, passed in attr->config |
| 77 | * any other bit is reserved | 83 | * any other bit is reserved |
| @@ -425,6 +431,24 @@ static struct attribute *rapl_events_cln_attr[] = { | |||
| 425 | NULL, | 431 | NULL, |
| 426 | }; | 432 | }; |
| 427 | 433 | ||
| 434 | static struct attribute *rapl_events_hsw_attr[] = { | ||
| 435 | EVENT_PTR(rapl_cores), | ||
| 436 | EVENT_PTR(rapl_pkg), | ||
| 437 | EVENT_PTR(rapl_gpu), | ||
| 438 | EVENT_PTR(rapl_ram), | ||
| 439 | |||
| 440 | EVENT_PTR(rapl_cores_unit), | ||
| 441 | EVENT_PTR(rapl_pkg_unit), | ||
| 442 | EVENT_PTR(rapl_gpu_unit), | ||
| 443 | EVENT_PTR(rapl_ram_unit), | ||
| 444 | |||
| 445 | EVENT_PTR(rapl_cores_scale), | ||
| 446 | EVENT_PTR(rapl_pkg_scale), | ||
| 447 | EVENT_PTR(rapl_gpu_scale), | ||
| 448 | EVENT_PTR(rapl_ram_scale), | ||
| 449 | NULL, | ||
| 450 | }; | ||
| 451 | |||
| 428 | static struct attribute_group rapl_pmu_events_group = { | 452 | static struct attribute_group rapl_pmu_events_group = { |
| 429 | .name = "events", | 453 | .name = "events", |
| 430 | .attrs = NULL, /* patched at runtime */ | 454 | .attrs = NULL, /* patched at runtime */ |
| @@ -511,6 +535,7 @@ static int rapl_cpu_prepare(int cpu) | |||
| 511 | struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu); | 535 | struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu); |
| 512 | int phys_id = topology_physical_package_id(cpu); | 536 | int phys_id = topology_physical_package_id(cpu); |
| 513 | u64 ms; | 537 | u64 ms; |
| 538 | u64 msr_rapl_power_unit_bits; | ||
| 514 | 539 | ||
| 515 | if (pmu) | 540 | if (pmu) |
| 516 | return 0; | 541 | return 0; |
| @@ -518,6 +543,10 @@ static int rapl_cpu_prepare(int cpu) | |||
| 518 | if (phys_id < 0) | 543 | if (phys_id < 0) |
| 519 | return -1; | 544 | return -1; |
| 520 | 545 | ||
| 546 | /* protect rdmsrl() to handle virtualization */ | ||
| 547 | if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits)) | ||
| 548 | return -1; | ||
| 549 | |||
| 521 | pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); | 550 | pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); |
| 522 | if (!pmu) | 551 | if (!pmu) |
| 523 | return -1; | 552 | return -1; |
| @@ -531,8 +560,7 @@ static int rapl_cpu_prepare(int cpu) | |||
| 531 | * | 560 | * |
| 532 | * we cache in local PMU instance | 561 | * we cache in local PMU instance |
| 533 | */ | 562 | */ |
| 534 | rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit); | 563 | pmu->hw_unit = (msr_rapl_power_unit_bits >> 8) & 0x1FULL; |
| 535 | pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL; | ||
| 536 | pmu->pmu = &rapl_pmu_class; | 564 | pmu->pmu = &rapl_pmu_class; |
| 537 | 565 | ||
| 538 | /* | 566 | /* |
| @@ -631,11 +659,14 @@ static int __init rapl_pmu_init(void) | |||
| 631 | switch (boot_cpu_data.x86_model) { | 659 | switch (boot_cpu_data.x86_model) { |
| 632 | case 42: /* Sandy Bridge */ | 660 | case 42: /* Sandy Bridge */ |
| 633 | case 58: /* Ivy Bridge */ | 661 | case 58: /* Ivy Bridge */ |
| 634 | case 60: /* Haswell */ | ||
| 635 | case 69: /* Haswell-Celeron */ | ||
| 636 | rapl_cntr_mask = RAPL_IDX_CLN; | 662 | rapl_cntr_mask = RAPL_IDX_CLN; |
| 637 | rapl_pmu_events_group.attrs = rapl_events_cln_attr; | 663 | rapl_pmu_events_group.attrs = rapl_events_cln_attr; |
| 638 | break; | 664 | break; |
| 665 | case 60: /* Haswell */ | ||
| 666 | case 69: /* Haswell-Celeron */ | ||
| 667 | rapl_cntr_mask = RAPL_IDX_HSW; | ||
| 668 | rapl_pmu_events_group.attrs = rapl_events_hsw_attr; | ||
| 669 | break; | ||
| 639 | case 45: /* Sandy Bridge-EP */ | 670 | case 45: /* Sandy Bridge-EP */ |
| 640 | case 62: /* IvyTown */ | 671 | case 62: /* IvyTown */ |
| 641 | rapl_cntr_mask = RAPL_IDX_SRV; | 672 | rapl_cntr_mask = RAPL_IDX_SRV; |
| @@ -650,7 +681,9 @@ static int __init rapl_pmu_init(void) | |||
| 650 | cpu_notifier_register_begin(); | 681 | cpu_notifier_register_begin(); |
| 651 | 682 | ||
| 652 | for_each_online_cpu(cpu) { | 683 | for_each_online_cpu(cpu) { |
| 653 | rapl_cpu_prepare(cpu); | 684 | ret = rapl_cpu_prepare(cpu); |
| 685 | if (ret) | ||
| 686 | goto out; | ||
| 654 | rapl_cpu_init(cpu); | 687 | rapl_cpu_init(cpu); |
| 655 | } | 688 | } |
| 656 | 689 | ||
| @@ -673,6 +706,7 @@ static int __init rapl_pmu_init(void) | |||
| 673 | hweight32(rapl_cntr_mask), | 706 | hweight32(rapl_cntr_mask), |
| 674 | ktime_to_ms(pmu->timer_interval)); | 707 | ktime_to_ms(pmu->timer_interval)); |
| 675 | 708 | ||
| 709 | out: | ||
| 676 | cpu_notifier_register_done(); | 710 | cpu_notifier_register_done(); |
| 677 | 711 | ||
| 678 | return 0; | 712 | return 0; |
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index b0cc3809723d..6e2537c32190 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c | |||
| @@ -240,7 +240,7 @@ static u32 __init intel_stolen_base(int num, int slot, int func, size_t stolen_s | |||
| 240 | return base; | 240 | return base; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | #define KB(x) ((x) * 1024) | 243 | #define KB(x) ((x) * 1024UL) |
| 244 | #define MB(x) (KB (KB (x))) | 244 | #define MB(x) (KB (KB (x))) |
| 245 | #define GB(x) (MB (KB (x))) | 245 | #define GB(x) (MB (KB (x))) |
| 246 | 246 | ||
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 79a3f9682871..61b17dc2c277 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
| @@ -897,9 +897,10 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
| 897 | struct kprobe *cur = kprobe_running(); | 897 | struct kprobe *cur = kprobe_running(); |
| 898 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 898 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 899 | 899 | ||
| 900 | switch (kcb->kprobe_status) { | 900 | if (unlikely(regs->ip == (unsigned long)cur->ainsn.insn)) { |
| 901 | case KPROBE_HIT_SS: | 901 | /* This must happen on single-stepping */ |
| 902 | case KPROBE_REENTER: | 902 | WARN_ON(kcb->kprobe_status != KPROBE_HIT_SS && |
| 903 | kcb->kprobe_status != KPROBE_REENTER); | ||
| 903 | /* | 904 | /* |
| 904 | * We are here because the instruction being single | 905 | * We are here because the instruction being single |
| 905 | * stepped caused a page fault. We reset the current | 906 | * stepped caused a page fault. We reset the current |
| @@ -914,9 +915,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
| 914 | else | 915 | else |
| 915 | reset_current_kprobe(); | 916 | reset_current_kprobe(); |
| 916 | preempt_enable_no_resched(); | 917 | preempt_enable_no_resched(); |
| 917 | break; | 918 | } else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE || |
| 918 | case KPROBE_HIT_ACTIVE: | 919 | kcb->kprobe_status == KPROBE_HIT_SSDONE) { |
| 919 | case KPROBE_HIT_SSDONE: | ||
| 920 | /* | 920 | /* |
| 921 | * We increment the nmissed count for accounting, | 921 | * We increment the nmissed count for accounting, |
| 922 | * we can also use npre/npostfault count for accounting | 922 | * we can also use npre/npostfault count for accounting |
| @@ -945,10 +945,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
| 945 | * fixup routine could not handle it, | 945 | * fixup routine could not handle it, |
| 946 | * Let do_page_fault() fix it. | 946 | * Let do_page_fault() fix it. |
| 947 | */ | 947 | */ |
| 948 | break; | ||
| 949 | default: | ||
| 950 | break; | ||
| 951 | } | 948 | } |
| 949 | |||
| 952 | return 0; | 950 | return 0; |
| 953 | } | 951 | } |
| 954 | 952 | ||
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 654b46574b91..3399d3a99730 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
| @@ -114,8 +114,8 @@ EXPORT_SYMBOL(machine_real_restart); | |||
| 114 | */ | 114 | */ |
| 115 | static int __init set_pci_reboot(const struct dmi_system_id *d) | 115 | static int __init set_pci_reboot(const struct dmi_system_id *d) |
| 116 | { | 116 | { |
| 117 | if (reboot_type != BOOT_CF9) { | 117 | if (reboot_type != BOOT_CF9_FORCE) { |
| 118 | reboot_type = BOOT_CF9; | 118 | reboot_type = BOOT_CF9_FORCE; |
| 119 | pr_info("%s series board detected. Selecting %s-method for reboots.\n", | 119 | pr_info("%s series board detected. Selecting %s-method for reboots.\n", |
| 120 | d->ident, "PCI"); | 120 | d->ident, "PCI"); |
| 121 | } | 121 | } |
| @@ -458,20 +458,23 @@ void __attribute__((weak)) mach_reboot_fixups(void) | |||
| 458 | } | 458 | } |
| 459 | 459 | ||
| 460 | /* | 460 | /* |
| 461 | * Windows compatible x86 hardware expects the following on reboot: | 461 | * To the best of our knowledge Windows compatible x86 hardware expects |
| 462 | * the following on reboot: | ||
| 462 | * | 463 | * |
| 463 | * 1) If the FADT has the ACPI reboot register flag set, try it | 464 | * 1) If the FADT has the ACPI reboot register flag set, try it |
| 464 | * 2) If still alive, write to the keyboard controller | 465 | * 2) If still alive, write to the keyboard controller |
| 465 | * 3) If still alive, write to the ACPI reboot register again | 466 | * 3) If still alive, write to the ACPI reboot register again |
| 466 | * 4) If still alive, write to the keyboard controller again | 467 | * 4) If still alive, write to the keyboard controller again |
| 467 | * 5) If still alive, call the EFI runtime service to reboot | 468 | * 5) If still alive, call the EFI runtime service to reboot |
| 468 | * 6) If still alive, write to the PCI IO port 0xCF9 to reboot | 469 | * 6) If no EFI runtime service, call the BIOS to do a reboot |
| 469 | * 7) If still alive, inform BIOS to do a proper reboot | ||
| 470 | * | 470 | * |
| 471 | * If the machine is still alive at this stage, it gives up. We default to | 471 | * We default to following the same pattern. We also have |
| 472 | * following the same pattern, except that if we're still alive after (7) we'll | 472 | * two other reboot methods: 'triple fault' and 'PCI', which |
| 473 | * try to force a triple fault and then cycle between hitting the keyboard | 473 | * can be triggered via the reboot= kernel boot option or |
| 474 | * controller and doing that | 474 | * via quirks. |
| 475 | * | ||
| 476 | * This means that this function can never return, it can misbehave | ||
| 477 | * by not rebooting properly and hanging. | ||
| 475 | */ | 478 | */ |
| 476 | static void native_machine_emergency_restart(void) | 479 | static void native_machine_emergency_restart(void) |
| 477 | { | 480 | { |
| @@ -492,6 +495,11 @@ static void native_machine_emergency_restart(void) | |||
| 492 | for (;;) { | 495 | for (;;) { |
| 493 | /* Could also try the reset bit in the Hammer NB */ | 496 | /* Could also try the reset bit in the Hammer NB */ |
| 494 | switch (reboot_type) { | 497 | switch (reboot_type) { |
| 498 | case BOOT_ACPI: | ||
| 499 | acpi_reboot(); | ||
| 500 | reboot_type = BOOT_KBD; | ||
| 501 | break; | ||
| 502 | |||
| 495 | case BOOT_KBD: | 503 | case BOOT_KBD: |
| 496 | mach_reboot_fixups(); /* For board specific fixups */ | 504 | mach_reboot_fixups(); /* For board specific fixups */ |
| 497 | 505 | ||
| @@ -509,43 +517,29 @@ static void native_machine_emergency_restart(void) | |||
| 509 | } | 517 | } |
| 510 | break; | 518 | break; |
| 511 | 519 | ||
| 512 | case BOOT_TRIPLE: | ||
| 513 | load_idt(&no_idt); | ||
| 514 | __asm__ __volatile__("int3"); | ||
| 515 | |||
| 516 | /* We're probably dead after this, but... */ | ||
| 517 | reboot_type = BOOT_KBD; | ||
| 518 | break; | ||
| 519 | |||
| 520 | case BOOT_BIOS: | ||
| 521 | machine_real_restart(MRR_BIOS); | ||
| 522 | |||
| 523 | /* We're probably dead after this, but... */ | ||
| 524 | reboot_type = BOOT_TRIPLE; | ||
| 525 | break; | ||
| 526 | |||
| 527 | case BOOT_ACPI: | ||
| 528 | acpi_reboot(); | ||
| 529 | reboot_type = BOOT_KBD; | ||
| 530 | break; | ||
| 531 | |||
| 532 | case BOOT_EFI: | 520 | case BOOT_EFI: |
| 533 | if (efi_enabled(EFI_RUNTIME_SERVICES)) | 521 | if (efi_enabled(EFI_RUNTIME_SERVICES)) |
| 534 | efi.reset_system(reboot_mode == REBOOT_WARM ? | 522 | efi.reset_system(reboot_mode == REBOOT_WARM ? |
| 535 | EFI_RESET_WARM : | 523 | EFI_RESET_WARM : |
| 536 | EFI_RESET_COLD, | 524 | EFI_RESET_COLD, |
| 537 | EFI_SUCCESS, 0, NULL); | 525 | EFI_SUCCESS, 0, NULL); |
| 538 | reboot_type = BOOT_CF9_COND; | 526 | reboot_type = BOOT_BIOS; |
| 527 | break; | ||
| 528 | |||
| 529 | case BOOT_BIOS: | ||
| 530 | machine_real_restart(MRR_BIOS); | ||
| 531 | |||
| 532 | /* We're probably dead after this, but... */ | ||
| 533 | reboot_type = BOOT_CF9_SAFE; | ||
| 539 | break; | 534 | break; |
| 540 | 535 | ||
| 541 | case BOOT_CF9: | 536 | case BOOT_CF9_FORCE: |
| 542 | port_cf9_safe = true; | 537 | port_cf9_safe = true; |
| 543 | /* Fall through */ | 538 | /* Fall through */ |
| 544 | 539 | ||
| 545 | case BOOT_CF9_COND: | 540 | case BOOT_CF9_SAFE: |
| 546 | if (port_cf9_safe) { | 541 | if (port_cf9_safe) { |
| 547 | u8 reboot_code = reboot_mode == REBOOT_WARM ? | 542 | u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E; |
| 548 | 0x06 : 0x0E; | ||
| 549 | u8 cf9 = inb(0xcf9) & ~reboot_code; | 543 | u8 cf9 = inb(0xcf9) & ~reboot_code; |
| 550 | outb(cf9|2, 0xcf9); /* Request hard reset */ | 544 | outb(cf9|2, 0xcf9); /* Request hard reset */ |
| 551 | udelay(50); | 545 | udelay(50); |
| @@ -553,7 +547,15 @@ static void native_machine_emergency_restart(void) | |||
| 553 | outb(cf9|reboot_code, 0xcf9); | 547 | outb(cf9|reboot_code, 0xcf9); |
| 554 | udelay(50); | 548 | udelay(50); |
| 555 | } | 549 | } |
| 556 | reboot_type = BOOT_BIOS; | 550 | reboot_type = BOOT_TRIPLE; |
| 551 | break; | ||
| 552 | |||
| 553 | case BOOT_TRIPLE: | ||
| 554 | load_idt(&no_idt); | ||
| 555 | __asm__ __volatile__("int3"); | ||
| 556 | |||
| 557 | /* We're probably dead after this, but... */ | ||
| 558 | reboot_type = BOOT_KBD; | ||
| 557 | break; | 559 | break; |
| 558 | } | 560 | } |
| 559 | } | 561 | } |
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index f6584a90aba3..5edc34b5b951 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
| @@ -26,6 +26,9 @@ | |||
| 26 | 26 | ||
| 27 | #define TOPOLOGY_REGISTER_OFFSET 0x10 | 27 | #define TOPOLOGY_REGISTER_OFFSET 0x10 |
| 28 | 28 | ||
| 29 | /* Flag below is initialized once during vSMP PCI initialization. */ | ||
| 30 | static int irq_routing_comply = 1; | ||
| 31 | |||
| 29 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT | 32 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT |
| 30 | /* | 33 | /* |
| 31 | * Interrupt control on vSMPowered systems: | 34 | * Interrupt control on vSMPowered systems: |
| @@ -101,6 +104,10 @@ static void __init set_vsmp_pv_ops(void) | |||
| 101 | #ifdef CONFIG_SMP | 104 | #ifdef CONFIG_SMP |
| 102 | if (cap & ctl & BIT(8)) { | 105 | if (cap & ctl & BIT(8)) { |
| 103 | ctl &= ~BIT(8); | 106 | ctl &= ~BIT(8); |
| 107 | |||
| 108 | /* Interrupt routing set to ignore */ | ||
| 109 | irq_routing_comply = 0; | ||
| 110 | |||
| 104 | #ifdef CONFIG_PROC_FS | 111 | #ifdef CONFIG_PROC_FS |
| 105 | /* Don't let users change irq affinity via procfs */ | 112 | /* Don't let users change irq affinity via procfs */ |
| 106 | no_irq_affinity = 1; | 113 | no_irq_affinity = 1; |
| @@ -218,7 +225,9 @@ static void vsmp_apic_post_init(void) | |||
| 218 | { | 225 | { |
| 219 | /* need to update phys_pkg_id */ | 226 | /* need to update phys_pkg_id */ |
| 220 | apic->phys_pkg_id = apicid_phys_pkg_id; | 227 | apic->phys_pkg_id = apicid_phys_pkg_id; |
| 221 | apic->vector_allocation_domain = fill_vector_allocation_domain; | 228 | |
| 229 | if (!irq_routing_comply) | ||
| 230 | apic->vector_allocation_domain = fill_vector_allocation_domain; | ||
| 222 | } | 231 | } |
| 223 | 232 | ||
| 224 | void __init vsmp_init(void) | 233 | void __init vsmp_init(void) |
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index bea60671ef8a..f47a104a749c 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
| @@ -308,7 +308,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 308 | const u32 kvm_supported_word9_x86_features = | 308 | const u32 kvm_supported_word9_x86_features = |
| 309 | F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | | 309 | F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | |
| 310 | F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) | | 310 | F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) | |
| 311 | F(ADX); | 311 | F(ADX) | F(SMAP); |
| 312 | 312 | ||
| 313 | /* all calls to cpuid_count() should be made on the same cpu */ | 313 | /* all calls to cpuid_count() should be made on the same cpu */ |
| 314 | get_cpu(); | 314 | get_cpu(); |
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index a2a1bb7ed8c1..eeecbed26ac7 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h | |||
| @@ -48,6 +48,14 @@ static inline bool guest_cpuid_has_smep(struct kvm_vcpu *vcpu) | |||
| 48 | return best && (best->ebx & bit(X86_FEATURE_SMEP)); | 48 | return best && (best->ebx & bit(X86_FEATURE_SMEP)); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | static inline bool guest_cpuid_has_smap(struct kvm_vcpu *vcpu) | ||
| 52 | { | ||
| 53 | struct kvm_cpuid_entry2 *best; | ||
| 54 | |||
| 55 | best = kvm_find_cpuid_entry(vcpu, 7, 0); | ||
| 56 | return best && (best->ebx & bit(X86_FEATURE_SMAP)); | ||
| 57 | } | ||
| 58 | |||
| 51 | static inline bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu) | 59 | static inline bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu) |
| 52 | { | 60 | { |
| 53 | struct kvm_cpuid_entry2 *best; | 61 | struct kvm_cpuid_entry2 *best; |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index f5704d9e5ddc..813d31038b93 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
| @@ -3601,20 +3601,27 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu, | |||
| 3601 | } | 3601 | } |
| 3602 | } | 3602 | } |
| 3603 | 3603 | ||
| 3604 | static void update_permission_bitmask(struct kvm_vcpu *vcpu, | 3604 | void update_permission_bitmask(struct kvm_vcpu *vcpu, |
| 3605 | struct kvm_mmu *mmu, bool ept) | 3605 | struct kvm_mmu *mmu, bool ept) |
| 3606 | { | 3606 | { |
| 3607 | unsigned bit, byte, pfec; | 3607 | unsigned bit, byte, pfec; |
| 3608 | u8 map; | 3608 | u8 map; |
| 3609 | bool fault, x, w, u, wf, uf, ff, smep; | 3609 | bool fault, x, w, u, wf, uf, ff, smapf, cr4_smap, cr4_smep, smap = 0; |
| 3610 | 3610 | ||
| 3611 | smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); | 3611 | cr4_smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); |
| 3612 | cr4_smap = kvm_read_cr4_bits(vcpu, X86_CR4_SMAP); | ||
| 3612 | for (byte = 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) { | 3613 | for (byte = 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) { |
| 3613 | pfec = byte << 1; | 3614 | pfec = byte << 1; |
| 3614 | map = 0; | 3615 | map = 0; |
| 3615 | wf = pfec & PFERR_WRITE_MASK; | 3616 | wf = pfec & PFERR_WRITE_MASK; |
| 3616 | uf = pfec & PFERR_USER_MASK; | 3617 | uf = pfec & PFERR_USER_MASK; |
| 3617 | ff = pfec & PFERR_FETCH_MASK; | 3618 | ff = pfec & PFERR_FETCH_MASK; |
| 3619 | /* | ||
| 3620 | * PFERR_RSVD_MASK bit is set in PFEC if the access is not | ||
| 3621 | * subject to SMAP restrictions, and cleared otherwise. The | ||
| 3622 | * bit is only meaningful if the SMAP bit is set in CR4. | ||
| 3623 | */ | ||
| 3624 | smapf = !(pfec & PFERR_RSVD_MASK); | ||
| 3618 | for (bit = 0; bit < 8; ++bit) { | 3625 | for (bit = 0; bit < 8; ++bit) { |
| 3619 | x = bit & ACC_EXEC_MASK; | 3626 | x = bit & ACC_EXEC_MASK; |
| 3620 | w = bit & ACC_WRITE_MASK; | 3627 | w = bit & ACC_WRITE_MASK; |
| @@ -3626,12 +3633,33 @@ static void update_permission_bitmask(struct kvm_vcpu *vcpu, | |||
| 3626 | /* Allow supervisor writes if !cr0.wp */ | 3633 | /* Allow supervisor writes if !cr0.wp */ |
| 3627 | w |= !is_write_protection(vcpu) && !uf; | 3634 | w |= !is_write_protection(vcpu) && !uf; |
| 3628 | /* Disallow supervisor fetches of user code if cr4.smep */ | 3635 | /* Disallow supervisor fetches of user code if cr4.smep */ |
| 3629 | x &= !(smep && u && !uf); | 3636 | x &= !(cr4_smep && u && !uf); |
| 3637 | |||
| 3638 | /* | ||
| 3639 | * SMAP:kernel-mode data accesses from user-mode | ||
| 3640 | * mappings should fault. A fault is considered | ||
| 3641 | * as a SMAP violation if all of the following | ||
| 3642 | * conditions are ture: | ||
| 3643 | * - X86_CR4_SMAP is set in CR4 | ||
| 3644 | * - An user page is accessed | ||
| 3645 | * - Page fault in kernel mode | ||
| 3646 | * - if CPL = 3 or X86_EFLAGS_AC is clear | ||
| 3647 | * | ||
| 3648 | * Here, we cover the first three conditions. | ||
| 3649 | * The fourth is computed dynamically in | ||
| 3650 | * permission_fault() and is in smapf. | ||
| 3651 | * | ||
| 3652 | * Also, SMAP does not affect instruction | ||
| 3653 | * fetches, add the !ff check here to make it | ||
| 3654 | * clearer. | ||
| 3655 | */ | ||
| 3656 | smap = cr4_smap && u && !uf && !ff; | ||
| 3630 | } else | 3657 | } else |
| 3631 | /* Not really needed: no U/S accesses on ept */ | 3658 | /* Not really needed: no U/S accesses on ept */ |
| 3632 | u = 1; | 3659 | u = 1; |
| 3633 | 3660 | ||
| 3634 | fault = (ff && !x) || (uf && !u) || (wf && !w); | 3661 | fault = (ff && !x) || (uf && !u) || (wf && !w) || |
| 3662 | (smapf && smap); | ||
| 3635 | map |= fault << bit; | 3663 | map |= fault << bit; |
| 3636 | } | 3664 | } |
| 3637 | mmu->permissions[byte] = map; | 3665 | mmu->permissions[byte] = map; |
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 292615274358..3842e70bdb7c 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h | |||
| @@ -44,11 +44,17 @@ | |||
| 44 | #define PT_DIRECTORY_LEVEL 2 | 44 | #define PT_DIRECTORY_LEVEL 2 |
| 45 | #define PT_PAGE_TABLE_LEVEL 1 | 45 | #define PT_PAGE_TABLE_LEVEL 1 |
| 46 | 46 | ||
| 47 | #define PFERR_PRESENT_MASK (1U << 0) | 47 | #define PFERR_PRESENT_BIT 0 |
| 48 | #define PFERR_WRITE_MASK (1U << 1) | 48 | #define PFERR_WRITE_BIT 1 |
| 49 | #define PFERR_USER_MASK (1U << 2) | 49 | #define PFERR_USER_BIT 2 |
| 50 | #define PFERR_RSVD_MASK (1U << 3) | 50 | #define PFERR_RSVD_BIT 3 |
| 51 | #define PFERR_FETCH_MASK (1U << 4) | 51 | #define PFERR_FETCH_BIT 4 |
| 52 | |||
| 53 | #define PFERR_PRESENT_MASK (1U << PFERR_PRESENT_BIT) | ||
| 54 | #define PFERR_WRITE_MASK (1U << PFERR_WRITE_BIT) | ||
| 55 | #define PFERR_USER_MASK (1U << PFERR_USER_BIT) | ||
| 56 | #define PFERR_RSVD_MASK (1U << PFERR_RSVD_BIT) | ||
| 57 | #define PFERR_FETCH_MASK (1U << PFERR_FETCH_BIT) | ||
| 52 | 58 | ||
| 53 | int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]); | 59 | int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]); |
| 54 | void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask); | 60 | void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask); |
| @@ -73,6 +79,8 @@ int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct); | |||
| 73 | void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context); | 79 | void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context); |
| 74 | void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, | 80 | void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, |
| 75 | bool execonly); | 81 | bool execonly); |
| 82 | void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, | ||
| 83 | bool ept); | ||
| 76 | 84 | ||
| 77 | static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm) | 85 | static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm) |
| 78 | { | 86 | { |
| @@ -110,10 +118,30 @@ static inline bool is_write_protection(struct kvm_vcpu *vcpu) | |||
| 110 | * Will a fault with a given page-fault error code (pfec) cause a permission | 118 | * Will a fault with a given page-fault error code (pfec) cause a permission |
| 111 | * fault with the given access (in ACC_* format)? | 119 | * fault with the given access (in ACC_* format)? |
| 112 | */ | 120 | */ |
| 113 | static inline bool permission_fault(struct kvm_mmu *mmu, unsigned pte_access, | 121 | static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, |
| 114 | unsigned pfec) | 122 | unsigned pte_access, unsigned pfec) |
| 115 | { | 123 | { |
| 116 | return (mmu->permissions[pfec >> 1] >> pte_access) & 1; | 124 | int cpl = kvm_x86_ops->get_cpl(vcpu); |
| 125 | unsigned long rflags = kvm_x86_ops->get_rflags(vcpu); | ||
| 126 | |||
| 127 | /* | ||
| 128 | * If CPL < 3, SMAP prevention are disabled if EFLAGS.AC = 1. | ||
| 129 | * | ||
| 130 | * If CPL = 3, SMAP applies to all supervisor-mode data accesses | ||
| 131 | * (these are implicit supervisor accesses) regardless of the value | ||
| 132 | * of EFLAGS.AC. | ||
| 133 | * | ||
| 134 | * This computes (cpl < 3) && (rflags & X86_EFLAGS_AC), leaving | ||
| 135 | * the result in X86_EFLAGS_AC. We then insert it in place of | ||
| 136 | * the PFERR_RSVD_MASK bit; this bit will always be zero in pfec, | ||
| 137 | * but it will be one in index if SMAP checks are being overridden. | ||
| 138 | * It is important to keep this branchless. | ||
| 139 | */ | ||
| 140 | unsigned long smap = (cpl - 3) & (rflags & X86_EFLAGS_AC); | ||
| 141 | int index = (pfec >> 1) + | ||
| 142 | (smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1)); | ||
| 143 | |||
| 144 | return (mmu->permissions[index] >> pte_access) & 1; | ||
| 117 | } | 145 | } |
| 118 | 146 | ||
| 119 | void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm); | 147 | void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm); |
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index b1e6c1bf68d3..123efd3ec29f 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
| @@ -353,7 +353,7 @@ retry_walk: | |||
| 353 | walker->ptes[walker->level - 1] = pte; | 353 | walker->ptes[walker->level - 1] = pte; |
| 354 | } while (!is_last_gpte(mmu, walker->level, pte)); | 354 | } while (!is_last_gpte(mmu, walker->level, pte)); |
| 355 | 355 | ||
| 356 | if (unlikely(permission_fault(mmu, pte_access, access))) { | 356 | if (unlikely(permission_fault(vcpu, mmu, pte_access, access))) { |
| 357 | errcode |= PFERR_PRESENT_MASK; | 357 | errcode |= PFERR_PRESENT_MASK; |
| 358 | goto error; | 358 | goto error; |
| 359 | } | 359 | } |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1320e0f8e611..33e8c028842f 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -503,7 +503,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) | |||
| 503 | [number##_HIGH] = VMCS12_OFFSET(name)+4 | 503 | [number##_HIGH] = VMCS12_OFFSET(name)+4 |
| 504 | 504 | ||
| 505 | 505 | ||
| 506 | static const unsigned long shadow_read_only_fields[] = { | 506 | static unsigned long shadow_read_only_fields[] = { |
| 507 | /* | 507 | /* |
| 508 | * We do NOT shadow fields that are modified when L0 | 508 | * We do NOT shadow fields that are modified when L0 |
| 509 | * traps and emulates any vmx instruction (e.g. VMPTRLD, | 509 | * traps and emulates any vmx instruction (e.g. VMPTRLD, |
| @@ -526,10 +526,10 @@ static const unsigned long shadow_read_only_fields[] = { | |||
| 526 | GUEST_LINEAR_ADDRESS, | 526 | GUEST_LINEAR_ADDRESS, |
| 527 | GUEST_PHYSICAL_ADDRESS | 527 | GUEST_PHYSICAL_ADDRESS |
| 528 | }; | 528 | }; |
| 529 | static const int max_shadow_read_only_fields = | 529 | static int max_shadow_read_only_fields = |
| 530 | ARRAY_SIZE(shadow_read_only_fields); | 530 | ARRAY_SIZE(shadow_read_only_fields); |
| 531 | 531 | ||
| 532 | static const unsigned long shadow_read_write_fields[] = { | 532 | static unsigned long shadow_read_write_fields[] = { |
| 533 | GUEST_RIP, | 533 | GUEST_RIP, |
| 534 | GUEST_RSP, | 534 | GUEST_RSP, |
| 535 | GUEST_CR0, | 535 | GUEST_CR0, |
| @@ -558,7 +558,7 @@ static const unsigned long shadow_read_write_fields[] = { | |||
| 558 | HOST_FS_SELECTOR, | 558 | HOST_FS_SELECTOR, |
| 559 | HOST_GS_SELECTOR | 559 | HOST_GS_SELECTOR |
| 560 | }; | 560 | }; |
| 561 | static const int max_shadow_read_write_fields = | 561 | static int max_shadow_read_write_fields = |
| 562 | ARRAY_SIZE(shadow_read_write_fields); | 562 | ARRAY_SIZE(shadow_read_write_fields); |
| 563 | 563 | ||
| 564 | static const unsigned short vmcs_field_to_offset_table[] = { | 564 | static const unsigned short vmcs_field_to_offset_table[] = { |
| @@ -3009,6 +3009,41 @@ static void free_kvm_area(void) | |||
| 3009 | } | 3009 | } |
| 3010 | } | 3010 | } |
| 3011 | 3011 | ||
| 3012 | static void init_vmcs_shadow_fields(void) | ||
| 3013 | { | ||
| 3014 | int i, j; | ||
| 3015 | |||
| 3016 | /* No checks for read only fields yet */ | ||
| 3017 | |||
| 3018 | for (i = j = 0; i < max_shadow_read_write_fields; i++) { | ||
| 3019 | switch (shadow_read_write_fields[i]) { | ||
| 3020 | case GUEST_BNDCFGS: | ||
| 3021 | if (!vmx_mpx_supported()) | ||
| 3022 | continue; | ||
| 3023 | break; | ||
| 3024 | default: | ||
| 3025 | break; | ||
| 3026 | } | ||
| 3027 | |||
| 3028 | if (j < i) | ||
| 3029 | shadow_read_write_fields[j] = | ||
| 3030 | shadow_read_write_fields[i]; | ||
| 3031 | j++; | ||
| 3032 | } | ||
| 3033 | max_shadow_read_write_fields = j; | ||
| 3034 | |||
| 3035 | /* shadowed fields guest access without vmexit */ | ||
| 3036 | for (i = 0; i < max_shadow_read_write_fields; i++) { | ||
| 3037 | clear_bit(shadow_read_write_fields[i], | ||
| 3038 | vmx_vmwrite_bitmap); | ||
| 3039 | clear_bit(shadow_read_write_fields[i], | ||
| 3040 | vmx_vmread_bitmap); | ||
| 3041 | } | ||
| 3042 | for (i = 0; i < max_shadow_read_only_fields; i++) | ||
| 3043 | clear_bit(shadow_read_only_fields[i], | ||
| 3044 | vmx_vmread_bitmap); | ||
| 3045 | } | ||
| 3046 | |||
| 3012 | static __init int alloc_kvm_area(void) | 3047 | static __init int alloc_kvm_area(void) |
| 3013 | { | 3048 | { |
| 3014 | int cpu; | 3049 | int cpu; |
| @@ -3039,6 +3074,8 @@ static __init int hardware_setup(void) | |||
| 3039 | enable_vpid = 0; | 3074 | enable_vpid = 0; |
| 3040 | if (!cpu_has_vmx_shadow_vmcs()) | 3075 | if (!cpu_has_vmx_shadow_vmcs()) |
| 3041 | enable_shadow_vmcs = 0; | 3076 | enable_shadow_vmcs = 0; |
| 3077 | if (enable_shadow_vmcs) | ||
| 3078 | init_vmcs_shadow_fields(); | ||
| 3042 | 3079 | ||
| 3043 | if (!cpu_has_vmx_ept() || | 3080 | if (!cpu_has_vmx_ept() || |
| 3044 | !cpu_has_vmx_ept_4levels()) { | 3081 | !cpu_has_vmx_ept_4levels()) { |
| @@ -3484,13 +3521,14 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
| 3484 | hw_cr4 &= ~X86_CR4_PAE; | 3521 | hw_cr4 &= ~X86_CR4_PAE; |
| 3485 | hw_cr4 |= X86_CR4_PSE; | 3522 | hw_cr4 |= X86_CR4_PSE; |
| 3486 | /* | 3523 | /* |
| 3487 | * SMEP is disabled if CPU is in non-paging mode in | 3524 | * SMEP/SMAP is disabled if CPU is in non-paging mode |
| 3488 | * hardware. However KVM always uses paging mode to | 3525 | * in hardware. However KVM always uses paging mode to |
| 3489 | * emulate guest non-paging mode with TDP. | 3526 | * emulate guest non-paging mode with TDP. |
| 3490 | * To emulate this behavior, SMEP needs to be manually | 3527 | * To emulate this behavior, SMEP/SMAP needs to be |
| 3491 | * disabled when guest switches to non-paging mode. | 3528 | * manually disabled when guest switches to non-paging |
| 3529 | * mode. | ||
| 3492 | */ | 3530 | */ |
| 3493 | hw_cr4 &= ~X86_CR4_SMEP; | 3531 | hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP); |
| 3494 | } else if (!(cr4 & X86_CR4_PAE)) { | 3532 | } else if (!(cr4 & X86_CR4_PAE)) { |
| 3495 | hw_cr4 &= ~X86_CR4_PAE; | 3533 | hw_cr4 &= ~X86_CR4_PAE; |
| 3496 | } | 3534 | } |
| @@ -8802,14 +8840,6 @@ static int __init vmx_init(void) | |||
| 8802 | 8840 | ||
| 8803 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); | 8841 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); |
| 8804 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); | 8842 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); |
| 8805 | /* shadowed read/write fields */ | ||
| 8806 | for (i = 0; i < max_shadow_read_write_fields; i++) { | ||
| 8807 | clear_bit(shadow_read_write_fields[i], vmx_vmwrite_bitmap); | ||
| 8808 | clear_bit(shadow_read_write_fields[i], vmx_vmread_bitmap); | ||
| 8809 | } | ||
| 8810 | /* shadowed read only fields */ | ||
| 8811 | for (i = 0; i < max_shadow_read_only_fields; i++) | ||
| 8812 | clear_bit(shadow_read_only_fields[i], vmx_vmread_bitmap); | ||
| 8813 | 8843 | ||
| 8814 | /* | 8844 | /* |
| 8815 | * Allow direct access to the PC debug port (it is often used for I/O | 8845 | * Allow direct access to the PC debug port (it is often used for I/O |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9d1b5cd4d34c..8b8fc0b792ba 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -652,6 +652,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
| 652 | if (!guest_cpuid_has_smep(vcpu) && (cr4 & X86_CR4_SMEP)) | 652 | if (!guest_cpuid_has_smep(vcpu) && (cr4 & X86_CR4_SMEP)) |
| 653 | return 1; | 653 | return 1; |
| 654 | 654 | ||
| 655 | if (!guest_cpuid_has_smap(vcpu) && (cr4 & X86_CR4_SMAP)) | ||
| 656 | return 1; | ||
| 657 | |||
| 655 | if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE)) | 658 | if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE)) |
| 656 | return 1; | 659 | return 1; |
| 657 | 660 | ||
| @@ -680,6 +683,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
| 680 | (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) | 683 | (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) |
| 681 | kvm_mmu_reset_context(vcpu); | 684 | kvm_mmu_reset_context(vcpu); |
| 682 | 685 | ||
| 686 | if ((cr4 ^ old_cr4) & X86_CR4_SMAP) | ||
| 687 | update_permission_bitmask(vcpu, vcpu->arch.walk_mmu, false); | ||
| 688 | |||
| 683 | if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE) | 689 | if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE) |
| 684 | kvm_update_cpuid(vcpu); | 690 | kvm_update_cpuid(vcpu); |
| 685 | 691 | ||
| @@ -1117,7 +1123,6 @@ static inline u64 get_kernel_ns(void) | |||
| 1117 | { | 1123 | { |
| 1118 | struct timespec ts; | 1124 | struct timespec ts; |
| 1119 | 1125 | ||
| 1120 | WARN_ON(preemptible()); | ||
| 1121 | ktime_get_ts(&ts); | 1126 | ktime_get_ts(&ts); |
| 1122 | monotonic_to_bootbased(&ts); | 1127 | monotonic_to_bootbased(&ts); |
| 1123 | return timespec_to_ns(&ts); | 1128 | return timespec_to_ns(&ts); |
| @@ -4164,7 +4169,8 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, | |||
| 4164 | | (write ? PFERR_WRITE_MASK : 0); | 4169 | | (write ? PFERR_WRITE_MASK : 0); |
| 4165 | 4170 | ||
| 4166 | if (vcpu_match_mmio_gva(vcpu, gva) | 4171 | if (vcpu_match_mmio_gva(vcpu, gva) |
| 4167 | && !permission_fault(vcpu->arch.walk_mmu, vcpu->arch.access, access)) { | 4172 | && !permission_fault(vcpu, vcpu->arch.walk_mmu, |
| 4173 | vcpu->arch.access, access)) { | ||
| 4168 | *gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT | | 4174 | *gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT | |
| 4169 | (gva & (PAGE_SIZE - 1)); | 4175 | (gva & (PAGE_SIZE - 1)); |
| 4170 | trace_vcpu_match_mmio(gva, *gpa, write, false); | 4176 | trace_vcpu_match_mmio(gva, *gpa, write, false); |
diff --git a/arch/x86/syscalls/Makefile b/arch/x86/syscalls/Makefile index f325af26107c..3323c2745248 100644 --- a/arch/x86/syscalls/Makefile +++ b/arch/x86/syscalls/Makefile | |||
| @@ -54,5 +54,7 @@ syshdr-$(CONFIG_X86_64) += syscalls_64.h | |||
| 54 | 54 | ||
| 55 | targets += $(uapisyshdr-y) $(syshdr-y) | 55 | targets += $(uapisyshdr-y) $(syshdr-y) |
| 56 | 56 | ||
| 57 | PHONY += all | ||
| 57 | all: $(addprefix $(uapi)/,$(uapisyshdr-y)) | 58 | all: $(addprefix $(uapi)/,$(uapisyshdr-y)) |
| 58 | all: $(addprefix $(out)/,$(syshdr-y)) | 59 | all: $(addprefix $(out)/,$(syshdr-y)) |
| 60 | @: | ||
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl index 96bc506ac6de..d6b867921612 100644 --- a/arch/x86/syscalls/syscall_32.tbl +++ b/arch/x86/syscalls/syscall_32.tbl | |||
| @@ -359,3 +359,4 @@ | |||
| 359 | 350 i386 finit_module sys_finit_module | 359 | 350 i386 finit_module sys_finit_module |
| 360 | 351 i386 sched_setattr sys_sched_setattr | 360 | 351 i386 sched_setattr sys_sched_setattr |
| 361 | 352 i386 sched_getattr sys_sched_getattr | 361 | 352 i386 sched_getattr sys_sched_getattr |
| 362 | 353 i386 renameat2 sys_renameat2 | ||
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile index e8120346903b..604a37efd4d5 100644 --- a/arch/x86/tools/Makefile +++ b/arch/x86/tools/Makefile | |||
| @@ -40,4 +40,6 @@ $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/ina | |||
| 40 | HOST_EXTRACFLAGS += -I$(srctree)/tools/include | 40 | HOST_EXTRACFLAGS += -I$(srctree)/tools/include |
| 41 | hostprogs-y += relocs | 41 | hostprogs-y += relocs |
| 42 | relocs-objs := relocs_32.o relocs_64.o relocs_common.o | 42 | relocs-objs := relocs_32.o relocs_64.o relocs_common.o |
| 43 | PHONY += relocs | ||
| 43 | relocs: $(obj)/relocs | 44 | relocs: $(obj)/relocs |
| 45 | @: | ||
diff --git a/arch/x86/vdso/vdso-layout.lds.S b/arch/x86/vdso/vdso-layout.lds.S index 2e263f367b13..9df017ab2285 100644 --- a/arch/x86/vdso/vdso-layout.lds.S +++ b/arch/x86/vdso/vdso-layout.lds.S | |||
| @@ -9,12 +9,9 @@ SECTIONS | |||
| 9 | #ifdef BUILD_VDSO32 | 9 | #ifdef BUILD_VDSO32 |
| 10 | #include <asm/vdso32.h> | 10 | #include <asm/vdso32.h> |
| 11 | 11 | ||
| 12 | .hpet_sect : { | 12 | hpet_page = . - VDSO_OFFSET(VDSO_HPET_PAGE); |
| 13 | hpet_page = . - VDSO_OFFSET(VDSO_HPET_PAGE); | ||
| 14 | } :text :hpet_sect | ||
| 15 | 13 | ||
| 16 | .vvar_sect : { | 14 | vvar = . - VDSO_OFFSET(VDSO_VVAR_PAGE); |
| 17 | vvar = . - VDSO_OFFSET(VDSO_VVAR_PAGE); | ||
| 18 | 15 | ||
| 19 | /* Place all vvars at the offsets in asm/vvar.h. */ | 16 | /* Place all vvars at the offsets in asm/vvar.h. */ |
| 20 | #define EMIT_VVAR(name, offset) vvar_ ## name = vvar + offset; | 17 | #define EMIT_VVAR(name, offset) vvar_ ## name = vvar + offset; |
| @@ -22,7 +19,6 @@ SECTIONS | |||
| 22 | #include <asm/vvar.h> | 19 | #include <asm/vvar.h> |
| 23 | #undef __VVAR_KERNEL_LDS | 20 | #undef __VVAR_KERNEL_LDS |
| 24 | #undef EMIT_VVAR | 21 | #undef EMIT_VVAR |
| 25 | } :text :vvar_sect | ||
| 26 | #endif | 22 | #endif |
| 27 | . = SIZEOF_HEADERS; | 23 | . = SIZEOF_HEADERS; |
| 28 | 24 | ||
| @@ -61,7 +57,12 @@ SECTIONS | |||
| 61 | */ | 57 | */ |
| 62 | . = ALIGN(0x100); | 58 | . = ALIGN(0x100); |
| 63 | 59 | ||
| 64 | .text : { *(.text*) } :text =0x90909090 | 60 | .text : { *(.text*) } :text =0x90909090, |
| 61 | |||
| 62 | /* | ||
| 63 | * The comma above works around a bug in gold: | ||
| 64 | * https://sourceware.org/bugzilla/show_bug.cgi?id=16804 | ||
| 65 | */ | ||
| 65 | 66 | ||
| 66 | /DISCARD/ : { | 67 | /DISCARD/ : { |
| 67 | *(.discard) | 68 | *(.discard) |
| @@ -84,8 +85,4 @@ PHDRS | |||
| 84 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 85 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
| 85 | note PT_NOTE FLAGS(4); /* PF_R */ | 86 | note PT_NOTE FLAGS(4); /* PF_R */ |
| 86 | eh_frame_hdr PT_GNU_EH_FRAME; | 87 | eh_frame_hdr PT_GNU_EH_FRAME; |
| 87 | #ifdef BUILD_VDSO32 | ||
| 88 | vvar_sect PT_NULL FLAGS(4); /* PF_R */ | ||
| 89 | hpet_sect PT_NULL FLAGS(4); /* PF_R */ | ||
| 90 | #endif | ||
| 91 | } | 88 | } |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index a18eadd8bb40..7005974c3ff3 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
| @@ -441,10 +441,11 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle) | |||
| 441 | irq_ctx_init(cpu); | 441 | irq_ctx_init(cpu); |
| 442 | #else | 442 | #else |
| 443 | clear_tsk_thread_flag(idle, TIF_FORK); | 443 | clear_tsk_thread_flag(idle, TIF_FORK); |
| 444 | #endif | ||
| 444 | per_cpu(kernel_stack, cpu) = | 445 | per_cpu(kernel_stack, cpu) = |
| 445 | (unsigned long)task_stack_page(idle) - | 446 | (unsigned long)task_stack_page(idle) - |
| 446 | KERNEL_STACK_OFFSET + THREAD_SIZE; | 447 | KERNEL_STACK_OFFSET + THREAD_SIZE; |
| 447 | #endif | 448 | |
| 448 | xen_setup_runstate_info(cpu); | 449 | xen_setup_runstate_info(cpu); |
| 449 | xen_setup_timer(cpu); | 450 | xen_setup_timer(cpu); |
| 450 | xen_init_lock_cpu(cpu); | 451 | xen_init_lock_cpu(cpu); |
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 4d3acc34a998..0ba5f3b967f0 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
| @@ -274,7 +274,7 @@ void __init xen_init_spinlocks(void) | |||
| 274 | printk(KERN_DEBUG "xen: PV spinlocks disabled\n"); | 274 | printk(KERN_DEBUG "xen: PV spinlocks disabled\n"); |
| 275 | return; | 275 | return; |
| 276 | } | 276 | } |
| 277 | 277 | printk(KERN_DEBUG "xen: PV spinlocks enabled\n"); | |
| 278 | pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning); | 278 | pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning); |
| 279 | pv_lock_ops.unlock_kick = xen_unlock_kick; | 279 | pv_lock_ops.unlock_kick = xen_unlock_kick; |
| 280 | } | 280 | } |
| @@ -290,6 +290,9 @@ static __init int xen_init_spinlocks_jump(void) | |||
| 290 | if (!xen_pvspin) | 290 | if (!xen_pvspin) |
| 291 | return 0; | 291 | return 0; |
| 292 | 292 | ||
| 293 | if (!xen_domain()) | ||
| 294 | return 0; | ||
| 295 | |||
| 293 | static_key_slow_inc(¶virt_ticketlocks_enabled); | 296 | static_key_slow_inc(¶virt_ticketlocks_enabled); |
| 294 | return 0; | 297 | return 0; |
| 295 | } | 298 | } |
diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S index 33ca6e42a4ca..fd92a64d748e 100644 --- a/arch/x86/xen/xen-asm_32.S +++ b/arch/x86/xen/xen-asm_32.S | |||
| @@ -75,6 +75,17 @@ ENDPROC(xen_sysexit) | |||
| 75 | * stack state in whatever form its in, we keep things simple by only | 75 | * stack state in whatever form its in, we keep things simple by only |
| 76 | * using a single register which is pushed/popped on the stack. | 76 | * using a single register which is pushed/popped on the stack. |
| 77 | */ | 77 | */ |
| 78 | |||
| 79 | .macro POP_FS | ||
| 80 | 1: | ||
| 81 | popw %fs | ||
| 82 | .pushsection .fixup, "ax" | ||
| 83 | 2: movw $0, (%esp) | ||
| 84 | jmp 1b | ||
| 85 | .popsection | ||
| 86 | _ASM_EXTABLE(1b,2b) | ||
| 87 | .endm | ||
| 88 | |||
| 78 | ENTRY(xen_iret) | 89 | ENTRY(xen_iret) |
| 79 | /* test eflags for special cases */ | 90 | /* test eflags for special cases */ |
| 80 | testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp) | 91 | testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp) |
| @@ -83,15 +94,13 @@ ENTRY(xen_iret) | |||
| 83 | push %eax | 94 | push %eax |
| 84 | ESP_OFFSET=4 # bytes pushed onto stack | 95 | ESP_OFFSET=4 # bytes pushed onto stack |
| 85 | 96 | ||
| 86 | /* | 97 | /* Store vcpu_info pointer for easy access */ |
| 87 | * Store vcpu_info pointer for easy access. Do it this way to | ||
| 88 | * avoid having to reload %fs | ||
| 89 | */ | ||
| 90 | #ifdef CONFIG_SMP | 98 | #ifdef CONFIG_SMP |
| 91 | GET_THREAD_INFO(%eax) | 99 | pushw %fs |
| 92 | movl %ss:TI_cpu(%eax), %eax | 100 | movl $(__KERNEL_PERCPU), %eax |
| 93 | movl %ss:__per_cpu_offset(,%eax,4), %eax | 101 | movl %eax, %fs |
| 94 | mov %ss:xen_vcpu(%eax), %eax | 102 | movl %fs:xen_vcpu, %eax |
| 103 | POP_FS | ||
| 95 | #else | 104 | #else |
| 96 | movl %ss:xen_vcpu, %eax | 105 | movl %ss:xen_vcpu, %eax |
| 97 | #endif | 106 | #endif |
