All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexey Kardashevskiy <aik@ozlabs.ru>
To: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman <michael@ellerman.id.au>,
	Paul Mackerras <paulus@samba.org>,
	Gavin Shan <gwshan@linux.vnet.ibm.com>
Subject: Re: [PATCH v4 16/16] vfio: powerpc/spapr: Enable Dynamic DMA windows
Date: Wed, 30 Jul 2014 19:36:52 +1000	[thread overview]
Message-ID: <53D8BCB4.7070802@ozlabs.ru> (raw)
In-Reply-To: <1406712695-9491-17-git-send-email-aik@ozlabs.ru>

On 07/30/2014 07:31 PM, Alexey Kardashevskiy wrote:
> This defines and implements VFIO IOMMU API required to support
> Dynamic DMA windows defined in the SPAPR specification. The ioctl handlers
> implement host-size part of corresponding RTAS calls:
> - VFIO_IOMMU_SPAPR_TCE_QUERY - ibm,query-pe-dma-window;
> - VFIO_IOMMU_SPAPR_TCE_CREATE - ibm,create-pe-dma-window;
> - VFIO_IOMMU_SPAPR_TCE_REMOVE - ibm,remove-pe-dma-window;
> - VFIO_IOMMU_SPAPR_TCE_RESET - ibm,reset-pe-dma-window.
> 
> The VFIO IOMMU driver does basic sanity checks and calls corresponding
> SPAPR TCE functions. At the moment only IODA2 (POWER8 PCI host bridge)
> implements them.
> 
> This advertises VFIO_IOMMU_SPAPR_TCE_FLAG_DDW capability via
> VFIO_IOMMU_SPAPR_TCE_GET_INFO.
> 
> This calls reset() when IOMMU is being disabled (happens when VFIO stops
> using it).
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
>  arch/powerpc/platforms/powernv/pci-ioda.c |   1 +
>  drivers/vfio/vfio_iommu_spapr_tce.c       | 173 +++++++++++++++++++++++++++++-
>  include/uapi/linux/vfio.h                 |  37 ++++++-
>  3 files changed, 209 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 6a847b2..f51afe2 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -859,6 +859,7 @@ static long pnv_pci_ioda2_ddw_create(struct spapr_tce_iommu_group *data,
>  
>  	/* Copy "invalidate" register address */
>  	tbl64->it_index = pe->tce32.table.it_index;
> +	tbl64->it_group = pe->tce32.table.it_group;

Just noticed. This does not belong here, this must be moved to earlier patch.


>  	tbl64->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE |
>  			TCE_PCI_SWINV_PAIR;
>  	tbl64->it_map = (void *) 0xDEADBEEF; /* poison */
> diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
> index 48b256c..32e2804 100644
> --- a/drivers/vfio/vfio_iommu_spapr_tce.c
> +++ b/drivers/vfio/vfio_iommu_spapr_tce.c
> @@ -45,6 +45,7 @@ struct tce_container {
>  	struct mutex lock;
>  	struct iommu_group *grp;
>  	bool enabled;
> +	unsigned long start64;
>  };
>  
>  
> @@ -123,19 +124,36 @@ static void tce_iommu_disable(struct tce_container *container)
>  
>  	container->enabled = false;
>  
> -	if (!container->grp || !current->mm)
> +	if (!container->grp)
>  		return;
>  
>  	data = iommu_group_get_iommudata(container->grp);
>  	if (!data || !data->iommu_owner || !data->ops->get_table)
>  		return;
>  
> +	/* Try resetting, there might have been a 64bit window */
> +	if (data->ops->reset)
> +		data->ops->reset(data);
> +
> +	if (!current->mm)
> +		return;
> +
>  	tbl = data->ops->get_table(data, TCE_DEFAULT_WINDOW);
>  	if (!tbl)
>  		return;
>  
>  	decrement_locked_vm((tbl->it_size << tbl->it_page_shift) >>
>  			PAGE_SHIFT);
> +
> +	if (!container->start64)
> +		return;
> +
> +	tbl = data->ops->get_table(data, container->start64);
> +	if (!tbl)
> +		return;
> +
> +	decrement_locked_vm((tbl->it_size << tbl->it_page_shift) >>
> +			PAGE_SHIFT);
>  }
>  
>  static void *tce_iommu_open(unsigned long arg)
> @@ -210,6 +228,8 @@ static long tce_iommu_ioctl(void *iommu_data,
>  		info.dma32_window_start = tbl->it_offset << tbl->it_page_shift;
>  		info.dma32_window_size = tbl->it_size << tbl->it_page_shift;
>  		info.flags = 0;
> +		if (data->ops->query && data->ops->create && data->ops->remove)
> +			info.flags |= VFIO_IOMMU_SPAPR_TCE_FLAG_DDW;
>  
>  		if (copy_to_user((void __user *)arg, &info, minsz))
>  			return -EFAULT;
> @@ -335,6 +355,157 @@ static long tce_iommu_ioctl(void *iommu_data,
>  		tce_iommu_disable(container);
>  		mutex_unlock(&container->lock);
>  		return 0;
> +
> +	case VFIO_IOMMU_SPAPR_TCE_QUERY: {
> +		struct vfio_iommu_spapr_tce_query query;
> +		struct spapr_tce_iommu_group *data;
> +
> +		if (WARN_ON(!container->grp))
> +			return -ENXIO;
> +
> +		data = iommu_group_get_iommudata(container->grp);
> +
> +		minsz = offsetofend(struct vfio_iommu_spapr_tce_query,
> +				page_size_mask);
> +
> +		if (copy_from_user(&query, (void __user *)arg, minsz))
> +			return -EFAULT;
> +
> +		if (query.argsz < minsz)
> +			return -EINVAL;
> +
> +		if (!data->ops->query || !data->iommu_owner)
> +			return -ENOSYS;
> +
> +		ret = data->ops->query(data,
> +				&query.windows_available,
> +				&query.page_size_mask);
> +
> +		if (ret)
> +			return ret;
> +
> +		if (copy_to_user((void __user *)arg, &query, minsz))
> +			return -EFAULT;
> +
> +		return 0;
> +	}
> +	case VFIO_IOMMU_SPAPR_TCE_CREATE: {
> +		struct vfio_iommu_spapr_tce_create create;
> +		struct spapr_tce_iommu_group *data;
> +		struct iommu_table *tbl;
> +
> +		if (WARN_ON(!container->grp))
> +			return -ENXIO;
> +
> +		data = iommu_group_get_iommudata(container->grp);
> +
> +		minsz = offsetofend(struct vfio_iommu_spapr_tce_create,
> +				start_addr);
> +
> +		if (copy_from_user(&create, (void __user *)arg, minsz))
> +			return -EFAULT;
> +
> +		if (create.argsz < minsz)
> +			return -EINVAL;
> +
> +		if (!data->ops->create || !data->iommu_owner)
> +			return -ENOSYS;
> +
> +		BUG_ON(!data || !data->ops || !data->ops->remove);
> +
> +		ret = data->ops->create(data, create.page_shift,
> +				create.window_shift, &tbl);
> +		if (ret)
> +			return ret;
> +
> +		ret = try_increment_locked_vm((tbl->it_size <<
> +					tbl->it_page_shift) >> PAGE_SHIFT);
> +		if (ret) {
> +			data->ops->remove(data, tbl);
> +			return ret;
> +		}
> +
> +		create.start_addr = tbl->it_offset << tbl->it_page_shift;
> +
> +		if (copy_to_user((void __user *)arg, &create, minsz)) {
> +			data->ops->remove(data, tbl);
> +			decrement_locked_vm((tbl->it_size <<
> +					tbl->it_page_shift) >> PAGE_SHIFT);
> +			return -EFAULT;
> +		}
> +
> +		return ret;
> +	}
> +	case VFIO_IOMMU_SPAPR_TCE_REMOVE: {
> +		struct vfio_iommu_spapr_tce_remove remove;
> +		struct spapr_tce_iommu_group *data;
> +		struct iommu_table *tbl;
> +
> +		if (WARN_ON(!container->grp))
> +			return -ENXIO;
> +
> +		data = iommu_group_get_iommudata(container->grp);
> +
> +		minsz = offsetofend(struct vfio_iommu_spapr_tce_remove,
> +				start_addr);
> +
> +		if (copy_from_user(&remove, (void __user *)arg, minsz))
> +			return -EFAULT;
> +
> +		if (remove.argsz < minsz)
> +			return -EINVAL;
> +
> +		if (!data->ops->remove || !data->iommu_owner)
> +			return -ENOSYS;
> +
> +		tbl = data->ops->get_table(data, remove.start_addr);
> +		if (!tbl)
> +			return -EINVAL;
> +
> +		ret = data->ops->remove(data, tbl);
> +		if (ret)
> +			return ret;
> +
> +		decrement_locked_vm((tbl->it_size << tbl->it_page_shift)
> +				>> PAGE_SHIFT);
> +		return 0;
> +	}
> +	case VFIO_IOMMU_SPAPR_TCE_RESET: {
> +		struct vfio_iommu_spapr_tce_reset reset;
> +		struct spapr_tce_iommu_group *data;
> +
> +		if (WARN_ON(!container->grp))
> +			return -ENXIO;
> +
> +		data = iommu_group_get_iommudata(container->grp);
> +
> +		minsz = offsetofend(struct vfio_iommu_spapr_tce_reset, argsz);
> +
> +		if (copy_from_user(&reset, (void __user *)arg, minsz))
> +			return -EFAULT;
> +
> +		if (reset.argsz < minsz)
> +			return -EINVAL;
> +
> +		if (!data->ops->reset || !data->iommu_owner)
> +			return -ENOSYS;
> +
> +		ret = data->ops->reset(data);
> +		if (ret)
> +			return ret;
> +
> +		if (container->start64) {
> +			struct iommu_table *tbl;
> +
> +			tbl = data->ops->get_table(data, container->start64);
> +			BUG_ON(!tbl);
> +
> +			decrement_locked_vm((tbl->it_size << tbl->it_page_shift)
> +					>> PAGE_SHIFT);
> +		}
> +
> +		return 0;
> +	}
>  	}
>  
>  	return -ENOTTY;
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index cb9023d..8b03381 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -448,13 +448,48 @@ struct vfio_iommu_type1_dma_unmap {
>   */
>  struct vfio_iommu_spapr_tce_info {
>  	__u32 argsz;
> -	__u32 flags;			/* reserved for future use */
> +	__u32 flags;
> +#define VFIO_IOMMU_SPAPR_TCE_FLAG_DDW	1 /* Support dynamic windows */
>  	__u32 dma32_window_start;	/* 32 bit window start (bytes) */
>  	__u32 dma32_window_size;	/* 32 bit window size (bytes) */
>  };
>  
>  #define VFIO_IOMMU_SPAPR_TCE_GET_INFO	_IO(VFIO_TYPE, VFIO_BASE + 12)
>  
> +/*
> + * Dynamic DMA windows
> + */
> +struct vfio_iommu_spapr_tce_query {
> +	__u32 argsz;
> +	/* out */
> +	__u32 windows_available;
> +	__u32 page_size_mask;
> +};
> +#define VFIO_IOMMU_SPAPR_TCE_QUERY	_IO(VFIO_TYPE, VFIO_BASE + 17)
> +
> +struct vfio_iommu_spapr_tce_create {
> +	__u32 argsz;
> +	/* in */
> +	__u32 page_shift;
> +	__u32 window_shift;
> +	/* out */
> +	__u64 start_addr;
> +
> +};
> +#define VFIO_IOMMU_SPAPR_TCE_CREATE	_IO(VFIO_TYPE, VFIO_BASE + 18)
> +
> +struct vfio_iommu_spapr_tce_remove {
> +	__u32 argsz;
> +	/* in */
> +	__u64 start_addr;
> +};
> +#define VFIO_IOMMU_SPAPR_TCE_REMOVE	_IO(VFIO_TYPE, VFIO_BASE + 19)
> +
> +struct vfio_iommu_spapr_tce_reset {
> +	__u32 argsz;
> +};
> +#define VFIO_IOMMU_SPAPR_TCE_RESET	_IO(VFIO_TYPE, VFIO_BASE + 20)
> +
>  /* ***************************************************************** */
>  
>  #endif /* _UAPIVFIO_H */
> 


-- 
Alexey

      reply	other threads:[~2014-07-30  9:37 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-30  9:31 [PATCH v4 00/16] powernv: vfio: Add Dynamic DMA windows (DDW) Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 01/16] rcu: Define notrace version of list_for_each_entry_rcu and list_entry_rcu Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 02/16] KVM: PPC: Use RCU for arch.spapr_tce_tables Alexey Kardashevskiy
2014-08-21  5:25   ` Paul Mackerras
2014-07-30  9:31 ` [PATCH v4 03/16] mm: Add helpers for locked_vm Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 04/16] KVM: PPC: Account TCE-containing pages in locked_vm Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 05/16] powerpc/iommu: Fix comments with it_page_shift Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 06/16] powerpc/powernv: Make invalidate() a callback Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 07/16] powerpc/spapr: vfio: Implement spapr_tce_iommu_ops Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 08/16] powerpc/powernv: Convert/move set_bypass() callback to take_ownership() Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 09/16] powerpc/iommu: Fix IOMMU ownership control functions Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 10/16] powerpc: Move tce_xxx callbacks from ppc_md to iommu_table Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 11/16] powerpc/powernv: Release replaced TCE Alexey Kardashevskiy
2014-08-06  6:25   ` Benjamin Herrenschmidt
2014-08-06  6:27   ` Benjamin Herrenschmidt
2014-08-06  6:27   ` Benjamin Herrenschmidt
2014-07-30  9:31 ` [PATCH v4 12/16] powerpc/pseries/lpar: Enable VFIO Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 13/16] powerpc/powernv: Implement Dynamic DMA windows (DDW) for IODA Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 14/16] vfio: powerpc/spapr: Reuse locked_vm accounting helpers Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 15/16] vfio: powerpc/spapr: Use it_page_size Alexey Kardashevskiy
2014-07-30  9:31 ` [PATCH v4 16/16] vfio: powerpc/spapr: Enable Dynamic DMA windows Alexey Kardashevskiy
2014-07-30  9:36   ` Alexey Kardashevskiy [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53D8BCB4.7070802@ozlabs.ru \
    --to=aik@ozlabs.ru \
    --cc=gwshan@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=michael@ellerman.id.au \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.