[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH V2 25/25] x86/vvtd: save and restore emulated VT-d
On Wed, Aug 09, 2017 at 04:34:26PM -0400, Lan Tianyu wrote: > From: Chao Gao <chao.gao@xxxxxxxxx> > > Wrap some useful status in a new structure hvm_hw_vvtd, following > the customs of vlapic, vioapic and etc. Provide two save-restore > pairs to save/restore registers and non-register status. > > Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx> > Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx> > --- > xen/drivers/passthrough/vtd/vvtd.c | 98 > ++++++++++++++++++++++------------ > xen/include/public/arch-x86/hvm/save.h | 24 ++++++++- > 2 files changed, 88 insertions(+), 34 deletions(-) > > diff --git a/xen/drivers/passthrough/vtd/vvtd.c > b/xen/drivers/passthrough/vtd/vvtd.c > index 4f5e28e..dd6be83 100644 > --- a/xen/drivers/passthrough/vtd/vvtd.c > +++ b/xen/drivers/passthrough/vtd/vvtd.c > @@ -20,6 +20,7 @@ > > #include <xen/domain_page.h> > #include <xen/lib.h> > +#include <xen/hvm/save.h> > #include <xen/sched.h> > #include <xen/types.h> > #include <xen/viommu.h> > @@ -32,39 +33,26 @@ > #include <asm/page.h> > #include <asm/p2m.h> > #include <asm/system.h> > +#include <public/hvm/save.h> > > #include "iommu.h" > #include "vtd.h" > > -struct hvm_hw_vvtd_regs { > - uint8_t data[1024]; > -}; > - > /* Status field of struct vvtd */ > #define VIOMMU_STATUS_DEFAULT (0) > #define VIOMMU_STATUS_IRQ_REMAPPING_ENABLED (1 << 0) > #define VIOMMU_STATUS_DMA_REMAPPING_ENABLED (1 << 1) > > #define vvtd_irq_remapping_enabled(vvtd) \ > - (vvtd->status & VIOMMU_STATUS_IRQ_REMAPPING_ENABLED) > + (vvtd->hw.status & VIOMMU_STATUS_IRQ_REMAPPING_ENABLED) > > struct vvtd { > - /* VIOMMU_STATUS_XXX */ > - int status; > - /* Fault Recording index */ > - int frcd_idx; > /* Address range of remapping hardware register-set */ > uint64_t base_addr; > uint64_t length; > /* Point back to the owner domain */ > struct domain *domain; > - /* Is in Extended Interrupt Mode? */ > - bool eim; > - /* Max remapping entries in IRT */ > - int irt_max_entry; > - /* Interrupt remapping table base gfn */ > - uint64_t irt; > - > + struct hvm_hw_vvtd hw; This should have been done in the first patch IMHO, rather than moving things around now. Directly define hvm_hw_vvtd instead of itroducing it now. > struct hvm_hw_vvtd_regs *regs; > struct page_info *regs_page; > }; > @@ -370,12 +358,12 @@ static int vvtd_alloc_frcd(struct vvtd *vvtd) > int prev; > > /* Set the F bit to indicate the FRCD is in use. */ > - if ( vvtd_test_and_set_bit(vvtd, DMA_FRCD(vvtd->frcd_idx, > DMA_FRCD3_OFFSET), > + if ( vvtd_test_and_set_bit(vvtd, DMA_FRCD(vvtd->hw.frcd_idx, > DMA_FRCD3_OFFSET), > DMA_FRCD_F_BIT) ) > { > - prev = vvtd->frcd_idx; > - vvtd->frcd_idx = (prev + 1) % DMA_FRCD_REG_NR; > - return vvtd->frcd_idx; > + prev = vvtd->hw.frcd_idx; > + vvtd->hw.frcd_idx = (prev + 1) % DMA_FRCD_REG_NR; > + return vvtd->hw.frcd_idx; > } > return -1; > } > @@ -712,12 +700,12 @@ static int vvtd_handle_gcmd_ire(struct vvtd *vvtd, > uint32_t val) > > if ( val & DMA_GCMD_IRE ) > { > - vvtd->status |= VIOMMU_STATUS_IRQ_REMAPPING_ENABLED; > + vvtd->hw.status |= VIOMMU_STATUS_IRQ_REMAPPING_ENABLED; > __vvtd_set_bit(vvtd, DMAR_GSTS_REG, DMA_GSTS_IRES_BIT); > } > else > { > - vvtd->status |= ~VIOMMU_STATUS_IRQ_REMAPPING_ENABLED; > + vvtd->hw.status |= ~VIOMMU_STATUS_IRQ_REMAPPING_ENABLED; > __vvtd_clear_bit(vvtd, DMAR_GSTS_REG, DMA_GSTS_IRES_BIT); > } > > @@ -736,11 +724,11 @@ static int vvtd_handle_gcmd_sirtp(struct vvtd *vvtd, > uint32_t val) > "active." ); > > vvtd_get_reg_quad(vvtd, DMAR_IRTA_REG, irta); > - vvtd->irt = DMA_IRTA_ADDR(irta) >> PAGE_SHIFT; > - vvtd->irt_max_entry = DMA_IRTA_SIZE(irta); > - vvtd->eim = DMA_IRTA_EIME(irta); > + vvtd->hw.irt = DMA_IRTA_ADDR(irta) >> PAGE_SHIFT; > + vvtd->hw.irt_max_entry = DMA_IRTA_SIZE(irta); > + vvtd->hw.eim = DMA_IRTA_EIME(irta); > VVTD_DEBUG(VVTD_DBG_RW, "Update IR info (addr=%lx eim=%d size=%d).", > - vvtd->irt, vvtd->eim, vvtd->irt_max_entry); > + vvtd->hw.irt, vvtd->hw.eim, vvtd->hw.irt_max_entry); > __vvtd_set_bit(vvtd, DMAR_GSTS_REG, DMA_GSTS_SIRTPS_BIT); > > return X86EMUL_OKAY; > @@ -947,13 +935,13 @@ static int vvtd_get_entry(struct vvtd *vvtd, > > VVTD_DEBUG(VVTD_DBG_TRANS, "interpret a request with index %x", entry); > > - if ( entry > vvtd->irt_max_entry ) > + if ( entry > vvtd->hw.irt_max_entry ) > { > ret = VTD_FR_IR_INDEX_OVER; > goto handle_fault; > } > > - ret = map_guest_page(vvtd->domain, vvtd->irt + (entry >> > IREMAP_ENTRY_ORDER), > + ret = map_guest_page(vvtd->domain, vvtd->hw.irt + (entry >> > IREMAP_ENTRY_ORDER), Line length. > (void**)&irt_page); > if ( ret ) > { > @@ -1077,6 +1065,49 @@ static int vvtd_get_irq_info(struct domain *d, > return 0; > } > > +static int vvtd_load_regs(struct domain *d, hvm_domain_context_t *h) > +{ > + if ( !domain_vvtd(d) ) > + return -ENODEV; > + > + if ( hvm_load_entry(IOMMU_REGS, h, domain_vvtd(d)->regs) ) > + return -EINVAL; > + > + return 0; > +} > + > +static int vvtd_save_regs(struct domain *d, hvm_domain_context_t *h) > +{ > + if ( !domain_vvtd(d) ) > + return 0; > + > + return hvm_save_entry(IOMMU_REGS, 0, h, domain_vvtd(d)->regs); > +} > + > +static int vvtd_load_hidden(struct domain *d, hvm_domain_context_t *h) > +{ > + if ( !domain_vvtd(d) ) > + return -ENODEV; > + > + if ( hvm_load_entry(IOMMU, h, &domain_vvtd(d)->hw) ) > + return -EINVAL; > + > + return 0; > +} > + > +static int vvtd_save_hidden(struct domain *d, hvm_domain_context_t *h) > +{ > + if ( !domain_vvtd(d) ) > + return 0; > + > + return hvm_save_entry(IOMMU, 0, h, &domain_vvtd(d)->hw); > +} > + > +HVM_REGISTER_SAVE_RESTORE(IOMMU, vvtd_save_hidden, vvtd_load_hidden, > + 1, HVMSR_PER_DOM); > +HVM_REGISTER_SAVE_RESTORE(IOMMU_REGS, vvtd_save_regs, vvtd_load_regs, > + 1, HVMSR_PER_DOM); > + > static void vvtd_reset(struct vvtd *vvtd, uint64_t capability) > { > uint64_t cap = DMA_CAP_NFR | DMA_CAP_SLLPS | DMA_CAP_FRO | > @@ -1122,12 +1153,13 @@ static int vvtd_create(struct domain *d, struct > viommu *viommu) > vvtd->base_addr = viommu->base_address; > vvtd->length = viommu->length; > vvtd->domain = d; > - vvtd->status = VIOMMU_STATUS_DEFAULT; > - vvtd->eim = 0; > - vvtd->irt = 0; > - vvtd->irt_max_entry = 0; > - vvtd->frcd_idx = 0; > + vvtd->hw.status = VIOMMU_STATUS_DEFAULT; > + vvtd->hw.eim = 0; > + vvtd->hw.irt = 0; > + vvtd->hw.irt_max_entry = 0; > + vvtd->hw.frcd_idx = 0; > register_mmio_handler(d, &vvtd_mmio_ops); > + viommu->priv = (void *)vvtd; > return 0; > > out2: > diff --git a/xen/include/public/arch-x86/hvm/save.h > b/xen/include/public/arch-x86/hvm/save.h > index fd7bf3f..10536cb 100644 > --- a/xen/include/public/arch-x86/hvm/save.h > +++ b/xen/include/public/arch-x86/hvm/save.h > @@ -639,10 +639,32 @@ struct hvm_msr { > > #define CPU_MSR_CODE 20 > > +struct hvm_hw_vvtd_regs { > + uint8_t data[1024]; > +}; > + > +DECLARE_HVM_SAVE_TYPE(IOMMU_REGS, 21, struct hvm_hw_vvtd_regs); > + > +struct hvm_hw_vvtd > +{ > + /* VIOMMU_STATUS_XXX */ > + uint32_t status; > + /* Fault Recording index */ > + uint32_t frcd_idx; > + /* Is in Extended Interrupt Mode? */ > + uint32_t eim; > + /* Max remapping entries in IRT */ > + uint32_t irt_max_entry; > + /* Interrupt remapping table base gfn */ > + uint64_t irt; > +}; > + > +DECLARE_HVM_SAVE_TYPE(IOMMU, 22, struct hvm_hw_vvtd); Why two separate structures? It should be the same structure. Roger. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |