Re: [RFC v3 1/2] vfio/platform: add support for msi

2021-01-15 Thread Auger Eric
Hi Vikas,

On 1/15/21 7:26 AM, Vikas Gupta wrote:
> Hi Eric,
> 
> On Tue, Jan 12, 2021 at 2:30 PM Auger Eric  wrote:
>>
>> Hi Vikas,
>>
>> On 1/5/21 6:53 AM, Vikas Gupta wrote:
>>> On Tue, Dec 22, 2020 at 10:57 PM Auger Eric  wrote:

 Hi Vikas,

 On 12/14/20 6:45 PM, Vikas Gupta wrote:
> MSI support for platform devices.The MSI block
> is added as an extended IRQ which exports caps
> VFIO_IRQ_INFO_CAP_TYPE and VFIO_IRQ_INFO_CAP_MSI_DESCS.
>
> Signed-off-by: Vikas Gupta 
> ---
>  drivers/vfio/platform/vfio_platform_common.c  | 179 +++-
>  drivers/vfio/platform/vfio_platform_irq.c | 260 +-
>  drivers/vfio/platform/vfio_platform_private.h |  32 +++
>  include/uapi/linux/vfio.h |  44 +++
>  4 files changed, 496 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/vfio/platform/vfio_platform_common.c 
> b/drivers/vfio/platform/vfio_platform_common.c
> index fb4b385191f2..c936852f35d7 100644
> --- a/drivers/vfio/platform/vfio_platform_common.c
> +++ b/drivers/vfio/platform/vfio_platform_common.c
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #include "vfio_platform_private.h"
>
> @@ -26,6 +27,8 @@
>  #define VFIO_PLATFORM_IS_ACPI(vdev) ((vdev)->acpihid != NULL)
>
>  static LIST_HEAD(reset_list);
> +/* devices having MSI support */
 nit: for devices using MSIs?
> +static LIST_HEAD(msi_list);
>  static DEFINE_MUTEX(driver_lock);
>
>  static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char 
> *compat,
> @@ -47,6 +50,25 @@ static vfio_platform_reset_fn_t 
> vfio_platform_lookup_reset(const char *compat,
>   return reset_fn;
>  }
>
> +static bool vfio_platform_lookup_msi(struct vfio_platform_device *vdev)
> +{
> + bool has_msi = false;
> + struct vfio_platform_msi_node *iter;
> +
> + mutex_lock(_lock);
> + list_for_each_entry(iter, _list, link) {
> + if (!strcmp(iter->compat, vdev->compat) &&
> + try_module_get(iter->owner)) {
> + vdev->msi_module = iter->owner;
> + vdev->of_get_msi = iter->of_get_msi;
> + has_msi = true;
> + break;
> + }
> + }
> + mutex_unlock(_lock);
> + return has_msi;
> +}
> +
>  static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev,
>   struct device *dev)
>  {
> @@ -126,6 +148,19 @@ static int vfio_platform_get_reset(struct 
> vfio_platform_device *vdev)
>   return vdev->of_reset ? 0 : -ENOENT;
>  }
>
> +static int vfio_platform_get_msi(struct vfio_platform_device *vdev)
> +{
> + bool has_msi;
> +
> + has_msi = vfio_platform_lookup_msi(vdev);
> + if (!has_msi) {
> + request_module("vfio-msi:%s", vdev->compat);
> + has_msi = vfio_platform_lookup_msi(vdev);
> + }
> +
> + return has_msi ? 0 : -ENOENT;
> +}
> +
>  static void vfio_platform_put_reset(struct vfio_platform_device *vdev)
>  {
>   if (VFIO_PLATFORM_IS_ACPI(vdev))
> @@ -135,6 +170,12 @@ static void vfio_platform_put_reset(struct 
> vfio_platform_device *vdev)
>   module_put(vdev->reset_module);
>  }
>
> +static void vfio_platform_put_msi(struct vfio_platform_device *vdev)
> +{
> + if (vdev->of_get_msi)
> + module_put(vdev->msi_module);
> +}
> +
>  static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
>  {
>   int cnt = 0, i;
> @@ -343,9 +384,17 @@ static long vfio_platform_ioctl(void *device_data,
>
>   } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
>   struct vfio_irq_info info;
> + struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
> + struct vfio_irq_info_cap_msi *msi_info = NULL;
> + int ext_irq_index = vdev->num_irqs - vdev->num_ext_irqs;
> + unsigned long capsz;
> + u32 index;
>
>   minsz = offsetofend(struct vfio_irq_info, count);
>
> + /* For backward compatibility, cannot require this */
> + capsz = offsetofend(struct vfio_irq_info, cap_offset);
> +
>   if (copy_from_user(, (void __user *)arg, minsz))
>   return -EFAULT;
>
> @@ -355,8 +404,94 @@ static long vfio_platform_ioctl(void *device_data,
>   if (info.index >= vdev->num_irqs)
>   return -EINVAL;
>
> - info.flags = vdev->irqs[info.index].flags;
> - info.count = 

Re: [RFC v3 1/2] vfio/platform: add support for msi

2021-01-14 Thread Vikas Gupta
Hi Eric,

On Tue, Jan 12, 2021 at 2:30 PM Auger Eric  wrote:
>
> Hi Vikas,
>
> On 1/5/21 6:53 AM, Vikas Gupta wrote:
> > On Tue, Dec 22, 2020 at 10:57 PM Auger Eric  wrote:
> >>
> >> Hi Vikas,
> >>
> >> On 12/14/20 6:45 PM, Vikas Gupta wrote:
> >>> MSI support for platform devices.The MSI block
> >>> is added as an extended IRQ which exports caps
> >>> VFIO_IRQ_INFO_CAP_TYPE and VFIO_IRQ_INFO_CAP_MSI_DESCS.
> >>>
> >>> Signed-off-by: Vikas Gupta 
> >>> ---
> >>>  drivers/vfio/platform/vfio_platform_common.c  | 179 +++-
> >>>  drivers/vfio/platform/vfio_platform_irq.c | 260 +-
> >>>  drivers/vfio/platform/vfio_platform_private.h |  32 +++
> >>>  include/uapi/linux/vfio.h |  44 +++
> >>>  4 files changed, 496 insertions(+), 19 deletions(-)
> >>>
> >>> diff --git a/drivers/vfio/platform/vfio_platform_common.c 
> >>> b/drivers/vfio/platform/vfio_platform_common.c
> >>> index fb4b385191f2..c936852f35d7 100644
> >>> --- a/drivers/vfio/platform/vfio_platform_common.c
> >>> +++ b/drivers/vfio/platform/vfio_platform_common.c
> >>> @@ -16,6 +16,7 @@
> >>>  #include 
> >>>  #include 
> >>>  #include 
> >>> +#include 
> >>>
> >>>  #include "vfio_platform_private.h"
> >>>
> >>> @@ -26,6 +27,8 @@
> >>>  #define VFIO_PLATFORM_IS_ACPI(vdev) ((vdev)->acpihid != NULL)
> >>>
> >>>  static LIST_HEAD(reset_list);
> >>> +/* devices having MSI support */
> >> nit: for devices using MSIs?
> >>> +static LIST_HEAD(msi_list);
> >>>  static DEFINE_MUTEX(driver_lock);
> >>>
> >>>  static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char 
> >>> *compat,
> >>> @@ -47,6 +50,25 @@ static vfio_platform_reset_fn_t 
> >>> vfio_platform_lookup_reset(const char *compat,
> >>>   return reset_fn;
> >>>  }
> >>>
> >>> +static bool vfio_platform_lookup_msi(struct vfio_platform_device *vdev)
> >>> +{
> >>> + bool has_msi = false;
> >>> + struct vfio_platform_msi_node *iter;
> >>> +
> >>> + mutex_lock(_lock);
> >>> + list_for_each_entry(iter, _list, link) {
> >>> + if (!strcmp(iter->compat, vdev->compat) &&
> >>> + try_module_get(iter->owner)) {
> >>> + vdev->msi_module = iter->owner;
> >>> + vdev->of_get_msi = iter->of_get_msi;
> >>> + has_msi = true;
> >>> + break;
> >>> + }
> >>> + }
> >>> + mutex_unlock(_lock);
> >>> + return has_msi;
> >>> +}
> >>> +
> >>>  static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev,
> >>>   struct device *dev)
> >>>  {
> >>> @@ -126,6 +148,19 @@ static int vfio_platform_get_reset(struct 
> >>> vfio_platform_device *vdev)
> >>>   return vdev->of_reset ? 0 : -ENOENT;
> >>>  }
> >>>
> >>> +static int vfio_platform_get_msi(struct vfio_platform_device *vdev)
> >>> +{
> >>> + bool has_msi;
> >>> +
> >>> + has_msi = vfio_platform_lookup_msi(vdev);
> >>> + if (!has_msi) {
> >>> + request_module("vfio-msi:%s", vdev->compat);
> >>> + has_msi = vfio_platform_lookup_msi(vdev);
> >>> + }
> >>> +
> >>> + return has_msi ? 0 : -ENOENT;
> >>> +}
> >>> +
> >>>  static void vfio_platform_put_reset(struct vfio_platform_device *vdev)
> >>>  {
> >>>   if (VFIO_PLATFORM_IS_ACPI(vdev))
> >>> @@ -135,6 +170,12 @@ static void vfio_platform_put_reset(struct 
> >>> vfio_platform_device *vdev)
> >>>   module_put(vdev->reset_module);
> >>>  }
> >>>
> >>> +static void vfio_platform_put_msi(struct vfio_platform_device *vdev)
> >>> +{
> >>> + if (vdev->of_get_msi)
> >>> + module_put(vdev->msi_module);
> >>> +}
> >>> +
> >>>  static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
> >>>  {
> >>>   int cnt = 0, i;
> >>> @@ -343,9 +384,17 @@ static long vfio_platform_ioctl(void *device_data,
> >>>
> >>>   } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
> >>>   struct vfio_irq_info info;
> >>> + struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
> >>> + struct vfio_irq_info_cap_msi *msi_info = NULL;
> >>> + int ext_irq_index = vdev->num_irqs - vdev->num_ext_irqs;
> >>> + unsigned long capsz;
> >>> + u32 index;
> >>>
> >>>   minsz = offsetofend(struct vfio_irq_info, count);
> >>>
> >>> + /* For backward compatibility, cannot require this */
> >>> + capsz = offsetofend(struct vfio_irq_info, cap_offset);
> >>> +
> >>>   if (copy_from_user(, (void __user *)arg, minsz))
> >>>   return -EFAULT;
> >>>
> >>> @@ -355,8 +404,94 @@ static long vfio_platform_ioctl(void *device_data,
> >>>   if (info.index >= vdev->num_irqs)
> >>>   return -EINVAL;
> >>>
> >>> - info.flags = vdev->irqs[info.index].flags;
> >>> - info.count = vdev->irqs[info.index].count;
> >>> + if (info.argsz >= capsz)
> >>> + 

Re: [RFC v3 1/2] vfio/platform: add support for msi

2021-01-12 Thread Auger Eric
Hi Vikas,

On 1/5/21 6:53 AM, Vikas Gupta wrote:
> On Tue, Dec 22, 2020 at 10:57 PM Auger Eric  wrote:
>>
>> Hi Vikas,
>>
>> On 12/14/20 6:45 PM, Vikas Gupta wrote:
>>> MSI support for platform devices.The MSI block
>>> is added as an extended IRQ which exports caps
>>> VFIO_IRQ_INFO_CAP_TYPE and VFIO_IRQ_INFO_CAP_MSI_DESCS.
>>>
>>> Signed-off-by: Vikas Gupta 
>>> ---
>>>  drivers/vfio/platform/vfio_platform_common.c  | 179 +++-
>>>  drivers/vfio/platform/vfio_platform_irq.c | 260 +-
>>>  drivers/vfio/platform/vfio_platform_private.h |  32 +++
>>>  include/uapi/linux/vfio.h |  44 +++
>>>  4 files changed, 496 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/drivers/vfio/platform/vfio_platform_common.c 
>>> b/drivers/vfio/platform/vfio_platform_common.c
>>> index fb4b385191f2..c936852f35d7 100644
>>> --- a/drivers/vfio/platform/vfio_platform_common.c
>>> +++ b/drivers/vfio/platform/vfio_platform_common.c
>>> @@ -16,6 +16,7 @@
>>>  #include 
>>>  #include 
>>>  #include 
>>> +#include 
>>>
>>>  #include "vfio_platform_private.h"
>>>
>>> @@ -26,6 +27,8 @@
>>>  #define VFIO_PLATFORM_IS_ACPI(vdev) ((vdev)->acpihid != NULL)
>>>
>>>  static LIST_HEAD(reset_list);
>>> +/* devices having MSI support */
>> nit: for devices using MSIs?
>>> +static LIST_HEAD(msi_list);
>>>  static DEFINE_MUTEX(driver_lock);
>>>
>>>  static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char 
>>> *compat,
>>> @@ -47,6 +50,25 @@ static vfio_platform_reset_fn_t 
>>> vfio_platform_lookup_reset(const char *compat,
>>>   return reset_fn;
>>>  }
>>>
>>> +static bool vfio_platform_lookup_msi(struct vfio_platform_device *vdev)
>>> +{
>>> + bool has_msi = false;
>>> + struct vfio_platform_msi_node *iter;
>>> +
>>> + mutex_lock(_lock);
>>> + list_for_each_entry(iter, _list, link) {
>>> + if (!strcmp(iter->compat, vdev->compat) &&
>>> + try_module_get(iter->owner)) {
>>> + vdev->msi_module = iter->owner;
>>> + vdev->of_get_msi = iter->of_get_msi;
>>> + has_msi = true;
>>> + break;
>>> + }
>>> + }
>>> + mutex_unlock(_lock);
>>> + return has_msi;
>>> +}
>>> +
>>>  static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev,
>>>   struct device *dev)
>>>  {
>>> @@ -126,6 +148,19 @@ static int vfio_platform_get_reset(struct 
>>> vfio_platform_device *vdev)
>>>   return vdev->of_reset ? 0 : -ENOENT;
>>>  }
>>>
>>> +static int vfio_platform_get_msi(struct vfio_platform_device *vdev)
>>> +{
>>> + bool has_msi;
>>> +
>>> + has_msi = vfio_platform_lookup_msi(vdev);
>>> + if (!has_msi) {
>>> + request_module("vfio-msi:%s", vdev->compat);
>>> + has_msi = vfio_platform_lookup_msi(vdev);
>>> + }
>>> +
>>> + return has_msi ? 0 : -ENOENT;
>>> +}
>>> +
>>>  static void vfio_platform_put_reset(struct vfio_platform_device *vdev)
>>>  {
>>>   if (VFIO_PLATFORM_IS_ACPI(vdev))
>>> @@ -135,6 +170,12 @@ static void vfio_platform_put_reset(struct 
>>> vfio_platform_device *vdev)
>>>   module_put(vdev->reset_module);
>>>  }
>>>
>>> +static void vfio_platform_put_msi(struct vfio_platform_device *vdev)
>>> +{
>>> + if (vdev->of_get_msi)
>>> + module_put(vdev->msi_module);
>>> +}
>>> +
>>>  static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
>>>  {
>>>   int cnt = 0, i;
>>> @@ -343,9 +384,17 @@ static long vfio_platform_ioctl(void *device_data,
>>>
>>>   } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
>>>   struct vfio_irq_info info;
>>> + struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
>>> + struct vfio_irq_info_cap_msi *msi_info = NULL;
>>> + int ext_irq_index = vdev->num_irqs - vdev->num_ext_irqs;
>>> + unsigned long capsz;
>>> + u32 index;
>>>
>>>   minsz = offsetofend(struct vfio_irq_info, count);
>>>
>>> + /* For backward compatibility, cannot require this */
>>> + capsz = offsetofend(struct vfio_irq_info, cap_offset);
>>> +
>>>   if (copy_from_user(, (void __user *)arg, minsz))
>>>   return -EFAULT;
>>>
>>> @@ -355,8 +404,94 @@ static long vfio_platform_ioctl(void *device_data,
>>>   if (info.index >= vdev->num_irqs)
>>>   return -EINVAL;
>>>
>>> - info.flags = vdev->irqs[info.index].flags;
>>> - info.count = vdev->irqs[info.index].count;
>>> + if (info.argsz >= capsz)
>>> + minsz = capsz;
>>> +
>>> + index = info.index;
>>> +
>>> + info.flags = vdev->irqs[index].flags;
>>> + info.count = vdev->irqs[index].count;
>>> +
>>> + if (ext_irq_index - index == VFIO_EXT_IRQ_MSI) {
>>> + struct vfio_irq_info_cap_type 

Re: [RFC v3 1/2] vfio/platform: add support for msi

2021-01-04 Thread Vikas Gupta
On Tue, Dec 22, 2020 at 10:57 PM Auger Eric  wrote:
>
> Hi Vikas,
>
> On 12/14/20 6:45 PM, Vikas Gupta wrote:
> > MSI support for platform devices.The MSI block
> > is added as an extended IRQ which exports caps
> > VFIO_IRQ_INFO_CAP_TYPE and VFIO_IRQ_INFO_CAP_MSI_DESCS.
> >
> > Signed-off-by: Vikas Gupta 
> > ---
> >  drivers/vfio/platform/vfio_platform_common.c  | 179 +++-
> >  drivers/vfio/platform/vfio_platform_irq.c | 260 +-
> >  drivers/vfio/platform/vfio_platform_private.h |  32 +++
> >  include/uapi/linux/vfio.h |  44 +++
> >  4 files changed, 496 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/vfio/platform/vfio_platform_common.c 
> > b/drivers/vfio/platform/vfio_platform_common.c
> > index fb4b385191f2..c936852f35d7 100644
> > --- a/drivers/vfio/platform/vfio_platform_common.c
> > +++ b/drivers/vfio/platform/vfio_platform_common.c
> > @@ -16,6 +16,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  #include "vfio_platform_private.h"
> >
> > @@ -26,6 +27,8 @@
> >  #define VFIO_PLATFORM_IS_ACPI(vdev) ((vdev)->acpihid != NULL)
> >
> >  static LIST_HEAD(reset_list);
> > +/* devices having MSI support */
> nit: for devices using MSIs?
> > +static LIST_HEAD(msi_list);
> >  static DEFINE_MUTEX(driver_lock);
> >
> >  static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char 
> > *compat,
> > @@ -47,6 +50,25 @@ static vfio_platform_reset_fn_t 
> > vfio_platform_lookup_reset(const char *compat,
> >   return reset_fn;
> >  }
> >
> > +static bool vfio_platform_lookup_msi(struct vfio_platform_device *vdev)
> > +{
> > + bool has_msi = false;
> > + struct vfio_platform_msi_node *iter;
> > +
> > + mutex_lock(_lock);
> > + list_for_each_entry(iter, _list, link) {
> > + if (!strcmp(iter->compat, vdev->compat) &&
> > + try_module_get(iter->owner)) {
> > + vdev->msi_module = iter->owner;
> > + vdev->of_get_msi = iter->of_get_msi;
> > + has_msi = true;
> > + break;
> > + }
> > + }
> > + mutex_unlock(_lock);
> > + return has_msi;
> > +}
> > +
> >  static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev,
> >   struct device *dev)
> >  {
> > @@ -126,6 +148,19 @@ static int vfio_platform_get_reset(struct 
> > vfio_platform_device *vdev)
> >   return vdev->of_reset ? 0 : -ENOENT;
> >  }
> >
> > +static int vfio_platform_get_msi(struct vfio_platform_device *vdev)
> > +{
> > + bool has_msi;
> > +
> > + has_msi = vfio_platform_lookup_msi(vdev);
> > + if (!has_msi) {
> > + request_module("vfio-msi:%s", vdev->compat);
> > + has_msi = vfio_platform_lookup_msi(vdev);
> > + }
> > +
> > + return has_msi ? 0 : -ENOENT;
> > +}
> > +
> >  static void vfio_platform_put_reset(struct vfio_platform_device *vdev)
> >  {
> >   if (VFIO_PLATFORM_IS_ACPI(vdev))
> > @@ -135,6 +170,12 @@ static void vfio_platform_put_reset(struct 
> > vfio_platform_device *vdev)
> >   module_put(vdev->reset_module);
> >  }
> >
> > +static void vfio_platform_put_msi(struct vfio_platform_device *vdev)
> > +{
> > + if (vdev->of_get_msi)
> > + module_put(vdev->msi_module);
> > +}
> > +
> >  static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
> >  {
> >   int cnt = 0, i;
> > @@ -343,9 +384,17 @@ static long vfio_platform_ioctl(void *device_data,
> >
> >   } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
> >   struct vfio_irq_info info;
> > + struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
> > + struct vfio_irq_info_cap_msi *msi_info = NULL;
> > + int ext_irq_index = vdev->num_irqs - vdev->num_ext_irqs;
> > + unsigned long capsz;
> > + u32 index;
> >
> >   minsz = offsetofend(struct vfio_irq_info, count);
> >
> > + /* For backward compatibility, cannot require this */
> > + capsz = offsetofend(struct vfio_irq_info, cap_offset);
> > +
> >   if (copy_from_user(, (void __user *)arg, minsz))
> >   return -EFAULT;
> >
> > @@ -355,8 +404,94 @@ static long vfio_platform_ioctl(void *device_data,
> >   if (info.index >= vdev->num_irqs)
> >   return -EINVAL;
> >
> > - info.flags = vdev->irqs[info.index].flags;
> > - info.count = vdev->irqs[info.index].count;
> > + if (info.argsz >= capsz)
> > + minsz = capsz;
> > +
> > + index = info.index;
> > +
> > + info.flags = vdev->irqs[index].flags;
> > + info.count = vdev->irqs[index].count;
> > +
> > + if (ext_irq_index - index == VFIO_EXT_IRQ_MSI) {
> > + struct vfio_irq_info_cap_type cap_type = {
> > + .header.id = 

Re: [RFC v3 1/2] vfio/platform: add support for msi

2020-12-22 Thread Auger Eric
Hi Vikas,

On 12/14/20 6:45 PM, Vikas Gupta wrote:
> MSI support for platform devices.The MSI block
> is added as an extended IRQ which exports caps
> VFIO_IRQ_INFO_CAP_TYPE and VFIO_IRQ_INFO_CAP_MSI_DESCS.
> 
> Signed-off-by: Vikas Gupta 
> ---
>  drivers/vfio/platform/vfio_platform_common.c  | 179 +++-
>  drivers/vfio/platform/vfio_platform_irq.c | 260 +-
>  drivers/vfio/platform/vfio_platform_private.h |  32 +++
>  include/uapi/linux/vfio.h |  44 +++
>  4 files changed, 496 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/vfio/platform/vfio_platform_common.c 
> b/drivers/vfio/platform/vfio_platform_common.c
> index fb4b385191f2..c936852f35d7 100644
> --- a/drivers/vfio/platform/vfio_platform_common.c
> +++ b/drivers/vfio/platform/vfio_platform_common.c
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "vfio_platform_private.h"
>  
> @@ -26,6 +27,8 @@
>  #define VFIO_PLATFORM_IS_ACPI(vdev) ((vdev)->acpihid != NULL)
>  
>  static LIST_HEAD(reset_list);
> +/* devices having MSI support */
nit: for devices using MSIs?
> +static LIST_HEAD(msi_list);
>  static DEFINE_MUTEX(driver_lock);
>  
>  static vfio_platform_reset_fn_t vfio_platform_lookup_reset(const char 
> *compat,
> @@ -47,6 +50,25 @@ static vfio_platform_reset_fn_t 
> vfio_platform_lookup_reset(const char *compat,
>   return reset_fn;
>  }
>  
> +static bool vfio_platform_lookup_msi(struct vfio_platform_device *vdev)
> +{
> + bool has_msi = false;
> + struct vfio_platform_msi_node *iter;
> +
> + mutex_lock(_lock);
> + list_for_each_entry(iter, _list, link) {
> + if (!strcmp(iter->compat, vdev->compat) &&
> + try_module_get(iter->owner)) {
> + vdev->msi_module = iter->owner;
> + vdev->of_get_msi = iter->of_get_msi;
> + has_msi = true;
> + break;
> + }
> + }
> + mutex_unlock(_lock);
> + return has_msi;
> +}
> +
>  static int vfio_platform_acpi_probe(struct vfio_platform_device *vdev,
>   struct device *dev)
>  {
> @@ -126,6 +148,19 @@ static int vfio_platform_get_reset(struct 
> vfio_platform_device *vdev)
>   return vdev->of_reset ? 0 : -ENOENT;
>  }
>  
> +static int vfio_platform_get_msi(struct vfio_platform_device *vdev)
> +{
> + bool has_msi;
> +
> + has_msi = vfio_platform_lookup_msi(vdev);
> + if (!has_msi) {
> + request_module("vfio-msi:%s", vdev->compat);
> + has_msi = vfio_platform_lookup_msi(vdev);
> + }
> +
> + return has_msi ? 0 : -ENOENT;
> +}
> +
>  static void vfio_platform_put_reset(struct vfio_platform_device *vdev)
>  {
>   if (VFIO_PLATFORM_IS_ACPI(vdev))
> @@ -135,6 +170,12 @@ static void vfio_platform_put_reset(struct 
> vfio_platform_device *vdev)
>   module_put(vdev->reset_module);
>  }
>  
> +static void vfio_platform_put_msi(struct vfio_platform_device *vdev)
> +{
> + if (vdev->of_get_msi)
> + module_put(vdev->msi_module);
> +}
> +
>  static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
>  {
>   int cnt = 0, i;
> @@ -343,9 +384,17 @@ static long vfio_platform_ioctl(void *device_data,
>  
>   } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
>   struct vfio_irq_info info;
> + struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
> + struct vfio_irq_info_cap_msi *msi_info = NULL;
> + int ext_irq_index = vdev->num_irqs - vdev->num_ext_irqs;
> + unsigned long capsz;
> + u32 index;
>  
>   minsz = offsetofend(struct vfio_irq_info, count);
>  
> + /* For backward compatibility, cannot require this */
> + capsz = offsetofend(struct vfio_irq_info, cap_offset);
> +
>   if (copy_from_user(, (void __user *)arg, minsz))
>   return -EFAULT;
>  
> @@ -355,8 +404,94 @@ static long vfio_platform_ioctl(void *device_data,
>   if (info.index >= vdev->num_irqs)
>   return -EINVAL;
>  
> - info.flags = vdev->irqs[info.index].flags;
> - info.count = vdev->irqs[info.index].count;
> + if (info.argsz >= capsz)
> + minsz = capsz;
> +
> + index = info.index;
> +
> + info.flags = vdev->irqs[index].flags;
> + info.count = vdev->irqs[index].count;
> +
> + if (ext_irq_index - index == VFIO_EXT_IRQ_MSI) {
> + struct vfio_irq_info_cap_type cap_type = {
> + .header.id = VFIO_IRQ_INFO_CAP_TYPE,
> + .header.version = 1 };
> + struct vfio_platform_irq *irq;
> + size_t msi_info_size;
> + int num_msgs;
> + int ret;
> + int i;
> +
> +