From patchwork Wed Jan 23 21:32:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 1030208 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=os.amperecomputing.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=amperemail.onmicrosoft.com header.i=@amperemail.onmicrosoft.com header.b="CbZup8Eo"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43lJsB6Y4Cz9s55 for ; Thu, 24 Jan 2019 08:51:42 +1100 (AEDT) Received: from localhost ([127.0.0.1]:42445 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gmQQu-00050E-NH for incoming@patchwork.ozlabs.org; Wed, 23 Jan 2019 16:51:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:43481) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gmQOC-0002o2-JJ for qemu-devel@nongnu.org; Wed, 23 Jan 2019 16:48:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gmQ8w-0005AR-Kz for qemu-devel@nongnu.org; Wed, 23 Jan 2019 16:33:08 -0500 Received: from mail-co1nam04on071f.outbound.protection.outlook.com ([2a01:111:f400:fe4d::71f]:57720 helo=NAM04-CO1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gmQ8m-0004Y5-LC; Wed, 23 Jan 2019 16:32:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amperemail.onmicrosoft.com; s=selector1-os-amperecomputing-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ySzXLXDYBfTCHgr4DN+CK+z2ilzj31VdmkW3L9/wmow=; b=CbZup8Eo+zonjZjNlAjEABN+uKpNRfTO+FW9xiK6C28/HuISPG/LhSP8vNlKmVtnTnQ7vo6HP+4XJiPF35UwV6XjLpFshCq/zC+pGMK8eetCw4AmXFaMF4TjSDu5Uya2dOCMI28bHCC8jVUmKGhgXpL+28c6VUvXUxez08CPCqA= Received: from DM6PR01MB4825.prod.exchangelabs.com (20.177.218.222) by DM6PR01MB5067.prod.exchangelabs.com (20.176.120.223) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1537.31; Wed, 23 Jan 2019 21:32:50 +0000 Received: from DM6PR01MB4825.prod.exchangelabs.com ([fe80::8054:2484:c74a:d082]) by DM6PR01MB4825.prod.exchangelabs.com ([fe80::8054:2484:c74a:d082%3]) with mapi id 15.20.1558.016; Wed, 23 Jan 2019 21:32:48 +0000 From: Aaron Lindsay OS To: "qemu-arm@nongnu.org" , Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite , Richard Henderson Thread-Topic: [PATCH v11 1/2] target/arm: Send interrupts on PMU counter overflow Thread-Index: AQHUs2Mvgkp0W1G2TUKxeLYaqfEzjQ== Date: Wed, 23 Jan 2019 21:32:47 +0000 Message-ID: <20190123213227.17077-2-aaron@os.amperecomputing.com> References: <20190123213227.17077-1-aaron@os.amperecomputing.com> In-Reply-To: <20190123213227.17077-1-aaron@os.amperecomputing.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: CY4PR18CA0051.namprd18.prod.outlook.com (2603:10b6:903:13f::13) To DM6PR01MB4825.prod.exchangelabs.com (2603:10b6:5:6b::30) authentication-results: spf=none (sender IP is ) smtp.mailfrom=aaron@os.amperecomputing.com; x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.20.1 x-originating-ip: [216.85.170.152] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DM6PR01MB5067; 6:9iNTT4qePzUmStpJEVeKICYDGjBd9kMKkIf+IGbFw4KLReUD9pImMlos9phkA5hF7Uo3NtGOsubPgkg5ksn+Uhd7EirhM/4H8aFlvp9hAuA9tFVewfDvBjLSy2tsIl8ApY6q8wTXlC7sMP7iuAwTq8YFTQoQasfGH9D7/oE+DeeQj7SUxbxy3MmsOUZHhx/C//CC3Yy1LGR0IlO1vWx5qTUEAqQ+T7VkOgWvEjbKJPHzB99vd7m0kyk3ltJ+GreP8F17P2Rhsp4+qgHRqrNLHApxaFmrWhxZ9XqfMUUz46v/tk7bpTf7yqDoeuVSP7igwNIGS5pRsy3nFfcgEoEQahGCiKesuQGGytzQjVVmRuhaYwDEl7XjpJEY8EtkzYXif888NrwywnzTiWJkXjs3+eDzYuzX4B5EX6FytNP9xHupDi0dDWj0f1D++9dcygKm2dHAVv7KynFG56iQpXUY1A==; 5:GU2lWhbHb8W2G/vnm0XcA56RZxs8UZBe6LpIsbahaB+wBEfdzUvdwFSe17wxlvqvZo9aKQtJl4ZUj2ydUoUQmJOf2QmrJ34NMeoHWqW01rbnALbK2FogOwLE2RlxbMW/bCY3RzWoVbeDXBRiLDJUKBIVdvl6Hf3CGZ65l0+3ObkWAo5stCabaAg08REqv7vnjuhSlgDOcf5tK8m+EzBOTg==; 7:iqbX5khKBg+WBe6uCHl7B44cYGRqDLPECUzJFES+6oAAsV6g9AJZmxWlBHHArnTlB5X20dkc8YLkAgAL8OBCSkDAF+lf0YkhmoyEGhy9rWZDlZDXPQDQWOchYRxvx6dYQ5RWR5K2u8p+0sHb5SsK7A== x-ms-office365-filtering-correlation-id: 928a4119-0e22-48fb-e9c0-08d6817a51b6 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600110)(711020)(4605077)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:DM6PR01MB5067; x-ms-traffictypediagnostic: DM6PR01MB5067: x-microsoft-antispam-prvs: x-forefront-prvs: 0926B0E013 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(396003)(376002)(346002)(366004)(136003)(39840400004)(189003)(199004)(102836004)(186003)(316002)(6486002)(105586002)(71200400001)(71190400001)(106356001)(110136005)(6512007)(54906003)(3846002)(6116002)(97736004)(256004)(86362001)(52116002)(26005)(6436002)(386003)(76176011)(99286004)(2501003)(6506007)(8676002)(81166006)(81156014)(8936002)(50226002)(68736007)(14444005)(7736002)(446003)(11346002)(2906002)(305945005)(53936002)(14454004)(25786009)(1076003)(107886003)(478600001)(39060400002)(66066001)(4326008)(486006)(476003)(2616005); DIR:OUT; SFP:1102; SCL:1; SRVR:DM6PR01MB5067; H:DM6PR01MB4825.prod.exchangelabs.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:0; received-spf: None (protection.outlook.com: os.amperecomputing.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: sg2EioCCniRX/PmNvDFJkLLD/J4HzkIjjHpNsjcB2mcKJWJdozOiQ1rmyGMJES5NXOb50+A4KpWR6DSmu7ATJlGmTq35oEPYtrYBq4VTVWGJ1XWvgO1QnQ1wOysjVU/DM7WrJ+ISAP14UmBiPEJIQzGMPbg2pgICyktx5YqS9PNlzTaRvRDUTBTqQaYC2SxQVYlBIQJuShWXS4n7OhCBYMY0t/k6tDC2eMnI/jw0oaJLjmjVY1pW9ilW7R6JSuHA5RW+IUk/9LQ4aBb5doX++15fmmSB3hMHcohOG2axMl8K+Il+F8Com9vNiOoczDse5K7grrrdynCB2u1M4lsdwiWd+SuxZQ04u+PlEd+iap89IK+Q9X3aJ8fSSXt/8Es1hjXeyPMcecclNQRRq4A+X8TqmEYujXTAGgrozLRufWY= MIME-Version: 1.0 X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 928a4119-0e22-48fb-e9c0-08d6817a51b6 X-MS-Exchange-CrossTenant-originalarrivaltime: 23 Jan 2019 21:32:46.7102 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR01MB5067 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 2a01:111:f400:fe4d::71f Subject: [Qemu-devel] [PATCH v11 1/2] target/arm: Send interrupts on PMU counter overflow X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Aaron Lindsay OS , Michael Spradling , "qemu-devel@nongnu.org" , Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Whenever we notice that a counter overflow has occurred, send an interrupt. This is made more reliable with the addition of a timer in a follow-on commit. Signed-off-by: Aaron Lindsay Reviewed-by: Richard Henderson --- target/arm/helper.c | 61 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 31273fb8de..df2f3dd42a 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -977,6 +977,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { /* Definitions for the PMU registers */ #define PMCRN_MASK 0xf800 #define PMCRN_SHIFT 11 +#define PMCRLC 0x40 #define PMCRDP 0x10 #define PMCRD 0x8 #define PMCRC 0x4 @@ -1293,6 +1294,13 @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter) return enabled && !prohibited && !filtered; } +static void pmu_update_irq(CPUARMState *env) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) && + (env->cp15.c9_pminten & env->cp15.c9_pmovsr)); +} + /* * Ensure c15_ccnt is the guest-visible count so that operations such as * enabling/disabling the counter or filtering, modifying the count itself, @@ -1310,7 +1318,16 @@ void pmccntr_op_start(CPUARMState *env) eff_cycles /= 64; } - env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta; + uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta; + + uint64_t overflow_mask = env->cp15.c9_pmcr & PMCRLC ? \ + INT64_MIN : INT32_MIN; + if (env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask) { + env->cp15.c9_pmovsr |= (1 << 31); + pmu_update_irq(env); + } + + env->cp15.c15_ccnt = new_pmccntr; } env->cp15.c15_ccnt_delta = cycles; } @@ -1345,8 +1362,13 @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter) } if (pmu_counter_enabled(env, counter)) { - env->cp15.c14_pmevcntr[counter] = - count - env->cp15.c14_pmevcntr_delta[counter]; + uint32_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter]; + + if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & INT32_MIN) { + env->cp15.c9_pmovsr |= (1 << counter); + pmu_update_irq(env); + } + env->cp15.c14_pmevcntr[counter] = new_pmevcntr; } env->cp15.c14_pmevcntr_delta[counter] = count; } @@ -1423,7 +1445,20 @@ static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri, /* counter is SW_INCR */ (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) { pmevcntr_op_start(env, i); - env->cp15.c14_pmevcntr[i]++; + + /* + * Detect if this write causes an overflow since we can't predict + * PMSWINC overflows like we can for other events + */ + uint32_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1; + + if (env->cp15.c14_pmevcntr[i] & ~new_pmswinc & INT32_MIN) { + env->cp15.c9_pmovsr |= (1 << i); + pmu_update_irq(env); + } + + env->cp15.c14_pmevcntr[i] = new_pmswinc; + pmevcntr_op_finish(env, i); } } @@ -1508,6 +1543,7 @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri, { value &= pmu_counter_mask(env); env->cp15.c9_pmovsr &= ~value; + pmu_update_irq(env); } static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1515,6 +1551,7 @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri, { value &= pmu_counter_mask(env); env->cp15.c9_pmovsr |= value; + pmu_update_irq(env); } static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1701,6 +1738,7 @@ static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri, /* We have no event counters so only the C bit can be changed */ value &= pmu_counter_mask(env); env->cp15.c9_pminten |= value; + pmu_update_irq(env); } static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1708,6 +1746,7 @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, { value &= pmu_counter_mask(env); env->cp15.c9_pminten &= ~value; + pmu_update_irq(env); } static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1846,7 +1885,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .writefn = pmcntenclr_write }, { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3, - .access = PL0_RW, + .access = PL0_RW, .type = ARM_CP_IO, .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr), .accessfn = pmreg_access, .writefn = pmovsr_write, @@ -1854,16 +1893,18 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { { .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3, .access = PL0_RW, .accessfn = pmreg_access, - .type = ARM_CP_ALIAS, + .type = ARM_CP_ALIAS | ARM_CP_IO, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), .writefn = pmovsr_write, .raw_writefn = raw_write }, { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4, - .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW, + .access = PL0_W, .accessfn = pmreg_access_swinc, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .writefn = pmswinc_write }, { .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4, - .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW, + .access = PL0_W, .accessfn = pmreg_access_swinc, + .type = ARM_CP_NO_RAW | ARM_CP_IO, .writefn = pmswinc_write }, { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, .access = PL0_RW, .type = ARM_CP_ALIAS, @@ -2050,14 +2091,14 @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = { /* PMOVSSET is not implemented in v7 before v7ve */ { .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3, .access = PL0_RW, .accessfn = pmreg_access, - .type = ARM_CP_ALIAS, + .type = ARM_CP_ALIAS | ARM_CP_IO, .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr), .writefn = pmovsset_write, .raw_writefn = raw_write }, { .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3, .access = PL0_RW, .accessfn = pmreg_access, - .type = ARM_CP_ALIAS, + .type = ARM_CP_ALIAS | ARM_CP_IO, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), .writefn = pmovsset_write, .raw_writefn = raw_write },