From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
To: Tao Tang <tangtao1634@phytium.com.cn>,
Eric Auger <eric.auger@redhat.com>,
Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org,
"Chen Baozi" <chenbaozi@phytium.com.cn>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Jean-Philippe Brucker" <jean-philippe@linaro.org>,
"Mostafa Saleh" <smostafa@google.com>,
"Mathieu Poirier" <mathieu.poirier@linaro.org>
Subject: Re: [RFC v3 19/21] hw/arm/smmuv3: Use iommu_index to represent the security context
Date: Tue, 14 Oct 2025 17:02:20 -0700 [thread overview]
Message-ID: <dbc4d33e-3477-4f39-a745-4fdc0866fc08@linaro.org> (raw)
In-Reply-To: <20251012151501.4131026-1-tangtao1634@phytium.com.cn>
Hi Tao,
On 10/12/25 8:15 AM, Tao Tang wrote:
> The Arm SMMUv3 architecture uses a SEC_SID (Secure StreamID) to select
> the programming interface. To support future extensions like RME, which
> defines four security states (Non-secure, Secure, Realm, and Root), the
> QEMU model must cleanly separate these contexts for all operations.
>
> This commit leverages the generic iommu_index to represent this
> security context. The core IOMMU layer now uses the SMMU's .attrs_to_index
> callback to map a transaction's ARMSecuritySpace attribute to the
> corresponding iommu_index.
>
> This index is then passed down to smmuv3_translate and used throughout
> the model to select the correct register bank and processing logic. This
> makes the iommu_index the clear QEMU equivalent of the architectural
> SEC_SID, cleanly separating the contexts for all subsequent lookups.
>
> Signed-off-by: Tao Tang <tangtao1634@phytium.com.cn>
> ---
> hw/arm/smmuv3.c | 36 +++++++++++++++++++++++++++++++++++-
> 1 file changed, 35 insertions(+), 1 deletion(-)
>
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index c9c742c80b..b44859540f 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -1080,6 +1080,38 @@ static void smmuv3_fixup_event(SMMUEventInfo *event, hwaddr iova)
> }
> }
>
> +static SMMUSecSID smmuv3_attrs_to_sec_sid(MemTxAttrs attrs)
> +{
> + switch (attrs.space) {
> + case ARMSS_Secure:
> + return SMMU_SEC_SID_S;
> + case ARMSS_NonSecure:
> + default:
> + return SMMU_SEC_SID_NS;
> + }
> +}
> +
> +/*
> + * ARM IOMMU index mapping (implements SEC_SID from ARM SMMU):
> + * iommu_idx = 0: Non-secure transactions
> + * iommu_idx = 1: Secure transactions
> + *
> + * The iommu_idx parameter effectively implements the SEC_SID
> + * (Security Stream ID) attribute from the ARM SMMU architecture specification,
> + * which allows the SMMU to differentiate between different security state
> + * transactions at the hardware level.
> + */
> +static int smmuv3_attrs_to_index(IOMMUMemoryRegion *iommu, MemTxAttrs attrs)
> +{
> + return (int)smmuv3_attrs_to_sec_sid(attrs);
> +}
> +
> +static int smmuv3_num_indexes(IOMMUMemoryRegion *iommu)
> +{
> + /* Support 2 IOMMU indexes for now: NS/S */
> + return SMMU_SEC_SID_NUM;
> +}
> +
> /* Entry point to SMMU, does everything. */
> static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
> IOMMUAccessFlags flag, int iommu_idx)
> @@ -1087,7 +1119,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
> SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
> SMMUv3State *s = sdev->smmu;
> uint32_t sid = smmu_get_sid(sdev);
> - SMMUSecSID sec_sid = SMMU_SEC_SID_NS;
> + SMMUSecSID sec_sid = iommu_idx;
> SMMUv3RegBank *bank = smmuv3_bank(s, sec_sid);
> SMMUEventInfo event = {.type = SMMU_EVT_NONE,
> .sid = sid,
> @@ -2540,6 +2572,8 @@ static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
>
> imrc->translate = smmuv3_translate;
> imrc->notify_flag_changed = smmuv3_notify_flag_changed;
> + imrc->attrs_to_index = smmuv3_attrs_to_index;
> + imrc->num_indexes = smmuv3_num_indexes;
> }
>
> static const TypeInfo smmuv3_type_info = {
I noticed that this commit breaks boot of a simple Linux kernel. It was
already the case with v2, and it seems there is a deeper issue.
Virtio drive initialization hangs up with:
[ 9.421906] virtio_blk virtio2: [vda] 20971520 512-byte logical
blocks (10.7 GB/10.0 GiB)
smmuv3_translate_disable smmuv3-iommu-memory-region-24-3 sid=0x18 bypass
(smmu disabled) iova:0xfffff040 is_write=1
You can reproduce that with any kernel/rootfs, but if you want a simple
recipe (you need podman and qemu-user-static):
$ git clone https://github.com/pbo-linaro/qemu-linux-stack
$ cd qemu-linux-stack
$ ./build_kernel.sh
$ ./build_rootfs.sh
$ /path/to/qemu-system-aarch64 \
-nographic -M virt,iommu=smmuv3 -cpu max -kernel out/Image.gz \
-append "root=/dev/vda rw" out/host.ext4 -trace 'smmuv3*'
Looking more closely,
we reach SMMU_TRANS_DISABLE, because iommu_idx associated is 1.
This values comes from smmuv3_attrs_to_sec_sid, by reading attrs.space,
which is ArmSS_Secure.
The problem is that it's impossible to have anything Secure given that
all the code above runs in NonSecure world.
After investigation, the original value read from attrs.space has not
been set anywhere, and is just the default zero-initialized value coming
from pci_msi_trigger. It happens that it defaults to SEC_SID_S, which
probably matches your use case with hafnium, but it's an happy accident.
Looking at the SMMU spec, I understand that SEC_SID is configured for
each stream, and can change dynamically.
On the opposite, a StreamID is fixed and derived from PCI bus and slot
for a given device.
Thus, I think we are missing some logic here.
I'm still trying to understand where the SEC_SID should come from initially.
"The association between a device and the Security state of the
programming interface is a system-defined property."
Does it mean we should be able to set a QEMU property for any device?
Does anyone familiar with this has some idea?
As well, we should check the SEC_SID found based on SMMU_S_IDR1.SECURE_IMPL.
3.10.1 StreamID Security state (SEC_SID)
If SMMU_S_IDR1.SECURE_IMPL == 0, then incoming transactions have a
StreamID, and either:
• A SEC_SID identifier with a value of 0.
• No SEC_SID identifer, and SEC_SID is implicitly treated as 0.
If SMMU_S_IDR1.SECURE_IMPL == 1, incoming transactions have a StreamID,
and a SEC_SID identifier.
Regards,
Pierrick
next prev parent reply other threads:[~2025-10-15 0:03 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-12 15:06 [RFC v3 00/21] hw/arm/smmuv3: Add initial support for Secure State Tao Tang
2025-10-12 15:06 ` [RFC v3 01/21] hw/arm/smmuv3: Fix incorrect reserved mask for SMMU CR0 register Tao Tang
2025-10-12 15:06 ` [RFC v3 02/21] hw/arm/smmuv3: Correct SMMUEN field name in CR0 Tao Tang
2025-10-12 15:06 ` [RFC v3 03/21] hw/arm/smmuv3: Introduce secure registers Tao Tang
2025-10-12 15:06 ` [RFC v3 04/21] refactor: Move ARMSecuritySpace to a common header Tao Tang
2025-10-12 15:06 ` [RFC v3 05/21] hw/arm/smmuv3: Introduce banked registers for SMMUv3 state Tao Tang
2025-10-12 15:06 ` [RFC v3 06/21] hw/arm/smmuv3: Thread SEC_SID through helper APIs Tao Tang
2025-10-12 15:06 ` [RFC v3 07/21] hw/arm/smmuv3: Track SEC_SID in configs and events Tao Tang
2025-10-12 15:06 ` [RFC v3 08/21] hw/arm/smmuv3: Add separate address space for secure SMMU accesses Tao Tang
2025-10-12 15:06 ` [RFC v3 09/21] hw/arm/smmuv3: Plumb transaction attributes into config helpers Tao Tang
2025-10-12 15:06 ` [RFC v3 10/21] hw/arm/smmu-common: Key configuration cache on SMMUDevice and SEC_SID Tao Tang
2025-10-12 15:06 ` [RFC v3 11/21] hw/arm/smmuv3: Decode security attributes from descriptors Tao Tang
2025-10-12 15:12 ` [RFC v3 12/21] hw/arm/smmu-common: Implement secure state handling in ptw Tao Tang
2025-10-12 15:12 ` [RFC v3 13/21] hw/arm/smmuv3: Tag IOTLB cache keys with SEC_SID Tao Tang
2025-10-12 15:13 ` [RFC v3 14/21] hw/arm/smmuv3: Add access checks for MMIO registers Tao Tang
2025-10-12 15:13 ` [RFC v3 15/21] hw/arm/smmuv3: Determine register bank from MMIO offset Tao Tang
2025-10-14 23:31 ` Pierrick Bouvier
2025-10-12 15:13 ` [RFC v3 16/21] hw/arm/smmuv3: Implement SMMU_S_INIT register Tao Tang
2025-10-12 15:14 ` [RFC v3 17/21] hw/arm/smmuv3: Pass security state to command queue and IRQ logic Tao Tang
2025-10-12 15:14 ` [RFC v3 18/21] hw/arm/smmuv3: Harden security checks in MMIO handlers Tao Tang
2025-10-12 15:15 ` [RFC v3 19/21] hw/arm/smmuv3: Use iommu_index to represent the security context Tao Tang
2025-10-15 0:02 ` Pierrick Bouvier [this message]
2025-10-16 6:37 ` Tao Tang
2025-10-16 7:04 ` Pierrick Bouvier
2025-10-20 8:44 ` Tao Tang
2025-10-20 22:55 ` Pierrick Bouvier
2025-10-21 3:51 ` Tao Tang
2025-10-22 21:23 ` Pierrick Bouvier
2025-10-23 9:02 ` Tao Tang
2025-10-12 15:15 ` [RFC v3 20/21] hw/arm/smmuv3: Initialize the secure register bank Tao Tang
2025-10-12 15:16 ` [RFC v3 21/21] hw/arm/smmuv3: Add secure migration and enable secure state Tao Tang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=dbc4d33e-3477-4f39-a745-4fdc0866fc08@linaro.org \
--to=pierrick.bouvier@linaro.org \
--cc=chenbaozi@phytium.com.cn \
--cc=eric.auger@redhat.com \
--cc=jean-philippe@linaro.org \
--cc=mathieu.poirier@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=smostafa@google.com \
--cc=tangtao1634@phytium.com.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).