Pull kvm fixes from Paolo Bonzini: "ARM64: - Fix pKVM error path on init, making sure we do not change critical system registers as we're about to fail - Make sure that the host's vector length is at capped by a value common to all CPUs - Fix kvm_has_feat*() handling of "negative" features, as the current code is pretty broken - Promote Joey to the status of official reviewer, while James steps down -- hopefully only temporarly x86: - Fix compilation with KVM_INTEL=KVM_AMD=n - Fix disabling KVM_X86_QUIRK_SLOT_ZAP_ALL when shadow MMU is in use Selftests: - Fix compilation on non-x86 architectures" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: x86/reboot: emergency callbacks are now registered by common KVM code KVM: x86: leave kvm.ko out of the build if no vendor module is requested KVM: x86/mmu: fix KVM_X86_QUIRK_SLOT_ZAP_ALL for shadow MMU KVM: arm64: Fix kvm_has_feat*() handling of negative features KVM: selftests: Fix build on architectures other than x86_64 KVM: arm64: Another reviewer reshuffle KVM: arm64: Constrain the host to the maximum shared SVE VL with pKVM KVM: arm64: Fix __pkvm_init_vcpu cptr_el2 error path
Unified · Split
| @@ -12463,7 +12463,7 @@ F: virt/kvm/* · 12462 unmodified lines | |||
| 12463 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) | 12463 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) |
| 12464 | M: Marc Zyngier <maz@kernel.org> | 12464 | M: Marc Zyngier <maz@kernel.org> |
| 12465 | M: Oliver Upton <oliver.upton@linux.dev> | 12465 | M: Oliver Upton <oliver.upton@linux.dev> |
| 12466 | R: James Morse <james.morse@arm.com> | 12466 | R: Joey Gouly <joey.gouly@arm.com> |
| 12467 | R: Suzuki K Poulose <suzuki.poulose@arm.com> | 12467 | R: Suzuki K Poulose <suzuki.poulose@arm.com> |
| 12468 | R: Zenghui Yu <yuzenghui@huawei.com> | 12468 | R: Zenghui Yu <yuzenghui@huawei.com> |
| 12469 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 12469 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -1441,11 +1441,6 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); · 1440 unmodified lines | |||
| 1441 | sign_extend64(__val, id##_##fld##_WIDTH - 1); \ | 1441 | sign_extend64(__val, id##_##fld##_WIDTH - 1); \ |
| 1442 | }) | 1442 | }) |
| 1443 | 1443 | ||
| 1444 | #define expand_field_sign(id, fld, val) \ | ||
| 1445 | (id##_##fld##_SIGNED ? \ | ||
| 1446 | __expand_field_sign_signed(id, fld, val) : \ | ||
| 1447 | __expand_field_sign_unsigned(id, fld, val)) | ||
| 1448 | |||
| 1449 | #define get_idreg_field_unsigned(kvm, id, fld) \ | 1444 | #define get_idreg_field_unsigned(kvm, id, fld) \ |
| 1450 | ({ \ | 1445 | ({ \ |
| 1451 | u64 __val = kvm_read_vm_id_reg((kvm), SYS_##id); \ | 1446 | u64 __val = kvm_read_vm_id_reg((kvm), SYS_##id); \ |
| @@ -1461,20 +1456,26 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); · 9 unmodified lines | |||
| 1461 | #define get_idreg_field_enum(kvm, id, fld) \ | 1456 | #define get_idreg_field_enum(kvm, id, fld) \ |
| 1462 | get_idreg_field_unsigned(kvm, id, fld) | 1457 | get_idreg_field_unsigned(kvm, id, fld) |
| 1463 | 1458 | ||
| 1464 | #define get_idreg_field(kvm, id, fld) \ | 1459 | #define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ |
| 1460 | (get_idreg_field_signed((kvm), id, fld) op __expand_field_sign_signed(id, fld, limit)) | ||
| 1461 | |||
| 1462 | #define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit) \ | ||
| 1463 | (get_idreg_field_unsigned((kvm), id, fld) op __expand_field_sign_unsigned(id, fld, limit)) | ||
| 1464 | |||
| 1465 | #define kvm_cmp_feat(kvm, id, fld, op, limit) \ | ||
| 1465 | (id##_##fld##_SIGNED ? \ | 1466 | (id##_##fld##_SIGNED ? \ |
| 1466 | get_idreg_field_signed(kvm, id, fld) : \ | 1467 | kvm_cmp_feat_signed(kvm, id, fld, op, limit) : \ |
| 1467 | get_idreg_field_unsigned(kvm, id, fld)) | 1468 | kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)) |
| 1468 | 1469 | ||
| 1469 | #define kvm_has_feat(kvm, id, fld, limit) \ | 1470 | #define kvm_has_feat(kvm, id, fld, limit) \ |
| 1470 | (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit)) | 1471 | kvm_cmp_feat(kvm, id, fld, >=, limit) |
| 1471 | 1472 | ||
| 1472 | #define kvm_has_feat_enum(kvm, id, fld, val) \ | 1473 | #define kvm_has_feat_enum(kvm, id, fld, val) \ |
| 1473 | (get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val)) | 1474 | kvm_cmp_feat_unsigned(kvm, id, fld, ==, val) |
| 1474 | 1475 | ||
| 1475 | #define kvm_has_feat_range(kvm, id, fld, min, max) \ | 1476 | #define kvm_has_feat_range(kvm, id, fld, min, max) \ |
| 1476 | (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \ | 1477 | (kvm_cmp_feat(kvm, id, fld, >=, min) && \ |
| 1477 | get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max)) | 1478 | kvm_cmp_feat(kvm, id, fld, <=, max)) |
| 1478 | 1479 | ||
| 1479 | /* Check for a given level of PAuth support */ | 1480 | /* Check for a given level of PAuth support */ |
| 1480 | #define kvm_has_pauth(k, l) \ | 1481 | #define kvm_has_pauth(k, l) \ |
| @@ -338,7 +338,7 @@ static inline void __hyp_sve_save_host(void) · 337 unmodified lines | |||
| 338 | struct cpu_sve_state *sve_state = *host_data_ptr(sve_state); | 338 | struct cpu_sve_state *sve_state = *host_data_ptr(sve_state); |
| 339 | 339 | ||
| 340 | sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR); | 340 | sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR); |
| 341 | write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); | 341 | write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); |
| 342 | __sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), | 342 | __sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), |
| 343 | &sve_state->fpsr, | 343 | &sve_state->fpsr, |
| 344 | true); | 344 | true); |
| @@ -33,7 +33,7 @@ static void __hyp_sve_save_guest(struct kvm_vcpu *vcpu) · 32 unmodified lines | |||
| 33 | */ | 33 | */ |
| 34 | sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2); | 34 | sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2); |
| 35 | __sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true); | 35 | __sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true); |
| 36 | write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); | 36 | write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static void __hyp_sve_restore_host(void) | 39 | static void __hyp_sve_restore_host(void) |
| @@ -45,10 +45,11 @@ static void __hyp_sve_restore_host(void) · 5 unmodified lines | |||
| 45 | * the host. The layout of the data when saving the sve state depends | 45 | * the host. The layout of the data when saving the sve state depends |
| 46 | * on the VL, so use a consistent (i.e., the maximum) host VL. | 46 | * on the VL, so use a consistent (i.e., the maximum) host VL. |
| 47 | * | 47 | * |
| 48 | * Setting ZCR_EL2 to ZCR_ELx_LEN_MASK sets the effective length | 48 | * Note that this constrains the PE to the maximum shared VL |
| 49 | * supported by the system (or limited at EL3). | 49 | * that was discovered, if we wish to use larger VLs this will |
| 50 | * need to be revisited. | ||
| 50 | */ | 51 | */ |
| 51 | write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); | 52 | write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2); |
| 52 | __sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), | 53 | __sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl), |
| 53 | &sve_state->fpsr, | 54 | &sve_state->fpsr, |
| 54 | true); | 55 | true); |
| @@ -488,7 +489,8 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) · 433 unmodified lines | |||
| 488 | case ESR_ELx_EC_SVE: | 489 | case ESR_ELx_EC_SVE: |
| 489 | cpacr_clear_set(0, CPACR_ELx_ZEN); | 490 | cpacr_clear_set(0, CPACR_ELx_ZEN); |
| 490 | isb(); | 491 | isb(); |
| 491 | sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); | 492 | sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, |
| 493 | SYS_ZCR_EL2); | ||
| 492 | break; | 494 | break; |
| 493 | case ESR_ELx_EC_IABT_LOW: | 495 | case ESR_ELx_EC_IABT_LOW: |
| 494 | case ESR_ELx_EC_DABT_LOW: | 496 | case ESR_ELx_EC_DABT_LOW: |
| @@ -574,12 +574,14 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu, · 573 unmodified lines | |||
| 574 | unlock: | 574 | unlock: |
| 575 | hyp_spin_unlock(&vm_table_lock); | 575 | hyp_spin_unlock(&vm_table_lock); |
| 576 | 576 | ||
| 577 | if (ret) | 577 | if (ret) { |
| 578 | unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu)); | 578 | unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu)); |
| 579 | return ret; | ||
| 580 | } | ||
| 579 | 581 | ||
| 580 | hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu); | 582 | hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu); |
| 581 | 583 | ||
| 582 | return ret; | 584 | return 0; |
| 583 | } | 585 | } |
| 584 | 586 | ||
| 585 | static void | 587 | static void |
| @@ -26,7 +26,7 @@ void __noreturn machine_real_restart(unsigned int type); · 25 unmodified lines | |||
| 26 | #define MRR_APM 1 | 26 | #define MRR_APM 1 |
| 27 | 27 | ||
| 28 | typedef void (cpu_emergency_virt_cb)(void); | 28 | typedef void (cpu_emergency_virt_cb)(void); |
| 29 | #if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD) | 29 | #if IS_ENABLED(CONFIG_KVM_X86) |
| 30 | void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); | 30 | void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); |
| 31 | void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback); | 31 | void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback); |
| 32 | void cpu_emergency_disable_virtualization(void); | 32 | void cpu_emergency_disable_virtualization(void); |
| @@ -34,7 +34,7 @@ void cpu_emergency_disable_virtualization(void); · 1 unmodified line | |||
| 34 | static inline void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) {} | 34 | static inline void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) {} |
| 35 | static inline void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) {} | 35 | static inline void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) {} |
| 36 | static inline void cpu_emergency_disable_virtualization(void) {} | 36 | static inline void cpu_emergency_disable_virtualization(void) {} |
| 37 | #endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */ | 37 | #endif /* CONFIG_KVM_X86 */ |
| 38 | 38 | ||
| 39 | typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); | 39 | typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); |
| 40 | void nmi_shootdown_cpus(nmi_shootdown_cb callback); | 40 | void nmi_shootdown_cpus(nmi_shootdown_cb callback); |
| @@ -530,7 +530,7 @@ static inline void kb_wait(void) · 529 unmodified lines | |||
| 530 | 530 | ||
| 531 | static inline void nmi_shootdown_cpus_on_restart(void); | 531 | static inline void nmi_shootdown_cpus_on_restart(void); |
| 532 | 532 | ||
| 533 | #if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD) | 533 | #if IS_ENABLED(CONFIG_KVM_X86) |
| 534 | /* RCU-protected callback to disable virtualization prior to reboot. */ | 534 | /* RCU-protected callback to disable virtualization prior to reboot. */ |
| 535 | static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback; | 535 | static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback; |
| 536 | 536 | ||
| @@ -600,7 +600,7 @@ static void emergency_reboot_disable_virtualization(void) · 63 unmodified lines | |||
| 600 | } | 600 | } |
| 601 | #else | 601 | #else |
| 602 | static void emergency_reboot_disable_virtualization(void) { } | 602 | static void emergency_reboot_disable_virtualization(void) { } |
| 603 | #endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */ | 603 | #endif /* CONFIG_KVM_X86 */ |
| 604 | 604 | ||
| 605 | void __attribute__((weak)) mach_reboot_fixups(void) | 605 | void __attribute__((weak)) mach_reboot_fixups(void) |
| 606 | { | 606 | { |
| @@ -17,8 +17,8 @@ menuconfig VIRTUALIZATION · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | if VIRTUALIZATION | 18 | if VIRTUALIZATION |
| 19 | 19 | ||
| 20 | config KVM | 20 | config KVM_X86 |
| 21 | tristate "Kernel-based Virtual Machine (KVM) support" | 21 | def_tristate KVM if KVM_INTEL || KVM_AMD |
| 22 | depends on X86_LOCAL_APIC | 22 | depends on X86_LOCAL_APIC |
| 23 | select KVM_COMMON | 23 | select KVM_COMMON |
| 24 | select KVM_GENERIC_MMU_NOTIFIER | 24 | select KVM_GENERIC_MMU_NOTIFIER |
| @@ -44,7 +44,11 @@ config KVM · 19 unmodified lines | |||
| 44 | select HAVE_KVM_PM_NOTIFIER if PM | 44 | select HAVE_KVM_PM_NOTIFIER if PM |
| 45 | select KVM_GENERIC_HARDWARE_ENABLING | 45 | select KVM_GENERIC_HARDWARE_ENABLING |
| 46 | select KVM_GENERIC_PRE_FAULT_MEMORY | 46 | select KVM_GENERIC_PRE_FAULT_MEMORY |
| 47 | select KVM_GENERIC_PRIVATE_MEM if KVM_SW_PROTECTED_VM | ||
| 47 | select KVM_WERROR if WERROR | 48 | select KVM_WERROR if WERROR |
| 49 | |||
| 50 | config KVM | ||
| 51 | tristate "Kernel-based Virtual Machine (KVM) support" | ||
| 48 | help | 52 | help |
| 49 | Support hosting fully virtualized guest machines using hardware | 53 | Support hosting fully virtualized guest machines using hardware |
| 50 | virtualization extensions. You will need a fairly recent | 54 | virtualization extensions. You will need a fairly recent |
| @@ -77,7 +81,6 @@ config KVM_SW_PROTECTED_VM · 26 unmodified lines | |||
| 77 | bool "Enable support for KVM software-protected VMs" | 81 | bool "Enable support for KVM software-protected VMs" |
| 78 | depends on EXPERT | 82 | depends on EXPERT |
| 79 | depends on KVM && X86_64 | 83 | depends on KVM && X86_64 |
| 80 | select KVM_GENERIC_PRIVATE_MEM | ||
| 81 | help | 84 | help |
| 82 | Enable support for KVM software-protected VMs. Currently, software- | 85 | Enable support for KVM software-protected VMs. Currently, software- |
| 83 | protected VMs are purely a development and testing vehicle for | 86 | protected VMs are purely a development and testing vehicle for |
| @@ -32,7 +32,7 @@ kvm-intel-y += vmx/vmx_onhyperv.o vmx/hyperv_evmcs.o · 31 unmodified lines | |||
| 32 | kvm-amd-y += svm/svm_onhyperv.o | 32 | kvm-amd-y += svm/svm_onhyperv.o |
| 33 | endif | 33 | endif |
| 34 | 34 | ||
| 35 | obj-$(CONFIG_KVM) += kvm.o | 35 | obj-$(CONFIG_KVM_X86) += kvm.o |
| 36 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o | 36 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o |
| 37 | obj-$(CONFIG_KVM_AMD) += kvm-amd.o | 37 | obj-$(CONFIG_KVM_AMD) += kvm-amd.o |
| 38 | 38 | ||
| @@ -1884,10 +1884,14 @@ static bool sp_has_gptes(struct kvm_mmu_page *sp) · 1883 unmodified lines | |||
| 1884 | if (is_obsolete_sp((_kvm), (_sp))) { \ | 1884 | if (is_obsolete_sp((_kvm), (_sp))) { \ |
| 1885 | } else | 1885 | } else |
| 1886 | 1886 | ||
| 1887 | #define for_each_gfn_valid_sp_with_gptes(_kvm, _sp, _gfn) \ | 1887 | #define for_each_gfn_valid_sp(_kvm, _sp, _gfn) \ |
| 1888 | for_each_valid_sp(_kvm, _sp, \ | 1888 | for_each_valid_sp(_kvm, _sp, \ |
| 1889 | &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)]) \ | 1889 | &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)]) \ |
| 1890 | if ((_sp)->gfn != (_gfn) || !sp_has_gptes(_sp)) {} else | 1890 | if ((_sp)->gfn != (_gfn)) {} else |
| 1891 | |||
| 1892 | #define for_each_gfn_valid_sp_with_gptes(_kvm, _sp, _gfn) \ | ||
| 1893 | for_each_gfn_valid_sp(_kvm, _sp, _gfn) \ | ||
| 1894 | if (!sp_has_gptes(_sp)) {} else | ||
| 1891 | 1895 | ||
| 1892 | static bool kvm_sync_page_check(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | 1896 | static bool kvm_sync_page_check(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) |
| 1893 | { | 1897 | { |
| @@ -7047,14 +7051,42 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) · 5153 unmodified lines | |||
| 7047 | kvm_mmu_zap_all(kvm); | 7051 | kvm_mmu_zap_all(kvm); |
| 7048 | } | 7052 | } |
| 7049 | 7053 | ||
| 7050 | /* | 7054 | static void kvm_mmu_zap_memslot_pages_and_flush(struct kvm *kvm, |
| 7051 | * Zapping leaf SPTEs with memslot range when a memslot is moved/deleted. | 7055 | struct kvm_memory_slot *slot, |
| 7052 | * | 7056 | bool flush) |
| 7053 | * Zapping non-leaf SPTEs, a.k.a. not-last SPTEs, isn't required, worst | 7057 | { |
| 7054 | * case scenario we'll have unused shadow pages lying around until they | 7058 | LIST_HEAD(invalid_list); |
| 7055 | * are recycled due to age or when the VM is destroyed. | 7059 | unsigned long i; |
| 7056 | */ | 7060 | |
| 7057 | static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *slot) | 7061 | if (list_empty(&kvm->arch.active_mmu_pages)) |
| 7062 | goto out_flush; | ||
| 7063 | |||
| 7064 | /* | ||
| 7065 | * Since accounting information is stored in struct kvm_arch_memory_slot, | ||
| 7066 | * shadow pages deletion (e.g. unaccount_shadowed()) requires that all | ||
| 7067 | * gfns with a shadow page have a corresponding memslot. Do so before | ||
| 7068 | * the memslot goes away. | ||
| 7069 | */ | ||
| 7070 | for (i = 0; i < slot->npages; i++) { | ||
| 7071 | struct kvm_mmu_page *sp; | ||
| 7072 | gfn_t gfn = slot->base_gfn + i; | ||
| 7073 | |||
| 7074 | for_each_gfn_valid_sp(kvm, sp, gfn) | ||
| 7075 | kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); | ||
| 7076 | |||
| 7077 | if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) { | ||
| 7078 | kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush); | ||
| 7079 | flush = false; | ||
| 7080 | cond_resched_rwlock_write(&kvm->mmu_lock); | ||
| 7081 | } | ||
| 7082 | } | ||
| 7083 | |||
| 7084 | out_flush: | ||
| 7085 | kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush); | ||
| 7086 | } | ||
| 7087 | |||
| 7088 | static void kvm_mmu_zap_memslot(struct kvm *kvm, | ||
| 7089 | struct kvm_memory_slot *slot) | ||
| 7058 | { | 7090 | { |
| 7059 | struct kvm_gfn_range range = { | 7091 | struct kvm_gfn_range range = { |
| 7060 | .slot = slot, | 7092 | .slot = slot, |
| @@ -7062,11 +7094,11 @@ static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *s · 1 unmodified line | |||
| 7062 | .end = slot->base_gfn + slot->npages, | 7094 | .end = slot->base_gfn + slot->npages, |
| 7063 | .may_block = true, | 7095 | .may_block = true, |
| 7064 | }; | 7096 | }; |
| 7097 | bool flush; | ||
| 7065 | 7098 | ||
| 7066 | write_lock(&kvm->mmu_lock); | 7099 | write_lock(&kvm->mmu_lock); |
| 7067 | if (kvm_unmap_gfn_range(kvm, &range)) | 7100 | flush = kvm_unmap_gfn_range(kvm, &range); |
| 7068 | kvm_flush_remote_tlbs_memslot(kvm, slot); | 7101 | kvm_mmu_zap_memslot_pages_and_flush(kvm, slot, flush); |
| 7069 | |||
| 7070 | write_unlock(&kvm->mmu_lock); | 7102 | write_unlock(&kvm->mmu_lock); |
| 7071 | } | 7103 | } |
| 7072 | 7104 | ||
| @@ -7082,7 +7114,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, · 9 unmodified lines | |||
| 7082 | if (kvm_memslot_flush_zap_all(kvm)) | 7114 | if (kvm_memslot_flush_zap_all(kvm)) |
| 7083 | kvm_mmu_zap_all_fast(kvm); | 7115 | kvm_mmu_zap_all_fast(kvm); |
| 7084 | else | 7116 | else |
| 7085 | kvm_mmu_zap_memslot_leafs(kvm, slot); | 7117 | kvm_mmu_zap_memslot(kvm, slot); |
| 7086 | } | 7118 | } |
| 7087 | 7119 | ||
| 7088 | void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen) | 7120 | void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen) |
| @@ -169,12 +169,14 @@ int main(int argc, char *argv[]) · 168 unmodified lines | |||
| 169 | case 'i': | 169 | case 'i': |
| 170 | p.nr_iterations = atoi_positive("Number of iterations", optarg); | 170 | p.nr_iterations = atoi_positive("Number of iterations", optarg); |
| 171 | break; | 171 | break; |
| 172 | #ifdef __x86_64__ | ||
| 172 | case 'q': | 173 | case 'q': |
| 173 | p.disable_slot_zap_quirk = true; | 174 | p.disable_slot_zap_quirk = true; |
| 174 | 175 | ||
| 175 | TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & | 176 | TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & |
| 176 | KVM_X86_QUIRK_SLOT_ZAP_ALL); | 177 | KVM_X86_QUIRK_SLOT_ZAP_ALL); |
| 177 | break; | 178 | break; |
| 179 | #endif | ||
| 178 | case 'h': | 180 | case 'h': |
| 179 | default: | 181 | default: |
| 180 | help(argv[0]); | 182 | help(argv[0]); |
| @@ -113,7 +113,9 @@ static_assert(ATOMIC_BOOL_LOCK_FREE == 2, "atomic bool is not lockless"); · 112 unmodified lines | |||
| 113 | static sem_t vcpu_ready; | 113 | static sem_t vcpu_ready; |
| 114 | 114 | ||
| 115 | static bool map_unmap_verify; | 115 | static bool map_unmap_verify; |
| 116 | #ifdef __x86_64__ | ||
| 116 | static bool disable_slot_zap_quirk; | 117 | static bool disable_slot_zap_quirk; |
| 118 | #endif | ||
| 117 | 119 | ||
| 118 | static bool verbose; | 120 | static bool verbose; |
| 119 | #define pr_info_v(...) \ | 121 | #define pr_info_v(...) \ |
| @@ -579,8 +581,10 @@ static bool test_memslot_move_prepare(struct vm_data *data, · 459 unmodified lines | |||
| 579 | uint32_t guest_page_size = data->vm->page_size; | 581 | uint32_t guest_page_size = data->vm->page_size; |
| 580 | uint64_t movesrcgpa, movetestgpa; | 582 | uint64_t movesrcgpa, movetestgpa; |
| 581 | 583 | ||
| 584 | #ifdef __x86_64__ | ||
| 582 | if (disable_slot_zap_quirk) | 585 | if (disable_slot_zap_quirk) |
| 583 | vm_enable_cap(data->vm, KVM_CAP_DISABLE_QUIRKS2, KVM_X86_QUIRK_SLOT_ZAP_ALL); | 586 | vm_enable_cap(data->vm, KVM_CAP_DISABLE_QUIRKS2, KVM_X86_QUIRK_SLOT_ZAP_ALL); |
| 587 | #endif | ||
| 584 | 588 | ||
| 585 | movesrcgpa = vm_slot2gpa(data, data->nslots - 1); | 589 | movesrcgpa = vm_slot2gpa(data, data->nslots - 1); |
| 586 | 590 | ||
| @@ -971,11 +975,13 @@ static bool parse_args(int argc, char *argv[], · 384 unmodified lines | |||
| 971 | case 'd': | 975 | case 'd': |
| 972 | map_unmap_verify = true; | 976 | map_unmap_verify = true; |
| 973 | break; | 977 | break; |
| 978 | #ifdef __x86_64__ | ||
| 974 | case 'q': | 979 | case 'q': |
| 975 | disable_slot_zap_quirk = true; | 980 | disable_slot_zap_quirk = true; |
| 976 | TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & | 981 | TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) & |
| 977 | KVM_X86_QUIRK_SLOT_ZAP_ALL); | 982 | KVM_X86_QUIRK_SLOT_ZAP_ALL); |
| 978 | break; | 983 | break; |
| 984 | #endif | ||
| 979 | case 's': | 985 | case 's': |
| 980 | targs->nslots = atoi_paranoid(optarg); | 986 | targs->nslots = atoi_paranoid(optarg); |
| 981 | if (targs->nslots <= 1 && targs->nslots != -1) { | 987 | if (targs->nslots <= 1 && targs->nslots != -1) { |