From patchwork Tue Dec 11 15:20:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 1011142 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=2001:4830:134:3::11; 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="mG14ExAK"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43DkJB6Byzz9s5c for ; Wed, 12 Dec 2018 02:24:26 +1100 (AEDT) Received: from localhost ([::1]:38637 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gWjtY-0006tS-Cp for incoming@patchwork.ozlabs.org; Tue, 11 Dec 2018 10:24:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57255) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gWjpo-0003sb-8R for qemu-devel@nongnu.org; Tue, 11 Dec 2018 10:20:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gWjpm-0001Ro-K9 for qemu-devel@nongnu.org; Tue, 11 Dec 2018 10:20:32 -0500 Received: from mail-eopbgr710107.outbound.protection.outlook.com ([40.107.71.107]:42240 helo=NAM05-BY2-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 1gWjpj-00018w-9S; Tue, 11 Dec 2018 10:20:27 -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=kxXQw8wF6i9b6+iGM1E8/MQMXncrQOBf5Etw+Ewwt+U=; b=mG14ExAKOAa4ofGz0ONX8RSjgSve80ExspCAUpERrqvQ8Q4G2SG+X6FHRVt2eCSDq78dvN+5p/dROs/jWnfuv/6dUtpNJWekazuIUbNy+O291aeCUCUxXprrPW4SGhrmSrOfhgsMCtxxYp4g8iDW1Cl6vFeAgdy0fQp2UiEZjIg= Received: from DM6PR01MB4825.prod.exchangelabs.com (20.177.218.222) by DM6PR01MB4379.prod.exchangelabs.com (20.177.221.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1425.18; Tue, 11 Dec 2018 15:20:14 +0000 Received: from DM6PR01MB4825.prod.exchangelabs.com ([fe80::9c7c:27c7:4cb7:f820]) by DM6PR01MB4825.prod.exchangelabs.com ([fe80::9c7c:27c7:4cb7:f820%2]) with mapi id 15.20.1404.026; Tue, 11 Dec 2018 15:20:14 +0000 From: Aaron Lindsay To: "qemu-arm@nongnu.org" , Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite , Richard Henderson Thread-Topic: [PATCH v10 02/14] target/arm: Reorganize PMCCNTR accesses Thread-Index: AQHUkWUEc+x23XVFC0mKscNz2fRtfw== Date: Tue, 11 Dec 2018 15:20:14 +0000 Message-ID: <20181211151945.29137-3-aaron@os.amperecomputing.com> References: <20181211151945.29137-1-aaron@os.amperecomputing.com> In-Reply-To: <20181211151945.29137-1-aaron@os.amperecomputing.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR11CA0041.namprd11.prod.outlook.com (2603:10b6:a03:80::18) 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-originating-ip: [65.190.6.212] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DM6PR01MB4379; 6:zN1PRuPm2xKnvuBTrCjqS9ZHEcE0Jfs7XW6XyFlfBNBCn3R49W9WehGOHClubzdPv1/al40MZxsk65cTcDUXgImNdIMQLY4Oue3KBm0Bqi1IOPJ0gTXM8LnaoOWduie2qb5qrffu/R6r7rg9fBMgxT08J6P66onFyIR79PjDlfIYjFMmC/Ki9FA3R2hP4pXk+CXFZo0O0uYEeG+ODS/zp5ohd2WCbYkXUeAOBnSdTAjMrIkJPU0YndMZMpb4L+xn7hHJgDPGQQ+t8SHI8bwTVK+okc9sxd/M81qriebsMCkcfJoEXMc88vQQIcEXYXjSJmDpNSMpCQRVFyM4KgOyRwOSzKLjY9eD/vYGcOHhd8G4nYFPzx6rnNGJ+jKrPHldGgCdfUMA1yPso4TaEi4pbFLeGbZPatpHuZHR9IEeiPU0CGfFnl3My312t7Da+VaDB0blsDWzft3Pdup5nExs8g==; 5:ofJYcunXHXGe3R2bwcOVq3CiZVFjCxutvyWIKRKAh8JIvb0WkmtdYWQPvAWR8Ewvge4Am54XYAC3my9469FPBaoYFfpCf8cdwZUpJV9fM7Y9D1nwAj3xkC8QXLAcFQw+4/XXT34o+lkCWM99xi1+8LVjb/6w7PHt9OAERls63A4=; 7:MzAid31wau95a6efTTW5jgZRWyI1LaMaHvnW/11KAD8Dg9JDxmR0r3zx2LlYcq8AhPzu8iL0GJ6lqOcccT2Pq+hpRBzTXzifFBNPsFYW5Dq2upSqOcm0wVVMex178LqknX0xWoS0KK5V+V9FhI5mhg== x-ms-office365-filtering-correlation-id: 6633f600-9002-4d55-d81e-08d65f7c267b x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390098)(7020095)(4652040)(8989299)(5600074)(711020)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:DM6PR01MB4379; x-ms-traffictypediagnostic: DM6PR01MB4379: x-microsoft-antispam-prvs: x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3231455)(999002)(944501520)(52105112)(93006095)(93001095)(10201501046)(3002001)(148016)(149066)(150057)(6041310)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:DM6PR01MB4379; BCL:0; PCL:0; RULEID:; SRVR:DM6PR01MB4379; x-forefront-prvs: 08831F51DC x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(366004)(136003)(39850400004)(396003)(346002)(376002)(189003)(199004)(4326008)(26005)(81166006)(81156014)(71200400001)(71190400001)(106356001)(6436002)(66066001)(14454004)(68736007)(3846002)(2501003)(102836004)(8936002)(6486002)(8676002)(97736004)(6116002)(186003)(446003)(99286004)(476003)(11346002)(2616005)(25786009)(7416002)(486006)(7736002)(54906003)(305945005)(39060400002)(478600001)(14444005)(256004)(52116002)(2906002)(386003)(1076002)(6506007)(105586002)(76176011)(6512007)(86362001)(53936002)(5660300001)(316002)(110136005); DIR:OUT; SFP:1102; SCL:1; SRVR:DM6PR01MB4379; 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-microsoft-antispam-message-info: yqAdo/GSvqw9eF2eC5AF23gaO9MxmOyyIbT85rS6fuLWMlfiRvwFC9rV7aoRr0dKDXdjFK1E7U8rdzCBlu/X8E3qj0fWs0YZSoEiCHHLILYu2ItHvf3AsCIrflr0wLlJrXj8qE14SHSZlkeMu6opzbpLrQ3KGkkNP2F/72OFFsUnigJosXZYaBldAyaq84Z/k9E+LaJTvTTD4l/DZ6lnqW3hOsilcRnY4vCBVnBI0jmFnL1QejE0ugL6pTYM05+QeKkakOcjzdlR7ZPGW4fYhm3SQzLb4RCjw2G2zt3ZgKy+zwThLmvY5V8jWBe3wZGs spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6633f600-9002-4d55-d81e-08d65f7c267b X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Dec 2018 15:20:14.8394 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR01MB4379 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 40.107.71.107 Subject: [Qemu-devel] [PATCH v10 02/14] target/arm: Reorganize PMCCNTR accesses 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: Michael Spradling , Digant Desai , "qemu-devel@nongnu.org" , Aaron Lindsay , Aaron Lindsay Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" pmccntr_read and pmccntr_write contained duplicate code that was already being handled by pmccntr_sync. Consolidate the duplicated code into two functions: pmccntr_op_start and pmccntr_op_finish. Add a companion to c15_ccnt in CPUARMState so that we can simultaneously save both the architectural register value and the last underlying cycle count - this ensures time isn't lost and will also allow us to access the 'old' architectural register value in order to detect overflows in later patches. Signed-off-by: Aaron Lindsay Signed-off-by: Aaron Lindsay Reviewed-by: Peter Maydell --- target/arm/cpu.h | 37 ++++++++++---- target/arm/helper.c | 114 +++++++++++++++++++++++++++----------------- 2 files changed, 98 insertions(+), 53 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 2a73fed9a0..61ac458627 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -468,10 +468,20 @@ typedef struct CPUARMState { uint64_t oslsr_el1; /* OS Lock Status */ uint64_t mdcr_el2; uint64_t mdcr_el3; - /* If the counter is enabled, this stores the last time the counter - * was reset. Otherwise it stores the counter value + /* Stores the architectural value of the counter *the last time it was + * updated* by pmccntr_op_start. Accesses should always be surrounded + * by pmccntr_op_start/pmccntr_op_finish to guarantee the latest + * architecturally-correct value is being read/set. */ uint64_t c15_ccnt; + /* Stores the delta between the architectural value and the underlying + * cycle count during normal operation. It is used to update c15_ccnt + * to be the correct architectural value before accesses. During + * accesses, c15_ccnt_delta contains the underlying count being used + * for the access, after which it reverts to the delta value in + * pmccntr_op_finish. + */ + uint64_t c15_ccnt_delta; uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */ uint64_t vpidr_el2; /* Virtualization Processor ID Register */ uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */ @@ -956,15 +966,26 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo, void *puc); /** - * pmccntr_sync + * pmccntr_op_start/finish + * @env: CPUARMState + * + * Convert the counter in the PMCCNTR between its delta form (the typical mode + * when it's enabled) and the guest-visible value. These two calls must always + * surround any action which might affect the counter. + */ +void pmccntr_op_start(CPUARMState *env); +void pmccntr_op_finish(CPUARMState *env); + +/** + * pmu_op_start/finish * @env: CPUARMState * - * Synchronises the counter in the PMCCNTR. This must always be called twice, - * once before any action that might affect the timer and again afterwards. - * The function is used to swap the state of the register if required. - * This only happens when not in user mode (!CONFIG_USER_ONLY) + * Convert all PMU counters between their delta form (the typical mode when + * they are enabled) and the guest-visible values. These two calls must + * surround any action which might affect the counters. */ -void pmccntr_sync(CPUARMState *env); +void pmu_op_start(CPUARMState *env); +void pmu_op_finish(CPUARMState *env); /* SCTLR bit meanings. Several bits have been reused in newer * versions of the architecture; in that case we define constants diff --git a/target/arm/helper.c b/target/arm/helper.c index 0da1424f72..497907fc79 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1085,28 +1085,63 @@ static inline bool arm_ccnt_enabled(CPUARMState *env) return true; } - -void pmccntr_sync(CPUARMState *env) +/* + * Ensure c15_ccnt is the guest-visible count so that operations such as + * enabling/disabling the counter or filtering, modifying the count itself, + * etc. can be done logically. This is essentially a no-op if the counter is + * not enabled at the time of the call. + */ +void pmccntr_op_start(CPUARMState *env) { - uint64_t temp_ticks; - - temp_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + uint64_t cycles = 0; + cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - temp_ticks /= 64; + if (arm_ccnt_enabled(env)) { + uint64_t eff_cycles = cycles; + if (env->cp15.c9_pmcr & PMCRD) { + /* Increment once every 64 processor clock cycles */ + eff_cycles /= 64; + } + + env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta; } + env->cp15.c15_ccnt_delta = cycles; +} +/* + * If PMCCNTR is enabled, recalculate the delta between the clock and the + * guest-visible count. A call to pmccntr_op_finish should follow every call to + * pmccntr_op_start. + */ +void pmccntr_op_finish(CPUARMState *env) +{ if (arm_ccnt_enabled(env)) { - env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt; + uint64_t prev_cycles = env->cp15.c15_ccnt_delta; + + if (env->cp15.c9_pmcr & PMCRD) { + /* Increment once every 64 processor clock cycles */ + prev_cycles /= 64; + } + + env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt; } } +void pmu_op_start(CPUARMState *env) +{ + pmccntr_op_start(env); +} + +void pmu_op_finish(CPUARMState *env) +{ + pmccntr_op_finish(env); +} + static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - pmccntr_sync(env); + pmu_op_start(env); if (value & PMCRC) { /* The counter has been reset */ @@ -1117,26 +1152,16 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.c9_pmcr &= ~0x39; env->cp15.c9_pmcr |= (value & 0x39); - pmccntr_sync(env); + pmu_op_finish(env); } static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri) { - uint64_t total_ticks; - - if (!arm_ccnt_enabled(env)) { - /* Counter is disabled, do not change value */ - return env->cp15.c15_ccnt; - } - - total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - total_ticks /= 64; - } - return total_ticks - env->cp15.c15_ccnt; + uint64_t ret; + pmccntr_op_start(env); + ret = env->cp15.c15_ccnt; + pmccntr_op_finish(env); + return ret; } static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1153,22 +1178,9 @@ static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri, static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - uint64_t total_ticks; - - if (!arm_ccnt_enabled(env)) { - /* Counter is disabled, set the absolute value */ - env->cp15.c15_ccnt = value; - return; - } - - total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - total_ticks /= 64; - } - env->cp15.c15_ccnt = total_ticks - value; + pmccntr_op_start(env); + env->cp15.c15_ccnt = value; + pmccntr_op_finish(env); } static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1181,7 +1193,19 @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri, #else /* CONFIG_USER_ONLY */ -void pmccntr_sync(CPUARMState *env) +void pmccntr_op_start(CPUARMState *env) +{ +} + +void pmccntr_op_finish(CPUARMState *env) +{ +} + +void pmu_op_start(CPUARMState *env) +{ +} + +void pmu_op_finish(CPUARMState *env) { } @@ -1190,9 +1214,9 @@ void pmccntr_sync(CPUARMState *env) static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - pmccntr_sync(env); + pmccntr_op_start(env); env->cp15.pmccfiltr_el0 = value & 0xfc000000; - pmccntr_sync(env); + pmccntr_op_finish(env); } static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,