Files
kernel_xiaomi_sm8250/arch/arm64/kernel/cpuinfo.c
Greg Kroah-Hartman bbc4834e22 Merge 4.19.320 into android-4.19-stable
Changes in 4.19.320
	platform/chrome: cros_ec_debugfs: fix wrong EC message version
	hfsplus: fix to avoid false alarm of circular locking
	x86/of: Return consistent error type from x86_of_pci_irq_enable()
	x86/pci/intel_mid_pci: Fix PCIBIOS_* return code handling
	x86/pci/xen: Fix PCIBIOS_* return code handling
	x86/platform/iosf_mbi: Convert PCIBIOS_* return codes to errnos
	hwmon: (adt7475) Fix default duty on fan is disabled
	pwm: stm32: Always do lazy disabling
	hwmon: (max6697) Fix underflow when writing limit attributes
	hwmon: Introduce SENSOR_DEVICE_ATTR_{RO, RW, WO} and variants
	hwmon: (max6697) Auto-convert to use SENSOR_DEVICE_ATTR_{RO, RW, WO}
	hwmon: (max6697) Fix swapped temp{1,8} critical alarms
	arm64: dts: rockchip: Increase VOP clk rate on RK3328
	m68k: atari: Fix TT bootup freeze / unexpected (SCU) interrupt messages
	x86/xen: Convert comma to semicolon
	m68k: cmpxchg: Fix return value for default case in __arch_xchg()
	wifi: brcmsmac: LCN PHY code is used for BCM4313 2G-only device
	net/smc: Allow SMC-D 1MB DMB allocations
	net/smc: set rmb's SG_MAX_SINGLE_ALLOC limitation only when CONFIG_ARCH_NO_SG_CHAIN is defined
	selftests/bpf: Check length of recv in test_sockmap
	wifi: cfg80211: fix typo in cfg80211_calculate_bitrate_he()
	wifi: cfg80211: handle 2x996 RU allocation in cfg80211_calculate_bitrate_he()
	net: fec: Refactor: #define magic constants
	net: fec: Fix FEC_ECR_EN1588 being cleared on link-down
	ipvs: Avoid unnecessary calls to skb_is_gso_sctp
	perf: Fix perf_aux_size() for greater-than 32-bit size
	perf: Prevent passing zero nr_pages to rb_alloc_aux()
	bna: adjust 'name' buf size of bna_tcb and bna_ccb structures
	selftests: forwarding: devlink_lib: Wait for udev events after reloading
	media: imon: Fix race getting ictx->lock
	saa7134: Unchecked i2c_transfer function result fixed
	media: uvcvideo: Allow entity-defined get_info and get_cur
	media: uvcvideo: Override default flags
	media: renesas: vsp1: Fix _irqsave and _irq mix
	media: renesas: vsp1: Store RPF partition configuration per RPF instance
	leds: trigger: Unregister sysfs attributes before calling deactivate()
	perf report: Fix condition in sort__sym_cmp()
	drm/etnaviv: fix DMA direction handling for cached RW buffers
	mfd: omap-usb-tll: Use struct_size to allocate tll
	ext4: avoid writing unitialized memory to disk in EA inodes
	sparc64: Fix incorrect function signature and add prototype for prom_cif_init
	PCI: Equalize hotplug memory and io for occupied and empty slots
	PCI: Fix resource double counting on remove & rescan
	RDMA/mlx4: Fix truncated output warning in mad.c
	RDMA/mlx4: Fix truncated output warning in alias_GUID.c
	RDMA/rxe: Don't set BTH_ACK_MASK for UC or UD QPs
	mtd: make mtd_test.c a separate module
	Input: elan_i2c - do not leave interrupt disabled on suspend failure
	MIPS: Octeron: remove source file executable bit
	powerpc/xmon: Fix disassembly CPU feature checks
	macintosh/therm_windtunnel: fix module unload.
	bnxt_re: Fix imm_data endianness
	ice: Rework flex descriptor programming
	netfilter: ctnetlink: use helper function to calculate expect ID
	pinctrl: core: fix possible memory leak when pinctrl_enable() fails
	pinctrl: single: fix possible memory leak when pinctrl_enable() fails
	pinctrl: ti: ti-iodelay: Drop if block with always false condition
	pinctrl: ti: ti-iodelay: fix possible memory leak when pinctrl_enable() fails
	pinctrl: freescale: mxs: Fix refcount of child
	fs/nilfs2: remove some unused macros to tame gcc
	nilfs2: avoid undefined behavior in nilfs_cnt32_ge macro
	tick/broadcast: Make takeover of broadcast hrtimer reliable
	net: netconsole: Disable target before netpoll cleanup
	af_packet: Handle outgoing VLAN packets without hardware offloading
	ipv6: take care of scope when choosing the src addr
	char: tpm: Fix possible memory leak in tpm_bios_measurements_open()
	media: venus: fix use after free in vdec_close
	hfs: fix to initialize fields of hfs_inode_info after hfs_alloc_inode()
	drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes
	drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes
	m68k: amiga: Turn off Warp1260 interrupts during boot
	ext4: check dot and dotdot of dx_root before making dir indexed
	ext4: make sure the first directory block is not a hole
	wifi: mwifiex: Fix interface type change
	leds: ss4200: Convert PCIBIOS_* return codes to errnos
	tools/memory-model: Fix bug in lock.cat
	hwrng: amd - Convert PCIBIOS_* return codes to errnos
	PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN
	binder: fix hang of unregistered readers
	scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds
	f2fs: fix to don't dirty inode for readonly filesystem
	clk: davinci: da8xx-cfgchip: Initialize clk_init_data before use
	ubi: eba: properly rollback inside self_check_eba
	decompress_bunzip2: fix rare decompression failure
	kobject_uevent: Fix OOB access within zap_modalias_env()
	rtc: cmos: Fix return value of nvmem callbacks
	scsi: qla2xxx: During vport delete send async logout explicitly
	scsi: qla2xxx: validate nvme_local_port correctly
	perf/x86/intel/pt: Fix topa_entry base length
	watchdog/perf: properly initialize the turbo mode timestamp and rearm counter
	platform: mips: cpu_hwmon: Disable driver on unsupported hardware
	RDMA/iwcm: Fix a use-after-free related to destroying CM IDs
	selftests/sigaltstack: Fix ppc64 GCC build
	nilfs2: handle inconsistent state in nilfs_btnode_create_block()
	kdb: Fix bound check compiler warning
	kdb: address -Wformat-security warnings
	kdb: Use the passed prompt in kdb_position_cursor()
	jfs: Fix array-index-out-of-bounds in diFree
	dma: fix call order in dmam_free_coherent
	MIPS: SMP-CPS: Fix address for GCR_ACCESS register for CM3 and later
	net: ip_rt_get_source() - use new style struct initializer instead of memset
	ipv4: Fix incorrect source address in Record Route option
	net: bonding: correctly annotate RCU in bond_should_notify_peers()
	tipc: Return non-zero value from tipc_udp_addr2str() on error
	mISDN: Fix a use after free in hfcmulti_tx()
	mm: avoid overflows in dirty throttling logic
	PCI: rockchip: Make 'ep-gpios' DT property optional
	PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio
	parport: parport_pc: Mark expected switch fall-through
	parport: Convert printk(KERN_<LEVEL> to pr_<level>(
	parport: Standardize use of printmode
	dev/parport: fix the array out-of-bounds risk
	driver core: Cast to (void *) with __force for __percpu pointer
	devres: Fix memory leakage caused by driver API devm_free_percpu()
	perf/x86/intel/pt: Export pt_cap_get()
	perf/x86/intel/pt: Use helpers to obtain ToPA entry size
	perf/x86/intel/pt: Use pointer arithmetics instead in ToPA entry calculation
	perf/x86/intel/pt: Split ToPA metadata and page layout
	perf/x86/intel/pt: Fix a topa_entry base address calculation
	remoteproc: imx_rproc: ignore mapping vdev regions
	remoteproc: imx_rproc: Fix ignoring mapping vdev regions
	remoteproc: imx_rproc: Skip over memory region when node value is NULL
	drm/vmwgfx: Fix overlay when using Screen Targets
	net/iucv: fix use after free in iucv_sock_close()
	ipv6: fix ndisc_is_useropt() handling for PIO
	protect the fetch of ->fd[fd] in do_dup2() from mispredictions
	ALSA: usb-audio: Correct surround channels in UAC1 channel map
	net: usb: sr9700: fix uninitialized variable use in sr_mdio_read
	irqchip/mbigen: Fix mbigen node address layout
	x86/mm: Fix pti_clone_pgtable() alignment assumption
	net: usb: qmi_wwan: fix memory leak for not ip packets
	net: linkwatch: use system_unbound_wq
	Bluetooth: l2cap: always unlock channel in l2cap_conless_channel()
	net: fec: Stop PPS on driver remove
	md/raid5: avoid BUG_ON() while continue reshape after reassembling
	clocksource/drivers/sh_cmt: Address race condition for clock events
	PCI: Add Edimax Vendor ID to pci_ids.h
	udf: prevent integer overflow in udf_bitmap_free_blocks()
	wifi: nl80211: don't give key data to userspace
	btrfs: fix bitmap leak when loading free space cache on duplicate entry
	media: uvcvideo: Ignore empty TS packets
	media: uvcvideo: Fix the bandwdith quirk on USB 3.x
	jbd2: avoid memleak in jbd2_journal_write_metadata_buffer
	s390/sclp: Prevent release of buffer in I/O
	SUNRPC: Fix a race to wake a sync task
	ext4: fix wrong unit use in ext4_mb_find_by_goal
	arm64: Add support for SB barrier and patch in over DSB; ISB sequences
	arm64: cpufeature: Force HWCAP to be based on the sysreg visible to user-space
	arm64: Add Neoverse-V2 part
	arm64: cputype: Add Cortex-X4 definitions
	arm64: cputype: Add Neoverse-V3 definitions
	arm64: errata: Add workaround for Arm errata 3194386 and 3312417
	arm64: cputype: Add Cortex-X3 definitions
	arm64: cputype: Add Cortex-A720 definitions
	arm64: cputype: Add Cortex-X925 definitions
	arm64: errata: Unify speculative SSBS errata logic
	arm64: errata: Expand speculative SSBS workaround
	arm64: cputype: Add Cortex-X1C definitions
	arm64: cputype: Add Cortex-A725 definitions
	arm64: errata: Expand speculative SSBS workaround (again)
	i2c: smbus: Don't filter out duplicate alerts
	i2c: smbus: Improve handling of stuck alerts
	i2c: smbus: Send alert notifications to all devices if source not found
	bpf: kprobe: remove unused declaring of bpf_kprobe_override
	spi: lpspi: Replace all "master" with "controller"
	spi: lpspi: Add slave mode support
	spi: lpspi: Let watermark change with send data length
	spi: lpspi: Add i.MX8 boards support for lpspi
	spi: lpspi: add the error info of transfer speed setting
	spi: fsl-lpspi: remove unneeded array
	spi: spi-fsl-lpspi: Fix scldiv calculation
	ALSA: line6: Fix racy access to midibuf
	usb: vhci-hcd: Do not drop references before new references are gained
	USB: serial: debug: do not echo input by default
	usb: gadget: core: Check for unset descriptor
	scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic
	tick/broadcast: Move per CPU pointer access into the atomic section
	ntp: Clamp maxerror and esterror to operating range
	driver core: Fix uevent_show() vs driver detach race
	ntp: Safeguard against time_constant overflow
	serial: core: check uartclk for zero to avoid divide by zero
	power: supply: axp288_charger: Fix constant_charge_voltage writes
	power: supply: axp288_charger: Round constant_charge_voltage writes down
	tracing: Fix overflow in get_free_elt()
	x86/mtrr: Check if fixed MTRRs exist before saving them
	drm/bridge: analogix_dp: properly handle zero sized AUX transactions
	drm/mgag200: Set DDC timeout in milliseconds
	kbuild: Fix '-S -c' in x86 stack protector scripts
	netfilter: nf_tables: set element extended ACK reporting support
	netfilter: nf_tables: use timestamp to check for set element timeout
	netfilter: nf_tables: prefer nft_chain_validate
	arm64: cpufeature: Fix the visibility of compat hwcaps
	media: uvcvideo: Use entity get_cur in uvc_ctrl_set
	drm/i915/gem: Fix Virtual Memory mapping boundaries calculation
	exec: Fix ToCToU between perm check and set-uid/gid usage
	nvme/pci: Add APST quirk for Lenovo N60z laptop
	Linux 4.19.320

Change-Id: I12efa55c04d97f29d34f1a49511948735871b2bd
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2024-08-28 09:03:40 +00:00

403 lines
10 KiB
C

/*
* Record and handle CPU attributes.
*
* Copyright (C) 2014 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/>.
*/
#include <asm/arch_timer.h>
#include <asm/cache.h>
#include <asm/cpu.h>
#include <asm/cputype.h>
#include <asm/cpufeature.h>
#include <asm/fpsimd.h>
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/compat.h>
#include <linux/elf.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/personality.h>
#include <linux/preempt.h>
#include <linux/printk.h>
#include <linux/seq_file.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/delay.h>
#include <linux/of_fdt.h>
char* (*arch_read_hardware_id)(void);
EXPORT_SYMBOL(arch_read_hardware_id);
static const char *machine_name;
/*
* In case the boot CPU is hotpluggable, we record its initial state and
* current state separately. Certain system registers may contain different
* values depending on configuration at or after reset.
*/
DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
static struct cpuinfo_arm64 boot_cpu_data;
static char *icache_policy_str[] = {
[0 ... ICACHE_POLICY_PIPT] = "RESERVED/UNKNOWN",
[ICACHE_POLICY_VIPT] = "VIPT",
[ICACHE_POLICY_PIPT] = "PIPT",
[ICACHE_POLICY_VPIPT] = "VPIPT",
};
unsigned long __icache_flags;
static const char *const hwcap_str[] = {
"fp",
"asimd",
"evtstrm",
"aes",
"pmull",
"sha1",
"sha2",
"crc32",
"atomics",
"fphp",
"asimdhp",
"cpuid",
"asimdrdm",
"jscvt",
"fcma",
"lrcpc",
"dcpop",
"sha3",
"sm3",
"sm4",
"asimddp",
"sha512",
"sve",
"asimdfhm",
"dit",
"uscat",
"ilrcpc",
"flagm",
"ssbs",
"sb",
NULL
};
#ifdef CONFIG_COMPAT
static const char *const compat_hwcap_str[] = {
"swp",
"half",
"thumb",
"26bit",
"fastmult",
"fpa",
"vfp",
"edsp",
"java",
"iwmmxt",
"crunch",
"thumbee",
"neon",
"vfpv3",
"vfpv3d16",
"tls",
"vfpv4",
"idiva",
"idivt",
"vfpd32",
"lpae",
"evtstrm",
NULL
};
static const char *const compat_hwcap2_str[] = {
"aes",
"pmull",
"sha1",
"sha2",
"crc32",
NULL
};
#endif /* CONFIG_COMPAT */
static int c_show(struct seq_file *m, void *v)
{
int i, j;
bool compat = personality(current->personality) == PER_LINUX32;
for_each_online_cpu(i) {
struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
u32 midr = cpuinfo->reg_midr;
/*
* glibc reads /proc/cpuinfo to determine the number of
* online processors, looking for lines beginning with
* "processor". Give glibc what it expects.
*/
seq_printf(m, "processor\t: %d\n", i);
if (compat)
seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
loops_per_jiffy / (500000UL/HZ),
loops_per_jiffy / (5000UL/HZ) % 100);
/*
* Dump out the common processor features in a single line.
* Userspace should read the hwcaps with getauxval(AT_HWCAP)
* rather than attempting to parse this, but there's a body of
* software which does already (at least for 32-bit).
*/
seq_puts(m, "Features\t:");
if (compat) {
#ifdef CONFIG_COMPAT
for (j = 0; compat_hwcap_str[j]; j++)
if (compat_elf_hwcap & (1 << j))
seq_printf(m, " %s", compat_hwcap_str[j]);
for (j = 0; compat_hwcap2_str[j]; j++)
if (compat_elf_hwcap2 & (1 << j))
seq_printf(m, " %s", compat_hwcap2_str[j]);
#endif /* CONFIG_COMPAT */
} else {
for (j = 0; hwcap_str[j]; j++)
if (elf_hwcap & (1 << j))
seq_printf(m, " %s", hwcap_str[j]);
}
seq_puts(m, "\n");
seq_printf(m, "CPU implementer\t: 0x%02x\n",
MIDR_IMPLEMENTOR(midr));
seq_printf(m, "CPU architecture: 8\n");
seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr));
seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr));
seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr));
}
if (!arch_read_hardware_id)
seq_printf(m, "Hardware\t: %s\n", machine_name);
else
seq_printf(m, "Hardware\t: %s\n", arch_read_hardware_id());
return 0;
}
static void *c_start(struct seq_file *m, loff_t *pos)
{
return *pos < 1 ? (void *)1 : NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
++*pos;
return NULL;
}
static void c_stop(struct seq_file *m, void *v)
{
}
const struct seq_operations cpuinfo_op = {
.start = c_start,
.next = c_next,
.stop = c_stop,
.show = c_show
};
static struct kobj_type cpuregs_kobj_type = {
.sysfs_ops = &kobj_sysfs_ops,
};
/*
* The ARM ARM uses the phrase "32-bit register" to describe a register
* whose upper 32 bits are RES0 (per C5.1.1, ARM DDI 0487A.i), however
* no statement is made as to whether the upper 32 bits will or will not
* be made use of in future, and between ARM DDI 0487A.c and ARM DDI
* 0487A.d CLIDR_EL1 was expanded from 32-bit to 64-bit.
*
* Thus, while both MIDR_EL1 and REVIDR_EL1 are described as 32-bit
* registers, we expose them both as 64 bit values to cater for possible
* future expansion without an ABI break.
*/
#define kobj_to_cpuinfo(kobj) container_of(kobj, struct cpuinfo_arm64, kobj)
#define CPUREGS_ATTR_RO(_name, _field) \
static ssize_t _name##_show(struct kobject *kobj, \
struct kobj_attribute *attr, char *buf) \
{ \
struct cpuinfo_arm64 *info = kobj_to_cpuinfo(kobj); \
\
if (info->reg_midr) \
return sprintf(buf, "0x%016x\n", info->reg_##_field); \
else \
return 0; \
} \
static struct kobj_attribute cpuregs_attr_##_name = __ATTR_RO(_name)
CPUREGS_ATTR_RO(midr_el1, midr);
CPUREGS_ATTR_RO(revidr_el1, revidr);
static struct attribute *cpuregs_id_attrs[] = {
&cpuregs_attr_midr_el1.attr,
&cpuregs_attr_revidr_el1.attr,
NULL
};
static const struct attribute_group cpuregs_attr_group = {
.attrs = cpuregs_id_attrs,
.name = "identification"
};
static int cpuid_cpu_online(unsigned int cpu)
{
int rc;
struct device *dev;
struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu);
dev = get_cpu_device(cpu);
if (!dev) {
rc = -ENODEV;
goto out;
}
rc = kobject_add(&info->kobj, &dev->kobj, "regs");
if (rc)
goto out;
rc = sysfs_create_group(&info->kobj, &cpuregs_attr_group);
if (rc)
kobject_del(&info->kobj);
out:
return rc;
}
static int cpuid_cpu_offline(unsigned int cpu)
{
struct device *dev;
struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu);
dev = get_cpu_device(cpu);
if (!dev)
return -ENODEV;
if (info->kobj.parent) {
sysfs_remove_group(&info->kobj, &cpuregs_attr_group);
kobject_del(&info->kobj);
}
return 0;
}
static int __init cpuinfo_regs_init(void)
{
int cpu, ret;
for_each_possible_cpu(cpu) {
struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu);
kobject_init(&info->kobj, &cpuregs_kobj_type);
}
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/cpuinfo:online",
cpuid_cpu_online, cpuid_cpu_offline);
if (ret < 0) {
pr_err("cpuinfo: failed to register hotplug callbacks.\n");
return ret;
}
return 0;
}
static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
{
unsigned int cpu = smp_processor_id();
u32 l1ip = CTR_L1IP(info->reg_ctr);
switch (l1ip) {
case ICACHE_POLICY_PIPT:
break;
case ICACHE_POLICY_VPIPT:
set_bit(ICACHEF_VPIPT, &__icache_flags);
break;
default:
/* Fallthrough */
case ICACHE_POLICY_VIPT:
/* Assume aliasing */
set_bit(ICACHEF_ALIASING, &__icache_flags);
}
pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
}
static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
{
info->reg_cntfrq = arch_timer_get_cntfrq();
info->reg_ctr = read_cpuid_cachetype();
info->reg_dczid = read_cpuid(DCZID_EL0);
info->reg_midr = read_cpuid_id();
info->reg_revidr = read_cpuid(REVIDR_EL1);
info->reg_id_aa64dfr0 = read_cpuid(ID_AA64DFR0_EL1);
info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1);
info->reg_id_aa64isar0 = read_cpuid(ID_AA64ISAR0_EL1);
info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1);
info->reg_id_aa64isar2 = read_cpuid(ID_AA64ISAR2_EL1);
info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1);
info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
/* Update the 32bit ID registers only if AArch32 is implemented */
if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1);
info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1);
info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1);
info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1);
info->reg_id_isar3 = read_cpuid(ID_ISAR3_EL1);
info->reg_id_isar4 = read_cpuid(ID_ISAR4_EL1);
info->reg_id_isar5 = read_cpuid(ID_ISAR5_EL1);
info->reg_id_mmfr0 = read_cpuid(ID_MMFR0_EL1);
info->reg_id_mmfr1 = read_cpuid(ID_MMFR1_EL1);
info->reg_id_mmfr2 = read_cpuid(ID_MMFR2_EL1);
info->reg_id_mmfr3 = read_cpuid(ID_MMFR3_EL1);
info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1);
info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1);
info->reg_mvfr0 = read_cpuid(MVFR0_EL1);
info->reg_mvfr1 = read_cpuid(MVFR1_EL1);
info->reg_mvfr2 = read_cpuid(MVFR2_EL1);
}
if (IS_ENABLED(CONFIG_ARM64_SVE) &&
id_aa64pfr0_sve(info->reg_id_aa64pfr0))
info->reg_zcr = read_zcr_features();
cpuinfo_detect_icache_policy(info);
}
void cpuinfo_store_cpu(void)
{
struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data);
__cpuinfo_store_cpu(info);
update_cpu_features(smp_processor_id(), info, &boot_cpu_data);
}
void __init cpuinfo_store_boot_cpu(void)
{
struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0);
__cpuinfo_store_cpu(info);
boot_cpu_data = *info;
init_cpu_features(&boot_cpu_data);
machine_name = of_flat_dt_get_machine_name();
}
device_initcall(cpuinfo_regs_init);