Re: [PATCH v9 07/11] arm/arm64: vgic: Implement KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO ioctl
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
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
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
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
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
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