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
2443{2443{
2444 bool list_unstable, zapped_root = false;2444 bool list_unstable, zapped_root = false;
2445 2445
2446 lockdep_assert_held_write(&kvm->mmu_lock);
2446 trace_kvm_mmu_prepare_zap_page(sp);2447 trace_kvm_mmu_prepare_zap_page(sp);
2447 ++kvm->stat.mmu_shadow_zapped;2448 ++kvm->stat.mmu_shadow_zapped;
2448 *nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list);2449 *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
4262 if (is_page_fault_stale(vcpu, fault, mmu_seq))4263 if (is_page_fault_stale(vcpu, fault, mmu_seq))
4263 goto out_unlock;4264 goto out_unlock;
4264 4265
4265 r = make_mmu_pages_available(vcpu);4266 if (is_tdp_mmu_fault) {
4266 if (r)
4267 goto out_unlock;
4268
4269 if (is_tdp_mmu_fault)
4270 r = kvm_tdp_mmu_map(vcpu, fault);4267 r = kvm_tdp_mmu_map(vcpu, fault);
4271 else4268 } else {
4269 r = make_mmu_pages_available(vcpu);
4270 if (r)
4271 goto out_unlock;
4272 r = __direct_map(vcpu, fault);4272 r = __direct_map(vcpu, fault);
4273 }
4273 4274
4274out_unlock:4275out_unlock:
4275 if (is_tdp_mmu_fault)4276 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
1091 1091
1092static void nested_svm_triple_fault(struct kvm_vcpu *vcpu)1092static void nested_svm_triple_fault(struct kvm_vcpu *vcpu)
1093{1093{
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);
1094 nested_svm_simple_vmexit(to_svm(vcpu), SVM_EXIT_SHUTDOWN);1100 nested_svm_simple_vmexit(to_svm(vcpu), SVM_EXIT_SHUTDOWN);
1095}1101}
1096 1102
@@ -1125,6 +1131,9 @@ void svm_free_nested(struct vcpu_svm *svm) · 28 unmodified lines
1125 if (!svm->nested.initialized)1131 if (!svm->nested.initialized)
1126 return;1132 return;
1127 1133
1134 if (WARN_ON_ONCE(svm->vmcb != svm->vmcb01.ptr))
1135 svm_switch_vmcb(svm, &svm->vmcb01);
1136
1128 svm_vcpu_free_msrpm(svm->nested.msrpm);1137 svm_vcpu_free_msrpm(svm->nested.msrpm);
1129 svm->nested.msrpm = NULL;1138 svm->nested.msrpm = NULL;
1130 1139
@@ -1143,9 +1152,6 @@ void svm_free_nested(struct vcpu_svm *svm) · 12 unmodified lines
1143 svm->nested.initialized = false;1152 svm->nested.initialized = false;
1144}1153}
1145 1154
1146/*
1147 * Forcibly leave nested mode in order to be able to reset the VCPU later on.
1148 */
1149void svm_leave_nested(struct kvm_vcpu *vcpu)1155void svm_leave_nested(struct kvm_vcpu *vcpu)
1150{1156{
1151 struct vcpu_svm *svm = to_svm(vcpu);1157 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
346 return 0;346 return 0;
347}347}
348 348
349static 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
355static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu)349static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu)
356{350{
357 struct vcpu_svm *svm = to_svm(vcpu);351 struct vcpu_svm *svm = to_svm(vcpu);
@@ -1438,6 +1432,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu) · 1080 unmodified lines
1438 */1432 */
1439 svm_clear_current_vmcb(svm->vmcb);1433 svm_clear_current_vmcb(svm->vmcb);
1440 1434
1435 svm_leave_nested(vcpu);
1441 svm_free_nested(svm);1436 svm_free_nested(svm);
1442 1437
1443 sev_free_vcpu(vcpu);1438 sev_free_vcpu(vcpu);
@@ -3425,15 +3420,6 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) · 1981 unmodified lines
3425 return 0;3420 return 0;
3426 }3421 }
3427 3422
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
3437 if (exit_fastpath != EXIT_FASTPATH_NONE)3423 if (exit_fastpath != EXIT_FASTPATH_NONE)
3438 return 1;3424 return 1;
3439 3425
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
4854 4854
4855static void nested_vmx_triple_fault(struct kvm_vcpu *vcpu)4855static void nested_vmx_triple_fault(struct kvm_vcpu *vcpu)
4856{4856{
4857 kvm_clear_request(KVM_REQ_TRIPLE_FAULT, vcpu);
4857 nested_vmx_vmexit(vcpu, EXIT_REASON_TRIPLE_FAULT, 0, 0);4858 nested_vmx_vmexit(vcpu, EXIT_REASON_TRIPLE_FAULT, 0, 0);
4858}4859}
4859 4860
@@ -6440,9 +6441,6 @@ out: · 1580 unmodified lines
6440 return kvm_state.size;6441 return kvm_state.size;
6441}6442}
6442 6443
6443/*
6444 * Forcibly leave nested mode in order to be able to reset the VCPU later on.
6445 */
6446void vmx_leave_nested(struct kvm_vcpu *vcpu)6444void vmx_leave_nested(struct kvm_vcpu *vcpu)
6447{6445{
6448 if (is_guest_mode(vcpu)) {6446 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
628 ex->payload = payload;628 ex->payload = payload;
629}629}
630 630
631/* Forcibly leave the nested mode in cases like a vCPU reset */
632static void kvm_leave_nested(struct kvm_vcpu *vcpu)
633{
634 kvm_x86_ops.nested_ops->leave_nested(vcpu);
635}
636
631static void kvm_multiple_exception(struct kvm_vcpu *vcpu,637static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
632 unsigned nr, bool has_error, u32 error_code,638 unsigned nr, bool has_error, u32 error_code,
633 bool has_payload, unsigned long payload, bool reinject)639 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
5195 5201
5196 if (events->flags & KVM_VCPUEVENT_VALID_SMM) {5202 if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
5197 if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {5203 if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
5198 kvm_x86_ops.nested_ops->leave_nested(vcpu);5204 kvm_leave_nested(vcpu);
5199 kvm_smm_changed(vcpu, events->smi.smm);5205 kvm_smm_changed(vcpu, events->smi.smm);
5200 }5206 }
5201 5207
@@ -9805,7 +9811,7 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu) · 4603 unmodified lines
9805 9811
9806int kvm_check_nested_events(struct kvm_vcpu *vcpu)9812int kvm_check_nested_events(struct kvm_vcpu *vcpu)
9807{9813{
9808 if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {9814 if (kvm_test_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
9809 kvm_x86_ops.nested_ops->triple_fault(vcpu);9815 kvm_x86_ops.nested_ops->triple_fault(vcpu);
9810 return 1;9816 return 1;
9811 }9817 }
@@ -10560,15 +10566,16 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 748 unmodified lines
10560 r = 0;10566 r = 0;
10561 goto out;10567 goto out;
10562 }10568 }
10563 if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {10569 if (kvm_test_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
10564 if (is_guest_mode(vcpu)) {10570 if (is_guest_mode(vcpu))
10565 kvm_x86_ops.nested_ops->triple_fault(vcpu);10571 kvm_x86_ops.nested_ops->triple_fault(vcpu);
10566 } else {10572
10573 if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
10567 vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN;10574 vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN;
10568 vcpu->mmio_needed = 0;10575 vcpu->mmio_needed = 0;
10569 r = 0;10576 r = 0;
10570 goto out;
10571 }10577 }
10578 goto out;
10572 }10579 }
10573 if (kvm_check_request(KVM_REQ_APF_HALT, vcpu)) {10580 if (kvm_check_request(KVM_REQ_APF_HALT, vcpu)) {
10574 /* Page is swapped out. Do synthetic halt */10581 /* 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
11997 WARN_ON_ONCE(!init_event &&12004 WARN_ON_ONCE(!init_event &&
11998 (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu)));12005 (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu)));
11999 12006
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
12000 kvm_lapic_reset(vcpu, init_event);12016 kvm_lapic_reset(vcpu, init_event);
12001 12017
12018 WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
12002 vcpu->arch.hflags = 0;12019 vcpu->arch.hflags = 0;
12003 12020
12004 vcpu->arch.smi_pending = 0;12021 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
954 return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result);954 return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result);
955}955}
956 956
957static 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
957static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports,965static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports,
958 evtchn_port_t *ports)966 evtchn_port_t *ports)
959{967{
@@ -1042,6 +1050,10 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode, · 82 unmodified lines
1042 *r = -EFAULT;1050 *r = -EFAULT;
1043 goto out;1051 goto out;
1044 }1052 }
1053 if (ports[i] >= max_evtchn_port(vcpu->kvm)) {
1054 *r = -EINVAL;
1055 goto out;
1056 }
1045 }1057 }
1046 1058
1047 if (sched_poll.nr_ports == 1)1059 if (sched_poll.nr_ports == 1)
@@ -1215,6 +1227,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 167 unmodified lines
1215 bool longmode;1227 bool longmode;
1216 u64 input, params[6], r = -ENOSYS;1228 u64 input, params[6], r = -ENOSYS;
1217 bool handled = false;1229 bool handled = false;
1230 u8 cpl;
1218 1231
1219 input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX);1232 input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX);
1220 1233
@@ -1242,9 +1255,17 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 21 unmodified lines
1242 params[5] = (u64)kvm_r9_read(vcpu);1255 params[5] = (u64)kvm_r9_read(vcpu);
1243 }1256 }
1244#endif1257#endif
1258 cpl = static_call(kvm_x86_get_cpl)(vcpu);
1245 trace_kvm_xen_hypercall(input, params[0], params[1], params[2],1259 trace_kvm_xen_hypercall(input, params[0], params[1], params[2],
1246 params[3], params[4], params[5]);1260 params[3], params[4], params[5]);
1247 1261
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
1248 switch (input) {1269 switch (input) {
1249 case __HYPERVISOR_xen_version:1270 case __HYPERVISOR_xen_version:
1250 if (params[0] == XENVER_version && vcpu->kvm->arch.xen.xen_version) {1271 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
1279 if (handled)1300 if (handled)
1280 return kvm_xen_hypercall_set_result(vcpu, r);1301 return kvm_xen_hypercall_set_result(vcpu, r);
1281 1302
1303handle_in_userspace:
1282 vcpu->run->exit_reason = KVM_EXIT_XEN;1304 vcpu->run->exit_reason = KVM_EXIT_XEN;
1283 vcpu->run->xen.type = KVM_EXIT_XEN_HCALL;1305 vcpu->run->xen.type = KVM_EXIT_XEN_HCALL;
1284 vcpu->run->xen.u.hcall.longmode = longmode;1306 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;
1286 vcpu->run->xen.u.hcall.input = input;1308 vcpu->run->xen.u.hcall.input = input;
1287 vcpu->run->xen.u.hcall.params[0] = params[0];1309 vcpu->run->xen.u.hcall.params[0] = params[0];
1288 vcpu->run->xen.u.hcall.params[1] = params[1];1310 vcpu->run->xen.u.hcall.params[1] = params[1];
@@ -1297,14 +1319,6 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 8 unmodified lines
1297 return 0;1319 return 0;
1298}1320}
1299 1321
1300static 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
1308static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port)1322static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port)
1309{1323{
1310 int poll_evtchn = vcpu->arch.xen.poll_evtchn;1324 int poll_evtchn = vcpu->arch.xen.poll_evtchn;
include/linux/kvm_host.h+1−0
@@ -776,6 +776,7 @@ struct kvm { · 775 unmodified lines
776 struct srcu_struct srcu;776 struct srcu_struct srcu;
777 struct srcu_struct irq_srcu;777 struct srcu_struct irq_srcu;
778 pid_t userspace_pid;778 pid_t userspace_pid;
779 bool override_halt_poll_ns;
779 unsigned int max_halt_poll_ns;780 unsigned int max_halt_poll_ns;
780 u32 dirty_ring_size;781 u32 dirty_ring_size;
781 bool vm_bugged;782 bool vm_bugged;
tools/testing/selftests/kvm/.gitignore+1−0
@@ -41,6 +41,7 @@ · 40 unmodified lines
41/x86_64/svm_vmcall_test41/x86_64/svm_vmcall_test
42/x86_64/svm_int_ctl_test42/x86_64/svm_int_ctl_test
43/x86_64/svm_nested_soft_inject_test43/x86_64/svm_nested_soft_inject_test
44/x86_64/svm_nested_shutdown_test
44/x86_64/sync_regs_test45/x86_64/sync_regs_test
45/x86_64/tsc_msrs_test46/x86_64/tsc_msrs_test
46/x86_64/tsc_scaling_sync47/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
101TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test101TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
102TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test102TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
103TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test103TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
104TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
104TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test105TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
105TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync106TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
106TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test107TEST_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
748 uint64_t rflags;748 uint64_t rflags;
749};749};
750 750
751struct 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
751void vm_init_descriptor_tables(struct kvm_vm *vm);764void vm_init_descriptor_tables(struct kvm_vm *vm);
752void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu);765void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu);
753void vm_install_exception_handler(struct kvm_vm *vm, int vector,766void 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
1074 }1074 }
1075}1075}
1076 1076
1077struct 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
1090static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,1077static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr,
1091 int dpl, unsigned short selector)1078 int dpl, unsigned short selector)
1092{1079{
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
15static void l2_guest_code(struct svm_test_data *svm)
16{
17 __asm__ __volatile__("ud2");
18}
19
20static 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
42int 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
3#include "kvm_util.h"3#include "kvm_util.h"
4#include "processor.h"4#include "processor.h"
5#include "vmx.h"5#include "vmx.h"
6#include "svm_util.h"
6 7
7#include <string.h>8#include <string.h>
8#include <sys/ioctl.h>9#include <sys/ioctl.h>
@@ -20,10 +21,11 @@ static void l2_guest_code(void) · 11 unmodified lines
20 : : [port] "d" (ARBITRARY_IO_PORT) : "rax");21 : : [port] "d" (ARBITRARY_IO_PORT) : "rax");
21}22}
22 23
23void l1_guest_code(struct vmx_pages *vmx)
24{
25#define L2_GUEST_STACK_SIZE 6424#define L2_GUEST_STACK_SIZE 64
26 unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];25unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
26
27void l1_guest_code_vmx(struct vmx_pages *vmx)
28{
27 29
28 GUEST_ASSERT(vmx->vmcs_gpa);30 GUEST_ASSERT(vmx->vmcs_gpa);
29 GUEST_ASSERT(prepare_for_vmx_operation(vmx));31 GUEST_ASSERT(prepare_for_vmx_operation(vmx));
@@ -38,24 +40,53 @@ void l1_guest_code(struct vmx_pages *vmx) · 8 unmodified lines
38 GUEST_DONE();40 GUEST_DONE();
39}41}
40 42
43void 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
41int main(void)59int main(void)
42{60{
43 struct kvm_vcpu *vcpu;61 struct kvm_vcpu *vcpu;
44 struct kvm_run *run;62 struct kvm_run *run;
45 struct kvm_vcpu_events events;63 struct kvm_vcpu_events events;
46 vm_vaddr_t vmx_pages_gva;
47 struct ucall uc;64 struct ucall uc;
48 65
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);
50 70
51 TEST_REQUIRE(kvm_has_cap(KVM_CAP_X86_TRIPLE_FAULT_EVENT));71 TEST_REQUIRE(kvm_has_cap(KVM_CAP_X86_TRIPLE_FAULT_EVENT));
52 72
53 vm = vm_create_with_one_vcpu(&vcpu, l1_guest_code);
54 vm_enable_cap(vm, KVM_CAP_X86_TRIPLE_FAULT_EVENT, 1);
55 73
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);
56 run = vcpu->run;89 run = vcpu->run;
57 vcpu_alloc_vmx(vm, &vmx_pages_gva);
58 vcpu_args_set(vcpu, 1, vmx_pages_gva);
59 vcpu_run(vcpu);90 vcpu_run(vcpu);
60 91
61 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,92 TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
@@ -78,13 +109,21 @@ int main(void) · 16 unmodified lines
78 "No triple fault pending");109 "No triple fault pending");
79 vcpu_run(vcpu);110 vcpu_run(vcpu);
80 111
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 }
89 112
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;
90}129}
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
1198 goto out_err_no_arch_destroy_vm;1198 goto out_err_no_arch_destroy_vm;
1199 }1199 }
1200 1200
1201 kvm->max_halt_poll_ns = halt_poll_ns;
1202
1203 r = kvm_arch_init_vm(kvm, type);1201 r = kvm_arch_init_vm(kvm, type);
1204 if (r)1202 if (r)
1205 goto out_err_no_arch_destroy_vm;1203 goto out_err_no_arch_destroy_vm;
@@ -3377,9 +3375,6 @@ static void grow_halt_poll_ns(struct kvm_vcpu *vcpu) · 2171 unmodified lines
3377 if (val < grow_start)3375 if (val < grow_start)
3378 val = grow_start;3376 val = grow_start;
3379 3377
3380 if (val > vcpu->kvm->max_halt_poll_ns)
3381 val = vcpu->kvm->max_halt_poll_ns;
3382
3383 vcpu->halt_poll_ns = val;3378 vcpu->halt_poll_ns = val;
3384out:3379out:
3385 trace_kvm_halt_poll_ns_grow(vcpu->vcpu_id, val, old);3380 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
3483 }3478 }
3484}3479}
3485 3480
3481static 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
3486/*3499/*
3487 * Emulate a vCPU halt condition, e.g. HLT on x86, WFI on arm, etc... If halt3500 * Emulate a vCPU halt condition, e.g. HLT on x86, WFI on arm, etc... If halt
3488 * polling is enabled, busy wait for a short time before blocking to avoid the3501 * 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
3491 */3504 */
3492void kvm_vcpu_halt(struct kvm_vcpu *vcpu)3505void kvm_vcpu_halt(struct kvm_vcpu *vcpu)
3493{3506{
3507 unsigned int max_halt_poll_ns = kvm_vcpu_max_halt_poll_ns(vcpu);
3494 bool halt_poll_allowed = !kvm_arch_no_poll(vcpu);3508 bool halt_poll_allowed = !kvm_arch_no_poll(vcpu);
3495 bool do_halt_poll = halt_poll_allowed && vcpu->halt_poll_ns;
3496 ktime_t start, cur, poll_end;3509 ktime_t start, cur, poll_end;
3497 bool waited = false;3510 bool waited = false;
3511 bool do_halt_poll;
3498 u64 halt_ns;3512 u64 halt_ns;
3499 3513
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
3500 start = cur = poll_end = ktime_get();3519 start = cur = poll_end = ktime_get();
3501 if (do_halt_poll) {3520 if (do_halt_poll) {
3502 ktime_t stop = ktime_add_ns(start, vcpu->halt_poll_ns);3521 ktime_t stop = ktime_add_ns(start, vcpu->halt_poll_ns);
@@ -3535,18 +3554,21 @@ out: · 32 unmodified lines
3535 update_halt_poll_stats(vcpu, start, poll_end, !waited);3554 update_halt_poll_stats(vcpu, start, poll_end, !waited);
3536 3555
3537 if (halt_poll_allowed) {3556 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
3538 if (!vcpu_valid_wakeup(vcpu)) {3560 if (!vcpu_valid_wakeup(vcpu)) {
3539 shrink_halt_poll_ns(vcpu);3561 shrink_halt_poll_ns(vcpu);
3540 } else if (vcpu->kvm->max_halt_poll_ns) {3562 } else if (max_halt_poll_ns) {
3541 if (halt_ns <= vcpu->halt_poll_ns)3563 if (halt_ns <= vcpu->halt_poll_ns)
3542 ;3564 ;
3543 /* we had a long block, shrink polling */3565 /* we had a long block, shrink polling */
3544 else if (vcpu->halt_poll_ns &&3566 else if (vcpu->halt_poll_ns &&
3545 halt_ns > vcpu->kvm->max_halt_poll_ns)3567 halt_ns > max_halt_poll_ns)
3546 shrink_halt_poll_ns(vcpu);3568 shrink_halt_poll_ns(vcpu);
3547 /* we had a short halt and our poll time is too small */3569 /* 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 &&3570 else if (vcpu->halt_poll_ns < max_halt_poll_ns &&
3549 halt_ns < vcpu->kvm->max_halt_poll_ns)3571 halt_ns < max_halt_poll_ns)
3550 grow_halt_poll_ns(vcpu);3572 grow_halt_poll_ns(vcpu);
3551 } else {3573 } else {
3552 vcpu->halt_poll_ns = 0;3574 vcpu->halt_poll_ns = 0;
@@ -4581,6 +4603,16 @@ static int kvm_vm_ioctl_enable_cap_generic(struct kvm *kvm, · 1028 unmodified lines
4581 return -EINVAL;4603 return -EINVAL;
4582 4604
4583 kvm->max_halt_poll_ns = cap->args[0];4605 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
4584 return 0;4616 return 0;
4585 }4617 }
4586 case KVM_CAP_DIRTY_LOG_RING:4618 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
297 if (!gpc->valid || old_uhva != gpc->uhva) {297 if (!gpc->valid || old_uhva != gpc->uhva) {
298 ret = hva_to_pfn_retry(kvm, gpc);298 ret = hva_to_pfn_retry(kvm, gpc);
299 } else {299 } 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;
301 old_pfn = KVM_PFN_ERR_FAULT;306 old_pfn = KVM_PFN_ERR_FAULT;
302 old_khva = NULL;307 old_khva = NULL;
303 ret = 0;308 ret = 0;