From nobody Thu Oct 22 19:25:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.dev Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1791547086354460.44866896780286; Fri, 9 Oct 2026 04:58:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1xF9EM-0004iT-TL; Fri, 09 Oct 2026 07:57:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1xF9EF-0004fB-NN for qemu-devel@nongnu.org; Fri, 09 Oct 2026 07:57:35 -0400 Received: from out-179.mta1.migadu.com ([2001:41d0:203:375::b3] helo=mta1.migadu.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1xF9EC-0001VB-3J for qemu-devel@nongnu.org; Fri, 09 Oct 2026 07:57:35 -0400 Received: by smtp.migadu.com with ESMTPS id ae2c93e32cc55c61; Fri, 09 Oct 2026 11:57:29 +0000 X-Envelope-To: qemu-devel@nongnu.org DKIM-Signature: a=rsa-sha256; bh=M+ZtplqIrDauigjFRV3gZedIQhB8KIDGj28jk0eQ/ZY=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1791547049; v=1; x=1792151849; b=GEwWzBBttIqU/eSld1pZDcN8hmMaoXvwDpl+WA/BQPJiShgyF1YOP3kgWm0Fi2ZUSocWr+qm XZ8YnN3gLREaH6wWWWXIe9agMmJfUy1EoiD1RtyM+PwhTWTBT7DKfDxDm5HuoX6l3cARG0XvFgq +Ph+RNM3Adiog404caOeB7EM= X-Envelope-To: qemu-devel@nongnu.org X-Mizu-Trace-ID: ae2c93e32cc55c61 X-Migadu-Flow: FLOW_OUT From: Fuad Tabba To: Peter Maydell Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, Richard Henderson , Gustavo Romero , Itaru Kitayama , Will Deacon , Fuad Tabba Subject: [PATCH v3 1/4] target/arm: Clear TTBR[5:0] from a 52-bit table base address Date: Fri, 9 Oct 2026 12:57:25 +0100 Message-Id: <20261009115728.1299384-2-fuad.tabba@linux.dev> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261009115728.1299384-1-fuad.tabba@linux.dev> References: <20261009115728.1299384-1-fuad.tabba@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2001:41d0:203:375::b3; envelope-from=fuad.tabba@linux.dev; helo=mta1.migadu.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1791547087735158501 Content-Type: text/plain; charset="utf-8" get_phys_addr_lpae() can read the first descriptor of a walk from the wrong address. This happens with a 52-bit OA when the initial lookup table has fewer than eight entries and its base address has bit 51 set, or bit 50 for a two-entry table. The walk then faults or translates through whatever that address holds. VTTBR walks for stage 2 take the same path. For example, the 16KB granule with a 48-bit VA has a two-entry level 0 (FEAT_LPA2). The 64KB granule with a 44-bit VA has a four-entry level 1 (FEAT_LPA). KVM's page_fault_test hangs on this in its 16KB, 52-bit PA guest mode under TCG, as reported on kvmarm. With a 52-bit OA, TTBR[5:2] hold bits [51:48] of the base address. Such a table is 64-byte aligned (R_KBLCR), so bits [5:0] of the base address are zero. get_phys_addr_lpae() ORs TTBR[5:2] into bits [51:48], but then clears only the bits in indexmask. For these tables indexmask covers fewer than six bits, so TTBR[5] stays in the address, and TTBR[4] too for a two-entry table. Clear TTBR[5:0] when forming a 52-bit table base address. Reported-by: Itaru Kitayama Link: https://lore.kernel.org/kvmarm/B4C0AC3E-6A4F-4A7B-B7BC-81207539115E@l= inux.dev/ Fixes: 7a928f43d872 ("target/arm: Implement FEAT_LPA") Cc: qemu-stable@nongnu.org Reviewed-by: Gustavo Romero Signed-off-by: Fuad Tabba --- target/arm/ptw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index de0435a58b..6cff52d592 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -2107,13 +2107,16 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1= Translate *ptw, descaddr =3D extract64(ttbr, 0, 48); =20 /* - * For FEAT_LPA and PS=3D6, bits [51:48] of descaddr are in [5:2] of T= TBR. + * With a 52-bit OA (FEAT_LPA or FEAT_LPA2), bits [51:48] of descaddr = are + * in [5:2] of TTBR, and bits [5:0] of the base address are zero: a ta= ble + * under 64 bytes is still 64-byte aligned (R_KBLCR). * * Otherwise, if the base address is out of range, raise AddressSizeFa= ult. * In the pseudocode, this is !IsZero(baseregister<47:outputsize>), * but we've just cleared the bits above 47, so simplify the test. */ if (outputsize > 48) { + descaddr &=3D ~MAKE_64BIT_MASK(0, 6); descaddr |=3D extract64(ttbr, 2, 4) << 48; } else if (descaddr >> outputsize) { level =3D 0; --=20 2.39.5 From nobody Thu Oct 22 19:25:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.dev Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1791547110185898.3233857519062; Fri, 9 Oct 2026 04:58:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1xF9EL-0004iP-KE; Fri, 09 Oct 2026 07:57:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1xF9EH-0004gE-5A for qemu-devel@nongnu.org; Fri, 09 Oct 2026 07:57:38 -0400 Received: from out-54.mta0.migadu.com ([2001:41d0:1004:224b::36] helo=mta0.migadu.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1xF9EF-0001WD-4I for qemu-devel@nongnu.org; Fri, 09 Oct 2026 07:57:36 -0400 Received: by smtp.migadu.com with ESMTPS id 16b2cbb997a424a7; Fri, 09 Oct 2026 11:57:32 +0000 X-Envelope-To: qemu-devel@nongnu.org DKIM-Signature: a=rsa-sha256; bh=OQQZ3ApuUEa7T2Q/cseY5Hv6MGtqtA7RpvRazwRx+M0=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1791547052; v=1; x=1792151852; b=pEmljV9DUOiFFVUoZl7QT3ebS4dXKIkoeJx2akEPRqG+3yA6W0c4zH1yFbZ5mDE1ThFMXZWp yhLfVDo3I5fLKESE/t7GElCPA7lLIHESh6T8rlfoDoTY6A9IUXAoagz0B/zWchpYsyhvLs/ErRQ ekO6/ql7RvXZxHdNlKqFCpI8= X-Envelope-To: qemu-devel@nongnu.org X-Mizu-Trace-ID: 16b2cbb997a424a7 X-Migadu-Flow: FLOW_OUT From: Fuad Tabba To: Peter Maydell Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, Richard Henderson , Gustavo Romero , Itaru Kitayama , Will Deacon , Fuad Tabba Subject: [PATCH v3 2/4] tests/tcg/aarch64: Add a test for a two-entry 52-bit TTBR table Date: Fri, 9 Oct 2026 12:57:26 +0100 Message-Id: <20261009115728.1299384-3-fuad.tabba@linux.dev> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261009115728.1299384-1-fuad.tabba@linux.dev> References: <20261009115728.1299384-1-fuad.tabba@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2001:41d0:1004:224b::36; envelope-from=fuad.tabba@linux.dev; helo=mta0.migadu.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1791547112169158500 Content-Type: text/plain; charset="utf-8" Add a test checking that, with a 52-bit OA, TTBR[4] of a two-entry level 0 table is taken only as base address bit 50, not also as bit 4. Reviewed-by: Gustavo Romero Signed-off-by: Fuad Tabba --- tests/tcg/aarch64/system/meson.build | 6 + tests/tcg/aarch64/system/ttbr-baddr.c | 153 ++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 tests/tcg/aarch64/system/ttbr-baddr.c diff --git a/tests/tcg/aarch64/system/meson.build b/tests/tcg/aarch64/syste= m/meson.build index f51feb253f..270d4d6c31 100644 --- a/tests/tcg/aarch64/system/meson.build +++ b/tests/tcg/aarch64/system/meson.build @@ -79,6 +79,12 @@ tests +=3D { '-semihosting-config', 'enable=3Don,arg=3D2', qemu_base_args] }, + 'ttbr-baddr.c': { + 'cflags': cflags, + 'qemu_args': ['-M', 'virt,virtualization=3Don', '-cpu', 'max', + '-semihosting-config', 'enable=3Don,arg=3D2', + qemu_base_args] + }, } =20 tests +=3D { diff --git a/tests/tcg/aarch64/system/ttbr-baddr.c b/tests/tcg/aarch64/syst= em/ttbr-baddr.c new file mode 100644 index 0000000000..b29c9e1ab0 --- /dev/null +++ b/tests/tcg/aarch64/system/ttbr-baddr.c @@ -0,0 +1,153 @@ +/* + * TTBR base address with a 52-bit layout and a small initial lookup table + * + * With a 52-bit OA, walk a two-entry level 0 table through an IPA with + * bit 50 set, which stage 2 maps back onto the table, so the walk + * succeeds only if TTBR[4] is cleared from bit 4 of the base address. + * + * Copyright (c) 2026 Google LLC + * Author: Fuad Tabba + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include + +/* from Linux's include/linux/stringify.h */ +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + +#define read_sysreg(r) ({ \ + uint64_t __val; \ + asm volatile("mrs %0, " __stringify(r) : "=3Dr" (__val)); \ + __val; \ +}) + +#define write_sysreg(r, v) do { \ + uint64_t __val =3D (uint64_t)(v); \ + asm volatile("msr " __stringify(r) ", %x0" \ + : : "rZ" (__val)); \ +} while (0) + +/* + * kernel.ld links the test at 1GB, so the tables below lie within the + * blocks mapped at RAM_BASE. + */ +#define RAM_BASE 0x40000000UL +#define HIGH_IPA (1UL << 50) +#define TEST_VA (0xffff000000000000UL | RAM_BASE) + +/* + * Stage 1: 16KB granule, 48-bit VA, so level 0 has two entries. + * Stage 2: 64KB granule, 52-bit IPA, mapping RAM at its own address and + * again at HIGH_IPA. + */ +static uint64_t s1_l0[2048] __attribute__((aligned(16384))); +static uint64_t s1_l1[2048] __attribute__((aligned(16384))); +static uint64_t s1_l2[2048] __attribute__((aligned(16384))); +static uint64_t s2_l1[1024] __attribute__((aligned(65536))); +static uint64_t s2_l2[8192] __attribute__((aligned(65536))); +static uint64_t s2_l2_high[8192] __attribute__((aligned(65536))); + +#define TCR_T0SZ(x) ((uint64_t)(x) << 0) +#define TCR_T1SZ(x) ((uint64_t)(x) << 16) +#define TCR_TG0_16K (2UL << 14) +#define TCR_TG1_16K (1UL << 30) +#define TCR_IPS_52 (6UL << 32) +#define TCR_DS (1UL << 59) + +#define VTCR_T0SZ(x) ((uint64_t)(x) << 0) +#define VTCR_SL0_L1 (2UL << 6) +#define VTCR_TG0_64K (1UL << 14) +#define VTCR_PS_52 (6UL << 16) +#define VTCR_RES1 (1UL << 31) + +#define HCR_VM (1UL << 0) +#define HCR_RW (1UL << 31) + +#define PAR_F (1UL << 0) +#define PAR_PA(par) ((par) & 0xfffffffff000UL) +#define S2_BLOCK ((1 << 10) | (3 << 6) | (0xf << 2) | 1) + +static void tlb_flush(void) +{ + asm volatile("dsb sy; tlbi alle1; dsb sy; isb" : : : "memory"); +} + +static uint64_t at(uint64_t ttbr1) +{ + uint64_t par; + + write_sysreg(ttbr1_el1, ttbr1); + tlb_flush(); + asm volatile("at s12e1r, %1; isb; mrs %0, par_el1" + : "=3Dr" (par) : "r" (TEST_VA)); + return par; +} + +static void setup_tables(void) +{ + /* Stage 1: TEST_VA -> RAM_BASE, 32MB block, AF */ + s1_l0[0] =3D (uint64_t)s1_l1 | 3; + s1_l1[0] =3D (uint64_t)s1_l2 | 3; + s1_l2[(RAM_BASE >> 25) & 0x7ff] =3D RAM_BASE | (1 << 10) | 1; + + /* Stage 2: 512MB blocks at RAM_BASE and HIGH_IPA | RAM_BASE, AF, RW */ + s2_l1[0] =3D (uint64_t)s2_l2 | 3; + s2_l1[HIGH_IPA >> 42] =3D (uint64_t)s2_l2_high | 3; + s2_l2[RAM_BASE >> 29] =3D RAM_BASE | S2_BLOCK; + s2_l2_high[RAM_BASE >> 29] =3D RAM_BASE | S2_BLOCK; +} + +static int check(const char *name, uint64_t par) +{ + int ok =3D !(par & PAR_F) && PAR_PA(par) =3D=3D RAM_BASE; + + ml_printf("%s: PAR_EL1=3D%lx %s\n", name, par, ok ? "ok" : "FAIL"); + return !ok; +} + +int main(void) +{ + uint64_t mmfr0 =3D read_sysreg(id_aa64mmfr0_el1); + uint64_t tcr =3D TCR_T0SZ(16) | TCR_T1SZ(16) | TCR_TG0_16K | TCR_TG1_1= 6K | + TCR_DS; + uint64_t base =3D (uint64_t)s1_l0; + int ret =3D 0; + + ml_printf("TTBR base address test\n"); + + /* + * PARange 52 bits (FEAT_LPA) and TGran16 with 52-bit addresses + * (FEAT_LPA2) + */ + if ((mmfr0 & 0xf) !=3D 6 || ((mmfr0 >> 20) & 0xf) !=3D 2) { + ml_printf("SKIP: no 52-bit PA or no FEAT_LPA2 with 16KB\n"); + return ret; + } + + /* + * The test runs at EL2 (arg=3D2) and walks the EL1&0 regime with AT, = so + * the EL1 MMU settings below only affect those walks. + */ + setup_tables(); + write_sysreg(mair_el1, 0xff); + write_sysreg(sctlr_el1, read_sysreg(sctlr_el1) | 1); + + /* + * 52-bit OA: TTBR[4] is base address bit 50, so with it set the + * level 0 table is at IPA HIGH_IPA | s1_l0. Stage 2 maps that IPA + * onto s1_l0 (through s2_l2_high), so the walk succeeds only if + * TTBR[4] does not also offset the two-entry table by 0x10. + */ + write_sysreg(vtcr_el2, VTCR_T0SZ(12) | VTCR_SL0_L1 | VTCR_TG0_64K | + VTCR_PS_52 | VTCR_RES1); + write_sysreg(vttbr_el2, (uint64_t)s2_l1); + write_sysreg(hcr_el2, HCR_RW | HCR_VM); + write_sysreg(tcr_el1, tcr | TCR_IPS_52); + ret |=3D check("ips52", at(base)); + ret |=3D check("ips52 ttbr[4]", at(base | (1 << 4))); + + return ret; +} --=20 2.39.5 From nobody Thu Oct 22 19:25:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.dev Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1791547101497459.4876853233311; Fri, 9 Oct 2026 04:58:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1xF9EK-0004hn-A3; Fri, 09 Oct 2026 07:57:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1xF9EH-0004gF-H8 for qemu-devel@nongnu.org; Fri, 09 Oct 2026 07:57:38 -0400 Received: from out-56.mta0.migadu.com ([2001:41d0:1004:224b::38] helo=mta0.migadu.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1xF9EF-0001XC-Py for qemu-devel@nongnu.org; Fri, 09 Oct 2026 07:57:37 -0400 Received: by smtp.migadu.com with ESMTPS id c5a0742f418a80cf; Fri, 09 Oct 2026 11:57:33 +0000 X-Envelope-To: qemu-devel@nongnu.org DKIM-Signature: a=rsa-sha256; bh=yOq/SAR2JwAJ7inL7GzZiSIF1VKEwUj39XzwFDpcgf8=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1791547053; v=1; x=1792151853; b=dK4Y3JQLNOQZOH+kdzpal5ypWhVKkX2RQbovEX8AcEoIuTu2zXobUthsw6cQZUqlq+0u3Nmt eJYbyWBkza2iqSfZ56Rqcy9sSMRvQrbpcPIJxxJ1nmw8oUdagyD72b7xgySAiowyabsXN2vGAqg QPGBP/xE2D2WY0UUfvLeOS/U= X-Envelope-To: qemu-devel@nongnu.org X-Mizu-Trace-ID: c5a0742f418a80cf X-Migadu-Flow: FLOW_OUT From: Fuad Tabba To: Peter Maydell Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, Richard Henderson , Gustavo Romero , Itaru Kitayama , Will Deacon , Fuad Tabba Subject: [PATCH v3 3/4] target/arm: Use the 52-bit TTBR base address layout when TCR.DS is set Date: Fri, 9 Oct 2026 12:57:27 +0100 Message-Id: <20261009115728.1299384-4-fuad.tabba@linux.dev> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261009115728.1299384-1-fuad.tabba@linux.dev> References: <20261009115728.1299384-1-fuad.tabba@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2001:41d0:1004:224b::38; envelope-from=fuad.tabba@linux.dev; helo=mta0.migadu.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1791547103853158500 Content-Type: text/plain; charset="utf-8" With TCR.DS set, TTBR[5:2] hold bits [51:48] of the translation table base address, whatever the OA size. If the effective OA size is below 52 bits, setting any of them is a level 0 Address size fault (AArch64_S1TTBaseAddress(), AArch64_S1Walk()). get_phys_addr_lpae() uses the 52-bit layout only when the OA size is over 48 bits. With TCR.DS set and an IPS of 48 bits, it takes TTBR[5:2] as base address bits [5:2] instead. A guest that sets them gets no fault: the walk either succeeds with TTBR[5:2] ignored, or reads its first descriptor from the wrong address. VTTBR walks with VTCR.DS take the same path. Use the 52-bit layout whenever TCR.DS is set, and check the whole base address against the OA size. Fixes: ef56c2425e5f ("target/arm: Implement FEAT_LPA2") Cc: qemu-stable@nongnu.org Reviewed-by: Gustavo Romero Signed-off-by: Fuad Tabba --- target/arm/ptw.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 6cff52d592..2e67d02493 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -2107,18 +2107,21 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1= Translate *ptw, descaddr =3D extract64(ttbr, 0, 48); =20 /* - * With a 52-bit OA (FEAT_LPA or FEAT_LPA2), bits [51:48] of descaddr = are - * in [5:2] of TTBR, and bits [5:0] of the base address are zero: a ta= ble - * under 64 bytes is still 64-byte aligned (R_KBLCR). + * With a 52-bit OA (FEAT_LPA or FEAT_LPA2), or with TCR.DS set at any= OA + * size, bits [51:48] of descaddr are in [5:2] of TTBR, and bits [5:0]= of + * the base address are zero: a table under 64 bytes is still 64-byte + * aligned (R_KBLCR). * - * Otherwise, if the base address is out of range, raise AddressSizeFa= ult. - * In the pseudocode, this is !IsZero(baseregister<47:outputsize>), - * but we've just cleared the bits above 47, so simplify the test. + * If the base address is out of range, raise AddressSizeFault. + * In the pseudocode, this is !IsZero(address) + * in AArch64_OAOutOfRange(), but descaddr has no bits set above 51, + * so simplify the test. */ - if (outputsize > 48) { + if (outputsize > 48 || param.ds) { descaddr &=3D ~MAKE_64BIT_MASK(0, 6); descaddr |=3D extract64(ttbr, 2, 4) << 48; - } else if (descaddr >> outputsize) { + } + if (descaddr >> outputsize) { level =3D 0; fi->type =3D ARMFault_AddressSize; goto do_fault; --=20 2.39.5 From nobody Thu Oct 22 19:25:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linux.dev Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 179154711977182.47596824468121; Fri, 9 Oct 2026 04:58:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1xF9ES-0004mk-Ix; Fri, 09 Oct 2026 07:57:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1xF9EP-0004jg-7F for qemu-devel@nongnu.org; Fri, 09 Oct 2026 07:57:45 -0400 Received: from out-193.mta1.migadu.com ([2001:41d0:203:375::c1] helo=mta1.migadu.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1xF9EK-0001Yl-Mj for qemu-devel@nongnu.org; Fri, 09 Oct 2026 07:57:43 -0400 Received: by smtp.migadu.com with ESMTPS id 1db8236c64979535; Fri, 09 Oct 2026 11:57:37 +0000 X-Envelope-To: qemu-devel@nongnu.org DKIM-Signature: a=rsa-sha256; bh=T5+vuArDf8zIBEFB0JTnGbnY6MQXVGtm4BY3GXQtyEQ=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1791547057; v=1; x=1792151857; b=BR4dCtx8F0I5NZf81VSHGilxwhjyC1T2mdHW0EWm46Egd5tWVbWlr/EPchnJ91GCUPpcdKBO hiOUGgbW5hr2Y3CdqJfQ8fjznkPBvYt7jO9fR08wZUs4eFB/t3Gr4M0s1x1EN3pn23/PFsCjplG V3HPXwX1y972ubIipALnmTKk= X-Envelope-To: qemu-devel@nongnu.org X-Mizu-Trace-ID: 1db8236c64979535 X-Migadu-Flow: FLOW_OUT From: Fuad Tabba To: Peter Maydell Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, Richard Henderson , Gustavo Romero , Itaru Kitayama , Will Deacon , Fuad Tabba Subject: [PATCH v3 4/4] tests/tcg/aarch64: Test the TTBR layout with TCR.DS and a 48-bit OA Date: Fri, 9 Oct 2026 12:57:28 +0100 Message-Id: <20261009115728.1299384-5-fuad.tabba@linux.dev> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20261009115728.1299384-1-fuad.tabba@linux.dev> References: <20261009115728.1299384-1-fuad.tabba@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2001:41d0:203:375::c1; envelope-from=fuad.tabba@linux.dev; helo=mta1.migadu.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1791547122199158500 Content-Type: text/plain; charset="utf-8" Extend the TTBR base address test to check that, with TCR.DS or VTCR.DS and a 48-bit OA, setting TTBR[5:2] is a level 0 Address size fault. Reviewed-by: Gustavo Romero Signed-off-by: Fuad Tabba --- tests/tcg/aarch64/system/ttbr-baddr.c | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/tcg/aarch64/system/ttbr-baddr.c b/tests/tcg/aarch64/syst= em/ttbr-baddr.c index b29c9e1ab0..20a240410d 100644 --- a/tests/tcg/aarch64/system/ttbr-baddr.c +++ b/tests/tcg/aarch64/system/ttbr-baddr.c @@ -4,6 +4,8 @@ * With a 52-bit OA, walk a two-entry level 0 table through an IPA with * bit 50 set, which stage 2 maps back onto the table, so the walk * succeeds only if TTBR[4] is cleared from bit 4 of the base address. + * With TCR.DS or VTCR.DS and a 48-bit OA, check that setting TTBR[5:2] + * is a level 0 Address size fault. * * Copyright (c) 2026 Google LLC * Author: Fuad Tabba @@ -42,10 +44,13 @@ * Stage 1: 16KB granule, 48-bit VA, so level 0 has two entries. * Stage 2: 64KB granule, 52-bit IPA, mapping RAM at its own address and * again at HIGH_IPA. + * Stage 2 with VTCR.DS: 16KB granule, 47-bit IPA, mapping RAM flat. */ static uint64_t s1_l0[2048] __attribute__((aligned(16384))); static uint64_t s1_l1[2048] __attribute__((aligned(16384))); static uint64_t s1_l2[2048] __attribute__((aligned(16384))); +static uint64_t s2ds_l1[2048] __attribute__((aligned(16384))); +static uint64_t s2ds_l2[2048] __attribute__((aligned(16384))); static uint64_t s2_l1[1024] __attribute__((aligned(65536))); static uint64_t s2_l2[8192] __attribute__((aligned(65536))); static uint64_t s2_l2_high[8192] __attribute__((aligned(65536))); @@ -54,20 +59,27 @@ static uint64_t s2_l2_high[8192] __attribute__((aligned= (65536))); #define TCR_T1SZ(x) ((uint64_t)(x) << 16) #define TCR_TG0_16K (2UL << 14) #define TCR_TG1_16K (1UL << 30) +#define TCR_IPS_48 (5UL << 32) #define TCR_IPS_52 (6UL << 32) #define TCR_DS (1UL << 59) =20 #define VTCR_T0SZ(x) ((uint64_t)(x) << 0) #define VTCR_SL0_L1 (2UL << 6) +#define VTCR_TG0_16K (2UL << 14) #define VTCR_TG0_64K (1UL << 14) +#define VTCR_PS_48 (5UL << 16) #define VTCR_PS_52 (6UL << 16) #define VTCR_RES1 (1UL << 31) +#define VTCR_DS (1UL << 32) =20 #define HCR_VM (1UL << 0) #define HCR_RW (1UL << 31) =20 #define PAR_F (1UL << 0) +#define PAR_FST(par) (((par) >> 1) & 0x3f) #define PAR_PA(par) ((par) & 0xfffffffff000UL) +#define FST_ADDR_SIZE_L0 0x00 + #define S2_BLOCK ((1 << 10) | (3 << 6) | (0xf << 2) | 1) =20 static void tlb_flush(void) @@ -86,6 +98,17 @@ static uint64_t at(uint64_t ttbr1) return par; } =20 +static uint64_t at_s1(uint64_t ttbr1) +{ + uint64_t par; + + write_sysreg(ttbr1_el1, ttbr1); + tlb_flush(); + asm volatile("at s1e1r, %1; isb; mrs %0, par_el1" + : "=3Dr" (par) : "r" (TEST_VA)); + return par; +} + static void setup_tables(void) { /* Stage 1: TEST_VA -> RAM_BASE, 32MB block, AF */ @@ -93,6 +116,10 @@ static void setup_tables(void) s1_l1[0] =3D (uint64_t)s1_l2 | 3; s1_l2[(RAM_BASE >> 25) & 0x7ff] =3D RAM_BASE | (1 << 10) | 1; =20 + /* Stage 2 with VTCR.DS: RAM_BASE -> RAM_BASE, 32MB block, AF, RW */ + s2ds_l1[0] =3D (uint64_t)s2ds_l2 | 3; + s2ds_l2[(RAM_BASE >> 25) & 0x7ff] =3D RAM_BASE | S2_BLOCK; + /* Stage 2: 512MB blocks at RAM_BASE and HIGH_IPA | RAM_BASE, AF, RW */ s2_l1[0] =3D (uint64_t)s2_l2 | 3; s2_l1[HIGH_IPA >> 42] =3D (uint64_t)s2_l2_high | 3; @@ -108,6 +135,15 @@ static int check(const char *name, uint64_t par) return !ok; } =20 +/* A level 0 Address size fault */ +static int check_fault(const char *name, uint64_t par) +{ + int ok =3D (par & PAR_F) && PAR_FST(par) =3D=3D FST_ADDR_SIZE_L0; + + ml_printf("%s: PAR_EL1=3D%lx %s\n", name, par, ok ? "ok" : "FAIL"); + return !ok; +} + int main(void) { uint64_t mmfr0 =3D read_sysreg(id_aa64mmfr0_el1); @@ -135,6 +171,25 @@ int main(void) write_sysreg(mair_el1, 0xff); write_sysreg(sctlr_el1, read_sysreg(sctlr_el1) | 1); =20 + /* + * TCR.DS with a 48-bit OA: TTBR[5:2] are base address bits [51:48], + * so setting any of them is a level 0 Address size fault. + */ + write_sysreg(hcr_el2, HCR_RW); + write_sysreg(tcr_el1, tcr | TCR_IPS_48); + ret |=3D check("ips48", at_s1(base)); + ret |=3D check_fault("ips48 ttbr[2]", at_s1(base | (1 << 2))); + ret |=3D check_fault("ips48 ttbr[4]", at_s1(base | (1 << 4))); + + /* The same for VTTBR, with VTCR.DS and a 48-bit PS */ + write_sysreg(vtcr_el2, VTCR_T0SZ(17) | VTCR_SL0_L1 | VTCR_TG0_16K | + VTCR_PS_48 | VTCR_RES1 | VTCR_DS); + write_sysreg(hcr_el2, HCR_RW | HCR_VM); + write_sysreg(vttbr_el2, (uint64_t)s2ds_l1); + ret |=3D check("ps48", at(base)); + write_sysreg(vttbr_el2, (uint64_t)s2ds_l1 | (1 << 2)); + ret |=3D check_fault("ps48 vttbr[2]", at(base)); + /* * 52-bit OA: TTBR[4] is base address bit 50, so with it set the * level 0 table is at IPA HIGH_IPA | s1_l0. Stage 2 maps that IPA --=20 2.39.5