From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 508B640A927; Tue, 15 Sep 2026 16:01:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488119; cv=none; b=GsiMsW89x/9CphDwg2WmY7HK5Aq4RFJ7BX828OAk8bl44PjgrD9XwN56KsyZu1oxRXYSKHZzU9PghdO2bUYmAhVKhROoBIOG0eIPcLgrsr5L1WeFuBc56/FbhjugGLISk2QtYAgJlaP2Bw+QOtHAgoUsQt4AuJ04ofRRjWaoL/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488119; c=relaxed/simple; bh=fBZJKiu/ewB5QHAgo63DvTdkFMYmp3Bnxwns6qPiSKA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fC9J3z4qG8e8unmEtsP3bXiphNs6Ox8A+6X8j/y1+AkK+2q8hkW/ySuSVyncaBirNJSz9fdjWAr5YJkixEjAFHo20RYIsVrGi3lrzDKRN50doxlaJgpExUbpzU2z9pC/FnW97J1dfuPsJhdylYDfoLM7PaqC2jmgQ5wu3wH5flM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=L+T9Uozv; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="L+T9Uozv" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3F63C1570; Tue, 15 Sep 2026 09:01:52 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 0D99B3F882; Tue, 15 Sep 2026 09:01:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488115; bh=fBZJKiu/ewB5QHAgo63DvTdkFMYmp3Bnxwns6qPiSKA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L+T9Uozv/tDz3Pk7iU8g5To5JLXyJmTx5wv6QVnTthjAprbbVslLEe34IJX7OM+c8 GJLf0uiZ2AMnawoZGSQoW8Andz9tS607fyocUuJsk0LMrZ3ceKKk7HXtT7xu1XjKA2 uT4Sl7KiuOY/7nO3VUg5fERL33q3Pl4N5SN4IaYw= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose , Marc Zyngier Subject: [PATCH v18 01/23] KVM: arm64: protected VM: Handle set_one_reg CNTVCT_EL0/CNTPCT_EL0 Date: Tue, 15 Sep 2026 17:01:19 +0100 Message-ID: <20260915160141.3543048-2-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Protected VMs doesn't allow setting offsets for virtual and phyiscal counters, as the offset is always fixed to 0. The VM ioclt is filtered out based on the cap. However we don't prevent the userspace from trying to write to the CNTVCT/CNTPCT registers. This would lead to KVM triggering a WARN() in timer_set_offset() as the vm_offset pointer is set to NULL. Fix this by always "fixing" the timer offsets to 0 and marking that the timer offset is set in the kvm->arch.flags at pKVM init time. The userspace cannot use the KVM_ARM_SET_COUNTER_OFFSET, as it is blocked for a protected VM. A userspace writing to the SYS_CNT*CT would observe success, without any real effect. This was chosen over preventing the writes to these registers and returning -EPERM. With that, we always have a valid vm_offset pointer, remove the checks for vm_offset =3D=3D NULL. Reported by Sashiko here https://lore.kernel.org/all/20260908164641.416911F00A3A@smtp.kernel.org Fixes: f7d05ee84a6a ("KVM: arm64: Prevent host from managing timer offsets = for protected VMs") Suggested-by: Marc Zyngier Signed-off-by: Suzuki K Poulose --- arch/arm64/kvm/arch_timer.c | 15 +++++---------- arch/arm64/kvm/arm.c | 15 +++++++++++++++ arch/arm64/kvm/hyp/nvhe/pkvm.c | 26 +++++++++++++------------- include/kvm/arm_arch_timer.h | 3 +-- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 6ac3321f4c575..dda020da4c9c7 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -1079,14 +1079,10 @@ static void timer_context_init(struct kvm_vcpu *vcp= u, int timerid) =20 ctxt->timer_id =3D timerid; =20 - if (!kvm_vm_is_protected(vcpu->kvm)) { - if (timerid =3D=3D TIMER_VTIMER) - ctxt->offset.vm_offset =3D &kvm->arch.timer_data.voffset; - else - ctxt->offset.vm_offset =3D &kvm->arch.timer_data.poffset; - } else { - ctxt->offset.vm_offset =3D NULL; - } + if (timerid =3D=3D TIMER_VTIMER) + ctxt->offset.vm_offset =3D &kvm->arch.timer_data.voffset; + else + ctxt->offset.vm_offset =3D &kvm->arch.timer_data.poffset; =20 hrtimer_setup(&ctxt->hrtimer, kvm_hrtimer_expire, CLOCK_MONOTONIC, HRTIME= R_MODE_ABS_HARD); =20 @@ -1110,8 +1106,7 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) timer_context_init(vcpu, i); =20 /* Synchronize offsets across timers of a VM if not already provided */ - if (!vcpu_is_protected(vcpu) && - !test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) { + if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) { timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read()); timer_set_offset(vcpu_ptimer(vcpu), 0); } diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 8b080804bc90b..7c88508cac8a1 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -214,6 +214,20 @@ static int kvm_arm_default_max_vcpus(void) return vgic_present ? kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS; } =20 +/* + * Fix the counter offset to 0 for Protected VMs and mark the + * offset flag. The user can't set the offset via KVM_ARM_SET_COUNTER_OFFS= ET. + */ +static void kvm_arch_fix_timer_offsets(struct kvm *kvm) +{ + if (!kvm_vm_is_protected(kvm)) + return; + + /* Fix the counter offset to 0 and mark the offset initialised */ + kvm->arch.timer_data.poffset =3D kvm->arch.timer_data.voffset =3D 0; + set_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &kvm->arch.flags); +} + /** * kvm_arch_init_vm - initializes a VM data structure * @kvm: pointer to the KVM struct @@ -267,6 +281,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long typ= e) =20 kvm_vgic_early_init(kvm); =20 + kvm_arch_fix_timer_offsets(kvm); kvm_timer_init_vm(kvm); =20 /* The maximum number of VCPUs is limited by the host's GIC model */ diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index 459bd9eb7e4bc..e7b38eff63bd1 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -528,19 +528,19 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *h= yp_vcpu, hyp_vcpu->vcpu.arch.cflags =3D READ_ONCE(host_vcpu->arch.cflags); hyp_vcpu->vcpu.arch.mp_state.mp_state =3D KVM_MP_STATE_STOPPED; =20 - if (!pkvm_hyp_vcpu_is_protected(hyp_vcpu)) { - /* - * Timer offsets are pointing to the untrusted KVM copy, - * which is pinned in __pkvm_init_vm() for the VM life time. - * It is worth noting that hyp_vm->host_kvm points to an EL2 - * linear map address and timer_get_offset() will use - * kern_hyp_va() which is safe as it is idempotent. - */ - vcpu_vtimer(&hyp_vcpu->vcpu)->offset.vm_offset =3D - &hyp_vm->host_kvm->arch.timer_data.voffset; - vcpu_ptimer(&hyp_vcpu->vcpu)->offset.vm_offset =3D - &hyp_vm->host_kvm->arch.timer_data.poffset; - } + /* + * Timer offsets are pointing to the untrusted KVM copy, + * which is pinned in __pkvm_init_vm() for the VM life time. + * It is worth noting that hyp_vm->host_kvm points to an EL2 + * linear map address and timer_get_offset() will use + * kern_hyp_va() which is safe as it is idempotent. + * Also for protected VMs the offset is fixed to 0 and is prevented + * from changing. + */ + vcpu_vtimer(&hyp_vcpu->vcpu)->offset.vm_offset =3D + &hyp_vm->host_kvm->arch.timer_data.voffset; + vcpu_ptimer(&hyp_vcpu->vcpu)->offset.vm_offset =3D + &hyp_vm->host_kvm->arch.timer_data.poffset; =20 ret =3D pkvm_vcpu_init_sysregs(hyp_vcpu); if (ret) diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index bc6f2fdd7ad33..4f0aa3bb69f45 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -176,8 +176,7 @@ static inline bool has_cntpoff(void) if (__ctxt) { \ struct arch_timer_offset *ato =3D &__ctxt->offset;\ \ - if (ato->vm_offset) \ - off +=3D *KERN_HYP_VA(ato->vm_offset); \ + off +=3D *KERN_HYP_VA(ato->vm_offset); \ if (ato->vcpu_offset) \ off +=3D *KERN_HYP_VA(ato->vcpu_offset); \ } \ --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A4A1741F5FB; Tue, 15 Sep 2026 16:01:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488122; cv=none; b=m1wPfxo3zZd7SaRy5TMfsI9miFC+72kE85eVcTsEFSDCYn5+WO2hh5/W9PSe42iYb/mUDOO8ug+6JANd87Em3cspDvHriRTTix52P9vZjbsrUYsMaky+b/Uxv8TcjEdiAQedQy3ogz+yjGlxAECi17n6Rn8+dGuPR3cM8uPJMiM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488122; c=relaxed/simple; bh=4g56UIu1zufZ3C4kHXyidjnLSZAyImym4hJ7wVm8PBQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WOrhfw+gg0hJMcXWN8JN33hulNeQ2/DdjOhCJYD0DMt5rQrZGoPti7PiZTD4+cev2V0uKn48N6oLyIOKOxoIfn6leDqC0aGqqVzCtMRKLaaZLnPeJ7Gt6Py0DYJTgjakh3y5CsJi99rUEcsWM2PWxwtQbjPfmHKFDDmuhB9XBbk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=e0VWjglM; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="e0VWjglM" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5224815A1; Tue, 15 Sep 2026 09:01:55 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 21F1C3F882; Tue, 15 Sep 2026 09:01:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488118; bh=4g56UIu1zufZ3C4kHXyidjnLSZAyImym4hJ7wVm8PBQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e0VWjglMYFuxmawU54dYGpmI6IFj7UT9XO0yHYiWDam3sdCT8tQZtlpl4C8+/R2BO cB+CDhM5Mxaj1BJdLgQod+wCjQ6TNJHd0cICEb1w4hkrVL79a7jxOchLRhxq7bzuIn vHzvG2q9o9HBlyAfRGH3xtCsw398U56YcC7GI4XM= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose , Fuad Tabba Subject: [PATCH v18 02/23] KVM: arm64: Disable Steal time accounting for protected guests Date: Tue, 15 Sep 2026 17:01:20 +0100 Message-ID: <20260915160141.3543048-3-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" PVTIME support is advertised by KVM_CAP_STEAL_TIME, which doesn't take into account the kvm instance. Even with that, a VMM could skip the CAP check and proceed to configure the PVTIME as we don't do further check on the DEVICE_= CTRL. Tighten this up by passing the KVM instance around wherever possible and catch things early Reviewed-by: Fuad Tabba Signed-off-by: Suzuki K Poulose --- arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/pvtime.c | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 27fe0cd5b2d7a..286489a69dff5 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -1346,7 +1346,7 @@ long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu); gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu); void kvm_update_stolen_time(struct kvm_vcpu *vcpu); =20 -bool kvm_arm_pvtime_supported(void); +bool kvm_arm_pvtime_supported(struct kvm *kvm); int kvm_arm_pvtime_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); int kvm_arm_pvtime_get_attr(struct kvm_vcpu *vcpu, diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 7c88508cac8a1..3fbdfce926475 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -462,7 +462,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long = ext) r =3D system_supports_mte(); break; case KVM_CAP_STEAL_TIME: - r =3D kvm_arm_pvtime_supported(); + r =3D kvm_arm_pvtime_supported(kvm); break; case KVM_CAP_ARM_EL1_32BIT: r =3D cpus_have_final_cap(ARM64_HAS_32BIT_EL1); diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c index 4ceabaa4c30bd..579e0a4720ad2 100644 --- a/arch/arm64/kvm/pvtime.c +++ b/arch/arm64/kvm/pvtime.c @@ -67,9 +67,9 @@ gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu) return base; } =20 -bool kvm_arm_pvtime_supported(void) +bool kvm_arm_pvtime_supported(struct kvm *kvm) { - return !!sched_info_on(); + return !!sched_info_on() && (!kvm || !kvm_vm_is_protected(kvm)); } =20 int kvm_arm_pvtime_set_attr(struct kvm_vcpu *vcpu, @@ -81,8 +81,8 @@ int kvm_arm_pvtime_set_attr(struct kvm_vcpu *vcpu, int ret =3D 0; int idx; =20 - if (!kvm_arm_pvtime_supported() || - attr->attr !=3D KVM_ARM_VCPU_PVTIME_IPA) + if (!kvm_arm_pvtime_supported(kvm) || + (attr->attr !=3D KVM_ARM_VCPU_PVTIME_IPA)) return -ENXIO; =20 if (get_user(ipa, user)) @@ -110,8 +110,8 @@ int kvm_arm_pvtime_get_attr(struct kvm_vcpu *vcpu, u64 __user *user =3D (u64 __user *)attr->addr; u64 ipa; =20 - if (!kvm_arm_pvtime_supported() || - attr->attr !=3D KVM_ARM_VCPU_PVTIME_IPA) + if (!kvm_arm_pvtime_supported(vcpu->kvm) || + (attr->attr !=3D KVM_ARM_VCPU_PVTIME_IPA)) return -ENXIO; =20 ipa =3D vcpu->arch.steal.base; @@ -126,7 +126,7 @@ int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu, { switch (attr->attr) { case KVM_ARM_VCPU_PVTIME_IPA: - if (kvm_arm_pvtime_supported()) + if (kvm_arm_pvtime_supported(vcpu->kvm)) return 0; } return -ENXIO; --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7FC6B426690; Tue, 15 Sep 2026 16:02:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488125; cv=none; b=u4mD19KJDjQChmHO2WzFgyI3Wc8wUj9b6Vf6B6sKWiCgjwtAULo6HUYmfQD1bshBUZzpRZ/fLhN28sa52jgI4D2Zp3Xt0HuPsKjNkpBuulMDOQpV36dXMgu83Ix3CJ8dxQZG8kOAB0V6BoUhcMVwltZOgPvwIdQ3C2hF7+zPlmE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488125; c=relaxed/simple; bh=8q9Rt/6mKLCfGe51uszKwi9iQrDRjaKLQZ+w4aPQW+c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=mLZcLoLOQoIlvQHvOz9UtDd3B4y2LV7TKWURvaGx3TLnCDvxwHe8fLGS+eKgLL0CTrumQBrDrMHVPJ0MOmQm1E6S9+PFQu3X7i5Sobt8EGorimADxfA6+9bfPIzV5v1ZyacyCVWCHZHPcXyqH9ssmGEQniVR5s9a8KS97d0mYi8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=nWbCCXse; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="nWbCCXse" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 72D53152B; Tue, 15 Sep 2026 09:01:58 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 365CA3F882; Tue, 15 Sep 2026 09:01:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488122; bh=8q9Rt/6mKLCfGe51uszKwi9iQrDRjaKLQZ+w4aPQW+c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nWbCCXsekbvTzwlFx/cCmPDi5S4a8fhGYI0dkfmWehsZtzCGn3bOI4RYcII0fMzGj Zlug/OpEpuJCmqxMH1VSwQh79dJapavF/xLh69AC4X3d+SoTEUZK700VxuFSm9iRhP tawEVg1kb81AP4bo1IX5ae463LenViZx8OMoLrSA= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose , Fuad Tabba Subject: [PATCH v18 03/23] KVM: arm64: Include kvm_emulate.h in kvm/arm_psci.h Date: Tue, 15 Sep 2026 17:01:21 +0100 Message-ID: <20260915160141.3543048-4-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Fix a potential build error (like below, when asm/kvm_emulate.h gets included after the kvm/arm_psci.h) by including the missing header file in kvm/arm_psci.h: ./include/kvm/arm_psci.h: In function =E2=80=98kvm_psci_version=E2=80=99: ./include/kvm/arm_psci.h:29:13: error: implicit declaration of function =E2=80=98vcpu_has_feature=E2=80=99; did you mean =E2=80=98cpu_have_featu= re=E2=80=99? [-Werror=3Dimplicit-function-declaration] 29 | if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2)) { | ^~~~~~~~~~~~~~~~ | cpu_have_feature Reviewed-by: Gavin Shan Reviewed-by: Fuad Tabba Signed-off-by: Suzuki K Poulose --- include/kvm/arm_psci.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h index f86a006d67136..06c20612e9e7d 100644 --- a/include/kvm/arm_psci.h +++ b/include/kvm/arm_psci.h @@ -10,6 +10,8 @@ #include #include =20 +#include + #define KVM_ARM_PSCI_0_1 PSCI_VERSION(0, 1) #define KVM_ARM_PSCI_0_2 PSCI_VERSION(0, 2) #define KVM_ARM_PSCI_1_0 PSCI_VERSION(1, 0) --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CD06C4AA02E; Tue, 15 Sep 2026 16:02:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488128; cv=none; b=CB8hAXaKqJ0MRrdPfFJ7qfRCtF7JmvV86zBSEWupzNDlb8mlVb8rQkbQ23RAhjRq3DlGI8vDSWXebCwKcr9B2AVgzrSRPiOeD2hj7FewuxfEj6HNCZGKEkkULUIIRXKU9I5gZ20GbHpNGE3KvxI+dHnKr0aoGBPEzpU1yoAU6S4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488128; c=relaxed/simple; bh=9i06HhoyM7DumxjGYoPgI8El9s/cOdUwPNulQZnoz6U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WGHoJkMpyeX8VHSEGPu5Voo5IzbgOUDgTAaIGWtvzof/oj/T9rz8WS2I2rsWgKxP9GGq3GVCy0824aFxRvlW/A7yPwx+uYUvCECKXw0JUIGW1O7SY3uLc37pQc8M2tdWa9rW3zjHvOFL7DKiF+sW4blBuQtFOZg7mfQUYpH6H+I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=Px8dinwi; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="Px8dinwi" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8697A15A1; Tue, 15 Sep 2026 09:02:01 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 54D743F882; Tue, 15 Sep 2026 09:02:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488125; bh=9i06HhoyM7DumxjGYoPgI8El9s/cOdUwPNulQZnoz6U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Px8dinwiFlMpfwFzy4vAZgkYLalZ6Ms5ZuXXvu/UsexSs6rYBmhimmiQ/ZFiNYa9H XpHU/+PFKhyDxsex/mvWl6OEn2Pl9pQXrHxIwV8Sgv0lGlnToRrJFV/njmPaJbwNCY p0ZnZZRZZ+jjUONUyV5xNYsZjRG4VWc+O8qqfUQE= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Fuad Tabba , Suzuki K Poulose Subject: [PATCH v18 04/23] KVM: arm64: Avoid including linux/kvm_host.h in kvm_pgtable.h Date: Tue, 15 Sep 2026 17:01:22 +0100 Message-ID: <20260915160141.3543048-5-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Price To avoid future include cycles, drop the linux/kvm_host.h include in kvm_pgtable.h and include the lightweight headers required for the types and inline helpers used there. Additionally provide a forward declaration for struct kvm_s2_mmu as it's only used as a pointer in this file. Both pgtable.c and kvm_pkvm.h relied on the indirect inclusion of kvm_host.h, so make that explicit. Reviewed-by: Fuad Tabba Reviewed-by: Gavin Shan Signed-off-by: Steven Price Signed-off-by: Suzuki K Poulose --- arch/arm64/include/asm/kvm_pgtable.h | 6 +++++- arch/arm64/include/asm/kvm_pkvm.h | 2 +- arch/arm64/kvm/hyp/pgtable.c | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/= kvm_pgtable.h index 41a8687938eb6..c2e4b29e605fc 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -8,9 +8,13 @@ #define __ARM64_KVM_PGTABLE_H__ =20 #include -#include +#include +#include +#include #include =20 +struct kvm_s2_mmu; + #define KVM_PGTABLE_FIRST_LEVEL -1 #define KVM_PGTABLE_LAST_LEVEL 3 =20 diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm= _pkvm.h index beea00e693a0a..54a618d887fa4 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -7,9 +7,9 @@ #define __ARM64_KVM_PKVM_H__ =20 #include +#include #include #include -#include #include =20 /* Maximum number of VMs that can co-exist under pKVM. */ diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index b74dd5ce1efd3..f48253b9d88b5 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -8,6 +8,7 @@ */ =20 #include +#include #include #include =20 --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AFD344B0CA4; Tue, 15 Sep 2026 16:02:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488130; cv=none; b=eSEy9IwZHoGywdPB7yXqr1kgrUW0IPAhQmcS8VwR08Da3umy0VkgOUxEu12q6qc8gtgIfj9qXaY09dvtchxqvhlcoFQ7PZBIcuAOzdeV0RpkKeQUcO/BiGDBOLcS2FyXRjX7bJmNM80AGv3tGeZfx9+wM4MRJ42FYoj26USBF9w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488130; c=relaxed/simple; bh=jG9ihcxiEJTt7tVd2KyBPA5CREP/rxRtBAPkiF4QgJg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m8yF2zbP0/NIs3ZQNuArYaprWseT8kMyHppG+yXbbSrhml97zArVr9zJXiM0YdRMBsbmLxe/4i0dg9GevQnqogsNWkURFK4lU2pXIsE9KSnvqdGAnf265Vq3Uw4coEHCEdzhH8wW7BetlbDqL2NpkHufXQ0HaorbGJEUNPd/J+w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=CTVCxqCp; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="CTVCxqCp" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9D7C91570; Tue, 15 Sep 2026 09:02:04 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 6B2F63F882; Tue, 15 Sep 2026 09:02:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488128; bh=jG9ihcxiEJTt7tVd2KyBPA5CREP/rxRtBAPkiF4QgJg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CTVCxqCpkgfesirYjDxLbvAxgs0+ftv7Bx8zVL9k11e6M5M8hJbtkdj4pyglAjjd5 eYGmGau1EcL7TTaBOmNFHnBDkV4ThR95WTnkw8NrGPo0VExydt0aBgx27F7gTPgayx GV6K+aoIop/KEI27gKobUkvPGjzLWOAhMe/gyXik= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose , Fuad Tabba Subject: [PATCH v18 05/23] KVM: arm64: Track the type of VM in kvm_arch Date: Tue, 15 Sep 2026 17:01:23 +0100 Message-ID: <20260915160141.3543048-6-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" KVM arm64 has different types of VMs with all the different modes in which = the hypervisor code can be run. e.g., VHE, nVHE, PKVM etc. Then there is protec= ted VM and normal VMs with PKVM. We might soon add other types, e.g., Arm CCA R= ealm. So in an effort to make the handling of these different types of VMs a bit = more friendly to the eyes, add a VM flavor to the kvm_arch and we could then add handlers for different operations based on the VM type. Keep the flavor initialisation at the beginning to allow for the detection early enough and fail out on any unsupported requests. (e.g., protected on = !pKVM) With that, use the vm_flavor to detect if a VM is protected VM on PKVM. A l= ater patch would generalize the "protected" VM predicate to cater for all confidential compute VMs. Based on a patch by Marc Zyngier Suggested-by: Marc Zyngier Reviewed-by: Fuad Tabba Signed-off-by: Suzuki K Poulose --- Changes since v17: * s/PKVM/pKVM for the comments * Drop type argument for pkvm_init_host_vm and also drop protected variabl= e. * Add helpers for checking if the VM is running on pKVM (kvm_vm_hyp_is_pkv= m()) * Use kvm_vm_hyp_is_pkvm() to replace is_protected_kvm_enabled() with valid kvm instance --- arch/arm64/include/asm/kvm_host.h | 14 +++++++++++-- arch/arm64/include/asm/kvm_pkvm.h | 2 +- arch/arm64/kvm/arm.c | 35 ++++++++++++++++++++++++------- arch/arm64/kvm/hyp/nvhe/pkvm.c | 2 +- arch/arm64/kvm/pkvm.c | 6 ++---- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 286489a69dff5..39d04ff702bc1 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -257,7 +257,6 @@ struct kvm_protected_vm { pkvm_handle_t handle; struct kvm_hyp_memcache teardown_mc; struct kvm_hyp_memcache stage2_teardown_mc; - bool is_protected; bool is_created; =20 /* @@ -306,9 +305,18 @@ enum fgt_group_id { __NR_FGT_GROUP_IDS__ }; =20 +enum kvm_arm_vm_flavor { + VM_NVHE, + VM_VHE, + VM_PKVM, /* Normal guests on pKVM */ + VM_PROTECTED_PKVM, /* Protected VM */ + VM_FLAVOR_MAX, +}; + struct kvm_arch { struct kvm_s2_mmu mmu; =20 + enum kvm_arm_vm_flavor vm_flavor; /* * Fine-Grained UNDEF, mimicking the FGT layout defined by the * architecture. We track them globally, as we present the @@ -1504,8 +1512,10 @@ struct kvm *kvm_arch_alloc_vm(void); =20 #define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE =20 -#define kvm_vm_is_protected(kvm) (is_protected_kvm_enabled() && (kvm)->arc= h.pkvm.is_protected) +#define kvm_vm_is_protected(kvm) ((kvm)->arch.vm_flavor =3D=3D VM_PROTECTE= D_PKVM) +#define kvm_vm_is_unprotected_pkvm(kvm) ((kvm)->arch.vm_flavor =3D=3D VM_P= KVM) =20 +#define kvm_vm_hyp_is_pkvm(kvm) (is_protected_kvm_enabled()) #define vcpu_is_protected(vcpu) kvm_vm_is_protected((vcpu)->kvm) =20 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature); diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm= _pkvm.h index 54a618d887fa4..a1f3e05e75dc1 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -17,7 +17,7 @@ =20 #define HYP_MEMBLOCK_REGIONS 128 =20 -int pkvm_init_host_vm(struct kvm *kvm, unsigned long type); +int pkvm_init_host_vm(struct kvm *kvm); int pkvm_create_hyp_vm(struct kvm *kvm); bool pkvm_hyp_vm_is_created(struct kvm *kvm); void pkvm_destroy_hyp_vm(struct kvm *kvm); diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 3fbdfce926475..4329c49fe49da 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -228,6 +228,26 @@ static void kvm_arch_fix_timer_offsets(struct kvm *kvm) set_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &kvm->arch.flags); } =20 +static int kvm_init_vm_flavor(struct kvm *kvm, unsigned long type) +{ + bool protected =3D type & KVM_VM_TYPE_ARM_PROTECTED; + + if (is_protected_kvm_enabled()) { + if (protected) + kvm->arch.vm_flavor =3D VM_PROTECTED_PKVM; + else + kvm->arch.vm_flavor =3D VM_PKVM; + } else if (protected) { + return -EINVAL; + } else if (has_vhe()) { + kvm->arch.vm_flavor =3D VM_VHE; + } else { + kvm->arch.vm_flavor =3D VM_NVHE; + } + + return 0; +} + /** * kvm_arch_init_vm - initializes a VM data structure * @kvm: pointer to the KVM struct @@ -250,6 +270,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long ty= pe) mutex_unlock(&kvm->lock); #endif =20 + ret =3D kvm_init_vm_flavor(kvm, type); + if (ret) + return ret; + kvm_init_nested(kvm); =20 ret =3D kvm_share_hyp(kvm, kvm + 1); @@ -266,17 +290,14 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long t= ype) if (ret) goto err_free_cpumask; =20 - if (is_protected_kvm_enabled()) { + if (kvm_vm_hyp_is_pkvm(kvm)) { /* * If any failures occur after this is successful, make sure to * call __pkvm_unreserve_vm to unreserve the VM in hyp. */ - ret =3D pkvm_init_host_vm(kvm, type); + ret =3D pkvm_init_host_vm(kvm); if (ret) goto err_uninit_mmu; - } else if (type & KVM_VM_TYPE_ARM_PROTECTED) { - ret =3D -EINVAL; - goto err_uninit_mmu; } =20 kvm_vgic_early_init(kvm); @@ -341,7 +362,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) =20 kvm_vgic_destroy(kvm); =20 - if (is_protected_kvm_enabled()) + if (kvm_vm_hyp_is_pkvm(kvm)) pkvm_destroy_hyp_vm(kvm); =20 kvm_uninit_stage2_mmu(kvm); @@ -603,7 +624,7 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) =20 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) { - if (!is_protected_kvm_enabled()) + if (!kvm_vm_hyp_is_pkvm(vcpu->kvm)) kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache); else free_hyp_memcache(&vcpu->arch.pkvm_memcache); diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index e7b38eff63bd1..9b69228f8402c 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -432,7 +432,7 @@ static void init_pkvm_hyp_vm(struct kvm *host_kvm, stru= ct pkvm_hyp_vm *hyp_vm, =20 hyp_vm->host_kvm =3D host_kvm; hyp_vm->kvm.created_vcpus =3D nr_vcpus; - hyp_vm->kvm.arch.pkvm.is_protected =3D READ_ONCE(host_kvm->arch.pkvm.is_p= rotected); + hyp_vm->kvm.arch.vm_flavor =3D READ_ONCE(host_kvm->arch.vm_flavor); hyp_vm->kvm.arch.flags =3D 0; pkvm_init_features_from_host(hyp_vm, host_kvm); =20 diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 8e4c6e4bec123..8e9176a700926 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -229,10 +229,9 @@ void pkvm_destroy_hyp_vm(struct kvm *kvm) mutex_unlock(&kvm->arch.config_lock); } =20 -int pkvm_init_host_vm(struct kvm *kvm, unsigned long type) +int pkvm_init_host_vm(struct kvm *kvm) { int ret; - bool protected =3D type & KVM_VM_TYPE_ARM_PROTECTED; =20 /* Reserve the VM in hyp and obtain a hyp handle for the VM. */ ret =3D kvm_call_hyp_nvhe(__pkvm_reserve_vm); @@ -240,8 +239,7 @@ int pkvm_init_host_vm(struct kvm *kvm, unsigned long ty= pe) return ret; =20 kvm->arch.pkvm.handle =3D ret; - kvm->arch.pkvm.is_protected =3D protected; - if (protected) { + if (kvm_vm_is_protected(kvm)) { pr_warn_once("kvm: protected VMs are experimental and for development on= ly, tainting kernel\n"); add_taint(TAINT_USER, LOCKDEP_STILL_OK); } --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5634641BA9B; Tue, 15 Sep 2026 16:02:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488134; cv=none; b=KXK3iYIiGt6GHcrWcJwx3rUEQc4nBufW9TzF/RHDeSdHMox/VL5stOGDaqmK48U4eIfIExQsLoXH54W78c7traLHJRTh7btCRDIWas3bD+ffoA3wM5v4eEA6pPhxSTKQ5k/LopeKc0pW4AmGGYi7AkNB3AhhCIL4g6qC3JUwVEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488134; c=relaxed/simple; bh=zo4tJn5ox5A1ElY6+qRKFeOLEDLTQwomQpoDrxj91Sg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QakPenG6fAyvQinxyCsimK13dsnYr92i+GJNVgWL0R3TCWaoZ729WvYLadxF+BEuKqEJKzVyBE1QOtNoF7r84ATqtpMQVZQw/QWu3hVc3QYIm5gGyJ0lPv5GB7a1cXDsiJMLH9us+m4INZwtA0ZLvp+YcHJRbldRLZXxCsTm/0U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=VhLRZwKy; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="VhLRZwKy" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9558115A1; Tue, 15 Sep 2026 09:02:07 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7FBFD3F882; Tue, 15 Sep 2026 09:02:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488131; bh=zo4tJn5ox5A1ElY6+qRKFeOLEDLTQwomQpoDrxj91Sg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VhLRZwKyzrrrdFfmbtBvNtfquscw9Vbmta+5/5OSPXsje/hBUmYzXHq23c7Vx6L2/ V8fDVh/eMMphkIXCzk4Ck56jLhf2T2uT81pRtVOQywXCGJqMbNqN/TRVqjSgIv4feC IgVy+0gdZrz1675ZQvhHyOdMfcs15zUOYZbQxyz0= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 06/23] KVM: arm64: Refactor the vcpu_load to allow for VM specific callbacks Date: Tue, 15 Sep 2026 17:01:24 +0100 Message-ID: <20260915160141.3543048-7-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Based on a work by Marc Zyngier To keep the VCPU load/put handling cleaner with the different kinds of VM t= ypes, we are about to introduce VM specific callbacks to do just the right thing. In preparation for that, make some refactoring to add the change easier. No functional changes intended. Reviewed-by: Gavin Shan Signed-off-by: Suzuki K Poulose --- arch/arm64/kvm/arm.c | 48 ++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 4329c49fe49da..8f94323f2968b 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -698,14 +698,11 @@ static bool kvm_vcpu_should_clear_twe(struct kvm_vcpu= *vcpu) return single_task_running(); } =20 -void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +static void vcpu_prepare_mmu(struct kvm_vcpu *vcpu) { struct kvm_s2_mmu *mmu; int *last_ran; =20 - if (is_protected_kvm_enabled()) - goto nommu; - if (vcpu_has_nv(vcpu)) kvm_vcpu_load_hw_mmu(vcpu); =20 @@ -735,10 +732,33 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cp= u) kvm_call_hyp(__kvm_flush_cpu_context, mmu); *last_ran =3D vcpu->vcpu_idx; } +} + +static void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu) +{ + if (kvm_vcpu_should_clear_twe(vcpu)) + vcpu->arch.hcr_el2 &=3D ~HCR_TWE; + else + vcpu->arch.hcr_el2 |=3D HCR_TWE; + + if (kvm_vcpu_should_clear_twi(vcpu)) + vcpu->arch.hcr_el2 &=3D ~HCR_TWI; + else + vcpu->arch.hcr_el2 |=3D HCR_TWI; +} + +static void vcpu_load_pvtime(struct kvm_vcpu *vcpu) +{ + if (kvm_arm_is_pvtime_enabled(&vcpu->arch)) + kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu); +} + +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + if (!is_protected_kvm_enabled()) + vcpu_prepare_mmu(vcpu); =20 -nommu: vcpu->cpu =3D cpu; - /* * The timer must be loaded before the vgic to correctly set up physical * interrupt deactivation in nested state (e.g. timer interrupt). @@ -751,19 +771,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvm_vcpu_load_vhe(vcpu); kvm_arch_vcpu_load_fp(vcpu); kvm_vcpu_pmu_restore_guest(vcpu); - if (kvm_arm_is_pvtime_enabled(&vcpu->arch)) - kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu); - - if (kvm_vcpu_should_clear_twe(vcpu)) - vcpu->arch.hcr_el2 &=3D ~HCR_TWE; - else - vcpu->arch.hcr_el2 |=3D HCR_TWE; - - if (kvm_vcpu_should_clear_twi(vcpu)) - vcpu->arch.hcr_el2 &=3D ~HCR_TWI; - else - vcpu->arch.hcr_el2 |=3D HCR_TWI; =20 + vcpu_load_pvtime(vcpu); + vcpu_set_wfx_traps(vcpu); vcpu_set_pauth_traps(vcpu); =20 if (is_protected_kvm_enabled()) { @@ -787,7 +797,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) kvm_call_hyp_nvhe(__pkvm_vcpu_put); =20 /* __pkvm_vcpu_put implies a sync of the state */ - if (!kvm_vm_is_protected(vcpu->kvm)) + if (kvm_vm_is_unprotected_pkvm(vcpu->kvm)) vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY); } =20 --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BAAFF4BA1D7; Tue, 15 Sep 2026 16:02:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488137; cv=none; b=fZAb5ekHs/tPXHF7aX6MVIiWnFmdfuIhw9DfiEnwanlKUE9x0uEKi5DM8G+L7mebBfRoJbTAR1cIPTIzpky8ujXEnd0OyhIlmKc5jhBPeCHS6e7xGFLRbgWtm7cc8AzmE2PiOlnRrrBjxh3EyS3Giii+aYi7ZhKWKAlq8P3+iTI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488137; c=relaxed/simple; bh=rnSoh9E2OmKCg6UmHNYVKd/aiask+GcwgyAqOYOiCBY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=We0bRLRNeYukEmFjm7QXl9TIw3O7oQM+XSHM3WlOmhUZDeqHmOpqPaC/IXJUGzH/2D1goZjLoMdQYBWApmkozYgBQ4r2Q53aHVB3Ev+ov3om+6mhgX2PPn62TMp4iiR5Hg6oLShu25AIHwmry4Y65pVVsxE62pm2qSGu16nbdF8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=J7EKMuSM; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="J7EKMuSM" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 933D41BF3; Tue, 15 Sep 2026 09:02:10 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7B6153F882; Tue, 15 Sep 2026 09:02:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488134; bh=rnSoh9E2OmKCg6UmHNYVKd/aiask+GcwgyAqOYOiCBY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J7EKMuSMjXYDb9wpZewkqXK/8snKxxW8CmMd9H7KPFUJ+ICMAPD4VllNhdfl+qwlI iTNhNmunThDrBRixIeQwp+OdaimYyFm3kwSg+igWVwrZ+FldmBqG6mK9e4sgO4JZv8 dmVsfj57DtZaOThBJ2Jczq5L/vt/UoTVNKS+mEtM= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 07/23] KVM: arm64: Add vcpu load/put call backs for flavors Date: Tue, 15 Sep 2026 17:01:25 +0100 Message-ID: <20260915160141.3543048-8-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add VM flavor specific handlers for VCPU load/put, in an effort to make it easier to follow the code. pauth traps were removed from VMs running PKVM as it is a no-op for them. Based on a patch by Marc Zyngier Suggested-by: Marc Zyngier Signed-off-by: Suzuki K Poulose --- Changes since v17: - Use macro to initialize the per-flavor ops - Add a wrapper to initialise ops in the vcpu structure. - Add BUILD_BUG_ON for the array size - Remove irrelevant comment about the order of timer loading for !VHE - Use the explicti kvm_call_hyp_nvhe for nVHE flavor - Don't call nvhe_vcpu_put from pkvm_vcpu_put, open code them - Drop cpu argument for vcpu_load() callback. We set the cpu before the callbacks are invoked --- arch/arm64/include/asm/kvm_host.h | 6 ++ arch/arm64/kvm/arm.c | 134 ++++++++++++++++++++++++------ 2 files changed, 114 insertions(+), 26 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 39d04ff702bc1..8601103717643 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -150,6 +150,11 @@ struct kvm_vmid { atomic64_t id; }; =20 +struct kvm_vcpu_ops { + void (*vcpu_load)(struct kvm_vcpu *vcpu); + void (*vcpu_put)(struct kvm_vcpu *vcpu); +}; + struct kvm_s2_mmu { struct kvm_vmid vmid; =20 @@ -854,6 +859,7 @@ struct vncr_tlb; =20 struct kvm_vcpu_arch { struct kvm_cpu_context ctxt; + const struct kvm_vcpu_ops *vcpu_ops; =20 /* * Guest floating point state diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 8f94323f2968b..36bd1c6c04899 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -93,6 +93,7 @@ static const struct kvm_ioctl_cap_map vm_ioctl_caps[] =3D= { { KVM_ARM_PREFERRED_TARGET, KVM_CAP_ARM_BASIC }, }; =20 +static void kvm_init_vcpu_ops(struct kvm_vcpu *vcpu); /* * Set *ext to the capability. * Return 0 if found, or -EINVAL if no IOCTL matches. @@ -584,6 +585,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) mutex_unlock(&vcpu->mutex); #endif =20 + kvm_init_vcpu_ops(vcpu); + /* Force users to call KVM_ARM_VCPU_INIT */ vcpu_clear_flag(vcpu, VCPU_INITIALIZED); =20 @@ -753,12 +756,9 @@ static void vcpu_load_pvtime(struct kvm_vcpu *vcpu) kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu); } =20 -void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +static void vhe_vcpu_load(struct kvm_vcpu *vcpu) { - if (!is_protected_kvm_enabled()) - vcpu_prepare_mmu(vcpu); - - vcpu->cpu =3D cpu; + vcpu_prepare_mmu(vcpu); /* * The timer must be loaded before the vgic to correctly set up physical * interrupt deactivation in nested state (e.g. timer interrupt). @@ -767,22 +767,53 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cp= u) kvm_vgic_load(vcpu); kvm_vcpu_load_debug(vcpu); kvm_vcpu_load_fgt(vcpu); - if (has_vhe()) - kvm_vcpu_load_vhe(vcpu); + kvm_vcpu_load_vhe(vcpu); kvm_arch_vcpu_load_fp(vcpu); kvm_vcpu_pmu_restore_guest(vcpu); =20 vcpu_load_pvtime(vcpu); vcpu_set_wfx_traps(vcpu); vcpu_set_pauth_traps(vcpu); +} =20 - if (is_protected_kvm_enabled()) { - kvm_call_hyp_nvhe(__pkvm_vcpu_load, - vcpu->kvm->arch.pkvm.handle, - vcpu->vcpu_idx, vcpu->arch.hcr_el2); - kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, - &vcpu->arch.vgic_cpu.vgic_v3); - } +static void nvhe_vcpu_load(struct kvm_vcpu *vcpu) +{ + vcpu_prepare_mmu(vcpu); + kvm_timer_vcpu_load(vcpu); + kvm_vgic_load(vcpu); + kvm_vcpu_load_debug(vcpu); + kvm_vcpu_load_fgt(vcpu); + kvm_arch_vcpu_load_fp(vcpu); + kvm_vcpu_pmu_restore_guest(vcpu); + + vcpu_load_pvtime(vcpu); + vcpu_set_wfx_traps(vcpu); + vcpu_set_pauth_traps(vcpu); +} + +static void pkvm_vcpu_load(struct kvm_vcpu *vcpu) +{ + kvm_timer_vcpu_load(vcpu); + kvm_vgic_load(vcpu); + kvm_vcpu_load_debug(vcpu); + kvm_vcpu_load_fgt(vcpu); + kvm_arch_vcpu_load_fp(vcpu); + kvm_vcpu_pmu_restore_guest(vcpu); + + vcpu_load_pvtime(vcpu); + vcpu_set_wfx_traps(vcpu); + + kvm_call_hyp_nvhe(__pkvm_vcpu_load, + vcpu->kvm->arch.pkvm.handle, + vcpu->vcpu_idx, vcpu->arch.hcr_el2); + kvm_call_hyp_nvhe(__vgic_v3_restore_vmcr_aprs, + &vcpu->arch.vgic_cpu.vgic_v3); +} + +void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +{ + vcpu->cpu =3D cpu; + vcpu->arch.vcpu_ops->vcpu_load(vcpu); =20 if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus)) vcpu_set_on_unsupported_cpu(vcpu); @@ -790,28 +821,48 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cp= u) vcpu->arch.pid =3D pid_nr(vcpu->pid); } =20 -void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) +static void vhe_vcpu_put(struct kvm_vcpu *vcpu) { - if (is_protected_kvm_enabled()) { - kvm_call_hyp(__vgic_v3_save_aprs, &vcpu->arch.vgic_cpu.vgic_v3); - kvm_call_hyp_nvhe(__pkvm_vcpu_put); - - /* __pkvm_vcpu_put implies a sync of the state */ - if (kvm_vm_is_unprotected_pkvm(vcpu->kvm)) - vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY); - } - kvm_vcpu_put_debug(vcpu); kvm_arch_vcpu_put_fp(vcpu); - if (has_vhe()) - kvm_vcpu_put_vhe(vcpu); + kvm_vcpu_put_vhe(vcpu); kvm_timer_vcpu_put(vcpu); kvm_vgic_put(vcpu); kvm_vcpu_pmu_restore_host(vcpu); if (vcpu_has_nv(vcpu)) kvm_vcpu_put_hw_mmu(vcpu); kvm_arm_vmid_clear_active(); +} =20 +static void nvhe_vcpu_put(struct kvm_vcpu *vcpu) +{ + kvm_vcpu_put_debug(vcpu); + kvm_arch_vcpu_put_fp(vcpu); + kvm_timer_vcpu_put(vcpu); + kvm_vgic_put(vcpu); + kvm_vcpu_pmu_restore_host(vcpu); + kvm_arm_vmid_clear_active(); +} + +static void pkvm_vcpu_put(struct kvm_vcpu *vcpu) +{ + kvm_call_hyp_nvhe(__vgic_v3_save_aprs, &vcpu->arch.vgic_cpu.vgic_v3); + kvm_call_hyp_nvhe(__pkvm_vcpu_put); + + /* __pkvm_vcpu_put implies a sync of the state */ + if (kvm_vm_is_unprotected_pkvm(vcpu->kvm)) + vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY); + + kvm_vcpu_put_debug(vcpu); + kvm_arch_vcpu_put_fp(vcpu); + kvm_timer_vcpu_put(vcpu); + kvm_vgic_put(vcpu); + kvm_vcpu_pmu_restore_host(vcpu); +} + +void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) +{ + vcpu->arch.vcpu_ops->vcpu_put(vcpu); vcpu_clear_on_unsupported_cpu(vcpu); vcpu->cpu =3D -1; } @@ -2151,6 +2202,37 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned in= t ioctl, unsigned long arg) } } =20 +static const struct kvm_vcpu_ops vhe_vcpu_ops =3D { + .vcpu_load =3D vhe_vcpu_load, + .vcpu_put =3D vhe_vcpu_put, +}; + +static const struct kvm_vcpu_ops nvhe_vcpu_ops =3D { + .vcpu_load =3D nvhe_vcpu_load, + .vcpu_put =3D nvhe_vcpu_put, +}; + +static const struct kvm_vcpu_ops pkvm_vcpu_ops =3D { + .vcpu_load =3D pkvm_vcpu_load, + .vcpu_put =3D pkvm_vcpu_put, +}; + +#define KVM_VCPU_OPS(flavor, ops) \ + [(flavor)] =3D (ops) + +static const struct kvm_vcpu_ops *arm64_vcpu_ops[] =3D { + KVM_VCPU_OPS(VM_VHE, &vhe_vcpu_ops), + KVM_VCPU_OPS(VM_NVHE, &nvhe_vcpu_ops), + KVM_VCPU_OPS(VM_PKVM, &pkvm_vcpu_ops), + KVM_VCPU_OPS(VM_PROTECTED_PKVM, &pkvm_vcpu_ops), +}; + +static void kvm_init_vcpu_ops(struct kvm_vcpu *vcpu) +{ + BUILD_BUG_ON(ARRAY_SIZE(arm64_vcpu_ops) !=3D VM_FLAVOR_MAX); + vcpu->arch.vcpu_ops =3D arm64_vcpu_ops[vcpu->kvm->arch.vm_flavor]; +} + static unsigned long nvhe_percpu_size(void) { return (unsigned long)CHOOSE_NVHE_SYM(__per_cpu_end) - --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 185084BB290; Tue, 15 Sep 2026 16:02:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488139; cv=none; b=T6bX6/UEDzwbxGOikdla1C8//C9z+HOILEMEFVKZb9jZCXrbk07YPKTJE2UZrwxPFvaQMzUlrtyT4qItsXPBFtaXHXoigNEYmjuco4VLT06NpB6Kjx65/6SJ4gEK6NGYBZhNwKvBmJq3ylLkfWqD06f6f6dOeXTrWxkSHTqyZRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488139; c=relaxed/simple; bh=S6IyfG0PUTG/ytKANeJCPt5NHSFJT2oomQgiRFIezP8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Jjg3jDG1Wy4c/vQSQed2TcTRokcG9dWQGqfcvB3NniIG+lcRGc/7/L/oslqBZIH9XxprzrUhsKmPotQ1mVgBHfdC4aQbO0LF3DJTynqjT+xyg4zr1XJObx3uZtsRxJSAnEAaIaFF/k3QF37kJ41bF2zTwHI7LO8oqBwdgr2ErSQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=bgJ//Kon; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="bgJ//Kon" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A85F41570; Tue, 15 Sep 2026 09:02:13 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 770603F882; Tue, 15 Sep 2026 09:02:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488137; bh=S6IyfG0PUTG/ytKANeJCPt5NHSFJT2oomQgiRFIezP8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bgJ//Kon3t61Mrl/V7xvaP154UeBjT1eg6R24BOXhSatgdRHXhqKtGneCh5ZS6quz S5W3aqfR6LhTI7dgv5HDhyS2emlh41WEcqhpjxyPFAhpXPDdhCEkNJLoZey81dnU02 9ENk2ZKlR85IYxVz7R+PG7ap+Di2g8uiS+DqHjSE= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose , Fuad Tabba Subject: [PATCH v18 08/23] KVM: arm64: Reuse kvm_stage2_unmap_range in kvm_unmap_gfn_range Date: Tue, 15 Sep 2026 17:01:26 +0100 Message-ID: <20260915160141.3543048-9-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for adding VM specific backends for stage2 operation, switch to kvm_stage2_unmap_range() instead of __unmap_stage2_range() from the kvm_unmap_gfn_range(). Drop the bail out check for protected VMs and defer that to the one in kvm_stage2_unmap_range(). Later we would replace the logic in kvm_stage2_unmap_range() with VM specific backends. No functional changes intended. Reviewed-by: Fuad Tabba Signed-off-by: Suzuki K Poulose --- arch/arm64/kvm/mmu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 9ba86450fe4af..67852acf7a6f8 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -2436,12 +2436,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) =20 bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) { - if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm)) + if (!kvm->arch.mmu.pgt) return false; =20 - __unmap_stage2_range(&kvm->arch.mmu, range->start << PAGE_SHIFT, - (range->end - range->start) << PAGE_SHIFT, - range->may_block); + kvm_stage2_unmap_range(&kvm->arch.mmu, range->start << PAGE_SHIFT, + (range->end - range->start) << PAGE_SHIFT, + range->may_block); =20 kvm_nested_s2_unmap(kvm, range->may_block); return false; --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 415F04BD0ED; Tue, 15 Sep 2026 16:02:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488145; cv=none; b=kTbGp9vshPlzLQL/NMoLrJrNyeM6nUMqO9igfrRcoO2LXCIzX8hK72Qa5pJwqVCimY7wKKB8tzN9zInxOCGm7HVFDWLMnyBbjBhpSieNl5k+0f4O/tEgF4qhASACjspZ3OsBiRV2Y+vo0e25sWSF0vnUkv4eg4eULTAo9VDhzzU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488145; c=relaxed/simple; bh=3VMx5MwIoQDjnI9Qu/OvOYrvB82xGQiLBVLLsk3Gcx8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FwOed/qKs645HxXPMJdxkDZc+FlfGv3VJbA2ufHyxnhJw6aHN1QaOFiciLhlvLcCm5rqodbPtzPBNDkrcspWctdJZrOXU/Xmv+ZHGrNakQPKW5ON6KXpqpvmvoIE6QmkbvVBs8VWgT5axtkGT+OnTphrMESA+vDhZ14m1B7Cy2c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=DRI2zR/s; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="DRI2zR/s" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A339315A1; Tue, 15 Sep 2026 09:02:16 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8BF253F882; Tue, 15 Sep 2026 09:02:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488140; bh=3VMx5MwIoQDjnI9Qu/OvOYrvB82xGQiLBVLLsk3Gcx8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DRI2zR/sQ3OywYBjEfa4m7sT3HReSjGgyJzGexBbYZDleQIwmFPXMqlmDoJ6xJUaj p1/mMOHS7nQ+bpt7azVo5UigJZT3UVCLXn+MypdoF+UD9nXc53fDfDjWfKleebBR0O yxGQc+1uEyevJQtq7QWD5k1fj+qG36Q38bwM8ENU= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 09/23] KVM: arm64: Add VM specific callback for S2 MMU operations Date: Tue, 15 Sep 2026 17:01:27 +0100 Message-ID: <20260915160141.3543048-10-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add VM type specific S2 MMU operation backends which can be initialized per= VM flavor, to keep the handling cleaner. Realm VM ops will be added gradually. Signed-off-by: Suzuki K Poulose --- arch/arm64/include/asm/kvm_host.h | 15 ++++ arch/arm64/kvm/mmu.c | 137 +++++++++++++++++++++++++----- 2 files changed, 131 insertions(+), 21 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 8601103717643..ad3b34ba0b805 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -155,6 +155,19 @@ struct kvm_vcpu_ops { void (*vcpu_put)(struct kvm_vcpu *vcpu); }; =20 +struct kvm_gfn_range; + +struct kvm_vm_s2_ops { + bool (*vm_age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range); + bool (*vm_test_age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range); + int (*vm_flush_remote_tlbs)(struct kvm *kvm); + int (*vm_flush_remote_tlbs_range)(struct kvm *kvm, gfn_t gfn, + u64 nr_pages); + void (*vm_stage2_unmap_range)(struct kvm_s2_mmu *mmu, + phys_addr_t start, u64 size, + bool may_block); +}; + struct kvm_s2_mmu { struct kvm_vmid vmid; =20 @@ -331,6 +344,8 @@ struct kvm_arch { */ u64 fgu[__NR_FGT_GROUP_IDS__]; =20 + const struct kvm_vm_s2_ops *vm_s2_ops; + /* * Stage 2 paging state for VMs with nested S2 using a virtual * VMID. diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 67852acf7a6f8..3d8b6e5b811ed 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -37,6 +37,8 @@ static unsigned long __ro_after_init io_map_base; =20 #define KVM_PGT_FN(fn) (!is_protected_kvm_enabled() ? fn : p ## fn) =20 +static int kvm_vm_init_vm_s2_ops(struct kvm *kvm); + static phys_addr_t __stage2_range_addr_end(phys_addr_t addr, phys_addr_t e= nd, phys_addr_t size) { @@ -166,6 +168,18 @@ static bool memslot_is_logging(struct kvm_memory_slot = *memslot) return memslot->dirty_bitmap && !(memslot->flags & KVM_MEM_READONLY); } =20 +static int pkvm_flush_remote_tlbs(struct kvm *kvm) +{ + kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle); + return 0; +} + +static int kvm_vm_flush_remote_tlbs(struct kvm *kvm) +{ + kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu); + return 0; +} + /** * kvm_arch_flush_remote_tlbs() - flush all VM TLB entries for v7/8 * @kvm: pointer to kvm structure. @@ -174,26 +188,36 @@ static bool memslot_is_logging(struct kvm_memory_slot= *memslot) */ int kvm_arch_flush_remote_tlbs(struct kvm *kvm) { - if (is_protected_kvm_enabled()) - kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle); - else - kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu); - return 0; + if (!kvm->arch.vm_s2_ops->vm_flush_remote_tlbs) + return 1; + return kvm->arch.vm_s2_ops->vm_flush_remote_tlbs(kvm); } =20 -int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, - gfn_t gfn, u64 nr_pages) +static int pkvm_flush_remote_tlbs_range(struct kvm *kvm, + gfn_t gfn, u64 nr_pages) +{ + return pkvm_flush_remote_tlbs(kvm); +} + +static int kvm_vm_flush_remote_tlbs_range(struct kvm *kvm, + gfn_t gfn, u64 nr_pages) { u64 size =3D nr_pages << PAGE_SHIFT; u64 addr =3D gfn << PAGE_SHIFT; =20 - if (is_protected_kvm_enabled()) - kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle); - else - kvm_tlb_flush_vmid_range(&kvm->arch.mmu, addr, size); + kvm_tlb_flush_vmid_range(&kvm->arch.mmu, addr, size); return 0; } =20 +int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, + gfn_t gfn, u64 nr_pages) +{ + if (!kvm->arch.vm_s2_ops->vm_flush_remote_tlbs_range) + return 1; + + return kvm->arch.vm_s2_ops->vm_flush_remote_tlbs_range(kvm, gfn, nr_pages= ); +} + static void *stage2_memcache_zalloc_page(void *arg) { struct kvm_mmu_memory_cache *mc =3D arg; @@ -337,13 +361,20 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *m= mu, phys_addr_t start, u64 may_block)); } =20 +static void kvm_vm_stage2_unmap_range(struct kvm_s2_mmu *mmu, + phys_addr_t start, + u64 size, bool may_block) +{ + __unmap_stage2_range(mmu, start, size, may_block); +} + void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size, bool may_block) { - if (kvm_vm_is_protected(kvm_s2_mmu_to_kvm(mmu))) - return; + struct kvm *kvm =3D kvm_s2_mmu_to_kvm(mmu); =20 - __unmap_stage2_range(mmu, start, size, may_block); + if (kvm->arch.vm_s2_ops->vm_stage2_unmap_range) + kvm->arch.vm_s2_ops->vm_stage2_unmap_range(mmu, start, size, may_block); } =20 void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys= _addr_t end) @@ -983,6 +1014,12 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s= 2_mmu *mmu, unsigned long t int cpu, err; struct kvm_pgtable *pgt; =20 + /* Initialize the VM ops for the VM instance for the first time */ + if (mmu =3D=3D &kvm->arch.mmu) { + err =3D kvm_vm_init_vm_s2_ops(kvm); + if (err) + return err; + } /* * If we already have our page tables in place, and that the * MMU context is the canonical one, we have a bug somewhere, @@ -2447,34 +2484,46 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kv= m_gfn_range *range) return false; } =20 -bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) +static bool kvm_vm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) { u64 size =3D (range->end - range->start) << PAGE_SHIFT; =20 - if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm)) - return false; - return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt, range->start << PAGE_SHIFT, size, true); +} + +bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) +{ + if (!kvm->arch.mmu.pgt || !kvm->arch.vm_s2_ops->vm_age_gfn) + return false; + + return kvm->arch.vm_s2_ops->vm_age_gfn(kvm, range); /* * TODO: Handle nested_mmu structures here using the reverse mapping in * a later version of patch series. */ } =20 -bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) +static bool kvm_vm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *ran= ge) { u64 size =3D (range->end - range->start) << PAGE_SHIFT; =20 - if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm)) - return false; =20 return KVM_PGT_FN(kvm_pgtable_stage2_test_clear_young)(kvm->arch.mmu.pgt, range->start << PAGE_SHIFT, size, false); } =20 +bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) +{ + + if (!kvm->arch.mmu.pgt || !kvm->arch.vm_s2_ops->vm_test_age_gfn) + return false; + + return kvm->arch.vm_s2_ops->vm_test_age_gfn(kvm, range); +} + phys_addr_t kvm_mmu_get_httbr(void) { return __pa(hyp_pgtable->pgd); @@ -2796,3 +2845,49 @@ void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool wa= s_enabled) =20 trace_kvm_toggle_cache(*vcpu_pc(vcpu), was_enabled, now_enabled); } + +static const struct kvm_vm_s2_ops protected_pkvm_vm_s2_ops =3D { + .vm_flush_remote_tlbs =3D pkvm_flush_remote_tlbs, + .vm_flush_remote_tlbs_range =3D pkvm_flush_remote_tlbs_range, + /* + * Not supported for Protected VMs under pKVM + * .vm_age_gfn + * .vm_test_age_gfn + * .vm_stage2_unmap_range + */ +}; + +static const struct kvm_vm_s2_ops pkvm_vm_s2_ops =3D { + .vm_flush_remote_tlbs =3D pkvm_flush_remote_tlbs, + .vm_flush_remote_tlbs_range =3D pkvm_flush_remote_tlbs_range, + .vm_age_gfn =3D kvm_vm_age_gfn, + .vm_test_age_gfn =3D kvm_vm_test_age_gfn, + .vm_stage2_unmap_range =3D kvm_vm_stage2_unmap_range, +}; + +static const struct kvm_vm_s2_ops kvm_default_vm_s2_ops =3D { + .vm_flush_remote_tlbs =3D kvm_vm_flush_remote_tlbs, + .vm_flush_remote_tlbs_range =3D kvm_vm_flush_remote_tlbs_range, + .vm_age_gfn =3D kvm_vm_age_gfn, + .vm_test_age_gfn =3D kvm_vm_test_age_gfn, + .vm_stage2_unmap_range =3D kvm_vm_stage2_unmap_range, +}; + +#define KVM_VM_S2_OPS(flavor, ops) \ + [flavor] =3D ops +static const struct kvm_vm_s2_ops *arm64_vm_s2_ops[] =3D { + KVM_VM_S2_OPS(VM_VHE, &kvm_default_vm_s2_ops), + KVM_VM_S2_OPS(VM_NVHE, &kvm_default_vm_s2_ops), + KVM_VM_S2_OPS(VM_PKVM, &pkvm_vm_s2_ops), + KVM_VM_S2_OPS(VM_PROTECTED_PKVM, &protected_pkvm_vm_s2_ops), +}; + +static int kvm_vm_init_vm_s2_ops(struct kvm *kvm) +{ + BUILD_BUG_ON(ARRAY_SIZE(arm64_vm_s2_ops) !=3D VM_FLAVOR_MAX); + + kvm->arch.vm_s2_ops =3D arm64_vm_s2_ops[kvm->arch.vm_flavor]; + if (WARN_ON(!kvm->arch.vm_s2_ops)) + return -EINVAL; + return 0; +} --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BAC354BD78D; Tue, 15 Sep 2026 16:02:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488145; cv=none; b=tzu9tbsq+Ch5FNg7svzU9HL/Z4NB1LxWKs1Vj+yrO8ZZYxkKoX1Y0vC7nEStOgG7Mzmps8tddJ31N++OROXOdne/bB1ApEcx3hOzriveWf0vHgcn9nV9qVFwSxBiwZBTtmkXVmncOsVFwFXQQ7kf0LA0OWCLAJ7MjSAfdP2VeeM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488145; c=relaxed/simple; bh=datF3OC3RosPiHglYYmm7bLuPO/48ROsNh7L6QxULV4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JlkVoCVW7jiZVFN4UQnVZ+Qaplwf1nDx0UD2cTb/eVvysj1USlcAYIl4w73lARt+s54+fCip0xTFAwoLNDl8hgvQyTAQfhLKR7cNpyxHve+7CjV+CHxCpqIzTm0FBePgWIHGkeKyUmzq8p+HCtsHxg6wrHhMu7nFdWgnim708ng= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=tZV7KI6s; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="tZV7KI6s" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9F5D51570; Tue, 15 Sep 2026 09:02:19 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 875953F882; Tue, 15 Sep 2026 09:02:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488143; bh=datF3OC3RosPiHglYYmm7bLuPO/48ROsNh7L6QxULV4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tZV7KI6sh7Jy4XfvXKUfJv/d50esT6k+3jQPDVPk4pGq4fxrnbzOCAoG25fcgKnwt lfOf0hV5nRpsA0AwRE4xNMCrqQKhIYO6qulCXkRZjXuPu5gAv744S4rnEjPRn3UCRJ zjpPn72PlTRpSGC6c2w6fPgbSfvLPF3LgSgHPx4I= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 10/23] KVM: arm64: Abstract out memory abort handling Date: Tue, 15 Sep 2026 17:01:28 +0100 Message-ID: <20260915160141.3543048-11-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move the memory abort handling under VM specific s2 operation. Signed-off-by: Suzuki K Poulose --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/kvm/mmu.c | 36 +++++++++++++++++++------------ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index ad3b34ba0b805..7ce46d853c47e 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -156,6 +156,7 @@ struct kvm_vcpu_ops { }; =20 struct kvm_gfn_range; +struct kvm_s2_fault_desc; =20 struct kvm_vm_s2_ops { bool (*vm_age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range); @@ -166,6 +167,7 @@ struct kvm_vm_s2_ops { void (*vm_stage2_unmap_range)(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size, bool may_block); + int (*vm_mem_abort)(const struct kvm_s2_fault_desc *s2fd); }; =20 struct kvm_s2_mmu { diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 3d8b6e5b811ed..607c908c15c42 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1742,7 +1742,7 @@ struct kvm_s2_fault_vma_info { bool map_non_cacheable; }; =20 -static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd) +static int protected_vm_mem_abort(const struct kvm_s2_fault_desc *s2fd) { unsigned int flags =3D FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE; struct kvm_vcpu *vcpu =3D s2fd->vcpu; @@ -2180,6 +2180,22 @@ static int user_mem_abort(const struct kvm_s2_fault_= desc *s2fd) return kvm_s2_fault_map(s2fd, &s2vi, prot, memcache); } =20 +static int kvm_vm_mem_abort(const struct kvm_s2_fault_desc *s2fd) +{ + int ret; + struct kvm_vcpu *vcpu =3D s2fd->vcpu; + + VM_WARN_ON_ONCE(kvm_vcpu_trap_is_permission_fault(vcpu) && + !kvm_is_write_fault(vcpu) && + !kvm_vcpu_trap_is_exec_fault(vcpu)); + + if (kvm_slot_has_gmem(s2fd->memslot)) + ret =3D gmem_abort(s2fd); + else + ret =3D user_mem_abort(s2fd); + return ret; +} + /* Resolve the access fault by making the page young again. */ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_i= pa) { @@ -2287,6 +2303,7 @@ int kvm_handle_guest_sea(struct kvm_vcpu *vcpu) int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) { struct kvm_s2_trans nested_trans, *nested =3D NULL; + struct kvm *kvm =3D vcpu->kvm; unsigned long esr; phys_addr_t fault_ipa; /* The address we faulted on */ phys_addr_t ipa; /* Always the IPA in the L1 guest phys space */ @@ -2448,19 +2465,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) .hva =3D hva, }; =20 - if (kvm_vm_is_protected(vcpu->kvm)) { - ret =3D pkvm_mem_abort(&s2fd); - } else { - VM_WARN_ON_ONCE(kvm_vcpu_trap_is_permission_fault(vcpu) && - !write_fault && - !kvm_vcpu_trap_is_exec_fault(vcpu)); - - if (kvm_slot_has_gmem(memslot)) - ret =3D gmem_abort(&s2fd); - else - ret =3D user_mem_abort(&s2fd); - } - + ret =3D kvm->arch.vm_s2_ops->vm_mem_abort(&s2fd); if (ret =3D=3D 0) ret =3D 1; out: @@ -2855,6 +2860,7 @@ static const struct kvm_vm_s2_ops protected_pkvm_vm_s= 2_ops =3D { * .vm_test_age_gfn * .vm_stage2_unmap_range */ + .vm_mem_abort =3D protected_vm_mem_abort, }; =20 static const struct kvm_vm_s2_ops pkvm_vm_s2_ops =3D { @@ -2863,6 +2869,7 @@ static const struct kvm_vm_s2_ops pkvm_vm_s2_ops =3D { .vm_age_gfn =3D kvm_vm_age_gfn, .vm_test_age_gfn =3D kvm_vm_test_age_gfn, .vm_stage2_unmap_range =3D kvm_vm_stage2_unmap_range, + .vm_mem_abort =3D kvm_vm_mem_abort, }; =20 static const struct kvm_vm_s2_ops kvm_default_vm_s2_ops =3D { @@ -2871,6 +2878,7 @@ static const struct kvm_vm_s2_ops kvm_default_vm_s2_o= ps =3D { .vm_age_gfn =3D kvm_vm_age_gfn, .vm_test_age_gfn =3D kvm_vm_test_age_gfn, .vm_stage2_unmap_range =3D kvm_vm_stage2_unmap_range, + .vm_mem_abort =3D kvm_vm_mem_abort, }; =20 #define KVM_VM_S2_OPS(flavor, ops) \ --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EE0A84BD7A8; Tue, 15 Sep 2026 16:02:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488149; cv=none; b=etn6LqgH7AxEJss1EGc/kfSzuJyrI8ILwRIbMNZEQtKVzxgLngDBMfWkISyQ7zLh/GTjABfUtOk16kAQdwJL3DQnSOS/d8JwbdT2c48VA2BtW5nZM2Dr91B5yPxYU4hSMXpBFXLeeHkrFF7q6Trgfw8S5h3jEcSoVQ7MBPxYGXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488149; c=relaxed/simple; bh=O20Il//CEz/+ccfyPp5fc/rnwGtdVWyTBiPY+ldH7Bk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LMyBsk65HxPH0Xy+Cog9qV7guTBNJuf7vsiDbFexcB4rUg8GHCvH0NS8nleafGV1uIWCMkl9/TLFm/ojkSKICLwCPAX9kiP7oH1KepUNPL+/QhbImQz2+I/6B70vJLVga65eunQvNAoT3UczhowBB6K+fX4QFRxM2oqFFrhStlw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=XqAo4y5x; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="XqAo4y5x" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9BF6915A1; Tue, 15 Sep 2026 09:02:22 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 82C8D3F882; Tue, 15 Sep 2026 09:02:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488146; bh=O20Il//CEz/+ccfyPp5fc/rnwGtdVWyTBiPY+ldH7Bk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XqAo4y5xDcLPy/SIM1ag+uNsHiVFPkhOybAkt1H7ifo9uJeJ0ZxAIbaflRaCpAqRY t5ePwLFllZ6a7snHTFb1SfpEBlJorXlNCETpp2gF2FvPrMTDhACTrFW/nUDHVySWEk jy5yHQHBYcVfHhitR71wOHtzml+p5kNu6OERGSKk= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 11/23] KVM: arm64: Use kvm_vm_is_unprotected() for !kvm_vm_is_protected() Date: Tue, 15 Sep 2026 17:01:29 +0100 Message-ID: <20260915160141.3543048-12-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that we have a flavor to check, use the helper to explicitly check the type for an unprotected PKVM guest. We don't convert all of the !kvm_vm_is_protected(), but only the ones that target unprotected PKVM guests. Signed-off-by: Suzuki K Poulose --- arch/arm64/include/asm/kvm_pkvm.h | 2 +- arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/handle_exit.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm= _pkvm.h index a1f3e05e75dc1..e4ea80711bec6 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -49,7 +49,7 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, = long ext) case KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES: return false; default: - return !kvm || !kvm_vm_is_protected(kvm); + return !kvm || kvm_vm_is_unprotected_pkvm(kvm); } } =20 diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 36bd1c6c04899..42d9385f5e329 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1082,7 +1082,7 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcp= u) =20 if (is_protected_kvm_enabled()) { /* Start with the vcpu in a dirty state */ - if (!kvm_vm_is_protected(vcpu->kvm)) + if (kvm_vm_is_unprotected_pkvm(vcpu->kvm)) vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY); ret =3D pkvm_create_hyp_vm(kvm); if (ret) diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index db37678dcb05c..384c5d258c7f8 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -490,7 +490,7 @@ static void handle_exit_pkvm_state(struct kvm_vcpu *vcp= u, int exception_index) { int exception_code =3D ARM_EXCEPTION_CODE(exception_index); =20 - if (!is_protected_kvm_enabled() || kvm_vm_is_protected(vcpu->kvm)) + if (!kvm_vm_is_unprotected_pkvm(vcpu->kvm)) return; =20 /* --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2A8154BE444; Tue, 15 Sep 2026 16:02:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488153; cv=none; b=dDRhak0Ttmyy2ri2coXEcRzYyl9XgOLEqc8+jzH87wmKquu9N/3ttuGPpB2Fdboluz2vX5G8rw/l+ubTqsZClTqtZomVqNJsCBzBWje1cZ5gz7JBmyqH/GzGmU/7jXJ25UUYS6jjoffTM7rnz4PzjIuaBObRsm7kCV/Ab3/jQQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488153; c=relaxed/simple; bh=qj0/UumNi5rDv9Vg9CrV5dfdz5rbhLtkWFeMlHj/0ZE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iSdVjSfiqcA2BrwSehR95M2JFiUbWMesxL7Lio1p1eZ9nXf9GDPgWGpSPimfa/HJXIl7UgogNhn79xViXJ/xM//MxMdJcerDxTjApm6fC4Hxr25lQhxYaWDSzyzYQV4LvOklSP/GZ9xLu7WssDchHKlTILu7/qZsN2kwJptM/NU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=uc/omc6L; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="uc/omc6L" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 962AF1BF3; Tue, 15 Sep 2026 09:02:25 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7CAD93F882; Tue, 15 Sep 2026 09:02:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488149; bh=qj0/UumNi5rDv9Vg9CrV5dfdz5rbhLtkWFeMlHj/0ZE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uc/omc6LolGCKoufSQrM1eLdyE1xcH7d+Puq7h5KkYr2fAslOBuR9wgoGo+lGo/xu bKhiV67zsxwjjhEyvws5kVS5N6sdOX39WqbvP77n79jT9mqJ4Kn918LdoQo7OXkQAG M2576vXCPvQdJs5xBMZHqUrcDrbAKbH7nFxM1HmI= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 12/23] KVM: arm64: Widen the scope of "protected" VMs Date: Tue, 15 Sep 2026 17:01:30 +0100 Message-ID: <20260915160141.3543048-13-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On arm64 we have "protected" VMs that run on PKVM as a confidential compute guest. Given we already have the construct of "kvm_vm_is_protected" in the = core KVM code, use that for all confidential compute guests including Realms that we are about to add. Use the VM flavor to detect the "protected" VMs by introducing a marker. Add explicit helper to detect if a given VM is a "protected" VM under PKVM. Change the existing users that precisely want to check the VM type. These include : - kvm_arch_prepare_memory_region - For preventing memslot changes after p= VM creation. All the others are retained as a wider check for confidential guest VMs. These are: - kvm_vm_ioctl_set_counter_offset - For disallowing timer offset configura= tion - io_mem_abort for dabt handling without valid syndrome information Both of which are true for Realms too. Realms support is restricted to VHE host and thus "kvm_vm_is_protected()" checks in the pkvm hyp specific code doesn't need to change, as the only protected guests it deals with is "protected PKVM" guests. Signed-off-by: Suzuki K Poulose --- arch/arm64/include/asm/kvm_host.h | 4 +++- arch/arm64/kvm/mmu.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 7ce46d853c47e..1bb43c57fb0f0 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -329,6 +329,7 @@ enum kvm_arm_vm_flavor { VM_NVHE, VM_VHE, VM_PKVM, /* Normal guests on pKVM */ + MARKER(__VM_PROTECTED), VM_PROTECTED_PKVM, /* Protected VM */ VM_FLAVOR_MAX, }; @@ -1535,7 +1536,8 @@ struct kvm *kvm_arch_alloc_vm(void); =20 #define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE =20 -#define kvm_vm_is_protected(kvm) ((kvm)->arch.vm_flavor =3D=3D VM_PROTECTE= D_PKVM) +#define kvm_vm_is_protected(kvm) ((kvm)->arch.vm_flavor >=3D __VM_PROTECTE= D) +#define kvm_vm_is_protected_pkvm(kvm) ((kvm)->arch.vm_flavor =3D=3D VM_PRO= TECTED_PKVM) #define kvm_vm_is_unprotected_pkvm(kvm) ((kvm)->arch.vm_flavor =3D=3D VM_P= KVM) =20 #define kvm_vm_hyp_is_pkvm(kvm) (is_protected_kvm_enabled()) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 607c908c15c42..38f3bf772278f 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -2678,7 +2678,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, hva_t hva, reg_end; int ret =3D 0; =20 - if (kvm_vm_is_protected(kvm)) { + if (kvm_vm_is_protected_pkvm(kvm)) { /* Cannot modify memslots once a pVM has run. */ if (pkvm_hyp_vm_is_created(kvm) && (change =3D=3D KVM_MR_DELETE || change =3D=3D KVM_MR_MOVE)) { --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8CDAF4BE437; Tue, 15 Sep 2026 16:02:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488153; cv=none; b=DZuP3UUkHUklkCYFQ2DWhAh6lkWBtbS1IZRgMeoDgMHbUjk+tAop4G934pzjm07MVouF6VIEOZEBHKrv4fwoX30b0DUdAD8+3gS63JmpeEMIgFcQs0x5xlxvxb2jqwWddSKADybH3ZuNUKGKcUszvcYI3cIAE0YVJ8eZqbfuH+8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488153; c=relaxed/simple; bh=j4bM4Le2AKal5yA6XAi5DmpI3S/KrZ5K/Wzmf15T0ZE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YPLskUApJ+Uc6EsVH1YycDYtTm1/NWdpaJdeWjZmxUi5Y11CsEg7DlJPgnGBHKY5fiq7HepDAAAkoOJAP2jQ5fVnNlnmnH1DSdLf3+eXT6qffvboR72UlC2TC/OE3FMeFD8XFpdafGegTcE7eLOfKjL/Pn6cmuK1tL4Ki0lzPSU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=ClzThnsv; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="ClzThnsv" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8F36215A1; Tue, 15 Sep 2026 09:02:28 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 77E883F882; Tue, 15 Sep 2026 09:02:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488152; bh=j4bM4Le2AKal5yA6XAi5DmpI3S/KrZ5K/Wzmf15T0ZE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ClzThnsvV0+f2nZe1I9A9CL5T0IFtVNFtDYXmBqMUKy7p9ELACjh0Ha7pRHGIj4sQ 68my1T9P80v3Ia1OsjWhaWL7ckX5so/M5GWZSFkcr9JHRNhaf7wWuasgcuObUGbPVQ PP/+qzn+CvhwZfT+DOXHMcbdyYCO42GZClAvvn3k= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 13/23] KVM: arm64: Add a helper for VMs running on hyp that don't trust the host Date: Tue, 15 Sep 2026 17:01:31 +0100 Message-ID: <20260915160141.3543048-14-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" PKVM and RMM, both do not trust the host. Add a helper to detect the VMs that have "distrusting" hyp. Use this for blocking ioremap of vgic-v2 into stage2. Signed-off-by: Suzuki K Poulose --- arch/arm64/include/asm/kvm_host.h | 3 +++ arch/arm64/kvm/mmu.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 1bb43c57fb0f0..09910b2c61bfb 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -328,6 +328,8 @@ enum fgt_group_id { enum kvm_arm_vm_flavor { VM_NVHE, VM_VHE, + /* VMs running on a hyp that doesn't trust */ + MARKER(__VM_DISTRUSTING_HYP), VM_PKVM, /* Normal guests on pKVM */ MARKER(__VM_PROTECTED), VM_PROTECTED_PKVM, /* Protected VM */ @@ -1540,6 +1542,7 @@ struct kvm *kvm_arch_alloc_vm(void); #define kvm_vm_is_protected_pkvm(kvm) ((kvm)->arch.vm_flavor =3D=3D VM_PRO= TECTED_PKVM) #define kvm_vm_is_unprotected_pkvm(kvm) ((kvm)->arch.vm_flavor =3D=3D VM_P= KVM) =20 +#define kvm_vm_hyp_is_distrusting(kvm) ((kvm)->arch.vm_flavor > __VM_DISTR= USTING_HYP) #define kvm_vm_hyp_is_pkvm(kvm) (is_protected_kvm_enabled()) #define vcpu_is_protected(vcpu) kvm_vm_is_protected((vcpu)->kvm) =20 diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 38f3bf772278f..559a8286807cd 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1251,7 +1251,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_= t guest_ipa, KVM_PGTABLE_PROT_R | (writable ? KVM_PGTABLE_PROT_W : 0); =20 - if (is_protected_kvm_enabled()) + if (kvm_vm_hyp_is_distrusting(kvm)) return -EPERM; =20 size +=3D offset_in_page(guest_ipa); --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9E1924C14E0; Tue, 15 Sep 2026 16:02:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488158; cv=none; b=BbZk/7VwZ4+CHA1qAmHdbEygJ0YtOihxNB2XU/bK6r9eKvBGJNCnlw0Imzoj2aCNiCPyh5Z3K9+LqRcDUzjxxp5hXcDJJ652SJ3EzaynIKEhcFoenBlR9SoIusIhFoeSK0zyKKrcFjvQkAX/0TUReBIxgkRNDZhWMLfEUQ92cDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488158; c=relaxed/simple; bh=3txRcWQsJihaCMkChZU8QnEkjzabm1OeIAmZ/JVQQZE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TrJqgFc1ewGlhpUnd1/PehkxF7dvnCw3iZuWSJGYzjPiEw1rsx+7hD3SrMuL/Se1/L3IlK6U/yxYc6I23IBEYQnMa7WuEkrCS3u/mc6d6CZCdVH4ctR+32q4mgJdY9cJ01dK5FQmV7tKC7cbgJHBdwYzMSt3c77N9R21MLCM014= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=Y5vhUav2; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="Y5vhUav2" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 88E381570; Tue, 15 Sep 2026 09:02:31 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 720E43F882; Tue, 15 Sep 2026 09:02:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488155; bh=3txRcWQsJihaCMkChZU8QnEkjzabm1OeIAmZ/JVQQZE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y5vhUav264lnGStYDQ0TrDQfREW9OpKJ195DiEGkUYDHu0TFERlAhLr1bJBeers14 fbsgOkT2O3P7YHJV/Ob3j9ZQ6Y1dUXc3m225l4pacgeBpzLtZ8dsmVh39ueNmoMEzH iz5JZ2FvD2dGagp7aEKsxerDKwiWGv6D9Mty3doQ= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 14/23] KVM: arm64: CCA: Add a new mode for supporting Realm guests Date: Tue, 15 Sep 2026 17:01:32 +0100 Message-ID: <20260915160141.3543048-15-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add an explicit mode to support Arm CCA guests. Signed-off-by: Suzuki K Poulose --- Documentation/admin-guide/kernel-parameters.txt | 3 +++ arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/kvm/arm.c | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentatio= n/admin-guide/kernel-parameters.txt index 68647ff4bdd24..1afe3df3b923e 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3256,6 +3256,9 @@ Kernel parameters nested: VHE-based mode with support for nested virtualization. Requires at least ARMv8.4 hardware (with FEAT_NV2). + rmm: Support for running confidential guests in Realm + world using RMM, as defined by Arm Confidential + Compute Architecture (CCA) =20 Defaults to VHE/nVHE based on hardware support. Setting mode to "protected" will disable kexec and hibernation diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 09910b2c61bfb..3cedb71f49ab8 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -69,6 +69,7 @@ enum kvm_mode { KVM_MODE_DEFAULT, KVM_MODE_PROTECTED, KVM_MODE_NV, + KVM_MODE_RMM, KVM_MODE_NONE, }; #ifdef CONFIG_KVM diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 42d9385f5e329..ae09d0d9812c5 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -3283,6 +3283,11 @@ static int __init early_kvm_mode_cfg(char *arg) return 0; } =20 + if (strcmp(arg, "rmm") =3D=3D 0 && !WARN_ON(!is_kernel_in_hyp_mode())) { + kvm_mode =3D KVM_MODE_RMM; + return 0; + } + return -EINVAL; } early_param("kvm-arm.mode", early_kvm_mode_cfg); --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 971314BFE8E; Tue, 15 Sep 2026 16:02:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488161; cv=none; b=RRjypcJur1c3dLZvyregixj/6T0TWiEL+/+fx9P0JaVa2tdZYPONJA7CgogduYdv67vIelLYGsG5JnDv9Hqb4gs3b6+gOIneTN7VkAyWUQgHPI2OpRsvrxLnIeQD/+waVynGUGqclcmfHLX5rd74fcb8X8bOwhtPfAyKcOkztbE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488161; c=relaxed/simple; bh=Hr0tbWfq8F0IVCRUDUUzkgoxynPwZ155E3egh/n+xRs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nEW982j7UTEOa67i/mKESQknT26Gb5YSwkoOyb8PsBrENmrgKZlrMtEksfJrDodGvLwLWz/WzmgOrQ76k2DXTCknWlErDESgcbfbtyl4lVCjBDb5LoSIxCFugJUr9aVbT90W0YaYPx/nDrTUg9UcL/bocQXUPtVeMCVT22Zmfa8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=Kx2tzd3N; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="Kx2tzd3N" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 85E6615A1; Tue, 15 Sep 2026 09:02:34 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 6C45B3F882; Tue, 15 Sep 2026 09:02:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488158; bh=Hr0tbWfq8F0IVCRUDUUzkgoxynPwZ155E3egh/n+xRs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Kx2tzd3Nv+rn3+vC7rREjlR1BIPSf/pZDIAS1O3hiGhCTyDvv4EK9/g5gzQugmByX r1uDhYnsSLstMaUATzLl8zkA9Jt5kdlUb9sKUk155ww04xKu3x+IolHC2Z/YQNfDEr vguv6TNdzO9st4cHgyzllNsRGHYk+x/KENNzsNvc= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 15/23] KVM: arm64: CCA: Add VCPU load/put for Realms Date: Tue, 15 Sep 2026 17:01:33 +0100 Message-ID: <20260915160141.3543048-16-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RMM controls the VCPU settings and most are hidden from the KVM, except for= the VGIC and timer bits. A later patch would add syncing the VCPU state into the Realm REC related S= MC parameters. Signed-off-by: Suzuki K Poulose --- arch/arm64/kvm/arm.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index ae09d0d9812c5..8defec75b8438 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -810,6 +810,13 @@ static void pkvm_vcpu_load(struct kvm_vcpu *vcpu) &vcpu->arch.vgic_cpu.vgic_v3); } =20 +static void realm_vcpu_load(struct kvm_vcpu *vcpu) +{ + kvm_timer_vcpu_load(vcpu); + kvm_vgic_load(vcpu); + vcpu_set_wfx_traps(vcpu); +} + void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { vcpu->cpu =3D cpu; @@ -860,6 +867,12 @@ static void pkvm_vcpu_put(struct kvm_vcpu *vcpu) kvm_vcpu_pmu_restore_host(vcpu); } =20 +static void realm_vcpu_put(struct kvm_vcpu *vcpu) +{ + kvm_timer_vcpu_put(vcpu); + kvm_vgic_put(vcpu); +} + void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { vcpu->arch.vcpu_ops->vcpu_put(vcpu); @@ -2217,6 +2230,11 @@ static const struct kvm_vcpu_ops pkvm_vcpu_ops =3D { .vcpu_put =3D pkvm_vcpu_put, }; =20 +static const struct kvm_vcpu_ops realm_vcpu_ops =3D { + .vcpu_load =3D realm_vcpu_load, + .vcpu_put =3D realm_vcpu_put, +}; + #define KVM_VCPU_OPS(flavor, ops) \ [(flavor)] =3D (ops) =20 --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8DC364078D1; Tue, 15 Sep 2026 16:02:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488164; cv=none; b=sDuE+vY4sn3t7NDS54mO7qBjzgYpfLm7vMu4up7lck/He2a1wRyiTgdGBQFz2tgm8W3E5e0CBPX3VCPOrv/IX/bzTvVuZFdtKnmutftoJtzdbXAqb6eUDITLF3O3VbTjz13Bi0hny2uIs29FfnUEgfzSVcxj0Rvu0IGAVdKf5qk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488164; c=relaxed/simple; bh=22gesudg8073MgbQnGHHio9ZG47S1o4pC17iaDfRE1M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Rh0b19HAPmAzxg+XopalA1+3dFWYRFWimgtQxENqO7xsBD24EVcEPXASK0DTUhqq4i8c9gB7WN86U6JuGtss98cphcJ9w04fOZbeA583WPVhQS8WJYhYIER5VAupVDZtTqfeYGLL/lVcs0wZutMppIhR7i2SfBBirVlpZ0n6fL8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=VA627VA8; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="VA627VA8" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7F9A61570; Tue, 15 Sep 2026 09:02:37 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 682F73F882; Tue, 15 Sep 2026 09:02:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488161; bh=22gesudg8073MgbQnGHHio9ZG47S1o4pC17iaDfRE1M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VA627VA8W1VJco18HSGHTgCmYqW7eNkG8c11Tmu0VK0RZIDReyB2TK8A00YGoM7zn biLItBO4p2vdxPwDwEHp2v33cmIzPivex8AuSSPakEYLwKMMLeEPK+P66+JlSY7JZW yR6yD7mkN2c727GfX8/WUQTs2afSGfWhY908GzCo= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 16/23] KVM: arm64: CCA: Add bare minimal S2 operations for Realm Date: Tue, 15 Sep 2026 17:01:34 +0100 Message-ID: <20260915160141.3543048-17-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add bare minimal MMU operation hooks for Realms. The mem_abort handling is chosen as the default KVM variant. However this cannot be reached for Realms yet and we would need real RMI command support to make it fully functional. RMM takes care of the TLB flushing as required, when the Stage2 is modified. So host doesn't need to do anything explicitly. RMM doesn't support access flags for the stage2, even for the shared IPA. Signed-off-by: Suzuki K Poulose --- arch/arm64/kvm/mmu.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 559a8286807cd..ac86b5a41c315 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -180,6 +180,12 @@ static int kvm_vm_flush_remote_tlbs(struct kvm *kvm) return 0; } =20 +static int realm_vm_flush_remote_tlbs(struct kvm *kvm) +{ + /* Nothing to do here, RMM takes care of this */ + return 0; +} + /** * kvm_arch_flush_remote_tlbs() - flush all VM TLB entries for v7/8 * @kvm: pointer to kvm structure. @@ -209,6 +215,13 @@ static int kvm_vm_flush_remote_tlbs_range(struct kvm *= kvm, return 0; } =20 +static int realm_vm_flush_remote_tlbs_range(struct kvm *kvm, + gfn_t gfn, u64 nr_pages) +{ + /* Nothing to do here, RMM takes care of this */ + return 0; +} + int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, u64 nr_pages) { @@ -2881,6 +2894,17 @@ static const struct kvm_vm_s2_ops kvm_default_vm_s2_= ops =3D { .vm_mem_abort =3D kvm_vm_mem_abort, }; =20 +static const struct kvm_vm_s2_ops realm_vm_s2_ops =3D { + .vm_flush_remote_tlbs =3D realm_vm_flush_remote_tlbs, + .vm_flush_remote_tlbs_range =3D realm_vm_flush_remote_tlbs_range, + .vm_mem_abort =3D kvm_vm_mem_abort, + /* + * Not supported for Realms + * .vm_age_gfn =3D realm_vm_age_gfn, + * .vm_test_age_gfn =3D realm_vm_test_age_gfn, + */ +}; + #define KVM_VM_S2_OPS(flavor, ops) \ [flavor] =3D ops static const struct kvm_vm_s2_ops *arm64_vm_s2_ops[] =3D { --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 045EB4C151E; Tue, 15 Sep 2026 16:02:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488167; cv=none; b=dbDbR8QCivtuXOXBly1vuPBnZs5QY8f9xRyHqiGS0OEzl5j+lvun34B1bEMOjojR78EYApuorw+Mhn23dnVLLsd3uwSFBMFZH4hCFtvP91of3T64HloBbxH1BQQ2adwLFLcQz3WhBgTWPv+y67c74A0vPUHR3/v3y4/XIyqXQX8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488167; c=relaxed/simple; bh=Zdf1YuvDb/HTBkdinDxFHd6mmHUfHxMl8ZYDMH6fHP0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=teLD0CnHpqqDzr1Zb5pztKRmDaZfo2cyIZ+7Ep+kSqVQQ8qyRMJNU6iXTuzkrPTv0vl99SznvQSC34avwf75G2gSeWhABEknDrkHMUuGMVLFklsgnglDVGGyEo7Z1bdDSsYH3XtFHOw7QKkQ9zjACmqZwv4cSsZcVjNk9jhiNME= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=TjQXR250; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="TjQXR250" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7B07B1BF3; Tue, 15 Sep 2026 09:02:40 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 63F2A3F882; Tue, 15 Sep 2026 09:02:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488164; bh=Zdf1YuvDb/HTBkdinDxFHd6mmHUfHxMl8ZYDMH6fHP0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TjQXR25007PbgX1DNvYvDjrZFZe/TbxerMbWhMZfhUMissEamRrdqYGfjHeDjdqId cB+Vq18eqkzDwLRbEArQSrYN1pTE2VdD9oK00YRcwHz2xNVOVXKQhNyNf4jjYdJIH/ xy85AbNagP/zu7ljgsHcyFHl2NyDxYQK9awdq2I8= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 17/23] KVM: arm64: CCA: Introduce Realms Date: Tue, 15 Sep 2026 17:01:35 +0100 Message-ID: <20260915160141.3543048-18-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add foundational work for supporting Realms. - Add a new VM flavor. - At KVM init, check if the KVM can support Realms (though not functional = yet) and will be advertised by static key kvm_rmi_is_available. This will be turned on in a later patches, once we have all the bits and pieces ready. For now check if we are blessed with KVM_MODE_RMM. - Add realm specific tracking in kvm_arch. Since Realm and protected pKVM states are mutually exclusive, move them into a union. Please note that we cannot create Realm VMs yet. This requires further chan= ges to the UABI and core RMI driver support, which will come later. Signed-off-by: Steven Price Co-developed-by: Suzuki K Poulose Signed-off-by: Suzuki K Poulose --- Changes since v16: * Share mutually exclusive pKVM and Realm per-VM storage in a union. * Move to the new VM flavor infrastructure, split bits out. Trimmed down * Move in Realm state and basic boiler plates Changes since v13: * Most of the init has been moved out of the 'kvm' directory so this is much more basic now. Changes since v12: * Drop check for 4k page size. Changes since v11: * Reword slightly the comments on the realm states. Changes since v10: * kvm_is_realm() no longer has a NULL check. * Rename from "rme" to "rmi" when referring to the RMM interface. * Check for RME (hardware) support before probing for RMI support. Changes since v8: * No need to guard kvm_init_rme() behind 'in_hyp_mode'. Changes since v6: * Improved message for an unsupported RMI ABI version. Changes since v5: * Reword "unsupported" message from "host supports" to "we want" to clarify that 'we' are the 'host'. Changes since v2: * Drop return value from kvm_init_rme(), it was always 0. * Rely on the RMM return value to identify whether the RSI ABI is compatible. --- arch/arm64/include/asm/kvm_emulate.h | 16 ++++++++ arch/arm64/include/asm/kvm_host.h | 18 +++++--- arch/arm64/include/asm/kvm_rmi.h | 61 ++++++++++++++++++++++++++++ arch/arm64/include/asm/virt.h | 1 + arch/arm64/kvm/Makefile | 2 +- arch/arm64/kvm/arm.c | 6 +++ arch/arm64/kvm/mmu.c | 1 + arch/arm64/kvm/rmi.c | 18 ++++++++ 8 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 arch/arm64/include/asm/kvm_rmi.h create mode 100644 arch/arm64/kvm/rmi.c diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/= kvm_emulate.h index a3c1928bdf743..d360a8b05b8bf 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -793,4 +793,20 @@ static inline void kvm_reset_vcpu_psci(struct kvm_vcpu= *vcpu, vcpu_set_reg(vcpu, 0, reset_state->r0); } =20 +static inline enum realm_state kvm_realm_state(struct kvm *kvm) +{ + return READ_ONCE(kvm->arch.realm.state); +} + +static inline void kvm_set_realm_state(struct kvm *kvm, + enum realm_state new_state) +{ + WRITE_ONCE(kvm->arch.realm.state, new_state); +} + +static inline bool kvm_realm_is_created(struct kvm *kvm) +{ + return kvm_vm_is_realm(kvm) && kvm_realm_state(kvm) !=3D REALM_STATE_NONE; +} + #endif /* __ARM64_KVM_EMULATE_H__ */ diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 3cedb71f49ab8..90bfa0fa4f3cf 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -27,6 +27,7 @@ #include #include #include +#include #include =20 #define __KVM_HAVE_ARCH_INTC_INITIALIZED @@ -334,6 +335,7 @@ enum kvm_arm_vm_flavor { VM_PKVM, /* Normal guests on pKVM */ MARKER(__VM_PROTECTED), VM_PROTECTED_PKVM, /* Protected VM */ + VM_REALM, /* CCA */ VM_FLAVOR_MAX, }; =20 @@ -451,11 +453,14 @@ struct kvm_arch { /* Count the number of VNCR_EL2 TLBs */ atomic_t vncr_tlb_count; =20 - /* - * For an untrusted host VM, 'pkvm.handle' is used to lookup - * the associated pKVM instance in the hypervisor. - */ - struct kvm_protected_vm pkvm; + union { + /* + * For an untrusted host VM, 'pkvm.handle' is used to lookup + * the associated pKVM instance in the hypervisor. + */ + struct kvm_protected_vm pkvm; + struct realm realm; + }; =20 #ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS /* Nested virtualization info */ @@ -1545,7 +1550,10 @@ struct kvm *kvm_arch_alloc_vm(void); =20 #define kvm_vm_hyp_is_distrusting(kvm) ((kvm)->arch.vm_flavor > __VM_DISTR= USTING_HYP) #define kvm_vm_hyp_is_pkvm(kvm) (is_protected_kvm_enabled()) +#define kvm_vm_is_realm(kvm) ((kvm)->arch.vm_flavor =3D=3D VM_REALM) + #define vcpu_is_protected(vcpu) kvm_vm_is_protected((vcpu)->kvm) +#define vcpu_is_rec(vcpu) kvm_vm_is_realm((vcpu)->kvm) =20 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature); bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/include/asm/kvm_rmi.h b/arch/arm64/include/asm/kvm_= rmi.h new file mode 100644 index 0000000000000..44f5c75a27b5b --- /dev/null +++ b/arch/arm64/include/asm/kvm_rmi.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023-2026 ARM Ltd. + */ + +#ifndef __ASM_KVM_RMI_H +#define __ASM_KVM_RMI_H + +/** + * enum realm_state - State of a Realm + * + * Mirrors the RMM's Realm lifecycle states where they are meaningful to K= VM, + * with REALM_STATE_DYING being a KVM-internal state used to prevent furth= er + * requests while teardown is in progress. KVM does not track REALM_SYSTEM= _OFF + * or REALM_ZOMBIE separately as they naturally lead to teardown. + */ +enum realm_state { + /** + * @REALM_STATE_NONE: + * Realm has not yet been created. rmi_realm_create() has not + * yet been called. + */ + REALM_STATE_NONE, + /** + * @REALM_STATE_NEW: + * Realm is under construction, rmi_realm_create() has been + * called, but it is not yet activated. Pages may be populated. + */ + REALM_STATE_NEW, + /** + * @REALM_STATE_ACTIVE: + * Realm has been created and is eligible for execution with + * rmi_rec_enter(). Pages may no longer be populated with + * rmi_data_create(). + */ + REALM_STATE_ACTIVE, + /** + * @REALM_STATE_DYING: + * Realm is in the process of being destroyed or has already been + * destroyed. + */ + REALM_STATE_DYING, + /** + * @REALM_STATE_DEAD: + * Realm has been destroyed. + */ + REALM_STATE_DEAD +}; + +/** + * struct realm - Additional per VM data for a Realm + * + * @state: The lifetime state machine for the realm + */ +struct realm { + enum realm_state state; +}; + +void kvm_init_rmi(void); + +#endif /* __ASM_KVM_RMI_H */ diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h index b546703c3ab9a..92cec42952f42 100644 --- a/arch/arm64/include/asm/virt.h +++ b/arch/arm64/include/asm/virt.h @@ -87,6 +87,7 @@ void __hyp_reset_vectors(void); bool is_kvm_arm_initialised(void); =20 DECLARE_STATIC_KEY_FALSE(kvm_protected_mode_initialized); +DECLARE_STATIC_KEY_FALSE(kvm_rmi_is_available); =20 static inline bool is_pkvm_initialized(void) { diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 59612d2f277c1..ed3cf30eb06e7 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -16,7 +16,7 @@ CFLAGS_handle_exit.o +=3D -Wno-override-init kvm-y +=3D arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \ inject_fault.o va_layout.o handle_exit.o config.o \ guest.o debug.o reset.o sys_regs.o stacktrace.o \ - vgic-sys-reg-v3.o fpsimd.o pkvm.o \ + vgic-sys-reg-v3.o fpsimd.o pkvm.o rmi.o \ arch_timer.o trng.o vmid.o emulate-nested.o nested.o at.o \ vgic/vgic.o vgic/vgic-init.o \ vgic/vgic-irqfd.o vgic/vgic-v2.o \ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 8defec75b8438..8ed7dd1ce446c 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include =20 @@ -112,6 +113,8 @@ long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long= *ext) return -EINVAL; } =20 +DEFINE_STATIC_KEY_FALSE(kvm_rmi_is_available); + DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector); =20 DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base); @@ -2243,6 +2246,7 @@ static const struct kvm_vcpu_ops *arm64_vcpu_ops[] = =3D { KVM_VCPU_OPS(VM_NVHE, &nvhe_vcpu_ops), KVM_VCPU_OPS(VM_PKVM, &pkvm_vcpu_ops), KVM_VCPU_OPS(VM_PROTECTED_PKVM, &pkvm_vcpu_ops), + KVM_VCPU_OPS(VM_REALM, &realm_vcpu_ops), }; =20 static void kvm_init_vcpu_ops(struct kvm_vcpu *vcpu) @@ -3196,6 +3200,8 @@ static __init int kvm_arm_init(void) =20 in_hyp_mode =3D is_kernel_in_hyp_mode(); =20 + kvm_init_rmi(); + if (cpus_have_final_cap(ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE) || cpus_have_final_cap(ARM64_WORKAROUND_1508412)) kvm_info("Guests without required CPU erratum workarounds can deadlock s= ystem!\n" \ diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index ac86b5a41c315..cc264726a6df8 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -2912,6 +2912,7 @@ static const struct kvm_vm_s2_ops *arm64_vm_s2_ops[] = =3D { KVM_VM_S2_OPS(VM_NVHE, &kvm_default_vm_s2_ops), KVM_VM_S2_OPS(VM_PKVM, &pkvm_vm_s2_ops), KVM_VM_S2_OPS(VM_PROTECTED_PKVM, &protected_pkvm_vm_s2_ops), + KVM_VM_S2_OPS(VM_REALM, &realm_vm_s2_ops), }; =20 static int kvm_vm_init_vm_s2_ops(struct kvm *kvm) diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c new file mode 100644 index 0000000000000..5ecc8b3498698 --- /dev/null +++ b/arch/arm64/kvm/rmi.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023-2026 ARM Ltd. + */ + +#include + +#include + +void kvm_init_rmi(void) +{ + if (kvm_get_mode() !=3D KVM_MODE_RMM) + return; + + /* TODO: Check if the RMI is available */ + + /* Future patch will enable static branch kvm_rmi_is_available */ +} --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DAFC63D3002; Tue, 15 Sep 2026 16:02:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488169; cv=none; b=eAWidO5vNjgIeNm4hd4furiYvMz00XyZ3vkpqhGjEsv4+rURsKyLTXXsOmvAV3G+liCIrK1QXp9+ONeP2S76QKUPvgzde/dOnwW2p62o8EkM5oPYWHicTCdj3rIYHb9WWvUHNp+/wUrtHIFrJXH7AaQjlbzaTOFUNZ7OKsOpEWQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488169; c=relaxed/simple; bh=CdQ3LU2C/wF8cnO0VzqHkPRgJxiUsivPTREctdi4DzQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GtW5TjXeOU+65vIIojmulF0mAp/7NzKdvl9CZHGMheX7KU9qR1k68sxY2hRioaZ2PYDXzjwIkMrRaf6z5B7esBxIBBgw38waLNVVCw0XCjXaeYGHlWU/oKYFaU1QlsJjTjIa77/m1HLwUM9S1Qfg2tud+HLa6oEaE2IuZt6o1Cs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=eE9sFgm/; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="eE9sFgm/" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7E7171570; Tue, 15 Sep 2026 09:02:43 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5EC183F882; Tue, 15 Sep 2026 09:02:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488167; bh=CdQ3LU2C/wF8cnO0VzqHkPRgJxiUsivPTREctdi4DzQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eE9sFgm/9L4mffffTTMC8gBmxw71DbR2kDVTJKfwh7EENeaXUz+dYvUUEb20Luu5X yrpqVtxXU81Xw8+0FtB3uaoRB4YHKw4K1fQaCdwlWJqnhUDYsbOlNTTMVJ+B/4yVJo joV8DrrTQScwI5OjXpRq6VTQD8oKirbUkFGYqIXE= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 18/23] KVM: arm64: CCA: Mandate VGIC_V3 for Realms Date: Tue, 15 Sep 2026 17:01:36 +0100 Message-ID: <20260915160141.3543048-19-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RMM mandates that we use a VGIC v3 for a Realm and nothing else is supporte= d. Mandate this in KVM. Signed-off-by: Suzuki K Poulose --- arch/arm64/kvm/vgic/vgic-init.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-ini= t.c index 4012df6002ea6..452c085073f3e 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -84,6 +84,9 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) !kvm_vgic_global_state.can_emulate_gicv2) return -ENODEV; =20 + /* Realms only support VGIC_V3 */ + if (kvm_vm_is_realm(kvm) && type !=3D KVM_DEV_TYPE_ARM_VGIC_V3) + return -ENODEV; /* * Ensure mutual exclusion with vCPU creation and any vCPU ioctls by: * --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D2D8C4C4F56; Tue, 15 Sep 2026 16:02:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488172; cv=none; b=EEVAPO4puQqxAiwJZterg8Vpee62lwJdVtXZYjU1gR8jytD+g/ubh/jvls4wor/oiE2sa+c/K7qUrPQtBRDlpL0sqQ8mE3BBSwhQ418ZL2RYb29fIFKq+O2JDuPMUqVouWhI9123AuoMLcXalyGkeWKgY0yvZQl607XDQNH2dS0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488172; c=relaxed/simple; bh=KNGyqBTTUJTWOTVKLgAvuyYtc0wespVw2YOMovUz8Jg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KK0s6x9oKb3otr6qj42/wEs94AztK0XuG1S+sEf8xVmVtSA3uFxixIoX6u0fRXHQ99t8Bup72MmOY0VE8XicQDJpUtHqxw2/5cOxoZKU28C2cw9jz/r0BLxjxHlRHbSZpEhPkHQ0Gwnqa35vAvnPLcqKVtab4M+FR2t8FLcT7zE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=M9v6rzUZ; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="M9v6rzUZ" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 78D8C1D70; Tue, 15 Sep 2026 09:02:46 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 637F63F882; Tue, 15 Sep 2026 09:02:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488170; bh=KNGyqBTTUJTWOTVKLgAvuyYtc0wespVw2YOMovUz8Jg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M9v6rzUZFHfz43wxKkRx3e2xakx1kna3LEd7bJX+wrLxtfmO6WJmoxsNI1XfDZkn+ qU6Re6idPVttaiaoWNuc3tRaFFgNXBmgVAFecgXl6jNMX3opYre6JnfKMBvjOaQzhM p4Ji0zuj//M+hKQvMrlJxscR9jiJ9H57ilvizYIA= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 19/23] KVM: arm64: CCA: Support timers in realm RECs Date: Tue, 15 Sep 2026 17:01:37 +0100 Message-ID: <20260915160141.3543048-20-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Price The RMM keeps track of the timer while the realm REC is running, but on exit to the normal world KVM is responsible for handling the timers. A later patch adds the support for propagating the timer values from the exit data structure and makeing sure the values are in sync for KVM. Also, RMM doesn't support injecting virtual interrupts backed by Physical interrupts. So, use the existing software resampling mechanims for Realm timer interrupts. Signed-off-by: Steven Price Signed-off-by: Suzuki K Poulose --- arch/arm64/kvm/arch_timer.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index dda020da4c9c7..ef5690956ee64 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -56,11 +56,25 @@ static unsigned long kvm_arch_timer_get_irq_flags(void) return kvm_vgic_global_state.no_hw_deactivation ? VGIC_IRQ_SW_RESAMPLE : = 0; } =20 +static unsigned long kvm_realm_timer_get_irq_flags(void) +{ + /* + * RMI_REC_ENTER rejects LRs with the HW bit set, so use the existing + * software resampling mechanism for Realm timer interrupts. + */ + return VGIC_IRQ_SW_RESAMPLE; +} + static const struct irq_ops arch_timer_irq_ops =3D { .get_flags =3D kvm_arch_timer_get_irq_flags, .get_input_level =3D kvm_arch_timer_get_input_level, }; =20 +static const struct irq_ops realm_timer_irq_ops =3D { + .get_flags =3D kvm_realm_timer_get_irq_flags, + .get_input_level =3D kvm_arch_timer_get_input_level, +}; + static const struct irq_ops arch_timer_irq_ops_vgic_v5 =3D { .get_input_level =3D kvm_arch_timer_get_input_level, .queue_irq_unlock =3D vgic_v5_ppi_queue_irq_unlock, @@ -1604,8 +1618,12 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) =20 get_timer_map(vcpu, &map); =20 - ops =3D vgic_is_v5(vcpu->kvm) ? &arch_timer_irq_ops_vgic_v5 : - &arch_timer_irq_ops; + if (vcpu_is_rec(vcpu)) + ops =3D &realm_timer_irq_ops; + else if (vgic_is_v5(vcpu->kvm)) + ops =3D &arch_timer_irq_ops_vgic_v5; + else + ops =3D &arch_timer_irq_ops; =20 for (int i =3D 0; i < nr_timers(vcpu); i++) kvm_vgic_set_irq_ops(vcpu, timer_irq(vcpu_get_timer(vcpu, i)), ops); --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A2736415F1D; Tue, 15 Sep 2026 16:02:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488177; cv=none; b=KkSzI5XIccuhRs9sgzs6TPIS4YpPh66MYL2waGzrInFll95esWGGT49rf9H6Gm9j28QH8dZtIP+IYwTIogKBjKa9hEtVqpmz3IBjRk2TEAlu0hmW4qibZdOPDSM/vGlmGbNVhptS/nhJoDdqeAQUW/Nu8Dz32EAeewKH0sEZF00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488177; c=relaxed/simple; bh=6jkrogZGSbm4RdA1R7kTYWIwGIAxksB43/2wFkQ0l0M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MKlLY+UaWkcEw+FLMb8P/RAXzIJ0LRvobriv+o7aBouZ6litXhJTL1z2EbWLxvHbp/8OFGgEu6p1GxcVNeNd+5qeSWUeFI+Qm+z3dzCEfTkN0DYNGMdu1reZLlMixbFTtpyyvxCEu4Lcz73ES905XuVKVa3nw6m+tCaNhojELYA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=bR1+20uS; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="bR1+20uS" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 781B415A1; Tue, 15 Sep 2026 09:02:49 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5FEFA3F882; Tue, 15 Sep 2026 09:02:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488173; bh=6jkrogZGSbm4RdA1R7kTYWIwGIAxksB43/2wFkQ0l0M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bR1+20uS1/cFWUrmp4PYnvq1nwFrNe0m5t5XuH/4v7LC0f2gew2gBZtGSvrOAUwaA x6a1/pEVTQNMWuLaILtEDNHY7dHY0xEV+IuV9wiFUmyO7zoHW3H6D8Qki/rxeVkyTB jyJoXuUwhsBmzNsv0GTL+hSVzESf4qvdlgP0w4/U= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Suzuki K Poulose Subject: [PATCH v18 20/23] KVM: arm64: CCA: Don't expose unsupported capabilities for realm guests Date: Tue, 15 Sep 2026 17:01:38 +0100 Message-ID: <20260915160141.3543048-21-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Limit the capabilities that are allowed for Realm VMs. Similarly block the vm_ioctls backed by the capabilities. Repurpose the kvm_pkvm_ioctl_allowed() to support both pKVM and Realm ioctls. Rename the helper to kvm_arch_vm_ioctl_allowed() and move it into arch/arm64/kvm/arm.c. Also add a generic kvm_arch_vm_ext_allowed() to handle pKVM and Realm capability filtering. Signed-off-by: Suzuki K Poulose --- Changes since v17: * Drop superfluous !kvm check from kvm_vm_ioctl_enable_cap() - Sashiko * Drop KVM_CAP_CREATE_IRQCHIP, as we don't support VGIC_V2 for Realms * Filter out the vm_ioctls that are based on blocked cap. * Repurpose the pkvm plumbing for filtering the caps and ioctl to generic and plumb the Realm support in Changes since v13: * Add missing check in kvm_vm_ioctl_enable_cap(). Changes since v10: * Add a kvm_realm_ext_allowed() function which limits which extensions are exposed to an allowlist. This removes the need for special casing various extensions. Changes since v7: * Remove the helper functions and inline the kvm_is_realm() check with a ternary operator. * Rewrite the commit message to explain this patch. --- arch/arm64/include/asm/kvm_pkvm.h | 19 ---------- arch/arm64/kvm/arm.c | 58 +++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm= _pkvm.h index e4ea80711bec6..1bc4fe2726e9b 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -53,25 +53,6 @@ static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm,= long ext) } } =20 -/* - * Check whether the KVM VM IOCTL is allowed in pKVM. - * - * Certain features are allowed only for non-protected VMs in pKVM, which = is why - * this takes the VM (kvm) as a parameter. - */ -static inline bool kvm_pkvm_ioctl_allowed(struct kvm *kvm, unsigned int io= ctl) -{ - long ext; - int r; - - r =3D kvm_get_cap_for_kvm_ioctl(ioctl, &ext); - - if (WARN_ON_ONCE(r < 0)) - return false; - - return kvm_pkvm_ext_allowed(kvm, ext); -} - extern struct memblock_region kvm_nvhe_sym(hyp_memory)[]; extern unsigned int kvm_nvhe_sym(hyp_memblock_nr); =20 diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 8ed7dd1ce446c..df0aa66b6f5ed 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -136,6 +136,58 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) return kvm_vcpu_exiting_guest_mode(vcpu) =3D=3D IN_GUEST_MODE; } =20 +static inline bool kvm_realm_ext_allowed(long ext) +{ + switch (ext) { + case KVM_CAP_ARM_PSCI: + case KVM_CAP_ARM_PSCI_0_2: + case KVM_CAP_NR_VCPUS: + case KVM_CAP_MAX_VCPUS: + case KVM_CAP_MAX_VCPU_ID: + case KVM_CAP_MSI_DEVID: + case KVM_CAP_ARM_VM_IPA_SIZE: + case KVM_CAP_ARM_SVE: + case KVM_CAP_ONE_REG: + case KVM_CAP_ARM_PTRAUTH_ADDRESS: + case KVM_CAP_ARM_PTRAUTH_GENERIC: + case KVM_CAP_SYNC_MMU: + return true; + } + return false; +} + +static inline bool kvm_arch_vm_ext_allowed(struct kvm *kvm, long ext) +{ + /* + * We could be called with kvm as NULL, so can't use kvm_vm_* for pKVM + * flavors + */ + if (is_protected_kvm_enabled()) + return kvm_pkvm_ext_allowed(kvm, ext); + else if (kvm && kvm_vm_is_realm(kvm)) + return kvm_realm_ext_allowed(ext); + else + return true; +} + +/* + * Check whether the KVM VM IOCTL is allowed. + * + * Certain features are allowed only for non-protected VMs in pKVM, which = is why + * this takes the VM (kvm) as a parameter. + */ +static inline bool kvm_arch_vm_ioctl_allowed(struct kvm *kvm, unsigned int= ioctl) +{ + long ext; + int r; + + r =3D kvm_get_cap_for_kvm_ioctl(ioctl, &ext); + if (WARN_ON_ONCE(r < 0)) + return false; + + return kvm_arch_vm_ext_allowed(kvm, ext); +} + int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) { @@ -144,7 +196,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, if (cap->flags) return -EINVAL; =20 - if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, cap->cap)) + if (!kvm_arch_vm_ext_allowed(kvm, cap->cap)) return -EINVAL; =20 switch (cap->cap) { @@ -418,7 +470,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long = ext) { int r; =20 - if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, ext)) + if (!kvm_arch_vm_ext_allowed(kvm, ext)) return 0; =20 switch (ext) { @@ -2150,7 +2202,7 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int= ioctl, unsigned long arg) void __user *argp =3D (void __user *)arg; struct kvm_device_attr attr; =20 - if (is_protected_kvm_enabled() && !kvm_pkvm_ioctl_allowed(kvm, ioctl)) + if (!kvm_arch_vm_ioctl_allowed(kvm, ioctl)) return -EINVAL; =20 switch (ioctl) { --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6D1B44C8C49; Tue, 15 Sep 2026 16:02:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488178; cv=none; b=aRzYSGCyoNlyc14ykTeMNC0Rb6nOrBhpo9ZpSn8lC7H6WPSxOINnwCibG3xNR8YB8WkD2lLU8ZiDlJq3gLEP1hj+SzRMGualQ84T0+S4MAg5c+eMeuBEokpQrUkPIsNAs9f+X95zyMB1j/gJKvsYxfANb4McYcwVVfNouQYFD9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488178; c=relaxed/simple; bh=rO1Aepg+ZPdfUbjznCSF+LW5fDa0Tz1f7cbp73DbIAA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=otggSW/IAFGCQFmxZxSOSQnvrobg6g2a8koira5f6xQWyueDr8ylNZrXDbQn7FZLjiZgo4HJLbCe/uq6DBkfiWVjexGWNtgtfZOIVv2jdXfDWBDT9IAg2fKRbJ+XYe5vSdwHS9cugg1KTqn5zqXliK1FhOnF2JKekoREDECF4Es= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=kiTqgz1Y; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="kiTqgz1Y" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 61F111D70; Tue, 15 Sep 2026 09:02:52 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5B9AD3F882; Tue, 15 Sep 2026 09:02:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488176; bh=rO1Aepg+ZPdfUbjznCSF+LW5fDa0Tz1f7cbp73DbIAA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kiTqgz1Yy7gR4b79nYtgyPn5gKXuxc5Ql439+CksEyu0ACTiBZF3AQnCkHudHESRL 56Vb4DL+sRoAZFCxozDJsocWeomwOVq3oITqrg/vq1LrdObvOx19lnRGaH0eq+s+EV iOwXxpFgCoINxg9YqCKXx/dlurAbS+Nv4jR1BzwY= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com Subject: [PATCH v18 21/23] KVM: arm64: CCA: WARN on injected undef exceptions Date: Tue, 15 Sep 2026 17:01:39 +0100 Message-ID: <20260915160141.3543048-22-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Steven Price The RMM doesn't allow injection of a undefined exception into a realm guest. Add a WARN to catch if this ever happens. Signed-off-by: Steven Price --- Changes since v15: * Switch to KVM_BUG() to mark the VM as bugged as well. Changes since v6: * if (x) WARN(1, ...) makes no sense, just WARN(x, ...)! --- arch/arm64/kvm/inject_fault.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c index d6c4fc16f8795..d61a3ff04fabb 100644 --- a/arch/arm64/kvm/inject_fault.c +++ b/arch/arm64/kvm/inject_fault.c @@ -317,6 +317,7 @@ void kvm_inject_size_fault(struct kvm_vcpu *vcpu) */ void kvm_inject_undefined(struct kvm_vcpu *vcpu) { + KVM_BUG(vcpu_is_rec(vcpu), vcpu->kvm, "Unexpected undefined exception inj= ection to REC"); if (vcpu_el1_is_32bit(vcpu)) inject_undef32(vcpu); else --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 03BB241686A; Tue, 15 Sep 2026 16:03:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488182; cv=none; b=Rb4r4Zy4MhYoIHl+XnlwTZy7Dd6gzUFO9PsIU5iZSYBVGhkfzP7IPvgYE8Y9dyrhqWBg7A/Q5cEf/se4HBpbemGISjeuq2AbTqylxhBGv/KclOR3/cLBhSt9/AaBAa5D8I22vAOT+X93QKLHaAAj9PvrisooKKU45ISD5UsLJT0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488182; c=relaxed/simple; bh=0DiVz6oTZzzTe7Vk2dRx5LJfEnBfW9deM4TNPnYIjLY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mv2F/ycPYvghik6FMAZPriVJQs4lUHg3xL7GrC6qhbY8IpiFc4xfiQ8Yzg+kCwAbtd9UysyGbYV1Kk13pCuw+57MLCqYTfMGcbAE2hF2n90vn7EXVnlixJo5Qn8EHvRZ9TZJtvTy4vGFfqjZsorsp+pZ65E92dQNfq3jAbJFHOM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=MLZpMrWe; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="MLZpMrWe" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 767D615A1; Tue, 15 Sep 2026 09:02:55 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 452F93F882; Tue, 15 Sep 2026 09:02:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488179; bh=0DiVz6oTZzzTe7Vk2dRx5LJfEnBfW9deM4TNPnYIjLY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MLZpMrWemDd0fF4dQFzLDQDBymYGGADIMgQvdHggywKboZZeqHdYdIdI0tiM9+ufu w1bTaYHyja+BD7tgqtQ8/hRTypNxGBbgIFDy3W0e9Im+fzxs4SlHhJw7KAKKQI9pKZ PjdBIp4GjULip/0sE+di/tkbi0M0oWuiy4S6fefY= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Jean-Philippe Brucker , Suzuki K Poulose Subject: [PATCH v18 22/23] KVM: arm64: CCA: Expose SVE VL register before VCPU finalization Date: Tue, 15 Sep 2026 17:01:40 +0100 Message-ID: <20260915160141.3543048-23-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Jean-Philippe Brucker Userspace must configure the SVE vector length before the Realm is created (as it is part of the parameter for Realm creation), but the Realm VCPUs cannot be finalized until after the Realm Descriptor has been created. KVM_GET_REG_LIST currently rejects the unfinalized VCPUs, which prevents the userspace from discovering and configuring the VLs for the Realm. Allow KVM_GET_REG_LIST for unfinalized RECs and make the SVE register enumeration handle the unfinalized case explicitly. i.e., only expose KVM_REG_ARM64_SVE_VLS before SVE is finalized. One adverse side effect of this change is that a KVM_GET_REG_LIST call that only probes for the array size will now succeed even if SVE is not finalize= d, but that seems harmless since the following KVM_GET_REG_LIST with the full array will fail. Signed-off-by: Jean-Philippe Brucker Signed-off-by: Steven Price Reviewed-by: Gavin Shan Signed-off-by: Suzuki K Poulose --- Changes since v17: - Rewrite the commit description to clearly describe the purpose --- arch/arm64/kvm/arm.c | 15 ++++++++++++++- arch/arm64/kvm/guest.c | 10 +++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index df0aa66b6f5ed..3d8ede8460e96 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -2017,6 +2017,19 @@ static int kvm_arm_vcpu_set_events(struct kvm_vcpu *= vcpu, return __kvm_arm_vcpu_set_events(vcpu, events); } =20 +/* + * Realm VCPUs can be finalized only after the Realm descriptor is created. + * But in order to seal the SVE VL, we need to allow the userspace to read= /write + * to the SVE_VL, before everything is finalized. + * Allow the register list for RECs before the VCPUs are finalized. + */ +static bool kvm_arm_vcpu_reg_list_allowed(struct kvm_vcpu *vcpu) +{ + if (kvm_arm_vcpu_is_finalized(vcpu)) + return true; + return vcpu_is_rec(vcpu); +} + long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -2072,7 +2085,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, break; =20 r =3D -EPERM; - if (!kvm_arm_vcpu_is_finalized(vcpu)) + if (!kvm_arm_vcpu_reg_list_allowed(vcpu)) break; =20 r =3D -EFAULT; diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index b01d6622b8720..c3ca369882273 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -598,8 +598,8 @@ static unsigned long num_sve_regs(const struct kvm_vcpu= *vcpu) if (!vcpu_has_sve(vcpu)) return 0; =20 - /* Policed by KVM_GET_REG_LIST: */ - WARN_ON(!kvm_arm_vcpu_sve_finalized(vcpu)); + if (!kvm_arm_vcpu_sve_finalized(vcpu)) + return 1; /* KVM_REG_ARM64_SVE_VLS */ =20 return slices * (SVE_NUM_PREGS + SVE_NUM_ZREGS + 1 /* FFR */) + 1; /* KVM_REG_ARM64_SVE_VLS */ @@ -616,9 +616,6 @@ static int copy_sve_reg_indices(const struct kvm_vcpu *= vcpu, if (!vcpu_has_sve(vcpu)) return 0; =20 - /* Policed by KVM_GET_REG_LIST: */ - WARN_ON(!kvm_arm_vcpu_sve_finalized(vcpu)); - /* * Enumerate this first, so that userspace can save/restore in * the order reported by KVM_GET_REG_LIST: @@ -628,6 +625,9 @@ static int copy_sve_reg_indices(const struct kvm_vcpu *= vcpu, return -EFAULT; ++num_regs; =20 + if (!kvm_arm_vcpu_sve_finalized(vcpu)) + return num_regs; + for (i =3D 0; i < slices; i++) { for (n =3D 0; n < SVE_NUM_ZREGS; n++) { reg =3D KVM_REG_ARM64_SVE_ZREG(n, i); --=20 2.43.0 From nobody Fri Sep 25 07:22:50 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AA2514CA78E; Tue, 15 Sep 2026 16:03:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488186; cv=none; b=Ht3MpiNtgPZ+ohhpRHI3nKat15S/1a2na7FXhn0M2IAWxYCEVm02o3kclL+mSy1Ra1lyPVi/3dEs57AvCk3g92Mz9YwNbkCth+tmwjCX+Rry9R+x2Ffbja0AcVo/jsioAssJKl2yOaSwNFTAfe/MGEkJUbqHGRiLfmLhxlY2BCk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789488186; c=relaxed/simple; bh=mmi6VEWU9VuEsCf9DcQoojukGEJWWKDyBgEMumw2iIQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KybOZup20uzUCdlbupduuTvliTRF+8YZYlC2vZurUkYXdzIQ+uMWg/OGaMqhoB8vOsbLYAiy79RTfjJUSEMGlI/RYXsAr4xRo0BmIcIGDs0oKGIA1R9DMiww0FhVkUtE1MUqoPP7DGbkcKWeoAayXmuFrLBAYFsb2D/dzl6Y1+E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=bdFSVjp8; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="bdFSVjp8" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8DC0C1D70; Tue, 15 Sep 2026 09:02:58 -0700 (PDT) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.2.197.99]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5B2393F882; Tue, 15 Sep 2026 09:02:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1789488182; bh=mmi6VEWU9VuEsCf9DcQoojukGEJWWKDyBgEMumw2iIQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bdFSVjp8EvWuv6uNe0bC1gC3Jff0pK6fz9Hf2o4MnE+98QgymeO15EnDC9P22GGd9 l7vgRs+WZmKl8iEr0eiPGo0S9vdQKjdb/zyvk5zuQbJyG2rWdBKbDjEwx30+Nr9HaI cSyJ2tI8Du1VTwP83+HE99Yfxy+noLq2+HtENGyI= From: Suzuki K Poulose To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: maz@kernel.org, will@kernel.org, catalin.marinas@arm.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, steven.price@arm.com, aneesh.kumar@kernel.org, oupton@kernel.org, gshan@redhat.com, joey.gouly@arm.com, tabba@google.com, yuzenghui@huawei.com, linux-coco@lists.linux.dev, gankulkarni@os.amperecomputing.com, sdonthineni@nvidia.com, alpergun@google.com, fj0570is@fujitsu.com, WeiLin.Chang@arm.com, lpieralisi@kernel.org, enju.kohei@fujitsu.com, Jean-Philippe Brucker , Suzuki K Poulose Subject: [PATCH v18 23/23] KVM: arm64: CCA: Control user register access for Realms Date: Tue, 15 Sep 2026 17:01:41 +0100 Message-ID: <20260915160141.3543048-24-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260915160141.3543048-1-suzuki.poulose@arm.com> References: <20260915160141.3543048-1-suzuki.poulose@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Jean-Philippe Brucker The RMM restricts the access to the register states that the host can read/modify for a given Realm. e.g., At VCPU creation, can modify GPRS (x0-x30) and PC. While servicing SMCCC calls via RSI_HOST_CALL or servicing PSCI reque= sts. MMIO emulation in the unprotected space. Additionally we use the sysreg configuration to advertise/configure the fol= lowing Realm parameters, which are required before the Realm Descriptor is created: - SVE Vector Length - Number of HW Breakpoints/Watchpoints - PMU Counters. Thus KVM also additionally allows access to ID_AA64DFR0_EL1 and SVE_VLS for the configuration of Realm creation paramters. The RMM makes similar restrictions for reading of the guest's registers (this is *confidential* compute after all), however we don't impose the restriction here. This allows the VMM to read (stale) values from the registers which might be useful to read back the initial values even if the RMM doesn't provide the latest version. For migration of a realm VM, a new interface will be needed so that the VMM can receive an (encrypted) blob of the VM's state. Reflect the above in KVM_GET_REG_LIST, KVM_SET_ONE_REG calls. Reviewed-by: Gavin Shan Reviewed-by: Suzuki K Poulose Reviewed-by: Joey Gouly Signed-off-by: Steven Price Signed-off-by: Suzuki K Poulose --- Changes since v17: - Merge related changes into one single patch for the user set/get regist= ers I have retained the Review tags, as the code hasn't changed, just the p= atches were merged into a single one with the same tags. - Limit KVM_GET_REG_LIST to the allowed CORE registers. Signed-off-by: Suzuki K Poulose --- arch/arm64/kvm/guest.c | 63 +++++++++++++++++++++++++++++++++++++ arch/arm64/kvm/hypercalls.c | 4 +-- arch/arm64/kvm/sys_regs.c | 29 +++++++++++++---- 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index c3ca369882273..4ec95810ca89b 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -73,6 +73,25 @@ static u64 core_reg_offset_from_id(u64 id) return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE); } =20 +static bool kvm_realm_validate_core_reg(u64 off) +{ + /* + * Note that GPRs can only sometimes be controlled by the VMM. + * For PSCI only X0-X6 are used, higher registers are ignored (restored + * from the REC). + * For HOST_CALL all of X0-X30 are copied to the RsiHostCall structure. + * For emulated MMIO X0 is always used. + * PC can only be set before the realm is activated. + */ + switch (off) { + case KVM_REG_ARM_CORE_REG(regs.regs[0]) ... + KVM_REG_ARM_CORE_REG(regs.regs[30]): + case KVM_REG_ARM_CORE_REG(regs.pc): + return true; + } + return false; +} + static int core_reg_size_from_offset(const struct kvm_vcpu *vcpu, u64 off) { int size; @@ -553,6 +572,9 @@ static int copy_core_reg_indices(const struct kvm_vcpu = *vcpu, u64 reg =3D KVM_REG_ARM64 | KVM_REG_ARM_CORE | i; int size =3D core_reg_size_from_offset(vcpu, i); =20 + if (vcpu_is_rec(vcpu) && !kvm_realm_validate_core_reg(i)) + continue; + if (size < 0) continue; =20 @@ -598,6 +620,9 @@ static unsigned long num_sve_regs(const struct kvm_vcpu= *vcpu) if (!vcpu_has_sve(vcpu)) return 0; =20 + if (kvm_vm_is_realm(vcpu->kvm)) + return 1; /* KVM_REG_ARM64_SVE_VLS */ + if (!kvm_arm_vcpu_sve_finalized(vcpu)) return 1; /* KVM_REG_ARM64_SVE_VLS */ =20 @@ -625,6 +650,10 @@ static int copy_sve_reg_indices(const struct kvm_vcpu = *vcpu, return -EFAULT; ++num_regs; =20 + /* For Realms only support SVE_VLS */ + if (kvm_vm_is_realm(vcpu->kvm)) + return num_regs; + if (!kvm_arm_vcpu_sve_finalized(vcpu)) return num_regs; =20 @@ -705,6 +734,11 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struc= t kvm_one_reg *reg) if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 !=3D KVM_REG_ARM64 >> 32) return -EINVAL; =20 + /* + * We don't filter out the register reads for Realms, like we do for + * the user writes. We expose junk data for the VMM instead of + * denying the requests. + */ switch (reg->id & KVM_REG_ARM_COPROC_MASK) { case KVM_REG_ARM_CORE: return get_core_reg(vcpu, reg); case KVM_REG_ARM_FW: @@ -716,12 +750,41 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const stru= ct kvm_one_reg *reg) return kvm_arm_sys_reg_get_reg(vcpu, reg); } =20 +#define KVM_REG_ARM_ID_AA64DFR0_EL1 ARM64_SYS_REG(3, 0, 0, 5, 0) +/* + * The RMI ABI only enables setting some GPRs and PC. The selection of GPRs + * that are available depends on the Realm state and the reason for the la= st + * exit. All other registers are reset to architectural or otherwise defi= ned + * reset values by the RMM, except for a few configuration fields that + * correspond to Realm parameters. + */ +static bool validate_realm_set_reg(struct kvm_vcpu *vcpu, + const struct kvm_one_reg *reg) +{ + if ((reg->id & KVM_REG_ARM_COPROC_MASK) =3D=3D KVM_REG_ARM_CORE) { + u64 off =3D core_reg_offset_from_id(reg->id); + + return kvm_realm_validate_core_reg(off); + } else { + switch (reg->id) { + case KVM_REG_ARM_ID_AA64DFR0_EL1: + case KVM_REG_ARM64_SVE_VLS: + return true; + } + } + + return false; +} + int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { /* We currently use nothing arch-specific in upper 32 bits */ if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 !=3D KVM_REG_ARM64 >> 32) return -EINVAL; =20 + if (kvm_vm_is_realm(vcpu->kvm) && !validate_realm_set_reg(vcpu, reg)) + return -EINVAL; + switch (reg->id & KVM_REG_ARM_COPROC_MASK) { case KVM_REG_ARM_CORE: return set_core_reg(vcpu, reg); case KVM_REG_ARM_FW: diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index b11b8821c9fbc..2b1e6fdeb4d5c 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -414,14 +414,14 @@ void kvm_arm_teardown_hypercalls(struct kvm *kvm) =20 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) { - return ARRAY_SIZE(kvm_arm_fw_reg_ids); + return vcpu_is_rec(vcpu) ? 0 : ARRAY_SIZE(kvm_arm_fw_reg_ids); } =20 int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindice= s) { int i; =20 - for (i =3D 0; i < ARRAY_SIZE(kvm_arm_fw_reg_ids); i++) { + for (i =3D 0; i < kvm_arm_get_fw_num_regs(vcpu); i++) { if (put_user(kvm_arm_fw_reg_ids[i], uindices++)) return -EFAULT; } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 44aae52c473d7..520cec19f49fa 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -5638,18 +5638,18 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, = const struct kvm_one_reg *reg sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); } =20 -static unsigned int num_demux_regs(void) +static inline unsigned int num_demux_regs(struct kvm_vcpu *vcpu) { - return CSSELR_MAX; + return vcpu_is_rec(vcpu) ? 0 : CSSELR_MAX; } =20 -static int write_demux_regids(u64 __user *uindices) +static int write_demux_regids(struct kvm_vcpu *vcpu, u64 __user *uindices) { u64 val =3D KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX; unsigned int i; =20 val |=3D KVM_REG_ARM_DEMUX_ID_CCSIDR; - for (i =3D 0; i < CSSELR_MAX; i++) { + for (i =3D 0; i < num_demux_regs(vcpu); i++) { if (put_user(val | i, uindices)) return -EFAULT; uindices++; @@ -5693,11 +5693,28 @@ static bool copy_reg_to_user(const struct sys_reg_d= esc *reg, u64 __user **uind) return true; } =20 +static inline bool kvm_realm_sys_reg_hidden_user(const struct kvm_vcpu *vc= pu, + u64 reg) +{ + if (!vcpu_is_rec(vcpu)) + return false; + + switch (reg) { + case SYS_ID_AA64DFR0_EL1: + case SYS_PMCR_EL0: + return false; + } + return true; +} + static int walk_one_sys_reg(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u64 __user **uind, unsigned int *total) { + if (kvm_realm_sys_reg_hidden_user(vcpu, reg_to_encoding(rd))) + return 0; + /* * Ignore registers we trap but don't save, * and for which no custom user accessor is provided. @@ -5735,7 +5752,7 @@ static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 _= _user *uind) =20 unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu) { - return num_demux_regs() + return num_demux_regs(vcpu) + walk_sys_regs(vcpu, (u64 __user *)NULL); } =20 @@ -5748,7 +5765,7 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcp= u, u64 __user *uindices) return err; uindices +=3D err; =20 - return write_demux_regids(uindices); + return write_demux_regids(vcpu, uindices); } =20 #define KVM_ARM_FEATURE_ID_RANGE_INDEX(r) \ --=20 2.43.0