From patchwork Tue Feb 5 19:02:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 157527 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp5576143jaa; Tue, 5 Feb 2019 11:56:01 -0800 (PST) X-Google-Smtp-Source: AHgI3IaNghdJw6201koaWQtjdQUKxCZ9oEgGxeh6oIL+94E80tS0ehffU1h96JzSwMZfyl6tqT4J X-Received: by 2002:a81:594:: with SMTP id 142mr5600441ywf.294.1549396561510; Tue, 05 Feb 2019 11:56:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549396561; cv=none; d=google.com; s=arc-20160816; b=sGNiXoXOjzrpHMu5twF0p+A3QTFXfxbRjgo+bbgBYv4YHKzASuYTm+/jp9UT+dulWC KY0XnPZP4OLw8+v29Etnv3OtkkZAmNNN/vxfexcCZTmz1Os8276O0+0XjUO5DZQz2o8t 1H8Tl9QDgryvAebh/ZajWhE92qbvM+nDfHhWEPNsujeC4qaYnstWRdABQ8Hl/yoByi4z pHKdl5IerzdMboHyxbtUMFE4s1zF1SDEWhEodGQIC/Zd2+32VdwoECGjVNRJUaQtqIOG SQkuPYzIoVJP/OKXfYYU11oqWugUUBJFu/yMCwJjIKmVAyOXsRr689t2sfLoNeWNwwIs 016w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=5K8fEiIOFo1VDdNnkd2vN+zdBEFCMFkNkVT82ANMtrs=; b=Ud+eGVMAcRb/0kmG7aeMIRULER9QNFywS3bwNjF54FzSkkiie1iI7OD3LMOlI5eH4q zpODd7bF1389sfnrNwrhgLA9sumuvHOMnkr2GpOn5jOD/weOlMHrPyc1YRSH9YUwVBVA 5gXAmxpy1+C35awZeRk2V1+zEg/VvOevtKFRhZkCVg+fTd8hwomyxKyJklPaXDLnbScd 3hr/TQKKqIZHD7GgQao2hgdsTvT+c9LkFEcNKg2D/WF/LPZ/wKmXgUXCEhxGEM+Z3s5R gY4oEt2U+CAOWb/2iji/8ZGOFj2haQugw/fDXAgnIsgQJL6BBxlKoV5SDz/JaerB7Idm h3Gw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Y+RdRgBy; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id u186si2491234ybf.47.2019.02.05.11.56.01 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 05 Feb 2019 11:56:01 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Y+RdRgBy; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:39396 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gr6p6-0000Co-VO for patch@linaro.org; Tue, 05 Feb 2019 14:56:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:52957) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gr5zc-0007p4-8f for qemu-devel@nongnu.org; Tue, 05 Feb 2019 14:02:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gr5zZ-0004Hq-Qq for qemu-devel@nongnu.org; Tue, 05 Feb 2019 14:02:47 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:39986) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gr5zZ-00043T-Ir for qemu-devel@nongnu.org; Tue, 05 Feb 2019 14:02:45 -0500 Received: by mail-wm1-x344.google.com with SMTP id q21so38671wmc.5 for ; Tue, 05 Feb 2019 11:02:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5K8fEiIOFo1VDdNnkd2vN+zdBEFCMFkNkVT82ANMtrs=; b=Y+RdRgBy2Ft64RkMtBuRvmr8eHJ+Ai9iEF+FjrB+n4KlutEIpru4+95qY+UPBYbY8o 5WHZoAirNc/D+SMU8aTBfm0cvcmiVbZUKunQTTGA5nxZ5xrlyzNT9sCGMtcpQGjpE1ii i5H0EINqltG2Kcl9N7MQqcSs8wIKD5KWlNxL9skEpmyFdT7tJrzGeJFlEJB5eDAu1QlV DaGBxHx4bibyJ1zUmAIgLuFniFekoxDtV+PwpUTRWP4V3nWVFNVpLkNML/BAQxJvh/+b TtVxjTwEt+SJnP5Ke+m7sOYNkOCOwPEov7uwPTmZ1AwvmQWNUymokY2Ce0FIKW8lXv8y vJ2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5K8fEiIOFo1VDdNnkd2vN+zdBEFCMFkNkVT82ANMtrs=; b=E7NeNmBHtgqJHOwFp1BS4dhxkn1mfVarRIDS9CXSJ1Jke4GHbtRgGUIB/5kdF7qx9E 5fTOh+dPMobw0MGxNJBMRTCtZZcNxFF9lwaQAJ3BD0yp98pStxW6DLlZpDXhhTVICU3x D+KHPIBCzxktI1+bKs/ltO+JgK+Fs/xq6rn2lTgdIg/5KxRVJhX/240dG4awo5iWwe12 Zn5SqL2GelttxZnFydtX+zlXt/AAdm3b3QcJKW92EC7fPic2d35EjgktWGofUw75UGw1 kOy9nk8ajQ1JMUeUcZFbm7x3dJDAOguaqhGZx/+LNRoa3E5/QWMAdaZEli8inUkcQ4Pr e/8w== X-Gm-Message-State: AHQUAuZ2FolSP0rhT1SXiN5RW+ctG1hwtJ0E9YKv4xXVvHXP7/onF578 Cvw8do8NSt4FTuIMzUXoRHpEyg== X-Received: by 2002:a7b:c08b:: with SMTP id r11mr122538wmh.29.1549393346444; Tue, 05 Feb 2019 11:02:26 -0800 (PST) Received: from zen.linaroharston ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id v22sm4901871wml.37.2019.02.05.11.02.24 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 05 Feb 2019 11:02:25 -0800 (PST) Received: from zen.linaroharston. (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 9600C1FF82; Tue, 5 Feb 2019 19:02:24 +0000 (UTC) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Date: Tue, 5 Feb 2019 19:02:20 +0000 Message-Id: <20190205190224.2198-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205190224.2198-1-alex.bennee@linaro.org> References: <20190205190224.2198-1-alex.bennee@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 Subject: [Qemu-devel] [PATCH v2 2/6] target/arm: expose CPUID registers to userspace 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: qemu-arm@nongnu.org, =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" A number of CPUID registers are exposed to userspace by modern Linux kernels thanks to the "ARM64 CPU Feature Registers" ABI. For QEMU's user-mode emulation we don't need to emulate the kernels trap but just return the value the trap would have done. To avoid too much #ifdef hackery we process ARMCPRegInfo with a new helper (modify_arm_cp_regs) before defining the registers. The modify routine is driven by a simple data structure which describes which bits are exported and which are fixed. Signed-off-by: Alex Bennée --- v4 - tweak commit message - use PL0U_R instead of PL1U_R to be less confusing - more CONFIG_USER logic for special cases - mask a bunch of bits for some registers v5 - use data driven modify_arm_cp_regs --- target/arm/cpu.h | 21 ++++++++++++++++ target/arm/helper.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) -- 2.20.1 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 1616632dcb..354df22102 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2449,6 +2449,27 @@ static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs) } const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp); +/* + * Definition of an ARM co-processor register as viewed from + * userspace. This is used for presenting sanitised versions of + * registers to userspace when emulating the Linux AArch64 CPU + * ID/feature ABI (advertised as HWCAP_CPUID). + */ +typedef struct ARMCPRegUserSpaceInfo { + /* Name of register */ + const char *name; + + /* Only some bits are exported to user space */ + uint64_t exported_bits; + + /* Fixed bits are applied after the mask */ + uint64_t fixed_bits; +} ARMCPRegUserSpaceInfo; + +#define REGUSERINFO_SENTINEL { .name = NULL } + +void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods); + /* CPWriteFn that can be used to implement writes-ignored behaviour */ void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value); diff --git a/target/arm/helper.c b/target/arm/helper.c index 5857c0ba96..f90754cc11 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6103,6 +6103,30 @@ void register_cp_regs_for_features(ARMCPU *cpu) .resetvalue = cpu->pmceid1 }, REGINFO_SENTINEL }; +#ifdef CONFIG_USER_ONLY + ARMCPRegUserSpaceInfo v8_user_idregs[] = { + { .name = "ID_AA64PFR0_EL1", + .exported_bits = 0x000f000f00ff0000, + .fixed_bits = 0x0000000000000011 }, + { .name = "ID_AA64PFR1_EL1", + .exported_bits = 0x00000000000000f0 }, + { .name = "ID_AA64ZFR0_EL1" }, + { .name = "ID_AA64MMFR0_EL1", + .fixed_bits = 0x00000000ff000000 }, + { .name = "ID_AA64MMFR1_EL1" }, + { .name = "ID_AA64DFR0_EL1", + .fixed_bits = 0x0000000000000006 }, + { .name = "ID_AA64DFR1_EL1" }, + { .name = "ID_AA64AFR0_EL1" }, + { .name = "ID_AA64AFR1_EL1" }, + { .name = "ID_AA64ISAR0_EL1", + .exported_bits = 0x00fffffff0fffff0 }, + { .name = "ID_AA64ISAR1_EL1", + .exported_bits = 0x000000f0ffffffff }, + REGUSERINFO_SENTINEL + }; + modify_arm_cp_regs(v8_idregs, v8_user_idregs); +#endif /* RVBAR_EL1 is only implemented if EL1 is the highest EL */ if (!arm_feature(env, ARM_FEATURE_EL3) && !arm_feature(env, ARM_FEATURE_EL2)) { @@ -6379,6 +6403,15 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_OVERRIDE }; +#ifdef CONFIG_USER_ONLY + ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = { + { .name = "MIDR_EL1", + .exported_bits = 0x00000000ffffffff }, + { .name = "REVIDR_EL1" }, + REGUSERINFO_SENTINEL + }; + modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo); +#endif if (arm_feature(env, ARM_FEATURE_OMAPCP) || arm_feature(env, ARM_FEATURE_STRONGARM)) { ARMCPRegInfo *r; @@ -6960,6 +6993,32 @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu, } } +/* + * Modify ARMCPRegInfo for access from userspace. + * + * This is a data driven modification directed by + * ARMCPRegUserSpaceInfo. All registers become ARM_CP_CONST as + * user-space cannot alter any values and dynamic values pertaining to + * execution state are hidden from user space view anyway. + */ +void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods) +{ + const ARMCPRegUserSpaceInfo *m; + ARMCPRegInfo *r; + + for (m = mods; m->name; m++) { + for (r = regs; r->type != ARM_CP_SENTINEL; r++) { + if (strcmp(r->name, m->name) == 0) { + r->type = ARM_CP_CONST; + r->access = PL0U_R; + r->resetvalue &= m->exported_bits; + r->resetvalue |= m->fixed_bits; + break; + } + } + } +} + const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp) { return g_hash_table_lookup(cpregs, &encoded_cp);