Commit 1184674d authored by Thomas Weißschuh's avatar Thomas Weißschuh Committed by Thomas Gleixner
Browse files

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: default avatarThomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20241010-vdso-generic-base-v1-26-b64f0842d512@linutronix.de
parent c22c06b4
Loading
Loading
Loading
Loading
+6 −26
Original line number Diff line number Diff line
@@ -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 */
+24 −1
Original line number Diff line number Diff line
@@ -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);
+3 −1
Original line number Diff line number Diff line
@@ -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/
+6 −4
Original line number Diff line number Diff line
@@ -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]);
+3 −0
Original line number Diff line number Diff line
@@ -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();
Loading