Commit e65733b5 authored by Oliver Upton's avatar Oliver Upton Committed by Marc Zyngier
Browse files

KVM: x86: Redefine 'longmode' as a flag for KVM_EXIT_HYPERCALL



The 'longmode' field is a bit annoying as it blows an entire __u32 to
represent a boolean value. Since other architectures are looking to add
support for KVM_EXIT_HYPERCALL, now is probably a good time to clean it
up.

Redefine the field (and the remaining padding) as a set of flags.
Preserve the existing ABI by using bit 0 to indicate if the guest was in
long mode and requiring that the remaining 31 bits must be zero.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: default avatarSean Christopherson <seanjc@google.com>
Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230404154050.2270077-2-oliver.upton@linux.dev
parent e8d018dd
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -6218,8 +6218,7 @@ to the byte array.
			__u64 nr;
			__u64 args[6];
			__u64 ret;
			__u32 longmode;
			__u32 pad;
			__u64 flags;
		} hypercall;

Unused.  This was once used for 'hypercall to userspace'.  To implement
+7 −0
Original line number Diff line number Diff line
@@ -2204,4 +2204,11 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages);
	 KVM_X86_QUIRK_FIX_HYPERCALL_INSN |	\
	 KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS)

/*
 * KVM previously used a u32 field in kvm_run to indicate the hypercall was
 * initiated from long mode. KVM now sets bit 0 to indicate long mode, but the
 * remaining 31 lower bits must be 0 to preserve ABI.
 */
#define KVM_EXIT_HYPERCALL_MBZ		GENMASK_ULL(31, 1)

#endif /* _ASM_X86_KVM_HOST_H */
+3 −0
Original line number Diff line number Diff line
@@ -559,4 +559,7 @@ struct kvm_pmu_event_filter {
#define KVM_VCPU_TSC_CTRL 0 /* control group for the timestamp counter (TSC) */
#define   KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */

/* x86-specific KVM_EXIT_HYPERCALL flags. */
#define KVM_EXIT_HYPERCALL_LONG_MODE	BIT(0)

#endif /* _ASM_X86_KVM_H */
+5 −1
Original line number Diff line number Diff line
@@ -9803,7 +9803,11 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
		vcpu->run->hypercall.args[0]  = gpa;
		vcpu->run->hypercall.args[1]  = npages;
		vcpu->run->hypercall.args[2]  = attrs;
		vcpu->run->hypercall.longmode = op_64_bit;
		vcpu->run->hypercall.flags    = 0;
		if (op_64_bit)
			vcpu->run->hypercall.flags |= KVM_EXIT_HYPERCALL_LONG_MODE;

		WARN_ON_ONCE(vcpu->run->hypercall.flags & KVM_EXIT_HYPERCALL_MBZ);
		vcpu->arch.complete_userspace_io = complete_hypercall_exit;
		return 0;
	}
+7 −2
Original line number Diff line number Diff line
@@ -341,8 +341,13 @@ struct kvm_run {
			__u64 nr;
			__u64 args[6];
			__u64 ret;

			union {
#ifndef __KERNEL__
				__u32 longmode;
			__u32 pad;
#endif
				__u64 flags;
			};
		} hypercall;
		/* KVM_EXIT_TPR_ACCESS */
		struct {