The bigger part of the change is a revert for x86 hosts. Here the
second patch was supposed to fix the first, but in reality it was just as broken, so both have to go. x86 host: * Revert incorrect assumption that cr3 changes come with preempt notifier callbacks (they don't when static branches are changed, for example) ARM host: * Correctly synchronise PMR and co on PSCI CPU_SUSPEND * Skip tests that depend on GICv3 when the HW isn't available -----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmIeGnUUHHBib256aW5p QHJlZGhhdC5jb20ACgkQv/vSX3jHroMCYgf9GPVUOQUbHVxVqvKB1ABnY3ZIZuS3 +/XLgVifSmXb2sPQmcKIPk7eQkxlzpnVdbznJO5qFMtVKRv/ppj+/ly2wwF8l+rR m1XvyYo2sukK5vTpBrQiRm3aWY7vpx0ds4DStLnrnBuPF/U7x6WlHSL/BqXaNcSJ e+SXd/UFhkg7dEQaU3eqXyf2/mMfR2ZLdUb4v+/UiV7kfzzvRqNERd8HUoVk2FcM VYBr07ChaV4XB/dZsCDVSz2Z7f7rH3sMMW82ZHKjuFUEW4Dij9NiX2ycaeRvkSLG tnliTuROCY2bOQeIVCTHf5XqCAAm7sA1AoClFaUy30+UW9s9j45NuhUQbA== =nuHK -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm Pull kvm fixes from Paolo Bonzini: "The bigger part of the change is a revert for x86 hosts. Here the second patch was supposed to fix the first, but in reality it was just as broken, so both have to go. x86 host: - Revert incorrect assumption that cr3 changes come with preempt notifier callbacks (they don't when static branches are changed, for example) ARM host: - Correctly synchronise PMR and co on PSCI CPU_SUSPEND - Skip tests that depend on GICv3 when the HW isn't available" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: selftests: aarch64: Skip tests if we can't create a vgic-v3 Revert "KVM: VMX: Save HOST_CR3 in vmx_prepare_switch_to_guest()" Revert "KVM: VMX: Save HOST_CR3 in vmx_set_host_fs_gs()" KVM: arm64: Don't miss pending interrupts for suspended vCPU
This commit is contained in:
commit
fb184c4af9
@ -46,8 +46,7 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
|
||||
* specification (ARM DEN 0022A). This means all suspend states
|
||||
* for KVM will preserve the register state.
|
||||
*/
|
||||
kvm_vcpu_halt(vcpu);
|
||||
kvm_clear_request(KVM_REQ_UNHALT, vcpu);
|
||||
kvm_vcpu_wfi(vcpu);
|
||||
|
||||
return PSCI_RET_SUCCESS;
|
||||
}
|
||||
|
@ -246,8 +246,7 @@ static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
|
||||
src = &prev->host_state;
|
||||
dest = &vmx->loaded_vmcs->host_state;
|
||||
|
||||
vmx_set_vmcs_host_state(dest, src->cr3, src->fs_sel, src->gs_sel,
|
||||
src->fs_base, src->gs_base);
|
||||
vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base);
|
||||
dest->ldt_sel = src->ldt_sel;
|
||||
#ifdef CONFIG_X86_64
|
||||
dest->ds_sel = src->ds_sel;
|
||||
@ -3056,7 +3055,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
|
||||
static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
unsigned long cr4;
|
||||
unsigned long cr3, cr4;
|
||||
bool vm_fail;
|
||||
|
||||
if (!nested_early_check)
|
||||
@ -3079,6 +3078,12 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
vmcs_writel(GUEST_RFLAGS, 0);
|
||||
|
||||
cr3 = __get_current_cr3_fast();
|
||||
if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
|
||||
vmcs_writel(HOST_CR3, cr3);
|
||||
vmx->loaded_vmcs->host_state.cr3 = cr3;
|
||||
}
|
||||
|
||||
cr4 = cr4_read_shadow();
|
||||
if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
|
||||
vmcs_writel(HOST_CR4, cr4);
|
||||
|
@ -1080,14 +1080,9 @@ static void pt_guest_exit(struct vcpu_vmx *vmx)
|
||||
wrmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl);
|
||||
}
|
||||
|
||||
void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3,
|
||||
u16 fs_sel, u16 gs_sel,
|
||||
unsigned long fs_base, unsigned long gs_base)
|
||||
void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
|
||||
unsigned long fs_base, unsigned long gs_base)
|
||||
{
|
||||
if (unlikely(cr3 != host->cr3)) {
|
||||
vmcs_writel(HOST_CR3, cr3);
|
||||
host->cr3 = cr3;
|
||||
}
|
||||
if (unlikely(fs_sel != host->fs_sel)) {
|
||||
if (!(fs_sel & 7))
|
||||
vmcs_write16(HOST_FS_SELECTOR, fs_sel);
|
||||
@ -1182,9 +1177,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
|
||||
gs_base = segment_base(gs_sel);
|
||||
#endif
|
||||
|
||||
vmx_set_vmcs_host_state(host_state, __get_current_cr3_fast(),
|
||||
fs_sel, gs_sel, fs_base, gs_base);
|
||||
|
||||
vmx_set_host_fs_gs(host_state, fs_sel, gs_sel, fs_base, gs_base);
|
||||
vmx->guest_state_loaded = true;
|
||||
}
|
||||
|
||||
@ -6791,7 +6784,7 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
|
||||
static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
unsigned long cr4;
|
||||
unsigned long cr3, cr4;
|
||||
|
||||
/* Record the guest's net vcpu time for enforced NMI injections. */
|
||||
if (unlikely(!enable_vnmi &&
|
||||
@ -6834,6 +6827,19 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||
vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
|
||||
vcpu->arch.regs_dirty = 0;
|
||||
|
||||
/*
|
||||
* Refresh vmcs.HOST_CR3 if necessary. This must be done immediately
|
||||
* prior to VM-Enter, as the kernel may load a new ASID (PCID) any time
|
||||
* it switches back to the current->mm, which can occur in KVM context
|
||||
* when switching to a temporary mm to patch kernel code, e.g. if KVM
|
||||
* toggles a static key while handling a VM-Exit.
|
||||
*/
|
||||
cr3 = __get_current_cr3_fast();
|
||||
if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
|
||||
vmcs_writel(HOST_CR3, cr3);
|
||||
vmx->loaded_vmcs->host_state.cr3 = cr3;
|
||||
}
|
||||
|
||||
cr4 = cr4_read_shadow();
|
||||
if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
|
||||
vmcs_writel(HOST_CR4, cr4);
|
||||
|
@ -374,9 +374,8 @@ int allocate_vpid(void);
|
||||
void free_vpid(int vpid);
|
||||
void vmx_set_constant_host_state(struct vcpu_vmx *vmx);
|
||||
void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu);
|
||||
void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3,
|
||||
u16 fs_sel, u16 gs_sel,
|
||||
unsigned long fs_base, unsigned long gs_base);
|
||||
void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
|
||||
unsigned long fs_base, unsigned long gs_base);
|
||||
int vmx_get_cpl(struct kvm_vcpu *vcpu);
|
||||
bool vmx_emulation_required(struct kvm_vcpu *vcpu);
|
||||
unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu);
|
||||
|
@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
|
||||
{
|
||||
struct kvm_vm *vm;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
int nr_vcpus = test_args.nr_vcpus;
|
||||
|
||||
vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
|
||||
@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
|
||||
|
||||
ucall_init(vm, NULL);
|
||||
test_init_timer_irq(vm);
|
||||
vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
|
||||
ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
|
||||
if (ret < 0) {
|
||||
print_skip("Failed to create vgic-v3");
|
||||
exit(KSFT_SKIP);
|
||||
}
|
||||
|
||||
/* Make all the test's cmdline args visible to the guest */
|
||||
sync_global_to_guest(vm, test_args);
|
||||
|
@ -761,6 +761,10 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
|
||||
|
||||
gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
|
||||
GICD_BASE_GPA, GICR_BASE_GPA);
|
||||
if (gic_fd < 0) {
|
||||
print_skip("Failed to create vgic-v3, skipping");
|
||||
exit(KSFT_SKIP);
|
||||
}
|
||||
|
||||
vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
|
||||
guest_irq_handlers[args.eoi_split][args.level_sensitive]);
|
||||
|
@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
|
||||
nr_vcpus, nr_vcpus_created);
|
||||
|
||||
/* Distributor setup */
|
||||
gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
|
||||
if (_kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3,
|
||||
false, &gic_fd) != 0)
|
||||
return -1;
|
||||
|
||||
kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
|
||||
0, &nr_irqs, true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user