* [PATCH v2] i386/kvm: Disable hypercall patching quirk by default
@ 2025-07-22 20:43 Mathias Krause
2025-07-23 6:54 ` Xiaoyao Li
0 siblings, 1 reply; 6+ messages in thread
From: Mathias Krause @ 2025-07-22 20:43 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel
Cc: Marcelo Tosatti, Xiaoyao Li, kvm, Mathias Krause, Oliver Upton,
Sean Christopherson
KVM has a weird behaviour when a guest executes VMCALL on an AMD system
or VMMCALL on an Intel CPU. Both naturally generate an invalid opcode
exception (#UD) as they are just the wrong instruction for the CPU
given. But instead of forwarding the exception to the guest, KVM tries
to patch the guest instruction to match the host's actual hypercall
instruction. That is doomed to fail as read-only code is rather the
standard these days. But, instead of letting go the patching attempt and
falling back to #UD injection, KVM injects the page fault instead.
That's wrong on multiple levels. Not only isn't that a valid exception
to be generated by these instructions, confusing attempts to handle
them. It also destroys guest state by doing so, namely the value of CR2.
Sean attempted to fix that in KVM[1] but the patch was never applied.
Later, Oliver added a quirk bit in [2] so the behaviour can, at least,
conceptually be disabled. Paolo even called out to add this very
functionality to disable the quirk in QEMU[3]. So lets just do it.
A new property 'hypercall-patching=on|off' is added, for the very
unlikely case that there are setups that really need the patching.
However, these would be vulnerable to memory corruption attacks freely
overwriting code as they please. So, my guess is, there are exactly 0
systems out there requiring this quirk.
[1] https://lore.kernel.org/kvm/20211210222903.3417968-1-seanjc@google.com/
[2] https://lore.kernel.org/kvm/20220316005538.2282772-2-oupton@google.com/
[3] https://lore.kernel.org/kvm/80e1f1d2-2d79-22b7-6665-c00e4fe9cb9c@redhat.com/
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Mathias Krause <minipli@grsecurity.net>
---
v2:
- rename hypercall_patching_enabled to hypercall_patching (Xiaoyao Li)
- make use of error_setg*() (Xiaoyao Li)
include/system/kvm_int.h | 1 +
qemu-options.hx | 10 +++++++++
target/i386/kvm/kvm.c | 45 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 56 insertions(+)
diff --git a/include/system/kvm_int.h b/include/system/kvm_int.h
index 756a3c0a250e..c909464c74a2 100644
--- a/include/system/kvm_int.h
+++ b/include/system/kvm_int.h
@@ -159,6 +159,7 @@ struct KVMState
uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */
struct KVMDirtyRingReaper reaper;
struct KVMMsrEnergy msr_energy;
+ bool hypercall_patching;
NotifyVmexitOption notify_vmexit;
uint32_t notify_window;
uint32_t xen_version;
diff --git a/qemu-options.hx b/qemu-options.hx
index 1f862b19a676..c2e232649c19 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -231,6 +231,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
" dirty-ring-size=n (KVM dirty ring GFN count, default 0)\n"
" eager-split-size=n (KVM Eager Page Split chunk size, default 0, disabled. ARM only)\n"
" notify-vmexit=run|internal-error|disable,notify-window=n (enable notify VM exit and set notify window, x86 only)\n"
+ " hypercall-patching=on|off (enable KVM's VMCALL/VMMCALL hypercall patching quirk, x86 only)\n"
" thread=single|multi (enable multi-threaded TCG)\n"
" device=path (KVM device path, default /dev/kvm)\n", QEMU_ARCH_ALL)
SRST
@@ -313,6 +314,15 @@ SRST
open up for a specified of time (i.e. notify-window).
Default: notify-vmexit=run,notify-window=0.
+ ``hypercall-patching=on|off``
+ KVM tries to recover from the wrong hypercall instruction being used by
+ a guest by attempting to rewrite it to the one supported natively by
+ the host CPU (VMCALL on Intel, VMMCALL for AMD systems). However, this
+ patching may fail if the guest memory is write protected, leading to a
+ page fault getting propagated to the guest instead of an illegal
+ instruction exception. As this may confuse guests, it gets disabled by
+ default (x86 only).
+
``device=path``
Sets the path to the KVM device node. Defaults to ``/dev/kvm``. This
option can be used to pass the KVM device to use via a file descriptor
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 56a6b9b6381a..55f744956970 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -3224,6 +3224,26 @@ static int kvm_vm_enable_energy_msrs(KVMState *s)
return 0;
}
+static int kvm_vm_disable_hypercall_patching(KVMState *s, Error **errp)
+{
+ int valid_quirks = kvm_vm_check_extension(s, KVM_CAP_DISABLE_QUIRKS2);
+ int ret = -1;
+
+ if (valid_quirks & KVM_X86_QUIRK_FIX_HYPERCALL_INSN) {
+ ret = kvm_vm_enable_cap(s, KVM_CAP_DISABLE_QUIRKS2, 0,
+ KVM_X86_QUIRK_FIX_HYPERCALL_INSN);
+ if (ret) {
+ error_setg_errno(errp, -ret, "kvm: failed to disable "
+ "hypercall patching quirk: %s",
+ strerror(-ret));
+ }
+ } else {
+ error_setg(errp, "kvm: disabling hypercall patching not supported");
+ }
+
+ return ret;
+}
+
int kvm_arch_init(MachineState *ms, KVMState *s)
{
int ret;
@@ -3363,6 +3383,12 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
}
}
+ if (s->hypercall_patching == false) {
+ if (kvm_vm_disable_hypercall_patching(s, &local_err)) {
+ error_report_err(local_err);
+ }
+ }
+
return 0;
}
@@ -6456,6 +6482,19 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask)
}
}
+static bool kvm_arch_get_hypercall_patching(Object *obj, Error **errp)
+{
+ KVMState *s = KVM_STATE(obj);
+ return s->hypercall_patching;
+}
+
+static void kvm_arch_set_hypercall_patching(Object *obj, bool value,
+ Error **errp)
+{
+ KVMState *s = KVM_STATE(obj);
+ s->hypercall_patching = value;
+}
+
static int kvm_arch_get_notify_vmexit(Object *obj, Error **errp)
{
KVMState *s = KVM_STATE(obj);
@@ -6589,6 +6628,12 @@ static void kvm_arch_set_xen_evtchn_max_pirq(Object *obj, Visitor *v,
void kvm_arch_accel_class_init(ObjectClass *oc)
{
+ object_class_property_add_bool(oc, "hypercall-patching",
+ kvm_arch_get_hypercall_patching,
+ kvm_arch_set_hypercall_patching);
+ object_class_property_set_description(oc, "hypercall-patching",
+ "Enable hypercall patching quirk");
+
object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOption",
&NotifyVmexitOption_lookup,
kvm_arch_get_notify_vmexit,
--
2.30.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2] i386/kvm: Disable hypercall patching quirk by default
2025-07-22 20:43 [PATCH v2] i386/kvm: Disable hypercall patching quirk by default Mathias Krause
@ 2025-07-23 6:54 ` Xiaoyao Li
2025-07-23 7:53 ` Mathias Krause
0 siblings, 1 reply; 6+ messages in thread
From: Xiaoyao Li @ 2025-07-23 6:54 UTC (permalink / raw)
To: Mathias Krause, Paolo Bonzini, qemu-devel
Cc: Marcelo Tosatti, kvm, Oliver Upton, Sean Christopherson
On 7/23/2025 4:43 AM, Mathias Krause wrote:
> KVM has a weird behaviour when a guest executes VMCALL on an AMD system
> or VMMCALL on an Intel CPU. Both naturally generate an invalid opcode
> exception (#UD) as they are just the wrong instruction for the CPU
> given. But instead of forwarding the exception to the guest, KVM tries
> to patch the guest instruction to match the host's actual hypercall
> instruction. That is doomed to fail as read-only code is rather the
> standard these days. But, instead of letting go the patching attempt and
> falling back to #UD injection, KVM injects the page fault instead.
>
> That's wrong on multiple levels. Not only isn't that a valid exception
> to be generated by these instructions, confusing attempts to handle
> them. It also destroys guest state by doing so, namely the value of CR2.
>
> Sean attempted to fix that in KVM[1] but the patch was never applied.
>
> Later, Oliver added a quirk bit in [2] so the behaviour can, at least,
> conceptually be disabled. Paolo even called out to add this very
> functionality to disable the quirk in QEMU[3]. So lets just do it.
>
> A new property 'hypercall-patching=on|off' is added, for the very
> unlikely case that there are setups that really need the patching.
> However, these would be vulnerable to memory corruption attacks freely
> overwriting code as they please. So, my guess is, there are exactly 0
> systems out there requiring this quirk.
>
> [1] https://lore.kernel.org/kvm/20211210222903.3417968-1-seanjc@google.com/
> [2] https://lore.kernel.org/kvm/20220316005538.2282772-2-oupton@google.com/
> [3] https://lore.kernel.org/kvm/80e1f1d2-2d79-22b7-6665-c00e4fe9cb9c@redhat.com/
>
> Cc: Oliver Upton <oliver.upton@linux.dev>
> Cc: Sean Christopherson <seanjc@google.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Mathias Krause <minipli@grsecurity.net>
I would leave it to Paolo to decide whether a compat property is needed
to disable the hypercall patching by default for newer machine, and keep
the old machine with old behavior (hypercall patching is enabled) by
default.
The implementation itself looks good to me, exception one nit. And I
tested that amd guest gets #UD on Intel host with this patch.
Tested-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> ---
> v2:
> - rename hypercall_patching_enabled to hypercall_patching (Xiaoyao Li)
> - make use of error_setg*() (Xiaoyao Li)
>
> include/system/kvm_int.h | 1 +
> qemu-options.hx | 10 +++++++++
> target/i386/kvm/kvm.c | 45 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 56 insertions(+)
>
> diff --git a/include/system/kvm_int.h b/include/system/kvm_int.h
> index 756a3c0a250e..c909464c74a2 100644
> --- a/include/system/kvm_int.h
> +++ b/include/system/kvm_int.h
> @@ -159,6 +159,7 @@ struct KVMState
> uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */
> struct KVMDirtyRingReaper reaper;
> struct KVMMsrEnergy msr_energy;
> + bool hypercall_patching;
> NotifyVmexitOption notify_vmexit;
> uint32_t notify_window;
> uint32_t xen_version;
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 1f862b19a676..c2e232649c19 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -231,6 +231,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
> " dirty-ring-size=n (KVM dirty ring GFN count, default 0)\n"
> " eager-split-size=n (KVM Eager Page Split chunk size, default 0, disabled. ARM only)\n"
> " notify-vmexit=run|internal-error|disable,notify-window=n (enable notify VM exit and set notify window, x86 only)\n"
> + " hypercall-patching=on|off (enable KVM's VMCALL/VMMCALL hypercall patching quirk, x86 only)\n"
> " thread=single|multi (enable multi-threaded TCG)\n"
> " device=path (KVM device path, default /dev/kvm)\n", QEMU_ARCH_ALL)
> SRST
> @@ -313,6 +314,15 @@ SRST
> open up for a specified of time (i.e. notify-window).
> Default: notify-vmexit=run,notify-window=0.
>
> + ``hypercall-patching=on|off``
> + KVM tries to recover from the wrong hypercall instruction being used by
> + a guest by attempting to rewrite it to the one supported natively by
> + the host CPU (VMCALL on Intel, VMMCALL for AMD systems). However, this
> + patching may fail if the guest memory is write protected, leading to a
> + page fault getting propagated to the guest instead of an illegal
> + instruction exception. As this may confuse guests, it gets disabled by
> + default (x86 only).
> +
> ``device=path``
> Sets the path to the KVM device node. Defaults to ``/dev/kvm``. This
> option can be used to pass the KVM device to use via a file descriptor
> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
> index 56a6b9b6381a..55f744956970 100644
> --- a/target/i386/kvm/kvm.c
> +++ b/target/i386/kvm/kvm.c
> @@ -3224,6 +3224,26 @@ static int kvm_vm_enable_energy_msrs(KVMState *s)
> return 0;
> }
>
> +static int kvm_vm_disable_hypercall_patching(KVMState *s, Error **errp)
> +{
> + int valid_quirks = kvm_vm_check_extension(s, KVM_CAP_DISABLE_QUIRKS2);
> + int ret = -1;
> +
> + if (valid_quirks & KVM_X86_QUIRK_FIX_HYPERCALL_INSN) {
> + ret = kvm_vm_enable_cap(s, KVM_CAP_DISABLE_QUIRKS2, 0,
> + KVM_X86_QUIRK_FIX_HYPERCALL_INSN);
> + if (ret) {
> + error_setg_errno(errp, -ret, "kvm: failed to disable "
> + "hypercall patching quirk: %s",
> + strerror(-ret));
> + }
> + } else {
> + error_setg(errp, "kvm: disabling hypercall patching not supported");
> + }
> +
> + return ret;
> +}
> +
> int kvm_arch_init(MachineState *ms, KVMState *s)
> {
> int ret;
> @@ -3363,6 +3383,12 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
> }
> }
>
> + if (s->hypercall_patching == false) {
Nit: it can be
if (!s->hypercall_patching )
> + if (kvm_vm_disable_hypercall_patching(s, &local_err)) {
> + error_report_err(local_err);
> + }
> + }
> +
> return 0;
> }
>
> @@ -6456,6 +6482,19 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask)
> }
> }
>
> +static bool kvm_arch_get_hypercall_patching(Object *obj, Error **errp)
> +{
> + KVMState *s = KVM_STATE(obj);
> + return s->hypercall_patching;
> +}
> +
> +static void kvm_arch_set_hypercall_patching(Object *obj, bool value,
> + Error **errp)
> +{
> + KVMState *s = KVM_STATE(obj);
> + s->hypercall_patching = value;
> +}
> +
> static int kvm_arch_get_notify_vmexit(Object *obj, Error **errp)
> {
> KVMState *s = KVM_STATE(obj);
> @@ -6589,6 +6628,12 @@ static void kvm_arch_set_xen_evtchn_max_pirq(Object *obj, Visitor *v,
>
> void kvm_arch_accel_class_init(ObjectClass *oc)
> {
> + object_class_property_add_bool(oc, "hypercall-patching",
> + kvm_arch_get_hypercall_patching,
> + kvm_arch_set_hypercall_patching);
> + object_class_property_set_description(oc, "hypercall-patching",
> + "Enable hypercall patching quirk");
> +
> object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOption",
> &NotifyVmexitOption_lookup,
> kvm_arch_get_notify_vmexit,
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] i386/kvm: Disable hypercall patching quirk by default
2025-07-23 6:54 ` Xiaoyao Li
@ 2025-07-23 7:53 ` Mathias Krause
2025-07-23 8:42 ` Xiaoyao Li
0 siblings, 1 reply; 6+ messages in thread
From: Mathias Krause @ 2025-07-23 7:53 UTC (permalink / raw)
To: Xiaoyao Li, Paolo Bonzini, qemu-devel
Cc: Marcelo Tosatti, kvm, Oliver Upton, Sean Christopherson
On 23.07.25 08:54, Xiaoyao Li wrote:
> On 7/23/2025 4:43 AM, Mathias Krause wrote:
>> KVM has a weird behaviour when a guest executes VMCALL on an AMD system
>> or VMMCALL on an Intel CPU. Both naturally generate an invalid opcode
>> exception (#UD) as they are just the wrong instruction for the CPU
>> given. But instead of forwarding the exception to the guest, KVM tries
>> to patch the guest instruction to match the host's actual hypercall
>> instruction. That is doomed to fail as read-only code is rather the
>> standard these days. But, instead of letting go the patching attempt and
>> falling back to #UD injection, KVM injects the page fault instead.
>>
>> That's wrong on multiple levels. Not only isn't that a valid exception
>> to be generated by these instructions, confusing attempts to handle
>> them. It also destroys guest state by doing so, namely the value of CR2.
>>
>> Sean attempted to fix that in KVM[1] but the patch was never applied.
>>
>> Later, Oliver added a quirk bit in [2] so the behaviour can, at least,
>> conceptually be disabled. Paolo even called out to add this very
>> functionality to disable the quirk in QEMU[3]. So lets just do it.
>>
>> A new property 'hypercall-patching=on|off' is added, for the very
>> unlikely case that there are setups that really need the patching.
>> However, these would be vulnerable to memory corruption attacks freely
>> overwriting code as they please. So, my guess is, there are exactly 0
>> systems out there requiring this quirk.
>>
>> [1] https://lore.kernel.org/kvm/20211210222903.3417968-1-
>> seanjc@google.com/
>> [2] https://lore.kernel.org/kvm/20220316005538.2282772-2-
>> oupton@google.com/
>> [3] https://lore.kernel.org/kvm/80e1f1d2-2d79-22b7-6665-
>> c00e4fe9cb9c@redhat.com/
>>
>> Cc: Oliver Upton <oliver.upton@linux.dev>
>> Cc: Sean Christopherson <seanjc@google.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> Signed-off-by: Mathias Krause <minipli@grsecurity.net>
>
> I would leave it to Paolo to decide whether a compat property is needed
> to disable the hypercall patching by default for newer machine, and keep
> the old machine with old behavior (hypercall patching is enabled) by
> default.
Bleh, I just noticed that there are KUT tests that actually rely on the
feature[1]. I'll fix these but, looks like, we need to default on for
the feature -- at least for existing machine definitions :(
Looks like I have to go the compat property route.
[1]
https://gitlab.com/kvm-unit-tests/kvm-unit-tests/-/blob/master/x86/vmexit.c?ref_type=heads#L36
>
> The implementation itself looks good to me, exception one nit. And I
> tested that amd guest gets #UD on Intel host with this patch.
>
> Tested-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Thanks a lot!
>
>> ---
>> v2:
>> - rename hypercall_patching_enabled to hypercall_patching (Xiaoyao Li)
>> - make use of error_setg*() (Xiaoyao Li)
>>
>> include/system/kvm_int.h | 1 +
>> qemu-options.hx | 10 +++++++++
>> target/i386/kvm/kvm.c | 45 ++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 56 insertions(+)
>>
>> diff --git a/include/system/kvm_int.h b/include/system/kvm_int.h
>> index 756a3c0a250e..c909464c74a2 100644
>> --- a/include/system/kvm_int.h
>> +++ b/include/system/kvm_int.h
>> @@ -159,6 +159,7 @@ struct KVMState
>> uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk
>> size */
>> struct KVMDirtyRingReaper reaper;
>> struct KVMMsrEnergy msr_energy;
>> + bool hypercall_patching;
>> NotifyVmexitOption notify_vmexit;
>> uint32_t notify_window;
>> uint32_t xen_version;
>> diff --git a/qemu-options.hx b/qemu-options.hx
>> index 1f862b19a676..c2e232649c19 100644
>> --- a/qemu-options.hx
>> +++ b/qemu-options.hx
>> @@ -231,6 +231,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
>> " dirty-ring-size=n (KVM dirty ring GFN count,
>> default 0)\n"
>> " eager-split-size=n (KVM Eager Page Split chunk
>> size, default 0, disabled. ARM only)\n"
>> " notify-vmexit=run|internal-error|
>> disable,notify-window=n (enable notify VM exit and set notify window,
>> x86 only)\n"
>> + " hypercall-patching=on|off (enable KVM's VMCALL/
>> VMMCALL hypercall patching quirk, x86 only)\n"
>> " thread=single|multi (enable multi-threaded TCG)\n"
>> " device=path (KVM device path, default /dev/
>> kvm)\n", QEMU_ARCH_ALL)
>> SRST
>> @@ -313,6 +314,15 @@ SRST
>> open up for a specified of time (i.e. notify-window).
>> Default: notify-vmexit=run,notify-window=0.
>> + ``hypercall-patching=on|off``
>> + KVM tries to recover from the wrong hypercall instruction
>> being used by
>> + a guest by attempting to rewrite it to the one supported
>> natively by
>> + the host CPU (VMCALL on Intel, VMMCALL for AMD systems).
>> However, this
>> + patching may fail if the guest memory is write protected,
>> leading to a
>> + page fault getting propagated to the guest instead of an illegal
>> + instruction exception. As this may confuse guests, it gets
>> disabled by
>> + default (x86 only).
>> +
>> ``device=path``
>> Sets the path to the KVM device node. Defaults to ``/dev/
>> kvm``. This
>> option can be used to pass the KVM device to use via a file
>> descriptor
>> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
>> index 56a6b9b6381a..55f744956970 100644
>> --- a/target/i386/kvm/kvm.c
>> +++ b/target/i386/kvm/kvm.c
>> @@ -3224,6 +3224,26 @@ static int kvm_vm_enable_energy_msrs(KVMState *s)
>> return 0;
>> }
>> +static int kvm_vm_disable_hypercall_patching(KVMState *s, Error
>> **errp)
>> +{
>> + int valid_quirks = kvm_vm_check_extension(s,
>> KVM_CAP_DISABLE_QUIRKS2);
>> + int ret = -1;
>> +
>> + if (valid_quirks & KVM_X86_QUIRK_FIX_HYPERCALL_INSN) {
>> + ret = kvm_vm_enable_cap(s, KVM_CAP_DISABLE_QUIRKS2, 0,
>> + KVM_X86_QUIRK_FIX_HYPERCALL_INSN);
>> + if (ret) {
>> + error_setg_errno(errp, -ret, "kvm: failed to disable "
>> + "hypercall patching quirk: %s",
>> + strerror(-ret));
>> + }
>> + } else {
>> + error_setg(errp, "kvm: disabling hypercall patching not
>> supported");
>> + }
>> +
>> + return ret;
>> +}
>> +
>> int kvm_arch_init(MachineState *ms, KVMState *s)
>> {
>> int ret;
>> @@ -3363,6 +3383,12 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
>> }
>> }
>> + if (s->hypercall_patching == false) {
>
> Nit: it can be
>
> if (!s->hypercall_patching )
That would be my regular style as well but I noticed, there was an
explicit test for 's->msr_energy.enable == true' just a few lines above
and thought QEMU style may differ. But sure, can change it like that.
>
>> + if (kvm_vm_disable_hypercall_patching(s, &local_err)) {
>> + error_report_err(local_err);
>> + }
>> + }
>> +
>> return 0;
>> }
>> @@ -6456,6 +6482,19 @@ void kvm_request_xsave_components(X86CPU
>> *cpu, uint64_t mask)
>> }
>> }
>> +static bool kvm_arch_get_hypercall_patching(Object *obj, Error **errp)
>> +{
>> + KVMState *s = KVM_STATE(obj);
>> + return s->hypercall_patching;
>> +}
>> +
>> +static void kvm_arch_set_hypercall_patching(Object *obj, bool value,
>> + Error **errp)
>> +{
>> + KVMState *s = KVM_STATE(obj);
>> + s->hypercall_patching = value;
>> +}
>> +
>> static int kvm_arch_get_notify_vmexit(Object *obj, Error **errp)
>> {
>> KVMState *s = KVM_STATE(obj);
>> @@ -6589,6 +6628,12 @@ static void
>> kvm_arch_set_xen_evtchn_max_pirq(Object *obj, Visitor *v,
>> void kvm_arch_accel_class_init(ObjectClass *oc)
>> {
>> + object_class_property_add_bool(oc, "hypercall-patching",
>> + kvm_arch_get_hypercall_patching,
>> + kvm_arch_set_hypercall_patching);
>> + object_class_property_set_description(oc, "hypercall-patching",
>> + "Enable hypercall patching
>> quirk");
>> +
>> object_class_property_add_enum(oc, "notify-vmexit",
>> "NotifyVMexitOption",
>> &NotifyVmexitOption_lookup,
>> kvm_arch_get_notify_vmexit,
>
Thanks,
Mathias
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] i386/kvm: Disable hypercall patching quirk by default
2025-07-23 7:53 ` Mathias Krause
@ 2025-07-23 8:42 ` Xiaoyao Li
2025-07-23 8:50 ` Xiaoyao Li
0 siblings, 1 reply; 6+ messages in thread
From: Xiaoyao Li @ 2025-07-23 8:42 UTC (permalink / raw)
To: Mathias Krause, Paolo Bonzini, qemu-devel
Cc: Marcelo Tosatti, kvm, Oliver Upton, Sean Christopherson
On 7/23/2025 3:53 PM, Mathias Krause wrote:
>> I would leave it to Paolo to decide whether a compat property is needed
>> to disable the hypercall patching by default for newer machine, and keep
>> the old machine with old behavior (hypercall patching is enabled) by
>> default.
> Bleh, I just noticed that there are KUT tests that actually rely on the
> feature[1]. I'll fix these but, looks like, we need to default on for
> the feature -- at least for existing machine definitions 🙁
You reminds me.
There is also even a specific KUT hypercall.c, and default off fails it
as well.
enabling apic
smp: waiting for 0 APs
Hypercall via VMCALL: OK
Unhandled exception 6 #UD at ip 00000000004003dd
error_code=0000 rflags=00010002 cs=00000008
rax=00000000ffffffff rcx=00000000000003fd rdx=00000000000003f8
rbx=0000000000000001
rbp=0000000000710ff0 rsi=00000000007107b1 rdi=000000000000000a
r8=00000000007107b1 r9=00000000000003f8 r10=000000000000000d
r11=0000000000000020
r12=0000000000000001 r13=0000000000000000 r14=0000000000000000
r15=0000000000000000
cr0=0000000080000011 cr2=0000000000000000 cr3=000000000040c000
cr4=0000000000000020
cr8=0000000000000000
STACK: @4003dd 4001ad
> Looks like I have to go the compat property route.
>
> [1]
> https://gitlab.com/kvm-unit-tests/kvm-unit-tests/-/blob/master/x86/
> vmexit.c?ref_type=heads#L36
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] i386/kvm: Disable hypercall patching quirk by default
2025-07-23 8:42 ` Xiaoyao Li
@ 2025-07-23 8:50 ` Xiaoyao Li
2025-07-24 19:21 ` Mathias Krause
0 siblings, 1 reply; 6+ messages in thread
From: Xiaoyao Li @ 2025-07-23 8:50 UTC (permalink / raw)
To: Mathias Krause, Paolo Bonzini, qemu-devel
Cc: Marcelo Tosatti, kvm, Oliver Upton, Sean Christopherson
On 7/23/2025 4:42 PM, Xiaoyao Li wrote:
> On 7/23/2025 3:53 PM, Mathias Krause wrote:
>>> I would leave it to Paolo to decide whether a compat property is needed
>>> to disable the hypercall patching by default for newer machine, and keep
>>> the old machine with old behavior (hypercall patching is enabled) by
>>> default.
>> Bleh, I just noticed that there are KUT tests that actually rely on the
>> feature[1]. I'll fix these but, looks like, we need to default on for
>> the feature -- at least for existing machine definitions 🙁
>
> You reminds me.
>
> There is also even a specific KUT hypercall.c, and default off fails it
> as well.
>
> enabling apic
> smp: waiting for 0 APs
> Hypercall via VMCALL: OK
> Unhandled exception 6 #UD at ip 00000000004003dd
> error_code=0000 rflags=00010002 cs=00000008
> rax=00000000ffffffff rcx=00000000000003fd rdx=00000000000003f8
> rbx=0000000000000001
> rbp=0000000000710ff0 rsi=00000000007107b1 rdi=000000000000000a
> r8=00000000007107b1 r9=00000000000003f8 r10=000000000000000d
> r11=0000000000000020
> r12=0000000000000001 r13=0000000000000000 r14=0000000000000000
> r15=0000000000000000
> cr0=0000000080000011 cr2=0000000000000000 cr3=000000000040c000
> cr4=0000000000000020
> cr8=0000000000000000
> STACK: @4003dd 4001ad
>> Looks like I have to go the compat property route.
BTW, the compat property doesn't fix KUT issues actually.
Since KUT doesn't use versioned machine, instead of it always uses the
latest machine.
>>
>> [1]
>> https://gitlab.com/kvm-unit-tests/kvm-unit-tests/-/blob/master/x86/
>> vmexit.c?ref_type=heads#L36
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] i386/kvm: Disable hypercall patching quirk by default
2025-07-23 8:50 ` Xiaoyao Li
@ 2025-07-24 19:21 ` Mathias Krause
0 siblings, 0 replies; 6+ messages in thread
From: Mathias Krause @ 2025-07-24 19:21 UTC (permalink / raw)
To: Xiaoyao Li, Paolo Bonzini, qemu-devel
Cc: Marcelo Tosatti, kvm, Oliver Upton, Sean Christopherson
On 23.07.25 10:50, Xiaoyao Li wrote:
> On 7/23/2025 4:42 PM, Xiaoyao Li wrote:
>> On 7/23/2025 3:53 PM, Mathias Krause wrote:
>>> Bleh, I just noticed that there are KUT tests that actually rely on the
>>> feature[1]. I'll fix these but, looks like, we need to default on for
>>> the feature -- at least for existing machine definitions 🙁
>>
>> You reminds me.
>>
>> There is also even a specific KUT hypercall.c, and default off fails
>> it as well.
>>
>> enabling apic
>> smp: waiting for 0 APs
>> Hypercall via VMCALL: OK
>> Unhandled exception 6 #UD at ip 00000000004003dd
>> error_code=0000 rflags=00010002 cs=00000008
>> rax=00000000ffffffff rcx=00000000000003fd rdx=00000000000003f8
>> rbx=0000000000000001
>> rbp=0000000000710ff0 rsi=00000000007107b1 rdi=000000000000000a
>> r8=00000000007107b1 r9=00000000000003f8 r10=000000000000000d
>> r11=0000000000000020
>> r12=0000000000000001 r13=0000000000000000 r14=0000000000000000
>> r15=0000000000000000
>> cr0=0000000080000011 cr2=0000000000000000 cr3=000000000040c000
>> cr4=0000000000000020
>> cr8=0000000000000000
>> STACK: @4003dd 4001ad
>
>>> Looks like I have to go the compat property route.
>
> BTW, the compat property doesn't fix KUT issues actually.
>
> Since KUT doesn't use versioned machine, instead of it always uses the
> latest machine.
KUT should be good with [1]. However, other similar mini-guests probably
still want the patching. :/
Thanks,
Mathias
[1]
https://lore.kernel.org/kvm/20250724191050.1988675-1-minipli@grsecurity.net/
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-07-24 19:21 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-22 20:43 [PATCH v2] i386/kvm: Disable hypercall patching quirk by default Mathias Krause
2025-07-23 6:54 ` Xiaoyao Li
2025-07-23 7:53 ` Mathias Krause
2025-07-23 8:42 ` Xiaoyao Li
2025-07-23 8:50 ` Xiaoyao Li
2025-07-24 19:21 ` Mathias Krause
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).