From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A50C5C87FCC for ; Sun, 27 Jul 2025 08:19:03 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ufwQM-00057r-5f; Sun, 27 Jul 2025 04:08:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ufwPM-0001Yi-Uo for qemu-devel@nongnu.org; Sun, 27 Jul 2025 04:07:01 -0400 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1ufwPK-0004k2-Hx for qemu-devel@nongnu.org; Sun, 27 Jul 2025 04:07:00 -0400 Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-234bfe37cccso28438025ad.0 for ; Sun, 27 Jul 2025 01:06:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1753603617; x=1754208417; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oAmWUG1RCHR1wBPHXNwosNOvy6qQDPfTqzqzFrLqHas=; b=WN9QlvB6idXj/5YWH8S02Uqc5ZNatnL7wQR+tvw0ntnQAQ5FIezgZqNqp+umu12xL/ WB8cWHMuj6sXAA/tlQicyXyasYOSAn4427FvUAB99xqckDdo/qpC8pYplkU2G0PxZmbx DMCE3+HomfPZTaVw+fmKkQK0YcaWVnGAHFf5tBLnvw0fC06m4rHqhCjtdNXj68tVu+eV 4gcwMrRfsasuG7a0kdmhb7CljWziIIlIy3X0iDyfZoWbcKfrdQxgAY7Ar6QMN1zjZ1tb Ps9X5qRnYNAe98Pgc15W0/5XDsqRmqROccYpU03o2MGmHqr1zQercxBZ5KOK6TAxm+RJ BFLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753603617; x=1754208417; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oAmWUG1RCHR1wBPHXNwosNOvy6qQDPfTqzqzFrLqHas=; b=qJXLCczoAooTgZKD8faEjY5L0eYV2q+x4boDeNej3v01QoJO2FnfITgGicG8fSnt26 pmqbRKxoJLbRbPraYQm1dKI6y9haCwp+hUDLPXNcVA210wrtIOLQo9HaR+58Ce/ekRO6 d/0pSn3Bs+HbGgypoKV0kAvNKljNSRwbeGmTMjj4nnrlAdHQPBTCLFz7bpXg05CX9eNj cKRP6IRv6MDJASIN0EjJ37rQvT9WGn4oH7feDfZKl1YmgzHgFo62+xthEJM1RyopW/XU O2cyB+Ik8hGDTrXB8fsrO5qQ1X6rIilpZKXv6Z14YojV7BBbIV6SHuMq4S4LOJ2CX5Ql 7b1Q== X-Gm-Message-State: AOJu0YyxoKiJknvk9Y3Mrqm1qzgOEpg2RhVDut6L4OmoJnjcWgA1Z426 CWIzdTXPxBhpLtvy7XR0igQ8MTVKfQ7NEkg2kUl+WM38F5qK49owoX+MPSseT4M/TXQBc3CVHEi TUBRP X-Gm-Gg: ASbGncsRP8nnMvrY3+QneeSBerpXRUhlatKzhonegmWcI85XdYHOYMVPGDRkWnWLqeB LLUtsMbsR/OzKJh8hQaYz+oq5d+Mi7ikHlm/15gZ3ymRrwzWNNQqi+QjnYx++wUAsWDylpXj/BQ B0BiZvNhwASHJs1PYO6dLIqPvE7+UnxChHs3ugnpY4YtEVWs3pmbg0eFK2tgVxnpF1klVIzqDQ0 8cMsTFxs0Pt/tgXgPca4q2fUtVt9Mejkkhyh6SGLQFT5Prtv1wTjJKWsSL/p/XrMEieXoPArrr0 la25lqgUxKmzLhzM1yuHC5WnlZuort+AOPoyUiomeSvqVpvC2aY3wxzXo99IxYboh0UCA7lcW0P zOsR+Gh9ij2HTmJLJI+a3lza3hywsJv6N25GcArz6PS5lHdpTbbiS9xrfWaX4sqyh3DXr7Ie9/z uALzrK0tFNjg== X-Google-Smtp-Source: AGHT+IHuNkOu00Nar9cfOXak0qgpjdu+yHE8bl8psmZx7AJj/VK3tYntnqLLutsJ2jLBpdNsNmPNDA== X-Received: by 2002:a17:902:f612:b0:240:e9d:6c43 with SMTP id d9443c01a7336-2400e9d6f7emr12389695ad.51.1753603617060; Sun, 27 Jul 2025 01:06:57 -0700 (PDT) Received: from localhost.localdomain (syn-098-150-199-049.res.spectrum.com. [98.150.199.49]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-24011d5bcbesm3908065ad.10.2025.07.27.01.06.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Jul 2025 01:06:56 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org Subject: [PATCH 49/82] target/arm: Implement EXLOCKException for ELR_ELx and SPSR_ELx Date: Sat, 26 Jul 2025 22:02:21 -1000 Message-ID: <20250727080254.83840-50-richard.henderson@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250727080254.83840-1-richard.henderson@linaro.org> References: <20250727080254.83840-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::635; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x635.google.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, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org If PSTATE.EXLOCK is set, and the GCS EXLOCK enable bit is set, and nested virt is in the appropriate state, then we need to raise an EXLOCK exception. Since PSTATE.EXLOCK cannot be set without GCS being present and enabled, no explicit check for GCS is required. Signed-off-by: Richard Henderson --- target/arm/cpregs.h | 3 ++ target/arm/cpu.h | 1 + target/arm/helper.c | 83 +++++++++++++++++++++++++++++++++++--- target/arm/tcg/op_helper.c | 4 ++ 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h index bc6adf5956..15894332b2 100644 --- a/target/arm/cpregs.h +++ b/target/arm/cpregs.h @@ -346,6 +346,9 @@ typedef enum CPAccessResult { * specified target EL. */ CP_ACCESS_UNDEFINED = (2 << 2), + + /* Access fails with EXLOCK, a GCS exception syndrome. */ + CP_ACCESS_EXLOCK = (3 << 2), } CPAccessResult; /* Indexes into fgt_read[] */ diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 7769c4ae3c..8eee722a9e 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1520,6 +1520,7 @@ void pmu_init(ARMCPU *cpu); #define PSTATE_C (1U << 29) #define PSTATE_Z (1U << 30) #define PSTATE_N (1U << 31) +#define PSTATE_EXLOCK (1ULL << 34) #define PSTATE_NZCV (PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V) #define PSTATE_DAIF (PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F) #define CACHED_PSTATE_BITS (PSTATE_NZCV | PSTATE_DAIF | PSTATE_BTYPE) diff --git a/target/arm/helper.c b/target/arm/helper.c index e404ba0f71..2514a03c0e 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3435,6 +3435,77 @@ static CPAccessResult access_nv1(CPUARMState *env, const ARMCPRegInfo *ri, return CP_ACCESS_OK; } +static CPAccessResult access_exlock_el1(CPUARMState *env, + const ARMCPRegInfo *ri, bool isread) +{ + int el = arm_current_el(env); + + if (el == 1) { + uint64_t hcr = arm_hcr_el2_eff(env); + + /* + * EXLOCK check is disabled for NVx in 'x11'. + * Since we have to diagnose that, dispatch NV1 trap too. + */ + if ((hcr & HCR_NV) && (hcr & HCR_NV1)) { + if (hcr & HCR_NV2) { + return CP_ACCESS_OK; + } + return CP_ACCESS_TRAP_EL2; + } + } + + if (!isread && + (env->pstate & PSTATE_EXLOCK) && + (el_is_in_host(env, el) ? el == 2 : el == 1) && + (env->cp15.gcscr_el[el] & GCSCR_EXLOCKEN)) { + return CP_ACCESS_EXLOCK; + } + return CP_ACCESS_OK; +} + +static CPAccessResult access_exlock_el2(CPUARMState *env, + const ARMCPRegInfo *ri, bool isread) +{ + int el = arm_current_el(env); + + if (el == 3) { + return CP_ACCESS_OK; + } + if (el == 1) { + uint64_t hcr = arm_hcr_el2_eff(env); + + /* + * EXLOCK check is disabled for NVx in 'xx1'. + * Since we have to diagnose that, dispatch NV1 trap too. + */ + if (hcr & HCR_NV) { + if (hcr & HCR_NV2) { + return CP_ACCESS_OK; + } + return CP_ACCESS_TRAP_EL2; + } + } + + if (!isread && + (env->pstate & PSTATE_EXLOCK) && + (env->cp15.gcscr_el[el] & GCSCR_EXLOCKEN)) { + return CP_ACCESS_EXLOCK; + } + return CP_ACCESS_OK; +} + +static CPAccessResult access_exlock_el3(CPUARMState *env, + const ARMCPRegInfo *ri, bool isread) +{ + if (!isread && + (env->pstate & PSTATE_EXLOCK) && + (env->cp15.gcscr_el[3] & GCSCR_EXLOCKEN)) { + return CP_ACCESS_EXLOCK; + } + return CP_ACCESS_OK; +} + #ifdef CONFIG_USER_ONLY /* * `IC IVAU` is handled to improve compatibility with JITs that dual-map their @@ -3606,13 +3677,13 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64, .type = ARM_CP_ALIAS, .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1, - .access = PL1_RW, .accessfn = access_nv1, + .access = PL1_RW, .accessfn = access_exlock_el1, .nv2_redirect_offset = 0x230 | NV2_REDIR_NV1, .fieldoffset = offsetof(CPUARMState, elr_el[1]) }, { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64, .type = ARM_CP_ALIAS, .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0, - .access = PL1_RW, .accessfn = access_nv1, + .access = PL1_RW, .accessfn = access_exlock_el1, .nv2_redirect_offset = 0x160 | NV2_REDIR_NV1, .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) }, /* @@ -4083,7 +4154,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64, .type = ARM_CP_ALIAS | ARM_CP_NV2_REDIRECT, .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1, - .access = PL2_RW, + .access = PL2_RW, .accessfn = access_exlock_el2, .fieldoffset = offsetof(CPUARMState, elr_el[2]) }, { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH, .type = ARM_CP_NV2_REDIRECT, @@ -4101,7 +4172,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64, .type = ARM_CP_ALIAS | ARM_CP_NV2_REDIRECT, .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0, - .access = PL2_RW, + .access = PL2_RW, .accessfn = access_exlock_el2, .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) }, { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0, @@ -4383,7 +4454,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64, .type = ARM_CP_ALIAS, .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1, - .access = PL3_RW, + .access = PL3_RW, .accessfn = access_exlock_el3, .fieldoffset = offsetof(CPUARMState, elr_el[3]) }, { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0, @@ -4394,7 +4465,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64, .type = ARM_CP_ALIAS, .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0, - .access = PL3_RW, + .access = PL3_RW, .accessfn = access_exlock_el3, .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) }, { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0, diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c index 46a3b911ec..56e117c01e 100644 --- a/target/arm/tcg/op_helper.c +++ b/target/arm/tcg/op_helper.c @@ -887,6 +887,10 @@ const void *HELPER(access_check_cp_reg)(CPUARMState *env, uint32_t key, } syndrome = syn_uncategorized(); break; + case CP_ACCESS_EXLOCK: + /* CP_ACCESS_EXLOCK is always directed to the current EL */ + syndrome = syn_gcs_exlock(); + break; default: g_assert_not_reached(); } -- 2.43.0