Re: [PATCH v9 07/11] arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl

2016-11-30 Thread Peter Maydell
On 30 November 2016 at 08:24, Christoffer Dall
 wrote:
> (Peter, I thought you once argued that it was important for user space
> to be able to save/restore the state without any ordering requirements,
> but I may have misunderstood.  It is still the option to add something
> like the above to the docs but also do our best to allow any ordering of
> level/config, but it becomes slightly more invasive.)

Hmm; perhaps I should think about this a bit more.

-- PMM
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v9 07/11] arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl

2016-11-30 Thread Christoffer Dall
On Wed, Nov 30, 2016 at 07:10:51AM +, Peter Maydell wrote:
> On 29 November 2016 at 21:09, Christoffer Dall
>  wrote:
> > Actually, I'm not sure what the semantics of the line level ioctl should
> > be for edge-triggered interrupts?  My inclination is that it shouldn't
> > have any effect at this point, but that would mean that at this point we
> > should only set the pending variable and try to queue the interrupt if
> > the config is level.  But that also means that when we set the config
> > later, we need to try to queue the interrupt, which we don't do
> > currently, because we rely on the guest not fiddling with the config of
> > an enabled interrupt.
> >
> > Could it be considered an error if user space tries to set the level for
> > an edge-triggered interrupt and therefore something we can just ignore
> > and assume that the corresponing interrupt will be configured as a
> > level-triggered one later?
> 
> Userspace will always read the line-level values out and write
> them back for migration, and I'd rather not make it have to
> do cross-checks against whether the interrupt is edge or level
> triggered to see whether it should write the level values into
> the kernel. Telling the kernel the level for an edge-triggered
> interrupt should be a no-op because it doesn't have any effect
> on pending status.
> 
> > In any case we probably need to clarify the ABI in terms of this
> > particular KVM_DEV_AR_VGIC_GRP_LEVEL_INFO group and how it relates to
> > the config of edge vs. level of interrupts and ordering on restore...
> 
> IIRC the QEMU code restores the config first. (There's a similar
> ordering thing for GICv2 where we have to restore GICD_ICFGRn before
> GICD_ISPENDRn.)
> 

So it sounds to me that we should add a note in the Documentation like
this:

diff --git a/Documentation/virtual/kvm/devices/arm-vgic-v3.txt 
b/Documentation/virtual/kvm/devices/arm-vgic-v3.txt
index 9348b3c..7bac20a 100644
--- a/Documentation/virtual/kvm/devices/arm-vgic-v3.txt
+++ b/Documentation/virtual/kvm/devices/arm-vgic-v3.txt
@@ -193,6 +193,11 @@ Groups:
 
Bit[n] indicates the status for interrupt vINTID + n.
 
+   Getting or setting the level info for an edge-triggered interrupt is
+   not guaranteed to work.  To restore the complete state of the VGIC, the
+   configuration (edge/level) of interrupts must be restored before
+   restoring the level.
+
 SGIs and any interrupt with a higher ID than the number of interrupts
 supported, will be RAZ/WI.  LPIs are always edge-triggered and are
 therefore not supported by this interface.

Vijay, this means that the first block in your if-statement should only
set pending and queue the interrupt if the interrupt is a level
triggered one.

(Peter, I thought you once argued that it was important for user space
to be able to save/restore the state without any ordering requirements,
but I may have misunderstood.  It is still the option to add something
like the above to the docs but also do our best to allow any ordering of
level/config, but it becomes slightly more invasive.)

Thanks,
-Christoffer
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v9 07/11] arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl

2016-11-29 Thread Peter Maydell
On 29 November 2016 at 21:09, Christoffer Dall
 wrote:
> Actually, I'm not sure what the semantics of the line level ioctl should
> be for edge-triggered interrupts?  My inclination is that it shouldn't
> have any effect at this point, but that would mean that at this point we
> should only set the pending variable and try to queue the interrupt if
> the config is level.  But that also means that when we set the config
> later, we need to try to queue the interrupt, which we don't do
> currently, because we rely on the guest not fiddling with the config of
> an enabled interrupt.
>
> Could it be considered an error if user space tries to set the level for
> an edge-triggered interrupt and therefore something we can just ignore
> and assume that the corresponing interrupt will be configured as a
> level-triggered one later?

Userspace will always read the line-level values out and write
them back for migration, and I'd rather not make it have to
do cross-checks against whether the interrupt is edge or level
triggered to see whether it should write the level values into
the kernel. Telling the kernel the level for an edge-triggered
interrupt should be a no-op because it doesn't have any effect
on pending status.

> In any case we probably need to clarify the ABI in terms of this
> particular KVM_DEV_AR_VGIC_GRP_LEVEL_INFO group and how it relates to
> the config of edge vs. level of interrupts and ordering on restore...

IIRC the QEMU code restores the config first. (There's a similar
ordering thing for GICv2 where we have to restore GICD_ICFGRn before
GICD_ISPENDRn.)

thanks
-- PMM
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v9 07/11] arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl

2016-11-29 Thread Christoffer Dall
On Tue, Nov 29, 2016 at 10:06:27PM +0530, Vijay Kilari wrote:
> On Tue, Nov 29, 2016 at 1:20 AM, Christoffer Dall
>  wrote:
> > On Wed, Nov 23, 2016 at 06:31:54PM +0530, vijay.kil...@gmail.com wrote:
> >> From: Vijaya Kumar K 
> >>
> >> Userspace requires to store and restore of line_level for
> >> level triggered interrupts using ioctl KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO.
> >>
> >> Signed-off-by: Vijaya Kumar K 
> >> ---
> >>  arch/arm/include/uapi/asm/kvm.h |  7 ++
> >>  arch/arm64/include/uapi/asm/kvm.h   |  6 +
> >>  virt/kvm/arm/vgic/vgic-kvm-device.c | 49 
> >> -
> >>  virt/kvm/arm/vgic/vgic-mmio-v3.c| 11 +
> >>  virt/kvm/arm/vgic/vgic-mmio.c   | 38 
> >>  virt/kvm/arm/vgic/vgic-mmio.h   |  5 
> >>  virt/kvm/arm/vgic/vgic.h|  2 ++
> >>  7 files changed, 117 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/arm/include/uapi/asm/kvm.h 
> >> b/arch/arm/include/uapi/asm/kvm.h
> >> index 98658d9d..f347779 100644
> >> --- a/arch/arm/include/uapi/asm/kvm.h
> >> +++ b/arch/arm/include/uapi/asm/kvm.h
> >> @@ -191,6 +191,13 @@ struct kvm_arch_memory_slot {
> >>  #define KVM_DEV_ARM_VGIC_GRP_CTRL   4
> >>  #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
> >>  #define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
> >> +#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
> >> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT   10
> >> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
> >> + (0x3fULL << 
> >> KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
> >> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK   0x3ff
> >> +#define VGIC_LEVEL_INFO_LINE_LEVEL   0
> >> +
> >>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT0
> >>
> >>  /* KVM_IRQ_LINE irq field index values */
> >> diff --git a/arch/arm64/include/uapi/asm/kvm.h 
> >> b/arch/arm64/include/uapi/asm/kvm.h
> >> index 91c7137..4100f8c 100644
> >> --- a/arch/arm64/include/uapi/asm/kvm.h
> >> +++ b/arch/arm64/include/uapi/asm/kvm.h
> >> @@ -211,6 +211,12 @@ struct kvm_arch_memory_slot {
> >>  #define KVM_DEV_ARM_VGIC_GRP_CTRL4
> >>  #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
> >>  #define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
> >> +#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
> >> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT   10
> >> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
> >> + (0x3fULL << 
> >> KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
> >> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK   0x3ff
> >> +#define VGIC_LEVEL_INFO_LINE_LEVEL   0
> >>
> >>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT 0
> >>
> >> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c 
> >> b/virt/kvm/arm/vgic/vgic-kvm-device.c
> >> index b6266fe..52ed00b 100644
> >> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
> >> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
> >> @@ -510,6 +510,25 @@ static int vgic_v3_attr_regs_access(struct kvm_device 
> >> *dev,
> >> regid, reg);
> >>   break;
> >>   }
> >> + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
> >> + unsigned int info, intid;
> >> +
> >> + info = (attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) 
> >> >>
> >> + KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT;
> >> + if (info == VGIC_LEVEL_INFO_LINE_LEVEL) {
> >> + if (is_write)
> >> + tmp32 = *reg;
> >> + intid = attr->attr &
> >> + KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK;
> >> + ret = vgic_v3_line_level_info_uaccess(vcpu, is_write,
> >> +   intid, &tmp32);
> >> + if (!is_write)
> >> + *reg = tmp32;
> >
> > I had a comment here about not having to use the tmp32 by modifying the
> > line_level_info function, that you seem to have missed.
> >
> > Hint: The level info is not called from an MMIO path so you should be
> > able to just write it in a natural way.
> 
> Ok. Changed the prototype of vgic_v3_line_level_info_uaccess() to take
> u64 reg instead of tmp32
> 
> >
> >> + } else {
> >> + ret = -EINVAL;
> >> + }
> >> + break;
> >> + }
> >>   default:
> >>   ret = -EINVAL;
> >>   break;
> >> @@ -552,6 +571,17 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
> >>
> >>   return vgic_v3_attr_regs_access(dev, attr, ®, true);
> >>   }
> >> + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
> >> + u32 __user *uaddr = (u32 __user *)(long)attr->addr;
> >> + u64 reg;
> >> + u32 tmp32;
> >> +
> >> + if (get_user(tmp32, uaddr))
> >> + return -EFAULT;
> >> +
> >> + reg = tmp32;
> >> + return vgic_v3_attr_regs_access(dev, attr, ®, true);
> >> + }
> >>

Re: [PATCH v9 07/11] arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl

2016-11-29 Thread Vijay Kilari
On Tue, Nov 29, 2016 at 1:20 AM, Christoffer Dall
 wrote:
> On Wed, Nov 23, 2016 at 06:31:54PM +0530, vijay.kil...@gmail.com wrote:
>> From: Vijaya Kumar K 
>>
>> Userspace requires to store and restore of line_level for
>> level triggered interrupts using ioctl KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO.
>>
>> Signed-off-by: Vijaya Kumar K 
>> ---
>>  arch/arm/include/uapi/asm/kvm.h |  7 ++
>>  arch/arm64/include/uapi/asm/kvm.h   |  6 +
>>  virt/kvm/arm/vgic/vgic-kvm-device.c | 49 
>> -
>>  virt/kvm/arm/vgic/vgic-mmio-v3.c| 11 +
>>  virt/kvm/arm/vgic/vgic-mmio.c   | 38 
>>  virt/kvm/arm/vgic/vgic-mmio.h   |  5 
>>  virt/kvm/arm/vgic/vgic.h|  2 ++
>>  7 files changed, 117 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/include/uapi/asm/kvm.h 
>> b/arch/arm/include/uapi/asm/kvm.h
>> index 98658d9d..f347779 100644
>> --- a/arch/arm/include/uapi/asm/kvm.h
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -191,6 +191,13 @@ struct kvm_arch_memory_slot {
>>  #define KVM_DEV_ARM_VGIC_GRP_CTRL   4
>>  #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
>>  #define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
>> +#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
>> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT   10
>> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
>> + (0x3fULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
>> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK   0x3ff
>> +#define VGIC_LEVEL_INFO_LINE_LEVEL   0
>> +
>>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT0
>>
>>  /* KVM_IRQ_LINE irq field index values */
>> diff --git a/arch/arm64/include/uapi/asm/kvm.h 
>> b/arch/arm64/include/uapi/asm/kvm.h
>> index 91c7137..4100f8c 100644
>> --- a/arch/arm64/include/uapi/asm/kvm.h
>> +++ b/arch/arm64/include/uapi/asm/kvm.h
>> @@ -211,6 +211,12 @@ struct kvm_arch_memory_slot {
>>  #define KVM_DEV_ARM_VGIC_GRP_CTRL4
>>  #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
>>  #define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
>> +#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
>> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT   10
>> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
>> + (0x3fULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
>> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK   0x3ff
>> +#define VGIC_LEVEL_INFO_LINE_LEVEL   0
>>
>>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT 0
>>
>> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c 
>> b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> index b6266fe..52ed00b 100644
>> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
>> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> @@ -510,6 +510,25 @@ static int vgic_v3_attr_regs_access(struct kvm_device 
>> *dev,
>> regid, reg);
>>   break;
>>   }
>> + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
>> + unsigned int info, intid;
>> +
>> + info = (attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) >>
>> + KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT;
>> + if (info == VGIC_LEVEL_INFO_LINE_LEVEL) {
>> + if (is_write)
>> + tmp32 = *reg;
>> + intid = attr->attr &
>> + KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK;
>> + ret = vgic_v3_line_level_info_uaccess(vcpu, is_write,
>> +   intid, &tmp32);
>> + if (!is_write)
>> + *reg = tmp32;
>
> I had a comment here about not having to use the tmp32 by modifying the
> line_level_info function, that you seem to have missed.
>
> Hint: The level info is not called from an MMIO path so you should be
> able to just write it in a natural way.

Ok. Changed the prototype of vgic_v3_line_level_info_uaccess() to take
u64 reg instead of tmp32

>
>> + } else {
>> + ret = -EINVAL;
>> + }
>> + break;
>> + }
>>   default:
>>   ret = -EINVAL;
>>   break;
>> @@ -552,6 +571,17 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
>>
>>   return vgic_v3_attr_regs_access(dev, attr, ®, true);
>>   }
>> + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
>> + u32 __user *uaddr = (u32 __user *)(long)attr->addr;
>> + u64 reg;
>> + u32 tmp32;
>> +
>> + if (get_user(tmp32, uaddr))
>> + return -EFAULT;
>> +
>> + reg = tmp32;
>> + return vgic_v3_attr_regs_access(dev, attr, ®, true);
>> + }
>>   }
>>   return -ENXIO;
>>  }
>> @@ -587,8 +617,18 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
>>   return ret;
>>   return put_user(reg, uaddr);
>>   }
>> - }
>> + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
>> + u32 __user *uaddr = (u32 _

Re: [PATCH v9 07/11] arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl

2016-11-28 Thread Christoffer Dall
On Wed, Nov 23, 2016 at 06:31:54PM +0530, vijay.kil...@gmail.com wrote:
> From: Vijaya Kumar K 
> 
> Userspace requires to store and restore of line_level for
> level triggered interrupts using ioctl KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO.
> 
> Signed-off-by: Vijaya Kumar K 
> ---
>  arch/arm/include/uapi/asm/kvm.h |  7 ++
>  arch/arm64/include/uapi/asm/kvm.h   |  6 +
>  virt/kvm/arm/vgic/vgic-kvm-device.c | 49 
> -
>  virt/kvm/arm/vgic/vgic-mmio-v3.c| 11 +
>  virt/kvm/arm/vgic/vgic-mmio.c   | 38 
>  virt/kvm/arm/vgic/vgic-mmio.h   |  5 
>  virt/kvm/arm/vgic/vgic.h|  2 ++
>  7 files changed, 117 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> index 98658d9d..f347779 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -191,6 +191,13 @@ struct kvm_arch_memory_slot {
>  #define KVM_DEV_ARM_VGIC_GRP_CTRL   4
>  #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
>  #define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
> +#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT   10
> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
> + (0x3fULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK   0x3ff
> +#define VGIC_LEVEL_INFO_LINE_LEVEL   0
> +
>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT0
>  
>  /* KVM_IRQ_LINE irq field index values */
> diff --git a/arch/arm64/include/uapi/asm/kvm.h 
> b/arch/arm64/include/uapi/asm/kvm.h
> index 91c7137..4100f8c 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -211,6 +211,12 @@ struct kvm_arch_memory_slot {
>  #define KVM_DEV_ARM_VGIC_GRP_CTRL4
>  #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
>  #define KVM_DEV_ARM_VGIC_CPU_SYSREGS6
> +#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT   10
> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
> + (0x3fULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
> +#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK   0x3ff
> +#define VGIC_LEVEL_INFO_LINE_LEVEL   0
>  
>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT 0
>  
> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c 
> b/virt/kvm/arm/vgic/vgic-kvm-device.c
> index b6266fe..52ed00b 100644
> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
> @@ -510,6 +510,25 @@ static int vgic_v3_attr_regs_access(struct kvm_device 
> *dev,
> regid, reg);
>   break;
>   }
> + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
> + unsigned int info, intid;
> +
> + info = (attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) >>
> + KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT;
> + if (info == VGIC_LEVEL_INFO_LINE_LEVEL) {
> + if (is_write)
> + tmp32 = *reg;
> + intid = attr->attr &
> + KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK;
> + ret = vgic_v3_line_level_info_uaccess(vcpu, is_write,
> +   intid, &tmp32);
> + if (!is_write)
> + *reg = tmp32;

I had a comment here about not having to use the tmp32 by modifying the
line_level_info function, that you seem to have missed.

Hint: The level info is not called from an MMIO path so you should be
able to just write it in a natural way.

> + } else {
> + ret = -EINVAL;
> + }
> + break;
> + }
>   default:
>   ret = -EINVAL;
>   break;
> @@ -552,6 +571,17 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
>  
>   return vgic_v3_attr_regs_access(dev, attr, ®, true);
>   }
> + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
> + u32 __user *uaddr = (u32 __user *)(long)attr->addr;
> + u64 reg;
> + u32 tmp32;
> +
> + if (get_user(tmp32, uaddr))
> + return -EFAULT;
> +
> + reg = tmp32;
> + return vgic_v3_attr_regs_access(dev, attr, ®, true);
> + }
>   }
>   return -ENXIO;
>  }
> @@ -587,8 +617,18 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
>   return ret;
>   return put_user(reg, uaddr);
>   }
> - }
> + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
> + u32 __user *uaddr = (u32 __user *)(long)attr->addr;
> + u64 reg;
> + u32 tmp32;
>  
> + ret = vgic_v3_attr_regs_access(dev, attr, ®, false);
> + if (ret)
> + return ret;
> + tmp32 = reg;
> + return put_user