From nobody Mon Feb 9 00:02:43 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.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=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1560615506; cv=none; d=zoho.com; s=zohoarc; b=G5wufL8X0BivKG0hyibgK/J5bKg7yFxdyDAVh+5Fg+K77PE90Bfpjvnjkr5iFqilAc0VmUIs0ldw6IaLz1IZbVEqAjXMaGyVavQXRuwf5nT4P4s4U3ja9uN7i5sQj5edr6s0FXh1jg0xQMNdsdcQaLrDtDy/T84F70UmQFKCfVE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1560615506; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=bClBz35C4eZKudRi6eke6WzC1/wABz1alcmA57Uujmc=; b=nbnBEYL+egK5327b9EVPVSLKb8GCdiTI1fv086HIa2Oyym9SlZ/auOohshKqf328ESlDQCN7ki8B2OcOHufI145gyonG4JNGjmJdd1R8wi2lQh0RW71J6lZrcBGYhJviAsUZK149MwW+XEP2aa23l+5G1TvahERKJgkoyPdp+oI= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.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 header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1560615506271759.3610599847605; Sat, 15 Jun 2019 09:18:26 -0700 (PDT) Received: from localhost ([::1]:33298 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hcBNf-0001Up-Nn for importer@patchew.org; Sat, 15 Jun 2019 12:18:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36095) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hcArJ-0004Sy-QP for qemu-devel@nongnu.org; Sat, 15 Jun 2019 11:44:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hcArH-0001dy-8O for qemu-devel@nongnu.org; Sat, 15 Jun 2019 11:44:49 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59592) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hcArB-0001KN-TN; Sat, 15 Jun 2019 11:44:42 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2E5053086246; Sat, 15 Jun 2019 15:44:41 +0000 (UTC) Received: from x1w.redhat.com (ovpn-204-41.brq.redhat.com [10.40.204.41]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7EABA1001B05; Sat, 15 Jun 2019 15:44:39 +0000 (UTC) From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Date: Sat, 15 Jun 2019 17:43:48 +0200 Message-Id: <20190615154352.26824-20-philmd@redhat.com> In-Reply-To: <20190615154352.26824-1-philmd@redhat.com> References: <20190615154352.26824-1-philmd@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Sat, 15 Jun 2019 15:44:41 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 19/23] target/arm: Move watchpoints APIs to helper.c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , qemu-arm@nongnu.org, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Samuel Ortiz , Robert Bradford Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Samuel Ortiz Here again, those APIs are not TCG dependent and can move to the always built helper.c. Signed-off-by: Samuel Ortiz Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Robert Bradford [PMD: Rebased] Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- target/arm/helper.c | 213 +++++++++++++++++++++++++++++++++++++++++ target/arm/internals.h | 6 ++ target/arm/op_helper.c | 213 ----------------------------------------- 3 files changed, 219 insertions(+), 213 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 8c32b2bc0d..8b7ce0561b 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11508,3 +11508,216 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, in= t flags) qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env)); } } + +/* Return true if the linked breakpoint entry lbn passes its checks */ +static bool linked_bp_matches(ARMCPU *cpu, int lbn) +{ + CPUARMState *env =3D &cpu->env; + uint64_t bcr =3D env->cp15.dbgbcr[lbn]; + int brps =3D extract32(cpu->dbgdidr, 24, 4); + int ctx_cmps =3D extract32(cpu->dbgdidr, 20, 4); + int bt; + uint32_t contextidr; + + /* + * Links to unimplemented or non-context aware breakpoints are + * CONSTRAINED UNPREDICTABLE: either behave as if disabled, or + * as if linked to an UNKNOWN context-aware breakpoint (in which + * case DBGWCR_EL1.LBN must indicate that breakpoint). + * We choose the former. + */ + if (lbn > brps || lbn < (brps - ctx_cmps)) { + return false; + } + + bcr =3D env->cp15.dbgbcr[lbn]; + + if (extract64(bcr, 0, 1) =3D=3D 0) { + /* Linked breakpoint disabled : generate no events */ + return false; + } + + bt =3D extract64(bcr, 20, 4); + + /* + * We match the whole register even if this is AArch32 using the + * short descriptor format (in which case it holds both PROCID and ASI= D), + * since we don't implement the optional v7 context ID masking. + */ + contextidr =3D extract64(env->cp15.contextidr_el[1], 0, 32); + + switch (bt) { + case 3: /* linked context ID match */ + if (arm_current_el(env) > 1) { + /* Context matches never fire in EL2 or (AArch64) EL3 */ + return false; + } + return (contextidr =3D=3D extract64(env->cp15.dbgbvr[lbn], 0, 32)); + case 5: /* linked address mismatch (reserved in AArch64) */ + case 9: /* linked VMID match (reserved if no EL2) */ + case 11: /* linked context ID and VMID match (reserved if no EL2) */ + default: + /* + * Links to Unlinked context breakpoints must generate no + * events; we choose to do the same for reserved values too. + */ + return false; + } + + return false; +} + +bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp) +{ + CPUARMState *env =3D &cpu->env; + uint64_t cr; + int pac, hmc, ssc, wt, lbn; + /* + * Note that for watchpoints the check is against the CPU security + * state, not the S/NS attribute on the offending data access. + */ + bool is_secure =3D arm_is_secure(env); + int access_el =3D arm_current_el(env); + + if (is_wp) { + CPUWatchpoint *wp =3D env->cpu_watchpoint[n]; + + if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) { + return false; + } + cr =3D env->cp15.dbgwcr[n]; + if (wp->hitattrs.user) { + /* + * The LDRT/STRT/LDT/STT "unprivileged access" instructions sh= ould + * match watchpoints as if they were accesses done at EL0, eve= n if + * the CPU is at EL1 or higher. + */ + access_el =3D 0; + } + } else { + uint64_t pc =3D is_a64(env) ? env->pc : env->regs[15]; + + if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc !=3D pc)= { + return false; + } + cr =3D env->cp15.dbgbcr[n]; + } + /* + * The WATCHPOINT_HIT flag guarantees us that the watchpoint is + * enabled and that the address and access type match; for breakpoints + * we know the address matched; check the remaining fields, including + * linked breakpoints. We rely on WCR and BCR having the same layout + * for the LBN, SSC, HMC, PAC/PMC and is-linked fields. + * Note that some combinations of {PAC, HMC, SSC} are reserved and + * must act either like some valid combination or as if the watchpoint + * were disabled. We choose the former, and use this together with + * the fact that EL3 must always be Secure and EL2 must always be + * Non-Secure to simplify the code slightly compared to the full + * table in the ARM ARM. + */ + pac =3D extract64(cr, 1, 2); + hmc =3D extract64(cr, 13, 1); + ssc =3D extract64(cr, 14, 2); + + switch (ssc) { + case 0: + break; + case 1: + case 3: + if (is_secure) { + return false; + } + break; + case 2: + if (!is_secure) { + return false; + } + break; + } + + switch (access_el) { + case 3: + case 2: + if (!hmc) { + return false; + } + break; + case 1: + if (extract32(pac, 0, 1) =3D=3D 0) { + return false; + } + break; + case 0: + if (extract32(pac, 1, 1) =3D=3D 0) { + return false; + } + break; + default: + g_assert_not_reached(); + } + + wt =3D extract64(cr, 20, 1); + lbn =3D extract64(cr, 16, 4); + + if (wt && !linked_bp_matches(cpu, lbn)) { + return false; + } + + return true; +} + +static bool check_watchpoints(ARMCPU *cpu) +{ + CPUARMState *env =3D &cpu->env; + int n; + + /* + * If watchpoints are disabled globally or we can't take debug + * exceptions here then watchpoint firings are ignored. + */ + if (extract32(env->cp15.mdscr_el1, 15, 1) =3D=3D 0 + || !arm_generate_debug_exceptions(env)) { + return false; + } + + for (n =3D 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) { + if (bp_wp_matches(cpu, n, true)) { + return true; + } + } + return false; +} + +bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) +{ + /* + * Called by core code when a CPU watchpoint fires; need to check if t= his + * is also an architectural watchpoint match. + */ + ARMCPU *cpu =3D ARM_CPU(cs); + + return check_watchpoints(cpu); +} + +vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len) +{ + ARMCPU *cpu =3D ARM_CPU(cs); + CPUARMState *env =3D &cpu->env; + + /* + * In BE32 system mode, target memory is stored byteswapped (on a + * little-endian host system), and by the time we reach here (via an + * opcode helper) the addresses of subword accesses have been adjusted + * to account for that, which means that watchpoints will not match. + * Undo the adjustment here. + */ + if (arm_sctlr_b(env)) { + if (len =3D=3D 1) { + addr ^=3D 3; + } else if (len =3D=3D 2) { + addr ^=3D 2; + } + } + + return addr; +} diff --git a/target/arm/internals.h b/target/arm/internals.h index 56281d8ece..fbbc701bb0 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1042,6 +1042,12 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t ad= dress, int *prot, bool *is_subpage, ARMMMUFaultInfo *fi, uint32_t *mregion); =20 +/* + * Returns true when the current CPU execution context matches + * the watchpoint or the breakpoint pointed at by n. + */ +bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp); + #ifdef TARGET_AARCH64 void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags); #else diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 63bce32810..68740e1b30 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -1018,185 +1018,6 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syn= drome) } } =20 -/* Return true if the linked breakpoint entry lbn passes its checks */ -static bool linked_bp_matches(ARMCPU *cpu, int lbn) -{ - CPUARMState *env =3D &cpu->env; - uint64_t bcr =3D env->cp15.dbgbcr[lbn]; - int brps =3D extract32(cpu->dbgdidr, 24, 4); - int ctx_cmps =3D extract32(cpu->dbgdidr, 20, 4); - int bt; - uint32_t contextidr; - - /* - * Links to unimplemented or non-context aware breakpoints are - * CONSTRAINED UNPREDICTABLE: either behave as if disabled, or - * as if linked to an UNKNOWN context-aware breakpoint (in which - * case DBGWCR_EL1.LBN must indicate that breakpoint). - * We choose the former. - */ - if (lbn > brps || lbn < (brps - ctx_cmps)) { - return false; - } - - bcr =3D env->cp15.dbgbcr[lbn]; - - if (extract64(bcr, 0, 1) =3D=3D 0) { - /* Linked breakpoint disabled : generate no events */ - return false; - } - - bt =3D extract64(bcr, 20, 4); - - /* - * We match the whole register even if this is AArch32 using the - * short descriptor format (in which case it holds both PROCID and ASI= D), - * since we don't implement the optional v7 context ID masking. - */ - contextidr =3D extract64(env->cp15.contextidr_el[1], 0, 32); - - switch (bt) { - case 3: /* linked context ID match */ - if (arm_current_el(env) > 1) { - /* Context matches never fire in EL2 or (AArch64) EL3 */ - return false; - } - return (contextidr =3D=3D extract64(env->cp15.dbgbvr[lbn], 0, 32)); - case 5: /* linked address mismatch (reserved in AArch64) */ - case 9: /* linked VMID match (reserved if no EL2) */ - case 11: /* linked context ID and VMID match (reserved if no EL2) */ - default: - /* - * Links to Unlinked context breakpoints must generate no - * events; we choose to do the same for reserved values too. - */ - return false; - } - - return false; -} - -static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp) -{ - CPUARMState *env =3D &cpu->env; - uint64_t cr; - int pac, hmc, ssc, wt, lbn; - /* - * Note that for watchpoints the check is against the CPU security - * state, not the S/NS attribute on the offending data access. - */ - bool is_secure =3D arm_is_secure(env); - int access_el =3D arm_current_el(env); - - if (is_wp) { - CPUWatchpoint *wp =3D env->cpu_watchpoint[n]; - - if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) { - return false; - } - cr =3D env->cp15.dbgwcr[n]; - if (wp->hitattrs.user) { - /* - * The LDRT/STRT/LDT/STT "unprivileged access" instructions sh= ould - * match watchpoints as if they were accesses done at EL0, eve= n if - * the CPU is at EL1 or higher. - */ - access_el =3D 0; - } - } else { - uint64_t pc =3D is_a64(env) ? env->pc : env->regs[15]; - - if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc !=3D pc)= { - return false; - } - cr =3D env->cp15.dbgbcr[n]; - } - /* - * The WATCHPOINT_HIT flag guarantees us that the watchpoint is - * enabled and that the address and access type match; for breakpoints - * we know the address matched; check the remaining fields, including - * linked breakpoints. We rely on WCR and BCR having the same layout - * for the LBN, SSC, HMC, PAC/PMC and is-linked fields. - * Note that some combinations of {PAC, HMC, SSC} are reserved and - * must act either like some valid combination or as if the watchpoint - * were disabled. We choose the former, and use this together with - * the fact that EL3 must always be Secure and EL2 must always be - * Non-Secure to simplify the code slightly compared to the full - * table in the ARM ARM. - */ - pac =3D extract64(cr, 1, 2); - hmc =3D extract64(cr, 13, 1); - ssc =3D extract64(cr, 14, 2); - - switch (ssc) { - case 0: - break; - case 1: - case 3: - if (is_secure) { - return false; - } - break; - case 2: - if (!is_secure) { - return false; - } - break; - } - - switch (access_el) { - case 3: - case 2: - if (!hmc) { - return false; - } - break; - case 1: - if (extract32(pac, 0, 1) =3D=3D 0) { - return false; - } - break; - case 0: - if (extract32(pac, 1, 1) =3D=3D 0) { - return false; - } - break; - default: - g_assert_not_reached(); - } - - wt =3D extract64(cr, 20, 1); - lbn =3D extract64(cr, 16, 4); - - if (wt && !linked_bp_matches(cpu, lbn)) { - return false; - } - - return true; -} - -static bool check_watchpoints(ARMCPU *cpu) -{ - CPUARMState *env =3D &cpu->env; - int n; - - /* - * If watchpoints are disabled globally or we can't take debug - * exceptions here then watchpoint firings are ignored. - */ - if (extract32(env->cp15.mdscr_el1, 15, 1) =3D=3D 0 - || !arm_generate_debug_exceptions(env)) { - return false; - } - - for (n =3D 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) { - if (bp_wp_matches(cpu, n, true)) { - return true; - } - } - return false; -} - static bool check_breakpoints(ARMCPU *cpu) { CPUARMState *env =3D &cpu->env; @@ -1227,40 +1048,6 @@ void HELPER(check_breakpoints)(CPUARMState *env) } } =20 -bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) -{ - /* - * Called by core code when a CPU watchpoint fires; need to check if t= his - * is also an architectural watchpoint match. - */ - ARMCPU *cpu =3D ARM_CPU(cs); - - return check_watchpoints(cpu); -} - -vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len) -{ - ARMCPU *cpu =3D ARM_CPU(cs); - CPUARMState *env =3D &cpu->env; - - /* - * In BE32 system mode, target memory is stored byteswapped (on a - * little-endian host system), and by the time we reach here (via an - * opcode helper) the addresses of subword accesses have been adjusted - * to account for that, which means that watchpoints will not match. - * Undo the adjustment here. - */ - if (arm_sctlr_b(env)) { - if (len =3D=3D 1) { - addr ^=3D 3; - } else if (len =3D=3D 2) { - addr ^=3D 2; - } - } - - return addr; -} - void arm_debug_excp_handler(CPUState *cs) { /* Called by core code when a watchpoint or breakpoint fires; --=20 2.20.1