From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 895C421E0B2 for ; Thu, 29 May 2025 22:19:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748557186; cv=none; b=YdlsrOtLE0V6upRKHmHRJP3zXjTeDr0xRKMyYgk7NO0UvcI8OveWXZVFXlrMRWkhUyu65w8+BQNcTXrEmU+IW4F0+z5SyWGYwUP7TsmwcQ1O8xzU4pXnnzeyaPZIDurd3X6ylX2tUTTsHmQ2e8xEgVWHm7Al5FqQrKVKLg/VGZ8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748557186; c=relaxed/simple; bh=cgiL6zTZDbFWyh/srJt9OQvAvRIx7sitjitOvoD+hiw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=dFmNoufuOvHHPIMc7wGOzohXXXuvHwnZSuA/LYu9o5cWx0n+AX9VT7fG/ZzgDk1K8/aXvo7nvYB9YfFSK3NU+PBbngyKCpyscgx6CzjnzRkOnu+YqJucerk+b1zcXZVpcpgn+crWNX/d35R3ktxrZOwVceUJipgEDvfTATm6jBY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=SOAPcdR7; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="SOAPcdR7" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-311ef4fb5eeso1176435a91.1 for ; Thu, 29 May 2025 15:19:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1748557184; x=1749161984; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=NjAP5WxBtyibNQurKYgxEnwWA84IR2Dkaa6sBfwiN+Y=; b=SOAPcdR7WeWTYLdCzytPV8vBBc7Jh8y/s/pJz2HauEkfy6XM5U3+01/5JC1u3LTJCL w74GdQn6iqfp+/doMlQ+rZUvWn9B7fq/SkjLvIRhX19rX4ttcePq5UCePLWF+PM10kP3 LiEUO3zfJrG1aronQLft5i+VtdQk/qQb2onMloPg/MgV44VxqnB8p98c6GQBMugR8iLc p5PbRNLbf0C3uurSlhm+p9JvAIkwcULf5EZbAD4r8saLw4U4riFQt+RiXbNlmYrcrrMk qF+yF0jEASLBi/nT9Uu4X2hC5r1PaEJyHHHGn9TUjIdrHVN+GjHLyAn0nBML/srQrs2N qKMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748557184; x=1749161984; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=NjAP5WxBtyibNQurKYgxEnwWA84IR2Dkaa6sBfwiN+Y=; b=OOZb31qE9Nh9CZA2EGWWZuRvd04391GWRmuWZjxMaeZMZgvs7g6+C985/+BsachiuO HhuJ+zvQN4u3xxU5aYDOdPig/+Zpq6lUw5s5eZZfhSqQF7cbLOksRi0ypdI/2qT+N53B AaDDIXn5kUy3haHhvM7p63LL99pViDsojNhFpKGovV8RTEmho7j35eG+59LiWfzFUcAN LEjQSWrXAHkxQaBeC8DcxDzSawiXdicnMVEuKIiRRZrgIYRmvHpsff9QmccqHkbQrR1U w86SmmCd6Veenz85PFUMOTkSEJmYOqZDQZU1iwY5pwTMpP3af74okaAxvCqwEXp1j0YJ j5pQ== X-Forwarded-Encrypted: i=1; AJvYcCX1FgGiNToXJdKPkGmDJ6xKQE9rd685BAY4nczfU9IgKTjW6wRpsrvPeHq8C+8NFir7ZxA=@vger.kernel.org X-Gm-Message-State: AOJu0YwFk5Jo8Tnlb6uVmpdDH0L9/ZsTKnNtAnkBidQsIpu4TlZqI7Sz A/s3jC6apC+uWFeJPMjbDXIUj7QtN09QbWJ1Rv5umjQSTLQW7I4GCiefDulne7zgHR8SU6y/1SU oRtw8Rg== X-Google-Smtp-Source: AGHT+IHh1a1Qp61K+GgQUYaz4jvy6YU1W428UbF736aOyyksea78LtwhAKn7hxiOh4DjAgu/TTS3ZiEv+gY= X-Received: from pjtq15.prod.google.com ([2002:a17:90a:c10f:b0:311:e9bb:f8d4]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3eca:b0:310:7486:d60b with SMTP id 98e67ed59e1d1-31214ecdba7mr7484658a91.14.1748557183846; Thu, 29 May 2025 15:19:43 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 29 May 2025 15:19:15 -0700 In-Reply-To: <20250529221929.3807680-1-seanjc@google.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250529221929.3807680-1-seanjc@google.com> X-Mailer: git-send-email 2.49.0.1204.g71687c7c1d-goog Message-ID: <20250529221929.3807680-3-seanjc@google.com> Subject: [kvm-unit-tests PATCH 02/16] x86: Encode X86_FEATURE_* definitions using a structure From: Sean Christopherson To: Andrew Jones , Janosch Frank , Claudio Imbrenda , "=?UTF-8?q?Nico=20B=C3=B6hr?=" , Paolo Bonzini Cc: kvm-riscv@lists.infradead.org, linux-s390@vger.kernel.org, kvm@vger.kernel.org, Sean Christopherson Content-Type: text/plain; charset="UTF-8" Encode X86_FEATURE_* macros using a new "struct x86_cpu_feature" instead of manually packing the values into a u64. Using a structure eliminates open code shifts and masks, and is largely self-documenting. Note, the code and naming scheme are stolen from KVM selftests. Signed-off-by: Sean Christopherson --- lib/x86/processor.h | 171 ++++++++++++++++++++++++-------------------- 1 file changed, 95 insertions(+), 76 deletions(-) diff --git a/lib/x86/processor.h b/lib/x86/processor.h index a0be04c5..3ac6711d 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -6,6 +6,7 @@ #include "msr.h" #include #include +#include #define CANONICAL_48_VAL 0xffffaaaaaaaaaaaaull #define CANONICAL_57_VAL 0xffaaaaaaaaaaaaaaull @@ -232,100 +233,118 @@ static inline bool is_intel(void) return strcmp((char *)name, "GenuineIntel") == 0; } -#define CPUID(a, b, c, d) ((((unsigned long long) a) << 32) | (b << 16) | \ - (c << 8) | d) - /* - * Each X86_FEATURE_XXX definition is 64-bit and contains the following - * CPUID meta-data: - * - * [63:32] : input value for EAX - * [31:16] : input value for ECX - * [15:8] : output register - * [7:0] : bit position in output register + * Pack the information into a 64-bit value so that each X86_FEATURE_XXX can be + * passed by value with no overhead. */ +struct x86_cpu_feature { + u32 function; + u16 index; + u8 reg; + u8 bit; +}; + +#define X86_CPU_FEATURE(fn, idx, gpr, __bit) \ +({ \ + struct x86_cpu_feature feature = { \ + .function = fn, \ + .index = idx, \ + .reg = gpr, \ + .bit = __bit, \ + }; \ + \ + static_assert((fn & 0xc0000000) == 0 || \ + (fn & 0xc0000000) == 0x40000000 || \ + (fn & 0xc0000000) == 0x80000000 || \ + (fn & 0xc0000000) == 0xc0000000); \ + static_assert(idx < BIT(sizeof(feature.index) * BITS_PER_BYTE)); \ + feature; \ +}) /* * Basic Leafs, a.k.a. Intel defined */ -#define X86_FEATURE_MWAIT (CPUID(0x1, 0, ECX, 3)) -#define X86_FEATURE_VMX (CPUID(0x1, 0, ECX, 5)) -#define X86_FEATURE_PDCM (CPUID(0x1, 0, ECX, 15)) -#define X86_FEATURE_PCID (CPUID(0x1, 0, ECX, 17)) -#define X86_FEATURE_X2APIC (CPUID(0x1, 0, ECX, 21)) -#define X86_FEATURE_MOVBE (CPUID(0x1, 0, ECX, 22)) -#define X86_FEATURE_TSC_DEADLINE_TIMER (CPUID(0x1, 0, ECX, 24)) -#define X86_FEATURE_XSAVE (CPUID(0x1, 0, ECX, 26)) -#define X86_FEATURE_OSXSAVE (CPUID(0x1, 0, ECX, 27)) -#define X86_FEATURE_RDRAND (CPUID(0x1, 0, ECX, 30)) -#define X86_FEATURE_MCE (CPUID(0x1, 0, EDX, 7)) -#define X86_FEATURE_APIC (CPUID(0x1, 0, EDX, 9)) -#define X86_FEATURE_CLFLUSH (CPUID(0x1, 0, EDX, 19)) -#define X86_FEATURE_DS (CPUID(0x1, 0, EDX, 21)) -#define X86_FEATURE_XMM (CPUID(0x1, 0, EDX, 25)) -#define X86_FEATURE_XMM2 (CPUID(0x1, 0, EDX, 26)) -#define X86_FEATURE_TSC_ADJUST (CPUID(0x7, 0, EBX, 1)) -#define X86_FEATURE_HLE (CPUID(0x7, 0, EBX, 4)) -#define X86_FEATURE_SMEP (CPUID(0x7, 0, EBX, 7)) -#define X86_FEATURE_INVPCID (CPUID(0x7, 0, EBX, 10)) -#define X86_FEATURE_RTM (CPUID(0x7, 0, EBX, 11)) -#define X86_FEATURE_SMAP (CPUID(0x7, 0, EBX, 20)) -#define X86_FEATURE_PCOMMIT (CPUID(0x7, 0, EBX, 22)) -#define X86_FEATURE_CLFLUSHOPT (CPUID(0x7, 0, EBX, 23)) -#define X86_FEATURE_CLWB (CPUID(0x7, 0, EBX, 24)) -#define X86_FEATURE_INTEL_PT (CPUID(0x7, 0, EBX, 25)) -#define X86_FEATURE_UMIP (CPUID(0x7, 0, ECX, 2)) -#define X86_FEATURE_PKU (CPUID(0x7, 0, ECX, 3)) -#define X86_FEATURE_LA57 (CPUID(0x7, 0, ECX, 16)) -#define X86_FEATURE_RDPID (CPUID(0x7, 0, ECX, 22)) -#define X86_FEATURE_SHSTK (CPUID(0x7, 0, ECX, 7)) -#define X86_FEATURE_IBT (CPUID(0x7, 0, EDX, 20)) -#define X86_FEATURE_SPEC_CTRL (CPUID(0x7, 0, EDX, 26)) -#define X86_FEATURE_FLUSH_L1D (CPUID(0x7, 0, EDX, 28)) -#define X86_FEATURE_ARCH_CAPABILITIES (CPUID(0x7, 0, EDX, 29)) -#define X86_FEATURE_PKS (CPUID(0x7, 0, ECX, 31)) -#define X86_FEATURE_LAM (CPUID(0x7, 1, EAX, 26)) +#define X86_FEATURE_MWAIT X86_CPU_FEATURE(0x1, 0, ECX, 3) +#define X86_FEATURE_VMX X86_CPU_FEATURE(0x1, 0, ECX, 5) +#define X86_FEATURE_PDCM X86_CPU_FEATURE(0x1, 0, ECX, 15) +#define X86_FEATURE_PCID X86_CPU_FEATURE(0x1, 0, ECX, 17) +#define X86_FEATURE_X2APIC X86_CPU_FEATURE(0x1, 0, ECX, 21) +#define X86_FEATURE_MOVBE X86_CPU_FEATURE(0x1, 0, ECX, 22) +#define X86_FEATURE_TSC_DEADLINE_TIMER X86_CPU_FEATURE(0x1, 0, ECX, 24) +#define X86_FEATURE_XSAVE X86_CPU_FEATURE(0x1, 0, ECX, 26) +#define X86_FEATURE_OSXSAVE X86_CPU_FEATURE(0x1, 0, ECX, 27) +#define X86_FEATURE_RDRAND X86_CPU_FEATURE(0x1, 0, ECX, 30) +#define X86_FEATURE_MCE X86_CPU_FEATURE(0x1, 0, EDX, 7) +#define X86_FEATURE_APIC X86_CPU_FEATURE(0x1, 0, EDX, 9) +#define X86_FEATURE_CLFLUSH X86_CPU_FEATURE(0x1, 0, EDX, 19) +#define X86_FEATURE_DS X86_CPU_FEATURE(0x1, 0, EDX, 21) +#define X86_FEATURE_XMM X86_CPU_FEATURE(0x1, 0, EDX, 25) +#define X86_FEATURE_XMM2 X86_CPU_FEATURE(0x1, 0, EDX, 26) +#define X86_FEATURE_TSC_ADJUST X86_CPU_FEATURE(0x7, 0, EBX, 1) +#define X86_FEATURE_HLE X86_CPU_FEATURE(0x7, 0, EBX, 4) +#define X86_FEATURE_SMEP X86_CPU_FEATURE(0x7, 0, EBX, 7) +#define X86_FEATURE_INVPCID X86_CPU_FEATURE(0x7, 0, EBX, 10) +#define X86_FEATURE_RTM X86_CPU_FEATURE(0x7, 0, EBX, 11) +#define X86_FEATURE_SMAP X86_CPU_FEATURE(0x7, 0, EBX, 20) +#define X86_FEATURE_PCOMMIT X86_CPU_FEATURE(0x7, 0, EBX, 22) +#define X86_FEATURE_CLFLUSHOPT X86_CPU_FEATURE(0x7, 0, EBX, 23) +#define X86_FEATURE_CLWB X86_CPU_FEATURE(0x7, 0, EBX, 24) +#define X86_FEATURE_INTEL_PT X86_CPU_FEATURE(0x7, 0, EBX, 25) +#define X86_FEATURE_UMIP X86_CPU_FEATURE(0x7, 0, ECX, 2) +#define X86_FEATURE_PKU X86_CPU_FEATURE(0x7, 0, ECX, 3) +#define X86_FEATURE_LA57 X86_CPU_FEATURE(0x7, 0, ECX, 16) +#define X86_FEATURE_RDPID X86_CPU_FEATURE(0x7, 0, ECX, 22) +#define X86_FEATURE_SHSTK X86_CPU_FEATURE(0x7, 0, ECX, 7) +#define X86_FEATURE_IBT X86_CPU_FEATURE(0x7, 0, EDX, 20) +#define X86_FEATURE_SPEC_CTRL X86_CPU_FEATURE(0x7, 0, EDX, 26) +#define X86_FEATURE_FLUSH_L1D X86_CPU_FEATURE(0x7, 0, EDX, 28) +#define X86_FEATURE_ARCH_CAPABILITIES X86_CPU_FEATURE(0x7, 0, EDX, 29) +#define X86_FEATURE_PKS X86_CPU_FEATURE(0x7, 0, ECX, 31) +#define X86_FEATURE_LAM X86_CPU_FEATURE(0x7, 1, EAX, 26) /* * KVM defined leafs */ -#define KVM_FEATURE_ASYNC_PF (CPUID(0x40000001, 0, EAX, 4)) -#define KVM_FEATURE_ASYNC_PF_INT (CPUID(0x40000001, 0, EAX, 14)) +#define KVM_FEATURE_ASYNC_PF X86_CPU_FEATURE(0x40000001, 0, EAX, 4) +#define KVM_FEATURE_ASYNC_PF_INT X86_CPU_FEATURE(0x40000001, 0, EAX, 14) /* * Extended Leafs, a.k.a. AMD defined */ -#define X86_FEATURE_SVM (CPUID(0x80000001, 0, ECX, 2)) -#define X86_FEATURE_PERFCTR_CORE (CPUID(0x80000001, 0, ECX, 23)) -#define X86_FEATURE_NX (CPUID(0x80000001, 0, EDX, 20)) -#define X86_FEATURE_GBPAGES (CPUID(0x80000001, 0, EDX, 26)) -#define X86_FEATURE_RDTSCP (CPUID(0x80000001, 0, EDX, 27)) -#define X86_FEATURE_LM (CPUID(0x80000001, 0, EDX, 29)) -#define X86_FEATURE_RDPRU (CPUID(0x80000008, 0, EBX, 4)) -#define X86_FEATURE_AMD_IBPB (CPUID(0x80000008, 0, EBX, 12)) -#define X86_FEATURE_NPT (CPUID(0x8000000A, 0, EDX, 0)) -#define X86_FEATURE_LBRV (CPUID(0x8000000A, 0, EDX, 1)) -#define X86_FEATURE_NRIPS (CPUID(0x8000000A, 0, EDX, 3)) -#define X86_FEATURE_TSCRATEMSR (CPUID(0x8000000A, 0, EDX, 4)) -#define X86_FEATURE_PAUSEFILTER (CPUID(0x8000000A, 0, EDX, 10)) -#define X86_FEATURE_PFTHRESHOLD (CPUID(0x8000000A, 0, EDX, 12)) -#define X86_FEATURE_VGIF (CPUID(0x8000000A, 0, EDX, 16)) -#define X86_FEATURE_VNMI (CPUID(0x8000000A, 0, EDX, 25)) -#define X86_FEATURE_AMD_PMU_V2 (CPUID(0x80000022, 0, EAX, 0)) +#define X86_FEATURE_SVM X86_CPU_FEATURE(0x80000001, 0, ECX, 2) +#define X86_FEATURE_PERFCTR_CORE X86_CPU_FEATURE(0x80000001, 0, ECX, 23) +#define X86_FEATURE_NX X86_CPU_FEATURE(0x80000001, 0, EDX, 20) +#define X86_FEATURE_GBPAGES X86_CPU_FEATURE(0x80000001, 0, EDX, 26) +#define X86_FEATURE_RDTSCP X86_CPU_FEATURE(0x80000001, 0, EDX, 27) +#define X86_FEATURE_LM X86_CPU_FEATURE(0x80000001, 0, EDX, 29) +#define X86_FEATURE_RDPRU X86_CPU_FEATURE(0x80000008, 0, EBX, 4) +#define X86_FEATURE_AMD_IBPB X86_CPU_FEATURE(0x80000008, 0, EBX, 12) +#define X86_FEATURE_NPT X86_CPU_FEATURE(0x8000000A, 0, EDX, 0) +#define X86_FEATURE_LBRV X86_CPU_FEATURE(0x8000000A, 0, EDX, 1) +#define X86_FEATURE_NRIPS X86_CPU_FEATURE(0x8000000A, 0, EDX, 3) +#define X86_FEATURE_TSCRATEMSR X86_CPU_FEATURE(0x8000000A, 0, EDX, 4) +#define X86_FEATURE_PAUSEFILTER X86_CPU_FEATURE(0x8000000A, 0, EDX, 10) +#define X86_FEATURE_PFTHRESHOLD X86_CPU_FEATURE(0x8000000A, 0, EDX, 12) +#define X86_FEATURE_VGIF X86_CPU_FEATURE(0x8000000A, 0, EDX, 16) +#define X86_FEATURE_VNMI X86_CPU_FEATURE(0x8000000A, 0, EDX, 25) +#define X86_FEATURE_AMD_PMU_V2 X86_CPU_FEATURE(0x80000022, 0, EAX, 0) -static inline bool this_cpu_has(u64 feature) +static inline u32 __this_cpu_has(u32 function, u32 index, u8 reg, u8 lo, u8 hi) { - u32 input_eax = feature >> 32; - u32 input_ecx = (feature >> 16) & 0xffff; - u32 output_reg = (feature >> 8) & 0xff; - u8 bit = feature & 0xff; - struct cpuid c; - u32 *tmp; + union { + struct cpuid cpuid; + u32 gprs[4]; + } c; - c = cpuid_indexed(input_eax, input_ecx); - tmp = (u32 *)&c; + c.cpuid = cpuid_indexed(function, index); - return ((*(tmp + (output_reg % 32))) & (1 << bit)); + return (c.gprs[reg] & GENMASK(hi, lo)) >> lo; +} + +static inline bool this_cpu_has(struct x86_cpu_feature feature) +{ + return __this_cpu_has(feature.function, feature.index, + feature.reg, feature.bit, feature.bit); } struct far_pointer32 { -- 2.49.0.1204.g71687c7c1d-goog