Message ID | 20230807162210.2528230-3-jingzhangos@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Enable writable for idregs DFR0,PFR0, MMFR{0,1,2,3} | expand |
On Mon, Aug 07 2023, Jing Zhang <jingzhangos@google.com> wrote: > Add some basic documentation on how to get feature ID register writable > masks from userspace. > > Signed-off-by: Jing Zhang <jingzhangos@google.com> > --- > Documentation/virt/kvm/api.rst | 29 +++++++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > index c0ddd3035462..92a9b20f970e 100644 > --- a/Documentation/virt/kvm/api.rst > +++ b/Documentation/virt/kvm/api.rst > @@ -6068,6 +6068,35 @@ writes to the CNTVCT_EL0 and CNTPCT_EL0 registers using the SET_ONE_REG > interface. No error will be returned, but the resulting offset will not be > applied. > > +4.139 KVM_ARM_GET_REG_WRITABLE_MASKS > +------------------------------------------- > + > +:Capability: none > +:Architectures: arm64 > +:Type: vm ioctl > +:Parameters: struct reg_mask_range (in/out) > +:Returns: 0 on success, < 0 on error > + > + > +:: > + > + #define ARM64_FEATURE_ID_SPACE_SIZE (3 * 8 * 8) > + > + struct reg_mask_range { > + __u64 addr; /* Pointer to mask array */ > + __u64 reserved[7]; > + }; > + > +This ioctl would copy the writable masks for feature ID registers to userspace. > +The Feature ID space is defined as the System register space in AArch64 with > +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}. > +To get the index in the mask array pointed by ``addr`` for a specified feature > +ID register, use the macro ``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``. > +This allows the userspace to know upfront whether it can actually tweak the > +contents of a feature ID register or not. > +The ``reserved[7]`` is reserved for future use to add other register space. For > +feature ID registers, it should be 0, otherwise, KVM may return error. In case of future extensions, this means that userspace needs to figure out what the kernel supports via different content in reg_mask_range (i.e. try with a value in one of the currently reserved fields and fall back to using addr only if that doesn't work.) Can we do better? Maybe we could introduce a capability that returns the supported ranges as flags, i.e. now we would return 1 for id regs masks, and for the future case where we have some values in the next reserved field we could return 1 & 2 etc. Would make life easier for userspace that needs to work with different kernels, but might be overkill if reserved[] is more like an insurance without any concrete plans for extensions.
On Mon, Aug 14, 2023 at 2:46 AM Cornelia Huck <cohuck@redhat.com> wrote: > > On Mon, Aug 07 2023, Jing Zhang <jingzhangos@google.com> wrote: > > > Add some basic documentation on how to get feature ID register writable > > masks from userspace. > > > > Signed-off-by: Jing Zhang <jingzhangos@google.com> > > --- > > Documentation/virt/kvm/api.rst | 29 +++++++++++++++++++++++++++++ > > 1 file changed, 29 insertions(+) > > > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > > index c0ddd3035462..92a9b20f970e 100644 > > --- a/Documentation/virt/kvm/api.rst > > +++ b/Documentation/virt/kvm/api.rst > > @@ -6068,6 +6068,35 @@ writes to the CNTVCT_EL0 and CNTPCT_EL0 registers using the SET_ONE_REG > > interface. No error will be returned, but the resulting offset will not be > > applied. > > > > +4.139 KVM_ARM_GET_REG_WRITABLE_MASKS > > +------------------------------------------- > > + > > +:Capability: none > > +:Architectures: arm64 > > +:Type: vm ioctl > > +:Parameters: struct reg_mask_range (in/out) > > +:Returns: 0 on success, < 0 on error > > + > > + > > +:: > > + > > + #define ARM64_FEATURE_ID_SPACE_SIZE (3 * 8 * 8) > > + > > + struct reg_mask_range { > > + __u64 addr; /* Pointer to mask array */ > > + __u64 reserved[7]; > > + }; > > + > > +This ioctl would copy the writable masks for feature ID registers to userspace. > > +The Feature ID space is defined as the System register space in AArch64 with > > +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}. > > +To get the index in the mask array pointed by ``addr`` for a specified feature > > +ID register, use the macro ``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``. > > +This allows the userspace to know upfront whether it can actually tweak the > > +contents of a feature ID register or not. > > +The ``reserved[7]`` is reserved for future use to add other register space. For > > +feature ID registers, it should be 0, otherwise, KVM may return error. > > In case of future extensions, this means that userspace needs to figure > out what the kernel supports via different content in reg_mask_range > (i.e. try with a value in one of the currently reserved fields and fall > back to using addr only if that doesn't work.) Can we do better? > > Maybe we could introduce a capability that returns the supported ranges > as flags, i.e. now we would return 1 for id regs masks, and for the > future case where we have some values in the next reserved field we > could return 1 & 2 etc. Would make life easier for userspace that needs > to work with different kernels, but might be overkill if reserved[] is > more like an insurance without any concrete plans for extensions. > Maybe it'd be better to leave this to whenever we do need to add other range support? Jing
On Mon, Aug 14 2023, Jing Zhang <jingzhangos@google.com> wrote: > On Mon, Aug 14, 2023 at 2:46 AM Cornelia Huck <cohuck@redhat.com> wrote: >> >> On Mon, Aug 07 2023, Jing Zhang <jingzhangos@google.com> wrote: >> >> > Add some basic documentation on how to get feature ID register writable >> > masks from userspace. >> > >> > Signed-off-by: Jing Zhang <jingzhangos@google.com> >> > --- >> > Documentation/virt/kvm/api.rst | 29 +++++++++++++++++++++++++++++ >> > 1 file changed, 29 insertions(+) >> > >> > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst >> > index c0ddd3035462..92a9b20f970e 100644 >> > --- a/Documentation/virt/kvm/api.rst >> > +++ b/Documentation/virt/kvm/api.rst >> > @@ -6068,6 +6068,35 @@ writes to the CNTVCT_EL0 and CNTPCT_EL0 registers using the SET_ONE_REG >> > interface. No error will be returned, but the resulting offset will not be >> > applied. >> > >> > +4.139 KVM_ARM_GET_REG_WRITABLE_MASKS >> > +------------------------------------------- >> > + >> > +:Capability: none >> > +:Architectures: arm64 >> > +:Type: vm ioctl >> > +:Parameters: struct reg_mask_range (in/out) >> > +:Returns: 0 on success, < 0 on error >> > + >> > + >> > +:: >> > + >> > + #define ARM64_FEATURE_ID_SPACE_SIZE (3 * 8 * 8) >> > + >> > + struct reg_mask_range { >> > + __u64 addr; /* Pointer to mask array */ >> > + __u64 reserved[7]; >> > + }; >> > + >> > +This ioctl would copy the writable masks for feature ID registers to userspace. >> > +The Feature ID space is defined as the System register space in AArch64 with >> > +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}. >> > +To get the index in the mask array pointed by ``addr`` for a specified feature >> > +ID register, use the macro ``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``. >> > +This allows the userspace to know upfront whether it can actually tweak the >> > +contents of a feature ID register or not. >> > +The ``reserved[7]`` is reserved for future use to add other register space. For >> > +feature ID registers, it should be 0, otherwise, KVM may return error. >> >> In case of future extensions, this means that userspace needs to figure >> out what the kernel supports via different content in reg_mask_range >> (i.e. try with a value in one of the currently reserved fields and fall >> back to using addr only if that doesn't work.) Can we do better? >> >> Maybe we could introduce a capability that returns the supported ranges >> as flags, i.e. now we would return 1 for id regs masks, and for the >> future case where we have some values in the next reserved field we >> could return 1 & 2 etc. Would make life easier for userspace that needs >> to work with different kernels, but might be overkill if reserved[] is >> more like an insurance without any concrete plans for extensions. >> > > Maybe it'd be better to leave this to whenever we do need to add other > range support? My point is: How does userspace figure out if the kernel that is running supports ranges other than id regs? If this is just an insurance against changes that might arrive or not, we can live with the awkward "just try it out" approach; if we think it's likely that we'll need to extend it, we need to add the mechanism for userspace to find out about it now, or it would need to probe for presence of the mechanism...
On Thu, 17 Aug 2023 09:16:56 +0100, Cornelia Huck <cohuck@redhat.com> wrote: > > On Mon, Aug 14 2023, Jing Zhang <jingzhangos@google.com> wrote: > > > Maybe it'd be better to leave this to whenever we do need to add other > > range support? > > My point is: How does userspace figure out if the kernel that is running > supports ranges other than id regs? If this is just an insurance against > changes that might arrive or not, we can live with the awkward "just try > it out" approach; if we think it's likely that we'll need to extend it, > we need to add the mechanism for userspace to find out about it now, or > it would need to probe for presence of the mechanism... Agreed. Nothing like the present to address this sort of things. it really doesn't cost much, and I'd rather have it right now. Here's a vague attempt at an advertising mechanism. If people are OK with it, I can stash that on top of Jing's series. Thanks, M. From bcfd87e85954e24ac4a905a3486c9040cdfc6d0b Mon Sep 17 00:00:00 2001 From: Marc Zyngier <maz@kernel.org> Date: Thu, 17 Aug 2023 14:48:16 +0100 Subject: [PATCH] KVM: arm64: Add KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES While the Feature ID range is well defined and pretty large, it isn't inconceivable that the architecture will eventually grow some other ranges that will need to similarly be described to userspace. Add a new capability (KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES) that returns a bitmap of the valid ranges, which can subsequently be retrieved, one at a time by setting the index of the set bit as the range identifier. Obviously, we only support a value of 0 for now. Signed-off-by: Marc Zyngier <maz@kernel.org> --- Documentation/virt/kvm/api.rst | 37 ++++++++++++++++++++----------- arch/arm64/include/uapi/asm/kvm.h | 13 +++++++---- arch/arm64/kvm/arm.c | 3 +++ arch/arm64/kvm/sys_regs.c | 5 +++-- include/uapi/linux/kvm.h | 1 + 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 92a9b20f970e..0e6ce02cac3b 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -6071,7 +6071,7 @@ applied. 4.139 KVM_ARM_GET_REG_WRITABLE_MASKS ------------------------------------------- -:Capability: none +:Capability: KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES :Architectures: arm64 :Type: vm ioctl :Parameters: struct reg_mask_range (in/out) @@ -6082,20 +6082,31 @@ applied. #define ARM64_FEATURE_ID_SPACE_SIZE (3 * 8 * 8) - struct reg_mask_range { - __u64 addr; /* Pointer to mask array */ - __u64 reserved[7]; - }; + struct reg_mask_range { + __u64 addr; /* Pointer to mask array */ + __u32 range; /* Requested range */ + __u32 reserved[13]; + }; -This ioctl would copy the writable masks for feature ID registers to userspace. -The Feature ID space is defined as the System register space in AArch64 with +This ioctl copies the writable masks for Feature ID registers to userspace. +The Feature ID space is defined as the AArch64 System Register space with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}. -To get the index in the mask array pointed by ``addr`` for a specified feature -ID register, use the macro ``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``. -This allows the userspace to know upfront whether it can actually tweak the -contents of a feature ID register or not. -The ``reserved[7]`` is reserved for future use to add other register space. For -feature ID registers, it should be 0, otherwise, KVM may return error. + +The mask array pointed to by ``addr`` is indexed by the macro +``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``, allowing userspace +to know what bits can be changed for the system register described by ``op0, +op1, crn, crm, op2``. + +The ``range`` field describes the requested range of registers. The valid +ranges can be retrieved by checking the return value of +KVM_CAP_CHECK_EXTENSION_VM for the KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES +capability, which will return a bitmask of the supported ranges. Each bit +set in the return value represents a possible value for the ``range`` +field. At the time of writing, only bit 0 is returned set by the +capability, meaning that only the value 0 is value for ``range``. + +The ``reserved[13]`` array is reserved for future use and should be 0, or +KVM may return an error. 5. The kvm_run structure ======================== diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 7a21bbb8a0f7..5148b4c22549 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -505,8 +505,9 @@ struct kvm_smccc_filter { #define KVM_HYPERCALL_EXIT_SMC (1U << 0) #define KVM_HYPERCALL_EXIT_16BIT (1U << 1) -/* Get feature ID registers userspace writable mask. */ /* + * Get feature ID registers userspace writable mask. + * * From DDI0487J.a, D19.2.66 ("ID_AA64MMFR2_EL1, AArch64 Memory Model * Feature Register 2"): * @@ -514,8 +515,11 @@ struct kvm_smccc_filter { * AArch64 with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, * op2=={0-7}." * - * This covers all R/O registers that indicate anything useful feature - * wise, including the ID registers. + * This covers all currently known R/O registers that indicate + * anything useful feature wise, including the ID registers. + * + * If we ever need to introduce a new range, it will be described as + * such in the range field. */ #define ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2) \ ({ \ @@ -528,7 +532,8 @@ struct kvm_smccc_filter { struct reg_mask_range { __u64 addr; /* Pointer to mask array */ - __u64 reserved[7]; + __u32 range; /* Requested range */ + __u32 reserved[13]; }; #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index e08894692829..6ea4d8b0e744 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -316,6 +316,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES: r = kvm_supported_block_sizes(); break; + case KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES: + r = BIT(0); + break; default: r = 0; } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 59c590fff4f2..6eadd0fa2c53 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -3600,8 +3600,9 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range * const void *zero_page = page_to_virt(ZERO_PAGE(0)); u64 __user *masks = (u64 __user *)range->addr; - /* Only feature id range is supported, reserved[7] must be zero. */ - if (memcmp(range->reserved, zero_page, sizeof(range->reserved))) + /* Only feature id range is supported, reserved[13] must be zero. */ + if (range->range || + memcmp(range->reserved, zero_page, sizeof(range->reserved))) return -EINVAL; /* Wipe the whole thing first */ diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 424b6d00440b..f5100055a1a6 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1192,6 +1192,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_COUNTER_OFFSET 227 #define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228 #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 +#define KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES 230 #ifdef KVM_CAP_IRQ_ROUTING
On Thu, Aug 17 2023, Marc Zyngier <maz@kernel.org> wrote: > On Thu, 17 Aug 2023 09:16:56 +0100, > Cornelia Huck <cohuck@redhat.com> wrote: >> >> On Mon, Aug 14 2023, Jing Zhang <jingzhangos@google.com> wrote: >> >> > Maybe it'd be better to leave this to whenever we do need to add other >> > range support? >> >> My point is: How does userspace figure out if the kernel that is running >> supports ranges other than id regs? If this is just an insurance against >> changes that might arrive or not, we can live with the awkward "just try >> it out" approach; if we think it's likely that we'll need to extend it, >> we need to add the mechanism for userspace to find out about it now, or >> it would need to probe for presence of the mechanism... > > Agreed. Nothing like the present to address this sort of things. it > really doesn't cost much, and I'd rather have it right now. > > Here's a vague attempt at an advertising mechanism. If people are OK > with it, I can stash that on top of Jing's series. I think that looks reasonable.
On Thu, Aug 17, 2023 at 7:00 AM Marc Zyngier <maz@kernel.org> wrote: > > On Thu, 17 Aug 2023 09:16:56 +0100, > Cornelia Huck <cohuck@redhat.com> wrote: > > > > On Mon, Aug 14 2023, Jing Zhang <jingzhangos@google.com> wrote: > > > > > Maybe it'd be better to leave this to whenever we do need to add other > > > range support? > > > > My point is: How does userspace figure out if the kernel that is running > > supports ranges other than id regs? If this is just an insurance against > > changes that might arrive or not, we can live with the awkward "just try > > it out" approach; if we think it's likely that we'll need to extend it, > > we need to add the mechanism for userspace to find out about it now, or > > it would need to probe for presence of the mechanism... > > Agreed. Nothing like the present to address this sort of things. it > really doesn't cost much, and I'd rather have it right now. > > Here's a vague attempt at an advertising mechanism. If people are OK > with it, I can stash that on top of Jing's series. > > Thanks, > > M. > > From bcfd87e85954e24ac4a905a3486c9040cdfc6d0b Mon Sep 17 00:00:00 2001 > From: Marc Zyngier <maz@kernel.org> > Date: Thu, 17 Aug 2023 14:48:16 +0100 > Subject: [PATCH] KVM: arm64: Add KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES > > While the Feature ID range is well defined and pretty large, it > isn't inconceivable that the architecture will eventually grow > some other ranges that will need to similarly be described to > userspace. > > Add a new capability (KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES) > that returns a bitmap of the valid ranges, which can subsequently > be retrieved, one at a time by setting the index of the set bit > as the range identifier. > > Obviously, we only support a value of 0 for now. > > Signed-off-by: Marc Zyngier <maz@kernel.org> > --- > Documentation/virt/kvm/api.rst | 37 ++++++++++++++++++++----------- > arch/arm64/include/uapi/asm/kvm.h | 13 +++++++---- > arch/arm64/kvm/arm.c | 3 +++ > arch/arm64/kvm/sys_regs.c | 5 +++-- > include/uapi/linux/kvm.h | 1 + > 5 files changed, 40 insertions(+), 19 deletions(-) > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > index 92a9b20f970e..0e6ce02cac3b 100644 > --- a/Documentation/virt/kvm/api.rst > +++ b/Documentation/virt/kvm/api.rst > @@ -6071,7 +6071,7 @@ applied. > 4.139 KVM_ARM_GET_REG_WRITABLE_MASKS > ------------------------------------------- > > -:Capability: none > +:Capability: KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES > :Architectures: arm64 > :Type: vm ioctl > :Parameters: struct reg_mask_range (in/out) > @@ -6082,20 +6082,31 @@ applied. > > #define ARM64_FEATURE_ID_SPACE_SIZE (3 * 8 * 8) > > - struct reg_mask_range { > - __u64 addr; /* Pointer to mask array */ > - __u64 reserved[7]; > - }; > + struct reg_mask_range { > + __u64 addr; /* Pointer to mask array */ > + __u32 range; /* Requested range */ > + __u32 reserved[13]; > + }; > > -This ioctl would copy the writable masks for feature ID registers to userspace. > -The Feature ID space is defined as the System register space in AArch64 with > +This ioctl copies the writable masks for Feature ID registers to userspace. > +The Feature ID space is defined as the AArch64 System Register space with > op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}. > -To get the index in the mask array pointed by ``addr`` for a specified feature > -ID register, use the macro ``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``. > -This allows the userspace to know upfront whether it can actually tweak the > -contents of a feature ID register or not. > -The ``reserved[7]`` is reserved for future use to add other register space. For > -feature ID registers, it should be 0, otherwise, KVM may return error. > + > +The mask array pointed to by ``addr`` is indexed by the macro > +``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``, allowing userspace > +to know what bits can be changed for the system register described by ``op0, > +op1, crn, crm, op2``. > + > +The ``range`` field describes the requested range of registers. The valid > +ranges can be retrieved by checking the return value of > +KVM_CAP_CHECK_EXTENSION_VM for the KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES > +capability, which will return a bitmask of the supported ranges. Each bit > +set in the return value represents a possible value for the ``range`` > +field. At the time of writing, only bit 0 is returned set by the > +capability, meaning that only the value 0 is value for ``range``. > + > +The ``reserved[13]`` array is reserved for future use and should be 0, or > +KVM may return an error. > > 5. The kvm_run structure > ======================== > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h > index 7a21bbb8a0f7..5148b4c22549 100644 > --- a/arch/arm64/include/uapi/asm/kvm.h > +++ b/arch/arm64/include/uapi/asm/kvm.h > @@ -505,8 +505,9 @@ struct kvm_smccc_filter { > #define KVM_HYPERCALL_EXIT_SMC (1U << 0) > #define KVM_HYPERCALL_EXIT_16BIT (1U << 1) > > -/* Get feature ID registers userspace writable mask. */ > /* > + * Get feature ID registers userspace writable mask. > + * > * From DDI0487J.a, D19.2.66 ("ID_AA64MMFR2_EL1, AArch64 Memory Model > * Feature Register 2"): > * > @@ -514,8 +515,11 @@ struct kvm_smccc_filter { > * AArch64 with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, > * op2=={0-7}." > * > - * This covers all R/O registers that indicate anything useful feature > - * wise, including the ID registers. > + * This covers all currently known R/O registers that indicate > + * anything useful feature wise, including the ID registers. > + * > + * If we ever need to introduce a new range, it will be described as > + * such in the range field. > */ > #define ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2) \ > ({ \ > @@ -528,7 +532,8 @@ struct kvm_smccc_filter { > > struct reg_mask_range { > __u64 addr; /* Pointer to mask array */ > - __u64 reserved[7]; > + __u32 range; /* Requested range */ > + __u32 reserved[13]; > }; > > #endif > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c > index e08894692829..6ea4d8b0e744 100644 > --- a/arch/arm64/kvm/arm.c > +++ b/arch/arm64/kvm/arm.c > @@ -316,6 +316,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) > case KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES: > r = kvm_supported_block_sizes(); > break; > + case KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES: > + r = BIT(0); > + break; > default: > r = 0; > } > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c > index 59c590fff4f2..6eadd0fa2c53 100644 > --- a/arch/arm64/kvm/sys_regs.c > +++ b/arch/arm64/kvm/sys_regs.c > @@ -3600,8 +3600,9 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range * > const void *zero_page = page_to_virt(ZERO_PAGE(0)); > u64 __user *masks = (u64 __user *)range->addr; > > - /* Only feature id range is supported, reserved[7] must be zero. */ > - if (memcmp(range->reserved, zero_page, sizeof(range->reserved))) > + /* Only feature id range is supported, reserved[13] must be zero. */ > + if (range->range || > + memcmp(range->reserved, zero_page, sizeof(range->reserved))) > return -EINVAL; > > /* Wipe the whole thing first */ > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index 424b6d00440b..f5100055a1a6 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -1192,6 +1192,7 @@ struct kvm_ppc_resize_hpt { > #define KVM_CAP_COUNTER_OFFSET 227 > #define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228 > #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 > +#define KVM_CAP_ARM_SUPPORTED_FEATURE_ID_RANGES 230 > > #ifdef KVM_CAP_IRQ_ROUTING > > > -- > Without deviation from the norm, progress is not possible. Looks good to me. Thanks, Jing
On 2023-08-21 18:24, Jing Zhang wrote: > On Thu, Aug 17, 2023 at 7:00 AM Marc Zyngier <maz@kernel.org> wrote: >> >> On Thu, 17 Aug 2023 09:16:56 +0100, >> Cornelia Huck <cohuck@redhat.com> wrote: >> > >> > On Mon, Aug 14 2023, Jing Zhang <jingzhangos@google.com> wrote: >> > >> > > Maybe it'd be better to leave this to whenever we do need to add other >> > > range support? >> > >> > My point is: How does userspace figure out if the kernel that is running >> > supports ranges other than id regs? If this is just an insurance against >> > changes that might arrive or not, we can live with the awkward "just try >> > it out" approach; if we think it's likely that we'll need to extend it, >> > we need to add the mechanism for userspace to find out about it now, or >> > it would need to probe for presence of the mechanism... >> >> Agreed. Nothing like the present to address this sort of things. it >> really doesn't cost much, and I'd rather have it right now. >> >> Here's a vague attempt at an advertising mechanism. If people are OK >> with it, I can stash that on top of Jing's series. [...] > Looks good to me. Well, that's of course conditional on the other comments I made against this series. And we're seriously running out of time... M.
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index c0ddd3035462..92a9b20f970e 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -6068,6 +6068,35 @@ writes to the CNTVCT_EL0 and CNTPCT_EL0 registers using the SET_ONE_REG interface. No error will be returned, but the resulting offset will not be applied. +4.139 KVM_ARM_GET_REG_WRITABLE_MASKS +------------------------------------------- + +:Capability: none +:Architectures: arm64 +:Type: vm ioctl +:Parameters: struct reg_mask_range (in/out) +:Returns: 0 on success, < 0 on error + + +:: + + #define ARM64_FEATURE_ID_SPACE_SIZE (3 * 8 * 8) + + struct reg_mask_range { + __u64 addr; /* Pointer to mask array */ + __u64 reserved[7]; + }; + +This ioctl would copy the writable masks for feature ID registers to userspace. +The Feature ID space is defined as the System register space in AArch64 with +op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, op2=={0-7}. +To get the index in the mask array pointed by ``addr`` for a specified feature +ID register, use the macro ``ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2)``. +This allows the userspace to know upfront whether it can actually tweak the +contents of a feature ID register or not. +The ``reserved[7]`` is reserved for future use to add other register space. For +feature ID registers, it should be 0, otherwise, KVM may return error. + 5. The kvm_run structure ========================
Add some basic documentation on how to get feature ID register writable masks from userspace. Signed-off-by: Jing Zhang <jingzhangos@google.com> --- Documentation/virt/kvm/api.rst | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)