Implement more of the shared state, namely the PIO emulation area and ioctl(KVM_RUN). Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- arch/x86/kvm/x86.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ebdbd08a840b..d2b43d9b6543 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11567,7 +11567,7 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) trace_kvm_fpu(0); } -int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) +static int kvm_vcpu_ioctl_run_plane(struct kvm_vcpu *vcpu) { struct kvm_queued_exception *ex = &vcpu->arch.exception; struct kvm_run *kvm_run = vcpu->run; @@ -11585,7 +11585,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) kvm_vcpu_srcu_read_lock(vcpu); if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) { - if (!vcpu->wants_to_run) { + if (!vcpu->plane0->wants_to_run) { r = -EINTR; goto out; } @@ -11664,7 +11664,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) WARN_ON_ONCE(vcpu->mmio_needed); } - if (!vcpu->wants_to_run) { + if (!vcpu->plane0->wants_to_run) { r = -EINTR; goto out; } @@ -11687,6 +11687,25 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) return r; } +int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) +{ + int plane_id = READ_ONCE(vcpu->run->plane); + struct kvm_plane *plane = vcpu->kvm->planes[plane_id]; + int r; + + if (plane_id) { + vcpu = kvm_get_plane_vcpu(plane, vcpu->vcpu_id); + mutex_lock_nested(&vcpu->mutex, 1); + } + + r = kvm_vcpu_ioctl_run_plane(vcpu); + + if (plane_id) + mutex_unlock(&vcpu->mutex); + + return r; +} + static void __get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) { if (vcpu->arch.emulate_regs_need_sync_to_vcpu) { @@ -12366,7 +12385,7 @@ static int kvm_init_guest_fpstate(struct kvm_vcpu *vcpu, struct kvm_vcpu *plane0 int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) { - struct page *page; + struct page *page = NULL; int r; vcpu->arch.last_vmentry_cpu = -1; @@ -12390,10 +12409,15 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) r = -ENOMEM; - page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); - if (!page) - goto fail_free_lapic; - vcpu->arch.pio_data = page_address(page); + if (plane->plane) { + page = NULL; + vcpu->arch.pio_data = vcpu->plane0->arch.pio_data; + } else { + page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); + if (!page) + goto fail_free_lapic; + vcpu->arch.pio_data = page_address(page); + } vcpu->arch.mce_banks = kcalloc(KVM_MAX_MCE_BANKS * 4, sizeof(u64), GFP_KERNEL_ACCOUNT); @@ -12451,7 +12475,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane) fail_free_mce_banks: kfree(vcpu->arch.mce_banks); kfree(vcpu->arch.mci_ctl2_banks); - free_page((unsigned long)vcpu->arch.pio_data); + __free_page(page); fail_free_lapic: kvm_free_lapic(vcpu); fail_mmu_destroy: @@ -12500,7 +12524,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) idx = srcu_read_lock(&vcpu->kvm->srcu); kvm_mmu_destroy(vcpu); srcu_read_unlock(&vcpu->kvm->srcu, idx); - free_page((unsigned long)vcpu->arch.pio_data); + if (!vcpu->plane) + free_page((unsigned long)vcpu->arch.pio_data); kvfree(vcpu->arch.cpuid_entries); } -- 2.49.0