Import the hypervisor definitions needed to intercept guest exceptions
and to inject events back into a guest, in preparation for gdbstub
debugging support in the MSHV accelerator.
Add:
- union hv_intercept_parameters, struct hv_input_install_intercept and
HVCALL_INSTALL_INTERCEPT, used to install an exception intercept on
the partition;
- struct hv_x64_exception_intercept_message, the message delivered on
an intercepted exception, carrying the faulting RIP, the exception
vector and the instruction bytes;
- HV_X64_PENDING_EVENT_EXCEPTION, the pending-event type for an
exception.
These definitions mirror the hypervisor headers and have no functional
effect on their own.
Signed-off-by: Doru Blânzeanu <[email protected]>
---
include/hw/hyperv/hvgdk_mini.h | 56 ++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/include/hw/hyperv/hvgdk_mini.h b/include/hw/hyperv/hvgdk_mini.h
index f8838a31bb..c81928d0c2 100644
--- a/include/hw/hyperv/hvgdk_mini.h
+++ b/include/hw/hyperv/hvgdk_mini.h
@@ -22,6 +22,9 @@
#define HV_X64_MSR_TSC_FREQUENCY 0x40000022
#define HV_X64_MSR_APIC_FREQUENCY 0x40000023
+/* event_type values for hv_x64_pending_exception_event */
+#define HV_X64_PENDING_EVENT_EXCEPTION 0
+
typedef enum hv_register_name {
/* Pending Interruption Register */
HV_REGISTER_PENDING_INTERRUPTION = 0x00010002,
@@ -236,6 +239,29 @@ enum hv_intercept_type {
HV_INTERCEPT_TYPE_INVALID = 0XFFFFFFFF,
};
+union hv_intercept_parameters {
+ /* HV_INTERCEPT_PARAMETERS is defined to be an 8-byte field. */
+ uint64_t as_uint64;
+ /* HV_INTERCEPT_TYPE_X64_IO_PORT */
+ uint16_t io_port;
+ /* HV_INTERCEPT_TYPE_X64_CPUID */
+ uint32_t cpuid_index;
+ /* HV_INTERCEPT_TYPE_X64_APIC_WRITE */
+ uint32_t apic_write_mask;
+ /* HV_INTERCEPT_TYPE_EXCEPTION */
+ uint16_t exception_vector;
+ /* HV_INTERCEPT_TYPE_X64_MSR_INDEX */
+ uint32_t msr_index;
+ /* N.B. Other intercept types do not have any parameters. */
+};
+
+struct hv_input_install_intercept {
+ uint64_t partition_id;
+ uint32_t access_type; /* mask */
+ uint32_t intercept_type; /* enum hv_intercept_type */
+ union hv_intercept_parameters intercept_parameter;
+} QEMU_PACKED;
+
struct hv_u128 {
uint64_t low_part;
uint64_t high_part;
@@ -836,6 +862,35 @@ struct hv_x64_memory_intercept_message {
uint8_t instruction_bytes[16];
} QEMU_PACKED;
+struct hv_x64_exception_intercept_message {
+ struct hv_x64_intercept_message_header header;
+ uint16_t exception_vector;
+ uint8_t exception_info;
+ uint8_t instruction_byte_count;
+ uint32_t error_code;
+ uint64_t exception_parameter; /* DR6 for #DB, CR2 for #PF */
+ uint64_t reserved;
+ uint8_t instruction_bytes[16];
+ struct hv_x64_segment_register ds_segment;
+ struct hv_x64_segment_register ss_segment;
+ uint64_t rax;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rbx;
+ uint64_t rsp;
+ uint64_t rbp;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+} QEMU_PACKED;
+
union hv_message_flags {
uint8_t asu8;
struct {
@@ -943,6 +998,7 @@ struct hv_cpuid {
#define HVCALL_GET_PARTITION_PROPERTY 0x0044
#define HVCALL_SET_PARTITION_PROPERTY 0x0045
+#define HVCALL_INSTALL_INTERCEPT 0x004d
#define HVCALL_GET_VP_REGISTERS 0x0050
#define HVCALL_SET_VP_REGISTERS 0x0051
#define HVCALL_TRANSLATE_VIRTUAL_ADDRESS 0x0052
--
2.53.0