Re: [PATCH v16 00/45] arm64: Support for Arm CCA in KVM

Alper Gun <[email protected]>
Newsgroups dev.linux.lists.linux-coco,dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.kvm,org.kernel.vger.linux-kernel
Message-ID <CABpDEukGY+ctSi6wHAaC7o4pGmastX_Y18K2_VYDhNME7TF+wQ@mail.gmail.com>
On Tue, Aug 11, 2026 at 8:08 PM Gavin Shan <[email protected]> wrote:
> As the following calltrace indicates, -EAGAIN is returned from tf-rmm::update_ripas()
> because true is returned from s2tte_drain_pending() for the S2TTE corresponding to
> IPA 0x80000000. Linux host received error (RMI_ERROR_RTT, level=3) in ripas_change().
> Upon this specific error and the IPA range [0x80000000 0x90000000], find_map_level()
> returns level of 2, and realm_create_rtt_levels() returns 0 without populating any
> RTTs. After that, rmi_rtt_set_ripas() is re-executed and the above loop starts over
> again.
>
>    Linux host
>    ==========
>    kvm_arch_vcpu_ioctl_run                     // cca/host-v16
>      check_vcpu_requests
>        kvm_check_request
>          kvm_rec_handle_request
>            kvm_complete_ripas_change
>              realm_set_ipa_state
>                ripas_change
>                  rmi_rtt_set_ripas
>                    SMC_RMI_RTT_SET_RIPAS
>
>    TF-RMM
>    ======
>    SMC_RMI_RTT_SET_RIPAS                      // tf-rmm/topics/rmm-v2.0-poc_3
>      smc_rtt_set_ripas
>        s2tt_walk_lock_unlock
>        rtt_set_ripas_range
>          update_ripas
>            s2tte_drain_pending                // true, returns -EAGAIN
>
> The problem is the pending-bit for RTE corresponding IPA address 0x80000000 isn't cleared
> when SMC_RMI_RTT_SET_RIPAS is invoked. I didn't figure out how this bit is set and why
> it's not cleared in time.
>

Hi Gavin, Suzuki,

I think I ran into a similar issue on rmm-v2.0-poc_3 last week.
This looks like a potential RMM bug: could bit 32 be part of the physical
Address (if PA >= 4 GiB)?

It seems s2tte_drain_pending() in lib/s2tt/src/s2tt.c checks bit 32 without
checking whether the descriptor is valid or invalid.

In my testing, guarding the drain checks with a check for S2TTE_INVALID seemed
to resolve the boot hang:
--- a/lib/s2tt/src/s2tt.c
+++ b/lib/s2tt/src/s2tt.c
@@ -1701,6 +1701,10 @@ unsigned long
s2tte_clear_drain_pending(unsigned long s2tte)

 bool s2tte_drain_pending(unsigned long s2tte)
 {
+ if ((s2tte & S2TT_DESC_VALID_MASK) != S2TTE_INVALID) {
+ return false;
+ }
+
  return (s2tte & S2TTE_SW_DRAIN_PENDING_BIT) != 0UL;
 }

@@ -1730,11 +1734,19 @@ unsigned long
s2tte_clear_tlbi_pending(unsigned long s2tte)

 bool s2tte_tlbi_pending(unsigned long s2tte)
 {
+ if ((s2tte & S2TT_DESC_VALID_MASK) != S2TTE_INVALID) {
+ return false;
+ }
+
  return (s2tte & S2TTE_SW_TLBI_PENDING_BIT) != 0UL;
 }

 unsigned int s2tte_drain_handle(unsigned long s2tte)
 {
+ if ((s2tte & S2TT_DESC_VALID_MASK) != S2TTE_INVALID) {
+ return 0U;
+ }
+
  return (unsigned int)EXTRACT(S2TTE_SW_HANDLE, s2tte);
 }

Sharing in case it helps.
Thanks,
Alper
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.