All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sriram Nambakam <snambakam@linux.microsoft.com>
To: kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [RFC PATCH v1 42/42] kvm: planes: reconcile core plane state, UAPI and hypercall exit
Date: Wed,  5 Aug 2026 04:03:24 -0700	[thread overview]
Message-ID: <20260805110324.25067-43-snambakam@linux.microsoft.com> (raw)
In-Reply-To: <20260805110324.25067-1-snambakam@linux.microsoft.com>

Align the generic plane core and its userspace ABI with vm-planes-merged:
the kvm_vcpu_common/kvm_plane layout and helpers, the KVM_CAP_PLANES /
KVM_EXIT_PLANE_EVENT definitions and documentation, and the x86 handling
that exits VM-plane and VBS hypercalls to userspace. These deltas came
from the integration branch's merge-commit conflict resolutions.
---
 Documentation/virt/kvm/api.rst | 35 +++++++-------
 arch/x86/kvm/svm/sev.c         |  5 +-
 arch/x86/kvm/x86.c             | 86 ++++++++++------------------------
 include/linux/kvm_host.h       |  8 ++--
 include/uapi/linux/kvm.h       | 23 +--------
 virt/kvm/kvm_main.c            | 86 +++++++++++++++-------------------
 6 files changed, 86 insertions(+), 157 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index c6b109fa8945..269be00c8dcf 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -9101,27 +9101,20 @@ helpful if user space wants to emulate instructions which are not
 This capability can be enabled dynamically even if VCPUs were already
 created and are running.
 
-hpage_2g module parameter is not set to 1, -EINVAL is returned.
-
-7.47 KVM_CAP_PLANES_FPU
------------------------
-
-:Architectures: x86
-:Parameters: arg[0] is 0 if each vCPU plane has a separate FPU,
-             1 if the FPU is shared
-:Type: vm
+7.47 KVM_CAP_S390_HPAGE_2G
+--------------------------
 
-When enabled, such as KVM_SET_XSAVE or KVM_SET_FPU *are* available for
-vCPU on all planes, but they will read and write the same data that is presented
-to other planes.  Note that KVM_GET/SET_XSAVE also allows access to some
-registers that are *not* part of FPU state; right now this is just PKRU.
-Those are never shared.
+:Architectures: s390
+:Parameters: none
+:Returns: 0 on success; -EINVAL if hpage_2g module parameter was not set,
+          cmma is enabled, or the VM has the KVM_VM_S390_UCONTROL
+          flag set; -EBUSY if vCPUs were already created for the VM.
 
-KVM_CAP_PLANES_FPU is experimental; userspace must *not* assume that
-KVM_CAP_PLANES_FPU is present on x86 for *any* VM type and different
-VM types may or may not allow enabling KVM_CAP_PLANES_FPU.  Like for other
-capabilities, KVM_CAP_PLANES_FPU can be queried on the VM file descriptor;
-KVM_CHECK_EXTENSION returns 1 if it is possible to enable shared FPU mode.
+With this capability the KVM support for memory backing with 2g pages
+through hugetlbfs can be enabled for a VM. After the capability is
+enabled, cmma can't be enabled anymore and pfmfi and the storage key
+interpretation are disabled. If cmma has already been enabled or the
+hpage_2g module parameter is not set to 1, -EINVAL is returned.
 
 8. Other capabilities.
 ======================
@@ -9674,6 +9667,10 @@ check for this capability on the VM file descriptor.
 When called on the system file descriptor, KVM returns the highest
 value supported on any machine type.
 
+When called on a plane file descriptor, KVM returns 0, because a
+plane cannot host planes of its own.  Other capabilities are
+forwarded to the plane's parent VM.
+
 8.47 KVM_CAP_S390_VSIE_ESAMODE
 ------------------------------
 
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index b9b0bbb72394..b94de3b8967a 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -4488,7 +4488,7 @@ static void sev_get_apic_ids(struct vcpu_svm *svm)
 	desc->num_entries = n;
 	kvm_for_each_vcpu(i, loop_vcpu, kvm) {
 		/*TODO: is this possible? */
-		if (i > n)
+		if (i >= n)
 			break;
 
 		desc->apic_ids[i] = loop_vcpu->vcpu_id;
@@ -4713,6 +4713,9 @@ static bool is_snp_only_vmgexit(u64 exit_code)
 	case SVM_VMGEXIT_GUEST_REQUEST:
 	case SVM_VMGEXIT_EXT_GUEST_REQUEST:
 	case SVM_VMGEXIT_PSC:
+	case SVM_VMGEXIT_HVDB_PAGE:
+	case SVM_VMGEXIT_HV_IPI:
+	case SVM_VMGEXIT_SNP_RUN_VMPL:
 		return true;
 	default:
 		return false;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c8c37d569023..d80b1caefc70 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -517,31 +517,6 @@ void kvm_free_plane(struct kvm_plane *plane)
 	kvm_x86_call(free_plane)(plane);
 }
 
-struct kvm_plane *x86_alloc_plane(void)
-{
-	/* For better type checking, do not return kzalloc() value directly */
-	struct kvm_plane *plane = kzalloc(sizeof(*plane), GFP_KERNEL_ACCOUNT);
-
-	return plane;
-}
-EXPORT_SYMBOL_FOR_KVM_INTERNAL(x86_alloc_plane);
-
-void x86_free_plane(struct kvm_plane *plane)
-{
-	kfree(plane);
-}
-EXPORT_SYMBOL_FOR_KVM_INTERNAL(x86_free_plane);
-
-struct kvm_plane *kvm_alloc_plane(void)
-{
-	return kvm_x86_call(alloc_plane)();
-}
-
-void kvm_free_plane(struct kvm_plane *plane)
-{
-	kvm_x86_call(free_plane)(plane);
-}
-
 /*
  * All feature MSRs except uCode revID, which tracks the currently loaded uCode
  * patch, are immutable once the vCPU model is defined.
@@ -1026,7 +1001,7 @@ static int complete_emulated_insn_gp(struct kvm_vcpu *vcpu, int err)
 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault,
 			   bool from_hardware)
 {
-	++vcpu->stat->pf_guest;
+	++vcpu->stat.pf_guest;
 
 	/*
 	 * Async #PF in L2 is always forwarded to L1 as a VM-Exit regardless of
@@ -3732,7 +3707,7 @@ static void kvmclock_reset(struct kvm_vcpu *vcpu)
 
 static void kvm_vcpu_flush_tlb_all(struct kvm_vcpu *vcpu)
 {
-	++vcpu->stat->tlb_flush;
+	++vcpu->stat.tlb_flush;
 	kvm_x86_call(flush_tlb_all)(vcpu);
 
 	/* Flushing all ASIDs flushes the current ASID... */
@@ -3741,7 +3716,7 @@ static void kvm_vcpu_flush_tlb_all(struct kvm_vcpu *vcpu)
 
 static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu)
 {
-	++vcpu->stat->tlb_flush;
+	++vcpu->stat.tlb_flush;
 
 	if (!tdp_enabled) {
 		/*
@@ -3766,7 +3741,7 @@ static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu)
 
 static inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu)
 {
-	++vcpu->stat->tlb_flush;
+	++vcpu->stat.tlb_flush;
 	kvm_x86_call(flush_tlb_current)(vcpu);
 }
 
@@ -5305,11 +5280,11 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu)
 	 * preempted if and only if the VM-Exit was due to a host interrupt.
 	 */
 	if (!vcpu->arch.at_instruction_boundary) {
-		vcpu->stat->preemption_other++;
+		vcpu->stat.preemption_other++;
 		return;
 	}
 
-	vcpu->stat->preemption_reported++;
+	vcpu->stat.preemption_reported++;
 	if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
 		return;
 
@@ -6845,7 +6820,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 		r = -EEXIST;
 		if (irqchip_in_kernel(kvm) || kvm->has_planes)
 			goto split_irqchip_unlock;
-		if (kvm->created_vcpus || kvm->has_planes)
+		if (kvm->created_vcpus)
 			goto split_irqchip_unlock;
 		/* Pairs with irqchip_in_kernel. */
 		smp_wmb();
@@ -9278,7 +9253,7 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
 {
 	struct kvm *kvm = vcpu->kvm;
 
-	++vcpu->stat->insn_emulation_fail;
+	++vcpu->stat.insn_emulation_fail;
 	trace_kvm_emulate_insn_failed(vcpu);
 
 	if (emulation_type & EMULTYPE_VMWARE_GP) {
@@ -9510,7 +9485,7 @@ int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type,
 	r = x86_decode_insn(ctxt, insn, insn_len, emulation_type);
 
 	trace_kvm_emulate_insn_start(vcpu);
-	++vcpu->stat->insn_emulation;
+	++vcpu->stat.insn_emulation;
 
 	return r;
 }
@@ -9685,7 +9660,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
 		}
 		r = 0;
 	} else if (vcpu->mmio_needed) {
-		++vcpu->stat->mmio_exits;
+		++vcpu->stat.mmio_exits;
 
 		if (!vcpu->mmio_is_write)
 			writeback = false;
@@ -10452,7 +10427,7 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id)
 	struct kvm_vcpu *target = NULL;
 	struct kvm_apic_map *map;
 
-	vcpu->stat->directed_yield_attempted++;
+	vcpu->stat.directed_yield_attempted++;
 
 	if (single_task_running())
 		goto no_yield;
@@ -10478,7 +10453,7 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id)
 	if (kvm_vcpu_yield_to(target) <= 0)
 		goto no_yield;
 
-	vcpu->stat->directed_yield_successful++;
+	vcpu->stat.directed_yield_successful++;
 
 no_yield:
 	return;
@@ -10555,7 +10530,7 @@ int ____kvm_emulate_hypercall(struct kvm_vcpu *vcpu, int cpl,
 	int op_64_bit = is_64_bit_hypercall(vcpu);
 	unsigned long ret, nr, a0, a1, a2, a3;
 
-	++vcpu->stat->hypercalls;
+	++vcpu->stat.hypercalls;
 
 	if (op_64_bit) {
 		nr = kvm_rax_read_raw(vcpu);
@@ -10673,7 +10648,7 @@ int ____kvm_emulate_hypercall(struct kvm_vcpu *vcpu, int cpl,
 
 				if (common->vtl_plane_ready) {
 					/* Parked in vtl_return: deliver now. */
-					kvm_rax_write(secure, a0);
+					kvm_rax_write_raw(secure, a0);
 					common->vtl_call_pending = false;
 				} else {
 					/* Still booting: deliver on readiness. */
@@ -11388,7 +11363,7 @@ void kvm_inc_or_dec_irq_window_inhibit(struct kvm *kvm, bool inc)
 	 */
 	guard(rwsem_write)(&kvm->arch.apicv_update_lock);
 	if (atomic_add_return(add, &kvm->arch.apicv_nr_irq_window_req) == inc)
-		__kvm_set_or_clear_apicv_inhibit(kvm->planes[0], APICV_INHIBIT_REASON_IRQWIN, inc);
+		__kvm_set_or_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_IRQWIN, inc);
 }
 EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_inc_or_dec_irq_window_inhibit);
 
@@ -11644,22 +11619,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 		goto out;
 	}
 
-	if (kvm_check_plane0_events(vcpu)) {
-		kvm_vcpu_set_plane_runnable(vcpu->common->vcpus[0]);
-
-		kvm_make_request(KVM_REQ_EVENT, vcpu);
-		kvm_make_request(KVM_REQ_PLANE_RESCHED, vcpu);
-	}
-
-	if (kvm_check_request(KVM_REQ_PLANE_RESCHED, vcpu)) {
-		vcpu->common->plane_switch = true;
-		r = 0;
-		goto out;
-	}
-
 	if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win ||
 	    kvm_xen_has_interrupt(vcpu)) {
-		++vcpu->stat->req_event;
+		++vcpu->stat.req_event;
 		r = kvm_apic_accept_events(vcpu);
 		if (r < 0) {
 			r = 0;
@@ -11815,7 +11777,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 		run_flags = 0;
 
 		/* Note, VM-Exits that go down the "slow" path are accounted below. */
-		++vcpu->stat->exits;
+		++vcpu->stat.exits;
 	}
 
 	kvm_load_host_pkru(vcpu);
@@ -11881,11 +11843,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 	 * VM-Exit on SVM and any ticks that occur between VM-Exit and now.
 	 * An instruction is required after local_irq_enable() to fully unblock
 	 * interrupts on processors that implement an interrupt shadow, the
-	 * stat->exits increment will do nicely.
+	 * stat.exits increment will do nicely.
 	 */
 	kvm_before_interrupt(vcpu, KVM_HANDLING_IRQ);
 	local_irq_enable();
-	++vcpu->stat->exits;
+	++vcpu->stat.exits;
 	local_irq_disable();
 	kvm_after_interrupt(vcpu);
 
@@ -12103,7 +12065,7 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
 			kvm_vcpu_ready_for_interrupt_injection(vcpu)) {
 			r = 0;
 			vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
-			++vcpu->stat->request_irq_exits;
+			++vcpu->stat.request_irq_exits;
 			break;
 		}
 
@@ -12128,7 +12090,7 @@ static int __kvm_emulate_halt(struct kvm_vcpu *vcpu, int state, int reason)
 	 * managed by userspace, in which case userspace is responsible for
 	 * handling wake events.
 	 */
-	++vcpu->stat->halt_exits;
+	++vcpu->stat.halt_exits;
 	if (lapic_in_kernel(vcpu)) {
 		if (kvm_vcpu_has_events(vcpu) || vcpu->arch.pv.pv_unhalted)
 			state = KVM_MP_STATE_RUNNABLE;
@@ -12300,7 +12262,7 @@ static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
 		return;
 
 	fpu_swap_kvm_fpstate(&vcpu->arch.guest_fpu, false);
-	++vcpu->stat->fpu_reload;
+	++vcpu->stat.fpu_reload;
 	trace_kvm_fpu(0);
 }
 
@@ -12387,7 +12349,7 @@ static int __kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		if (signal_pending(current)) {
 			r = -EINTR;
 			kvm_run->exit_reason = KVM_EXIT_INTR;
-			++vcpu->stat->signal_exits;
+			++vcpu->stat.signal_exits;
 		}
 		goto out;
 	}
@@ -13180,7 +13142,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
 	return 0;
 }
 
-int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane)
+int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 {
 	int r;
 
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 05c9edd4a73d..bee8eaea05bc 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -453,8 +453,7 @@ struct kvm_vcpu {
 #endif
 
 	struct kvm_vcpu_arch arch;
-	struct kvm_vcpu_stat *stat;
-	struct kvm_vcpu_stat __stat;
+	struct kvm_vcpu_stat stat;
 	char stats_id[KVM_STATS_NAME_SIZE];
 
 	/*
@@ -1012,7 +1011,6 @@ struct kvm {
 	bool dirty_ring_with_bitmap;
 	bool vm_bugged;
 	bool vm_dead;
-	bool has_planes;
 
 #ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
 	struct notifier_block pm_notifier;
@@ -1801,7 +1799,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu);
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu);
 int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id);
-int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu, struct kvm_plane *plane);
+int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu);
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu);
 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu);
 
@@ -2664,7 +2662,7 @@ static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
 static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu)
 {
 	vcpu->run->exit_reason = KVM_EXIT_INTR;
-	vcpu->stat->signal_exits++;
+	vcpu->stat.signal_exits++;
 }
 
 static inline int kvm_xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 3118b31d13f6..fa2799c4dddb 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -140,16 +140,6 @@ struct kvm_xen_exit {
 	} u;
 };
 
-struct kvm_plane_event_exit {
-#define KVM_PLANE_EVENT_INTERRUPT    1
-	__u16 cause;
-	__u16 pending_event_planes;
-	__u16 target;
-	__u16 padding;
-	__u32 flags;
-	__u64 extra[8];
-};
-
 struct kvm_exit_snp_req_certs {
 	__u64 gpa;
 	__u64 npages;
@@ -243,13 +233,7 @@ struct kvm_run {
 	/* in */
 	__u8 request_interrupt_window;
 	__u8 HINT_UNSAFE_IN_KVM(immediate_exit);
-
-	/* in/out */
-	__u8 plane;
-	__u16 suspended_planes;
-
-	/* in */
-	__u16 req_exit_planes;
+	__u8 padding1[6];
 
 	/* out */
 	__u32 exit_reason;
@@ -486,8 +470,6 @@ struct kvm_run {
 			__u64 gpa;
 			__u64 size;
 		} memory_fault;
-		/* KVM_EXIT_PLANE_EVENT */
-		struct kvm_plane_event_exit plane_event;
 		/* KVM_EXIT_TDX */
 		struct {
 			__u64 flags;
@@ -1709,7 +1691,4 @@ struct kvm_pre_fault_memory {
 	__u64 padding[5];
 };
 
-#define KVM_CREATE_PLANE	_IO(KVMIO, 0xd6)
-#define KVM_CREATE_VCPU_PLANE	_IO(KVMIO, 0xd7)
-
 #endif /* __LINUX_KVM_H */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 6e4f3f3e6881..6b2d272797d3 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -440,7 +440,7 @@ void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc)
 
 static int kvm_vcpu_init_common(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned long id)
 {
-	struct kvm_vcpu_common *common = kzalloc(sizeof(*common), GFP_KERNEL_ACCOUNT);
+	struct kvm_vcpu_common *common __free(kfree) = kzalloc(sizeof(*common), GFP_KERNEL_ACCOUNT);
 	struct page *page;
 	int r;
 
@@ -503,10 +503,7 @@ static int kvm_vcpu_init_common(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned
 	if (r)
 		goto out_free_dirty_ring;
 
-	vcpu->common = common;
-
-	kvm_vcpu_set_in_spin_loop(vcpu, false);
-	kvm_vcpu_set_dy_eligible(vcpu, false);
+	vcpu->common = no_free_ptr(common);
 
 	kvm_vcpu_set_in_spin_loop(vcpu, false);
 	kvm_vcpu_set_dy_eligible(vcpu, false);
@@ -522,8 +519,6 @@ static int kvm_vcpu_init_common(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned
 	kvm->created_vcpus--;
 	mutex_unlock(&kvm->lock);
 
-	kfree(common);
-
 	return r;
 }
 
@@ -1243,7 +1238,6 @@ static struct kvm_plane *kvm_create_plane(struct kvm *kvm, unsigned plane_level)
 	if (kvm_arch_plane_init(kvm, plane, plane_level))
 		goto out_free_plane;
 
-
 	kvm->planes[plane_level] = plane;
 
 	return plane;
@@ -1490,6 +1484,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
 #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
 	xa_destroy(&kvm->mem_attr_array);
 #endif
+	kvm_destroy_planes(kvm);
 	kvm_arch_free_vm(kvm);
 	kvm_destroy_planes(kvm);
 	preempt_notifier_dec();
@@ -4383,6 +4378,7 @@ static int kvm_plane_ioctl_create_vcpu(struct kvm_plane *plane, unsigned long id
 {
 	struct kvm *kvm = plane->kvm;
 	struct kvm_vcpu *vcpu;
+	struct kvm_vcpu *prev_current_vcpu;
 	int r;
 
 	mutex_lock(&kvm->lock);
@@ -4427,7 +4423,25 @@ static int kvm_plane_ioctl_create_vcpu(struct kvm_plane *plane, unsigned long id
 
 	kvm_vcpu_init(vcpu, kvm, id);
 
-	r = kvm_arch_vcpu_create(vcpu, plane);
+	/*
+	 * For planes above plane-0 the vCPU shares plane-0's kvm_vcpu_common,
+	 * including ->current_vcpu and the preempt notifier consulted by
+	 * kvm_sched_in()/kvm_sched_out().  kvm_arch_vcpu_create() (and
+	 * kvm_arch_vcpu_postcreate() below) load this vCPU's VMCS via
+	 * vcpu_load() but do not update ->current_vcpu, which still points at
+	 * plane-0's vCPU.  The arch create path performs GFP_KERNEL
+	 * allocations, so the creating task can sleep and be rescheduled while
+	 * this vCPU's VMCS is loaded; the shared notifier would then
+	 * save/restore plane-0's vCPU and desync the per-CPU loaded_vmcs
+	 * tracking from the hardware-current VMCS, wedging VMX (host hard
+	 * lockup).  Mirror the run loop's invariant (see
+	 * kvm_vcpu_select_plane()): make ->current_vcpu the vCPU whose VMCS is
+	 * loaded for the duration, then restore it.
+	 */
+	prev_current_vcpu = vcpu->common->current_vcpu;
+	vcpu->common->current_vcpu = vcpu;
+	r = kvm_arch_vcpu_create(vcpu);
+	vcpu->common->current_vcpu = prev_current_vcpu;
 	if (r)
 		goto vcpu_free_common;
 
@@ -4456,14 +4470,18 @@ static int kvm_plane_ioctl_create_vcpu(struct kvm_plane *plane, unsigned long id
 	kvm_vcpu_unlock(vcpu);
 
 	mutex_unlock(&kvm->lock);
+	/* Same VMCS/current_vcpu invariant as above (vcpu_load in postcreate). */
+	prev_current_vcpu = vcpu->common->current_vcpu;
+	vcpu->common->current_vcpu = vcpu;
 	kvm_arch_vcpu_postcreate(vcpu);
+	vcpu->common->current_vcpu = prev_current_vcpu;
 	kvm_create_vcpu_debugfs(vcpu);
 	return r;
 
 kvm_put_xa_erase:
 	kvm_vcpu_unlock(vcpu);
 	kvm_put_kvm_no_destroy(kvm);
-	xa_erase(&kvm->planes[0]->vcpu_array, vcpu->vcpu_idx);
+	xa_erase(&plane->vcpu_array, vcpu->vcpu_idx);
 unlock_vcpu_destroy:
 	mutex_unlock(&kvm->lock);
 	kvm_arch_vcpu_destroy(vcpu);
@@ -4614,38 +4632,16 @@ static int kvm_wait_for_vcpu_online(struct kvm_vcpu *vcpu)
 static inline bool kvm_is_vcpu_plane_ioctl(unsigned ioctl)
 {
 	switch (ioctl) {
-	case KVM_GET_DEBUGREGS:
-	case KVM_SET_DEBUGREGS:
 	case KVM_GET_FPU:
 	case KVM_SET_FPU:
-	case KVM_GET_LAPIC:
-	case KVM_SET_LAPIC:
-	case KVM_GET_MSRS:
-	case KVM_SET_MSRS:
-	case KVM_GET_NESTED_STATE:
-	case KVM_SET_NESTED_STATE:
-	case KVM_GET_ONE_REG:
-	case KVM_SET_ONE_REG:
 	case KVM_GET_REGS:
 	case KVM_SET_REGS:
 	case KVM_GET_SREGS:
 	case KVM_SET_SREGS:
-	case KVM_GET_SREGS2:
-	case KVM_SET_SREGS2:
-	case KVM_GET_VCPU_EVENTS:
-	case KVM_SET_VCPU_EVENTS:
-	case KVM_GET_XCRS:
-	case KVM_SET_XCRS:
-	case KVM_GET_XSAVE:
-	case KVM_GET_XSAVE2:
-	case KVM_SET_XSAVE:
-
-	case KVM_GET_REG_LIST:
 	case KVM_TRANSLATE:
 		return true;
-
 	default:
-		return false;
+		return kvm_arch_is_vcpu_plane_ioctl(ioctl);
 	}
 }
 
@@ -4950,7 +4946,6 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg);
 
 static long __kvm_plane_ioctl(struct kvm_plane *plane, unsigned int ioctl, unsigned long arg)
 {
-	void __user *argp = (void __user *)arg;
 	long r;
 
 	switch (ioctl) {
@@ -4966,38 +4961,35 @@ static long __kvm_plane_ioctl(struct kvm_plane *plane, unsigned int ioctl, unsig
 		break;
 #ifdef CONFIG_HAVE_KVM_MSI
 	case KVM_SIGNAL_MSI: {
+		void __user *argp = (void __user *)arg;
 		struct kvm_msi msi;
 
-		r = -EFAULT;
 		if (copy_from_user(&msi, argp, sizeof(msi)))
-			goto out;
+			return -EFAULT;
 		r = kvm_send_userspace_msi(plane->kvm, &msi, plane->level);
 		break;
 	}
 #endif
 #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
 	case KVM_SET_GSI_ROUTING: {
+		void __user *argp = (void __user *)arg;
 		struct kvm_irq_routing routing;
 		struct kvm_irq_routing __user *urouting;
 		struct kvm_irq_routing_entry *entries = NULL;
 
-		r = -EFAULT;
 		if (copy_from_user(&routing, argp, sizeof(routing)))
-			goto out;
-		r = -EINVAL;
-		if (!kvm_arch_can_set_irq_routing(plane->kvm))
-			goto out;
-		if (routing.nr > KVM_MAX_IRQ_ROUTES)
-			goto out;
-		if (routing.flags)
-			goto out;
+			return -EFAULT;
+		if (!kvm_arch_can_set_irq_routing(plane->kvm) ||
+		    routing.nr > KVM_MAX_IRQ_ROUTES ||
+		    routing.flags)
+			return -EINVAL;
 		if (routing.nr) {
 			urouting = argp;
 			entries = vmemdup_array_user(urouting->entries,
 						     routing.nr, sizeof(*entries));
 			if (IS_ERR(entries)) {
 				r = PTR_ERR(entries);
-				goto out;
+				return r;
 			}
 		}
 		r = kvm_set_irq_routing(plane->kvm, entries, routing.nr,
@@ -5010,7 +5002,6 @@ static long __kvm_plane_ioctl(struct kvm_plane *plane, unsigned int ioctl, unsig
 		r = -ENOTTY;
 	}
 
-out:
 	return r;
 }
 
@@ -5590,7 +5581,6 @@ static int kvm_vm_ioctl_create_plane(struct kvm *kvm, unsigned id)
 		goto put_kvm;
 	}
 
-	kvm->planes[id] = plane;
 	kvm->has_planes = true;
 	fd_install(fd, file);
 	return fd;
-- 
2.55.0


      parent reply	other threads:[~2026-08-05 11:04 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-05 11:02 [RFC PATCH v1 00/42] VBS/VSM-on-KVM: VBS integration for KVM VM planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 01/42] Fix merge issue - Remove duplicate definition for kvm_arch_has_irq_bypass Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 02/42] Fix compilation Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 03/42] Fix compile error Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 04/42] Fix compile errors Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 05/42] Initial support for VM Planes - Add kernel config for CONFIG_VM_PLANES - Parse vm plane config from initrd for plane configuration - Make hypercalls to allocate memory for the vm planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 06/42] Use vcpu count from the plane configuration Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 07/42] skip processing plane configuration for plane 0 - plane 0 is the boot plane Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 08/42] Add plane config param to specify kernel image format Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 09/42] Activate the VM Planes through the Hypervisor - Using KVM as the VMM Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 10/42] allow the command line to be specified for kernels in other planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 11/42] Various changes to support VM Planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 12/42] Add a Virtualization Based Security (VBS) framework. - Add backends for AMD SEV-SNP, Intel TDX, Arm CCA and KVM Planes. - Support VTL on Hyper-V in addition to Planes on KVM Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 13/42] Add a inter-plane communication mechanism through KVM. - model this to use a single page similar to SEV-SNP Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 14/42] KVM: Add per-plane memory attribute support for cross-plane EPT protection Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 15/42] KVM: x86: Add KVM_HC_VBS_VTL_CALL hypercall for VBS inter-plane calls Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 16/42] vbs: Add HEKI kernel sealing and fix KVM plane memory attribute guards Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 17/42] vbs: Add module authentication via VBS/HEKI Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 18/42] vbs: Add kexec validation and make module auth non-fatal Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 19/42] Merge branch 'master' into vm-planes Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 20/42] kvm: x86: fix merged plane API/stat build regressions Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 21/42] KVM: x86: exit VM planes and VBS hypercalls to userspace Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 22/42] kexec: block legacy kexec_load when VBS is active Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 23/42] kvm: x86: fix merged plane API/stat build regressions Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 24/42] KVM: planes: expose memory-attribute setting to in-kernel callers Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 25/42] vm_planes: drop unused per-plane vcpu_count Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 26/42] drivers/virt: add VBS secure-plane park loop Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 27/42] KVM: planes: add arch-neutral in-kernel plane switch helper Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 28/42] KVM: x86: add VBS VTL call/return and cross-plane set-mem-attrs hypercalls Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 29/42] init/vm_planes: set up planes from rootfs_initcall and load ELF payloads Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 30/42] security/vbs: run backend probe and HEKI seal at rootfs_initcall Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 31/42] security/vbs: pin the VTL call hypercall to CPU0 Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 32/42] security/vbs: add secure-plane monitor backend Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 33/42] drivers/virt: rename VBS park loop to secure_monitor Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 34/42] x86/realmode: skip the sub-1M trampoline for the VBS secure plane Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 35/42] KVM: x86: deny normal-plane access to secure-plane memory Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 36/42] KVM: plane: handle KVM_CHECK_EXTENSION on the plane fd Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 37/42] KVM: selftests: run plane tests with a split IRQ chip Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 38/42] kvm: x86: drop obsolete kvm_cache_regs.h Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 39/42] kvm: arch: finalize plane hooks and kvm_arch_vcpu_create signature Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 40/42] kvm: x86: use kvm_vcpu scheduling-state accessors and struct stat fields Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 41/42] kvm: x86: finalize per-plane APIC state and CPUID placement Sriram Nambakam
2026-08-05 11:03 ` Sriram Nambakam [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260805110324.25067-43-snambakam@linux.microsoft.com \
    --to=snambakam@linux.microsoft.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.