Merge branch 'x86/cpu' into x86/fpu, to pick up dependent commits
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
+3
-3
@@ -1097,7 +1097,7 @@ R: Carlos Bilbao <carlos.bilbao@kernel.org>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/arch/x86/amd_hsmp.rst
|
||||
F: arch/x86/include/asm/amd_hsmp.h
|
||||
F: arch/x86/include/asm/amd/hsmp.h
|
||||
F: arch/x86/include/uapi/asm/amd_hsmp.h
|
||||
F: drivers/platform/x86/amd/hsmp/
|
||||
|
||||
@@ -1142,7 +1142,7 @@ M: Mario Limonciello <mario.limonciello@amd.com>
|
||||
M: Yazen Ghannam <yazen.ghannam@amd.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
F: arch/x86/include/asm/amd_node.h
|
||||
F: arch/x86/include/asm/amd/node.h
|
||||
F: arch/x86/kernel/amd_node.c
|
||||
|
||||
AMD PDS CORE DRIVER
|
||||
@@ -26139,7 +26139,7 @@ R: Ahmed S. Darwish <darwi@linutronix.de>
|
||||
L: x86-cpuid@lists.linux.dev
|
||||
S: Maintained
|
||||
W: https://x86-cpuid.org
|
||||
F: tools/arch/x86/kcpuid/cpuid.csv
|
||||
F: tools/arch/x86/kcpuid/
|
||||
|
||||
X86 ENTRY CODE
|
||||
M: Andy Lutomirski <luto@kernel.org>
|
||||
|
||||
@@ -26,7 +26,7 @@ static u32 ibs_caps;
|
||||
#include <linux/hardirq.h>
|
||||
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/amd-ibs.h>
|
||||
#include <asm/amd/ibs.h>
|
||||
|
||||
/* attr.config2 */
|
||||
#define IBS_SW_FILTER_MASK 1
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
|
||||
#ifndef _ASM_X86_AMD_HSMP_H_
|
||||
#define _ASM_X86_AMD_HSMP_H_
|
||||
|
||||
@@ -13,4 +12,5 @@ static inline int hsmp_send_message(struct hsmp_message *msg)
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_ASM_X86_AMD_HSMP_H_*/
|
||||
@@ -1,4 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_X86_AMD_IBS_H
|
||||
#define _ASM_X86_AMD_IBS_H
|
||||
|
||||
/*
|
||||
* From PPR Vol 1 for AMD Family 19h Model 01h B1
|
||||
* 55898 Rev 0.35 - Feb 5, 2021
|
||||
@@ -151,3 +154,5 @@ struct perf_ibs_data {
|
||||
};
|
||||
u64 regs[MSR_AMD64_IBS_REG_COUNT_MAX];
|
||||
};
|
||||
|
||||
#endif /* _ASM_X86_AMD_IBS_H */
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
struct amd_nb_bus_dev_range {
|
||||
u8 bus;
|
||||
@@ -476,11 +476,11 @@
|
||||
#define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* Clear branch history at syscall entry using SW loop */
|
||||
#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* BHI_DIS_S HW control available */
|
||||
#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* BHI_DIS_S HW control enabled */
|
||||
#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
|
||||
#define X86_FEATURE_AMD_FAST_CPPC (21*32 + 5) /* Fast CPPC */
|
||||
#define X86_FEATURE_AMD_HETEROGENEOUS_CORES (21*32 + 6) /* Heterogeneous Core Topology */
|
||||
#define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32 + 7) /* Workload Classification */
|
||||
#define X86_FEATURE_PREFER_YMM (21*32 + 8) /* Avoid ZMM registers due to downclocking */
|
||||
#define X86_FEATURE_CLEAR_BHB_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
|
||||
#define X86_FEATURE_AMD_FAST_CPPC (21*32+ 5) /* Fast CPPC */
|
||||
#define X86_FEATURE_AMD_HTR_CORES (21*32+ 6) /* Heterogeneous Core Topology */
|
||||
#define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32+ 7) /* Workload Classification */
|
||||
#define X86_FEATURE_PREFER_YMM (21*32+ 8) /* Avoid ZMM registers due to downclocking */
|
||||
|
||||
/*
|
||||
* BUG word(s)
|
||||
@@ -519,7 +519,7 @@
|
||||
#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* "itlb_multihit" CPU may incur MCE during certain page attribute changes */
|
||||
#define X86_BUG_SRBDS X86_BUG(24) /* "srbds" CPU may leak RNG bits if not mitigated */
|
||||
#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* "mmio_stale_data" CPU is affected by Processor MMIO Stale Data vulnerabilities */
|
||||
#define X86_BUG_MMIO_UNKNOWN X86_BUG(26) /* "mmio_unknown" CPU is too old and its MMIO Stale Data status is unknown */
|
||||
/* unused, was #define X86_BUG_MMIO_UNKNOWN X86_BUG(26) "mmio_unknown" CPU is too old and its MMIO Stale Data status is unknown */
|
||||
#define X86_BUG_RETBLEED X86_BUG(27) /* "retbleed" CPU is affected by RETBleed */
|
||||
#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* "eibrs_pbrsb" EIBRS is vulnerable to Post Barrier RSB Predictions */
|
||||
#define X86_BUG_SMT_RSB X86_BUG(29) /* "smt_rsb" CPU is vulnerable to Cross-Thread Return Address Predictions */
|
||||
@@ -527,10 +527,10 @@
|
||||
#define X86_BUG_TDX_PW_MCE X86_BUG(31) /* "tdx_pw_mce" CPU may incur #MC if non-TD software does partial write to TDX private memory */
|
||||
|
||||
/* BUG word 2 */
|
||||
#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* "srso" AMD SRSO bug */
|
||||
#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */
|
||||
#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
|
||||
#define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
|
||||
#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
|
||||
#define X86_BUG_SPECTRE_V2_USER X86_BUG(1*32 + 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */
|
||||
#define X86_BUG_SRSO X86_BUG( 1*32+ 0) /* "srso" AMD SRSO bug */
|
||||
#define X86_BUG_DIV0 X86_BUG( 1*32+ 1) /* "div0" AMD DIV0 speculation bug */
|
||||
#define X86_BUG_RFDS X86_BUG( 1*32+ 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
|
||||
#define X86_BUG_BHI X86_BUG( 1*32+ 3) /* "bhi" CPU is affected by Branch History Injection */
|
||||
#define X86_BUG_IBPB_NO_RET X86_BUG( 1*32+ 4) /* "ibpb_no_ret" IBPB omits return target predictions */
|
||||
#define X86_BUG_SPECTRE_V2_USER X86_BUG( 1*32+ 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */
|
||||
#endif /* _ASM_X86_CPUFEATURES_H */
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
#define _ASM_X86_CPUID_H
|
||||
|
||||
#include <asm/cpuid/api.h>
|
||||
#include <asm/cpuid/leaf_0x2_api.h>
|
||||
|
||||
#endif /* _ASM_X86_CPUID_H */
|
||||
|
||||
@@ -36,9 +36,9 @@ static inline void native_cpuid(u32 *eax, u32 *ebx,
|
||||
}
|
||||
|
||||
#define NATIVE_CPUID_REG(reg) \
|
||||
static inline u32 native_cpuid_##reg(u32 op) \
|
||||
static inline u32 native_cpuid_##reg(u32 op) \
|
||||
{ \
|
||||
u32 eax = op, ebx, ecx = 0, edx; \
|
||||
u32 eax = op, ebx, ecx = 0, edx; \
|
||||
\
|
||||
native_cpuid(&eax, &ebx, &ecx, &edx); \
|
||||
\
|
||||
@@ -207,4 +207,13 @@ static inline u32 hypervisor_cpuid_base(const char *sig, u32 leaves)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPUID(0x80000006) parsing helpers
|
||||
*/
|
||||
|
||||
static inline bool cpuid_amd_hygon_has_l3_cache(void)
|
||||
{
|
||||
return cpuid_edx(0x80000006);
|
||||
}
|
||||
|
||||
#endif /* _ASM_X86_CPUID_API_H */
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_X86_CPUID_LEAF_0x2_API_H
|
||||
#define _ASM_X86_CPUID_LEAF_0x2_API_H
|
||||
|
||||
#include <asm/cpuid/api.h>
|
||||
#include <asm/cpuid/types.h>
|
||||
|
||||
/**
|
||||
* cpuid_get_leaf_0x2_regs() - Return sanitized leaf 0x2 register output
|
||||
* @regs: Output parameter
|
||||
*
|
||||
* Query CPUID leaf 0x2 and store its output in @regs. Force set any
|
||||
* invalid 1-byte descriptor returned by the hardware to zero (the NULL
|
||||
* cache/TLB descriptor) before returning it to the caller.
|
||||
*
|
||||
* Use for_each_leaf_0x2_entry() to iterate over the register output in
|
||||
* parsed form.
|
||||
*/
|
||||
static inline void cpuid_get_leaf_0x2_regs(union leaf_0x2_regs *regs)
|
||||
{
|
||||
cpuid_leaf(0x2, regs);
|
||||
|
||||
/*
|
||||
* All Intel CPUs must report an iteration count of 1. In case
|
||||
* of bogus hardware, treat all returned descriptors as NULL.
|
||||
*/
|
||||
if (regs->desc[0] != 0x01) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
regs->regv[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The most significant bit (MSB) of each register must be clear.
|
||||
* If a register is invalid, replace its descriptors with NULL.
|
||||
*/
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (regs->reg[i].invalid)
|
||||
regs->regv[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* for_each_leaf_0x2_entry() - Iterator for parsed leaf 0x2 descriptors
|
||||
* @regs: Leaf 0x2 register output, returned by cpuid_get_leaf_0x2_regs()
|
||||
* @__ptr: u8 pointer, for macro internal use only
|
||||
* @entry: Pointer to parsed descriptor information at each iteration
|
||||
*
|
||||
* Loop over the 1-byte descriptors in the passed leaf 0x2 output registers
|
||||
* @regs. Provide the parsed information for each descriptor through @entry.
|
||||
*
|
||||
* To handle cache-specific descriptors, switch on @entry->c_type. For TLB
|
||||
* descriptors, switch on @entry->t_type.
|
||||
*
|
||||
* Example usage for cache descriptors::
|
||||
*
|
||||
* const struct leaf_0x2_table *entry;
|
||||
* union leaf_0x2_regs regs;
|
||||
* u8 *ptr;
|
||||
*
|
||||
* cpuid_get_leaf_0x2_regs(®s);
|
||||
* for_each_leaf_0x2_entry(regs, ptr, entry) {
|
||||
* switch (entry->c_type) {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
#define for_each_leaf_0x2_entry(regs, __ptr, entry) \
|
||||
for (__ptr = &(regs).desc[1]; \
|
||||
__ptr < &(regs).desc[16] && (entry = &cpuid_0x2_table[*__ptr]); \
|
||||
__ptr++)
|
||||
|
||||
#endif /* _ASM_X86_CPUID_LEAF_0x2_API_H */
|
||||
@@ -2,6 +2,7 @@
|
||||
#ifndef _ASM_X86_CPUID_TYPES_H
|
||||
#define _ASM_X86_CPUID_TYPES_H
|
||||
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
@@ -29,4 +30,99 @@ enum cpuid_regs_idx {
|
||||
#define CPUID_LEAF_FREQ 0x16
|
||||
#define CPUID_LEAF_TILE 0x1d
|
||||
|
||||
/*
|
||||
* Types for CPUID(0x2) parsing
|
||||
* Check <asm/cpuid/leaf_0x2_api.h>
|
||||
*/
|
||||
|
||||
struct leaf_0x2_reg {
|
||||
u32 : 31,
|
||||
invalid : 1;
|
||||
};
|
||||
|
||||
union leaf_0x2_regs {
|
||||
struct leaf_0x2_reg reg[4];
|
||||
u32 regv[4];
|
||||
u8 desc[16];
|
||||
};
|
||||
|
||||
/*
|
||||
* Leaf 0x2 1-byte descriptors' cache types
|
||||
* To be used for their mappings at cpuid_0x2_table[]
|
||||
*
|
||||
* Start at 1 since type 0 is reserved for HW byte descriptors which are
|
||||
* not recognized by the kernel; i.e., those without an explicit mapping.
|
||||
*/
|
||||
enum _cache_table_type {
|
||||
CACHE_L1_INST = 1,
|
||||
CACHE_L1_DATA,
|
||||
CACHE_L2,
|
||||
CACHE_L3
|
||||
/* Adjust __TLB_TABLE_TYPE_BEGIN before adding more types */
|
||||
} __packed;
|
||||
#ifndef __CHECKER__
|
||||
static_assert(sizeof(enum _cache_table_type) == 1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ensure that leaf 0x2 cache and TLB type values do not intersect,
|
||||
* since they share the same type field at struct cpuid_0x2_table.
|
||||
*/
|
||||
#define __TLB_TABLE_TYPE_BEGIN (CACHE_L3 + 1)
|
||||
|
||||
/*
|
||||
* Leaf 0x2 1-byte descriptors' TLB types
|
||||
* To be used for their mappings at cpuid_0x2_table[]
|
||||
*/
|
||||
enum _tlb_table_type {
|
||||
TLB_INST_4K = __TLB_TABLE_TYPE_BEGIN,
|
||||
TLB_INST_4M,
|
||||
TLB_INST_2M_4M,
|
||||
TLB_INST_ALL,
|
||||
|
||||
TLB_DATA_4K,
|
||||
TLB_DATA_4M,
|
||||
TLB_DATA_2M_4M,
|
||||
TLB_DATA_4K_4M,
|
||||
TLB_DATA_1G,
|
||||
TLB_DATA_1G_2M_4M,
|
||||
|
||||
TLB_DATA0_4K,
|
||||
TLB_DATA0_4M,
|
||||
TLB_DATA0_2M_4M,
|
||||
|
||||
STLB_4K,
|
||||
STLB_4K_2M,
|
||||
} __packed;
|
||||
#ifndef __CHECKER__
|
||||
static_assert(sizeof(enum _tlb_table_type) == 1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Combined parsing table for leaf 0x2 cache and TLB descriptors.
|
||||
*/
|
||||
|
||||
struct leaf_0x2_table {
|
||||
union {
|
||||
enum _cache_table_type c_type;
|
||||
enum _tlb_table_type t_type;
|
||||
};
|
||||
union {
|
||||
short c_size;
|
||||
short entries;
|
||||
};
|
||||
};
|
||||
|
||||
extern const struct leaf_0x2_table cpuid_0x2_table[256];
|
||||
|
||||
/*
|
||||
* All of leaf 0x2's one-byte TLB descriptors implies the same number of entries
|
||||
* for their respective TLB types. TLB descriptor 0x63 is an exception: it
|
||||
* implies 4 dTLB entries for 1GB pages and 32 dTLB entries for 2MB or 4MB pages.
|
||||
*
|
||||
* Encode that descriptor's dTLB entry count for 2MB/4MB pages here, as the entry
|
||||
* count for dTLB 1GB pages is already encoded at the cpuid_0x2_table[]'s mapping.
|
||||
*/
|
||||
#define TLB_0x63_2M_4M_ENTRIES 32
|
||||
|
||||
#endif /* _ASM_X86_CPUID_TYPES_H */
|
||||
|
||||
@@ -327,7 +327,7 @@
|
||||
.endm
|
||||
|
||||
.macro CLEAR_BRANCH_HISTORY_VMEXIT
|
||||
ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT
|
||||
ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_VMEXIT
|
||||
.endm
|
||||
#else
|
||||
#define CLEAR_BRANCH_HISTORY
|
||||
|
||||
@@ -272,7 +272,7 @@ int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
|
||||
}
|
||||
|
||||
/* detect if running on heterogeneous design */
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HETEROGENEOUS_CORES)) {
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES)) {
|
||||
switch (core_type) {
|
||||
case TOPO_CPU_TYPE_UNKNOWN:
|
||||
pr_warn("Undefined core type found for cpu %d\n", cpu);
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <asm/gart.h>
|
||||
#include <asm/set_memory.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
static unsigned long iommu_bus_base; /* GART remapping area (physical) */
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <asm/amd_nb.h>
|
||||
|
||||
#include <asm/amd/nb.h>
|
||||
#include <asm/cpuid.h>
|
||||
|
||||
static u32 *flush_words;
|
||||
|
||||
@@ -91,10 +93,7 @@ static int amd_cache_northbridges(void)
|
||||
if (amd_gart_present())
|
||||
amd_northbridges.flags |= AMD_NB_GART;
|
||||
|
||||
/*
|
||||
* Check for L3 cache presence.
|
||||
*/
|
||||
if (!cpuid_edx(0x80000006))
|
||||
if (!cpuid_amd_hygon_has_l3_cache())
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
/*
|
||||
* AMD Nodes are a physical collection of I/O devices within an SoC. There can be one
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <asm/gart.h>
|
||||
#include <asm/pci-direct.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
#include <asm/x86_init.h>
|
||||
#include <linux/crash_dump.h>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ obj-y += rdrand.o
|
||||
obj-y += match.o
|
||||
obj-y += bugs.o
|
||||
obj-y += aperfmperf.o
|
||||
obj-y += cpuid-deps.o
|
||||
obj-y += cpuid-deps.o cpuid_0x2_table.o
|
||||
obj-y += umwait.o
|
||||
obj-y += capflags.o powerflags.o
|
||||
|
||||
@@ -38,6 +38,9 @@ obj-y += intel.o tsx.o
|
||||
obj-$(CONFIG_PM) += intel_epb.o
|
||||
endif
|
||||
obj-$(CONFIG_CPU_SUP_AMD) += amd.o
|
||||
ifeq ($(CONFIG_AMD_NB)$(CONFIG_SYSFS),yy)
|
||||
obj-y += amd_cache_disable.o
|
||||
endif
|
||||
obj-$(CONFIG_CPU_SUP_HYGON) += hygon.o
|
||||
obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
|
||||
obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o
|
||||
|
||||
@@ -0,0 +1,301 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* AMD L3 cache_disable_{0,1} sysfs handling
|
||||
* Documentation/ABI/testing/sysfs-devices-system-cpu
|
||||
*/
|
||||
|
||||
#include <linux/cacheinfo.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <asm/amd/nb.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
/*
|
||||
* L3 cache descriptors
|
||||
*/
|
||||
static void amd_calc_l3_indices(struct amd_northbridge *nb)
|
||||
{
|
||||
struct amd_l3_cache *l3 = &nb->l3_cache;
|
||||
unsigned int sc0, sc1, sc2, sc3;
|
||||
u32 val = 0;
|
||||
|
||||
pci_read_config_dword(nb->misc, 0x1C4, &val);
|
||||
|
||||
/* calculate subcache sizes */
|
||||
l3->subcaches[0] = sc0 = !(val & BIT(0));
|
||||
l3->subcaches[1] = sc1 = !(val & BIT(4));
|
||||
|
||||
if (boot_cpu_data.x86 == 0x15) {
|
||||
l3->subcaches[0] = sc0 += !(val & BIT(1));
|
||||
l3->subcaches[1] = sc1 += !(val & BIT(5));
|
||||
}
|
||||
|
||||
l3->subcaches[2] = sc2 = !(val & BIT(8)) + !(val & BIT(9));
|
||||
l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
|
||||
|
||||
l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* check whether a slot used for disabling an L3 index is occupied.
|
||||
* @l3: L3 cache descriptor
|
||||
* @slot: slot number (0..1)
|
||||
*
|
||||
* @returns: the disabled index if used or negative value if slot free.
|
||||
*/
|
||||
static int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned int slot)
|
||||
{
|
||||
unsigned int reg = 0;
|
||||
|
||||
pci_read_config_dword(nb->misc, 0x1BC + slot * 4, ®);
|
||||
|
||||
/* check whether this slot is activated already */
|
||||
if (reg & (3UL << 30))
|
||||
return reg & 0xfff;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t show_cache_disable(struct cacheinfo *ci, char *buf, unsigned int slot)
|
||||
{
|
||||
int index;
|
||||
struct amd_northbridge *nb = ci->priv;
|
||||
|
||||
index = amd_get_l3_disable_slot(nb, slot);
|
||||
if (index >= 0)
|
||||
return sysfs_emit(buf, "%d\n", index);
|
||||
|
||||
return sysfs_emit(buf, "FREE\n");
|
||||
}
|
||||
|
||||
#define SHOW_CACHE_DISABLE(slot) \
|
||||
static ssize_t \
|
||||
cache_disable_##slot##_show(struct device *dev, \
|
||||
struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
struct cacheinfo *ci = dev_get_drvdata(dev); \
|
||||
return show_cache_disable(ci, buf, slot); \
|
||||
}
|
||||
|
||||
SHOW_CACHE_DISABLE(0)
|
||||
SHOW_CACHE_DISABLE(1)
|
||||
|
||||
static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu,
|
||||
unsigned int slot, unsigned long idx)
|
||||
{
|
||||
int i;
|
||||
|
||||
idx |= BIT(30);
|
||||
|
||||
/*
|
||||
* disable index in all 4 subcaches
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
u32 reg = idx | (i << 20);
|
||||
|
||||
if (!nb->l3_cache.subcaches[i])
|
||||
continue;
|
||||
|
||||
pci_write_config_dword(nb->misc, 0x1BC + slot * 4, reg);
|
||||
|
||||
/*
|
||||
* We need to WBINVD on a core on the node containing the L3
|
||||
* cache which indices we disable therefore a simple wbinvd()
|
||||
* is not sufficient.
|
||||
*/
|
||||
wbinvd_on_cpu(cpu);
|
||||
|
||||
reg |= BIT(31);
|
||||
pci_write_config_dword(nb->misc, 0x1BC + slot * 4, reg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* disable a L3 cache index by using a disable-slot
|
||||
*
|
||||
* @l3: L3 cache descriptor
|
||||
* @cpu: A CPU on the node containing the L3 cache
|
||||
* @slot: slot number (0..1)
|
||||
* @index: index to disable
|
||||
*
|
||||
* @return: 0 on success, error status on failure
|
||||
*/
|
||||
static int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu,
|
||||
unsigned int slot, unsigned long index)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* check if @slot is already used or the index is already disabled */
|
||||
ret = amd_get_l3_disable_slot(nb, slot);
|
||||
if (ret >= 0)
|
||||
return -EEXIST;
|
||||
|
||||
if (index > nb->l3_cache.indices)
|
||||
return -EINVAL;
|
||||
|
||||
/* check whether the other slot has disabled the same index already */
|
||||
if (index == amd_get_l3_disable_slot(nb, !slot))
|
||||
return -EEXIST;
|
||||
|
||||
amd_l3_disable_index(nb, cpu, slot, index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t store_cache_disable(struct cacheinfo *ci, const char *buf,
|
||||
size_t count, unsigned int slot)
|
||||
{
|
||||
struct amd_northbridge *nb = ci->priv;
|
||||
unsigned long val = 0;
|
||||
int cpu, err = 0;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
cpu = cpumask_first(&ci->shared_cpu_map);
|
||||
|
||||
if (kstrtoul(buf, 10, &val) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
err = amd_set_l3_disable_slot(nb, cpu, slot, val);
|
||||
if (err) {
|
||||
if (err == -EEXIST)
|
||||
pr_warn("L3 slot %d in use/index already disabled!\n",
|
||||
slot);
|
||||
return err;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#define STORE_CACHE_DISABLE(slot) \
|
||||
static ssize_t \
|
||||
cache_disable_##slot##_store(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
const char *buf, size_t count) \
|
||||
{ \
|
||||
struct cacheinfo *ci = dev_get_drvdata(dev); \
|
||||
return store_cache_disable(ci, buf, count, slot); \
|
||||
}
|
||||
|
||||
STORE_CACHE_DISABLE(0)
|
||||
STORE_CACHE_DISABLE(1)
|
||||
|
||||
static ssize_t subcaches_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct cacheinfo *ci = dev_get_drvdata(dev);
|
||||
int cpu = cpumask_first(&ci->shared_cpu_map);
|
||||
|
||||
return sysfs_emit(buf, "%x\n", amd_get_subcaches(cpu));
|
||||
}
|
||||
|
||||
static ssize_t subcaches_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct cacheinfo *ci = dev_get_drvdata(dev);
|
||||
int cpu = cpumask_first(&ci->shared_cpu_map);
|
||||
unsigned long val;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (kstrtoul(buf, 16, &val) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (amd_set_subcaches(cpu, val))
|
||||
return -EINVAL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(cache_disable_0);
|
||||
static DEVICE_ATTR_RW(cache_disable_1);
|
||||
static DEVICE_ATTR_RW(subcaches);
|
||||
|
||||
static umode_t cache_private_attrs_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int unused)
|
||||
{
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct cacheinfo *ci = dev_get_drvdata(dev);
|
||||
umode_t mode = attr->mode;
|
||||
|
||||
if (!ci->priv)
|
||||
return 0;
|
||||
|
||||
if ((attr == &dev_attr_subcaches.attr) &&
|
||||
amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
|
||||
return mode;
|
||||
|
||||
if ((attr == &dev_attr_cache_disable_0.attr ||
|
||||
attr == &dev_attr_cache_disable_1.attr) &&
|
||||
amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE))
|
||||
return mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct attribute_group cache_private_group = {
|
||||
.is_visible = cache_private_attrs_is_visible,
|
||||
};
|
||||
|
||||
static void init_amd_l3_attrs(void)
|
||||
{
|
||||
static struct attribute **amd_l3_attrs;
|
||||
int n = 1;
|
||||
|
||||
if (amd_l3_attrs) /* already initialized */
|
||||
return;
|
||||
|
||||
if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE))
|
||||
n += 2;
|
||||
if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
|
||||
n += 1;
|
||||
|
||||
amd_l3_attrs = kcalloc(n, sizeof(*amd_l3_attrs), GFP_KERNEL);
|
||||
if (!amd_l3_attrs)
|
||||
return;
|
||||
|
||||
n = 0;
|
||||
if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) {
|
||||
amd_l3_attrs[n++] = &dev_attr_cache_disable_0.attr;
|
||||
amd_l3_attrs[n++] = &dev_attr_cache_disable_1.attr;
|
||||
}
|
||||
if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
|
||||
amd_l3_attrs[n++] = &dev_attr_subcaches.attr;
|
||||
|
||||
cache_private_group.attrs = amd_l3_attrs;
|
||||
}
|
||||
|
||||
const struct attribute_group *cache_get_priv_group(struct cacheinfo *ci)
|
||||
{
|
||||
struct amd_northbridge *nb = ci->priv;
|
||||
|
||||
if (ci->level < 3 || !nb)
|
||||
return NULL;
|
||||
|
||||
if (nb && nb->l3_cache.indices)
|
||||
init_amd_l3_attrs();
|
||||
|
||||
return &cache_private_group;
|
||||
}
|
||||
|
||||
struct amd_northbridge *amd_init_l3_cache(int index)
|
||||
{
|
||||
struct amd_northbridge *nb;
|
||||
int node;
|
||||
|
||||
/* only for L3, and not in virtualized environments */
|
||||
if (index < 3)
|
||||
return NULL;
|
||||
|
||||
node = topology_amd_node_id(smp_processor_id());
|
||||
nb = node_to_amd_nb(node);
|
||||
if (nb && !nb->l3_cache.indices)
|
||||
amd_calc_l3_indices(nb);
|
||||
|
||||
return nb;
|
||||
}
|
||||
@@ -427,7 +427,6 @@ static const char * const mmio_strings[] = {
|
||||
static void __init mmio_select_mitigation(void)
|
||||
{
|
||||
if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) ||
|
||||
boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) ||
|
||||
cpu_mitigations_off()) {
|
||||
mmio_mitigation = MMIO_MITIGATION_OFF;
|
||||
return;
|
||||
@@ -590,8 +589,6 @@ out:
|
||||
pr_info("TAA: %s\n", taa_strings[taa_mitigation]);
|
||||
if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA))
|
||||
pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]);
|
||||
else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
|
||||
pr_info("MMIO Stale Data: Unknown: No mitigations\n");
|
||||
if (boot_cpu_has_bug(X86_BUG_RFDS))
|
||||
pr_info("Register File Data Sampling: %s\n", rfds_strings[rfds_mitigation]);
|
||||
}
|
||||
@@ -1706,13 +1703,13 @@ static void __init bhi_select_mitigation(void)
|
||||
|
||||
if (bhi_mitigation == BHI_MITIGATION_VMEXIT_ONLY) {
|
||||
pr_info("Spectre BHI mitigation: SW BHB clearing on VM exit only\n");
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT);
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_VMEXIT);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("Spectre BHI mitigation: SW BHB clearing on syscall and VM exit\n");
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP);
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT);
|
||||
setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_VMEXIT);
|
||||
}
|
||||
|
||||
static void __init spectre_v2_select_mitigation(void)
|
||||
@@ -2780,9 +2777,6 @@ static ssize_t tsx_async_abort_show_state(char *buf)
|
||||
|
||||
static ssize_t mmio_stale_data_show_state(char *buf)
|
||||
{
|
||||
if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
|
||||
return sysfs_emit(buf, "Unknown: No mitigations\n");
|
||||
|
||||
if (mmio_mitigation == MMIO_MITIGATION_OFF)
|
||||
return sysfs_emit(buf, "%s\n", mmio_strings[mmio_mitigation]);
|
||||
|
||||
@@ -2858,7 +2852,7 @@ static const char *spectre_bhi_state(void)
|
||||
!boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE) &&
|
||||
rrsba_disabled)
|
||||
return "; BHI: Retpoline";
|
||||
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT))
|
||||
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_VMEXIT))
|
||||
return "; BHI: Vulnerable, KVM: SW loop";
|
||||
|
||||
return "; BHI: Vulnerable";
|
||||
@@ -2967,7 +2961,6 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
||||
return srbds_show_state(buf);
|
||||
|
||||
case X86_BUG_MMIO_STALE_DATA:
|
||||
case X86_BUG_MMIO_UNKNOWN:
|
||||
return mmio_stale_data_show_state(buf);
|
||||
|
||||
case X86_BUG_RETBLEED:
|
||||
@@ -3036,10 +3029,7 @@ ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char *
|
||||
|
||||
ssize_t cpu_show_mmio_stale_data(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
|
||||
return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_UNKNOWN);
|
||||
else
|
||||
return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA);
|
||||
return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA);
|
||||
}
|
||||
|
||||
ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
|
||||
+362
-743
File diff suppressed because it is too large
Load Diff
@@ -1402,15 +1402,10 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
||||
* Affected CPU list is generally enough to enumerate the vulnerability,
|
||||
* but for virtualization case check for ARCH_CAP MSR bits also, VMM may
|
||||
* not want the guest to enumerate the bug.
|
||||
*
|
||||
* Set X86_BUG_MMIO_UNKNOWN for CPUs that are neither in the blacklist,
|
||||
* nor in the whitelist and also don't enumerate MSR ARCH_CAP MMIO bits.
|
||||
*/
|
||||
if (!arch_cap_mmio_immune(x86_arch_cap_msr)) {
|
||||
if (cpu_matches(cpu_vuln_blacklist, MMIO))
|
||||
setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA);
|
||||
else if (!cpu_matches(cpu_vuln_whitelist, NO_MMIO))
|
||||
setup_force_cpu_bug(X86_BUG_MMIO_UNKNOWN);
|
||||
}
|
||||
|
||||
if (!cpu_has(c, X86_FEATURE_BTC_NO)) {
|
||||
|
||||
@@ -75,6 +75,15 @@ extern void check_null_seg_clears_base(struct cpuinfo_x86 *c);
|
||||
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id);
|
||||
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c);
|
||||
|
||||
#if defined(CONFIG_AMD_NB) && defined(CONFIG_SYSFS)
|
||||
struct amd_northbridge *amd_init_l3_cache(int index);
|
||||
#else
|
||||
static inline struct amd_northbridge *amd_init_l3_cache(int index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int aperfmperf_get_khz(int cpu);
|
||||
void cpu_select_mitigations(void);
|
||||
|
||||
|
||||
@@ -82,8 +82,12 @@ static const struct cpuid_dep cpuid_deps[] = {
|
||||
{ X86_FEATURE_XFD, X86_FEATURE_XSAVES },
|
||||
{ X86_FEATURE_XFD, X86_FEATURE_XGETBV1 },
|
||||
{ X86_FEATURE_AMX_TILE, X86_FEATURE_XFD },
|
||||
{ X86_FEATURE_AMX_FP16, X86_FEATURE_AMX_TILE },
|
||||
{ X86_FEATURE_AMX_BF16, X86_FEATURE_AMX_TILE },
|
||||
{ X86_FEATURE_AMX_INT8, X86_FEATURE_AMX_TILE },
|
||||
{ X86_FEATURE_SHSTK, X86_FEATURE_XSAVES },
|
||||
{ X86_FEATURE_FRED, X86_FEATURE_LKGS },
|
||||
{ X86_FEATURE_SPEC_CTRL_SSBD, X86_FEATURE_SPEC_CTRL },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#include <asm/cpuid/types.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#define CACHE_ENTRY(_desc, _type, _size) \
|
||||
[_desc] = { \
|
||||
.c_type = (_type), \
|
||||
.c_size = (_size) / SZ_1K, \
|
||||
}
|
||||
|
||||
#define TLB_ENTRY(_desc, _type, _entries) \
|
||||
[_desc] = { \
|
||||
.t_type = (_type), \
|
||||
.entries = (_entries), \
|
||||
}
|
||||
|
||||
const struct leaf_0x2_table cpuid_0x2_table[256] = {
|
||||
CACHE_ENTRY(0x06, CACHE_L1_INST, SZ_8K ), /* 4-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x08, CACHE_L1_INST, SZ_16K ), /* 4-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x09, CACHE_L1_INST, SZ_32K ), /* 4-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x0a, CACHE_L1_DATA, SZ_8K ), /* 2 way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x0c, CACHE_L1_DATA, SZ_16K ), /* 4-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x0d, CACHE_L1_DATA, SZ_16K ), /* 4-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x0e, CACHE_L1_DATA, SZ_24K ), /* 6-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x21, CACHE_L2, SZ_256K ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x22, CACHE_L3, SZ_512K ), /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x23, CACHE_L3, SZ_1M ), /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x25, CACHE_L3, SZ_2M ), /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x29, CACHE_L3, SZ_4M ), /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x2c, CACHE_L1_DATA, SZ_32K ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x30, CACHE_L1_INST, SZ_32K ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x39, CACHE_L2, SZ_128K ), /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x3a, CACHE_L2, SZ_192K ), /* 6-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x3b, CACHE_L2, SZ_128K ), /* 2-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x3c, CACHE_L2, SZ_256K ), /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x3d, CACHE_L2, SZ_384K ), /* 6-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x3e, CACHE_L2, SZ_512K ), /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x3f, CACHE_L2, SZ_256K ), /* 2-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x41, CACHE_L2, SZ_128K ), /* 4-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x42, CACHE_L2, SZ_256K ), /* 4-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x43, CACHE_L2, SZ_512K ), /* 4-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x44, CACHE_L2, SZ_1M ), /* 4-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x45, CACHE_L2, SZ_2M ), /* 4-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x46, CACHE_L3, SZ_4M ), /* 4-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x47, CACHE_L3, SZ_8M ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x48, CACHE_L2, SZ_3M ), /* 12-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x49, CACHE_L3, SZ_4M ), /* 16-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x4a, CACHE_L3, SZ_6M ), /* 12-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x4b, CACHE_L3, SZ_8M ), /* 16-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x4c, CACHE_L3, SZ_12M ), /* 12-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x4d, CACHE_L3, SZ_16M ), /* 16-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x4e, CACHE_L2, SZ_6M ), /* 24-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x60, CACHE_L1_DATA, SZ_16K ), /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x66, CACHE_L1_DATA, SZ_8K ), /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x67, CACHE_L1_DATA, SZ_16K ), /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x68, CACHE_L1_DATA, SZ_32K ), /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x78, CACHE_L2, SZ_1M ), /* 4-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x79, CACHE_L2, SZ_128K ), /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x7a, CACHE_L2, SZ_256K ), /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x7b, CACHE_L2, SZ_512K ), /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x7c, CACHE_L2, SZ_1M ), /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
CACHE_ENTRY(0x7d, CACHE_L2, SZ_2M ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x7f, CACHE_L2, SZ_512K ), /* 2-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x80, CACHE_L2, SZ_512K ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x82, CACHE_L2, SZ_256K ), /* 8-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x83, CACHE_L2, SZ_512K ), /* 8-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x84, CACHE_L2, SZ_1M ), /* 8-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x85, CACHE_L2, SZ_2M ), /* 8-way set assoc, 32 byte line size */
|
||||
CACHE_ENTRY(0x86, CACHE_L2, SZ_512K ), /* 4-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0x87, CACHE_L2, SZ_1M ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xd0, CACHE_L3, SZ_512K ), /* 4-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xd1, CACHE_L3, SZ_1M ), /* 4-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xd2, CACHE_L3, SZ_2M ), /* 4-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xd6, CACHE_L3, SZ_1M ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xd7, CACHE_L3, SZ_2M ), /* 8-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xd8, CACHE_L3, SZ_4M ), /* 12-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xdc, CACHE_L3, SZ_2M ), /* 12-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xdd, CACHE_L3, SZ_4M ), /* 12-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xde, CACHE_L3, SZ_8M ), /* 12-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xe2, CACHE_L3, SZ_2M ), /* 16-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xe3, CACHE_L3, SZ_4M ), /* 16-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xe4, CACHE_L3, SZ_8M ), /* 16-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xea, CACHE_L3, SZ_12M ), /* 24-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xeb, CACHE_L3, SZ_18M ), /* 24-way set assoc, 64 byte line size */
|
||||
CACHE_ENTRY(0xec, CACHE_L3, SZ_24M ), /* 24-way set assoc, 64 byte line size */
|
||||
|
||||
TLB_ENTRY( 0x01, TLB_INST_4K, 32 ), /* TLB_INST 4 KByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0x02, TLB_INST_4M, 2 ), /* TLB_INST 4 MByte pages, full associative */
|
||||
TLB_ENTRY( 0x03, TLB_DATA_4K, 64 ), /* TLB_DATA 4 KByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0x04, TLB_DATA_4M, 8 ), /* TLB_DATA 4 MByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0x05, TLB_DATA_4M, 32 ), /* TLB_DATA 4 MByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0x0b, TLB_INST_4M, 4 ), /* TLB_INST 4 MByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0x4f, TLB_INST_4K, 32 ), /* TLB_INST 4 KByte pages */
|
||||
TLB_ENTRY( 0x50, TLB_INST_ALL, 64 ), /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
TLB_ENTRY( 0x51, TLB_INST_ALL, 128 ), /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
TLB_ENTRY( 0x52, TLB_INST_ALL, 256 ), /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
TLB_ENTRY( 0x55, TLB_INST_2M_4M, 7 ), /* TLB_INST 2-MByte or 4-MByte pages, fully associative */
|
||||
TLB_ENTRY( 0x56, TLB_DATA0_4M, 16 ), /* TLB_DATA0 4 MByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0x57, TLB_DATA0_4K, 16 ), /* TLB_DATA0 4 KByte pages, 4-way associative */
|
||||
TLB_ENTRY( 0x59, TLB_DATA0_4K, 16 ), /* TLB_DATA0 4 KByte pages, fully associative */
|
||||
TLB_ENTRY( 0x5a, TLB_DATA0_2M_4M, 32 ), /* TLB_DATA0 2-MByte or 4 MByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0x5b, TLB_DATA_4K_4M, 64 ), /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
TLB_ENTRY( 0x5c, TLB_DATA_4K_4M, 128 ), /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
TLB_ENTRY( 0x5d, TLB_DATA_4K_4M, 256 ), /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
TLB_ENTRY( 0x61, TLB_INST_4K, 48 ), /* TLB_INST 4 KByte pages, full associative */
|
||||
TLB_ENTRY( 0x63, TLB_DATA_1G_2M_4M, 4 ), /* TLB_DATA 1 GByte pages, 4-way set associative
|
||||
* (plus 32 entries TLB_DATA 2 MByte or 4 MByte pages, not encoded here) */
|
||||
TLB_ENTRY( 0x6b, TLB_DATA_4K, 256 ), /* TLB_DATA 4 KByte pages, 8-way associative */
|
||||
TLB_ENTRY( 0x6c, TLB_DATA_2M_4M, 128 ), /* TLB_DATA 2 MByte or 4 MByte pages, 8-way associative */
|
||||
TLB_ENTRY( 0x6d, TLB_DATA_1G, 16 ), /* TLB_DATA 1 GByte pages, fully associative */
|
||||
TLB_ENTRY( 0x76, TLB_INST_2M_4M, 8 ), /* TLB_INST 2-MByte or 4-MByte pages, fully associative */
|
||||
TLB_ENTRY( 0xb0, TLB_INST_4K, 128 ), /* TLB_INST 4 KByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0xb1, TLB_INST_2M_4M, 4 ), /* TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries */
|
||||
TLB_ENTRY( 0xb2, TLB_INST_4K, 64 ), /* TLB_INST 4KByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0xb3, TLB_DATA_4K, 128 ), /* TLB_DATA 4 KByte pages, 4-way set associative */
|
||||
TLB_ENTRY( 0xb4, TLB_DATA_4K, 256 ), /* TLB_DATA 4 KByte pages, 4-way associative */
|
||||
TLB_ENTRY( 0xb5, TLB_INST_4K, 64 ), /* TLB_INST 4 KByte pages, 8-way set associative */
|
||||
TLB_ENTRY( 0xb6, TLB_INST_4K, 128 ), /* TLB_INST 4 KByte pages, 8-way set associative */
|
||||
TLB_ENTRY( 0xba, TLB_DATA_4K, 64 ), /* TLB_DATA 4 KByte pages, 4-way associative */
|
||||
TLB_ENTRY( 0xc0, TLB_DATA_4K_4M, 8 ), /* TLB_DATA 4 KByte and 4 MByte pages, 4-way associative */
|
||||
TLB_ENTRY( 0xc1, STLB_4K_2M, 1024 ), /* STLB 4 KByte and 2 MByte pages, 8-way associative */
|
||||
TLB_ENTRY( 0xc2, TLB_DATA_2M_4M, 16 ), /* TLB_DATA 2 MByte/4MByte pages, 4-way associative */
|
||||
TLB_ENTRY( 0xca, STLB_4K, 512 ), /* STLB 4 KByte pages, 4-way associative */
|
||||
};
|
||||
+11
-113
@@ -6,6 +6,7 @@
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#include <linux/topology.h>
|
||||
@@ -15,6 +16,7 @@
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpuid.h>
|
||||
#include <asm/hwcap2.h>
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/microcode.h>
|
||||
@@ -646,103 +648,11 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define TLB_INST_4K 0x01
|
||||
#define TLB_INST_4M 0x02
|
||||
#define TLB_INST_2M_4M 0x03
|
||||
|
||||
#define TLB_INST_ALL 0x05
|
||||
#define TLB_INST_1G 0x06
|
||||
|
||||
#define TLB_DATA_4K 0x11
|
||||
#define TLB_DATA_4M 0x12
|
||||
#define TLB_DATA_2M_4M 0x13
|
||||
#define TLB_DATA_4K_4M 0x14
|
||||
|
||||
#define TLB_DATA_1G 0x16
|
||||
#define TLB_DATA_1G_2M_4M 0x17
|
||||
|
||||
#define TLB_DATA0_4K 0x21
|
||||
#define TLB_DATA0_4M 0x22
|
||||
#define TLB_DATA0_2M_4M 0x23
|
||||
|
||||
#define STLB_4K 0x41
|
||||
#define STLB_4K_2M 0x42
|
||||
|
||||
/*
|
||||
* All of leaf 0x2's one-byte TLB descriptors implies the same number of
|
||||
* entries for their respective TLB types. The 0x63 descriptor is an
|
||||
* exception: it implies 4 dTLB entries for 1GB pages 32 dTLB entries
|
||||
* for 2MB or 4MB pages. Encode descriptor 0x63 dTLB entry count for
|
||||
* 2MB/4MB pages here, as its count for dTLB 1GB pages is already at the
|
||||
* intel_tlb_table[] mapping.
|
||||
*/
|
||||
#define TLB_0x63_2M_4M_ENTRIES 32
|
||||
|
||||
struct _tlb_table {
|
||||
unsigned char descriptor;
|
||||
char tlb_type;
|
||||
unsigned int entries;
|
||||
};
|
||||
|
||||
static const struct _tlb_table intel_tlb_table[] = {
|
||||
{ 0x01, TLB_INST_4K, 32}, /* TLB_INST 4 KByte pages, 4-way set associative */
|
||||
{ 0x02, TLB_INST_4M, 2}, /* TLB_INST 4 MByte pages, full associative */
|
||||
{ 0x03, TLB_DATA_4K, 64}, /* TLB_DATA 4 KByte pages, 4-way set associative */
|
||||
{ 0x04, TLB_DATA_4M, 8}, /* TLB_DATA 4 MByte pages, 4-way set associative */
|
||||
{ 0x05, TLB_DATA_4M, 32}, /* TLB_DATA 4 MByte pages, 4-way set associative */
|
||||
{ 0x0b, TLB_INST_4M, 4}, /* TLB_INST 4 MByte pages, 4-way set associative */
|
||||
{ 0x4f, TLB_INST_4K, 32}, /* TLB_INST 4 KByte pages */
|
||||
{ 0x50, TLB_INST_ALL, 64}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
{ 0x51, TLB_INST_ALL, 128}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
{ 0x52, TLB_INST_ALL, 256}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
{ 0x55, TLB_INST_2M_4M, 7}, /* TLB_INST 2-MByte or 4-MByte pages, fully associative */
|
||||
{ 0x56, TLB_DATA0_4M, 16}, /* TLB_DATA0 4 MByte pages, 4-way set associative */
|
||||
{ 0x57, TLB_DATA0_4K, 16}, /* TLB_DATA0 4 KByte pages, 4-way associative */
|
||||
{ 0x59, TLB_DATA0_4K, 16}, /* TLB_DATA0 4 KByte pages, fully associative */
|
||||
{ 0x5a, TLB_DATA0_2M_4M, 32}, /* TLB_DATA0 2-MByte or 4 MByte pages, 4-way set associative */
|
||||
{ 0x5b, TLB_DATA_4K_4M, 64}, /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
{ 0x5c, TLB_DATA_4K_4M, 128}, /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
{ 0x5d, TLB_DATA_4K_4M, 256}, /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
{ 0x61, TLB_INST_4K, 48}, /* TLB_INST 4 KByte pages, full associative */
|
||||
{ 0x63, TLB_DATA_1G_2M_4M, 4}, /* TLB_DATA 1 GByte pages, 4-way set associative
|
||||
* (plus 32 entries TLB_DATA 2 MByte or 4 MByte pages, not encoded here) */
|
||||
{ 0x6b, TLB_DATA_4K, 256}, /* TLB_DATA 4 KByte pages, 8-way associative */
|
||||
{ 0x6c, TLB_DATA_2M_4M, 128}, /* TLB_DATA 2 MByte or 4 MByte pages, 8-way associative */
|
||||
{ 0x6d, TLB_DATA_1G, 16}, /* TLB_DATA 1 GByte pages, fully associative */
|
||||
{ 0x76, TLB_INST_2M_4M, 8}, /* TLB_INST 2-MByte or 4-MByte pages, fully associative */
|
||||
{ 0xb0, TLB_INST_4K, 128}, /* TLB_INST 4 KByte pages, 4-way set associative */
|
||||
{ 0xb1, TLB_INST_2M_4M, 4}, /* TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries */
|
||||
{ 0xb2, TLB_INST_4K, 64}, /* TLB_INST 4KByte pages, 4-way set associative */
|
||||
{ 0xb3, TLB_DATA_4K, 128}, /* TLB_DATA 4 KByte pages, 4-way set associative */
|
||||
{ 0xb4, TLB_DATA_4K, 256}, /* TLB_DATA 4 KByte pages, 4-way associative */
|
||||
{ 0xb5, TLB_INST_4K, 64}, /* TLB_INST 4 KByte pages, 8-way set associative */
|
||||
{ 0xb6, TLB_INST_4K, 128}, /* TLB_INST 4 KByte pages, 8-way set associative */
|
||||
{ 0xba, TLB_DATA_4K, 64}, /* TLB_DATA 4 KByte pages, 4-way associative */
|
||||
{ 0xc0, TLB_DATA_4K_4M, 8}, /* TLB_DATA 4 KByte and 4 MByte pages, 4-way associative */
|
||||
{ 0xc1, STLB_4K_2M, 1024}, /* STLB 4 KByte and 2 MByte pages, 8-way associative */
|
||||
{ 0xc2, TLB_DATA_2M_4M, 16}, /* TLB_DATA 2 MByte/4MByte pages, 4-way associative */
|
||||
{ 0xca, STLB_4K, 512}, /* STLB 4 KByte pages, 4-way associative */
|
||||
{ 0x00, 0, 0 }
|
||||
};
|
||||
|
||||
static void intel_tlb_lookup(const unsigned char desc)
|
||||
static void intel_tlb_lookup(const struct leaf_0x2_table *entry)
|
||||
{
|
||||
unsigned int entries;
|
||||
unsigned char k;
|
||||
short entries = entry->entries;
|
||||
|
||||
if (desc == 0)
|
||||
return;
|
||||
|
||||
/* look up this descriptor in the table */
|
||||
for (k = 0; intel_tlb_table[k].descriptor != desc &&
|
||||
intel_tlb_table[k].descriptor != 0; k++)
|
||||
;
|
||||
|
||||
if (intel_tlb_table[k].tlb_type == 0)
|
||||
return;
|
||||
|
||||
entries = intel_tlb_table[k].entries;
|
||||
switch (intel_tlb_table[k].tlb_type) {
|
||||
switch (entry->t_type) {
|
||||
case STLB_4K:
|
||||
tlb_lli_4k = max(tlb_lli_4k, entries);
|
||||
tlb_lld_4k = max(tlb_lld_4k, entries);
|
||||
@@ -799,28 +709,16 @@ static void intel_tlb_lookup(const unsigned char desc)
|
||||
|
||||
static void intel_detect_tlb(struct cpuinfo_x86 *c)
|
||||
{
|
||||
int i, j, n;
|
||||
unsigned int regs[4];
|
||||
unsigned char *desc = (unsigned char *)regs;
|
||||
const struct leaf_0x2_table *entry;
|
||||
union leaf_0x2_regs regs;
|
||||
u8 *ptr;
|
||||
|
||||
if (c->cpuid_level < 2)
|
||||
return;
|
||||
|
||||
/* Number of times to iterate */
|
||||
n = cpuid_eax(2) & 0xFF;
|
||||
|
||||
for (i = 0 ; i < n ; i++) {
|
||||
cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]);
|
||||
|
||||
/* If bit 31 is set, this is an unknown format */
|
||||
for (j = 0 ; j < 4 ; j++)
|
||||
if (regs[j] & (1 << 31))
|
||||
regs[j] = 0;
|
||||
|
||||
/* Byte 0 is level count, not a descriptor */
|
||||
for (j = 1 ; j < 16 ; j++)
|
||||
intel_tlb_lookup(desc[j]);
|
||||
}
|
||||
cpuid_get_leaf_0x2_regs(®s);
|
||||
for_each_leaf_0x2_entry(regs, ptr, entry)
|
||||
intel_tlb_lookup(entry);
|
||||
}
|
||||
|
||||
static const struct cpu_dev intel_cpu_dev = {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/irq_vectors.h>
|
||||
#include <asm/mce.h>
|
||||
|
||||
@@ -53,7 +53,7 @@ static const struct cpuid_bit cpuid_bits[] = {
|
||||
{ X86_FEATURE_PERFMON_V2, CPUID_EAX, 0, 0x80000022, 0 },
|
||||
{ X86_FEATURE_AMD_LBR_V2, CPUID_EAX, 1, 0x80000022, 0 },
|
||||
{ X86_FEATURE_AMD_LBR_PMC_FREEZE, CPUID_EAX, 2, 0x80000022, 0 },
|
||||
{ X86_FEATURE_AMD_HETEROGENEOUS_CORES, CPUID_EAX, 30, 0x80000026, 0 },
|
||||
{ X86_FEATURE_AMD_HTR_CORES, CPUID_EAX, 30, 0x80000026, 0 },
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ static void parse_topology_amd(struct topo_scan *tscan)
|
||||
if (cpu_feature_enabled(X86_FEATURE_TOPOEXT))
|
||||
has_topoext = cpu_parse_topology_ext(tscan);
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HETEROGENEOUS_CORES))
|
||||
if (cpu_feature_enabled(X86_FEATURE_AMD_HTR_CORES))
|
||||
tscan->c->topo.cpu_type = cpuid_ebx(0x80000026);
|
||||
|
||||
if (!has_topoext && !parse_8000_0008(tscan))
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <asm/numa.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
|
||||
static unsigned char __initdata nodeids[8];
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
#include <asm/e820/api.h>
|
||||
#include <asm/proto.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
|
||||
#include "numa_internal.h"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/range.h>
|
||||
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
#include <asm/pci_x86.h>
|
||||
|
||||
#include <asm/pci-direct.h>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/vgaarb.h>
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
#include <asm/hpet.h>
|
||||
#include <asm/pci_x86.h>
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <linux/mmzone.h>
|
||||
#include <asm/page.h> /* PAGE_SIZE */
|
||||
#include <asm/e820/api.h>
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
#include <asm/gart.h>
|
||||
#include "agp.h"
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#include <linux/ras.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include "amd64_edac.h"
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/nb.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
static struct edac_pci_ctl_info *pci_ctl;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor");
|
||||
|
||||
@@ -72,6 +72,8 @@ static const char * const cma_events[] = {
|
||||
static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid,
|
||||
enum ib_gid_type gid_type);
|
||||
|
||||
static void cma_netevent_work_handler(struct work_struct *_work);
|
||||
|
||||
const char *__attribute_const__ rdma_event_msg(enum rdma_cm_event_type event)
|
||||
{
|
||||
size_t index = event;
|
||||
@@ -1047,6 +1049,7 @@ __rdma_create_id(struct net *net, rdma_cm_event_handler event_handler,
|
||||
get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num);
|
||||
id_priv->id.route.addr.dev_addr.net = get_net(net);
|
||||
id_priv->seq_num &= 0x00ffffff;
|
||||
INIT_WORK(&id_priv->id.net_work, cma_netevent_work_handler);
|
||||
|
||||
rdma_restrack_new(&id_priv->res, RDMA_RESTRACK_CM_ID);
|
||||
if (parent)
|
||||
@@ -5241,7 +5244,6 @@ static int cma_netevent_callback(struct notifier_block *self,
|
||||
if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
|
||||
neigh->ha, ETH_ALEN))
|
||||
continue;
|
||||
INIT_WORK(¤t_id->id.net_work, cma_netevent_work_handler);
|
||||
cma_id_get(current_id);
|
||||
queue_work(cma_wq, ¤t_id->id.net_work);
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ int ib_create_ucap(enum rdma_user_cap type)
|
||||
ucap->dev.class = &ucaps_class;
|
||||
ucap->dev.devt = MKDEV(MAJOR(ucaps_base_dev), type);
|
||||
ucap->dev.release = ucap_dev_release;
|
||||
ret = dev_set_name(&ucap->dev, ucap_names[type]);
|
||||
ret = dev_set_name(&ucap->dev, "%s", ucap_names[type]);
|
||||
if (ret)
|
||||
goto err_device;
|
||||
|
||||
|
||||
@@ -76,12 +76,14 @@ static inline int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
|
||||
|
||||
npfns = (end - start) >> PAGE_SHIFT;
|
||||
umem_odp->pfn_list = kvcalloc(
|
||||
npfns, sizeof(*umem_odp->pfn_list), GFP_KERNEL);
|
||||
npfns, sizeof(*umem_odp->pfn_list),
|
||||
GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!umem_odp->pfn_list)
|
||||
return -ENOMEM;
|
||||
|
||||
umem_odp->dma_list = kvcalloc(
|
||||
ndmas, sizeof(*umem_odp->dma_list), GFP_KERNEL);
|
||||
ndmas, sizeof(*umem_odp->dma_list),
|
||||
GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!umem_odp->dma_list) {
|
||||
ret = -ENOMEM;
|
||||
goto out_pfn_list;
|
||||
|
||||
@@ -1774,10 +1774,7 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq, struct ib_udata *udata)
|
||||
ib_srq);
|
||||
struct bnxt_re_dev *rdev = srq->rdev;
|
||||
struct bnxt_qplib_srq *qplib_srq = &srq->qplib_srq;
|
||||
struct bnxt_qplib_nq *nq = NULL;
|
||||
|
||||
if (qplib_srq->cq)
|
||||
nq = qplib_srq->cq->nq;
|
||||
if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT) {
|
||||
free_page((unsigned long)srq->uctx_srq_page);
|
||||
hash_del(&srq->hash_entry);
|
||||
@@ -1785,8 +1782,6 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq, struct ib_udata *udata)
|
||||
bnxt_qplib_destroy_srq(&rdev->qplib_res, qplib_srq);
|
||||
ib_umem_release(srq->umem);
|
||||
atomic_dec(&rdev->stats.res.srq_count);
|
||||
if (nq)
|
||||
nq->budget--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1827,7 +1822,6 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
struct bnxt_qplib_dev_attr *dev_attr;
|
||||
struct bnxt_qplib_nq *nq = NULL;
|
||||
struct bnxt_re_ucontext *uctx;
|
||||
struct bnxt_re_dev *rdev;
|
||||
struct bnxt_re_srq *srq;
|
||||
@@ -1873,7 +1867,6 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
|
||||
srq->qplib_srq.eventq_hw_ring_id = rdev->nqr->nq[0].ring_id;
|
||||
srq->qplib_srq.sg_info.pgsize = PAGE_SIZE;
|
||||
srq->qplib_srq.sg_info.pgshft = PAGE_SHIFT;
|
||||
nq = &rdev->nqr->nq[0];
|
||||
|
||||
if (udata) {
|
||||
rc = bnxt_re_init_user_srq(rdev, pd, srq, udata);
|
||||
@@ -1908,8 +1901,6 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (nq)
|
||||
nq->budget++;
|
||||
active_srqs = atomic_inc_return(&rdev->stats.res.srq_count);
|
||||
if (active_srqs > rdev->stats.res.srq_watermark)
|
||||
rdev->stats.res.srq_watermark = active_srqs;
|
||||
@@ -3079,7 +3070,6 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
|
||||
ib_umem_release(cq->umem);
|
||||
|
||||
atomic_dec(&rdev->stats.res.cq_count);
|
||||
nq->budget--;
|
||||
kfree(cq->cql);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -763,7 +763,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
dma_set_max_seg_size(dev, UINT_MAX);
|
||||
dma_set_max_seg_size(dev, SZ_2G);
|
||||
ret = ib_register_device(ib_dev, "hns_%d", dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "ib_register_device failed!\n");
|
||||
|
||||
@@ -3461,7 +3461,6 @@ DECLARE_UVERBS_NAMED_OBJECT(
|
||||
&UVERBS_METHOD(MLX5_IB_METHOD_STEERING_ANCHOR_DESTROY));
|
||||
|
||||
const struct uapi_definition mlx5_ib_flow_defs[] = {
|
||||
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
|
||||
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
|
||||
MLX5_IB_OBJECT_FLOW_MATCHER),
|
||||
UAPI_DEF_CHAIN_OBJ_TREE(
|
||||
@@ -3472,7 +3471,6 @@ const struct uapi_definition mlx5_ib_flow_defs[] = {
|
||||
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
|
||||
MLX5_IB_OBJECT_STEERING_ANCHOR,
|
||||
UAPI_DEF_IS_OBJ_SUPPORTED(mlx5_ib_shared_ft_allowed)),
|
||||
#endif
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
@@ -397,7 +397,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
|
||||
if (!us_ibdev) {
|
||||
usnic_err("Device %s context alloc failed\n",
|
||||
netdev_name(pci_get_drvdata(dev)));
|
||||
return ERR_PTR(-EFAULT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
us_ibdev->ufdev = usnic_fwd_dev_alloc(dev);
|
||||
@@ -517,8 +517,8 @@ static struct usnic_ib_dev *usnic_ib_discover_pf(struct usnic_vnic *vnic)
|
||||
}
|
||||
|
||||
us_ibdev = usnic_ib_device_add(parent_pci);
|
||||
if (IS_ERR_OR_NULL(us_ibdev)) {
|
||||
us_ibdev = us_ibdev ? us_ibdev : ERR_PTR(-EFAULT);
|
||||
if (!us_ibdev) {
|
||||
us_ibdev = ERR_PTR(-EFAULT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -586,10 +586,10 @@ static int usnic_ib_pci_probe(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
pf = usnic_ib_discover_pf(vf->vnic);
|
||||
if (IS_ERR_OR_NULL(pf)) {
|
||||
usnic_err("Failed to discover pf of vnic %s with err%ld\n",
|
||||
pci_name(pdev), PTR_ERR(pf));
|
||||
err = pf ? PTR_ERR(pf) : -EFAULT;
|
||||
if (IS_ERR(pf)) {
|
||||
err = PTR_ERR(pf);
|
||||
usnic_err("Failed to discover pf of vnic %s with err%d\n",
|
||||
pci_name(pdev), err);
|
||||
goto out_clean_vnic;
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,12 @@ static inline int qp_mtu(struct rxe_qp *qp)
|
||||
return IB_MTU_4096;
|
||||
}
|
||||
|
||||
static inline bool is_odp_mr(struct rxe_mr *mr)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING) && mr->umem &&
|
||||
mr->umem->is_odp;
|
||||
}
|
||||
|
||||
void free_rd_atomic_resource(struct resp_res *res);
|
||||
|
||||
static inline void rxe_advance_resp_resource(struct rxe_qp *qp)
|
||||
|
||||
@@ -323,7 +323,7 @@ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (mr->umem->is_odp)
|
||||
if (is_odp_mr(mr))
|
||||
return rxe_odp_mr_copy(mr, iova, addr, length, dir);
|
||||
else
|
||||
return rxe_mr_copy_xarray(mr, iova, addr, length, dir);
|
||||
@@ -536,7 +536,7 @@ int rxe_mr_do_atomic_write(struct rxe_mr *mr, u64 iova, u64 value)
|
||||
u64 *va;
|
||||
|
||||
/* ODP is not supported right now. WIP. */
|
||||
if (mr->umem->is_odp)
|
||||
if (is_odp_mr(mr))
|
||||
return RESPST_ERR_UNSUPPORTED_OPCODE;
|
||||
|
||||
/* See IBA oA19-28 */
|
||||
|
||||
@@ -650,7 +650,7 @@ static enum resp_states process_flush(struct rxe_qp *qp,
|
||||
struct resp_res *res = qp->resp.res;
|
||||
|
||||
/* ODP is not supported right now. WIP. */
|
||||
if (mr->umem->is_odp)
|
||||
if (is_odp_mr(mr))
|
||||
return RESPST_ERR_UNSUPPORTED_OPCODE;
|
||||
|
||||
/* oA19-14, oA19-15 */
|
||||
@@ -706,7 +706,7 @@ static enum resp_states atomic_reply(struct rxe_qp *qp,
|
||||
if (!res->replay) {
|
||||
u64 iova = qp->resp.va + qp->resp.offset;
|
||||
|
||||
if (mr->umem->is_odp)
|
||||
if (is_odp_mr(mr))
|
||||
err = rxe_odp_atomic_op(mr, iova, pkt->opcode,
|
||||
atmeth_comp(pkt),
|
||||
atmeth_swap_add(pkt),
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <asm/amd_hsmp.h>
|
||||
#include <asm/amd/hsmp.h>
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <uapi/asm-generic/errno-base.h>
|
||||
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
#include "hsmp.h"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* This file provides a device implementation for HSMP interface
|
||||
*/
|
||||
|
||||
#include <asm/amd_hsmp.h>
|
||||
#include <asm/amd/hsmp.h>
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <asm/amd_hsmp.h>
|
||||
#include <asm/amd/hsmp.h>
|
||||
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/device.h>
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
#include "hsmp.h"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
#include "pmf.h"
|
||||
|
||||
/* PMF-SMU communication registers */
|
||||
|
||||
@@ -290,7 +290,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
|
||||
|
||||
#ifdef CONFIG_AMD_NB
|
||||
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd/nb.h>
|
||||
|
||||
static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
|
||||
{
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/ras.h>
|
||||
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/nb.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
#include "reg_fields.h"
|
||||
|
||||
@@ -362,4 +362,7 @@ static inline void atl_debug_on_bad_intlv_mode(struct addr_ctx *ctx)
|
||||
atl_debug(ctx, "Unrecognized interleave mode: %u", ctx->map.intlv_mode);
|
||||
}
|
||||
|
||||
#define MI300_UMC_MCA_COL GENMASK(5, 1)
|
||||
#define MI300_UMC_MCA_ROW13 BIT(23)
|
||||
|
||||
#endif /* __AMD_ATL_INTERNAL_H__ */
|
||||
|
||||
@@ -229,7 +229,6 @@ int get_umc_info_mi300(void)
|
||||
* Additionally, the PC and Bank bits may be hashed. This must be accounted for before
|
||||
* reconstructing the normalized address.
|
||||
*/
|
||||
#define MI300_UMC_MCA_COL GENMASK(5, 1)
|
||||
#define MI300_UMC_MCA_BANK GENMASK(9, 6)
|
||||
#define MI300_UMC_MCA_ROW GENMASK(24, 10)
|
||||
#define MI300_UMC_MCA_PC BIT(25)
|
||||
@@ -320,7 +319,7 @@ static unsigned long convert_dram_to_norm_addr_mi300(unsigned long addr)
|
||||
* See amd_atl::convert_dram_to_norm_addr_mi300() for MI300 address formats.
|
||||
*/
|
||||
#define MI300_NUM_COL BIT(HWEIGHT(MI300_UMC_MCA_COL))
|
||||
static void retire_row_mi300(struct atl_err *a_err)
|
||||
static void _retire_row_mi300(struct atl_err *a_err)
|
||||
{
|
||||
unsigned long addr;
|
||||
struct page *p;
|
||||
@@ -351,6 +350,22 @@ static void retire_row_mi300(struct atl_err *a_err)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In addition to the column bits, the row[13] bit should also be included when
|
||||
* calculating addresses affected by a physical row.
|
||||
*
|
||||
* Instead of running through another loop over a single bit, just run through
|
||||
* the column bits twice and flip the row[13] bit in-between.
|
||||
*
|
||||
* See MI300_UMC_MCA_ROW for the row bits in MCA_ADDR_UMC value.
|
||||
*/
|
||||
static void retire_row_mi300(struct atl_err *a_err)
|
||||
{
|
||||
_retire_row_mi300(a_err);
|
||||
a_err->addr ^= MI300_UMC_MCA_ROW13;
|
||||
_retire_row_mi300(a_err);
|
||||
}
|
||||
|
||||
void amd_retire_dram_row(struct atl_err *a_err)
|
||||
{
|
||||
if (df_cfg.rev == DF4p5 && df_cfg.flags.heterogeneous)
|
||||
|
||||
@@ -250,6 +250,13 @@ static bool rec_has_valid_entries(struct fru_rec *rec)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Row retirement is done on MI300 systems, and some bits are 'don't
|
||||
* care' for comparing addresses with unique physical rows. This
|
||||
* includes all column bits and the row[13] bit.
|
||||
*/
|
||||
#define MASK_ADDR(addr) ((addr) & ~(MI300_UMC_MCA_ROW13 | MI300_UMC_MCA_COL))
|
||||
|
||||
static bool fpds_equal(struct cper_fru_poison_desc *old, struct cper_fru_poison_desc *new)
|
||||
{
|
||||
/*
|
||||
@@ -258,7 +265,7 @@ static bool fpds_equal(struct cper_fru_poison_desc *old, struct cper_fru_poison_
|
||||
*
|
||||
* Also, order the checks from most->least likely to fail to shortcut the code.
|
||||
*/
|
||||
if (old->addr != new->addr)
|
||||
if (MASK_ADDR(old->addr) != MASK_ADDR(new->addr))
|
||||
return false;
|
||||
|
||||
if (old->hw_id != new->hw_id)
|
||||
|
||||
+2
-2
@@ -348,9 +348,9 @@ static int afs_dynroot_readdir(struct file *file, struct dir_context *ctx)
|
||||
}
|
||||
|
||||
if ((unsigned long long)ctx->pos <= AFS_MAX_DYNROOT_CELL_INO) {
|
||||
rcu_read_lock();
|
||||
down_read(&net->cells_lock);
|
||||
ret = afs_dynroot_readdir_cells(net, ctx);
|
||||
rcu_read_unlock();
|
||||
up_read(&net->cells_lock);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
+2
-2
@@ -89,12 +89,12 @@ enum {
|
||||
};
|
||||
|
||||
static const struct fs_parameter_spec devpts_param_specs[] = {
|
||||
fsparam_u32 ("gid", Opt_gid),
|
||||
fsparam_gid ("gid", Opt_gid),
|
||||
fsparam_s32 ("max", Opt_max),
|
||||
fsparam_u32oct ("mode", Opt_mode),
|
||||
fsparam_flag ("newinstance", Opt_newinstance),
|
||||
fsparam_u32oct ("ptmxmode", Opt_ptmxmode),
|
||||
fsparam_u32 ("uid", Opt_uid),
|
||||
fsparam_uid ("uid", Opt_uid),
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -1669,6 +1669,9 @@ static int virtio_fs_get_tree(struct fs_context *fsc)
|
||||
unsigned int virtqueue_size;
|
||||
int err = -EIO;
|
||||
|
||||
if (!fsc->source)
|
||||
return invalf(fsc, "No source specified");
|
||||
|
||||
/* This gets a reference on virtio_fs object. This ptr gets installed
|
||||
* in fc->iq->priv. Once fuse_conn is going away, it calls ->put()
|
||||
* to drop the reference to this object.
|
||||
|
||||
@@ -67,6 +67,12 @@ void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off)
|
||||
else
|
||||
key_len = tree->max_key_len + 1;
|
||||
|
||||
if (key_len > sizeof(hfs_btree_key) || key_len < 1) {
|
||||
memset(key, 0, sizeof(hfs_btree_key));
|
||||
pr_err("hfs: Invalid key length: %d\n", key_len);
|
||||
return;
|
||||
}
|
||||
|
||||
hfs_bnode_read(node, key, off, key_len);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,12 @@ void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off)
|
||||
else
|
||||
key_len = tree->max_key_len + 2;
|
||||
|
||||
if (key_len > sizeof(hfsplus_btree_key) || key_len < 1) {
|
||||
memset(key, 0, sizeof(hfsplus_btree_key));
|
||||
pr_err("hfsplus: Invalid key length: %d\n", key_len);
|
||||
return;
|
||||
}
|
||||
|
||||
hfs_bnode_read(node, key, off, key_len);
|
||||
}
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio,
|
||||
}
|
||||
|
||||
/* truncate len if we find any trailing uptodate block(s) */
|
||||
for ( ; i <= last; i++) {
|
||||
while (++i <= last) {
|
||||
if (ifs_block_is_uptodate(ifs, i)) {
|
||||
plen -= (last - i + 1) * block_size;
|
||||
last = i - 1;
|
||||
|
||||
+1
-1
@@ -180,7 +180,7 @@ static struct dentry *isofs_fh_to_parent(struct super_block *sb,
|
||||
return NULL;
|
||||
|
||||
return isofs_export_iget(sb,
|
||||
fh_len > 2 ? ifid->parent_block : 0,
|
||||
fh_len > 3 ? ifid->parent_block : 0,
|
||||
ifid->parent_offset,
|
||||
fh_len > 4 ? ifid->parent_generation : 0);
|
||||
}
|
||||
|
||||
+4
-4
@@ -125,9 +125,9 @@
|
||||
|
||||
#define EMBEDDED_NAME_MAX (PATH_MAX - offsetof(struct filename, iname))
|
||||
|
||||
static inline void initname(struct filename *name)
|
||||
static inline void initname(struct filename *name, const char __user *uptr)
|
||||
{
|
||||
name->uptr = NULL;
|
||||
name->uptr = uptr;
|
||||
name->aname = NULL;
|
||||
atomic_set(&name->refcnt, 1);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ getname_flags(const char __user *filename, int flags)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
}
|
||||
}
|
||||
initname(result);
|
||||
initname(result, filename);
|
||||
audit_getname(result);
|
||||
return result;
|
||||
}
|
||||
@@ -268,7 +268,7 @@ struct filename *getname_kernel(const char * filename)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
}
|
||||
memcpy((char *)result->name, filename, len);
|
||||
initname(result);
|
||||
initname(result, NULL);
|
||||
audit_getname(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
+21
-13
@@ -1830,6 +1830,8 @@ static inline void namespace_lock(void)
|
||||
down_write(&namespace_sem);
|
||||
}
|
||||
|
||||
DEFINE_GUARD(namespace_lock, struct rw_semaphore *, namespace_lock(), namespace_unlock())
|
||||
|
||||
enum umount_tree_flags {
|
||||
UMOUNT_SYNC = 1,
|
||||
UMOUNT_PROPAGATE = 2,
|
||||
@@ -2383,7 +2385,7 @@ void dissolve_on_fput(struct vfsmount *mnt)
|
||||
return;
|
||||
}
|
||||
|
||||
scoped_guard(rwsem_write, &namespace_sem) {
|
||||
scoped_guard(namespace_lock, &namespace_sem) {
|
||||
ns = m->mnt_ns;
|
||||
if (!must_dissolve(ns))
|
||||
return;
|
||||
@@ -5189,8 +5191,8 @@ static void finish_mount_kattr(struct mount_kattr *kattr)
|
||||
mnt_idmap_put(kattr->mnt_idmap);
|
||||
}
|
||||
|
||||
static int copy_mount_setattr(struct mount_attr __user *uattr, size_t usize,
|
||||
struct mount_kattr *kattr)
|
||||
static int wants_mount_setattr(struct mount_attr __user *uattr, size_t usize,
|
||||
struct mount_kattr *kattr)
|
||||
{
|
||||
int ret;
|
||||
struct mount_attr attr;
|
||||
@@ -5213,9 +5215,13 @@ static int copy_mount_setattr(struct mount_attr __user *uattr, size_t usize,
|
||||
if (attr.attr_set == 0 &&
|
||||
attr.attr_clr == 0 &&
|
||||
attr.propagation == 0)
|
||||
return 0;
|
||||
return 0; /* Tell caller to not bother. */
|
||||
|
||||
return build_mount_kattr(&attr, usize, kattr);
|
||||
ret = build_mount_kattr(&attr, usize, kattr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path,
|
||||
@@ -5247,8 +5253,8 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path,
|
||||
if (flags & AT_RECURSIVE)
|
||||
kattr.kflags |= MOUNT_KATTR_RECURSE;
|
||||
|
||||
err = copy_mount_setattr(uattr, usize, &kattr);
|
||||
if (err)
|
||||
err = wants_mount_setattr(uattr, usize, &kattr);
|
||||
if (err <= 0)
|
||||
return err;
|
||||
|
||||
err = user_path_at(dfd, path, kattr.lookup_flags, &target);
|
||||
@@ -5282,15 +5288,17 @@ SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename,
|
||||
if (flags & AT_RECURSIVE)
|
||||
kattr.kflags |= MOUNT_KATTR_RECURSE;
|
||||
|
||||
ret = copy_mount_setattr(uattr, usize, &kattr);
|
||||
if (ret)
|
||||
ret = wants_mount_setattr(uattr, usize, &kattr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = do_mount_setattr(&file->f_path, &kattr);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret) {
|
||||
ret = do_mount_setattr(&file->f_path, &kattr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
finish_mount_kattr(&kattr);
|
||||
finish_mount_kattr(&kattr);
|
||||
}
|
||||
}
|
||||
|
||||
fd = get_unused_fd_flags(flags & O_CLOEXEC);
|
||||
|
||||
@@ -127,11 +127,13 @@ static int __init netfs_init(void)
|
||||
if (mempool_init_slab_pool(&netfs_subrequest_pool, 100, netfs_subrequest_slab) < 0)
|
||||
goto error_subreqpool;
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
if (!proc_mkdir("fs/netfs", NULL))
|
||||
goto error_proc;
|
||||
if (!proc_create_seq("fs/netfs/requests", S_IFREG | 0444, NULL,
|
||||
&netfs_requests_seq_ops))
|
||||
goto error_procfile;
|
||||
#endif
|
||||
#ifdef CONFIG_FSCACHE_STATS
|
||||
if (!proc_create_single("fs/netfs/stats", S_IFREG | 0444, NULL,
|
||||
netfs_stats_show))
|
||||
@@ -144,9 +146,11 @@ static int __init netfs_init(void)
|
||||
return 0;
|
||||
|
||||
error_fscache:
|
||||
#ifdef CONFIG_PROC_FS
|
||||
error_procfile:
|
||||
remove_proc_subtree("fs/netfs", NULL);
|
||||
error_proc:
|
||||
#endif
|
||||
mempool_exit(&netfs_subrequest_pool);
|
||||
error_subreqpool:
|
||||
kmem_cache_destroy(netfs_subrequest_slab);
|
||||
|
||||
@@ -541,8 +541,6 @@ int ovl_set_metacopy_xattr(struct ovl_fs *ofs, struct dentry *d,
|
||||
bool ovl_is_metacopy_dentry(struct dentry *dentry);
|
||||
char *ovl_get_redirect_xattr(struct ovl_fs *ofs, const struct path *path, int padding);
|
||||
int ovl_ensure_verity_loaded(struct path *path);
|
||||
int ovl_get_verity_xattr(struct ovl_fs *ofs, const struct path *path,
|
||||
u8 *digest_buf, int *buf_length);
|
||||
int ovl_validate_verity(struct ovl_fs *ofs,
|
||||
struct path *metapath,
|
||||
struct path *datapath);
|
||||
|
||||
@@ -1138,6 +1138,11 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (ctx->nr == ctx->nr_data) {
|
||||
pr_err("at least one non-data lowerdir is required\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
err = -EINVAL;
|
||||
for (i = 0; i < ctx->nr; i++) {
|
||||
l = &ctx->lower[i];
|
||||
|
||||
+49
-55
@@ -173,65 +173,59 @@ struct dentry_operations {
|
||||
*/
|
||||
|
||||
/* d_flags entries */
|
||||
#define DCACHE_OP_HASH BIT(0)
|
||||
#define DCACHE_OP_COMPARE BIT(1)
|
||||
#define DCACHE_OP_REVALIDATE BIT(2)
|
||||
#define DCACHE_OP_DELETE BIT(3)
|
||||
#define DCACHE_OP_PRUNE BIT(4)
|
||||
enum dentry_flags {
|
||||
DCACHE_OP_HASH = BIT(0),
|
||||
DCACHE_OP_COMPARE = BIT(1),
|
||||
DCACHE_OP_REVALIDATE = BIT(2),
|
||||
DCACHE_OP_DELETE = BIT(3),
|
||||
DCACHE_OP_PRUNE = BIT(4),
|
||||
/*
|
||||
* This dentry is possibly not currently connected to the dcache tree,
|
||||
* in which case its parent will either be itself, or will have this
|
||||
* flag as well. nfsd will not use a dentry with this bit set, but will
|
||||
* first endeavour to clear the bit either by discovering that it is
|
||||
* connected, or by performing lookup operations. Any filesystem which
|
||||
* supports nfsd_operations MUST have a lookup function which, if it
|
||||
* finds a directory inode with a DCACHE_DISCONNECTED dentry, will
|
||||
* d_move that dentry into place and return that dentry rather than the
|
||||
* passed one, typically using d_splice_alias.
|
||||
*/
|
||||
DCACHE_DISCONNECTED = BIT(5),
|
||||
DCACHE_REFERENCED = BIT(6), /* Recently used, don't discard. */
|
||||
DCACHE_DONTCACHE = BIT(7), /* Purge from memory on final dput() */
|
||||
DCACHE_CANT_MOUNT = BIT(8),
|
||||
DCACHE_GENOCIDE = BIT(9),
|
||||
DCACHE_SHRINK_LIST = BIT(10),
|
||||
DCACHE_OP_WEAK_REVALIDATE = BIT(11),
|
||||
/*
|
||||
* this dentry has been "silly renamed" and has to be deleted on the
|
||||
* last dput()
|
||||
*/
|
||||
DCACHE_NFSFS_RENAMED = BIT(12),
|
||||
DCACHE_FSNOTIFY_PARENT_WATCHED = BIT(13), /* Parent inode is watched by some fsnotify listener */
|
||||
DCACHE_DENTRY_KILLED = BIT(14),
|
||||
DCACHE_MOUNTED = BIT(15), /* is a mountpoint */
|
||||
DCACHE_NEED_AUTOMOUNT = BIT(16), /* handle automount on this dir */
|
||||
DCACHE_MANAGE_TRANSIT = BIT(17), /* manage transit from this dirent */
|
||||
DCACHE_LRU_LIST = BIT(18),
|
||||
DCACHE_ENTRY_TYPE = (7 << 19), /* bits 19..21 are for storing type: */
|
||||
DCACHE_MISS_TYPE = (0 << 19), /* Negative dentry */
|
||||
DCACHE_WHITEOUT_TYPE = (1 << 19), /* Whiteout dentry (stop pathwalk) */
|
||||
DCACHE_DIRECTORY_TYPE = (2 << 19), /* Normal directory */
|
||||
DCACHE_AUTODIR_TYPE = (3 << 19), /* Lookupless directory (presumed automount) */
|
||||
DCACHE_REGULAR_TYPE = (4 << 19), /* Regular file type */
|
||||
DCACHE_SPECIAL_TYPE = (5 << 19), /* Other file type */
|
||||
DCACHE_SYMLINK_TYPE = (6 << 19), /* Symlink */
|
||||
DCACHE_NOKEY_NAME = BIT(22), /* Encrypted name encoded without key */
|
||||
DCACHE_OP_REAL = BIT(23),
|
||||
DCACHE_PAR_LOOKUP = BIT(24), /* being looked up (with parent locked shared) */
|
||||
DCACHE_DENTRY_CURSOR = BIT(25),
|
||||
DCACHE_NORCU = BIT(26), /* No RCU delay for freeing */
|
||||
};
|
||||
|
||||
#define DCACHE_DISCONNECTED BIT(5)
|
||||
/* This dentry is possibly not currently connected to the dcache tree, in
|
||||
* which case its parent will either be itself, or will have this flag as
|
||||
* well. nfsd will not use a dentry with this bit set, but will first
|
||||
* endeavour to clear the bit either by discovering that it is connected,
|
||||
* or by performing lookup operations. Any filesystem which supports
|
||||
* nfsd_operations MUST have a lookup function which, if it finds a
|
||||
* directory inode with a DCACHE_DISCONNECTED dentry, will d_move that
|
||||
* dentry into place and return that dentry rather than the passed one,
|
||||
* typically using d_splice_alias. */
|
||||
|
||||
#define DCACHE_REFERENCED BIT(6) /* Recently used, don't discard. */
|
||||
|
||||
#define DCACHE_DONTCACHE BIT(7) /* Purge from memory on final dput() */
|
||||
|
||||
#define DCACHE_CANT_MOUNT BIT(8)
|
||||
#define DCACHE_GENOCIDE BIT(9)
|
||||
#define DCACHE_SHRINK_LIST BIT(10)
|
||||
|
||||
#define DCACHE_OP_WEAK_REVALIDATE BIT(11)
|
||||
|
||||
#define DCACHE_NFSFS_RENAMED BIT(12)
|
||||
/* this dentry has been "silly renamed" and has to be deleted on the last
|
||||
* dput() */
|
||||
#define DCACHE_FSNOTIFY_PARENT_WATCHED BIT(13)
|
||||
/* Parent inode is watched by some fsnotify listener */
|
||||
|
||||
#define DCACHE_DENTRY_KILLED BIT(14)
|
||||
|
||||
#define DCACHE_MOUNTED BIT(15) /* is a mountpoint */
|
||||
#define DCACHE_NEED_AUTOMOUNT BIT(16) /* handle automount on this dir */
|
||||
#define DCACHE_MANAGE_TRANSIT BIT(17) /* manage transit from this dirent */
|
||||
#define DCACHE_MANAGED_DENTRY \
|
||||
(DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT)
|
||||
|
||||
#define DCACHE_LRU_LIST BIT(18)
|
||||
|
||||
#define DCACHE_ENTRY_TYPE (7 << 19) /* bits 19..21 are for storing type: */
|
||||
#define DCACHE_MISS_TYPE (0 << 19) /* Negative dentry */
|
||||
#define DCACHE_WHITEOUT_TYPE (1 << 19) /* Whiteout dentry (stop pathwalk) */
|
||||
#define DCACHE_DIRECTORY_TYPE (2 << 19) /* Normal directory */
|
||||
#define DCACHE_AUTODIR_TYPE (3 << 19) /* Lookupless directory (presumed automount) */
|
||||
#define DCACHE_REGULAR_TYPE (4 << 19) /* Regular file type */
|
||||
#define DCACHE_SPECIAL_TYPE (5 << 19) /* Other file type */
|
||||
#define DCACHE_SYMLINK_TYPE (6 << 19) /* Symlink */
|
||||
|
||||
#define DCACHE_NOKEY_NAME BIT(22) /* Encrypted name encoded without key */
|
||||
#define DCACHE_OP_REAL BIT(23)
|
||||
|
||||
#define DCACHE_PAR_LOOKUP BIT(24) /* being looked up (with parent locked shared) */
|
||||
#define DCACHE_DENTRY_CURSOR BIT(25)
|
||||
#define DCACHE_NORCU BIT(26) /* No RCU delay for freeing */
|
||||
|
||||
extern seqlock_t rename_lock;
|
||||
|
||||
/*
|
||||
|
||||
@@ -4790,7 +4790,14 @@ void roce_del_all_netdev_gids(struct ib_device *ib_dev,
|
||||
|
||||
struct ib_ucontext *ib_uverbs_get_ucontext_file(struct ib_uverbs_file *ufile);
|
||||
|
||||
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
|
||||
int uverbs_destroy_def_handler(struct uverbs_attr_bundle *attrs);
|
||||
#else
|
||||
static inline int uverbs_destroy_def_handler(struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct net_device *rdma_alloc_netdev(struct ib_device *device, u32 port_num,
|
||||
enum rdma_netdev_t type, const char *name,
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
#include "amd.h"
|
||||
#include "../mach-config.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
#include "amd.h"
|
||||
#include "acp-mach.h"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "amd.h"
|
||||
#include "acp-mach.h"
|
||||
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
#define DRV_NAME "acp_asoc_acp70"
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/amd_node.h>
|
||||
#include <asm/amd/node.h>
|
||||
|
||||
#include "../ops.h"
|
||||
#include "acp.h"
|
||||
|
||||
@@ -43,9 +43,6 @@
|
||||
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
|
||||
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
|
||||
|
||||
#define KVM_REG_SIZE(id) \
|
||||
(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
|
||||
|
||||
struct kvm_regs {
|
||||
struct user_pt_regs regs; /* sp = sp_el0 */
|
||||
|
||||
@@ -108,6 +105,7 @@ struct kvm_regs {
|
||||
#define KVM_ARM_VCPU_PTRAUTH_ADDRESS 5 /* VCPU uses address authentication */
|
||||
#define KVM_ARM_VCPU_PTRAUTH_GENERIC 6 /* VCPU uses generic authentication */
|
||||
#define KVM_ARM_VCPU_HAS_EL2 7 /* Support nested virtualization */
|
||||
#define KVM_ARM_VCPU_HAS_EL2_E2H0 8 /* Limit NV support to E2H RES0 */
|
||||
|
||||
struct kvm_vcpu_init {
|
||||
__u32 target;
|
||||
@@ -418,6 +416,7 @@ enum {
|
||||
#define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
|
||||
#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
|
||||
#define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8
|
||||
#define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ 9
|
||||
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
|
||||
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
|
||||
(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
|
||||
|
||||
@@ -1,24 +1,2 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (C) 2012 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define __ARCH_WANT_RENAMEAT
|
||||
#define __ARCH_WANT_NEW_STAT
|
||||
#define __ARCH_WANT_SET_GET_RLIMIT
|
||||
#define __ARCH_WANT_TIME32_SYSCALLS
|
||||
#define __ARCH_WANT_MEMFD_SECRET
|
||||
|
||||
#include <asm-generic/unistd.h>
|
||||
#include <asm/unistd_64.h>
|
||||
|
||||
@@ -75,8 +75,8 @@
|
||||
#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* "centaur_mcr" Centaur MCRs (= MTRRs) */
|
||||
#define X86_FEATURE_K8 ( 3*32+ 4) /* Opteron, Athlon64 */
|
||||
#define X86_FEATURE_ZEN5 ( 3*32+ 5) /* CPU based on Zen5 microarchitecture */
|
||||
#define X86_FEATURE_P3 ( 3*32+ 6) /* P3 */
|
||||
#define X86_FEATURE_P4 ( 3*32+ 7) /* P4 */
|
||||
/* Free ( 3*32+ 6) */
|
||||
/* Free ( 3*32+ 7) */
|
||||
#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* "constant_tsc" TSC ticks at a constant rate */
|
||||
#define X86_FEATURE_UP ( 3*32+ 9) /* "up" SMP kernel running on UP */
|
||||
#define X86_FEATURE_ART ( 3*32+10) /* "art" Always running timer (ART) */
|
||||
@@ -329,6 +329,7 @@
|
||||
#define X86_FEATURE_CLZERO (13*32+ 0) /* "clzero" CLZERO instruction */
|
||||
#define X86_FEATURE_IRPERF (13*32+ 1) /* "irperf" Instructions Retired Count */
|
||||
#define X86_FEATURE_XSAVEERPTR (13*32+ 2) /* "xsaveerptr" Always save/restore FP error pointers */
|
||||
#define X86_FEATURE_INVLPGB (13*32+ 3) /* INVLPGB and TLBSYNC instructions supported */
|
||||
#define X86_FEATURE_RDPRU (13*32+ 4) /* "rdpru" Read processor register at user level */
|
||||
#define X86_FEATURE_WBNOINVD (13*32+ 9) /* "wbnoinvd" WBNOINVD instruction */
|
||||
#define X86_FEATURE_AMD_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */
|
||||
@@ -377,6 +378,7 @@
|
||||
#define X86_FEATURE_V_SPEC_CTRL (15*32+20) /* "v_spec_ctrl" Virtual SPEC_CTRL */
|
||||
#define X86_FEATURE_VNMI (15*32+25) /* "vnmi" Virtual NMI */
|
||||
#define X86_FEATURE_SVME_ADDR_CHK (15*32+28) /* SVME addr check */
|
||||
#define X86_FEATURE_IDLE_HLT (15*32+30) /* IDLE HLT intercept */
|
||||
|
||||
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ECX), word 16 */
|
||||
#define X86_FEATURE_AVX512VBMI (16*32+ 1) /* "avx512vbmi" AVX512 Vector Bit Manipulation instructions*/
|
||||
@@ -434,15 +436,18 @@
|
||||
#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* Speculative Store Bypass Disable */
|
||||
|
||||
/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */
|
||||
#define X86_FEATURE_SME (19*32+ 0) /* "sme" AMD Secure Memory Encryption */
|
||||
#define X86_FEATURE_SEV (19*32+ 1) /* "sev" AMD Secure Encrypted Virtualization */
|
||||
#define X86_FEATURE_SME (19*32+ 0) /* "sme" Secure Memory Encryption */
|
||||
#define X86_FEATURE_SEV (19*32+ 1) /* "sev" Secure Encrypted Virtualization */
|
||||
#define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* VM Page Flush MSR is supported */
|
||||
#define X86_FEATURE_SEV_ES (19*32+ 3) /* "sev_es" AMD Secure Encrypted Virtualization - Encrypted State */
|
||||
#define X86_FEATURE_SEV_SNP (19*32+ 4) /* "sev_snp" AMD Secure Encrypted Virtualization - Secure Nested Paging */
|
||||
#define X86_FEATURE_SEV_ES (19*32+ 3) /* "sev_es" Secure Encrypted Virtualization - Encrypted State */
|
||||
#define X86_FEATURE_SEV_SNP (19*32+ 4) /* "sev_snp" Secure Encrypted Virtualization - Secure Nested Paging */
|
||||
#define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* Virtual TSC_AUX */
|
||||
#define X86_FEATURE_SME_COHERENT (19*32+10) /* AMD hardware-enforced cache coherency */
|
||||
#define X86_FEATURE_DEBUG_SWAP (19*32+14) /* "debug_swap" AMD SEV-ES full debug state swap support */
|
||||
#define X86_FEATURE_SME_COHERENT (19*32+10) /* hardware-enforced cache coherency */
|
||||
#define X86_FEATURE_DEBUG_SWAP (19*32+14) /* "debug_swap" SEV-ES full debug state swap support */
|
||||
#define X86_FEATURE_RMPREAD (19*32+21) /* RMPREAD instruction */
|
||||
#define X86_FEATURE_SEGMENTED_RMP (19*32+23) /* Segmented RMP support */
|
||||
#define X86_FEATURE_SVSM (19*32+28) /* "svsm" SVSM present */
|
||||
#define X86_FEATURE_HV_INUSE_WR_ALLOWED (19*32+30) /* Allow Write to in-use hypervisor-owned pages */
|
||||
|
||||
/* AMD-defined Extended Feature 2 EAX, CPUID level 0x80000021 (EAX), word 20 */
|
||||
#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */
|
||||
@@ -455,6 +460,11 @@
|
||||
#define X86_FEATURE_SBPB (20*32+27) /* Selective Branch Prediction Barrier */
|
||||
#define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* MSR_PRED_CMD[IBPB] flushes all branch type predictions */
|
||||
#define X86_FEATURE_SRSO_NO (20*32+29) /* CPU is not affected by SRSO */
|
||||
#define X86_FEATURE_SRSO_USER_KERNEL_NO (20*32+30) /* CPU is not affected by SRSO across user/kernel boundaries */
|
||||
#define X86_FEATURE_SRSO_BP_SPEC_REDUCE (20*32+31) /*
|
||||
* BP_CFG[BpSpecReduce] can be used to mitigate SRSO for VMs.
|
||||
* (SRSO_MSR_FIX in the official doc).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extended auxiliary flags: Linux defined - for features scattered in various
|
||||
@@ -466,10 +476,11 @@
|
||||
#define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* Clear branch history at syscall entry using SW loop */
|
||||
#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* BHI_DIS_S HW control available */
|
||||
#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* BHI_DIS_S HW control enabled */
|
||||
#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
|
||||
#define X86_FEATURE_AMD_FAST_CPPC (21*32 + 5) /* Fast CPPC */
|
||||
#define X86_FEATURE_AMD_HETEROGENEOUS_CORES (21*32 + 6) /* Heterogeneous Core Topology */
|
||||
#define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32 + 7) /* Workload Classification */
|
||||
#define X86_FEATURE_CLEAR_BHB_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
|
||||
#define X86_FEATURE_AMD_FAST_CPPC (21*32+ 5) /* Fast CPPC */
|
||||
#define X86_FEATURE_AMD_HTR_CORES (21*32+ 6) /* Heterogeneous Core Topology */
|
||||
#define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32+ 7) /* Workload Classification */
|
||||
#define X86_FEATURE_PREFER_YMM (21*32+ 8) /* Avoid ZMM registers due to downclocking */
|
||||
|
||||
/*
|
||||
* BUG word(s)
|
||||
@@ -508,7 +519,7 @@
|
||||
#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* "itlb_multihit" CPU may incur MCE during certain page attribute changes */
|
||||
#define X86_BUG_SRBDS X86_BUG(24) /* "srbds" CPU may leak RNG bits if not mitigated */
|
||||
#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* "mmio_stale_data" CPU is affected by Processor MMIO Stale Data vulnerabilities */
|
||||
#define X86_BUG_MMIO_UNKNOWN X86_BUG(26) /* "mmio_unknown" CPU is too old and its MMIO Stale Data status is unknown */
|
||||
/* unused, was #define X86_BUG_MMIO_UNKNOWN X86_BUG(26) "mmio_unknown" CPU is too old and its MMIO Stale Data status is unknown */
|
||||
#define X86_BUG_RETBLEED X86_BUG(27) /* "retbleed" CPU is affected by RETBleed */
|
||||
#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* "eibrs_pbrsb" EIBRS is vulnerable to Post Barrier RSB Predictions */
|
||||
#define X86_BUG_SMT_RSB X86_BUG(29) /* "smt_rsb" CPU is vulnerable to Cross-Thread Return Address Predictions */
|
||||
@@ -516,9 +527,10 @@
|
||||
#define X86_BUG_TDX_PW_MCE X86_BUG(31) /* "tdx_pw_mce" CPU may incur #MC if non-TD software does partial write to TDX private memory */
|
||||
|
||||
/* BUG word 2 */
|
||||
#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* "srso" AMD SRSO bug */
|
||||
#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */
|
||||
#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
|
||||
#define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
|
||||
#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
|
||||
#define X86_BUG_SRSO X86_BUG( 1*32+ 0) /* "srso" AMD SRSO bug */
|
||||
#define X86_BUG_DIV0 X86_BUG( 1*32+ 1) /* "div0" AMD DIV0 speculation bug */
|
||||
#define X86_BUG_RFDS X86_BUG( 1*32+ 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
|
||||
#define X86_BUG_BHI X86_BUG( 1*32+ 3) /* "bhi" CPU is affected by Branch History Injection */
|
||||
#define X86_BUG_IBPB_NO_RET X86_BUG( 1*32+ 4) /* "ibpb_no_ret" IBPB omits return target predictions */
|
||||
#define X86_BUG_SPECTRE_V2_USER X86_BUG( 1*32+ 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */
|
||||
#endif /* _ASM_X86_CPUFEATURES_H */
|
||||
|
||||
@@ -397,7 +397,8 @@
|
||||
#define MSR_IA32_PASID_VALID BIT_ULL(31)
|
||||
|
||||
/* DEBUGCTLMSR bits (others vary by model): */
|
||||
#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */
|
||||
#define DEBUGCTLMSR_LBR_BIT 0 /* last branch recording */
|
||||
#define DEBUGCTLMSR_LBR (1UL << DEBUGCTLMSR_LBR_BIT)
|
||||
#define DEBUGCTLMSR_BTF_SHIFT 1
|
||||
#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */
|
||||
#define DEBUGCTLMSR_BUS_LOCK_DETECT (1UL << 2)
|
||||
@@ -610,6 +611,7 @@
|
||||
#define MSR_AMD_PERF_CTL 0xc0010062
|
||||
#define MSR_AMD_PERF_STATUS 0xc0010063
|
||||
#define MSR_AMD_PSTATE_DEF_BASE 0xc0010064
|
||||
#define MSR_AMD64_GUEST_TSC_FREQ 0xc0010134
|
||||
#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
|
||||
#define MSR_AMD64_OSVW_STATUS 0xc0010141
|
||||
#define MSR_AMD_PPIN_CTL 0xc00102f0
|
||||
@@ -646,6 +648,7 @@
|
||||
#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
|
||||
#define MSR_AMD64_SVM_AVIC_DOORBELL 0xc001011b
|
||||
#define MSR_AMD64_VM_PAGE_FLUSH 0xc001011e
|
||||
#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f
|
||||
#define MSR_AMD64_SEV_ES_GHCB 0xc0010130
|
||||
#define MSR_AMD64_SEV 0xc0010131
|
||||
#define MSR_AMD64_SEV_ENABLED_BIT 0
|
||||
@@ -684,11 +687,12 @@
|
||||
#define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
|
||||
#define MSR_AMD64_SNP_RESV_BIT 18
|
||||
#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
|
||||
|
||||
#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f
|
||||
|
||||
#define MSR_AMD64_RMP_BASE 0xc0010132
|
||||
#define MSR_AMD64_RMP_END 0xc0010133
|
||||
#define MSR_AMD64_RMP_CFG 0xc0010136
|
||||
#define MSR_AMD64_SEG_RMP_ENABLED_BIT 0
|
||||
#define MSR_AMD64_SEG_RMP_ENABLED BIT_ULL(MSR_AMD64_SEG_RMP_ENABLED_BIT)
|
||||
#define MSR_AMD64_RMP_SEGMENT_SHIFT(x) (((x) & GENMASK_ULL(13, 8)) >> 8)
|
||||
|
||||
#define MSR_SVSM_CAA 0xc001f000
|
||||
|
||||
@@ -699,15 +703,17 @@
|
||||
#define MSR_AMD_CPPC_REQ 0xc00102b3
|
||||
#define MSR_AMD_CPPC_STATUS 0xc00102b4
|
||||
|
||||
#define AMD_CPPC_LOWEST_PERF(x) (((x) >> 0) & 0xff)
|
||||
#define AMD_CPPC_LOWNONLIN_PERF(x) (((x) >> 8) & 0xff)
|
||||
#define AMD_CPPC_NOMINAL_PERF(x) (((x) >> 16) & 0xff)
|
||||
#define AMD_CPPC_HIGHEST_PERF(x) (((x) >> 24) & 0xff)
|
||||
/* Masks for use with MSR_AMD_CPPC_CAP1 */
|
||||
#define AMD_CPPC_LOWEST_PERF_MASK GENMASK(7, 0)
|
||||
#define AMD_CPPC_LOWNONLIN_PERF_MASK GENMASK(15, 8)
|
||||
#define AMD_CPPC_NOMINAL_PERF_MASK GENMASK(23, 16)
|
||||
#define AMD_CPPC_HIGHEST_PERF_MASK GENMASK(31, 24)
|
||||
|
||||
#define AMD_CPPC_MAX_PERF(x) (((x) & 0xff) << 0)
|
||||
#define AMD_CPPC_MIN_PERF(x) (((x) & 0xff) << 8)
|
||||
#define AMD_CPPC_DES_PERF(x) (((x) & 0xff) << 16)
|
||||
#define AMD_CPPC_ENERGY_PERF_PREF(x) (((x) & 0xff) << 24)
|
||||
/* Masks for use with MSR_AMD_CPPC_REQ */
|
||||
#define AMD_CPPC_MAX_PERF_MASK GENMASK(7, 0)
|
||||
#define AMD_CPPC_MIN_PERF_MASK GENMASK(15, 8)
|
||||
#define AMD_CPPC_DES_PERF_MASK GENMASK(23, 16)
|
||||
#define AMD_CPPC_EPP_PERF_MASK GENMASK(31, 24)
|
||||
|
||||
/* AMD Performance Counter Global Status and Control MSRs */
|
||||
#define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS 0xc0000300
|
||||
@@ -719,6 +725,7 @@
|
||||
|
||||
/* Zen4 */
|
||||
#define MSR_ZEN4_BP_CFG 0xc001102e
|
||||
#define MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT 4
|
||||
#define MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT 5
|
||||
|
||||
/* Fam 19h MSRs */
|
||||
|
||||
@@ -559,6 +559,9 @@ struct kvm_x86_mce {
|
||||
#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
|
||||
#define KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA (1 << 8)
|
||||
|
||||
#define KVM_XEN_MSR_MIN_INDEX 0x40000000u
|
||||
#define KVM_XEN_MSR_MAX_INDEX 0x4fffffffu
|
||||
|
||||
struct kvm_xen_hvm_config {
|
||||
__u32 flags;
|
||||
__u32 msr;
|
||||
@@ -925,5 +928,6 @@ struct kvm_hyperv_eventfd {
|
||||
#define KVM_X86_SEV_VM 2
|
||||
#define KVM_X86_SEV_ES_VM 3
|
||||
#define KVM_X86_SNP_VM 4
|
||||
#define KVM_X86_TDX_VM 5
|
||||
|
||||
#endif /* _ASM_X86_KVM_H */
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
#define SVM_EXIT_CR14_WRITE_TRAP 0x09e
|
||||
#define SVM_EXIT_CR15_WRITE_TRAP 0x09f
|
||||
#define SVM_EXIT_INVPCID 0x0a2
|
||||
#define SVM_EXIT_IDLE_HLT 0x0a6
|
||||
#define SVM_EXIT_NPF 0x400
|
||||
#define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401
|
||||
#define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402
|
||||
@@ -224,6 +225,7 @@
|
||||
{ SVM_EXIT_CR4_WRITE_TRAP, "write_cr4_trap" }, \
|
||||
{ SVM_EXIT_CR8_WRITE_TRAP, "write_cr8_trap" }, \
|
||||
{ SVM_EXIT_INVPCID, "invpcid" }, \
|
||||
{ SVM_EXIT_IDLE_HLT, "idle-halt" }, \
|
||||
{ SVM_EXIT_NPF, "npf" }, \
|
||||
{ SVM_EXIT_AVIC_INCOMPLETE_IPI, "avic_incomplete_ipi" }, \
|
||||
{ SVM_EXIT_AVIC_UNACCELERATED_ACCESS, "avic_unaccelerated_access" }, \
|
||||
|
||||
+455
-336
File diff suppressed because it is too large
Load Diff
+180
-195
@@ -1,14 +1,17 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cpuid.h>
|
||||
#include <err.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define __noreturn __attribute__((__noreturn__))
|
||||
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
@@ -49,7 +52,7 @@ static const char * const reg_names[] = {
|
||||
struct subleaf {
|
||||
u32 index;
|
||||
u32 sub;
|
||||
u32 eax, ebx, ecx, edx;
|
||||
u32 output[NR_REGS];
|
||||
struct reg_desc info[NR_REGS];
|
||||
};
|
||||
|
||||
@@ -63,21 +66,64 @@ struct cpuid_func {
|
||||
int nr;
|
||||
};
|
||||
|
||||
enum range_index {
|
||||
RANGE_STD = 0, /* Standard */
|
||||
RANGE_EXT = 0x80000000, /* Extended */
|
||||
RANGE_TSM = 0x80860000, /* Transmeta */
|
||||
RANGE_CTR = 0xc0000000, /* Centaur/Zhaoxin */
|
||||
};
|
||||
|
||||
#define CPUID_INDEX_MASK 0xffff0000
|
||||
#define CPUID_FUNCTION_MASK (~CPUID_INDEX_MASK)
|
||||
|
||||
struct cpuid_range {
|
||||
/* array of main leafs */
|
||||
struct cpuid_func *funcs;
|
||||
/* number of valid leafs */
|
||||
int nr;
|
||||
bool is_ext;
|
||||
enum range_index index;
|
||||
};
|
||||
|
||||
/*
|
||||
* basic: basic functions range: [0... ]
|
||||
* ext: extended functions range: [0x80000000... ]
|
||||
*/
|
||||
struct cpuid_range *leafs_basic, *leafs_ext;
|
||||
static struct cpuid_range ranges[] = {
|
||||
{ .index = RANGE_STD, },
|
||||
{ .index = RANGE_EXT, },
|
||||
{ .index = RANGE_TSM, },
|
||||
{ .index = RANGE_CTR, },
|
||||
};
|
||||
|
||||
static char *range_to_str(struct cpuid_range *range)
|
||||
{
|
||||
switch (range->index) {
|
||||
case RANGE_STD: return "Standard";
|
||||
case RANGE_EXT: return "Extended";
|
||||
case RANGE_TSM: return "Transmeta";
|
||||
case RANGE_CTR: return "Centaur";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define __for_each_cpuid_range(range, __condition) \
|
||||
for (unsigned int i = 0; \
|
||||
i < ARRAY_SIZE(ranges) && ((range) = &ranges[i]) && (__condition); \
|
||||
i++)
|
||||
|
||||
#define for_each_valid_cpuid_range(range) __for_each_cpuid_range(range, (range)->nr != 0)
|
||||
#define for_each_cpuid_range(range) __for_each_cpuid_range(range, true)
|
||||
|
||||
struct cpuid_range *index_to_cpuid_range(u32 index)
|
||||
{
|
||||
u32 func_idx = index & CPUID_FUNCTION_MASK;
|
||||
u32 range_idx = index & CPUID_INDEX_MASK;
|
||||
struct cpuid_range *range;
|
||||
|
||||
for_each_valid_cpuid_range(range) {
|
||||
if (range->index == range_idx && (u32)range->nr > func_idx)
|
||||
return range;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool is_amd;
|
||||
static bool show_details;
|
||||
static bool show_raw;
|
||||
static bool show_flags_only = true;
|
||||
@@ -85,16 +131,16 @@ static u32 user_index = 0xFFFFFFFF;
|
||||
static u32 user_sub = 0xFFFFFFFF;
|
||||
static int flines;
|
||||
|
||||
static inline void cpuid(u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
|
||||
{
|
||||
/* ecx is often an input as well as an output. */
|
||||
asm volatile("cpuid"
|
||||
: "=a" (*eax),
|
||||
"=b" (*ebx),
|
||||
"=c" (*ecx),
|
||||
"=d" (*edx)
|
||||
: "0" (*eax), "2" (*ecx));
|
||||
}
|
||||
/*
|
||||
* Force using <cpuid.h> __cpuid_count() instead of __cpuid(). The
|
||||
* latter leaves ECX uninitialized, which can break CPUID queries.
|
||||
*/
|
||||
|
||||
#define cpuid(leaf, a, b, c, d) \
|
||||
__cpuid_count(leaf, 0, a, b, c, d)
|
||||
|
||||
#define cpuid_count(leaf, subleaf, a, b, c, d) \
|
||||
__cpuid_count(leaf, subleaf, a, b, c, d)
|
||||
|
||||
static inline bool has_subleafs(u32 f)
|
||||
{
|
||||
@@ -117,11 +163,11 @@ static void leaf_print_raw(struct subleaf *leaf)
|
||||
if (leaf->sub == 0)
|
||||
printf("0x%08x: subleafs:\n", leaf->index);
|
||||
|
||||
printf(" %2d: EAX=0x%08x, EBX=0x%08x, ECX=0x%08x, EDX=0x%08x\n",
|
||||
leaf->sub, leaf->eax, leaf->ebx, leaf->ecx, leaf->edx);
|
||||
printf(" %2d: EAX=0x%08x, EBX=0x%08x, ECX=0x%08x, EDX=0x%08x\n", leaf->sub,
|
||||
leaf->output[0], leaf->output[1], leaf->output[2], leaf->output[3]);
|
||||
} else {
|
||||
printf("0x%08x: EAX=0x%08x, EBX=0x%08x, ECX=0x%08x, EDX=0x%08x\n",
|
||||
leaf->index, leaf->eax, leaf->ebx, leaf->ecx, leaf->edx);
|
||||
printf("0x%08x: EAX=0x%08x, EBX=0x%08x, ECX=0x%08x, EDX=0x%08x\n", leaf->index,
|
||||
leaf->output[0], leaf->output[1], leaf->output[2], leaf->output[3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,19 +186,19 @@ static bool cpuid_store(struct cpuid_range *range, u32 f, int subleaf,
|
||||
* Cut off vendor-prefix from CPUID function as we're using it as an
|
||||
* index into ->funcs.
|
||||
*/
|
||||
func = &range->funcs[f & 0xffff];
|
||||
func = &range->funcs[f & CPUID_FUNCTION_MASK];
|
||||
|
||||
if (!func->leafs) {
|
||||
func->leafs = malloc(sizeof(struct subleaf));
|
||||
if (!func->leafs)
|
||||
perror("malloc func leaf");
|
||||
err(EXIT_FAILURE, NULL);
|
||||
|
||||
func->nr = 1;
|
||||
} else {
|
||||
s = func->nr;
|
||||
func->leafs = realloc(func->leafs, (s + 1) * sizeof(*leaf));
|
||||
if (!func->leafs)
|
||||
perror("realloc f->leafs");
|
||||
err(EXIT_FAILURE, NULL);
|
||||
|
||||
func->nr++;
|
||||
}
|
||||
@@ -161,84 +207,73 @@ static bool cpuid_store(struct cpuid_range *range, u32 f, int subleaf,
|
||||
|
||||
leaf->index = f;
|
||||
leaf->sub = subleaf;
|
||||
leaf->eax = a;
|
||||
leaf->ebx = b;
|
||||
leaf->ecx = c;
|
||||
leaf->edx = d;
|
||||
leaf->output[R_EAX] = a;
|
||||
leaf->output[R_EBX] = b;
|
||||
leaf->output[R_ECX] = c;
|
||||
leaf->output[R_EDX] = d;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void raw_dump_range(struct cpuid_range *range)
|
||||
{
|
||||
u32 f;
|
||||
int i;
|
||||
|
||||
printf("%s Leafs :\n", range->is_ext ? "Extended" : "Basic");
|
||||
printf("%s Leafs :\n", range_to_str(range));
|
||||
printf("================\n");
|
||||
|
||||
for (f = 0; (int)f < range->nr; f++) {
|
||||
for (u32 f = 0; (int)f < range->nr; f++) {
|
||||
struct cpuid_func *func = &range->funcs[f];
|
||||
u32 index = f;
|
||||
|
||||
if (range->is_ext)
|
||||
index += 0x80000000;
|
||||
|
||||
/* Skip leaf without valid items */
|
||||
if (!func->nr)
|
||||
continue;
|
||||
|
||||
/* First item is the main leaf, followed by all subleafs */
|
||||
for (i = 0; i < func->nr; i++)
|
||||
for (int i = 0; i < func->nr; i++)
|
||||
leaf_print_raw(&func->leafs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_SUBLEAF_NUM 64
|
||||
struct cpuid_range *setup_cpuid_range(u32 input_eax)
|
||||
#define MAX_RANGE_INDEX_OFFSET 0xff
|
||||
void setup_cpuid_range(struct cpuid_range *range)
|
||||
{
|
||||
u32 max_func, idx_func, subleaf, max_subleaf;
|
||||
u32 eax, ebx, ecx, edx, f = input_eax;
|
||||
struct cpuid_range *range;
|
||||
bool allzero;
|
||||
u32 max_func, range_funcs_sz;
|
||||
u32 eax, ebx, ecx, edx;
|
||||
|
||||
eax = input_eax;
|
||||
ebx = ecx = edx = 0;
|
||||
cpuid(range->index, max_func, ebx, ecx, edx);
|
||||
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
max_func = eax;
|
||||
idx_func = (max_func & 0xffff) + 1;
|
||||
/*
|
||||
* If the CPUID range's maximum function value is garbage, then it
|
||||
* is not recognized by this CPU. Set the range's number of valid
|
||||
* leaves to zero so that for_each_valid_cpu_range() can ignore it.
|
||||
*/
|
||||
if (max_func < range->index || max_func > (range->index + MAX_RANGE_INDEX_OFFSET)) {
|
||||
range->nr = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
range = malloc(sizeof(struct cpuid_range));
|
||||
if (!range)
|
||||
perror("malloc range");
|
||||
range->nr = (max_func & CPUID_FUNCTION_MASK) + 1;
|
||||
range_funcs_sz = range->nr * sizeof(struct cpuid_func);
|
||||
|
||||
if (input_eax & 0x80000000)
|
||||
range->is_ext = true;
|
||||
else
|
||||
range->is_ext = false;
|
||||
|
||||
range->funcs = malloc(sizeof(struct cpuid_func) * idx_func);
|
||||
range->funcs = malloc(range_funcs_sz);
|
||||
if (!range->funcs)
|
||||
perror("malloc range->funcs");
|
||||
err(EXIT_FAILURE, NULL);
|
||||
|
||||
range->nr = idx_func;
|
||||
memset(range->funcs, 0, sizeof(struct cpuid_func) * idx_func);
|
||||
memset(range->funcs, 0, range_funcs_sz);
|
||||
|
||||
for (; f <= max_func; f++) {
|
||||
eax = f;
|
||||
subleaf = ecx = 0;
|
||||
for (u32 f = range->index; f <= max_func; f++) {
|
||||
u32 max_subleaf = MAX_SUBLEAF_NUM;
|
||||
bool allzero;
|
||||
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
allzero = cpuid_store(range, f, subleaf, eax, ebx, ecx, edx);
|
||||
cpuid(f, eax, ebx, ecx, edx);
|
||||
|
||||
allzero = cpuid_store(range, f, 0, eax, ebx, ecx, edx);
|
||||
if (allzero)
|
||||
continue;
|
||||
|
||||
if (!has_subleafs(f))
|
||||
continue;
|
||||
|
||||
max_subleaf = MAX_SUBLEAF_NUM;
|
||||
|
||||
/*
|
||||
* Some can provide the exact number of subleafs,
|
||||
* others have to be tried (0xf)
|
||||
@@ -256,20 +291,15 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
|
||||
if (f == 0x80000026)
|
||||
max_subleaf = 5;
|
||||
|
||||
for (subleaf = 1; subleaf < max_subleaf; subleaf++) {
|
||||
eax = f;
|
||||
ecx = subleaf;
|
||||
for (u32 subleaf = 1; subleaf < max_subleaf; subleaf++) {
|
||||
cpuid_count(f, subleaf, eax, ebx, ecx, edx);
|
||||
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
allzero = cpuid_store(range, f, subleaf,
|
||||
eax, ebx, ecx, edx);
|
||||
allzero = cpuid_store(range, f, subleaf, eax, ebx, ecx, edx);
|
||||
if (allzero)
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -280,15 +310,13 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
|
||||
* 0, 0, EAX, 31:0, max_basic_leafs, Max input value for supported subleafs
|
||||
* 1, 0, ECX, 0, sse3, Streaming SIMD Extensions 3(SSE3)
|
||||
*/
|
||||
static int parse_line(char *line)
|
||||
static void parse_line(char *line)
|
||||
{
|
||||
char *str;
|
||||
int i;
|
||||
struct cpuid_range *range;
|
||||
struct cpuid_func *func;
|
||||
struct subleaf *leaf;
|
||||
u32 index;
|
||||
u32 sub;
|
||||
char buffer[512];
|
||||
char *buf;
|
||||
/*
|
||||
@@ -310,12 +338,12 @@ static int parse_line(char *line)
|
||||
|
||||
/* Skip comments and NULL line */
|
||||
if (line[0] == '#' || line[0] == '\n')
|
||||
return 0;
|
||||
return;
|
||||
|
||||
strncpy(buffer, line, 511);
|
||||
buffer[511] = 0;
|
||||
str = buffer;
|
||||
for (i = 0; i < 5; i++) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
tokens[i] = strtok(str, ",");
|
||||
if (!tokens[i])
|
||||
goto err_exit;
|
||||
@@ -328,21 +356,19 @@ static int parse_line(char *line)
|
||||
/* index/main-leaf */
|
||||
index = strtoull(tokens[0], NULL, 0);
|
||||
|
||||
if (index & 0x80000000)
|
||||
range = leafs_ext;
|
||||
else
|
||||
range = leafs_basic;
|
||||
|
||||
index &= 0x7FFFFFFF;
|
||||
/* Skip line parsing for non-existing indexes */
|
||||
if ((int)index >= range->nr)
|
||||
return -1;
|
||||
/*
|
||||
* Skip line parsing if the index is not covered by known-valid
|
||||
* CPUID ranges on this CPU.
|
||||
*/
|
||||
range = index_to_cpuid_range(index);
|
||||
if (!range)
|
||||
return;
|
||||
|
||||
/* Skip line parsing if the index CPUID output is all zero */
|
||||
index &= CPUID_FUNCTION_MASK;
|
||||
func = &range->funcs[index];
|
||||
|
||||
/* Return if the index has no valid item on this platform */
|
||||
if (!func->nr)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
/* subleaf */
|
||||
buf = tokens[1];
|
||||
@@ -355,11 +381,11 @@ static int parse_line(char *line)
|
||||
subleaf_start = strtoul(start, NULL, 0);
|
||||
subleaf_end = min(subleaf_end, (u32)(func->nr - 1));
|
||||
if (subleaf_start > subleaf_end)
|
||||
return 0;
|
||||
return;
|
||||
} else {
|
||||
subleaf_start = subleaf_end;
|
||||
if (subleaf_start > (u32)(func->nr - 1))
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* register */
|
||||
@@ -382,7 +408,7 @@ static int parse_line(char *line)
|
||||
bit_end = strtoul(end, NULL, 0);
|
||||
bit_start = (start) ? strtoul(start, NULL, 0) : bit_end;
|
||||
|
||||
for (sub = subleaf_start; sub <= subleaf_end; sub++) {
|
||||
for (u32 sub = subleaf_start; sub <= subleaf_end; sub++) {
|
||||
leaf = &func->leafs[sub];
|
||||
reg = &leaf->info[reg_index];
|
||||
bdesc = ®->descs[reg->nr++];
|
||||
@@ -392,12 +418,11 @@ static int parse_line(char *line)
|
||||
strcpy(bdesc->simp, strtok(tokens[4], " \t"));
|
||||
strcpy(bdesc->detail, tokens[5]);
|
||||
}
|
||||
return 0;
|
||||
return;
|
||||
|
||||
err_exit:
|
||||
printf("Warning: wrong line format:\n");
|
||||
printf("\tline[%d]: %s\n", flines, line);
|
||||
return -1;
|
||||
warnx("Wrong line format:\n"
|
||||
"\tline[%d]: %s", flines, line);
|
||||
}
|
||||
|
||||
/* Parse csv file, and construct the array of all leafs and subleafs */
|
||||
@@ -418,10 +443,8 @@ static void parse_text(void)
|
||||
file = fopen("./cpuid.csv", "r");
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
printf("Fail to open '%s'\n", filename);
|
||||
return;
|
||||
}
|
||||
if (!file)
|
||||
err(EXIT_FAILURE, "%s", filename);
|
||||
|
||||
while (1) {
|
||||
ret = getline(&line, &len, file);
|
||||
@@ -436,21 +459,13 @@ static void parse_text(void)
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
|
||||
/* Decode every eax/ebx/ecx/edx */
|
||||
static void decode_bits(u32 value, struct reg_desc *rdesc, enum cpuid_reg reg)
|
||||
static void show_reg(const struct reg_desc *rdesc, u32 value)
|
||||
{
|
||||
struct bits_desc *bdesc;
|
||||
int start, end, i;
|
||||
const struct bits_desc *bdesc;
|
||||
int start, end;
|
||||
u32 mask;
|
||||
|
||||
if (!rdesc->nr) {
|
||||
if (show_details)
|
||||
printf("\t %s: 0x%08x\n", reg_names[reg], value);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < rdesc->nr; i++) {
|
||||
for (int i = 0; i < rdesc->nr; i++) {
|
||||
bdesc = &rdesc->descs[i];
|
||||
|
||||
start = bdesc->start;
|
||||
@@ -480,23 +495,21 @@ static void decode_bits(u32 value, struct reg_desc *rdesc, enum cpuid_reg reg)
|
||||
}
|
||||
}
|
||||
|
||||
static void show_reg_header(bool has_entries, u32 leaf, u32 subleaf, const char *reg_name)
|
||||
{
|
||||
if (show_details && has_entries)
|
||||
printf("CPUID_0x%x_%s[0x%x]:\n", leaf, reg_name, subleaf);
|
||||
}
|
||||
|
||||
static void show_leaf(struct subleaf *leaf)
|
||||
{
|
||||
if (!leaf)
|
||||
return;
|
||||
|
||||
if (show_raw) {
|
||||
if (show_raw)
|
||||
leaf_print_raw(leaf);
|
||||
} else {
|
||||
if (show_details)
|
||||
printf("CPUID_0x%x_ECX[0x%x]:\n",
|
||||
leaf->index, leaf->sub);
|
||||
}
|
||||
|
||||
decode_bits(leaf->eax, &leaf->info[R_EAX], R_EAX);
|
||||
decode_bits(leaf->ebx, &leaf->info[R_EBX], R_EBX);
|
||||
decode_bits(leaf->ecx, &leaf->info[R_ECX], R_ECX);
|
||||
decode_bits(leaf->edx, &leaf->info[R_EDX], R_EDX);
|
||||
for (int i = R_EAX; i < NR_REGS; i++) {
|
||||
show_reg_header((leaf->info[i].nr > 0), leaf->index, leaf->sub, reg_names[i]);
|
||||
show_reg(&leaf->info[i], leaf->output[i]);
|
||||
}
|
||||
|
||||
if (!show_raw && show_details)
|
||||
printf("\n");
|
||||
@@ -504,46 +517,37 @@ static void show_leaf(struct subleaf *leaf)
|
||||
|
||||
static void show_func(struct cpuid_func *func)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!func)
|
||||
return;
|
||||
|
||||
for (i = 0; i < func->nr; i++)
|
||||
for (int i = 0; i < func->nr; i++)
|
||||
show_leaf(&func->leafs[i]);
|
||||
}
|
||||
|
||||
static void show_range(struct cpuid_range *range)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < range->nr; i++)
|
||||
for (int i = 0; i < range->nr; i++)
|
||||
show_func(&range->funcs[i]);
|
||||
}
|
||||
|
||||
static inline struct cpuid_func *index_to_func(u32 index)
|
||||
{
|
||||
u32 func_idx = index & CPUID_FUNCTION_MASK;
|
||||
struct cpuid_range *range;
|
||||
u32 func_idx;
|
||||
|
||||
range = (index & 0x80000000) ? leafs_ext : leafs_basic;
|
||||
func_idx = index & 0xffff;
|
||||
|
||||
if ((func_idx + 1) > (u32)range->nr) {
|
||||
printf("ERR: invalid input index (0x%x)\n", index);
|
||||
range = index_to_cpuid_range(index);
|
||||
if (!range)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &range->funcs[func_idx];
|
||||
}
|
||||
|
||||
static void show_info(void)
|
||||
{
|
||||
struct cpuid_range *range;
|
||||
struct cpuid_func *func;
|
||||
|
||||
if (show_raw) {
|
||||
/* Show all of the raw output of 'cpuid' instr */
|
||||
raw_dump_range(leafs_basic);
|
||||
raw_dump_range(leafs_ext);
|
||||
for_each_valid_cpuid_range(range)
|
||||
raw_dump_range(range);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -551,18 +555,19 @@ static void show_info(void)
|
||||
/* Only show specific leaf/subleaf info */
|
||||
func = index_to_func(user_index);
|
||||
if (!func)
|
||||
return;
|
||||
errx(EXIT_FAILURE, "Invalid input leaf (0x%x)", user_index);
|
||||
|
||||
/* Dump the raw data also */
|
||||
show_raw = true;
|
||||
|
||||
if (user_sub != 0xFFFFFFFF) {
|
||||
if (user_sub + 1 <= (u32)func->nr) {
|
||||
show_leaf(&func->leafs[user_sub]);
|
||||
return;
|
||||
if (user_sub + 1 > (u32)func->nr) {
|
||||
errx(EXIT_FAILURE, "Leaf 0x%x has no valid subleaf = 0x%x",
|
||||
user_index, user_sub);
|
||||
}
|
||||
|
||||
printf("ERR: invalid input subleaf (0x%x)\n", user_sub);
|
||||
show_leaf(&func->leafs[user_sub]);
|
||||
return;
|
||||
}
|
||||
|
||||
show_func(func);
|
||||
@@ -570,38 +575,21 @@ static void show_info(void)
|
||||
}
|
||||
|
||||
printf("CPU features:\n=============\n\n");
|
||||
show_range(leafs_basic);
|
||||
show_range(leafs_ext);
|
||||
for_each_valid_cpuid_range(range)
|
||||
show_range(range);
|
||||
}
|
||||
|
||||
static void setup_platform_cpuid(void)
|
||||
static void __noreturn usage(int exit_code)
|
||||
{
|
||||
u32 eax, ebx, ecx, edx;
|
||||
|
||||
/* Check vendor */
|
||||
eax = ebx = ecx = edx = 0;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
|
||||
/* "htuA" */
|
||||
if (ebx == 0x68747541)
|
||||
is_amd = true;
|
||||
|
||||
/* Setup leafs for the basic and extended range */
|
||||
leafs_basic = setup_cpuid_range(0x0);
|
||||
leafs_ext = setup_cpuid_range(0x80000000);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
|
||||
"\t-a|--all Show both bit flags and complex bit fields info\n"
|
||||
"\t-b|--bitflags Show boolean flags only\n"
|
||||
"\t-d|--detail Show details of the flag/fields (default)\n"
|
||||
"\t-f|--flags Specify the cpuid csv file\n"
|
||||
"\t-h|--help Show usage info\n"
|
||||
"\t-l|--leaf=index Specify the leaf you want to check\n"
|
||||
"\t-r|--raw Show raw cpuid data\n"
|
||||
"\t-s|--subleaf=sub Specify the subleaf you want to check\n"
|
||||
errx(exit_code, "kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
|
||||
"\t-a|--all Show both bit flags and complex bit fields info\n"
|
||||
"\t-b|--bitflags Show boolean flags only\n"
|
||||
"\t-d|--detail Show details of the flag/fields (default)\n"
|
||||
"\t-f|--flags Specify the CPUID CSV file\n"
|
||||
"\t-h|--help Show usage info\n"
|
||||
"\t-l|--leaf=index Specify the leaf you want to check\n"
|
||||
"\t-r|--raw Show raw CPUID data\n"
|
||||
"\t-s|--subleaf=sub Specify the subleaf you want to check"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -617,7 +605,7 @@ static struct option opts[] = {
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
static int parse_options(int argc, char *argv[])
|
||||
static void parse_options(int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -637,9 +625,7 @@ static int parse_options(int argc, char *argv[])
|
||||
user_csv = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
exit(1);
|
||||
break;
|
||||
usage(EXIT_SUCCESS);
|
||||
case 'l':
|
||||
/* main leaf */
|
||||
user_index = strtoul(optarg, NULL, 0);
|
||||
@@ -652,11 +638,8 @@ static int parse_options(int argc, char *argv[])
|
||||
user_sub = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
printf("%s: Invalid option '%c'\n", argv[0], optopt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
usage(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -669,11 +652,13 @@ static int parse_options(int argc, char *argv[])
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (parse_options(argc, argv))
|
||||
return -1;
|
||||
struct cpuid_range *range;
|
||||
|
||||
parse_options(argc, argv);
|
||||
|
||||
/* Setup the cpuid leafs of current platform */
|
||||
setup_platform_cpuid();
|
||||
for_each_cpuid_range(range)
|
||||
setup_cpuid_range(range);
|
||||
|
||||
/* Read and parse the 'cpuid.csv' */
|
||||
parse_text();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/cfi_types.h>
|
||||
#include <asm/cpufeatures.h>
|
||||
#include <asm/alternative.h>
|
||||
|
||||
@@ -28,7 +29,7 @@
|
||||
* only for the return value that is the same as the source input,
|
||||
* which the compiler could/should do much better anyway.
|
||||
*/
|
||||
SYM_FUNC_START(__memset)
|
||||
SYM_TYPED_FUNC_START(__memset)
|
||||
ALTERNATIVE "jmp memset_orig", "", X86_FEATURE_FSRS
|
||||
|
||||
movq %rdi,%r9
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Clang Control Flow Integrity (CFI) type definitions.
|
||||
*/
|
||||
#ifndef _LINUX_CFI_TYPES_H
|
||||
#define _LINUX_CFI_TYPES_H
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#ifdef CONFIG_CFI_CLANG
|
||||
/*
|
||||
* Use the __kcfi_typeid_<function> type identifier symbol to
|
||||
* annotate indirectly called assembly functions. The compiler emits
|
||||
* these symbols for all address-taken function declarations in C
|
||||
* code.
|
||||
*/
|
||||
#ifndef __CFI_TYPE
|
||||
#define __CFI_TYPE(name) \
|
||||
.4byte __kcfi_typeid_##name
|
||||
#endif
|
||||
|
||||
#define SYM_TYPED_ENTRY(name, linkage, align...) \
|
||||
linkage(name) ASM_NL \
|
||||
align ASM_NL \
|
||||
__CFI_TYPE(name) ASM_NL \
|
||||
name:
|
||||
|
||||
#define SYM_TYPED_START(name, linkage, align...) \
|
||||
SYM_TYPED_ENTRY(name, linkage, align)
|
||||
|
||||
#else /* CONFIG_CFI_CLANG */
|
||||
|
||||
#define SYM_TYPED_START(name, linkage, align...) \
|
||||
SYM_START(name, linkage, align)
|
||||
|
||||
#endif /* CONFIG_CFI_CLANG */
|
||||
|
||||
#ifndef SYM_TYPED_FUNC_START
|
||||
#define SYM_TYPED_FUNC_START(name) \
|
||||
SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* _LINUX_CFI_TYPES_H */
|
||||
@@ -85,6 +85,7 @@
|
||||
/* compatibility flags */
|
||||
#define MAP_FILE 0
|
||||
|
||||
#define PKEY_UNRESTRICTED 0x0
|
||||
#define PKEY_DISABLE_ACCESS 0x1
|
||||
#define PKEY_DISABLE_WRITE 0x2
|
||||
#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
|
||||
|
||||
@@ -849,9 +849,11 @@ __SYSCALL(__NR_getxattrat, sys_getxattrat)
|
||||
__SYSCALL(__NR_listxattrat, sys_listxattrat)
|
||||
#define __NR_removexattrat 466
|
||||
__SYSCALL(__NR_removexattrat, sys_removexattrat)
|
||||
#define __NR_open_tree_attr 467
|
||||
__SYSCALL(__NR_open_tree_attr, sys_open_tree_attr)
|
||||
|
||||
#undef __NR_syscalls
|
||||
#define __NR_syscalls 467
|
||||
#define __NR_syscalls 468
|
||||
|
||||
/*
|
||||
* 32 bit systems traditionally used different
|
||||
|
||||
@@ -79,6 +79,8 @@ enum {
|
||||
#define IPPROTO_MPLS IPPROTO_MPLS
|
||||
IPPROTO_ETHERNET = 143, /* Ethernet-within-IPv6 Encapsulation */
|
||||
#define IPPROTO_ETHERNET IPPROTO_ETHERNET
|
||||
IPPROTO_AGGFRAG = 144, /* AGGFRAG in ESP (RFC 9347) */
|
||||
#define IPPROTO_AGGFRAG IPPROTO_AGGFRAG
|
||||
IPPROTO_RAW = 255, /* Raw IP packets */
|
||||
#define IPPROTO_RAW IPPROTO_RAW
|
||||
IPPROTO_SMC = 256, /* Shared Memory Communications */
|
||||
|
||||
@@ -617,10 +617,6 @@ struct kvm_ioeventfd {
|
||||
#define KVM_X86_DISABLE_EXITS_HLT (1 << 1)
|
||||
#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2)
|
||||
#define KVM_X86_DISABLE_EXITS_CSTATE (1 << 3)
|
||||
#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \
|
||||
KVM_X86_DISABLE_EXITS_HLT | \
|
||||
KVM_X86_DISABLE_EXITS_PAUSE | \
|
||||
KVM_X86_DISABLE_EXITS_CSTATE)
|
||||
|
||||
/* for KVM_ENABLE_CAP */
|
||||
struct kvm_enable_cap {
|
||||
@@ -933,6 +929,7 @@ struct kvm_enable_cap {
|
||||
#define KVM_CAP_PRE_FAULT_MEMORY 236
|
||||
#define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237
|
||||
#define KVM_CAP_X86_GUEST_MODE 238
|
||||
#define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239
|
||||
|
||||
struct kvm_irq_routing_irqchip {
|
||||
__u32 irqchip;
|
||||
@@ -1070,6 +1067,10 @@ struct kvm_dirty_tlb {
|
||||
|
||||
#define KVM_REG_SIZE_SHIFT 52
|
||||
#define KVM_REG_SIZE_MASK 0x00f0000000000000ULL
|
||||
|
||||
#define KVM_REG_SIZE(id) \
|
||||
(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
|
||||
|
||||
#define KVM_REG_SIZE_U8 0x0000000000000000ULL
|
||||
#define KVM_REG_SIZE_U16 0x0010000000000000ULL
|
||||
#define KVM_REG_SIZE_U32 0x0020000000000000ULL
|
||||
|
||||
@@ -385,6 +385,8 @@ enum perf_event_read_format {
|
||||
*
|
||||
* @sample_max_stack: Max number of frame pointers in a callchain,
|
||||
* should be < /proc/sys/kernel/perf_event_max_stack
|
||||
* Max number of entries of branch stack
|
||||
* should be < hardware limit
|
||||
*/
|
||||
struct perf_event_attr {
|
||||
|
||||
|
||||
@@ -98,43 +98,93 @@ struct statx_timestamp {
|
||||
*/
|
||||
struct statx {
|
||||
/* 0x00 */
|
||||
__u32 stx_mask; /* What results were written [uncond] */
|
||||
__u32 stx_blksize; /* Preferred general I/O size [uncond] */
|
||||
__u64 stx_attributes; /* Flags conveying information about the file [uncond] */
|
||||
/* What results were written [uncond] */
|
||||
__u32 stx_mask;
|
||||
|
||||
/* Preferred general I/O size [uncond] */
|
||||
__u32 stx_blksize;
|
||||
|
||||
/* Flags conveying information about the file [uncond] */
|
||||
__u64 stx_attributes;
|
||||
|
||||
/* 0x10 */
|
||||
__u32 stx_nlink; /* Number of hard links */
|
||||
__u32 stx_uid; /* User ID of owner */
|
||||
__u32 stx_gid; /* Group ID of owner */
|
||||
__u16 stx_mode; /* File mode */
|
||||
/* Number of hard links */
|
||||
__u32 stx_nlink;
|
||||
|
||||
/* User ID of owner */
|
||||
__u32 stx_uid;
|
||||
|
||||
/* Group ID of owner */
|
||||
__u32 stx_gid;
|
||||
|
||||
/* File mode */
|
||||
__u16 stx_mode;
|
||||
__u16 __spare0[1];
|
||||
|
||||
/* 0x20 */
|
||||
__u64 stx_ino; /* Inode number */
|
||||
__u64 stx_size; /* File size */
|
||||
__u64 stx_blocks; /* Number of 512-byte blocks allocated */
|
||||
__u64 stx_attributes_mask; /* Mask to show what's supported in stx_attributes */
|
||||
/* Inode number */
|
||||
__u64 stx_ino;
|
||||
|
||||
/* File size */
|
||||
__u64 stx_size;
|
||||
|
||||
/* Number of 512-byte blocks allocated */
|
||||
__u64 stx_blocks;
|
||||
|
||||
/* Mask to show what's supported in stx_attributes */
|
||||
__u64 stx_attributes_mask;
|
||||
|
||||
/* 0x40 */
|
||||
struct statx_timestamp stx_atime; /* Last access time */
|
||||
struct statx_timestamp stx_btime; /* File creation time */
|
||||
struct statx_timestamp stx_ctime; /* Last attribute change time */
|
||||
struct statx_timestamp stx_mtime; /* Last data modification time */
|
||||
/* Last access time */
|
||||
struct statx_timestamp stx_atime;
|
||||
|
||||
/* File creation time */
|
||||
struct statx_timestamp stx_btime;
|
||||
|
||||
/* Last attribute change time */
|
||||
struct statx_timestamp stx_ctime;
|
||||
|
||||
/* Last data modification time */
|
||||
struct statx_timestamp stx_mtime;
|
||||
|
||||
/* 0x80 */
|
||||
__u32 stx_rdev_major; /* Device ID of special file [if bdev/cdev] */
|
||||
/* Device ID of special file [if bdev/cdev] */
|
||||
__u32 stx_rdev_major;
|
||||
__u32 stx_rdev_minor;
|
||||
__u32 stx_dev_major; /* ID of device containing file [uncond] */
|
||||
|
||||
/* ID of device containing file [uncond] */
|
||||
__u32 stx_dev_major;
|
||||
__u32 stx_dev_minor;
|
||||
|
||||
/* 0x90 */
|
||||
__u64 stx_mnt_id;
|
||||
__u32 stx_dio_mem_align; /* Memory buffer alignment for direct I/O */
|
||||
__u32 stx_dio_offset_align; /* File offset alignment for direct I/O */
|
||||
|
||||
/* Memory buffer alignment for direct I/O */
|
||||
__u32 stx_dio_mem_align;
|
||||
|
||||
/* File offset alignment for direct I/O */
|
||||
__u32 stx_dio_offset_align;
|
||||
|
||||
/* 0xa0 */
|
||||
__u64 stx_subvol; /* Subvolume identifier */
|
||||
__u32 stx_atomic_write_unit_min; /* Min atomic write unit in bytes */
|
||||
__u32 stx_atomic_write_unit_max; /* Max atomic write unit in bytes */
|
||||
/* Subvolume identifier */
|
||||
__u64 stx_subvol;
|
||||
|
||||
/* Min atomic write unit in bytes */
|
||||
__u32 stx_atomic_write_unit_min;
|
||||
|
||||
/* Max atomic write unit in bytes */
|
||||
__u32 stx_atomic_write_unit_max;
|
||||
|
||||
/* 0xb0 */
|
||||
__u32 stx_atomic_write_segments_max; /* Max atomic write segment count */
|
||||
__u32 __spare1[1];
|
||||
/* Max atomic write segment count */
|
||||
__u32 stx_atomic_write_segments_max;
|
||||
|
||||
/* File offset alignment for direct I/O reads */
|
||||
__u32 stx_dio_read_offset_align;
|
||||
|
||||
/* 0xb8 */
|
||||
__u64 __spare3[9]; /* Spare space for future expansion */
|
||||
|
||||
/* 0x100 */
|
||||
};
|
||||
|
||||
@@ -164,6 +214,7 @@ struct statx {
|
||||
#define STATX_MNT_ID_UNIQUE 0x00004000U /* Want/got extended stx_mount_id */
|
||||
#define STATX_SUBVOL 0x00008000U /* Want/got stx_subvol */
|
||||
#define STATX_WRITE_ATOMIC 0x00010000U /* Want/got atomic_write_* fields */
|
||||
#define STATX_DIO_READ_ALIGN 0x00020000U /* Want/got dio read alignment info */
|
||||
|
||||
#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */
|
||||
|
||||
|
||||
@@ -481,3 +481,4 @@
|
||||
464 common getxattrat sys_getxattrat
|
||||
465 common listxattrat sys_listxattrat
|
||||
466 common removexattrat sys_removexattrat
|
||||
467 common open_tree_attr sys_open_tree_attr
|
||||
|
||||
@@ -381,3 +381,4 @@
|
||||
464 n64 getxattrat sys_getxattrat
|
||||
465 n64 listxattrat sys_listxattrat
|
||||
466 n64 removexattrat sys_removexattrat
|
||||
467 n64 open_tree_attr sys_open_tree_attr
|
||||
|
||||
@@ -557,3 +557,4 @@
|
||||
464 common getxattrat sys_getxattrat
|
||||
465 common listxattrat sys_listxattrat
|
||||
466 common removexattrat sys_removexattrat
|
||||
467 common open_tree_attr sys_open_tree_attr
|
||||
|
||||
@@ -469,3 +469,4 @@
|
||||
464 common getxattrat sys_getxattrat sys_getxattrat
|
||||
465 common listxattrat sys_listxattrat sys_listxattrat
|
||||
466 common removexattrat sys_removexattrat sys_removexattrat
|
||||
467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr
|
||||
|
||||
@@ -470,3 +470,4 @@
|
||||
464 common getxattrat sys_getxattrat
|
||||
465 common listxattrat sys_listxattrat
|
||||
466 common removexattrat sys_removexattrat
|
||||
467 common open_tree_attr sys_open_tree_attr
|
||||
|
||||
@@ -512,3 +512,4 @@
|
||||
464 common getxattrat sys_getxattrat
|
||||
465 common listxattrat sys_listxattrat
|
||||
466 common removexattrat sys_removexattrat
|
||||
467 common open_tree_attr sys_open_tree_attr
|
||||
|
||||
@@ -396,7 +396,7 @@
|
||||
381 i386 pkey_alloc sys_pkey_alloc
|
||||
382 i386 pkey_free sys_pkey_free
|
||||
383 i386 statx sys_statx
|
||||
384 i386 arch_prctl sys_arch_prctl compat_sys_arch_prctl
|
||||
384 i386 arch_prctl sys_arch_prctl
|
||||
385 i386 io_pgetevents sys_io_pgetevents_time32 compat_sys_io_pgetevents
|
||||
386 i386 rseq sys_rseq
|
||||
393 i386 semget sys_semget
|
||||
@@ -472,3 +472,4 @@
|
||||
464 i386 getxattrat sys_getxattrat
|
||||
465 i386 listxattrat sys_listxattrat
|
||||
466 i386 removexattrat sys_removexattrat
|
||||
467 i386 open_tree_attr sys_open_tree_attr
|
||||
|
||||
@@ -390,6 +390,7 @@
|
||||
464 common getxattrat sys_getxattrat
|
||||
465 common listxattrat sys_listxattrat
|
||||
466 common removexattrat sys_removexattrat
|
||||
467 common open_tree_attr sys_open_tree_attr
|
||||
|
||||
#
|
||||
# Due to a historical design error, certain syscalls are numbered differently
|
||||
|
||||
@@ -437,3 +437,4 @@
|
||||
464 common getxattrat sys_getxattrat
|
||||
465 common listxattrat sys_listxattrat
|
||||
466 common removexattrat sys_removexattrat
|
||||
467 common open_tree_attr sys_open_tree_attr
|
||||
|
||||
@@ -20,6 +20,7 @@ FILES=(
|
||||
"include/uapi/linux/stat.h"
|
||||
"include/linux/bits.h"
|
||||
"include/vdso/bits.h"
|
||||
"include/linux/cfi_types.h"
|
||||
"include/linux/const.h"
|
||||
"include/vdso/const.h"
|
||||
"include/vdso/unaligned.h"
|
||||
@@ -185,7 +186,7 @@ done
|
||||
# diff with extra ignore lines
|
||||
check arch/x86/lib/memcpy_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memcpy_\(erms\|orig\))" -I"^#include <linux/cfi_types.h>"'
|
||||
check arch/x86/lib/memset_64.S '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memset_\(erms\|orig\))"'
|
||||
check arch/x86/include/asm/amd-ibs.h '-I "^#include [<\"]\(asm/\)*msr-index.h"'
|
||||
check arch/x86/include/asm/amd/ibs.h '-I "^#include [<\"]\(asm/\)*msr-index.h"'
|
||||
check arch/arm64/include/asm/cputype.h '-I "^#include [<\"]\(asm/\)*sysreg.h"'
|
||||
check include/linux/unaligned.h '-I "^#include <linux/unaligned/packed_struct.h>" -I "^#include <asm/byteorder.h>" -I "^#pragma GCC diagnostic"'
|
||||
check include/uapi/asm-generic/mman.h '-I "^#include <\(uapi/\)*asm-generic/mman-common\(-tools\)*.h>"'
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user