[PATCH 4/4] KVM: tell userspace that system_event.ndata is valid

Paolo Bonzini
2022-04-21T18:05:01Z

Now that all architectures are fixed, introduce a new capability
so that userspace knows that it can look at the ndata and data[]
members of run->system_event. Adjust the documentation.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
Documentation/virt/kvm/api.rst | 29 ++++++++++++++++-------------
include/uapi/linux/kvm.h | 1 +
virt/kvm/kvm_main.c | 1 +
3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 72183ae628f7..fe5805ab0d75 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6089,21 +6089,18 @@ should put the acknowledged interrupt vector into the 'epr' field.
#define KVM_SYSTEM_EVENT_RESET 2
#define KVM_SYSTEM_EVENT_CRASH 3
#define KVM_SYSTEM_EVENT_SEV_TERM 4
- #define KVM_SYSTEM_EVENT_NDATA_VALID (1u << 31)
__u32 type;
__u32 ndata;
- __u64 flags;
__u64 data[16];
} system_event;

If exit_reason is KVM_EXIT_SYSTEM_EVENT then the vcpu has triggered
a system-level event using some architecture specific mechanism (hypercall
or some special instruction). In case of ARM64, this is triggered using
-HVC instruction based PSCI call from the vcpu. The 'type' field describes
-the system-level event type. The 'flags' field describes architecture
-specific flags for the system-level event.
+HVC instruction based PSCI call from the vcpu.

-Valid values for bits 30:0 of 'type' are:
+The 'type' field describes the system-level event type.
+Valid values for 'type' are:

- KVM_SYSTEM_EVENT_SHUTDOWN -- the guest has requested a shutdown of the
VM. Userspace is not obliged to honour this, and if it does honour
@@ -6117,16 +6114,23 @@ Valid values for bits 30:0 of 'type' are:
to ignore the request, or to gather VM memory core dump and/or
reset/shutdown of the VM.
- KVM_SYSTEM_EVENT_SEV_TERM -- an AMD SEV guest requested termination.
- The guest physical address of the guest's GHCB is stored in `data[0]`.

-Valid flags are:
+If KVM_CAP_SYSTEM_EVENT_DATA is present, the 'data' field can contain
+architecture specific information for the system-level event. Only
+the first `ndata` items (possibly zero) of the data array are valid.
+
+ - for arm64, data[0] is set to KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 if
+ the guest issued a SYSTEM_RESET2 call according to v1.1 of the PSCI
+ specification.
+
+ - for RISC-V, data[0] is set to the value of the second argument of the
+ ``sbi_system_reset`` call.

- - KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (arm64 only) -- the guest issued
- a SYSTEM_RESET2 call according to v1.1 of the PSCI specification.
+ - for x86, KVM_SYSTEM_EVENT_SEV_TERM stores the guest physical address of the
+ guest's GHCB in `data[0]`.

-Extra data for this event is stored in the `data[]` array, up to index
-`ndata-1` included, if bit 31 is set in `type`. The data depends on the
-`type` field. There is no extra data if bit 31 is clear or `ndata` is zero.
+Previous versions of Linux defined a `flags` member in this struct. The
+field however was never written.

::

diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 5a57f74b4903..f76ffecda38a 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1147,6 +1147,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_PMU_CAPABILITY 212
#define KVM_CAP_DISABLE_QUIRKS2 213
#define KVM_CAP_VM_TSC_CONTROL 214
+#define KVM_CAP_SYSTEM_EVENT_DATA 215

#ifdef KVM_CAP_IRQ_ROUTING

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index dfb7dabdbc63..ac57fc2c935f 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -4333,6 +4333,7 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
return 0;
#endif
case KVM_CAP_BINARY_STATS_FD:
+ case KVM_CAP_SYSTEM_EVENT_DATA:
return 1;
default:
break;
--
2.31.1