RE: [PATCH v3 04/11] vfio: Move storage of allow_unsafe_interrupts to vfio_main.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> From: Jason Gunthorpe <jgg@xxxxxxxxxx>
> Sent: Thursday, November 24, 2022 3:48 AM
> 
> On Mon, Nov 21, 2022 at 09:59:28PM -0400, Jason Gunthorpe wrote:
> > On Fri, Nov 18, 2022 at 01:36:46PM -0700, Alex Williamson wrote:
> > > On Fri, 18 Nov 2022 11:36:14 -0400
> > > Jason Gunthorpe <jgg@xxxxxxxxxx> wrote:
> > >
> > > > On Thu, Nov 17, 2022 at 01:14:51PM -0700, Alex Williamson wrote:
> > > > > On Wed, 16 Nov 2022 17:05:29 -0400
> > > > > Jason Gunthorpe <jgg@xxxxxxxxxx> wrote:
> > > > >
> > > > > > This legacy module knob has become uAPI, when set on the
> vfio_iommu_type1
> > > > > > it disables some security protections in the iommu drivers. Move the
> > > > > > storage for this knob to vfio_main.c so that iommufd can access it
> too.
> > > > > >
> > > > > > The may need enhancing as we learn more about how necessary
> > > > > > allow_unsafe_interrupts is in the current state of the world. If vfio
> > > > > > container is disabled then this option will not be available to the
> user.
> > > > > >
> > > > > > Tested-by: Nicolin Chen <nicolinc@xxxxxxxxxx>
> > > > > > Tested-by: Yi Liu <yi.l.liu@xxxxxxxxx>
> > > > > > Tested-by: Lixiao Yang <lixiao.yang@xxxxxxxxx>
> > > > > > Tested-by: Matthew Rosato <mjrosato@xxxxxxxxxxxxx>
> > > > > > Tested-by: Yu He <yu.he@xxxxxxxxx>
> > > > > > Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx>
> > > > > > ---
> > > > > >  drivers/vfio/vfio.h             | 2 ++
> > > > > >  drivers/vfio/vfio_iommu_type1.c | 5 ++---
> > > > > >  drivers/vfio/vfio_main.c        | 3 +++
> > > > > >  3 files changed, 7 insertions(+), 3 deletions(-)
> > > > >
> > > > > It's really quite trivial to convert to a vfio_iommu.ko module to host
> > > > > a separate option for this.  Half of the patch below is undoing what's
> > > > > done here.  Is your only concern with this approach that we use a few
> > > > > KB more memory for the separate module?
> > > >
> > > > My main dislike is that it just seems arbitary to shunt iommufd
> > > > support to a module when it is always required by vfio.ko. In general
> > > > if you have a module that is only ever used by 1 other module, you
> > > > should probably just combine them. It saves memory and simplifies
> > > > operation (eg you don't have to unload a zoo of modules during
> > > > development testing)
> > >
> > > These are all great reasons for why iommufd should host this option, as
> > > it's fundamentally part of the DMA isolation of the device, which vfio
> > > relies on iommufd to provide in this case.
> >
> > Fine, lets do that.
> 
> It looks like this:
> 
> diff --git a/drivers/iommu/iommufd/device.c
> b/drivers/iommu/iommufd/device.c
> index 07d4dcc0dbf5e1..6d088af776034b 100644
> --- a/drivers/iommu/iommufd/device.c
> +++ b/drivers/iommu/iommufd/device.c
> @@ -9,6 +9,13 @@
>  #include "io_pagetable.h"
>  #include "iommufd_private.h"
> 
> +static bool allow_unsafe_interrupts;
> +module_param(allow_unsafe_interrupts, bool, S_IRUGO | S_IWUSR);
> +MODULE_PARM_DESC(
> +	allow_unsafe_interrupts,
> +	"Allow IOMMUFD to bind to devices even if the platform cannot
> isolate "
> +	"the MSI interrupt window. Enabling this is a security weakness.");
> +
>  /*
>   * A iommufd_device object represents the binding relationship between a
>   * consuming driver and the iommufd. These objects are created/destroyed
> by
> @@ -127,8 +134,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_unbind,
> IOMMUFD);
> 
>  static int iommufd_device_setup_msi(struct iommufd_device *idev,
>  				    struct iommufd_hw_pagetable *hwpt,
> -				    phys_addr_t sw_msi_start,
> -				    unsigned int flags)
> +				    phys_addr_t sw_msi_start)
>  {
>  	int rc;
> 
> @@ -174,12 +180,11 @@ static int iommufd_device_setup_msi(struct
> iommufd_device *idev,
>  	 * historical compat with VFIO allow a module parameter to ignore
> the
>  	 * insecurity.
>  	 */
> -	if (!(flags &
> IOMMUFD_ATTACH_FLAGS_ALLOW_UNSAFE_INTERRUPT))
> +	if (!allow_unsafe_interrupts)
>  		return -EPERM;
> -

keep the blank line.

>  	dev_warn(
>  		idev->dev,
> -		"Device interrupts cannot be isolated by the IOMMU, this
> platform in insecure. Use an \"allow_unsafe_interrupts\" module parameter
> to override\n");
> +		"MSI interrupt window cannot be isolated by the IOMMU,
> this platform in insecure. Use the \"allow_unsafe_interrupts\" module

s/in/is/

> parameter to override\n");
>  	return 0;
>  }
> 
> @@ -195,8 +200,7 @@ static bool
> iommufd_hw_pagetable_has_group(struct iommufd_hw_pagetable *hwpt,
>  }
> 
>  static int iommufd_device_do_attach(struct iommufd_device *idev,
> -				    struct iommufd_hw_pagetable *hwpt,
> -				    unsigned int flags)
> +				    struct iommufd_hw_pagetable *hwpt)
>  {
>  	phys_addr_t sw_msi_start = 0;
>  	int rc;
> @@ -226,7 +230,7 @@ static int iommufd_device_do_attach(struct
> iommufd_device *idev,
>  	if (rc)
>  		goto out_unlock;
> 
> -	rc = iommufd_device_setup_msi(idev, hwpt, sw_msi_start, flags);
> +	rc = iommufd_device_setup_msi(idev, hwpt, sw_msi_start);
>  	if (rc)
>  		goto out_iova;
> 
> @@ -268,8 +272,7 @@ static int iommufd_device_do_attach(struct
> iommufd_device *idev,
>   * Automatic domain selection will never pick a manually created domain.
>   */
>  static int iommufd_device_auto_get_domain(struct iommufd_device *idev,
> -					  struct iommufd_ioas *ioas,
> -					  unsigned int flags)
> +					  struct iommufd_ioas *ioas)
>  {
>  	struct iommufd_hw_pagetable *hwpt;
>  	int rc;
> @@ -284,7 +287,7 @@ static int iommufd_device_auto_get_domain(struct
> iommufd_device *idev,
>  		if (!hwpt->auto_domain)
>  			continue;
> 
> -		rc = iommufd_device_do_attach(idev, hwpt, flags);
> +		rc = iommufd_device_do_attach(idev, hwpt);
> 
>  		/*
>  		 * -EINVAL means the domain is incompatible with the device.
> @@ -303,7 +306,7 @@ static int iommufd_device_auto_get_domain(struct
> iommufd_device *idev,
>  	}
>  	hwpt->auto_domain = true;
> 
> -	rc = iommufd_device_do_attach(idev, hwpt, flags);
> +	rc = iommufd_device_do_attach(idev, hwpt);
>  	if (rc)
>  		goto out_abort;
>  	list_add_tail(&hwpt->hwpt_item, &ioas->hwpt_list);
> @@ -324,7 +327,6 @@ static int iommufd_device_auto_get_domain(struct
> iommufd_device *idev,
>   * @idev: device to attach
>   * @pt_id: Input a IOMMUFD_OBJ_IOAS, or
> IOMMUFD_OBJ_HW_PAGETABLE
>   *         Output the IOMMUFD_OBJ_HW_PAGETABLE ID
> - * @flags: Optional flags
>   *
>   * This connects the device to an iommu_domain, either automatically or
> manually
>   * selected. Once this completes the device could do DMA.
> @@ -332,8 +334,7 @@ static int iommufd_device_auto_get_domain(struct
> iommufd_device *idev,
>   * The caller should return the resulting pt_id back to userspace.
>   * This function is undone by calling iommufd_device_detach().
>   */
> -int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id,
> -			  unsigned int flags)
> +int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id)
>  {
>  	struct iommufd_object *pt_obj;
>  	int rc;
> @@ -347,7 +348,7 @@ int iommufd_device_attach(struct iommufd_device
> *idev, u32 *pt_id,
>  		struct iommufd_hw_pagetable *hwpt =
>  			container_of(pt_obj, struct iommufd_hw_pagetable,
> obj);
> 
> -		rc = iommufd_device_do_attach(idev, hwpt, flags);
> +		rc = iommufd_device_do_attach(idev, hwpt);
>  		if (rc)
>  			goto out_put_pt_obj;
> 
> @@ -360,7 +361,7 @@ int iommufd_device_attach(struct iommufd_device
> *idev, u32 *pt_id,
>  		struct iommufd_ioas *ioas =
>  			container_of(pt_obj, struct iommufd_ioas, obj);
> 
> -		rc = iommufd_device_auto_get_domain(idev, ioas, flags);
> +		rc = iommufd_device_auto_get_domain(idev, ioas);
>  		if (rc)
>  			goto out_put_pt_obj;
>  		break;
> diff --git a/drivers/vfio/iommufd.c b/drivers/vfio/iommufd.c
> index 5a7ce4d9fbae0a..da50feb24b6e1d 100644
> --- a/drivers/vfio/iommufd.c
> +++ b/drivers/vfio/iommufd.c
> @@ -108,12 +108,9 @@
> EXPORT_SYMBOL_GPL(vfio_iommufd_physical_unbind);
> 
>  int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
>  {
> -	unsigned int flags = 0;
>  	int rc;
> 
> -	if (vfio_allow_unsafe_interrupts)
> -		flags |=
> IOMMUFD_ATTACH_FLAGS_ALLOW_UNSAFE_INTERRUPT;
> -	rc = iommufd_device_attach(vdev->iommufd_device, pt_id, flags);
> +	rc = iommufd_device_attach(vdev->iommufd_device, pt_id);
>  	if (rc)
>  		return rc;
>  	vdev->iommufd_attached = true;
> diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
> index 3378714a746274..ce5fe3fc493b4e 100644
> --- a/drivers/vfio/vfio.h
> +++ b/drivers/vfio/vfio.h
> @@ -216,6 +216,4 @@ extern bool vfio_noiommu __read_mostly;
>  enum { vfio_noiommu = false };
>  #endif
> 
> -extern bool vfio_allow_unsafe_interrupts;
> -
>  #endif
> diff --git a/drivers/vfio/vfio_iommu_type1.c
> b/drivers/vfio/vfio_iommu_type1.c
> index 186e33a006d314..23c24fe98c00d4 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -44,8 +44,9 @@
>  #define DRIVER_AUTHOR   "Alex Williamson
> <alex.williamson@xxxxxxxxxx>"
>  #define DRIVER_DESC     "Type1 IOMMU driver for VFIO"
> 
> +static bool allow_unsafe_interrupts;
>  module_param_named(allow_unsafe_interrupts,
> -		   vfio_allow_unsafe_interrupts, bool, S_IRUGO | S_IWUSR);
> +		   allow_unsafe_interrupts, bool, S_IRUGO | S_IWUSR);
>  MODULE_PARM_DESC(allow_unsafe_interrupts,
>  		 "Enable VFIO IOMMU support for on platforms without
> interrupt remapping support.");
> 
> @@ -2281,7 +2282,7 @@ static int vfio_iommu_type1_attach_group(void
> *iommu_data,
>  		    iommu_group_for_each_dev(iommu_group, (void
> *)IOMMU_CAP_INTR_REMAP,
>  					     vfio_iommu_device_capable);
> 
> -	if (!vfio_allow_unsafe_interrupts && !msi_remap) {
> +	if (!allow_unsafe_interrupts && !msi_remap) {
>  		pr_warn("%s: No interrupt remapping support.  Use the
> module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support
> on this platform\n",
>  		       __func__);
>  		ret = -EPERM;
> diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
> index 451a07eb702b34..593d45f43a16ba 100644
> --- a/drivers/vfio/vfio_main.c
> +++ b/drivers/vfio/vfio_main.c
> @@ -52,9 +52,6 @@ static struct vfio {
>  	struct ida			device_ida;
>  } vfio;
> 
> -bool vfio_allow_unsafe_interrupts;
> -EXPORT_SYMBOL_GPL(vfio_allow_unsafe_interrupts);
> -
>  static DEFINE_XARRAY(vfio_device_set_xa);
>  static const struct file_operations vfio_group_fops;
> 
> diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
> index bf2b3ea5f90fd2..9d1afd417215d0 100644
> --- a/include/linux/iommufd.h
> +++ b/include/linux/iommufd.h
> @@ -21,11 +21,7 @@ struct iommufd_device *iommufd_device_bind(struct
> iommufd_ctx *ictx,
>  					   struct device *dev, u32 *id);
>  void iommufd_device_unbind(struct iommufd_device *idev);
> 
> -enum {
> -	IOMMUFD_ATTACH_FLAGS_ALLOW_UNSAFE_INTERRUPT = 1 << 0,
> -};
> -int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id,
> -			  unsigned int flags);
> +int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id);
>  void iommufd_device_detach(struct iommufd_device *idev);
> 
>  struct iommufd_access_ops {

this looks good to me:

Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux