Message ID | 20200320165840.30057-6-eric.auger@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | vSMMUv3/pSMMUv3 2 stage VFIO integration | expand |
Hi Eric, I'm also considering how to inject iommu fault to vIOMMU. As our previous discussion (long time ago), MemoryRegion way doesn't work well for VTd case. So I'd like see your opinion on the proposal below: I've a patch to make vIOMMUs register PCIIOMMUOps to PCI layer. Current usage is to get address space and set/unset HostIOMMUContext (added by me). I think it may be also nice to add the fault injection callback in the PCIIOMMUOps. Thoughts? https://patchwork.ozlabs.org/patch/1259645/ Regards, Yi Liu > From: Eric Auger <eric.auger@redhat.com> > Sent: Saturday, March 21, 2020 12:58 AM > To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-devel@nongnu.org; > Subject: [RFC v6 05/24] memory: Introduce IOMMU Memory Region inject_faults > API > > This new API allows to inject @count iommu_faults into > the IOMMU memory region. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > --- > include/exec/memory.h | 25 +++++++++++++++++++++++++ > memory.c | 10 ++++++++++ > 2 files changed, 35 insertions(+) > > diff --git a/include/exec/memory.h b/include/exec/memory.h > index f2c773163f..141a5dc197 100644 > --- a/include/exec/memory.h > +++ b/include/exec/memory.h > @@ -57,6 +57,8 @@ struct MemoryRegionMmio { > CPUWriteMemoryFunc *write[3]; > }; > > +struct iommu_fault; > + > typedef struct IOMMUTLBEntry IOMMUTLBEntry; > > /* See address_space_translate: bit 0 is read, bit 1 is write. */ > @@ -357,6 +359,19 @@ typedef struct IOMMUMemoryRegionClass { > * @iommu: the IOMMUMemoryRegion > */ > int (*num_indexes)(IOMMUMemoryRegion *iommu); > + > + /* > + * Inject @count faults into the IOMMU memory region > + * > + * Optional method: if this method is not provided, then > + * memory_region_injection_faults() will return -ENOENT > + * > + * @iommu: the IOMMU memory region to inject the faults in > + * @count: number of faults to inject > + * @buf: fault buffer > + */ > + int (*inject_faults)(IOMMUMemoryRegion *iommu, int count, > + struct iommu_fault *buf); > } IOMMUMemoryRegionClass; > > typedef struct CoalescedMemoryRange CoalescedMemoryRange; > @@ -1365,6 +1380,16 @@ int > memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr, > */ > int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr); > > +/** > + * memory_region_inject_faults : inject @count faults stored in @buf > + * > + * @iommu_mr: the IOMMU memory region > + * @count: number of faults to be injected > + * @buf: buffer containing the faults > + */ > +int memory_region_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, > + struct iommu_fault *buf); > + > /** > * memory_region_name: get a memory region's name > * > diff --git a/memory.c b/memory.c > index 09be40edd2..9cdd77e0de 100644 > --- a/memory.c > +++ b/memory.c > @@ -2001,6 +2001,16 @@ int > memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr) > return imrc->num_indexes(iommu_mr); > } > > +int memory_region_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, > + struct iommu_fault *buf) > +{ > + IOMMUMemoryRegionClass *imrc = > IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr); > + if (!imrc->inject_faults) { > + return -ENOENT; > + } > + return imrc->inject_faults(iommu_mr, count, buf); > +} > + > void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) > { > uint8_t mask = 1 << client; > -- > 2.20.1
diff --git a/include/exec/memory.h b/include/exec/memory.h index f2c773163f..141a5dc197 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -57,6 +57,8 @@ struct MemoryRegionMmio { CPUWriteMemoryFunc *write[3]; }; +struct iommu_fault; + typedef struct IOMMUTLBEntry IOMMUTLBEntry; /* See address_space_translate: bit 0 is read, bit 1 is write. */ @@ -357,6 +359,19 @@ typedef struct IOMMUMemoryRegionClass { * @iommu: the IOMMUMemoryRegion */ int (*num_indexes)(IOMMUMemoryRegion *iommu); + + /* + * Inject @count faults into the IOMMU memory region + * + * Optional method: if this method is not provided, then + * memory_region_injection_faults() will return -ENOENT + * + * @iommu: the IOMMU memory region to inject the faults in + * @count: number of faults to inject + * @buf: fault buffer + */ + int (*inject_faults)(IOMMUMemoryRegion *iommu, int count, + struct iommu_fault *buf); } IOMMUMemoryRegionClass; typedef struct CoalescedMemoryRange CoalescedMemoryRange; @@ -1365,6 +1380,16 @@ int memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr, */ int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr); +/** + * memory_region_inject_faults : inject @count faults stored in @buf + * + * @iommu_mr: the IOMMU memory region + * @count: number of faults to be injected + * @buf: buffer containing the faults + */ +int memory_region_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, + struct iommu_fault *buf); + /** * memory_region_name: get a memory region's name * diff --git a/memory.c b/memory.c index 09be40edd2..9cdd77e0de 100644 --- a/memory.c +++ b/memory.c @@ -2001,6 +2001,16 @@ int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr) return imrc->num_indexes(iommu_mr); } +int memory_region_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, + struct iommu_fault *buf) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr); + if (!imrc->inject_faults) { + return -ENOENT; + } + return imrc->inject_faults(iommu_mr, count, buf); +} + void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) { uint8_t mask = 1 << client;
This new API allows to inject @count iommu_faults into the IOMMU memory region. Signed-off-by: Eric Auger <eric.auger@redhat.com> --- include/exec/memory.h | 25 +++++++++++++++++++++++++ memory.c | 10 ++++++++++ 2 files changed, 35 insertions(+)