[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH V3 11/29] x86/hvm: Introduce a emulated VTD for HVM
On Thu, Oct 19, 2017 at 12:20:35PM +0100, Roger Pau Monné wrote: >On Thu, Sep 21, 2017 at 11:01:52PM -0400, Lan Tianyu wrote: >> From: Chao Gao <chao.gao@xxxxxxxxx> >> >> This patch adds create/destroy function for the emulated VTD >> and adapts it to the common VIOMMU abstraction. >> >> Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx> >> Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx> >> --- >> >> -obj-y += iommu.o >> obj-y += dmar.o >> -obj-y += utils.o >> -obj-y += qinval.o >> obj-y += intremap.o >> +obj-y += iommu.o >> +obj-y += qinval.o >> obj-y += quirks.o >> +obj-y += utils.o > >Why do you need to shuffle the list above? I placed them in alphabetic order. > >Also I'm not sure the Intel vIOMMU implementation should live here. As >you can see the path is: > >xen/drivers/passthrough/vtd/ > >The vIOMMU is not tied to passthrough at all, so I would rather place >it in: > >xen/drivers/vvtd/ > >Or maybe you can create something like: > >xen/drivers/viommu/ > >So that all vIOMMU implementations can share some code. > vvtd and vtd use the same header files (i.g. vtd.h). That is why we put it there. If that, we shoule move the related header files to a public directory. >> #define cap_isoch(c) (((c) >> 23) & 1) >> #define cap_qos(c) (((c) >> 22) & 1) >> #define cap_mgaw(c) ((((c) >> 16) & 0x3f) + 1) >> -#define cap_sagaw(c) (((c) >> 8) & 0x1f) >> +#define cap_set_mgaw(c) ((((c) - 1) & 0x3f) << 16) >> +#define cap_sagaw(c) (((c) >> DMA_CAP_SAGAW_SHIFT) & 0x1f) >> #define cap_caching_mode(c) (((c) >> 7) & 1) >> #define cap_phmr(c) (((c) >> 6) & 1) >> #define cap_plmr(c) (((c) >> 5) & 1) >> @@ -104,10 +113,16 @@ >> #define ecap_niotlb_iunits(e) ((((e) >> 24) & 0xff) + 1) >> #define ecap_iotlb_offset(e) ((((e) >> 8) & 0x3ff) * 16) >> #define ecap_coherent(e) ((e >> 0) & 0x1) >> -#define ecap_queued_inval(e) ((e >> 1) & 0x1) >> +#define DMA_ECAP_QI_SHIFT 1 >> +#define DMA_ECAP_QI (1ULL << DMA_ECAP_QI_SHIFT) >> +#define ecap_queued_inval(e) ((e >> DMA_ECAP_QI_SHIFT) & 0x1) > >Looks like this could be based on MASK_EXTR instead, but seeing how >the file is full of open-coded mask extracts I'm not sure it's worth >it anymore. > >> #define ecap_dev_iotlb(e) ((e >> 2) & 0x1) >> -#define ecap_intr_remap(e) ((e >> 3) & 0x1) >> -#define ecap_eim(e) ((e >> 4) & 0x1) >> +#define DMA_ECAP_IR_SHIFT 3 >> +#define DMA_ECAP_IR (1ULL << DMA_ECAP_IR_SHIFT) >> +#define ecap_intr_remap(e) ((e >> DMA_ECAP_IR_SHIFT) & 0x1) >> +#define DMA_ECAP_EIM_SHIFT 4 >> +#define DMA_ECAP_EIM (1ULL << DMA_ECAP_EIM_SHIFT) >> +#define ecap_eim(e) ((e >> DMA_ECAP_EIM_SHIFT) & 0x1) > >Maybe worth placing all the DMA_ECAP_* defines in a separate section? >Seems like how it's done for other features like DMA_FSTS or >DMA_CCMD. Got it. >> + >> +/* Supported capabilities by vvtd */ >> +unsigned int vvtd_caps = VIOMMU_CAP_IRQ_REMAPPING; > >static? > >Or even better, why is this not a define like VIOMMU_MAX_CAPS or >similar. Yeah. It should be renamed to VVTD_MAX_CAPS. > >> + >> +union hvm_hw_vvtd_regs { >> + uint32_t data32[256]; >> + uint64_t data64[128]; >> +}; > >Do you really need to store all the register space instead of only >storing specific registers? I prefer to store all the registers for we don't need a trick to map the real offset in hardware to the index in the array. > >> + >> +struct vvtd { >> + /* Address range of remapping hardware register-set */ >> + uint64_t base_addr; >> + uint64_t length; > >The length field doesn't seem to be used below. will remove it. > >> + /* Point back to the owner domain */ >> + struct domain *domain; >> + union hvm_hw_vvtd_regs *regs; > >Does this need to be a pointer? Seems not. > >> + struct page_info *regs_page; >> +}; >> + >> +static int vvtd_create(struct domain *d, struct viommu *viommu) >> +{ >> + struct vvtd *vvtd; >> + int ret; >> + >> + if ( !is_hvm_domain(d) || (viommu->base_address & (PAGE_SIZE - 1)) || >> + (~vvtd_caps & viommu->caps) ) >> + return -EINVAL; >> + >> + ret = -ENOMEM; >> + vvtd = xzalloc_bytes(sizeof(struct vvtd)); >> + if ( !vvtd ) >> + return ret; >> + >> + vvtd->regs_page = alloc_domheap_page(d, MEMF_no_owner); >> + if ( !vvtd->regs_page ) >> + goto out1; >> + >> + vvtd->regs = __map_domain_page_global(vvtd->regs_page); >> + if ( !vvtd->regs ) >> + goto out2; >> + clear_page(vvtd->regs); > >Not sure why vvtd->regs needs to be a pointer, and why it needs to use >a full page. AFAICT the size of hvm_hw_vvtd_regs is 1024B, so you are >wasting 3/4 of a page. I will define registers as an array directly and shrink the size to the number we are really used now. >> +struct viommu_ops vvtd_hvm_vmx_ops = { >> + .create = vvtd_create, >> + .destroy = vvtd_destroy >> +}; >> + >> +static int vvtd_register(void) >> +{ >> + viommu_register_type(VIOMMU_TYPE_INTEL_VTD, &vvtd_hvm_vmx_ops); >> + return 0; >> +} >> +__initcall(vvtd_register); > >As commented in another patch I think the vIOMMU types should be >registered using a method similar to REGISTER_SCHEDULER. Both are ok to me. Will follow your suggestion. Thanks Chao _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |