Skip to content

Commit e65733b

Browse files
ouptonMarc Zyngier
authored andcommitted
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: Sean Christopherson <seanjc@google.com> Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20230404154050.2270077-2-oliver.upton@linux.dev
1 parent e8d018d commit e65733b

5 files changed

Lines changed: 23 additions & 5 deletions

File tree

Documentation/virt/kvm/api.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6218,8 +6218,7 @@ to the byte array.
62186218
__u64 nr;
62196219
__u64 args[6];
62206220
__u64 ret;
6221-
__u32 longmode;
6222-
__u32 pad;
6221+
__u64 flags;
62236222
} hypercall;
62246223

62256224
Unused. This was once used for 'hypercall to userspace'. To implement

arch/x86/include/asm/kvm_host.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,4 +2204,11 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages);
22042204
KVM_X86_QUIRK_FIX_HYPERCALL_INSN | \
22052205
KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS)
22062206

2207+
/*
2208+
* KVM previously used a u32 field in kvm_run to indicate the hypercall was
2209+
* initiated from long mode. KVM now sets bit 0 to indicate long mode, but the
2210+
* remaining 31 lower bits must be 0 to preserve ABI.
2211+
*/
2212+
#define KVM_EXIT_HYPERCALL_MBZ GENMASK_ULL(31, 1)
2213+
22072214
#endif /* _ASM_X86_KVM_HOST_H */

arch/x86/include/uapi/asm/kvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,4 +559,7 @@ struct kvm_pmu_event_filter {
559559
#define KVM_VCPU_TSC_CTRL 0 /* control group for the timestamp counter (TSC) */
560560
#define KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */
561561

562+
/* x86-specific KVM_EXIT_HYPERCALL flags. */
563+
#define KVM_EXIT_HYPERCALL_LONG_MODE BIT(0)
564+
562565
#endif /* _ASM_X86_KVM_H */

arch/x86/kvm/x86.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9803,7 +9803,11 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
98039803
vcpu->run->hypercall.args[0] = gpa;
98049804
vcpu->run->hypercall.args[1] = npages;
98059805
vcpu->run->hypercall.args[2] = attrs;
9806-
vcpu->run->hypercall.longmode = op_64_bit;
9806+
vcpu->run->hypercall.flags = 0;
9807+
if (op_64_bit)
9808+
vcpu->run->hypercall.flags |= KVM_EXIT_HYPERCALL_LONG_MODE;
9809+
9810+
WARN_ON_ONCE(vcpu->run->hypercall.flags & KVM_EXIT_HYPERCALL_MBZ);
98079811
vcpu->arch.complete_userspace_io = complete_hypercall_exit;
98089812
return 0;
98099813
}

include/uapi/linux/kvm.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,13 @@ struct kvm_run {
341341
__u64 nr;
342342
__u64 args[6];
343343
__u64 ret;
344-
__u32 longmode;
345-
__u32 pad;
344+
345+
union {
346+
#ifndef __KERNEL__
347+
__u32 longmode;
348+
#endif
349+
__u64 flags;
350+
};
346351
} hypercall;
347352
/* KVM_EXIT_TPR_ACCESS */
348353
struct {

0 commit comments

Comments
 (0)