powerpc: Split systemcfg data out of vdso data page

The systemcfg data only has minimal overlap with the vdso data.
Splitting the two avoids mapping the implementation-defined vdso data
into /proc/ppc64/systemcfg.
It is also a preparation for the standardization of vdso data storage.

The only field actually used by both systemcfg and vdso is
tb_ticks_per_sec and it is only changed once during time_init().
Initialize it in both structures there.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-26-b64f0842d512@linutronix.de
This commit is contained in:
Thomas Weißschuh 2024-10-10 09:01:28 +02:00 committed by Thomas Gleixner
parent c22c06b4cc
commit 1184674d6e
8 changed files with 48 additions and 54 deletions

View File

@ -10,21 +10,6 @@
*/
/*
* Note about this structure:
*
* This structure was historically called systemcfg and exposed to
* userland via /proc/ppc64/systemcfg. Unfortunately, this became an
* ABI issue as some proprietary software started relying on being able
* to mmap() it, thus we have to keep the base layout at least for a
* few kernel versions.
*
* However, since ppc32 doesn't suffer from this backward handicap,
* a simpler version of the data structure is used there with only the
* fields actually used by the vDSO.
*
*/
/*
* If the major version changes we are incompatible.
* Minor version changes are a hint.
@ -40,13 +25,9 @@
#define SYSCALL_MAP_SIZE ((NR_syscalls + 31) / 32)
/*
* So here is the ppc64 backward compatible version
*/
#ifdef CONFIG_PPC64
struct vdso_arch_data {
struct systemcfg {
__u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */
struct { /* Systemcfg version numbers */
__u32 major; /* Major number 0x10 */
@ -71,10 +52,12 @@ struct vdso_arch_data {
__u32 dcache_line_size; /* L1 d-cache line size 0x64 */
__u32 icache_size; /* L1 i-cache size 0x68 */
__u32 icache_line_size; /* L1 i-cache line size 0x6C */
};
/* those additional ones don't have to be located anywhere
* special as they were not part of the original systemcfg
*/
extern struct systemcfg *systemcfg;
struct vdso_arch_data {
__u64 tb_ticks_per_sec; /* Timebase tics / sec */
__u32 dcache_block_size; /* L1 d-cache block size */
__u32 icache_block_size; /* L1 i-cache block size */
__u32 dcache_log_block_size; /* L1 d-cache log block size */
@ -88,9 +71,6 @@ struct vdso_arch_data {
#else /* CONFIG_PPC64 */
/*
* And here is the simpler 32 bits version
*/
struct vdso_arch_data {
__u64 tb_ticks_per_sec; /* Timebase tics / sec */
__u32 syscall_map[SYSCALL_MAP_SIZE]; /* Map of syscalls */

View File

@ -4,6 +4,7 @@
*/
#include <linux/init.h>
#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
@ -44,13 +45,35 @@ static const struct proc_ops page_map_proc_ops = {
.proc_mmap = page_map_mmap,
};
static union {
struct systemcfg data;
u8 page[PAGE_SIZE];
} systemcfg_data_store __page_aligned_data;
struct systemcfg *systemcfg = &systemcfg_data_store.data;
static int __init proc_ppc64_init(void)
{
struct proc_dir_entry *pde;
strcpy((char *)systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
systemcfg->version.major = SYSTEMCFG_MAJOR;
systemcfg->version.minor = SYSTEMCFG_MINOR;
systemcfg->processor = mfspr(SPRN_PVR);
/*
* Fake the old platform number for pSeries and add
* in LPAR bit if necessary
*/
systemcfg->platform = 0x100;
if (firmware_has_feature(FW_FEATURE_LPAR))
systemcfg->platform |= 1;
systemcfg->physicalMemorySize = memblock_phys_mem_size();
systemcfg->dcache_size = ppc64_caches.l1d.size;
systemcfg->dcache_line_size = ppc64_caches.l1d.line_size;
systemcfg->icache_size = ppc64_caches.l1i.size;
systemcfg->icache_line_size = ppc64_caches.l1i.line_size;
pde = proc_create_data("powerpc/systemcfg", S_IFREG | 0444, NULL,
&page_map_proc_ops, vdso_data);
&page_map_proc_ops, systemcfg);
if (!pde)
return 1;
proc_set_size(pde, PAGE_SIZE);

View File

@ -560,7 +560,9 @@ void __init smp_setup_cpu_maps(void)
out:
of_node_put(dn);
}
vdso_data->processorCount = num_present_cpus();
#endif
#ifdef CONFIG_PPC64_PROC_SYSTEMCFG
systemcfg->processorCount = num_present_cpus();
#endif /* CONFIG_PPC64 */
/* Initialize CPU <=> thread mapping/

View File

@ -1186,8 +1186,8 @@ int generic_cpu_disable(void)
return -EBUSY;
set_cpu_online(cpu, false);
#ifdef CONFIG_PPC64
vdso_data->processorCount--;
#ifdef CONFIG_PPC64_PROC_SYSTEMCFG
systemcfg->processorCount--;
#endif
/* Update affinity of all IRQs previously aimed at this CPU */
irq_migrate_all_off_this_cpu();
@ -1642,10 +1642,12 @@ void start_secondary(void *unused)
secondary_cpu_time_init();
#ifdef CONFIG_PPC64
#ifdef CONFIG_PPC64_PROC_SYSTEMCFG
if (system_state == SYSTEM_RUNNING)
vdso_data->processorCount++;
systemcfg->processorCount++;
#endif
#ifdef CONFIG_PPC64
vdso_getcpu_init();
#endif
set_numa_node(numa_cpu_lookup_table[cpu]);

View File

@ -950,6 +950,9 @@ void __init time_init(void)
}
vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
#ifdef CONFIG_PPC64_PROC_SYSTEMCFG
systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
#endif
/* initialise and enable the large decrementer (if we have one) */
set_decrementer_max();

View File

@ -16,7 +16,6 @@
#include <linux/user.h>
#include <linux/elf.h>
#include <linux/security.h>
#include <linux/memblock.h>
#include <linux/syscalls.h>
#include <linux/time_namespace.h>
#include <vdso/datapage.h>
@ -349,25 +348,6 @@ static struct page ** __init vdso_setup_pages(void *start, void *end)
static int __init vdso_init(void)
{
#ifdef CONFIG_PPC64
/*
* Fill up the "systemcfg" stuff for backward compatibility
*/
strcpy((char *)vdso_data->eye_catcher, "SYSTEMCFG:PPC64");
vdso_data->version.major = SYSTEMCFG_MAJOR;
vdso_data->version.minor = SYSTEMCFG_MINOR;
vdso_data->processor = mfspr(SPRN_PVR);
/*
* Fake the old platform number for pSeries and add
* in LPAR bit if necessary
*/
vdso_data->platform = 0x100;
if (firmware_has_feature(FW_FEATURE_LPAR))
vdso_data->platform |= 1;
vdso_data->physicalMemorySize = memblock_phys_mem_size();
vdso_data->dcache_size = ppc64_caches.l1d.size;
vdso_data->dcache_line_size = ppc64_caches.l1d.line_size;
vdso_data->icache_size = ppc64_caches.l1i.size;
vdso_data->icache_line_size = ppc64_caches.l1i.line_size;
vdso_data->dcache_block_size = ppc64_caches.l1d.block_size;
vdso_data->icache_block_size = ppc64_caches.l1i.block_size;
vdso_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size;

View File

@ -136,7 +136,9 @@ static int pnv_smp_cpu_disable(void)
* the generic fixup_irqs. --BenH.
*/
set_cpu_online(cpu, false);
vdso_data->processorCount--;
#ifdef CONFIG_PPC64_PROC_SYSTEMCFG
systemcfg->processorCount--;
#endif
if (cpu == boot_cpuid)
boot_cpuid = cpumask_any(cpu_online_mask);
if (xive_enabled())

View File

@ -83,7 +83,9 @@ static int pseries_cpu_disable(void)
int cpu = smp_processor_id();
set_cpu_online(cpu, false);
vdso_data->processorCount--;
#ifdef CONFIG_PPC64_PROC_SYSTEMCFG
systemcfg->processorCount--;
#endif
/*fix boot_cpuid here*/
if (cpu == boot_cpuid)