mirror of https://github.com/xemu-project/xemu.git
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>
This commit is contained in:
parent
b1f030a0a2
commit
b8ffd7d671
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -228,6 +228,7 @@ struct IntelIOMMUState {
|
|||
|
||||
bool caching_mode; /* RO - is cap CM enabled? */
|
||||
bool scalable_mode; /* RO - is Scalable Mode supported? */
|
||||
bool snoop_control; /* RO - is SNP filed supported? */
|
||||
|
||||
dma_addr_t root; /* Current root table pointer */
|
||||
bool root_scalable; /* Type of root table (scalable or not) */
|
||||
|
|
Loading…
Reference in New Issue