On Fri, Aug 15, 2014 at 08:12:29PM +1000, Alexey Kardashevskiy wrote: > This adds support for Dynamic DMA Windows (DDW) option defined by > the SPAPR specification which allows to have additional DMA window(s) > which can support page sizes other than 4K. > > The existing implementation of DDW in the guest tries to create one huge > DMA window with 64K or 16MB pages and map the entire guest RAM to. If it > succeeds, the guest switches to dma_direct_ops and never calls > TCE hypercalls (H_PUT_TCE,...) again. This enables VFIO devices to use > the entire RAM and not waste time on map/unmap. > > This adds 4 RTAS handlers: > * ibm,query-pe-dma-window > * ibm,create-pe-dma-window > * ibm,remove-pe-dma-window > * ibm,reset-pe-dma-window > These are registered from type_init() callback. > > These RTAS handlers are implemented in a separate file to avoid polluting > spapr_iommu.c with PHB. > > Since no PHB class implements new callback in this patch, no functional > change is expected.
[snip] > +static void rtas_ibm_create_pe_dma_window(PowerPCCPU *cpu, > + sPAPREnvironment *spapr, > + uint32_t token, uint32_t nargs, > + target_ulong args, > + uint32_t nret, target_ulong rets) > +{ > + sPAPRPHBState *sphb; > + sPAPRPHBClass *spc; > + sPAPRTCETable *tcet = NULL; > + uint32_t addr, page_shift, window_shift, liobn; > + uint64_t buid; > + long ret; > + > + if ((nargs != 5) || (nret != 4)) { > + goto param_error_exit; > + } > + > + buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); > + addr = rtas_ld(args, 0); > + sphb = spapr_pci_find_phb(spapr, buid); > + if (!sphb) { > + goto param_error_exit; > + } > + > + spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb); > + if (!spc->ddw_create) { > + goto hw_error_exit; > + } > + > + page_shift = rtas_ld(args, 3); > + window_shift = rtas_ld(args, 4); > + /* Default 32bit window#0 is always there so +1 */ > + liobn = SPAPR_PCI_LIOBN(sphb->index, sphb->ddw_num + 1); > + > + ret = spc->ddw_create(sphb, page_shift, window_shift, liobn, &tcet); > + trace_spapr_iommu_ddw_create(buid, addr, 1ULL << page_shift, > + 1ULL << window_shift, > + tcet ? tcet->bus_offset : 0xbaadf00d, > + liobn, ret); > + if (ret || !tcet) { > + goto hw_error_exit; > + } > + > + sphb->ddw_num++; You increment ddw_num here... [snip] > +static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu, > + sPAPREnvironment *spapr, > + uint32_t token, uint32_t nargs, > + target_ulong args, > + uint32_t nret, target_ulong rets) > +{ > + sPAPRPHBState *sphb; > + sPAPRPHBClass *spc; > + sPAPRTCETable *tcet; > + uint32_t liobn; > + long ret; > + > + if ((nargs != 1) || (nret != 1)) { > + goto param_error_exit; > + } > + > + liobn = rtas_ld(args, 0); > + tcet = spapr_tce_find_by_liobn(liobn); > + if (!tcet) { > + goto param_error_exit; > + } > + > + sphb = SPAPR_PCI_HOST_BRIDGE(OBJECT(tcet)->parent); > + if (!sphb) { > + goto param_error_exit; > + } > + > + spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb); > + if (!spc->ddw_remove) { > + goto hw_error_exit; > + } > + > + ret = spc->ddw_remove(sphb, tcet); > + trace_spapr_iommu_ddw_remove(liobn, ret); > + if (ret) { > + goto hw_error_exit; > + } > + > + rtas_st(rets, 0, RTAS_OUT_SUCCESS); > + return; .. but don't decrement it here. Is that a bug? [snip] > +static void rtas_ibm_reset_pe_dma_window(PowerPCCPU *cpu, > + sPAPREnvironment *spapr, > + uint32_t token, uint32_t nargs, > + target_ulong args, > + uint32_t nret, target_ulong rets) > +{ > + sPAPRPHBState *sphb; > + sPAPRPHBClass *spc; > + uint64_t buid; > + uint32_t addr; > + long ret; > + > + if ((nargs != 3) || (nret != 1)) { > + goto param_error_exit; > + } > + > + buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); > + addr = rtas_ld(args, 0); > + sphb = spapr_pci_find_phb(spapr, buid); > + if (!sphb) { > + goto param_error_exit; > + } > + > + spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb); > + if (!spc->ddw_reset) { > + goto hw_error_exit; > + } > + > + ret = spc->ddw_reset(sphb); > + trace_spapr_iommu_ddw_reset(buid, addr, ret); > + if (ret) { > + goto hw_error_exit; > + } Likewise ddw_num doesn't seem to be reset here. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
pgpTvE7NLqJrd.pgp
Description: PGP signature