[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CA+EHjTxFfY_XkEQrNvme94uHoxQLWEaX1q1MikbcmwmUMq=NwA@mail.gmail.com>
Date: Tue, 13 Jan 2026 14:40:58 +0000
From: Fuad Tabba <tabba@...gle.com>
To: Mark Brown <broonie@...nel.org>
Cc: Marc Zyngier <maz@...nel.org>, Joey Gouly <joey.gouly@....com>,
Catalin Marinas <catalin.marinas@....com>, Suzuki K Poulose <suzuki.poulose@....com>,
Will Deacon <will@...nel.org>, Paolo Bonzini <pbonzini@...hat.com>, Jonathan Corbet <corbet@....net>,
Shuah Khan <shuah@...nel.org>, Oliver Upton <oupton@...nel.org>, Dave Martin <Dave.Martin@....com>,
Mark Rutland <mark.rutland@....com>, Ben Horgan <ben.horgan@....com>,
linux-arm-kernel@...ts.infradead.org, kvmarm@...ts.linux.dev,
linux-kernel@...r.kernel.org, kvm@...r.kernel.org, linux-doc@...r.kernel.org,
linux-kselftest@...r.kernel.org, Peter Maydell <peter.maydell@...aro.org>,
Eric Auger <eric.auger@...hat.com>
Subject: Re: [PATCH v9 26/30] KVM: arm64: Provide interface for configuring
and enabling SME for guests
On Tue, 23 Dec 2025 at 01:23, Mark Brown <broonie@...nel.org> wrote:
>
> Since SME requires configuration of a vector length in order to know the
> size of both the streaming mode SVE state and ZA array we implement a
> capability for it and require that it be enabled and finalized before
> the SME specific state can be accessed, similarly to SVE.
>
> Due to the overlap with sizing the SVE state we finalise both SVE and
> SME with a single finalization, preventing any further changes to the
> SVE and SME configuration once KVM_ARM_VCPU_VEC (an alias for _VCPU_SVE)
> has been finalised. This is not a thing of great elegance but it ensures
With KVM_ARM_VCPU_VEC being an alias for KVM_ARM_VCPU_SVE, wouldn't
kvm_arm_vcpu_finalize() fail for guests that have only SME enabled but
not SVE?
Cheers,
/fuad
> that we never have a state where one of SVE or SME is finalised and the
> other not, avoiding complexity.
>
> SME is supported for normal and protected guests.
>
> Signed-off-by: Mark Brown <broonie@...nel.org>
> ---
> arch/arm64/include/asm/kvm_host.h | 12 +++-
> arch/arm64/include/uapi/asm/kvm.h | 1 +
> arch/arm64/kvm/arm.c | 10 ++++
> arch/arm64/kvm/hyp/nvhe/pkvm.c | 76 +++++++++++++++++++-----
> arch/arm64/kvm/hyp/nvhe/sys_regs.c | 6 ++
> arch/arm64/kvm/reset.c | 116 +++++++++++++++++++++++++++++++------
> include/uapi/linux/kvm.h | 1 +
> 7 files changed, 189 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index bceaf0608d75..011debfc1afd 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -39,7 +39,7 @@
>
> #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
>
> -#define KVM_VCPU_MAX_FEATURES 9
> +#define KVM_VCPU_MAX_FEATURES 10
> #define KVM_VCPU_VALID_FEATURES (BIT(KVM_VCPU_MAX_FEATURES) - 1)
>
> #define KVM_REQ_SLEEP \
> @@ -82,6 +82,7 @@ extern unsigned int __ro_after_init kvm_host_max_vl[ARM64_VEC_MAX];
> DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
>
> int __init kvm_arm_init_sve(void);
> +int __init kvm_arm_init_sme(void);
>
> u32 __attribute_const__ kvm_target_cpu(void);
> void kvm_reset_vcpu(struct kvm_vcpu *vcpu);
> @@ -1149,7 +1150,14 @@ struct kvm_vcpu_arch {
> __size_ret; \
> })
>
> -#define vcpu_sve_state_size(vcpu) sve_state_size_from_vl((vcpu)->arch.max_vl[ARM64_VEC_SVE])
> +#define vcpu_sve_state_size(vcpu) ({ \
> + unsigned int __max_vl; \
> + \
> + __max_vl = max((vcpu)->arch.max_vl[ARM64_VEC_SVE], \
> + (vcpu)->arch.max_vl[ARM64_VEC_SME]); \
> + \
> + sve_state_size_from_vl(__max_vl); \
> +})
>
> #define vcpu_sme_state(vcpu) (kern_hyp_va((vcpu)->arch.sme_state))
>
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index 9a19cc58d227..b4be424e4230 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -106,6 +106,7 @@ struct kvm_regs {
> #define KVM_ARM_VCPU_PTRAUTH_GENERIC 6 /* VCPU uses generic authentication */
> #define KVM_ARM_VCPU_HAS_EL2 7 /* Support nested virtualization */
> #define KVM_ARM_VCPU_HAS_EL2_E2H0 8 /* Limit NV support to E2H RES0 */
> +#define KVM_ARM_VCPU_SME 9 /* enable SME for this CPU */
>
> /*
> * An alias for _SVE since we finalize VL configuration for both SVE and SME
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 4f80da0c0d1d..7de7b497f74f 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -402,6 +402,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> case KVM_CAP_ARM_SVE:
> r = system_supports_sve();
> break;
> + case KVM_CAP_ARM_SME:
> + r = system_supports_sme();
> + break;
> case KVM_CAP_ARM_PTRAUTH_ADDRESS:
> case KVM_CAP_ARM_PTRAUTH_GENERIC:
> r = kvm_has_full_ptr_auth();
> @@ -1456,6 +1459,9 @@ static unsigned long system_supported_vcpu_features(void)
> if (!system_supports_sve())
> clear_bit(KVM_ARM_VCPU_SVE, &features);
>
> + if (!system_supports_sme())
> + clear_bit(KVM_ARM_VCPU_SME, &features);
> +
> if (!kvm_has_full_ptr_auth()) {
> clear_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, &features);
> clear_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, &features);
> @@ -2878,6 +2884,10 @@ static __init int kvm_arm_init(void)
> if (err)
> return err;
>
> + err = kvm_arm_init_sme();
> + if (err)
> + return err;
> +
> err = kvm_arm_vmid_alloc_init();
> if (err) {
> kvm_err("Failed to initialize VMID allocator.\n");
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index b656449dff69..30ee9f371b0d 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -148,10 +148,6 @@ static int pkvm_check_pvm_cpu_features(struct kvm_vcpu *vcpu)
> !kvm_has_feat(kvm, ID_AA64PFR0_EL1, AdvSIMD, IMP))
> return -EINVAL;
>
> - /* No SME support in KVM right now. Check to catch if it changes. */
> - if (kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
> - return -EINVAL;
> -
> return 0;
> }
>
> @@ -377,6 +373,11 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc
> kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_GUEST_HAS_SVE);
> }
>
> + if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SME)) {
> + set_bit(KVM_ARM_VCPU_SME, allowed_features);
> + kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_GUEST_HAS_SME);
> + }
> +
> bitmap_and(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features,
> allowed_features, KVM_VCPU_MAX_FEATURES);
> }
> @@ -399,6 +400,18 @@ static void unpin_host_sve_state(struct pkvm_hyp_vcpu *hyp_vcpu)
> sve_state + vcpu_sve_state_size(&hyp_vcpu->vcpu));
> }
>
> +static void unpin_host_sme_state(struct pkvm_hyp_vcpu *hyp_vcpu)
> +{
> + void *sme_state;
> +
> + if (!vcpu_has_feature(&hyp_vcpu->vcpu, KVM_ARM_VCPU_SME))
> + return;
> +
> + sme_state = kern_hyp_va(hyp_vcpu->vcpu.arch.sme_state);
> + hyp_unpin_shared_mem(sme_state,
> + sme_state + vcpu_sme_state_size(&hyp_vcpu->vcpu));
> +}
> +
> static void unpin_host_vcpus(struct pkvm_hyp_vcpu *hyp_vcpus[],
> unsigned int nr_vcpus)
> {
> @@ -412,6 +425,7 @@ static void unpin_host_vcpus(struct pkvm_hyp_vcpu *hyp_vcpus[],
>
> unpin_host_vcpu(hyp_vcpu->host_vcpu);
> unpin_host_sve_state(hyp_vcpu);
> + unpin_host_sme_state(hyp_vcpu);
> }
> }
>
> @@ -438,23 +452,35 @@ static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
> mmu->pgt = &hyp_vm->pgt;
> }
>
> -static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *host_vcpu)
> +static int pkvm_vcpu_init_vec(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *host_vcpu)
> {
> struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
> - unsigned int sve_max_vl;
> - size_t sve_state_size;
> - void *sve_state;
> + unsigned int sve_max_vl, sme_max_vl;
> + size_t sve_state_size, sme_state_size;
> + void *sve_state, *sme_state;
> int ret = 0;
>
> - if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) {
> + if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE) &&
> + !vcpu_has_feature(vcpu, KVM_ARM_VCPU_SME)) {
> vcpu_clear_flag(vcpu, VCPU_VEC_FINALIZED);
> return 0;
> }
>
> /* Limit guest vector length to the maximum supported by the host. */
> - sve_max_vl = min(READ_ONCE(host_vcpu->arch.max_vl[ARM64_VEC_SVE]),
> - kvm_host_max_vl[ARM64_VEC_SVE]);
> - sve_state_size = sve_state_size_from_vl(sve_max_vl);
> + if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE))
> + sve_max_vl = min(READ_ONCE(host_vcpu->arch.max_vl[ARM64_VEC_SVE]),
> + kvm_host_max_vl[ARM64_VEC_SVE]);
> + else
> + sve_max_vl = 0;
> +
> + if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SME))
> + sme_max_vl = min(READ_ONCE(host_vcpu->arch.max_vl[ARM64_VEC_SME]),
> + kvm_host_max_vl[ARM64_VEC_SME]);
> + else
> + sme_max_vl = 0;
> +
> + /* We need SVE storage for the larger of normal or streaming mode */
> + sve_state_size = sve_state_size_from_vl(max(sve_max_vl, sme_max_vl));
> sve_state = kern_hyp_va(READ_ONCE(host_vcpu->arch.sve_state));
>
> if (!sve_state || !sve_state_size) {
> @@ -466,12 +492,36 @@ static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *h
> if (ret)
> goto err;
>
> + if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SME)) {
> + sme_state_size = sme_state_size_from_vl(sme_max_vl,
> + vcpu_has_sme2(vcpu));
> + sme_state = kern_hyp_va(READ_ONCE(host_vcpu->arch.sme_state));
> +
> + if (!sme_state || !sme_state_size) {
> + ret = -EINVAL;
> + goto err_sve_mapped;
> + }
> +
> + ret = hyp_pin_shared_mem(sme_state, sme_state + sme_state_size);
> + if (ret)
> + goto err_sve_mapped;
> + } else {
> + sme_state = 0;
> + }
> +
> vcpu->arch.sve_state = sve_state;
> vcpu->arch.max_vl[ARM64_VEC_SVE] = sve_max_vl;
>
> + vcpu->arch.sme_state = sme_state;
> + vcpu->arch.max_vl[ARM64_VEC_SME] = sme_max_vl;
> +
> return 0;
> +
> +err_sve_mapped:
> + hyp_unpin_shared_mem(sve_state, sve_state + sve_state_size);
> err:
> clear_bit(KVM_ARM_VCPU_SVE, vcpu->kvm->arch.vcpu_features);
> + clear_bit(KVM_ARM_VCPU_SME, vcpu->kvm->arch.vcpu_features);
> return ret;
> }
>
> @@ -501,7 +551,7 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
> if (ret)
> goto done;
>
> - ret = pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
> + ret = pkvm_vcpu_init_vec(hyp_vcpu, host_vcpu);
> done:
> if (ret)
> unpin_host_vcpu(host_vcpu);
> diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> index 3108b5185c20..40127ba86335 100644
> --- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> @@ -66,6 +66,11 @@ static bool vm_has_ptrauth(const struct kvm *kvm)
> kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_PTRAUTH_GENERIC);
> }
>
> +static bool vm_has_sme(const struct kvm *kvm)
> +{
> + return system_supports_sme() && kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_SME);
> +}
> +
> static bool vm_has_sve(const struct kvm *kvm)
> {
> return system_supports_sve() && kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_SVE);
> @@ -102,6 +107,7 @@ static const struct pvm_ftr_bits pvmid_aa64pfr0[] = {
> };
>
> static const struct pvm_ftr_bits pvmid_aa64pfr1[] = {
> + MAX_FEAT_FUNC(ID_AA64PFR1_EL1, SME, SME2, vm_has_sme),
> MAX_FEAT(ID_AA64PFR1_EL1, BT, IMP),
> MAX_FEAT(ID_AA64PFR1_EL1, SSBS, SSBS2),
> MAX_FEAT_ENUM(ID_AA64PFR1_EL1, MTE_frac, NI),
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index a8684a1346ec..e6dc04267cbb 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -76,6 +76,34 @@ int __init kvm_arm_init_sve(void)
> return 0;
> }
>
> +int __init kvm_arm_init_sme(void)
> +{
> + if (system_supports_sme()) {
> + kvm_max_vl[ARM64_VEC_SME] = sme_max_virtualisable_vl();
> + kvm_host_max_vl[ARM64_VEC_SME] = sme_max_vl();
> + kvm_nvhe_sym(kvm_host_max_vl[ARM64_VEC_SME]) = kvm_host_max_vl[ARM64_VEC_SME];
> +
> + /*
> + * The get_sve_reg()/set_sve_reg() ioctl interface will need
> + * to be extended with multiple register slice support in
> + * order to support vector lengths greater than
> + * VL_ARCH_MAX:
> + */
> + if (WARN_ON(kvm_max_vl[ARM64_VEC_SME] > VL_ARCH_MAX))
> + kvm_max_vl[ARM64_VEC_SME] = VL_ARCH_MAX;
> +
> + /*
> + * Don't even try to make use of vector lengths that
> + * aren't available on all CPUs, for now:
> + */
> + if (kvm_max_vl[ARM64_VEC_SME] < sme_max_vl())
> + pr_warn("KVM: SME vector length for guests limited to %u bytes\n",
> + kvm_max_vl[ARM64_VEC_SME]);
> + }
> +
> + return 0;
> +}
> +
> static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
> {
> vcpu->arch.max_vl[ARM64_VEC_SVE] = kvm_max_vl[ARM64_VEC_SVE];
> @@ -88,42 +116,86 @@ static void kvm_vcpu_enable_sve(struct kvm_vcpu *vcpu)
> set_bit(KVM_ARCH_FLAG_GUEST_HAS_SVE, &vcpu->kvm->arch.flags);
> }
>
> +static void kvm_vcpu_enable_sme(struct kvm_vcpu *vcpu)
> +{
> + vcpu->arch.max_vl[ARM64_VEC_SME] = kvm_max_vl[ARM64_VEC_SME];
> +
> + /*
> + * Userspace can still customize the vector lengths by writing
> + * KVM_REG_ARM64_SME_VLS. Allocation is deferred until
> + * kvm_arm_vcpu_finalize(), which freezes the configuration.
> + */
> + set_bit(KVM_ARCH_FLAG_GUEST_HAS_SME, &vcpu->kvm->arch.flags);
> +}
> +
> /*
> - * Finalize vcpu's maximum SVE vector length, allocating
> - * vcpu->arch.sve_state as necessary.
> + * Finalize vcpu's maximum vector lengths, allocating
> + * vcpu->arch.sve_state and vcpu->arch.sme_state as necessary.
> */
> static int kvm_vcpu_finalize_vec(struct kvm_vcpu *vcpu)
> {
> - void *buf;
> + void *sve_state, *sme_state;
> unsigned int vl;
> - size_t reg_sz;
> int ret;
>
> - vl = vcpu->arch.max_vl[ARM64_VEC_SVE];
> -
> /*
> * Responsibility for these properties is shared between
> * kvm_arm_init_sve(), kvm_vcpu_enable_sve() and
> * set_sve_vls(). Double-check here just to be sure:
> */
> - if (WARN_ON(!sve_vl_valid(vl) || vl > sve_max_virtualisable_vl() ||
> - vl > VL_ARCH_MAX))
> - return -EIO;
> + if (vcpu_has_sve(vcpu)) {
> + vl = vcpu->arch.max_vl[ARM64_VEC_SVE];
> + if (WARN_ON(!sve_vl_valid(vl) ||
> + vl > sve_max_virtualisable_vl() ||
> + vl > VL_ARCH_MAX))
> + return -EIO;
> + }
>
> - reg_sz = vcpu_sve_state_size(vcpu);
> - buf = kzalloc(reg_sz, GFP_KERNEL_ACCOUNT);
> - if (!buf)
> + /* Similarly for SME */
> + if (vcpu_has_sme(vcpu)) {
> + vl = vcpu->arch.max_vl[ARM64_VEC_SME];
> + if (WARN_ON(!sve_vl_valid(vl) ||
> + vl > sme_max_virtualisable_vl() ||
> + vl > VL_ARCH_MAX))
> + return -EIO;
> + }
> +
> + sve_state = kzalloc(vcpu_sve_state_size(vcpu), GFP_KERNEL_ACCOUNT);
> + if (!sve_state)
> return -ENOMEM;
>
> - ret = kvm_share_hyp(buf, buf + reg_sz);
> - if (ret) {
> - kfree(buf);
> - return ret;
> + ret = kvm_share_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
> + if (ret)
> + goto err_sve_alloc;
> +
> + if (vcpu_has_sme(vcpu)) {
> + sme_state = kzalloc(vcpu_sme_state_size(vcpu),
> + GFP_KERNEL_ACCOUNT);
> + if (!sme_state) {
> + ret = -ENOMEM;
> + goto err_sve_map;
> + }
> +
> + ret = kvm_share_hyp(sme_state,
> + sme_state + vcpu_sme_state_size(vcpu));
> + if (ret)
> + goto err_sme_alloc;
> + } else {
> + sme_state = NULL;
> }
> -
> - vcpu->arch.sve_state = buf;
> +
> + vcpu->arch.sve_state = sve_state;
> + vcpu->arch.sme_state = sme_state;
> vcpu_set_flag(vcpu, VCPU_VEC_FINALIZED);
> return 0;
> +
> +err_sme_alloc:
> + kfree(sme_state);
> +err_sve_map:
> + kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
> +err_sve_alloc:
> + kfree(sve_state);
> + return ret;
> }
>
> int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature)
> @@ -153,12 +225,16 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu)
> void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu)
> {
> void *sve_state = vcpu->arch.sve_state;
> + void *sme_state = vcpu->arch.sme_state;
>
> kvm_unshare_hyp(vcpu, vcpu + 1);
> if (sve_state)
> kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
> kfree(sve_state);
> free_page((unsigned long)vcpu->arch.ctxt.vncr_array);
> + if (sme_state)
> + kvm_unshare_hyp(sme_state, sme_state + vcpu_sme_state_size(vcpu));
> + kfree(sme_state);
> kfree(vcpu->arch.vncr_tlb);
> kfree(vcpu->arch.ccsidr);
> }
> @@ -167,6 +243,8 @@ static void kvm_vcpu_reset_vec(struct kvm_vcpu *vcpu)
> {
> if (vcpu_has_sve(vcpu))
> memset(vcpu->arch.sve_state, 0, vcpu_sve_state_size(vcpu));
> + if (vcpu_has_sme(vcpu))
> + memset(vcpu->arch.sme_state, 0, vcpu_sme_state_size(vcpu));
> }
>
> /**
> @@ -206,6 +284,8 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> if (!kvm_arm_vcpu_vec_finalized(vcpu)) {
> if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE))
> kvm_vcpu_enable_sve(vcpu);
> + if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SME))
> + kvm_vcpu_enable_sme(vcpu);
> } else {
> kvm_vcpu_reset_vec(vcpu);
> }
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index dddb781b0507..d9e068db3b73 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -974,6 +974,7 @@ struct kvm_enable_cap {
> #define KVM_CAP_GUEST_MEMFD_FLAGS 244
> #define KVM_CAP_ARM_SEA_TO_USER 245
> #define KVM_CAP_S390_USER_OPEREXEC 246
> +#define KVM_CAP_ARM_SME 247
>
> struct kvm_irq_routing_irqchip {
> __u32 irqchip;
>
> --
> 2.47.3
>
Powered by blists - more mailing lists