Commit fb184c4a authored by Linus Torvalds's avatar Linus Torvalds

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
parents 57511536 ece32a75
...@@ -46,8 +46,7 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu) ...@@ -46,8 +46,7 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
* specification (ARM DEN 0022A). This means all suspend states * specification (ARM DEN 0022A). This means all suspend states
* for KVM will preserve the register state. * for KVM will preserve the register state.
*/ */
kvm_vcpu_halt(vcpu); kvm_vcpu_wfi(vcpu);
kvm_clear_request(KVM_REQ_UNHALT, vcpu);
return PSCI_RET_SUCCESS; return PSCI_RET_SUCCESS;
} }
......
...@@ -246,8 +246,7 @@ static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx, ...@@ -246,8 +246,7 @@ static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
src = &prev->host_state; src = &prev->host_state;
dest = &vmx->loaded_vmcs->host_state; dest = &vmx->loaded_vmcs->host_state;
vmx_set_vmcs_host_state(dest, src->cr3, src->fs_sel, src->gs_sel, vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base);
src->fs_base, src->gs_base);
dest->ldt_sel = src->ldt_sel; dest->ldt_sel = src->ldt_sel;
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
dest->ds_sel = src->ds_sel; dest->ds_sel = src->ds_sel;
...@@ -3056,7 +3055,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu, ...@@ -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) static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
{ {
struct vcpu_vmx *vmx = to_vmx(vcpu); struct vcpu_vmx *vmx = to_vmx(vcpu);
unsigned long cr4; unsigned long cr3, cr4;
bool vm_fail; bool vm_fail;
if (!nested_early_check) if (!nested_early_check)
...@@ -3079,6 +3078,12 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu) ...@@ -3079,6 +3078,12 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
*/ */
vmcs_writel(GUEST_RFLAGS, 0); 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(); cr4 = cr4_read_shadow();
if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) { if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
vmcs_writel(HOST_CR4, cr4); vmcs_writel(HOST_CR4, cr4);
......
...@@ -1080,14 +1080,9 @@ static void pt_guest_exit(struct vcpu_vmx *vmx) ...@@ -1080,14 +1080,9 @@ static void pt_guest_exit(struct vcpu_vmx *vmx)
wrmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl); wrmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl);
} }
void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3, void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
u16 fs_sel, u16 gs_sel,
unsigned long fs_base, unsigned long gs_base) 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 (unlikely(fs_sel != host->fs_sel)) {
if (!(fs_sel & 7)) if (!(fs_sel & 7))
vmcs_write16(HOST_FS_SELECTOR, fs_sel); vmcs_write16(HOST_FS_SELECTOR, fs_sel);
...@@ -1182,9 +1177,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) ...@@ -1182,9 +1177,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
gs_base = segment_base(gs_sel); gs_base = segment_base(gs_sel);
#endif #endif
vmx_set_vmcs_host_state(host_state, __get_current_cr3_fast(), vmx_set_host_fs_gs(host_state, fs_sel, gs_sel, fs_base, gs_base);
fs_sel, gs_sel, fs_base, gs_base);
vmx->guest_state_loaded = true; vmx->guest_state_loaded = true;
} }
...@@ -6791,7 +6784,7 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, ...@@ -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) static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
{ {
struct vcpu_vmx *vmx = to_vmx(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. */ /* Record the guest's net vcpu time for enforced NMI injections. */
if (unlikely(!enable_vnmi && if (unlikely(!enable_vnmi &&
...@@ -6834,6 +6827,19 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu) ...@@ -6834,6 +6827,19 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
vcpu->arch.regs_dirty = 0; 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(); cr4 = cr4_read_shadow();
if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) { if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
vmcs_writel(HOST_CR4, cr4); vmcs_writel(HOST_CR4, cr4);
......
...@@ -374,8 +374,7 @@ int allocate_vpid(void); ...@@ -374,8 +374,7 @@ int allocate_vpid(void);
void free_vpid(int vpid); void free_vpid(int vpid);
void vmx_set_constant_host_state(struct vcpu_vmx *vmx); void vmx_set_constant_host_state(struct vcpu_vmx *vmx);
void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu); void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu);
void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3, void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
u16 fs_sel, u16 gs_sel,
unsigned long fs_base, unsigned long gs_base); unsigned long fs_base, unsigned long gs_base);
int vmx_get_cpl(struct kvm_vcpu *vcpu); int vmx_get_cpl(struct kvm_vcpu *vcpu);
bool vmx_emulation_required(struct kvm_vcpu *vcpu); bool vmx_emulation_required(struct kvm_vcpu *vcpu);
......
...@@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void) ...@@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
{ {
struct kvm_vm *vm; struct kvm_vm *vm;
unsigned int i; unsigned int i;
int ret;
int nr_vcpus = test_args.nr_vcpus; int nr_vcpus = test_args.nr_vcpus;
vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL); 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) ...@@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
ucall_init(vm, NULL); ucall_init(vm, NULL);
test_init_timer_irq(vm); 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 */ /* Make all the test's cmdline args visible to the guest */
sync_global_to_guest(vm, test_args); 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) ...@@ -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, gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
GICD_BASE_GPA, GICR_BASE_GPA); 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, vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
guest_irq_handlers[args.eoi_split][args.level_sensitive]); 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, ...@@ -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); nr_vcpus, nr_vcpus_created);
/* Distributor setup */ /* 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, kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
0, &nr_irqs, true); 0, &nr_irqs, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment