aboutsummaryrefslogtreecommitdiff
path: root/hw/i386
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2022-02-14 14:03:46 +0800
committerMichael S. Tsirkin <mst@redhat.com>2022-03-06 05:08:23 -0500
commitb8ffd7d6713fb2703f4b09cea3e62d1c61767107 (patch)
treec4d35897c53f09c81366f67f682be60be2b5d13c /hw/i386
parentb1f030a0a2e281193b09350c0281c0084e84bcf4 (diff)
intel_iommu: support snoop control
SC is required for some kernel features like vhost-vDPA. So this patch implements basic SC feature. The idea is pretty simple, for software emulated DMA it would be always coherent. In this case we can simple advertise ECAP_SC bit. For VFIO and vhost, thing will be more much complicated, so this patch simply fail the IOMMU notifier registration. In the future, we may want to have a dedicated notifiers flag or similar mechanism to demonstrate the coherency so VFIO could advertise that if it has VFIO_DMA_CC_IOMMU, for vhost kernel backend we don't need that since it's a software backend. Signed-off-by: Jason Wang <jasowang@redhat.com> Message-Id: <20220214060346.72455-1-jasowang@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386')
-rw-r--r--hw/i386/intel_iommu.c14
-rw-r--r--hw/i386/intel_iommu_internal.h1
2 files changed, 14 insertions, 1 deletions
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 4c6c016388..32471a44cb 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3030,6 +3030,13 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
IntelIOMMUState *s = vtd_as->iommu_state;
+ /* TODO: add support for VFIO and vhost users */
+ if (s->snoop_control) {
+ error_setg_errno(errp, -ENOTSUP,
+ "Snoop Control with vhost or VFIO is not supported");
+ return -ENOTSUP;
+ }
+
/* Update per-address-space notifier flags */
vtd_as->notifier_flags = new;
@@ -3113,6 +3120,7 @@ static Property vtd_properties[] = {
VTD_HOST_ADDRESS_WIDTH),
DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE),
DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE),
+ DEFINE_PROP_BOOL("snoop-control", IntelIOMMUState, snoop_control, false),
DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),
DEFINE_PROP_END_OF_LIST(),
};
@@ -3643,7 +3651,7 @@ static void vtd_init(IntelIOMMUState *s)
vtd_spte_rsvd_large[3] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits,
x86_iommu->dt_supported);
- if (s->scalable_mode) {
+ if (s->scalable_mode || s->snoop_control) {
vtd_spte_rsvd[1] &= ~VTD_SPTE_SNP;
vtd_spte_rsvd_large[2] &= ~VTD_SPTE_SNP;
vtd_spte_rsvd_large[3] &= ~VTD_SPTE_SNP;
@@ -3674,6 +3682,10 @@ static void vtd_init(IntelIOMMUState *s)
s->ecap |= VTD_ECAP_SMTS | VTD_ECAP_SRS | VTD_ECAP_SLTS;
}
+ if (s->snoop_control) {
+ s->ecap |= VTD_ECAP_SC;
+ }
+
vtd_reset_caches(s);
/* Define registers with default values and bit semantics */
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index a6c788049b..1ff13b40f9 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -188,6 +188,7 @@
#define VTD_ECAP_IR (1ULL << 3)
#define VTD_ECAP_EIM (1ULL << 4)
#define VTD_ECAP_PT (1ULL << 6)
+#define VTD_ECAP_SC (1ULL << 7)
#define VTD_ECAP_MHMV (15ULL << 20)
#define VTD_ECAP_SRS (1ULL << 31)
#define VTD_ECAP_SMTS (1ULL << 43)