History

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Paolo Bonzini: "x86: - Fixes for Xen emulation. While nobody should be enabling it in the kernel (the only public users of the feature are the selftests), the bug effectively allows userspace to read arbitrary memory. - Correctness fixes for nested hypervisors that do not intercept INIT or SHUTDOWN on AMD; the subsequent CPU reset can cause a use-after-free when it disables virtualization extensions. While downgrading the panic to a WARN is quite easy, the full fix is a bit more laborious; there are also tests. This is the bulk of the pull request. - Fix race condition due to incorrect mmu_lock use around make_mmu_pages_available(). Generic: - Obey changes to the kvm.halt_poll_ns module parameter in VMs not using KVM_CAP_HALT_POLL, restoring behavior from before the introduction of the capability" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: Update gfn_to_pfn_cache khva when it moves within the same page KVM: x86/xen: Only do in-kernel acceleration of hypercalls for guest CPL0 KVM: x86/xen: Validate port number in SCHEDOP_poll KVM: x86/mmu: Fix race condition in direct_page_fault KVM: x86: remove exit_int_info warning in svm_handle_exit KVM: selftests: add svm part to triple_fault_test KVM: x86: allow L1 to not intercept triple fault kvm: selftests: add svm nested shutdown test KVM: selftests: move idt_entry to header KVM: x86: forcibly leave nested mode on vCPU reset KVM: x86: add kvm_leave_nested KVM: x86: nSVM: harden svm_free_nested against freeing vmcb02 while still in use KVM: x86: nSVM: leave nested mode on vCPU free KVM: Obey kvm.halt_poll_ns in VMs not using KVM_CAP_HALT_POLL KVM: Avoid re-reading kvm->max_halt_poll_ns during halt-polling KVM: Cap vcpu->halt_poll_ns before halting rather than after

Linus Torvalds committed 3 years ago

Commit bf82d382 parents 30a853c fe08e3615 files · +251 −83Browse files

Unified · Split

15 files
  1. arch/x86/kvm/mmu/mmu.c +7 −6
  2. arch/x86/kvm/svm/nested.c +9 −3
  3. arch/x86/kvm/svm/svm.c +1 −15
  4. arch/x86/kvm/vmx/nested.c +1 −3
  5. arch/x86/kvm/x86.c +23 −6
  6. arch/x86/kvm/xen.c +23 −9
  7. include/linux/kvm_host.h +1 −0
  8. tools/testing/selftests/kvm/.gitignore +1 −0
  9. tools/testing/selftests/kvm/Makefile +1 −0
  10. tools/testing/selftests/kvm/include/x86_64/processor.h +13 −0
  11. tools/testing/selftests/kvm/lib/x86_64/processor.c +0 −13
  12. tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c +67 −0
  13. tools/testing/selftests/kvm/x86_64/triple_fault_event_test.c +56 −17
  14. virt/kvm/kvm_main.c +42 −10
  15. virt/kvm/pfncache.c +6 −1
arch/x86/kvm/mmu/mmu.c+7−6
@@ -2443,6 +2443,7 @@ static bool __kvm_mmu_prepare_zap_page(struct kvm *kvm, · 2442 unmodified lines
24432443 {
24442444 bool list_unstable, zapped_root = false;
24452445
2446+ lockdep_assert_held_write(&kvm->mmu_lock);
24462447 trace_kvm_mmu_prepare_zap_page(sp);
24472448 ++kvm->stat.mmu_shadow_zapped;
24482449 *nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list);
@@ -4262,14 +4263,14 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault · 1813 unmodified lines
42624263 if (is_page_fault_stale(vcpu, fault, mmu_seq))
42634264 goto out_unlock;
42644265
4265− r = make_mmu_pages_available(vcpu);
4266− if (r)
4267− goto out_unlock;
4268−
4269− if (is_tdp_mmu_fault)
4266+ if (is_tdp_mmu_fault) {
42704267 r = kvm_tdp_mmu_map(vcpu, fault);
4271− else
4268+ } else {
4269+ r = make_mmu_pages_available(vcpu);
4270+ if (r)
4271+ goto out_unlock;
42724272 r = __direct_map(vcpu, fault);
4273+ }
42734274
42744275 out_unlock:
42754276 if (is_tdp_mmu_fault)
arch/x86/kvm/svm/nested.c+9−3
@@ -1091,6 +1091,12 @@ int nested_svm_vmexit(struct vcpu_svm *svm) · 1090 unmodified lines
10911091
10921092 static void nested_svm_triple_fault(struct kvm_vcpu *vcpu)
10931093 {
1094+ struct vcpu_svm *svm = to_svm(vcpu);
1095+
1096+ if (!vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_SHUTDOWN))
1097+ return;
1098+
1099+ kvm_clear_request(KVM_REQ_TRIPLE_FAULT, vcpu);
10941100 nested_svm_simple_vmexit(to_svm(vcpu), SVM_EXIT_SHUTDOWN);
10951101 }
10961102
@@ -1125,6 +1131,9 @@ void svm_free_nested(struct vcpu_svm *svm) · 28 unmodified lines
11251131 if (!svm->nested.initialized)
11261132 return;
11271133
1134+ if (WARN_ON_ONCE(svm->vmcb != svm->vmcb01.ptr))
1135+ svm_switch_vmcb(svm, &svm->vmcb01);
1136+
11281137 svm_vcpu_free_msrpm(svm->nested.msrpm);
11291138 svm->nested.msrpm = NULL;
11301139
@@ -1143,9 +1152,6 @@ void svm_free_nested(struct vcpu_svm *svm) · 12 unmodified lines
11431152 svm->nested.initialized = false;
11441153 }
11451154
1146−/*
1147− * Forcibly leave nested mode in order to be able to reset the VCPU later on.
1148− */
11491155 void svm_leave_nested(struct kvm_vcpu *vcpu)
11501156 {
11511157 struct vcpu_svm *svm = to_svm(vcpu);
arch/x86/kvm/svm/svm.c+1−15
@@ -346,12 +346,6 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) · 345 unmodified lines
346346 return 0;
347347 }
348348
349−static int is_external_interrupt(u32 info)
350−{
351− info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
352− return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
353−}
354−
355349 static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu)
356350 {
357351 struct vcpu_svm *svm = to_svm(vcpu);
@@ -1438,6 +1432,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu) · 1080 unmodified lines
14381432 */
14391433 svm_clear_current_vmcb(svm->vmcb);
14401434
1435+ svm_leave_nested(vcpu);
14411436 svm_free_nested(svm);
14421437
14431438 sev_free_vcpu(vcpu);
@@ -3425,15 +3420,6 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) · 1981 unmodified lines
34253420 return 0;
34263421 }
34273422
3428− if (is_external_interrupt(svm->vmcb->control.exit_int_info) &&
3429− exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR &&
3430− exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH &&
3431− exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI)
3432− printk(KERN_ERR "%s: unexpected exit_int_info 0x%x "
3433− "exit_code 0x%x\n",
3434− __func__, svm->vmcb->control.exit_int_info,
3435− exit_code);
3436−
34373423 if (exit_fastpath != EXIT_FASTPATH_NONE)
34383424 return 1;
34393425
arch/x86/kvm/vmx/nested.c+1−3
@@ -4854,6 +4854,7 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, · 4853 unmodified lines
48544854
48554855 static void nested_vmx_triple_fault(struct kvm_vcpu *vcpu)
48564856 {
4857+ kvm_clear_request(KVM_REQ_TRIPLE_FAULT, vcpu);
48574858 nested_vmx_vmexit(vcpu, EXIT_REASON_TRIPLE_FAULT, 0, 0);
48584859 }
48594860
@@ -6440,9 +6441,6 @@ out: · 1580 unmodified lines
64406441 return kvm_state.size;
64416442 }
64426443
6443−/*
6444− * Forcibly leave nested mode in order to be able to reset the VCPU later on.
6445− */
64466444 void vmx_leave_nested(struct kvm_vcpu *vcpu)
64476445 {
64486446 if (is_guest_mode(vcpu)) {
arch/x86/kvm/x86.c+23−6
@@ -628,6 +628,12 @@ static void kvm_queue_exception_vmexit(struct kvm_vcpu *vcpu, unsigned int vecto · 627 unmodified lines
628628 ex->payload = payload;
629629 }
630630
631+/* Forcibly leave the nested mode in cases like a vCPU reset */
632+static void kvm_leave_nested(struct kvm_vcpu *vcpu)
633+{
634+ kvm_x86_ops.nested_ops->leave_nested(vcpu);
635+}
636+
631637 static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
632638 unsigned nr, bool has_error, u32 error_code,
633639 bool has_payload, unsigned long payload, bool reinject)
@@ -5195,7 +5201,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, · 4561 unmodified lines
51955201
51965202 if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
51975203 if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
5198− kvm_x86_ops.nested_ops->leave_nested(vcpu);
5204+ kvm_leave_nested(vcpu);
51995205 kvm_smm_changed(vcpu, events->smi.smm);
52005206 }
52015207
@@ -9805,7 +9811,7 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu) · 4603 unmodified lines
98059811
98069812 int kvm_check_nested_events(struct kvm_vcpu *vcpu)
98079813 {
9808− if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
9814+ if (kvm_test_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
98099815 kvm_x86_ops.nested_ops->triple_fault(vcpu);
98109816 return 1;
98119817 }
@@ -10560,15 +10566,16 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 748 unmodified lines
1056010566 r = 0;
1056110567 goto out;
1056210568 }
10563− if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
10564− if (is_guest_mode(vcpu)) {
10569+ if (kvm_test_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
10570+ if (is_guest_mode(vcpu))
1056510571 kvm_x86_ops.nested_ops->triple_fault(vcpu);
10566− } else {
10572+
10573+ if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
1056710574 vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN;
1056810575 vcpu->mmio_needed = 0;
1056910576 r = 0;
10570− goto out;
1057110577 }
10578+ goto out;
1057210579 }
1057310580 if (kvm_check_request(KVM_REQ_APF_HALT, vcpu)) {
1057410581 /* Page is swapped out. Do synthetic halt */
@@ -11997,8 +12004,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 1422 unmodified lines
1199712004 WARN_ON_ONCE(!init_event &&
1199812005 (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu)));
1199912006
12007+ /*
12008+ * SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's
12009+ * possible to INIT the vCPU while L2 is active. Force the vCPU back
12010+ * into L1 as EFER.SVME is cleared on INIT (along with all other EFER
12011+ * bits), i.e. virtualization is disabled.
12012+ */
12013+ if (is_guest_mode(vcpu))
12014+ kvm_leave_nested(vcpu);
12015+
1200012016 kvm_lapic_reset(vcpu, init_event);
1200112017
12018+ WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
1200212019 vcpu->arch.hflags = 0;
1200312020
1200412021 vcpu->arch.smi_pending = 0;
arch/x86/kvm/xen.c+23−9
@@ -954,6 +954,14 @@ static int kvm_xen_hypercall_complete_userspace(struct kvm_vcpu *vcpu) · 953 unmodified lines
954954 return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result);
955955 }
956956
957+static inline int max_evtchn_port(struct kvm *kvm)
958+{
959+ if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
960+ return EVTCHN_2L_NR_CHANNELS;
961+ else
962+ return COMPAT_EVTCHN_2L_NR_CHANNELS;
963+}
964+
957965 static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports,
958966 evtchn_port_t *ports)
959967 {
@@ -1042,6 +1050,10 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode, · 82 unmodified lines
10421050 *r = -EFAULT;
10431051 goto out;
10441052 }
1053+ if (ports[i] >= max_evtchn_port(vcpu->kvm)) {
1054+ *r = -EINVAL;
1055+ goto out;
1056+ }
10451057 }
10461058
10471059 if (sched_poll.nr_ports == 1)
@@ -1215,6 +1227,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 167 unmodified lines
12151227 bool longmode;
12161228 u64 input, params[6], r = -ENOSYS;
12171229 bool handled = false;
1230+ u8 cpl;
12181231
12191232 input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX);
12201233
@@ -1242,9 +1255,17 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 21 unmodified lines
12421255 params[5] = (u64)kvm_r9_read(vcpu);
12431256 }
12441257 #endif
1258+ cpl = static_call(kvm_x86_get_cpl)(vcpu);
12451259 trace_kvm_xen_hypercall(input, params[0], params[1], params[2],
12461260 params[3], params[4], params[5]);
12471261
1262+ /*
1263+ * Only allow hypercall acceleration for CPL0. The rare hypercalls that
1264+ * are permitted in guest userspace can be handled by the VMM.
1265+ */
1266+ if (unlikely(cpl > 0))
1267+ goto handle_in_userspace;
1268+
12481269 switch (input) {
12491270 case __HYPERVISOR_xen_version:
12501271 if (params[0] == XENVER_version && vcpu->kvm->arch.xen.xen_version) {
@@ -1279,10 +1300,11 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 28 unmodified lines
12791300 if (handled)
12801301 return kvm_xen_hypercall_set_result(vcpu, r);
12811302
1303+handle_in_userspace:
12821304 vcpu->run->exit_reason = KVM_EXIT_XEN;
12831305 vcpu->run->xen.type = KVM_EXIT_XEN_HCALL;
12841306 vcpu->run->xen.u.hcall.longmode = longmode;
1285− vcpu->run->xen.u.hcall.cpl = static_call(kvm_x86_get_cpl)(vcpu);
1307+ vcpu->run->xen.u.hcall.cpl = cpl;
12861308 vcpu->run->xen.u.hcall.input = input;
12871309 vcpu->run->xen.u.hcall.params[0] = params[0];
12881310 vcpu->run->xen.u.hcall.params[1] = params[1];
@@ -1297,14 +1319,6 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 8 unmodified lines
12971319 return 0;
12981320 }
12991321
1300−static inline int max_evtchn_port(struct kvm *kvm)
1301−{
1302− if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
1303− return EVTCHN_2L_NR_CHANNELS;
1304− else
1305− return COMPAT_EVTCHN_2L_NR_CHANNELS;
1306−}
1307−
13081322 static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port)
13091323 {
13101324 int poll_evtchn = vcpu->arch.xen.poll_evtchn;
include/linux/kvm_host.h+1−0
@@ -776,6 +776,7 @@ struct kvm { · 775 unmodified lines
776776 struct srcu_struct srcu;
777777 struct srcu_struct irq_srcu;
778778 pid_t userspace_pid;
779+ bool override_halt_poll_ns;
779780 unsigned int max_halt_poll_ns;
780781 u32 dirty_ring_size;
781782 bool vm_bugged;
tools/testing/selftests/kvm/.gitignore+1−0
@@ -41,6 +41,7 @@ · 40 unmodified lines
4141 /x86_64/svm_vmcall_test
4242 /x86_64/svm_int_ctl_test
4343 /x86_64/svm_nested_soft_inject_test
44+/x86_64/svm_nested_shutdown_test
4445 /x86_64/sync_regs_test
4546 /x86_64/tsc_msrs_test
4647 /x86_64/tsc_scaling_sync
tools/testing/selftests/kvm/Makefile+1−0
@@ -101,6 +101,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/state_test · 100 unmodified lines
101101 TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
102102 TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
103103 TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
104+TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
104105 TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
105106 TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
106107 TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
tools/testing/selftests/kvm/include/x86_64/processor.h+13−0
@@ -748,6 +748,19 @@ struct ex_regs { · 747 unmodified lines
748748 uint64_t rflags;
749749 };
750750
751+struct idt_entry {
752+ uint16_t offset0;
753+ uint16_t selector;
754+ uint16_t ist : 3;
755+ uint16_t : 5;
756+ uint16_t type : 4;
757+ uint16_t : 1;
758+ uint16_t dpl : 2;
759+ uint16_t p : 1;
760+ uint16_t offset1;
761+ uint32_t offset2; uint32_t reserved;
762+};
763+
751764 void vm_init_descriptor_tables(struct kvm_vm *vm);
752765 void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu);
753766 void vm_install_exception_handler(struct kvm_vm *vm, int vector,
tools/testing/selftests/kvm/lib/x86_64/processor.c+0−13
@@ -1074,19 +1074,6 @@ void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits) · 1073 unmodified lines
10741074 }
10751075 }
10761076
1077−struct idt_entry {
1078− uint16_t offset0;
1079− uint16_t selector;
1080− uint16_t ist : 3;
1081− uint16_t : 5;
1082− uint16_t type : 4;
1083− uint16_t : 1;
1084− uint16_t dpl : 2;
1085− uint16_t p : 1;
1086− uint16_t offset1;
1087− uint32_t offset2; uint32_t reserved;
1088−};
1089−
10901077 static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
10911078 int dpl, unsigned short selector)
10921079 {
tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c+67−0
@@ -0,0 +1,67 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * svm_nested_shutdown_test
4+ *
5+ * Copyright (C) 2022, Red Hat, Inc.
6+ *
7+ * Nested SVM testing: test that unintercepted shutdown in L2 doesn't crash the host
8+ */
9+
10+#include "test_util.h"
11+#include "kvm_util.h"
12+#include "processor.h"
13+#include "svm_util.h"
14+
15+static void l2_guest_code(struct svm_test_data *svm)
16+{
17+ __asm__ __volatile__("ud2");
18+}
19+
20+static void l1_guest_code(struct svm_test_data *svm, struct idt_entry *idt)
21+{
22+ #define L2_GUEST_STACK_SIZE 64
23+ unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
24+ struct vmcb *vmcb = svm->vmcb;
25+
26+ generic_svm_setup(svm, l2_guest_code,
27+ &l2_guest_stack[L2_GUEST_STACK_SIZE]);
28+
29+ vmcb->control.intercept &= ~(BIT(INTERCEPT_SHUTDOWN));
30+
31+ idt[6].p = 0; // #UD is intercepted but its injection will cause #NP
32+ idt[11].p = 0; // #NP is not intercepted and will cause another
33+ // #NP that will be converted to #DF
34+ idt[8].p = 0; // #DF will cause #NP which will cause SHUTDOWN
35+
36+ run_guest(vmcb, svm->vmcb_gpa);
37+
38+ /* should not reach here */
39+ GUEST_ASSERT(0);
40+}
41+
42+int main(int argc, char *argv[])
43+{
44+ struct kvm_vcpu *vcpu;
45+ struct kvm_run *run;
46+ vm_vaddr_t svm_gva;
47+ struct kvm_vm *vm;
48+
49+ TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));
50+
51+ vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
52+ vm_init_descriptor_tables(vm);
53+ vcpu_init_descriptor_tables(vcpu);
54+
55+ vcpu_alloc_svm(vm, &svm_gva);
56+
57+ vcpu_args_set(vcpu, 2, svm_gva, vm->idt);
58+ run = vcpu->run;
59+
60+ vcpu_run(vcpu);
61+ TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN,
62+ "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s)\n",
63+ run->exit_reason,
64+ exit_reason_str(run->exit_reason));
65+
66+ kvm_vm_free(vm);
67+}
tools/testing/selftests/kvm/x86_64/triple_fault_event_test.c+56−17
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #include "kvm_util.h"
44 #include "processor.h"
55 #include "vmx.h"
6+#include "svm_util.h"
67
78 #include <string.h>
89 #include <sys/ioctl.h>
@@ -20,10 +21,11 @@ static void l2_guest_code(void) · 11 unmodified lines
2021 : : [port] "d" (ARBITRARY_IO_PORT) : "rax");
2122 }
2223
23−void l1_guest_code(struct vmx_pages *vmx)
24−{
2524 #define L2_GUEST_STACK_SIZE 64
26− unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
25+unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
26+
27+void l1_guest_code_vmx(struct vmx_pages *vmx)
28+{
2729
2830 GUEST_ASSERT(vmx->vmcs_gpa);
2931 GUEST_ASSERT(prepare_for_vmx_operation(vmx));
@@ -38,24 +40,53 @@ void l1_guest_code(struct vmx_pages *vmx) · 8 unmodified lines
3840 GUEST_DONE();
3941 }
4042
43+void l1_guest_code_svm(struct svm_test_data *svm)
44+{
45+ struct vmcb *vmcb = svm->vmcb;
46+
47+ generic_svm_setup(svm, l2_guest_code,
48+ &l2_guest_stack[L2_GUEST_STACK_SIZE]);
49+
50+ /* don't intercept shutdown to test the case of SVM allowing to do so */
51+ vmcb->control.intercept &= ~(BIT(INTERCEPT_SHUTDOWN));
52+
53+ run_guest(vmcb, svm->vmcb_gpa);
54+
55+ /* should not reach here, L1 should crash */
56+ GUEST_ASSERT(0);
57+}
58+
4159 int main(void)
4260 {
4361 struct kvm_vcpu *vcpu;
4462 struct kvm_run *run;
4563 struct kvm_vcpu_events events;
46− vm_vaddr_t vmx_pages_gva;
4764 struct ucall uc;
4865
49− TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX));
66+ bool has_vmx = kvm_cpu_has(X86_FEATURE_VMX);
67+ bool has_svm = kvm_cpu_has(X86_FEATURE_SVM);
68+
69+ TEST_REQUIRE(has_vmx || has_svm);
5070
5171 TEST_REQUIRE(kvm_has_cap(KVM_CAP_X86_TRIPLE_FAULT_EVENT));
5272
53− vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
54− vm_enable_cap(vm, KVM_CAP_X86_TRIPLE_FAULT_EVENT, 1);
5573
74+ if (has_vmx) {
75+ vm_vaddr_t vmx_pages_gva;
76+
77+ vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code_vmx);
78+ vcpu_alloc_vmx(vm, &vmx_pages_gva);
79+ vcpu_args_set(vcpu, 1, vmx_pages_gva);
80+ } else {
81+ vm_vaddr_t svm_gva;
82+
83+ vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code_svm);
84+ vcpu_alloc_svm(vm, &svm_gva);
85+ vcpu_args_set(vcpu, 1, svm_gva);
86+ }
87+
88+ vm_enable_cap(vm, KVM_CAP_X86_TRIPLE_FAULT_EVENT, 1);
5689 run = vcpu->run;
57− vcpu_alloc_vmx(vm, &vmx_pages_gva);
58− vcpu_args_set(vcpu, 1, vmx_pages_gva);
5990 vcpu_run(vcpu);
6091
6192 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
@@ -78,13 +109,21 @@ int main(void) · 16 unmodified lines
78109 "No triple fault pending");
79110 vcpu_run(vcpu);
80111
81− switch (get_ucall(vcpu, &uc)) {
82− case UCALL_DONE:
83− break;
84− case UCALL_ABORT:
85− REPORT_GUEST_ASSERT(uc);
86− default:
87− TEST_FAIL("Unexpected ucall: %lu", uc.cmd);
88− }
89112
113+ if (has_svm) {
114+ TEST_ASSERT(run->exit_reason == KVM_EXIT_SHUTDOWN,
115+ "Got exit_reason other than KVM_EXIT_SHUTDOWN: %u (%s)\n",
116+ run->exit_reason,
117+ exit_reason_str(run->exit_reason));
118+ } else {
119+ switch (get_ucall(vcpu, &uc)) {
120+ case UCALL_DONE:
121+ break;
122+ case UCALL_ABORT:
123+ REPORT_GUEST_ASSERT(uc);
124+ default:
125+ TEST_FAIL("Unexpected ucall: %lu", uc.cmd);
126+ }
127+ }
128+ return 0;
90129 }
virt/kvm/kvm_main.c+42−10
@@ -1198,8 +1198,6 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname) · 1197 unmodified lines
11981198 goto out_err_no_arch_destroy_vm;
11991199 }
12001200
1201− kvm->max_halt_poll_ns = halt_poll_ns;
1202−
12031201 r = kvm_arch_init_vm(kvm, type);
12041202 if (r)
12051203 goto out_err_no_arch_destroy_vm;
@@ -3377,9 +3375,6 @@ static void grow_halt_poll_ns(struct kvm_vcpu *vcpu) · 2171 unmodified lines
33773375 if (val < grow_start)
33783376 val = grow_start;
33793377
3380− if (val > vcpu->kvm->max_halt_poll_ns)
3381− val = vcpu->kvm->max_halt_poll_ns;
3382−
33833378 vcpu->halt_poll_ns = val;
33843379 out:
33853380 trace_kvm_halt_poll_ns_grow(vcpu->vcpu_id, val, old);
@@ -3483,6 +3478,24 @@ static inline void update_halt_poll_stats(struct kvm_vcpu *vcpu, ktime_t start, · 97 unmodified lines
34833478 }
34843479 }
34853480
3481+static unsigned int kvm_vcpu_max_halt_poll_ns(struct kvm_vcpu *vcpu)
3482+{
3483+ struct kvm *kvm = vcpu->kvm;
3484+
3485+ if (kvm->override_halt_poll_ns) {
3486+ /*
3487+ * Ensure kvm->max_halt_poll_ns is not read before
3488+ * kvm->override_halt_poll_ns.
3489+ *
3490+ * Pairs with the smp_wmb() when enabling KVM_CAP_HALT_POLL.
3491+ */
3492+ smp_rmb();
3493+ return READ_ONCE(kvm->max_halt_poll_ns);
3494+ }
3495+
3496+ return READ_ONCE(halt_poll_ns);
3497+}
3498+
34863499 /*
34873500 * Emulate a vCPU halt condition, e.g. HLT on x86, WFI on arm, etc... If halt
34883501 * polling is enabled, busy wait for a short time before blocking to avoid the
@@ -3491,12 +3504,18 @@ static inline void update_halt_poll_stats(struct kvm_vcpu *vcpu, ktime_t start, · 2 unmodified lines
34913504 */
34923505 void kvm_vcpu_halt(struct kvm_vcpu *vcpu)
34933506 {
3507+ unsigned int max_halt_poll_ns = kvm_vcpu_max_halt_poll_ns(vcpu);
34943508 bool halt_poll_allowed = !kvm_arch_no_poll(vcpu);
3495− bool do_halt_poll = halt_poll_allowed && vcpu->halt_poll_ns;
34963509 ktime_t start, cur, poll_end;
34973510 bool waited = false;
3511+ bool do_halt_poll;
34983512 u64 halt_ns;
34993513
3514+ if (vcpu->halt_poll_ns > max_halt_poll_ns)
3515+ vcpu->halt_poll_ns = max_halt_poll_ns;
3516+
3517+ do_halt_poll = halt_poll_allowed && vcpu->halt_poll_ns;
3518+
35003519 start = cur = poll_end = ktime_get();
35013520 if (do_halt_poll) {
35023521 ktime_t stop = ktime_add_ns(start, vcpu->halt_poll_ns);
@@ -3535,18 +3554,21 @@ out: · 32 unmodified lines
35353554 update_halt_poll_stats(vcpu, start, poll_end, !waited);
35363555
35373556 if (halt_poll_allowed) {
3557+ /* Recompute the max halt poll time in case it changed. */
3558+ max_halt_poll_ns = kvm_vcpu_max_halt_poll_ns(vcpu);
3559+
35383560 if (!vcpu_valid_wakeup(vcpu)) {
35393561 shrink_halt_poll_ns(vcpu);
3540− } else if (vcpu->kvm->max_halt_poll_ns) {
3562+ } else if (max_halt_poll_ns) {
35413563 if (halt_ns <= vcpu->halt_poll_ns)
35423564 ;
35433565 /* we had a long block, shrink polling */
35443566 else if (vcpu->halt_poll_ns &&
3545− halt_ns > vcpu->kvm->max_halt_poll_ns)
3567+ halt_ns > max_halt_poll_ns)
35463568 shrink_halt_poll_ns(vcpu);
35473569 /* we had a short halt and our poll time is too small */
3548− else if (vcpu->halt_poll_ns < vcpu->kvm->max_halt_poll_ns &&
3549− halt_ns < vcpu->kvm->max_halt_poll_ns)
3570+ else if (vcpu->halt_poll_ns < max_halt_poll_ns &&
3571+ halt_ns < max_halt_poll_ns)
35503572 grow_halt_poll_ns(vcpu);
35513573 } else {
35523574 vcpu->halt_poll_ns = 0;
@@ -4581,6 +4603,16 @@ static int kvm_vm_ioctl_enable_cap_generic(struct kvm *kvm, · 1028 unmodified lines
45814603 return -EINVAL;
45824604
45834605 kvm->max_halt_poll_ns = cap->args[0];
4606+
4607+ /*
4608+ * Ensure kvm->override_halt_poll_ns does not become visible
4609+ * before kvm->max_halt_poll_ns.
4610+ *
4611+ * Pairs with the smp_rmb() in kvm_vcpu_max_halt_poll_ns().
4612+ */
4613+ smp_wmb();
4614+ kvm->override_halt_poll_ns = true;
4615+
45844616 return 0;
45854617 }
45864618 case KVM_CAP_DIRTY_LOG_RING:
virt/kvm/pfncache.c+6−1
@@ -297,7 +297,12 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc, · 296 unmodified lines
297297 if (!gpc->valid || old_uhva != gpc->uhva) {
298298 ret = hva_to_pfn_retry(kvm, gpc);
299299 } else {
300− /* If the HVA→PFN mapping was already valid, don't unmap it. */
300+ /*
301+ * If the HVA→PFN mapping was already valid, don't unmap it.
302+ * But do update gpc->khva because the offset within the page
303+ * may have changed.
304+ */
305+ gpc->khva = old_khva + page_offset;
301306 old_pfn = KVM_PFN_ERR_FAULT;
302307 old_khva = NULL;
303308 ret = 0;