Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753016AbbHEO7L (ORCPT ); Wed, 5 Aug 2015 10:59:11 -0400 Received: from eu-smtp-delivery-143.mimecast.com ([207.82.80.143]:19772 "EHLO eu-smtp-delivery-143.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752122AbbHEO64 convert rfc822-to-8bit (ORCPT ); Wed, 5 Aug 2015 10:58:56 -0400 Message-ID: <55C224AB.8020402@arm.com> Date: Wed, 05 Aug 2015 15:58:51 +0100 From: "Suzuki K. Poulose" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: "linux-arm-kernel@lists.infradead.org" CC: Catalin Marinas , Will Deacon , Mark Rutland , "edward.nevill@linaro.org" , "aph@redhat.com" , "linux-kernel@vger.kernel.org" Subject: Re: [RFC PATCH 05/10] arm64: Keep track of CPU feature registers References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com> <1437731037-25795-6-git-send-email-suzuki.poulose@arm.com> In-Reply-To: <1437731037-25795-6-git-send-email-suzuki.poulose@arm.com> X-OriginalArrivalTime: 05 Aug 2015 14:58:51.0969 (UTC) FILETIME=[3DE8E310:01D0CF8F] X-MC-Unique: i0gHCMcYQmqYxvUrnH4NcQ-1 Content-Type: text/plain; charset=WINDOWS-1252; format=flowed Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8632 Lines: 202 On 24/07/15 10:43, Suzuki K. Poulose wrote: > From: "Suzuki K. Poulose" > > This patch adds an infrastructure to keep track of the CPU feature > registers on the system. This patch also consolidates the cpuinfo > SANITY checks which ensures that we don't have conflicting feature > supports across the CPUs. > > Each register has a set of feature bits defined by the architecture. > We define the following attributes: > > 1) strict - If strict matching is required for the field across the > all the CPUs for SANITY checks. > 2) visible - If the field is exposed to the userspace (See documentation > for more details). > > The default 'safe' value for the feature is also defined, which will be > used: > 1) To set the value for a 'discrete' feature with conflicting values. > 2) To set the value for an 'invisible' feature for the userspace. > > The infrastructure keeps track of the following values for a feature > register: > - user visible value > - system wide safe value > > Signed-off-by: Suzuki K. Poulose > --- > arch/arm64/include/asm/cpu.h | 149 ++++++++++++++++ > arch/arm64/kernel/cpuinfo.c | 399 ++++++++++++++++++++++++++++++++++++++---- > 2 files changed, 511 insertions(+), 37 deletions(-) > > diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h > index a34de72..c7b0b89 100644 > --- a/arch/arm64/include/asm/cpu.h > +++ b/arch/arm64/include/asm/cpu.h ... > diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c > index a13468b..ae2a37f 100644 > --- a/arch/arm64/kernel/cpuinfo.c > +++ b/arch/arm64/kernel/cpuinfo.c > @@ -31,6 +31,207 @@ > #include > #include > ... > -#define CHECK_MASK(field, mask, boot, cur, cpu) \ > - check_reg_mask(#field, mask, (boot)->reg_ ## field, (cur)->reg_ ## field, cpu) > - > -#define CHECK(field, boot, cur, cpu) \ > - CHECK_MASK(field, ~0ULL, boot, cur, cpu) > +#define CHECK_CPUINFO(field) \ > + ({ \ > + int __rc = 0; \ > + struct arm64_ftr_reg *__regp = get_arm64_sys_reg(sys_ ## field); \ > + if (__regp) { \ > + __rc = check_reg_mask(__regp, \ > + (boot)->reg_ ## field, \ > + (cur)->reg_ ## field, cpu); \ > + update_cpu_ftr_reg(__regp, cur->reg_ ## field, cpu); \ > + } \ > + __rc; \ > + }) > > /* > * Verify that CPUs don't have unexpected differences that will cause problems. > @@ -123,17 +448,17 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur) > * caches should look identical. Userspace JITs will make use of > * *minLine. > */ > - diff |= CHECK_MASK(ctr, 0xffff3fff, boot, cur, cpu); > + diff |= CHECK_CPUINFO(ctr); > > /* > * Userspace may perform DC ZVA instructions. Mismatched block sizes > * could result in too much or too little memory being zeroed if a > * process is preempted and migrated between CPUs. > */ > - diff |= CHECK(dczid, boot, cur, cpu); > + diff |= CHECK_CPUINFO(dczid); > > /* If different, timekeeping will be broken (especially with KVM) */ > - diff |= CHECK(cntfrq, boot, cur, cpu); > + diff |= CHECK_CPUINFO(cntfrq); > > /* > * The kernel uses self-hosted debug features and expects CPUs to > @@ -141,15 +466,15 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur) > * and BRPs to be identical. > * ID_AA64DFR1 is currently RES0. > */ > - diff |= CHECK(id_aa64dfr0, boot, cur, cpu); > - diff |= CHECK(id_aa64dfr1, boot, cur, cpu); > + diff |= CHECK_CPUINFO(id_aa64dfr0); > + diff |= CHECK_CPUINFO(id_aa64dfr1); > > /* > * Even in big.LITTLE, processors should be identical instruction-set > * wise. > */ > - diff |= CHECK(id_aa64isar0, boot, cur, cpu); > - diff |= CHECK(id_aa64isar1, boot, cur, cpu); > + diff |= CHECK_CPUINFO(id_aa64isar0); > + diff |= CHECK_CPUINFO(id_aa64isar1); > > /* > * Differing PARange support is fine as long as all peripherals and > @@ -157,42 +482,42 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur) > * Linux should not care about secure memory. > * ID_AA64MMFR1 is currently RES0. > */ > - diff |= CHECK_MASK(id_aa64mmfr0, 0xffffffffffff0ff0, boot, cur, cpu); > - diff |= CHECK(id_aa64mmfr1, boot, cur, cpu); > + diff |= CHECK_CPUINFO(id_aa64mmfr0); > + diff |= CHECK_CPUINFO(id_aa64mmfr1); > > /* > * EL3 is not our concern. > * ID_AA64PFR1 is currently RES0. > */ > - diff |= CHECK_MASK(id_aa64pfr0, 0xffffffffffff0fff, boot, cur, cpu); > - diff |= CHECK(id_aa64pfr1, boot, cur, cpu); > + diff |= CHECK_CPUINFO(id_aa64pfr0); > + diff |= CHECK_CPUINFO(id_aa64pfr1); > > /* > * If we have AArch32, we care about 32-bit features for compat. These > * registers should be RES0 otherwise. > */ > - diff |= CHECK(id_dfr0, boot, cur, cpu); > - diff |= CHECK(id_isar0, boot, cur, cpu); > - diff |= CHECK(id_isar1, boot, cur, cpu); > - diff |= CHECK(id_isar2, boot, cur, cpu); > - diff |= CHECK(id_isar3, boot, cur, cpu); > - diff |= CHECK(id_isar4, boot, cur, cpu); > - diff |= CHECK(id_isar5, boot, cur, cpu); > + diff |= CHECK_CPUINFO(id_dfr0); > + diff |= CHECK_CPUINFO(id_isar0); > + diff |= CHECK_CPUINFO(id_isar1); > + diff |= CHECK_CPUINFO(id_isar2); > + diff |= CHECK_CPUINFO(id_isar3); > + diff |= CHECK_CPUINFO(id_isar4); > + diff |= CHECK_CPUINFO(id_isar5); > /* > * Regardless of the value of the AuxReg field, the AIFSR, ADFSR, and > * ACTLR formats could differ across CPUs and therefore would have to > * be trapped for virtualization anyway. > */ > - diff |= CHECK_MASK(id_mmfr0, 0xff0fffff, boot, cur, cpu); > - diff |= CHECK(id_mmfr1, boot, cur, cpu); > - diff |= CHECK(id_mmfr2, boot, cur, cpu); > - diff |= CHECK(id_mmfr3, boot, cur, cpu); > - diff |= CHECK(id_pfr0, boot, cur, cpu); > - diff |= CHECK(id_pfr1, boot, cur, cpu); > + diff |= CHECK_CPUINFO(id_mmfr0); > + diff |= CHECK_CPUINFO(id_mmfr1); > + diff |= CHECK_CPUINFO(id_mmfr2); > + diff |= CHECK_CPUINFO(id_mmfr3); > + diff |= CHECK_CPUINFO(id_pfr0); > + diff |= CHECK_CPUINFO(id_pfr1); > > - diff |= CHECK(mvfr0, boot, cur, cpu); > - diff |= CHECK(mvfr1, boot, cur, cpu); > - diff |= CHECK(mvfr2, boot, cur, cpu); > + diff |= CHECK_CPUINFO(mvfr0); > + diff |= CHECK_CPUINFO(mvfr1); > + diff |= CHECK_CPUINFO(mvfr2); > > /* > * Mismatched CPU features are a recipe for disaster. Don't even > @@ -239,7 +564,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) > cpuinfo_detect_icache_policy(info); > > check_local_cpu_errata(); > - check_local_cpu_features(); > + cpuinfo_sanity_check(info); These two changes shouldn't be there, I have fixed it locally. > update_cpu_features(info); > } > > @@ -247,13 +572,13 @@ void cpuinfo_store_cpu(void) > { > struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data); > __cpuinfo_store_cpu(info); > - cpuinfo_sanity_check(info); As above, this line should be retained here. > } > > void __init cpuinfo_store_boot_cpu(void) > { > struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0); > __cpuinfo_store_cpu(info); > + init_cpu_ftrs(info); Thanks Suzuki -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/