summaryrefslogtreecommitdiff
path: root/include/hyperv
diff options
context:
space:
mode:
authorWei Liu <wei.liu@kernel.org>2026-09-30 22:14:05 +0800
committerJoerg Roedel <joerg.roedel@amd.com>2026-10-09 10:37:40 +0200
commit1d87b20d1c272daf3bb36a155487fe8cc1da4490 (patch)
tree4ea2181d5fc7082a3abb8cc6776904ceeb1315e1 /include/hyperv
parent93f51579e7df248780214094418f205253383cc5 (diff)
hyperv: Introduce new hypercall interfaces used by Hyper-V guest IOMMU
Hyper-V guest IOMMU is a para-virtualized IOMMU based on hypercalls. Introduce the hypercalls used by the child partition to interact with this facility. These hypercalls fall into below categories: - Detection and capability: HVCALL_GET_IOMMU_CAPABILITIES is used to detect the existence and capabilities of the guest IOMMU. - Device management: HVCALL_GET_LOGICAL_DEVICE_PROPERTY is used to check whether an endpoint device is managed by the guest IOMMU. - Domain management: A set of hypercalls is provided to handle the creation, configuration, and deletion of guest domains, as well as the attachment/detachment of endpoint devices to/from those domains. - IOTLB flushing: HVCALL_FLUSH_DEVICE_DOMAIN is used to ask Hyper-V for a domain-selective IOTLB flush (which in its handler may flush the device TLB as well). Signed-off-by: Wei Liu <wei.liu@kernel.org> Co-developed-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com> Signed-off-by: Easwar Hariharan <easwar.hariharan@linux.microsoft.com> Co-developed-by: Yu Zhang <zhangyu1@linux.microsoft.com> Signed-off-by: Yu Zhang <zhangyu1@linux.microsoft.com> Reviewed-by: Jacob Pan <jacob.pan@linux.microsoft.com> Reviewed-by: Michael Kelley <mhklinux@outlook.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'include/hyperv')
-rw-r--r--include/hyperv/hvgdk_mini.h9
-rw-r--r--include/hyperv/hvhdk_mini.h137
2 files changed, 146 insertions, 0 deletions
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index 6a4e8b9d570f..5d1338197eee 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -37,6 +37,7 @@ struct hv_u128 {
#define HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED 0x20
#define HV_STATUS_INVALID_LP_INDEX 0x41
#define HV_STATUS_INVALID_REGISTER_VALUE 0x50
+#define HV_STATUS_DEVICE_ALREADY_IN_DOMAIN 0x66
#define HV_STATUS_OPERATION_FAILED 0x71
#define HV_STATUS_INSUFFICIENT_ROOT_MEMORY 0x73
#define HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY 0x75
@@ -486,10 +487,16 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_GET_VP_INDEX_FROM_APIC_ID 0x009a
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
+#define HVCALL_CREATE_DEVICE_DOMAIN 0x00b1
+#define HVCALL_ATTACH_DEVICE_DOMAIN 0x00b2
#define HVCALL_SIGNAL_EVENT_DIRECT 0x00c0
#define HVCALL_POST_MESSAGE_DIRECT 0x00c1
#define HVCALL_DISPATCH_VP 0x00c2
+#define HVCALL_DETACH_DEVICE_DOMAIN 0x00c4
+#define HVCALL_DELETE_DEVICE_DOMAIN 0x00c5
#define HVCALL_GET_GPA_PAGES_ACCESS_STATES 0x00c9
+#define HVCALL_CONFIGURE_DEVICE_DOMAIN 0x00ce
+#define HVCALL_FLUSH_DEVICE_DOMAIN 0x00d0
#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
@@ -502,6 +509,8 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_MMIO_READ 0x0106
#define HVCALL_MMIO_WRITE 0x0107
#define HVCALL_DISABLE_HYP_EX 0x010f
+#define HVCALL_GET_IOMMU_CAPABILITIES 0x0125
+#define HVCALL_GET_LOGICAL_DEVICE_PROPERTY 0x0127
#define HVCALL_MAP_STATS_PAGE2 0x0131
/* HV_HYPERCALL_INPUT */
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index 035ba20870f7..7b9f43b320cd 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -548,4 +548,141 @@ union hv_device_id { /* HV_DEVICE_ID */
} acpi;
} __packed;
+/* Device domain types */
+#define HV_DEVICE_DOMAIN_TYPE_S1 1 /* HV_DEVICE_DOMAIN_ID_TYPE_S1 */
+
+/* ID for default domain and NULL domain */
+#define HV_DEVICE_DOMAIN_ID_DEFAULT 0
+#define HV_DEVICE_DOMAIN_ID_NULL 0xFFFFFFFFULL
+
+union hv_device_domain_id { /* HV_DEVICE_DOMAIN_ID */
+ u64 as_uint64;
+ struct {
+ u32 type: 4;
+ u32 reserved: 28;
+ u32 id;
+ } __packed;
+};
+
+struct hv_input_device_domain { /* HV_INPUT_DEVICE_DOMAIN */
+ u64 partition_id;
+ union hv_input_vtl owner_vtl;
+ u8 padding[7];
+ union hv_device_domain_id domain_id;
+} __packed;
+
+/* HV_CREATE_DEVICE_DOMAIN_FLAGS */
+union hv_create_device_domain_flags {
+ u32 as_uint32;
+ struct {
+ u32 forward_progress_required: 1;
+ u32 inherit_owning_vtl: 1;
+ u32 reserved: 30;
+ } __packed;
+};
+
+/* HV_INPUT_CREATE_DEVICE_DOMAIN */
+struct hv_input_create_device_domain {
+ struct hv_input_device_domain device_domain;
+ union hv_create_device_domain_flags create_device_domain_flags;
+ u32 padding;
+} __packed;
+
+/* HV_INPUT_DELETE_DEVICE_DOMAIN */
+struct hv_input_delete_device_domain {
+ struct hv_input_device_domain device_domain;
+} __packed;
+
+/* HV_INPUT_ATTACH_DEVICE_DOMAIN */
+struct hv_input_attach_device_domain {
+ struct hv_input_device_domain device_domain;
+ union hv_device_id device_id;
+} __packed;
+
+/* HV_INPUT_DETACH_DEVICE_DOMAIN */
+struct hv_input_detach_device_domain {
+ u64 partition_id;
+ union hv_device_id device_id;
+} __packed;
+
+struct hv_device_domain_settings { /* HV_DEVICE_DOMAIN_SETTINGS */
+ struct {
+ /*
+ * Enable translations. If not enabled, all transaction bypass
+ * S1 translations.
+ */
+ u64 translation_enabled: 1;
+ u64 blocked: 1;
+ /*
+ * First stage address translation paging mode:
+ * 0: 4-level paging (default)
+ * 1: 5-level paging
+ */
+ u64 first_stage_paging_mode: 1;
+ u64 reserved: 61;
+ } flags;
+
+ /* Address of translation table */
+ u64 page_table_root;
+} __packed;
+
+/* HV_INPUT_CONFIGURE_DEVICE_DOMAIN */
+struct hv_input_configure_device_domain {
+ struct hv_input_device_domain device_domain;
+ struct hv_device_domain_settings settings;
+} __packed;
+
+/* HV_INPUT_GET_IOMMU_CAPABILITIES */
+struct hv_input_get_iommu_capabilities {
+ u64 partition_id;
+ u64 reserved;
+} __packed;
+
+/* HV_OUTPUT_GET_IOMMU_CAPABILITIES */
+struct hv_output_get_iommu_capabilities {
+ u32 size;
+ u16 reserved;
+ u8 max_iova_width;
+ u8 max_pasid_width;
+
+#define HV_IOMMU_CAP_PRESENT BIT_ULL(0)
+#define HV_IOMMU_CAP_S2 BIT_ULL(1)
+#define HV_IOMMU_CAP_S1 BIT_ULL(2)
+#define HV_IOMMU_CAP_S1_5LVL BIT_ULL(3)
+#define HV_IOMMU_CAP_PASID BIT_ULL(4)
+#define HV_IOMMU_CAP_ATS BIT_ULL(5)
+#define HV_IOMMU_CAP_PRI BIT_ULL(6)
+
+ u64 iommu_cap;
+ u64 pgsize_bitmap;
+} __packed;
+
+/* HV_LOGICAL_DEVICE_PROPERTY_CODE */
+enum hv_logical_device_property_code {
+ HV_LOGICAL_DEVICE_PROPERTY_PVIOMMU = 10,
+};
+
+/* HV_INPUT_GET_LOGICAL_DEVICE_PROPERTY */
+struct hv_input_get_logical_device_property {
+ u64 partition_id;
+ u64 logical_device_id;
+ /* Takes values from enum hv_logical_device_property_code. */
+ u32 code;
+ u32 reserved;
+} __packed;
+
+/* HV_OUTPUT_GET_LOGICAL_DEVICE_PROPERTY */
+struct hv_output_get_logical_device_property {
+#define HV_DEVICE_IOMMU_ENABLED BIT_ULL(0)
+ u64 device_iommu;
+ u64 reserved;
+} __packed;
+
+/* HV_INPUT_FLUSH_DEVICE_DOMAIN */
+struct hv_input_flush_device_domain {
+ struct hv_input_device_domain device_domain;
+ u32 flags;
+ u32 reserved;
+} __packed;
+
#endif /* _HV_HVHDK_MINI_H */