The Linux Kernel Mailing List
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox