A few additional definitions are required for the mshv driver code
(to follow). Introduce those here and clean up a little bit while
at it.
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
---
include/hyperv/hvgdk_mini.h | 64 ++++++++++++++++-
include/hyperv/hvhdk.h | 132 ++++++++++++++++++++++++++++++++++--
include/hyperv/hvhdk_mini.h | 91 +++++++++++++++++++++++++
3 files changed, 280 insertions(+), 7 deletions(-)
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index 58895883f636..e4a3cca0cbce 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -13,7 +13,7 @@ struct hv_u128 {
u64 high_part;
} __packed;
-/* NOTE: when adding below, update hv_status_to_string() */
+/* NOTE: when adding below, update hv_result_to_string() */
#define HV_STATUS_SUCCESS 0x0
#define HV_STATUS_INVALID_HYPERCALL_CODE 0x2
#define HV_STATUS_INVALID_HYPERCALL_INPUT 0x3
@@ -51,6 +51,7 @@ struct hv_u128 {
#define HV_HYP_PAGE_SHIFT 12
#define HV_HYP_PAGE_SIZE BIT(HV_HYP_PAGE_SHIFT)
#define HV_HYP_PAGE_MASK (~(HV_HYP_PAGE_SIZE - 1))
+#define HV_HYP_LARGE_PAGE_SHIFT 21
#define HV_PARTITION_ID_INVALID ((u64)0)
#define HV_PARTITION_ID_SELF ((u64)-1)
@@ -374,6 +375,10 @@ union hv_hypervisor_version_info {
#define HV_SHARED_GPA_BOUNDARY_ACTIVE BIT(5)
#define HV_SHARED_GPA_BOUNDARY_BITS GENMASK(11, 6)
+/* HYPERV_CPUID_FEATURES.ECX bits. */
+#define HV_VP_DISPATCH_INTERRUPT_INJECTION_AVAILABLE BIT(9)
+#define HV_VP_GHCB_ROOT_MAPPING_AVAILABLE BIT(10)
+
enum hv_isolation_type {
HV_ISOLATION_TYPE_NONE = 0, /* HV_PARTITION_ISOLATION_TYPE_NONE */
HV_ISOLATION_TYPE_VBS = 1,
@@ -437,9 +442,12 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_MAP_GPA_PAGES 0x004b
#define HVCALL_UNMAP_GPA_PAGES 0x004c
#define HVCALL_CREATE_VP 0x004e
+#define HVCALL_INSTALL_INTERCEPT 0x004d
#define HVCALL_DELETE_VP 0x004f
#define HVCALL_GET_VP_REGISTERS 0x0050
#define HVCALL_SET_VP_REGISTERS 0x0051
+#define HVCALL_TRANSLATE_VIRTUAL_ADDRESS 0x0052
+#define HVCALL_CLEAR_VIRTUAL_INTERRUPT 0x0056
#define HVCALL_DELETE_PORT 0x0058
#define HVCALL_DISCONNECT_PORT 0x005b
#define HVCALL_POST_MESSAGE 0x005c
@@ -447,12 +455,15 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_POST_DEBUG_DATA 0x0069
#define HVCALL_RETRIEVE_DEBUG_DATA 0x006a
#define HVCALL_RESET_DEBUG_SESSION 0x006b
+#define HVCALL_MAP_STATS_PAGE 0x006c
+#define HVCALL_UNMAP_STATS_PAGE 0x006d
#define HVCALL_ADD_LOGICAL_PROCESSOR 0x0076
#define HVCALL_GET_SYSTEM_PROPERTY 0x007b
#define HVCALL_MAP_DEVICE_INTERRUPT 0x007c
#define HVCALL_UNMAP_DEVICE_INTERRUPT 0x007d
#define HVCALL_RETARGET_INTERRUPT 0x007e
#define HVCALL_NOTIFY_PORT_RING_EMPTY 0x008b
+#define HVCALL_REGISTER_INTERCEPT_RESULT 0x0091
#define HVCALL_ASSERT_VIRTUAL_INTERRUPT 0x0094
#define HVCALL_CREATE_PORT 0x0095
#define HVCALL_CONNECT_PORT 0x0096
@@ -460,12 +471,18 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_GET_VP_ID_FROM_APIC_ID 0x009a
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
+#define HVCALL_SIGNAL_EVENT_DIRECT 0x00c0
+#define HVCALL_POST_MESSAGE_DIRECT 0x00c1
#define HVCALL_DISPATCH_VP 0x00c2
+#define HVCALL_GET_GPA_PAGES_ACCESS_STATES 0x00c9
+#define HVCALL_ACQUIRE_SPARSE_SPA_PAGE_HOST_ACCESS 0x00d7
+#define HVCALL_RELEASE_SPARSE_SPA_PAGE_HOST_ACCESS 0x00d8
#define HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY 0x00db
#define HVCALL_MAP_VP_STATE_PAGE 0x00e1
#define HVCALL_UNMAP_VP_STATE_PAGE 0x00e2
#define HVCALL_GET_VP_STATE 0x00e3
#define HVCALL_SET_VP_STATE 0x00e4
+#define HVCALL_GET_VP_CPUID_VALUES 0x00f4
#define HVCALL_MMIO_READ 0x0106
#define HVCALL_MMIO_WRITE 0x0107
@@ -807,6 +824,8 @@ struct hv_x64_table_register {
u64 base;
} __packed;
+#define HV_NORMAL_VTL 0
+
union hv_input_vtl {
u8 as_uint8;
struct {
@@ -1325,6 +1344,49 @@ struct hv_retarget_device_interrupt { /* HV_INPUT_RETARGET_DEVICE_INTERRUPT */
struct hv_device_interrupt_target int_target;
} __packed __aligned(8);
+enum hv_intercept_type {
+#if defined(CONFIG_X86_64)
+ HV_INTERCEPT_TYPE_X64_IO_PORT = 0x00000000,
+ HV_INTERCEPT_TYPE_X64_MSR = 0x00000001,
+ HV_INTERCEPT_TYPE_X64_CPUID = 0x00000002,
+#endif
+ HV_INTERCEPT_TYPE_EXCEPTION = 0x00000003,
+ /* Used to be HV_INTERCEPT_TYPE_REGISTER */
+ HV_INTERCEPT_TYPE_RESERVED0 = 0x00000004,
+ HV_INTERCEPT_TYPE_MMIO = 0x00000005,
+#if defined(CONFIG_X86_64)
+ HV_INTERCEPT_TYPE_X64_GLOBAL_CPUID = 0x00000006,
+ HV_INTERCEPT_TYPE_X64_APIC_SMI = 0x00000007,
+#endif
+ HV_INTERCEPT_TYPE_HYPERCALL = 0x00000008,
+#if defined(CONFIG_X86_64)
+ HV_INTERCEPT_TYPE_X64_APIC_INIT_SIPI = 0x00000009,
+ HV_INTERCEPT_MC_UPDATE_PATCH_LEVEL_MSR_READ = 0x0000000A,
+ HV_INTERCEPT_TYPE_X64_APIC_WRITE = 0x0000000B,
+ HV_INTERCEPT_TYPE_X64_MSR_INDEX = 0x0000000C,
+#endif
+ HV_INTERCEPT_TYPE_MAX,
+ HV_INTERCEPT_TYPE_INVALID = 0xFFFFFFFF,
+};
+
+union hv_intercept_parameters {
+ /* HV_INTERCEPT_PARAMETERS is defined to be an 8-byte field. */
+ __u64 as_uint64;
+#if defined(CONFIG_X86_64)
+ /* HV_INTERCEPT_TYPE_X64_IO_PORT */
+ __u16 io_port;
+ /* HV_INTERCEPT_TYPE_X64_CPUID */
+ __u32 cpuid_index;
+ /* HV_INTERCEPT_TYPE_X64_APIC_WRITE */
+ __u32 apic_write_mask;
+ /* HV_INTERCEPT_TYPE_EXCEPTION */
+ __u16 exception_vector;
+ /* HV_INTERCEPT_TYPE_X64_MSR_INDEX */
+ __u32 msr_index;
+#endif
+ /* N.B. Other intercept types do not have any parameters. */
+};
+
/* Data structures for HVCALL_MMIO_READ and HVCALL_MMIO_WRITE */
#define HV_HYPERCALL_MMIO_MAX_DATA_LENGTH 64
diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
index 64407c2a3809..1b447155c338 100644
--- a/include/hyperv/hvhdk.h
+++ b/include/hyperv/hvhdk.h
@@ -19,11 +19,24 @@
#define HV_VP_REGISTER_PAGE_VERSION_1 1u
+#define HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT 7
+
+union hv_vp_register_page_interrupt_vectors {
+ u64 as_uint64;
+ struct {
+ u8 vector_count;
+ u8 vector[HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT];
+ } __packed;
+} __packed;
+
struct hv_vp_register_page {
u16 version;
u8 isvalid;
u8 rsvdz;
u32 dirty;
+
+#if IS_ENABLED(CONFIG_X86)
+
union {
struct {
/* General purpose registers
@@ -95,6 +108,22 @@ struct hv_vp_register_page {
union hv_x64_pending_interruption_register pending_interruption;
union hv_x64_interrupt_state_register interrupt_state;
u64 instruction_emulation_hints;
+ u64 xfem;
+
+ /*
+ * Fields from this point are not included in the register page save chunk.
+ * The reserved field is intended to maintain alignment for unsaved fields.
+ */
+ u8 reserved1[0x100];
+
+ /*
+ * Interrupts injected as part of HvCallDispatchVp.
+ */
+ union hv_vp_register_page_interrupt_vectors interrupt_vectors;
+
+#elif IS_ENABLED(CONFIG_ARM64)
+ /* Not yet supported in ARM */
+#endif
} __packed;
#define HV_PARTITION_PROCESSOR_FEATURES_BANKS 2
@@ -299,10 +328,11 @@ union hv_partition_isolation_properties {
#define HV_PARTITION_ISOLATION_HOST_TYPE_RESERVED 0x2
/* Note: Exo partition is enabled by default */
-#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
-#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
-#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
-#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
+#define HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED BIT(4)
+#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
+#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
+#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
+#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
struct hv_input_create_partition {
u64 flags;
@@ -349,13 +379,23 @@ struct hv_input_set_partition_property {
enum hv_vp_state_page_type {
HV_VP_STATE_PAGE_REGISTERS = 0,
HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1,
+ HV_VP_STATE_PAGE_GHCB,
HV_VP_STATE_PAGE_COUNT
};
struct hv_input_map_vp_state_page {
u64 partition_id;
u32 vp_index;
- u32 type; /* enum hv_vp_state_page_type */
+ u16 type; /* enum hv_vp_state_page_type */
+ union hv_input_vtl input_vtl;
+ union {
+ u8 as_uint8;
+ struct {
+ u8 map_location_provided : 1;
+ u8 reserved : 7;
+ };
+ } flags;
+ u64 requested_map_location;
} __packed;
struct hv_output_map_vp_state_page {
@@ -365,7 +405,14 @@ struct hv_output_map_vp_state_page {
struct hv_input_unmap_vp_state_page {
u64 partition_id;
u32 vp_index;
- u32 type; /* enum hv_vp_state_page_type */
+ u16 type; /* enum hv_vp_state_page_type */
+ union hv_input_vtl input_vtl;
+ u8 reserved0;
+} __packed;
+
+struct hv_x64_apic_eoi_message {
+ __u32 vp_index;
+ __u32 interrupt_vector;
} __packed;
struct hv_opaque_intercept_message {
@@ -515,6 +562,13 @@ struct hv_synthetic_timers_state {
u64 reserved[5];
} __packed;
+struct hv_async_completion_message_payload {
+ __u64 partition_id;
+ __u32 status;
+ __u32 completion_count;
+ __u64 sub_status;
+} __packed;
+
union hv_input_delete_vp {
u64 as_uint64[2];
struct {
@@ -649,6 +703,57 @@ struct hv_input_set_vp_state {
union hv_input_set_vp_state_data data[];
} __packed;
+union hv_x64_vp_execution_state {
+ __u16 as_uint16;
+ struct {
+ __u16 cpl:2;
+ __u16 cr0_pe:1;
+ __u16 cr0_am:1;
+ __u16 efer_lma:1;
+ __u16 debug_active:1;
+ __u16 interruption_pending:1;
+ __u16 vtl:4;
+ __u16 enclave_mode:1;
+ __u16 interrupt_shadow:1;
+ __u16 virtualization_fault_active:1;
+ __u16 reserved:2;
+ } __packed;
+};
+
+struct hv_x64_intercept_message_header {
+ __u32 vp_index;
+ __u8 instruction_length:4;
+ __u8 cr8:4; /* Only set for exo partitions */
+ __u8 intercept_access_type;
+ union hv_x64_vp_execution_state execution_state;
+ struct hv_x64_segment_register cs_segment;
+ __u64 rip;
+ __u64 rflags;
+} __packed;
+
+union hv_x64_memory_access_info {
+ __u8 as_uint8;
+ struct {
+ __u8 gva_valid:1;
+ __u8 gva_gpa_valid:1;
+ __u8 hypercall_output_pending:1;
+ __u8 tlb_locked_no_overlay:1;
+ __u8 reserved:4;
+ } __packed;
+};
+
+struct hv_x64_memory_intercept_message {
+ struct hv_x64_intercept_message_header header;
+ __u32 cache_type; /* enum hv_cache_type */
+ __u8 instruction_byte_count;
+ union hv_x64_memory_access_info memory_access_info;
+ __u8 tpr_priority;
+ __u8 reserved1;
+ __u64 guest_virtual_address;
+ __u64 guest_physical_address;
+ __u8 instruction_bytes[16];
+} __packed;
+
/*
* Dispatch state for the VP communicated by the hypervisor to the
* VP-dispatching thread in the root on return from HVCALL_DISPATCH_VP.
@@ -716,6 +821,7 @@ static_assert(sizeof(struct hv_vp_signal_pair_scheduler_message) ==
#define HV_DISPATCH_VP_FLAG_SKIP_VP_SPEC_FLUSH 0x8
#define HV_DISPATCH_VP_FLAG_SKIP_CALLER_SPEC_FLUSH 0x10
#define HV_DISPATCH_VP_FLAG_SKIP_CALLER_USER_SPEC_FLUSH 0x20
+#define HV_DISPATCH_VP_FLAG_SCAN_INTERRUPT_INJECTION 0x40
struct hv_input_dispatch_vp {
u64 partition_id;
@@ -730,4 +836,18 @@ struct hv_output_dispatch_vp {
u32 dispatch_event; /* enum hv_vp_dispatch_event */
} __packed;
+struct hv_input_modify_sparse_spa_page_host_access {
+ u32 host_access : 2;
+ u32 reserved : 30;
+ u32 flags;
+ u64 partition_id;
+ u64 spa_page_list[];
+} __packed;
+
+/* hv_input_modify_sparse_spa_page_host_access flags */
+#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE 0x1
+#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_SHARED 0x2
+#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE 0x4
+#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_HUGE_PAGE 0x8
+
#endif /* _HV_HVHDK_H */
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index f8a39d3e9ce6..42e7876455b5 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -36,6 +36,52 @@ enum hv_scheduler_type {
HV_SCHEDULER_TYPE_MAX
};
+/* HV_STATS_AREA_TYPE */
+enum hv_stats_area_type {
+ HV_STATS_AREA_SELF = 0,
+ HV_STATS_AREA_PARENT = 1,
+ HV_STATS_AREA_INTERNAL = 2,
+ HV_STATS_AREA_COUNT
+};
+
+enum hv_stats_object_type {
+ HV_STATS_OBJECT_HYPERVISOR = 0x00000001,
+ HV_STATS_OBJECT_LOGICAL_PROCESSOR = 0x00000002,
+ HV_STATS_OBJECT_PARTITION = 0x00010001,
+ HV_STATS_OBJECT_VP = 0x00010002
+};
+
+union hv_stats_object_identity {
+ /* hv_stats_hypervisor */
+ struct {
+ u8 reserved[15];
+ u8 stats_area_type;
+ } __packed hv;
+
+ /* hv_stats_logical_processor */
+ struct {
+ u32 lp_index;
+ u8 reserved[11];
+ u8 stats_area_type;
+ } __packed lp;
+
+ /* hv_stats_partition */
+ struct {
+ u64 partition_id;
+ u8 reserved[7];
+ u8 stats_area_type;
+ } __packed partition;
+
+ /* hv_stats_vp */
+ struct {
+ u64 partition_id;
+ u32 vp_index;
+ u16 flags;
+ u8 reserved;
+ u8 stats_area_type;
+ } __packed vp;
+};
+
enum hv_partition_property_code {
/* Privilege properties */
HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS = 0x00010000,
@@ -47,19 +93,45 @@ enum hv_partition_property_code {
/* Compatibility properties */
HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES = 0x00060002,
+ HV_PARTITION_PROPERTY_XSAVE_STATES = 0x00060007,
HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE = 0x00060008,
HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY = 0x00060009,
};
+enum hv_snp_status {
+ HV_SNP_STATUS_NONE = 0,
+ HV_SNP_STATUS_AVAILABLE = 1,
+ HV_SNP_STATUS_INCOMPATIBLE = 2,
+ HV_SNP_STATUS_PSP_UNAVAILABLE = 3,
+ HV_SNP_STATUS_PSP_INIT_FAILED = 4,
+ HV_SNP_STATUS_PSP_BAD_FW_VERSION = 5,
+ HV_SNP_STATUS_BAD_CONFIGURATION = 6,
+ HV_SNP_STATUS_PSP_FW_UPDATE_IN_PROGRESS = 7,
+ HV_SNP_STATUS_PSP_RB_INIT_FAILED = 8,
+ HV_SNP_STATUS_PSP_PLATFORM_STATUS_FAILED = 9,
+ HV_SNP_STATUS_PSP_INIT_LATE_FAILED = 10,
+};
+
enum hv_system_property {
/* Add more values when needed */
HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15,
+ HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21,
+};
+
+enum hv_dynamic_processor_feature_property {
+ /* Add more values when needed */
+ HV_X64_DYNAMIC_PROCESSOR_FEATURE_MAX_ENCRYPTED_PARTITIONS = 13,
+ HV_X64_DYNAMIC_PROCESSOR_FEATURE_SNP_STATUS = 16,
};
struct hv_input_get_system_property {
u32 property_id; /* enum hv_system_property */
union {
u32 as_uint32;
+#if IS_ENABLED(CONFIG_X86)
+ /* enum hv_dynamic_processor_feature_property */
+ u32 hv_processor_feature;
+#endif
/* More fields to be filled in when needed */
};
} __packed;
@@ -67,9 +139,28 @@ struct hv_input_get_system_property {
struct hv_output_get_system_property {
union {
u32 scheduler_type; /* enum hv_scheduler_type */
+#if IS_ENABLED(CONFIG_X86)
+ u64 hv_processor_feature_value;
+#endif
};
} __packed;
+struct hv_input_map_stats_page {
+ u32 type; /* enum hv_stats_object_type */
+ u32 padding;
+ union hv_stats_object_identity identity;
+} __packed;
+
+struct hv_output_map_stats_page {
+ u64 map_location;
+} __packed;
+
+struct hv_input_unmap_stats_page {
+ u32 type; /* enum hv_stats_object_type */
+ u32 padding;
+ union hv_stats_object_identity identity;
+} __packed;
+
struct hv_proximity_domain_flags {
u32 proximity_preferred : 1;
u32 reserved : 30;
--
2.34.1
On Thu, Feb 27, 2025 at 7:11 AM Nuno Das Neves <nunodasneves@linux.microsoft.com> wrote: > > A few additional definitions are required for the mshv driver code > (to follow). Introduce those here and clean up a little bit while > at it. > > Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com> > --- It may be better to unify data type u8, u16, u32, u64 or __u8, __u16, __u32, __u64 in the hvhdk.h. Others like good. Reviewed-by: Tianyu Lan <tiala@microsoft.com> -- Thanks Tianyu Lan
On 3/10/2025 5:40 AM, Tianyu Lan wrote: > On Thu, Feb 27, 2025 at 7:11 AM Nuno Das Neves > <nunodasneves@linux.microsoft.com> wrote: >> >> A few additional definitions are required for the mshv driver code >> (to follow). Introduce those here and clean up a little bit while >> at it. >> >> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com> >> --- > > It may be better to unify data type u8, u16, u32, u64 or __u8, __u16, > __u32, __u64 in the hvhdk.h. > Agreed, this was an oversight. They should all be the kernel types without the __ prefix. Thanks Nuno > Others like good. > > Reviewed-by: Tianyu Lan <tiala@microsoft.com> >
On 2/26/2025 3:08 PM, Nuno Das Neves wrote:
> A few additional definitions are required for the mshv driver code
> (to follow). Introduce those here and clean up a little bit while
> at it.
>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
> include/hyperv/hvgdk_mini.h | 64 ++++++++++++++++-
> include/hyperv/hvhdk.h | 132 ++++++++++++++++++++++++++++++++++--
> include/hyperv/hvhdk_mini.h | 91 +++++++++++++++++++++++++
> 3 files changed, 280 insertions(+), 7 deletions(-)
>
> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
> index 58895883f636..e4a3cca0cbce 100644
> --- a/include/hyperv/hvgdk_mini.h
> +++ b/include/hyperv/hvgdk_mini.h
> @@ -13,7 +13,7 @@ struct hv_u128 {
> u64 high_part;
> } __packed;
>
<snip>
> union hv_input_vtl {
> u8 as_uint8;
> struct {
> @@ -1325,6 +1344,49 @@ struct hv_retarget_device_interrupt { /* HV_INPUT_RETARGET_DEVICE_INTERRUPT */
> struct hv_device_interrupt_target int_target;
> } __packed __aligned(8);
>
> +enum hv_intercept_type {
> +#if defined(CONFIG_X86_64)
These chosen ifdef's come across kinda arbitrary. The hypervisor code has
this enabled for both 32-bit and 64-bit x86, but you've chosen x86_64 only.
I thought that may be because we only intend to support root partition for 64-bit
platforms, but then, below...
> + HV_INTERCEPT_TYPE_X64_IO_PORT = 0x00000000,
> + HV_INTERCEPT_TYPE_X64_MSR = 0x00000001,
> + HV_INTERCEPT_TYPE_X64_CPUID = 0x00000002,
> +#endif
> + HV_INTERCEPT_TYPE_EXCEPTION = 0x00000003,
> + /* Used to be HV_INTERCEPT_TYPE_REGISTER */
> + HV_INTERCEPT_TYPE_RESERVED0 = 0x00000004,
> + HV_INTERCEPT_TYPE_MMIO = 0x00000005,
> +#if defined(CONFIG_X86_64)
> + HV_INTERCEPT_TYPE_X64_GLOBAL_CPUID = 0x00000006,
> + HV_INTERCEPT_TYPE_X64_APIC_SMI = 0x00000007,
> +#endif
> + HV_INTERCEPT_TYPE_HYPERCALL = 0x00000008,
> +#if defined(CONFIG_X86_64)
> + HV_INTERCEPT_TYPE_X64_APIC_INIT_SIPI = 0x00000009,
> + HV_INTERCEPT_MC_UPDATE_PATCH_LEVEL_MSR_READ = 0x0000000A,
> + HV_INTERCEPT_TYPE_X64_APIC_WRITE = 0x0000000B,
> + HV_INTERCEPT_TYPE_X64_MSR_INDEX = 0x0000000C,
> +#endif
> + HV_INTERCEPT_TYPE_MAX,
> + HV_INTERCEPT_TYPE_INVALID = 0xFFFFFFFF,
> +};
> +
> +union hv_intercept_parameters {
> + /* HV_INTERCEPT_PARAMETERS is defined to be an 8-byte field. */
> + __u64 as_uint64;
> +#if defined(CONFIG_X86_64)
> + /* HV_INTERCEPT_TYPE_X64_IO_PORT */
> + __u16 io_port;
> + /* HV_INTERCEPT_TYPE_X64_CPUID */
> + __u32 cpuid_index;
> + /* HV_INTERCEPT_TYPE_X64_APIC_WRITE */
> + __u32 apic_write_mask;
> + /* HV_INTERCEPT_TYPE_EXCEPTION */
> + __u16 exception_vector;
> + /* HV_INTERCEPT_TYPE_X64_MSR_INDEX */
> + __u32 msr_index;
> +#endif
> + /* N.B. Other intercept types do not have any parameters. */
> +};
> +
> /* Data structures for HVCALL_MMIO_READ and HVCALL_MMIO_WRITE */
> #define HV_HYPERCALL_MMIO_MAX_DATA_LENGTH 64
>
> diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
> index 64407c2a3809..1b447155c338 100644
> --- a/include/hyperv/hvhdk.h
> +++ b/include/hyperv/hvhdk.h
> @@ -19,11 +19,24 @@
>
> #define HV_VP_REGISTER_PAGE_VERSION_1 1u
>
> +#define HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT 7
> +
> +union hv_vp_register_page_interrupt_vectors {
> + u64 as_uint64;
> + struct {
> + u8 vector_count;
> + u8 vector[HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT];
> + } __packed;
> +} __packed;
> +
> struct hv_vp_register_page {
> u16 version;
> u8 isvalid;
> u8 rsvdz;
> u32 dirty;
> +
> +#if IS_ENABLED(CONFIG_X86)
> +
...you've chosen to include 32bit here, where the hypervisor code supports both.
Confused
> union {
> struct {
> /* General purpose registers
> @@ -95,6 +108,22 @@ struct hv_vp_register_page {
> union hv_x64_pending_interruption_register pending_interruption;
> union hv_x64_interrupt_state_register interrupt_state;
> u64 instruction_emulation_hints;
> + u64 xfem;
> +
> + /*
> + * Fields from this point are not included in the register page save chunk.
> + * The reserved field is intended to maintain alignment for unsaved fields.
> + */
> + u8 reserved1[0x100];
> +
> + /*
> + * Interrupts injected as part of HvCallDispatchVp.
> + */
> + union hv_vp_register_page_interrupt_vectors interrupt_vectors;
> +
> +#elif IS_ENABLED(CONFIG_ARM64)
> + /* Not yet supported in ARM */
> +#endif
> } __packed;
>
> #define HV_PARTITION_PROCESSOR_FEATURES_BANKS 2
> @@ -299,10 +328,11 @@ union hv_partition_isolation_properties {
> #define HV_PARTITION_ISOLATION_HOST_TYPE_RESERVED 0x2
>
> /* Note: Exo partition is enabled by default */
> -#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
> -#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
> -#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
> -#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
> +#define HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED BIT(4)
> +#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
> +#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
> +#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
> +#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
>
> struct hv_input_create_partition {
> u64 flags;
> @@ -349,13 +379,23 @@ struct hv_input_set_partition_property {
> enum hv_vp_state_page_type {
> HV_VP_STATE_PAGE_REGISTERS = 0,
> HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1,
> + HV_VP_STATE_PAGE_GHCB,
> HV_VP_STATE_PAGE_COUNT
> };
>
> struct hv_input_map_vp_state_page {
> u64 partition_id;
> u32 vp_index;
> - u32 type; /* enum hv_vp_state_page_type */
> + u16 type; /* enum hv_vp_state_page_type */
> + union hv_input_vtl input_vtl;
> + union {
> + u8 as_uint8;
> + struct {
> + u8 map_location_provided : 1;
> + u8 reserved : 7;
> + };
> + } flags;
> + u64 requested_map_location;
> } __packed;
>
> struct hv_output_map_vp_state_page {
> @@ -365,7 +405,14 @@ struct hv_output_map_vp_state_page {
> struct hv_input_unmap_vp_state_page {
> u64 partition_id;
> u32 vp_index;
> - u32 type; /* enum hv_vp_state_page_type */
> + u16 type; /* enum hv_vp_state_page_type */
> + union hv_input_vtl input_vtl;
> + u8 reserved0;
> +} __packed;
> +
> +struct hv_x64_apic_eoi_message {
> + __u32 vp_index;
> + __u32 interrupt_vector;
Can these be plain u32? Similar below...
> } __packed;
>
> struct hv_opaque_intercept_message {
> @@ -515,6 +562,13 @@ struct hv_synthetic_timers_state {
> u64 reserved[5];
> } __packed;
>
> +struct hv_async_completion_message_payload {
> + __u64 partition_id;
> + __u32 status;
> + __u32 completion_count;
> + __u64 sub_status;
> +} __packed;
> +
> union hv_input_delete_vp {
> u64 as_uint64[2];
> struct {
> @@ -649,6 +703,57 @@ struct hv_input_set_vp_state {
> union hv_input_set_vp_state_data data[];
> } __packed;
>
> +union hv_x64_vp_execution_state {
> + __u16 as_uint16;
> + struct {
> + __u16 cpl:2;
> + __u16 cr0_pe:1;
> + __u16 cr0_am:1;
> + __u16 efer_lma:1;
> + __u16 debug_active:1;
> + __u16 interruption_pending:1;
> + __u16 vtl:4;
> + __u16 enclave_mode:1;
> + __u16 interrupt_shadow:1;
> + __u16 virtualization_fault_active:1;
> + __u16 reserved:2;
> + } __packed;
> +};
> +
> +struct hv_x64_intercept_message_header {
> + __u32 vp_index;
> + __u8 instruction_length:4;
> + __u8 cr8:4; /* Only set for exo partitions */
> + __u8 intercept_access_type;
> + union hv_x64_vp_execution_state execution_state;
> + struct hv_x64_segment_register cs_segment;
> + __u64 rip;
> + __u64 rflags;
> +} __packed;
> +
> +union hv_x64_memory_access_info {
> + __u8 as_uint8;
> + struct {
> + __u8 gva_valid:1;
> + __u8 gva_gpa_valid:1;
> + __u8 hypercall_output_pending:1;
> + __u8 tlb_locked_no_overlay:1;
> + __u8 reserved:4;
> + } __packed;
> +};
> +
> +struct hv_x64_memory_intercept_message {
> + struct hv_x64_intercept_message_header header;
> + __u32 cache_type; /* enum hv_cache_type */
> + __u8 instruction_byte_count;
> + union hv_x64_memory_access_info memory_access_info;
> + __u8 tpr_priority;
> + __u8 reserved1;
> + __u64 guest_virtual_address;
> + __u64 guest_physical_address;
> + __u8 instruction_bytes[16];
> +} __packed;
> +
> /*
> * Dispatch state for the VP communicated by the hypervisor to the
> * VP-dispatching thread in the root on return from HVCALL_DISPATCH_VP.
> @@ -716,6 +821,7 @@ static_assert(sizeof(struct hv_vp_signal_pair_scheduler_message) ==
> #define HV_DISPATCH_VP_FLAG_SKIP_VP_SPEC_FLUSH 0x8
> #define HV_DISPATCH_VP_FLAG_SKIP_CALLER_SPEC_FLUSH 0x10
> #define HV_DISPATCH_VP_FLAG_SKIP_CALLER_USER_SPEC_FLUSH 0x20
> +#define HV_DISPATCH_VP_FLAG_SCAN_INTERRUPT_INJECTION 0x40
>
> struct hv_input_dispatch_vp {
> u64 partition_id;
> @@ -730,4 +836,18 @@ struct hv_output_dispatch_vp {
> u32 dispatch_event; /* enum hv_vp_dispatch_event */
> } __packed;
>
> +struct hv_input_modify_sparse_spa_page_host_access {
> + u32 host_access : 2;
> + u32 reserved : 30;
> + u32 flags;
> + u64 partition_id;
> + u64 spa_page_list[];
> +} __packed;
> +
> +/* hv_input_modify_sparse_spa_page_host_access flags */
> +#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE 0x1
> +#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_SHARED 0x2
> +#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE 0x4
> +#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_HUGE_PAGE 0x8
> +
> #endif /* _HV_HVHDK_H */
> diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
> index f8a39d3e9ce6..42e7876455b5 100644
> --- a/include/hyperv/hvhdk_mini.h
> +++ b/include/hyperv/hvhdk_mini.h
> @@ -36,6 +36,52 @@ enum hv_scheduler_type {
> HV_SCHEDULER_TYPE_MAX
> };
>
> +/* HV_STATS_AREA_TYPE */
> +enum hv_stats_area_type {
> + HV_STATS_AREA_SELF = 0,
> + HV_STATS_AREA_PARENT = 1,
> + HV_STATS_AREA_INTERNAL = 2,
> + HV_STATS_AREA_COUNT
> +};
> +
> +enum hv_stats_object_type {
> + HV_STATS_OBJECT_HYPERVISOR = 0x00000001,
> + HV_STATS_OBJECT_LOGICAL_PROCESSOR = 0x00000002,
> + HV_STATS_OBJECT_PARTITION = 0x00010001,
> + HV_STATS_OBJECT_VP = 0x00010002
> +};
> +
> +union hv_stats_object_identity {
> + /* hv_stats_hypervisor */
> + struct {
> + u8 reserved[15];
> + u8 stats_area_type;
> + } __packed hv;
> +
> + /* hv_stats_logical_processor */
> + struct {
> + u32 lp_index;
> + u8 reserved[11];
> + u8 stats_area_type;
> + } __packed lp;
> +
> + /* hv_stats_partition */
> + struct {
> + u64 partition_id;
> + u8 reserved[7];
> + u8 stats_area_type;
> + } __packed partition;
> +
> + /* hv_stats_vp */
> + struct {
> + u64 partition_id;
> + u32 vp_index;
> + u16 flags;
> + u8 reserved;
> + u8 stats_area_type;
> + } __packed vp;
> +};
> +
> enum hv_partition_property_code {
> /* Privilege properties */
> HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS = 0x00010000,
> @@ -47,19 +93,45 @@ enum hv_partition_property_code {
>
> /* Compatibility properties */
> HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES = 0x00060002,
> + HV_PARTITION_PROPERTY_XSAVE_STATES = 0x00060007,
> HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE = 0x00060008,
> HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY = 0x00060009,
> };
>
> +enum hv_snp_status {
> + HV_SNP_STATUS_NONE = 0,
> + HV_SNP_STATUS_AVAILABLE = 1,
> + HV_SNP_STATUS_INCOMPATIBLE = 2,
> + HV_SNP_STATUS_PSP_UNAVAILABLE = 3,
> + HV_SNP_STATUS_PSP_INIT_FAILED = 4,
> + HV_SNP_STATUS_PSP_BAD_FW_VERSION = 5,
> + HV_SNP_STATUS_BAD_CONFIGURATION = 6,
> + HV_SNP_STATUS_PSP_FW_UPDATE_IN_PROGRESS = 7,
> + HV_SNP_STATUS_PSP_RB_INIT_FAILED = 8,
> + HV_SNP_STATUS_PSP_PLATFORM_STATUS_FAILED = 9,
> + HV_SNP_STATUS_PSP_INIT_LATE_FAILED = 10,
> +};
> +
> enum hv_system_property {
> /* Add more values when needed */
> HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15,
> + HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21,
> +};
> +
> +enum hv_dynamic_processor_feature_property {
> + /* Add more values when needed */
> + HV_X64_DYNAMIC_PROCESSOR_FEATURE_MAX_ENCRYPTED_PARTITIONS = 13,
> + HV_X64_DYNAMIC_PROCESSOR_FEATURE_SNP_STATUS = 16,
> };
>
> struct hv_input_get_system_property {
> u32 property_id; /* enum hv_system_property */
> union {
> u32 as_uint32;
> +#if IS_ENABLED(CONFIG_X86)
> + /* enum hv_dynamic_processor_feature_property */
> + u32 hv_processor_feature;
> +#endif
> /* More fields to be filled in when needed */
> };
> } __packed;
> @@ -67,9 +139,28 @@ struct hv_input_get_system_property {
> struct hv_output_get_system_property {
> union {
> u32 scheduler_type; /* enum hv_scheduler_type */
> +#if IS_ENABLED(CONFIG_X86)
> + u64 hv_processor_feature_value;
> +#endif
> };
> } __packed;
>
> +struct hv_input_map_stats_page {
> + u32 type; /* enum hv_stats_object_type */
> + u32 padding;
> + union hv_stats_object_identity identity;
> +} __packed;
> +
> +struct hv_output_map_stats_page {
> + u64 map_location;
> +} __packed;
> +
> +struct hv_input_unmap_stats_page {
> + u32 type; /* enum hv_stats_object_type */
> + u32 padding;
> + union hv_stats_object_identity identity;
> +} __packed;
> +
> struct hv_proximity_domain_flags {
> u32 proximity_preferred : 1;
> u32 reserved : 30;
On 2/27/2025 5:27 PM, Easwar Hariharan wrote:
> On 2/26/2025 3:08 PM, Nuno Das Neves wrote:
>> A few additional definitions are required for the mshv driver code
>> (to follow). Introduce those here and clean up a little bit while
>> at it.
>>
>> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
>> ---
>> include/hyperv/hvgdk_mini.h | 64 ++++++++++++++++-
>> include/hyperv/hvhdk.h | 132 ++++++++++++++++++++++++++++++++++--
>> include/hyperv/hvhdk_mini.h | 91 +++++++++++++++++++++++++
>> 3 files changed, 280 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
>> index 58895883f636..e4a3cca0cbce 100644
>> --- a/include/hyperv/hvgdk_mini.h
>> +++ b/include/hyperv/hvgdk_mini.h
>> @@ -13,7 +13,7 @@ struct hv_u128 {
>> u64 high_part;
>> } __packed;
>>
>
> <snip>
>
>> union hv_input_vtl {
>> u8 as_uint8;
>> struct {
>> @@ -1325,6 +1344,49 @@ struct hv_retarget_device_interrupt { /* HV_INPUT_RETARGET_DEVICE_INTERRUPT */
>> struct hv_device_interrupt_target int_target;
>> } __packed __aligned(8);
>>
>> +enum hv_intercept_type {
>> +#if defined(CONFIG_X86_64)
>
> These chosen ifdef's come across kinda arbitrary. The hypervisor code has
> this enabled for both 32-bit and 64-bit x86, but you've chosen x86_64 only.
> I thought that may be because we only intend to support root partition for 64-bit
> platforms, but then, below...
>
Oops! They should all be X86 instead of X86_64. It's true root partition is only
supported on 64-bit systems, but guests (whom also use these headers) can of course
be 32-bit. It makes better sense to just use CONFIG_X86 for these ifdefs.
>> + HV_INTERCEPT_TYPE_X64_IO_PORT = 0x00000000,
>> + HV_INTERCEPT_TYPE_X64_MSR = 0x00000001,
>> + HV_INTERCEPT_TYPE_X64_CPUID = 0x00000002,
>> +#endif
>> + HV_INTERCEPT_TYPE_EXCEPTION = 0x00000003,
>> + /* Used to be HV_INTERCEPT_TYPE_REGISTER */
>> + HV_INTERCEPT_TYPE_RESERVED0 = 0x00000004,
>> + HV_INTERCEPT_TYPE_MMIO = 0x00000005,
>> +#if defined(CONFIG_X86_64)
>> + HV_INTERCEPT_TYPE_X64_GLOBAL_CPUID = 0x00000006,
>> + HV_INTERCEPT_TYPE_X64_APIC_SMI = 0x00000007,
>> +#endif
>> + HV_INTERCEPT_TYPE_HYPERCALL = 0x00000008,
>> +#if defined(CONFIG_X86_64)
>> + HV_INTERCEPT_TYPE_X64_APIC_INIT_SIPI = 0x00000009,
>> + HV_INTERCEPT_MC_UPDATE_PATCH_LEVEL_MSR_READ = 0x0000000A,
>> + HV_INTERCEPT_TYPE_X64_APIC_WRITE = 0x0000000B,
>> + HV_INTERCEPT_TYPE_X64_MSR_INDEX = 0x0000000C,
>> +#endif
>> + HV_INTERCEPT_TYPE_MAX,
>> + HV_INTERCEPT_TYPE_INVALID = 0xFFFFFFFF,
>> +};
>> +
>> +union hv_intercept_parameters {
>> + /* HV_INTERCEPT_PARAMETERS is defined to be an 8-byte field. */
>> + __u64 as_uint64;
>> +#if defined(CONFIG_X86_64)
>> + /* HV_INTERCEPT_TYPE_X64_IO_PORT */
>> + __u16 io_port;
>> + /* HV_INTERCEPT_TYPE_X64_CPUID */
>> + __u32 cpuid_index;
>> + /* HV_INTERCEPT_TYPE_X64_APIC_WRITE */
>> + __u32 apic_write_mask;
>> + /* HV_INTERCEPT_TYPE_EXCEPTION */
>> + __u16 exception_vector;
>> + /* HV_INTERCEPT_TYPE_X64_MSR_INDEX */
>> + __u32 msr_index;
>> +#endif
>> + /* N.B. Other intercept types do not have any parameters. */
>> +};
>> +
>> /* Data structures for HVCALL_MMIO_READ and HVCALL_MMIO_WRITE */
>> #define HV_HYPERCALL_MMIO_MAX_DATA_LENGTH 64
>>
>> diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
>> index 64407c2a3809..1b447155c338 100644
>> --- a/include/hyperv/hvhdk.h
>> +++ b/include/hyperv/hvhdk.h
>> @@ -19,11 +19,24 @@
>>
>> #define HV_VP_REGISTER_PAGE_VERSION_1 1u
>>
>> +#define HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT 7
>> +
>> +union hv_vp_register_page_interrupt_vectors {
>> + u64 as_uint64;
>> + struct {
>> + u8 vector_count;
>> + u8 vector[HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT];
>> + } __packed;
>> +} __packed;
>> +
>> struct hv_vp_register_page {
>> u16 version;
>> u8 isvalid;
>> u8 rsvdz;
>> u32 dirty;
>> +
>> +#if IS_ENABLED(CONFIG_X86)
>> +
>
> ...you've chosen to include 32bit here, where the hypervisor code supports both.
>
> Confused
>
>> union {
>> struct {
>> /* General purpose registers
>> @@ -95,6 +108,22 @@ struct hv_vp_register_page {
>> union hv_x64_pending_interruption_register pending_interruption;
>> union hv_x64_interrupt_state_register interrupt_state;
>> u64 instruction_emulation_hints;
>> + u64 xfem;
>> +
>> + /*
>> + * Fields from this point are not included in the register page save chunk.
>> + * The reserved field is intended to maintain alignment for unsaved fields.
>> + */
>> + u8 reserved1[0x100];
>> +
>> + /*
>> + * Interrupts injected as part of HvCallDispatchVp.
>> + */
>> + union hv_vp_register_page_interrupt_vectors interrupt_vectors;
>> +
>> +#elif IS_ENABLED(CONFIG_ARM64)
>> + /* Not yet supported in ARM */
>> +#endif
>> } __packed;
>>
>> #define HV_PARTITION_PROCESSOR_FEATURES_BANKS 2
>> @@ -299,10 +328,11 @@ union hv_partition_isolation_properties {
>> #define HV_PARTITION_ISOLATION_HOST_TYPE_RESERVED 0x2
>>
>> /* Note: Exo partition is enabled by default */
>> -#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
>> -#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
>> -#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
>> -#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
>> +#define HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED BIT(4)
>> +#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
>> +#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
>> +#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
>> +#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
>>
>> struct hv_input_create_partition {
>> u64 flags;
>> @@ -349,13 +379,23 @@ struct hv_input_set_partition_property {
>> enum hv_vp_state_page_type {
>> HV_VP_STATE_PAGE_REGISTERS = 0,
>> HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1,
>> + HV_VP_STATE_PAGE_GHCB,
>> HV_VP_STATE_PAGE_COUNT
>> };
>>
>> struct hv_input_map_vp_state_page {
>> u64 partition_id;
>> u32 vp_index;
>> - u32 type; /* enum hv_vp_state_page_type */
>> + u16 type; /* enum hv_vp_state_page_type */
>> + union hv_input_vtl input_vtl;
>> + union {
>> + u8 as_uint8;
>> + struct {
>> + u8 map_location_provided : 1;
>> + u8 reserved : 7;
>> + };
>> + } flags;
>> + u64 requested_map_location;
>> } __packed;
>>
>> struct hv_output_map_vp_state_page {
>> @@ -365,7 +405,14 @@ struct hv_output_map_vp_state_page {
>> struct hv_input_unmap_vp_state_page {
>> u64 partition_id;
>> u32 vp_index;
>> - u32 type; /* enum hv_vp_state_page_type */
>> + u16 type; /* enum hv_vp_state_page_type */
>> + union hv_input_vtl input_vtl;
>> + u8 reserved0;
>> +} __packed;
>> +
>> +struct hv_x64_apic_eoi_message {
>> + __u32 vp_index;
>> + __u32 interrupt_vector;
>
> Can these be plain u32? Similar below...
>
Yes, these are some uapi types I forgot to convert somehow, oops!
Thanks
Nuno
<snip>
On 2/26/2025 3:08 PM, Nuno Das Neves wrote:
> A few additional definitions are required for the mshv driver code
> (to follow). Introduce those here and clean up a little bit while
> at it.
>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
> include/hyperv/hvgdk_mini.h | 64 ++++++++++++++++-
> include/hyperv/hvhdk.h | 132 ++++++++++++++++++++++++++++++++++--
> include/hyperv/hvhdk_mini.h | 91 +++++++++++++++++++++++++
> 3 files changed, 280 insertions(+), 7 deletions(-)
>
> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
> index 58895883f636..e4a3cca0cbce 100644
> --- a/include/hyperv/hvgdk_mini.h
> +++ b/include/hyperv/hvgdk_mini.h
> @@ -13,7 +13,7 @@ struct hv_u128 {
> u64 high_part;
> } __packed;
>
> -/* NOTE: when adding below, update hv_status_to_string() */
> +/* NOTE: when adding below, update hv_result_to_string() */
> #define HV_STATUS_SUCCESS 0x0
> #define HV_STATUS_INVALID_HYPERCALL_CODE 0x2
> #define HV_STATUS_INVALID_HYPERCALL_INPUT 0x3
> @@ -51,6 +51,7 @@ struct hv_u128 {
> #define HV_HYP_PAGE_SHIFT 12
> #define HV_HYP_PAGE_SIZE BIT(HV_HYP_PAGE_SHIFT)
> #define HV_HYP_PAGE_MASK (~(HV_HYP_PAGE_SIZE - 1))
> +#define HV_HYP_LARGE_PAGE_SHIFT 21
>
> #define HV_PARTITION_ID_INVALID ((u64)0)
> #define HV_PARTITION_ID_SELF ((u64)-1)
> @@ -374,6 +375,10 @@ union hv_hypervisor_version_info {
> #define HV_SHARED_GPA_BOUNDARY_ACTIVE BIT(5)
> #define HV_SHARED_GPA_BOUNDARY_BITS GENMASK(11, 6)
>
> +/* HYPERV_CPUID_FEATURES.ECX bits. */
> +#define HV_VP_DISPATCH_INTERRUPT_INJECTION_AVAILABLE BIT(9)
> +#define HV_VP_GHCB_ROOT_MAPPING_AVAILABLE BIT(10)
> +
> enum hv_isolation_type {
> HV_ISOLATION_TYPE_NONE = 0, /* HV_PARTITION_ISOLATION_TYPE_NONE */
> HV_ISOLATION_TYPE_VBS = 1,
> @@ -437,9 +442,12 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
> #define HVCALL_MAP_GPA_PAGES 0x004b
> #define HVCALL_UNMAP_GPA_PAGES 0x004c
> #define HVCALL_CREATE_VP 0x004e
> +#define HVCALL_INSTALL_INTERCEPT 0x004d
> #define HVCALL_DELETE_VP 0x004f
> #define HVCALL_GET_VP_REGISTERS 0x0050
> #define HVCALL_SET_VP_REGISTERS 0x0051
> +#define HVCALL_TRANSLATE_VIRTUAL_ADDRESS 0x0052
> +#define HVCALL_CLEAR_VIRTUAL_INTERRUPT 0x0056
> #define HVCALL_DELETE_PORT 0x0058
> #define HVCALL_DISCONNECT_PORT 0x005b
> #define HVCALL_POST_MESSAGE 0x005c
> @@ -447,12 +455,15 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
> #define HVCALL_POST_DEBUG_DATA 0x0069
> #define HVCALL_RETRIEVE_DEBUG_DATA 0x006a
> #define HVCALL_RESET_DEBUG_SESSION 0x006b
> +#define HVCALL_MAP_STATS_PAGE 0x006c
> +#define HVCALL_UNMAP_STATS_PAGE 0x006d
> #define HVCALL_ADD_LOGICAL_PROCESSOR 0x0076
> #define HVCALL_GET_SYSTEM_PROPERTY 0x007b
> #define HVCALL_MAP_DEVICE_INTERRUPT 0x007c
> #define HVCALL_UNMAP_DEVICE_INTERRUPT 0x007d
> #define HVCALL_RETARGET_INTERRUPT 0x007e
> #define HVCALL_NOTIFY_PORT_RING_EMPTY 0x008b
> +#define HVCALL_REGISTER_INTERCEPT_RESULT 0x0091
> #define HVCALL_ASSERT_VIRTUAL_INTERRUPT 0x0094
> #define HVCALL_CREATE_PORT 0x0095
> #define HVCALL_CONNECT_PORT 0x0096
> @@ -460,12 +471,18 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
> #define HVCALL_GET_VP_ID_FROM_APIC_ID 0x009a
> #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
> #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
> +#define HVCALL_SIGNAL_EVENT_DIRECT 0x00c0
> +#define HVCALL_POST_MESSAGE_DIRECT 0x00c1
> #define HVCALL_DISPATCH_VP 0x00c2
> +#define HVCALL_GET_GPA_PAGES_ACCESS_STATES 0x00c9
> +#define HVCALL_ACQUIRE_SPARSE_SPA_PAGE_HOST_ACCESS 0x00d7
> +#define HVCALL_RELEASE_SPARSE_SPA_PAGE_HOST_ACCESS 0x00d8
> #define HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY 0x00db
> #define HVCALL_MAP_VP_STATE_PAGE 0x00e1
> #define HVCALL_UNMAP_VP_STATE_PAGE 0x00e2
> #define HVCALL_GET_VP_STATE 0x00e3
> #define HVCALL_SET_VP_STATE 0x00e4
> +#define HVCALL_GET_VP_CPUID_VALUES 0x00f4
> #define HVCALL_MMIO_READ 0x0106
> #define HVCALL_MMIO_WRITE 0x0107
>
> @@ -807,6 +824,8 @@ struct hv_x64_table_register {
> u64 base;
> } __packed;
>
> +#define HV_NORMAL_VTL 0
> +
> union hv_input_vtl {
> u8 as_uint8;
> struct {
> @@ -1325,6 +1344,49 @@ struct hv_retarget_device_interrupt { /* HV_INPUT_RETARGET_DEVICE_INTERRUPT */
> struct hv_device_interrupt_target int_target;
> } __packed __aligned(8);
>
> +enum hv_intercept_type {
> +#if defined(CONFIG_X86_64)
> + HV_INTERCEPT_TYPE_X64_IO_PORT = 0x00000000,
> + HV_INTERCEPT_TYPE_X64_MSR = 0x00000001,
> + HV_INTERCEPT_TYPE_X64_CPUID = 0x00000002,
> +#endif
> + HV_INTERCEPT_TYPE_EXCEPTION = 0x00000003,
> + /* Used to be HV_INTERCEPT_TYPE_REGISTER */
> + HV_INTERCEPT_TYPE_RESERVED0 = 0x00000004,
> + HV_INTERCEPT_TYPE_MMIO = 0x00000005,
> +#if defined(CONFIG_X86_64)
> + HV_INTERCEPT_TYPE_X64_GLOBAL_CPUID = 0x00000006,
> + HV_INTERCEPT_TYPE_X64_APIC_SMI = 0x00000007,
> +#endif
> + HV_INTERCEPT_TYPE_HYPERCALL = 0x00000008,
> +#if defined(CONFIG_X86_64)
> + HV_INTERCEPT_TYPE_X64_APIC_INIT_SIPI = 0x00000009,
> + HV_INTERCEPT_MC_UPDATE_PATCH_LEVEL_MSR_READ = 0x0000000A,
> + HV_INTERCEPT_TYPE_X64_APIC_WRITE = 0x0000000B,
> + HV_INTERCEPT_TYPE_X64_MSR_INDEX = 0x0000000C,
> +#endif
> + HV_INTERCEPT_TYPE_MAX,
> + HV_INTERCEPT_TYPE_INVALID = 0xFFFFFFFF,
> +};
> +
> +union hv_intercept_parameters {
> + /* HV_INTERCEPT_PARAMETERS is defined to be an 8-byte field. */
> + __u64 as_uint64;
> +#if defined(CONFIG_X86_64)
> + /* HV_INTERCEPT_TYPE_X64_IO_PORT */
> + __u16 io_port;
> + /* HV_INTERCEPT_TYPE_X64_CPUID */
> + __u32 cpuid_index;
> + /* HV_INTERCEPT_TYPE_X64_APIC_WRITE */
> + __u32 apic_write_mask;
> + /* HV_INTERCEPT_TYPE_EXCEPTION */
> + __u16 exception_vector;
> + /* HV_INTERCEPT_TYPE_X64_MSR_INDEX */
> + __u32 msr_index;
> +#endif
> + /* N.B. Other intercept types do not have any parameters. */
> +};
> +
> /* Data structures for HVCALL_MMIO_READ and HVCALL_MMIO_WRITE */
> #define HV_HYPERCALL_MMIO_MAX_DATA_LENGTH 64
>
> diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
> index 64407c2a3809..1b447155c338 100644
> --- a/include/hyperv/hvhdk.h
> +++ b/include/hyperv/hvhdk.h
> @@ -19,11 +19,24 @@
>
> #define HV_VP_REGISTER_PAGE_VERSION_1 1u
>
> +#define HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT 7
> +
> +union hv_vp_register_page_interrupt_vectors {
> + u64 as_uint64;
> + struct {
> + u8 vector_count;
> + u8 vector[HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT];
> + } __packed;
> +} __packed;
> +
> struct hv_vp_register_page {
> u16 version;
> u8 isvalid;
> u8 rsvdz;
> u32 dirty;
> +
> +#if IS_ENABLED(CONFIG_X86)
> +
> union {
> struct {
> /* General purpose registers
> @@ -95,6 +108,22 @@ struct hv_vp_register_page {
> union hv_x64_pending_interruption_register pending_interruption;
> union hv_x64_interrupt_state_register interrupt_state;
> u64 instruction_emulation_hints;
> + u64 xfem;
> +
> + /*
> + * Fields from this point are not included in the register page save chunk.
> + * The reserved field is intended to maintain alignment for unsaved fields.
> + */
> + u8 reserved1[0x100];
> +
> + /*
> + * Interrupts injected as part of HvCallDispatchVp.
> + */
> + union hv_vp_register_page_interrupt_vectors interrupt_vectors;
> +
> +#elif IS_ENABLED(CONFIG_ARM64)
> + /* Not yet supported in ARM */
> +#endif
> } __packed;
>
> #define HV_PARTITION_PROCESSOR_FEATURES_BANKS 2
> @@ -299,10 +328,11 @@ union hv_partition_isolation_properties {
> #define HV_PARTITION_ISOLATION_HOST_TYPE_RESERVED 0x2
>
> /* Note: Exo partition is enabled by default */
> -#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
> -#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
> -#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
> -#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
> +#define HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED BIT(4)
> +#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
> +#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
> +#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
> +#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
>
> struct hv_input_create_partition {
> u64 flags;
> @@ -349,13 +379,23 @@ struct hv_input_set_partition_property {
> enum hv_vp_state_page_type {
> HV_VP_STATE_PAGE_REGISTERS = 0,
> HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1,
> + HV_VP_STATE_PAGE_GHCB,
> HV_VP_STATE_PAGE_COUNT
> };
>
> struct hv_input_map_vp_state_page {
> u64 partition_id;
> u32 vp_index;
> - u32 type; /* enum hv_vp_state_page_type */
> + u16 type; /* enum hv_vp_state_page_type */
> + union hv_input_vtl input_vtl;
> + union {
> + u8 as_uint8;
> + struct {
> + u8 map_location_provided : 1;
> + u8 reserved : 7;
> + };
> + } flags;
> + u64 requested_map_location;
> } __packed;
>
> struct hv_output_map_vp_state_page {
> @@ -365,7 +405,14 @@ struct hv_output_map_vp_state_page {
> struct hv_input_unmap_vp_state_page {
> u64 partition_id;
> u32 vp_index;
> - u32 type; /* enum hv_vp_state_page_type */
> + u16 type; /* enum hv_vp_state_page_type */
> + union hv_input_vtl input_vtl;
> + u8 reserved0;
> +} __packed;
> +
> +struct hv_x64_apic_eoi_message {
> + __u32 vp_index;
> + __u32 interrupt_vector;
> } __packed;
>
> struct hv_opaque_intercept_message {
> @@ -515,6 +562,13 @@ struct hv_synthetic_timers_state {
> u64 reserved[5];
> } __packed;
>
> +struct hv_async_completion_message_payload {
> + __u64 partition_id;
> + __u32 status;
> + __u32 completion_count;
> + __u64 sub_status;
> +} __packed;
> +
> union hv_input_delete_vp {
> u64 as_uint64[2];
> struct {
> @@ -649,6 +703,57 @@ struct hv_input_set_vp_state {
> union hv_input_set_vp_state_data data[];
> } __packed;
>
> +union hv_x64_vp_execution_state {
> + __u16 as_uint16;
> + struct {
> + __u16 cpl:2;
> + __u16 cr0_pe:1;
> + __u16 cr0_am:1;
> + __u16 efer_lma:1;
> + __u16 debug_active:1;
> + __u16 interruption_pending:1;
> + __u16 vtl:4;
> + __u16 enclave_mode:1;
> + __u16 interrupt_shadow:1;
> + __u16 virtualization_fault_active:1;
> + __u16 reserved:2;
> + } __packed;
> +};
> +
> +struct hv_x64_intercept_message_header {
> + __u32 vp_index;
> + __u8 instruction_length:4;
> + __u8 cr8:4; /* Only set for exo partitions */
> + __u8 intercept_access_type;
> + union hv_x64_vp_execution_state execution_state;
> + struct hv_x64_segment_register cs_segment;
> + __u64 rip;
> + __u64 rflags;
> +} __packed;
> +
> +union hv_x64_memory_access_info {
> + __u8 as_uint8;
> + struct {
> + __u8 gva_valid:1;
> + __u8 gva_gpa_valid:1;
> + __u8 hypercall_output_pending:1;
> + __u8 tlb_locked_no_overlay:1;
> + __u8 reserved:4;
> + } __packed;
> +};
> +
> +struct hv_x64_memory_intercept_message {
> + struct hv_x64_intercept_message_header header;
> + __u32 cache_type; /* enum hv_cache_type */
> + __u8 instruction_byte_count;
> + union hv_x64_memory_access_info memory_access_info;
> + __u8 tpr_priority;
> + __u8 reserved1;
> + __u64 guest_virtual_address;
> + __u64 guest_physical_address;
> + __u8 instruction_bytes[16];
> +} __packed;
> +
> /*
> * Dispatch state for the VP communicated by the hypervisor to the
> * VP-dispatching thread in the root on return from HVCALL_DISPATCH_VP.
> @@ -716,6 +821,7 @@ static_assert(sizeof(struct hv_vp_signal_pair_scheduler_message) ==
> #define HV_DISPATCH_VP_FLAG_SKIP_VP_SPEC_FLUSH 0x8
> #define HV_DISPATCH_VP_FLAG_SKIP_CALLER_SPEC_FLUSH 0x10
> #define HV_DISPATCH_VP_FLAG_SKIP_CALLER_USER_SPEC_FLUSH 0x20
> +#define HV_DISPATCH_VP_FLAG_SCAN_INTERRUPT_INJECTION 0x40
>
> struct hv_input_dispatch_vp {
> u64 partition_id;
> @@ -730,4 +836,18 @@ struct hv_output_dispatch_vp {
> u32 dispatch_event; /* enum hv_vp_dispatch_event */
> } __packed;
>
> +struct hv_input_modify_sparse_spa_page_host_access {
> + u32 host_access : 2;
> + u32 reserved : 30;
> + u32 flags;
> + u64 partition_id;
> + u64 spa_page_list[];
> +} __packed;
> +
> +/* hv_input_modify_sparse_spa_page_host_access flags */
> +#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE 0x1
> +#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_SHARED 0x2
> +#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE 0x4
> +#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_HUGE_PAGE 0x8
> +
> #endif /* _HV_HVHDK_H */
> diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
> index f8a39d3e9ce6..42e7876455b5 100644
> --- a/include/hyperv/hvhdk_mini.h
> +++ b/include/hyperv/hvhdk_mini.h
> @@ -36,6 +36,52 @@ enum hv_scheduler_type {
> HV_SCHEDULER_TYPE_MAX
> };
>
> +/* HV_STATS_AREA_TYPE */
> +enum hv_stats_area_type {
> + HV_STATS_AREA_SELF = 0,
> + HV_STATS_AREA_PARENT = 1,
> + HV_STATS_AREA_INTERNAL = 2,
> + HV_STATS_AREA_COUNT
> +};
> +
> +enum hv_stats_object_type {
> + HV_STATS_OBJECT_HYPERVISOR = 0x00000001,
> + HV_STATS_OBJECT_LOGICAL_PROCESSOR = 0x00000002,
> + HV_STATS_OBJECT_PARTITION = 0x00010001,
> + HV_STATS_OBJECT_VP = 0x00010002
> +};
> +
> +union hv_stats_object_identity {
> + /* hv_stats_hypervisor */
> + struct {
> + u8 reserved[15];
> + u8 stats_area_type;
> + } __packed hv;
> +
> + /* hv_stats_logical_processor */
> + struct {
> + u32 lp_index;
> + u8 reserved[11];
> + u8 stats_area_type;
> + } __packed lp;
> +
> + /* hv_stats_partition */
> + struct {
> + u64 partition_id;
> + u8 reserved[7];
> + u8 stats_area_type;
> + } __packed partition;
> +
> + /* hv_stats_vp */
> + struct {
> + u64 partition_id;
> + u32 vp_index;
> + u16 flags;
> + u8 reserved;
> + u8 stats_area_type;
> + } __packed vp;
> +};
> +
> enum hv_partition_property_code {
> /* Privilege properties */
> HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS = 0x00010000,
> @@ -47,19 +93,45 @@ enum hv_partition_property_code {
>
> /* Compatibility properties */
> HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES = 0x00060002,
> + HV_PARTITION_PROPERTY_XSAVE_STATES = 0x00060007,
> HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE = 0x00060008,
> HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY = 0x00060009,
> };
>
> +enum hv_snp_status {
> + HV_SNP_STATUS_NONE = 0,
> + HV_SNP_STATUS_AVAILABLE = 1,
> + HV_SNP_STATUS_INCOMPATIBLE = 2,
> + HV_SNP_STATUS_PSP_UNAVAILABLE = 3,
> + HV_SNP_STATUS_PSP_INIT_FAILED = 4,
> + HV_SNP_STATUS_PSP_BAD_FW_VERSION = 5,
> + HV_SNP_STATUS_BAD_CONFIGURATION = 6,
> + HV_SNP_STATUS_PSP_FW_UPDATE_IN_PROGRESS = 7,
> + HV_SNP_STATUS_PSP_RB_INIT_FAILED = 8,
> + HV_SNP_STATUS_PSP_PLATFORM_STATUS_FAILED = 9,
> + HV_SNP_STATUS_PSP_INIT_LATE_FAILED = 10,
> +};
> +
> enum hv_system_property {
> /* Add more values when needed */
> HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15,
> + HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21,
> +};
> +
> +enum hv_dynamic_processor_feature_property {
> + /* Add more values when needed */
> + HV_X64_DYNAMIC_PROCESSOR_FEATURE_MAX_ENCRYPTED_PARTITIONS = 13,
> + HV_X64_DYNAMIC_PROCESSOR_FEATURE_SNP_STATUS = 16,
> };
>
> struct hv_input_get_system_property {
> u32 property_id; /* enum hv_system_property */
> union {
> u32 as_uint32;
> +#if IS_ENABLED(CONFIG_X86)
> + /* enum hv_dynamic_processor_feature_property */
> + u32 hv_processor_feature;
> +#endif
> /* More fields to be filled in when needed */
> };
> } __packed;
> @@ -67,9 +139,28 @@ struct hv_input_get_system_property {
> struct hv_output_get_system_property {
> union {
> u32 scheduler_type; /* enum hv_scheduler_type */
> +#if IS_ENABLED(CONFIG_X86)
> + u64 hv_processor_feature_value;
> +#endif
> };
> } __packed;
>
> +struct hv_input_map_stats_page {
> + u32 type; /* enum hv_stats_object_type */
> + u32 padding;
> + union hv_stats_object_identity identity;
> +} __packed;
> +
> +struct hv_output_map_stats_page {
> + u64 map_location;
> +} __packed;
> +
> +struct hv_input_unmap_stats_page {
> + u32 type; /* enum hv_stats_object_type */
> + u32 padding;
> + union hv_stats_object_identity identity;
> +} __packed;
> +
> struct hv_proximity_domain_flags {
> u32 proximity_preferred : 1;
> u32 reserved : 30;
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
--
Thank you,
Roman
On Wed, Feb 26, 2025 at 03:08:03PM -0800, Nuno Das Neves wrote:
> A few additional definitions are required for the mshv driver code
> (to follow). Introduce those here and clean up a little bit while
> at it.
>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> ---
> include/hyperv/hvgdk_mini.h | 64 ++++++++++++++++-
> include/hyperv/hvhdk.h | 132 ++++++++++++++++++++++++++++++++++--
> include/hyperv/hvhdk_mini.h | 91 +++++++++++++++++++++++++
> 3 files changed, 280 insertions(+), 7 deletions(-)
>
> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
> index 58895883f636..e4a3cca0cbce 100644
> --- a/include/hyperv/hvgdk_mini.h
> +++ b/include/hyperv/hvgdk_mini.h
@@ -1325,6 +1344,49 @@ struct hv_retarget_device_interrupt { /* HV_INPUT_RETARGET_DEVICE_INTERRUPT */
> struct hv_device_interrupt_target int_target;
> } __packed __aligned(8);
>
> +enum hv_intercept_type {
> +#if defined(CONFIG_X86_64)
Prehaps it would be nice to have per-arch headers for such structures
instead.
> + HV_INTERCEPT_TYPE_X64_IO_PORT = 0x00000000,
> + HV_INTERCEPT_TYPE_X64_MSR = 0x00000001,
> + HV_INTERCEPT_TYPE_X64_CPUID = 0x00000002,
> +#endif
> + HV_INTERCEPT_TYPE_EXCEPTION = 0x00000003,
> + /* Used to be HV_INTERCEPT_TYPE_REGISTER */
> + HV_INTERCEPT_TYPE_RESERVED0 = 0x00000004,
> + HV_INTERCEPT_TYPE_MMIO = 0x00000005,
> +#if defined(CONFIG_X86_64)
> + HV_INTERCEPT_TYPE_X64_GLOBAL_CPUID = 0x00000006,
> + HV_INTERCEPT_TYPE_X64_APIC_SMI = 0x00000007,
> +#endif
> + HV_INTERCEPT_TYPE_HYPERCALL = 0x00000008,
> +#if defined(CONFIG_X86_64)
> + HV_INTERCEPT_TYPE_X64_APIC_INIT_SIPI = 0x00000009,
> + HV_INTERCEPT_MC_UPDATE_PATCH_LEVEL_MSR_READ = 0x0000000A,
> + HV_INTERCEPT_TYPE_X64_APIC_WRITE = 0x0000000B,
> + HV_INTERCEPT_TYPE_X64_MSR_INDEX = 0x0000000C,
> +#endif
> + HV_INTERCEPT_TYPE_MAX,
> + HV_INTERCEPT_TYPE_INVALID = 0xFFFFFFFF,
> +};
> +
> +union hv_intercept_parameters {
> + /* HV_INTERCEPT_PARAMETERS is defined to be an 8-byte field. */
> + __u64 as_uint64;
Should this one be "u64" instead of "__u64" (here and below) ?
> +#if defined(CONFIG_X86_64)
> + /* HV_INTERCEPT_TYPE_X64_IO_PORT */
> + __u16 io_port;
> + /* HV_INTERCEPT_TYPE_X64_CPUID */
> + __u32 cpuid_index;
> + /* HV_INTERCEPT_TYPE_X64_APIC_WRITE */
> + __u32 apic_write_mask;
> + /* HV_INTERCEPT_TYPE_EXCEPTION */
> + __u16 exception_vector;
> + /* HV_INTERCEPT_TYPE_X64_MSR_INDEX */
> + __u32 msr_index;
> +#endif
> + /* N.B. Other intercept types do not have any parameters. */
> +};
> +
> /* Data structures for HVCALL_MMIO_READ and HVCALL_MMIO_WRITE */
> #define HV_HYPERCALL_MMIO_MAX_DATA_LENGTH 64
>
> diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
> index 64407c2a3809..1b447155c338 100644
> --- a/include/hyperv/hvhdk.h
> +++ b/include/hyperv/hvhdk.h
> @@ -19,11 +19,24 @@
>
> #define HV_VP_REGISTER_PAGE_VERSION_1 1u
>
> +#define HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT 7
> +
> +union hv_vp_register_page_interrupt_vectors {
> + u64 as_uint64;
> + struct {
> + u8 vector_count;
> + u8 vector[HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT];
> + } __packed;
> +} __packed;
Packed attribute for the union looks redundant.
Reviewed-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
On 2/26/2025 3:51 PM, Stanislav Kinsburskii wrote:
> On Wed, Feb 26, 2025 at 03:08:03PM -0800, Nuno Das Neves wrote:
>> A few additional definitions are required for the mshv driver code
>> (to follow). Introduce those here and clean up a little bit while
>> at it.
>>
>> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
>> ---
>> include/hyperv/hvgdk_mini.h | 64 ++++++++++++++++-
>> include/hyperv/hvhdk.h | 132 ++++++++++++++++++++++++++++++++++--
>> include/hyperv/hvhdk_mini.h | 91 +++++++++++++++++++++++++
>> 3 files changed, 280 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
>> index 58895883f636..e4a3cca0cbce 100644
>> --- a/include/hyperv/hvgdk_mini.h
>> +++ b/include/hyperv/hvgdk_mini.h
> @@ -1325,6 +1344,49 @@ struct hv_retarget_device_interrupt { /* HV_INPUT_RETARGET_DEVICE_INTERRUPT */
>> struct hv_device_interrupt_target int_target;
>> } __packed __aligned(8);
>>
>> +enum hv_intercept_type {
>> +#if defined(CONFIG_X86_64)
>
> Prehaps it would be nice to have per-arch headers for such structures
> instead.
>
The goal with these files is to reflect the Hyper-V code closely, in order
to make porting the definitions to Linux as easy as possible. Splitting
these into per-arch headers is not my preferred approach because it is
counter to that goal.
>> + HV_INTERCEPT_TYPE_X64_IO_PORT = 0x00000000,
>> + HV_INTERCEPT_TYPE_X64_MSR = 0x00000001,
>> + HV_INTERCEPT_TYPE_X64_CPUID = 0x00000002,
>> +#endif
>> + HV_INTERCEPT_TYPE_EXCEPTION = 0x00000003,
>> + /* Used to be HV_INTERCEPT_TYPE_REGISTER */
>> + HV_INTERCEPT_TYPE_RESERVED0 = 0x00000004,
>> + HV_INTERCEPT_TYPE_MMIO = 0x00000005,
>> +#if defined(CONFIG_X86_64)
>> + HV_INTERCEPT_TYPE_X64_GLOBAL_CPUID = 0x00000006,
>> + HV_INTERCEPT_TYPE_X64_APIC_SMI = 0x00000007,
>> +#endif
>> + HV_INTERCEPT_TYPE_HYPERCALL = 0x00000008,
>> +#if defined(CONFIG_X86_64)
>> + HV_INTERCEPT_TYPE_X64_APIC_INIT_SIPI = 0x00000009,
>> + HV_INTERCEPT_MC_UPDATE_PATCH_LEVEL_MSR_READ = 0x0000000A,
>> + HV_INTERCEPT_TYPE_X64_APIC_WRITE = 0x0000000B,
>> + HV_INTERCEPT_TYPE_X64_MSR_INDEX = 0x0000000C,
>> +#endif
>> + HV_INTERCEPT_TYPE_MAX,
>> + HV_INTERCEPT_TYPE_INVALID = 0xFFFFFFFF,
>> +};
>> +
>> +union hv_intercept_parameters {
>> + /* HV_INTERCEPT_PARAMETERS is defined to be an 8-byte field. */
>> + __u64 as_uint64;
>
> Should this one be "u64" instead of "__u64" (here and below) ?
>
Yes, it looks like a few of the uapi types are still lingering, oops!
>> +#if defined(CONFIG_X86_64)
>> + /* HV_INTERCEPT_TYPE_X64_IO_PORT */
>> + __u16 io_port;
>> + /* HV_INTERCEPT_TYPE_X64_CPUID */
>> + __u32 cpuid_index;
>> + /* HV_INTERCEPT_TYPE_X64_APIC_WRITE */
>> + __u32 apic_write_mask;
>> + /* HV_INTERCEPT_TYPE_EXCEPTION */
>> + __u16 exception_vector;
>> + /* HV_INTERCEPT_TYPE_X64_MSR_INDEX */
>> + __u32 msr_index;
>> +#endif
>> + /* N.B. Other intercept types do not have any parameters. */
>> +};
>> +
>> /* Data structures for HVCALL_MMIO_READ and HVCALL_MMIO_WRITE */
>> #define HV_HYPERCALL_MMIO_MAX_DATA_LENGTH 64
>>
>> diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h
>> index 64407c2a3809..1b447155c338 100644
>> --- a/include/hyperv/hvhdk.h
>> +++ b/include/hyperv/hvhdk.h
>> @@ -19,11 +19,24 @@
>>
>> #define HV_VP_REGISTER_PAGE_VERSION_1 1u
>>
>> +#define HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT 7
>> +
>> +union hv_vp_register_page_interrupt_vectors {
>> + u64 as_uint64;
>> + struct {
>> + u8 vector_count;
>> + u8 vector[HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT];
>> + } __packed;
>> +} __packed;
>
> Packed attribute for the union looks redundant.
>
Good point, I can remove it in the next version
> Reviewed-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
© 2016 - 2026 Red Hat, Inc.