Re: [PATCH 3/4] parisc: Use absolute_pointer for memcmp on fixed memory location
From: Helge Deller <deller@gmx.de>
Date: 2021-09-12 20:00:49
Also in:
lkml, netdev
Subsystem:
console subsystem, framebuffer layer, parisc architecture, the rest · Maintainers:
Greg Kroah-Hartman, Helge Deller, "James E.J. Bottomley", Linus Torvalds
* Linus Torvalds [off-list ref]:
On Sun, Sep 12, 2021 at 9:02 AM Guenter Roeck [off-list ref] wrote:quoted
- running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0); + running_on_qemu = (memcmp(absolute_pointer(&PAGE0->pad0), "SeaBIOS", 8) == 0);This seems entirely the wrong thing to do, and makes no sense. That "&PAGE0->pad0" is a perfectly valid pointer, and that's not where the problem is. The problem is "PAGE0" itself: #define PAGE0 ((struct zeropage *)__PAGE_OFFSET) which takes that absolute offset and creates a pointer out of it. IOW, _that_ is what should have the "absolute_pointer()" thing, and in that context the name of that macro and its use actually makes sense. No? An alternative - and possibly cleaner - approach that doesn't need absolute_pointer() at all might be to just do extern struct zeropage PAGE0; and then make that PAGE0 be defined to __PAGE_OFFSET in the parisc vmlinux.lds.S file. Then doing things like running_on_qemu = !memcmp(&PAGE0.pad0, "SeaBIOS", 8); would JustWork(tm).
Yes, this second approach seems to work nicely, although the patch then gets slightly bigger. Below is a tested patch. I'll check it some further and apply it to the parisc tree then. Thanks! Helge -------- [PATCH] Define and export PAGE0 in vmlinux.lds.S linker script Signed-off-by: Helge Deller <deller@gmx.de> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> ---
diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c
index 7ee49f5881d1..1b957c6bbe5c 100644
--- a/arch/parisc/boot/compressed/misc.c
+++ b/arch/parisc/boot/compressed/misc.c@@ -319,7 +319,7 @@ unsigned long decompress_kernel(unsigned int started_wide, /* Limit memory for bootoader to 1GB */ #define ARTIFICIAL_LIMIT (1*1024*1024*1024) - free_mem_end_ptr = PAGE0->imm_max_mem; + free_mem_end_ptr = PAGE0.imm_max_mem; if (free_mem_end_ptr > ARTIFICIAL_LIMIT) free_mem_end_ptr = ARTIFICIAL_LIMIT;
diff --git a/arch/parisc/boot/compressed/vmlinux.lds.S b/arch/parisc/boot/compressed/vmlinux.lds.S
index ab7b43990857..83a1f8f67aba 100644
--- a/arch/parisc/boot/compressed/vmlinux.lds.S
+++ b/arch/parisc/boot/compressed/vmlinux.lds.S@@ -14,6 +14,9 @@ ENTRY(startup) SECTIONS { + . = __PAGE_OFFSET; + PAGE0 = .; + /* palo loads at 0x60000 */ /* loaded kernel will move to 0x10000 */ . = 0xe0000; /* should not overwrite palo code */
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index d00313d1274e..7b64c05abd0c 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h@@ -100,6 +100,9 @@ typedef struct __physmem_range { extern physmem_range_t pmem_ranges[]; extern int npmem_ranges; +/* Address of PAGE0 is defined in vmlinux.lds.S */ +extern struct zeropage PAGE0; + #endif /* !__ASSEMBLY__ */ /* WARNING: The definitions below must match exactly to sizeof(pte_t)
@@ -184,8 +187,6 @@ extern int npmem_ranges; #include <asm-generic/getorder.h> #include <asm/pdc.h> -#define PAGE0 ((struct zeropage *)__PAGE_OFFSET) - /* DEFINITION OF THE ZERO-PAGE (PAG0) */ /* based on work by Jason Eckhardt (jason@equator.com) */
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 776d624a7207..2e8b6e530c09 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c@@ -944,9 +944,9 @@ static __init void qemu_header(void) pr_info("#define PARISC_PDC_ENTRY_ORG 0x%04lx\n\n", #ifdef CONFIG_64BIT - (unsigned long)(PAGE0->mem_pdc_hi) << 32 | + (unsigned long)(PAGE0.mem_pdc_hi) << 32 | #endif - (unsigned long)PAGE0->mem_pdc); + (unsigned long)PAGE0.mem_pdc); pr_info("#define PARISC_PDC_CACHE_INFO"); p = (unsigned long *) &cache_info;
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 7034227dbdf3..17516de2f191 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c@@ -103,10 +103,10 @@ long real64_call(unsigned long function, ...); long real32_call(unsigned long function, ...); #ifdef CONFIG_64BIT -# define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc +# define MEM_PDC (unsigned long)(PAGE0.mem_pdc_hi) << 32 | PAGE0.mem_pdc # define mem_pdc_call(args...) unlikely(parisc_narrow_firmware) ? real32_call(MEM_PDC, args) : real64_call(MEM_PDC, args) #else -# define MEM_PDC (unsigned long)PAGE0->mem_pdc +# define MEM_PDC (unsigned long)PAGE0.mem_pdc # define mem_pdc_call(args...) real32_call(MEM_PDC, args) #endif
@@ -1249,9 +1249,9 @@ int pdc_iodc_print(const unsigned char *str, unsigned count) print: spin_lock_irqsave(&pdc_lock, flags); - real32_call(PAGE0->mem_cons.iodc_io, - (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT, - PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers), + real32_call(PAGE0.mem_cons.iodc_io, + (unsigned long)PAGE0.mem_cons.hpa, ENTRY_IO_COUT, + PAGE0.mem_cons.spa, __pa(PAGE0.mem_cons.dp.layers), __pa(iodc_retbuf), 0, __pa(iodc_dbuf), i, 0); spin_unlock_irqrestore(&pdc_lock, flags);
@@ -1272,14 +1272,14 @@ int pdc_iodc_getc(void) unsigned long flags; /* Bail if no console input device. */ - if (!PAGE0->mem_kbd.iodc_io) + if (!PAGE0.mem_kbd.iodc_io) return 0; /* wait for a keyboard (rs232)-input */ spin_lock_irqsave(&pdc_lock, flags); - real32_call(PAGE0->mem_kbd.iodc_io, - (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN, - PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers), + real32_call(PAGE0.mem_kbd.iodc_io, + (unsigned long)PAGE0.mem_kbd.hpa, ENTRY_IO_CIN, + PAGE0.mem_kbd.spa, __pa(PAGE0.mem_kbd.dp.layers), __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0); ch = *iodc_dbuf;
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
index 7ab2f2a54400..13234c663e4b 100644
--- a/arch/parisc/kernel/inventory.c
+++ b/arch/parisc/kernel/inventory.c@@ -164,7 +164,7 @@ static void __init pagezero_memconfig(void) * should be done. */ - npages = (PAGE_ALIGN(PAGE0->imm_max_mem) >> PAGE_SHIFT); + npages = (PAGE_ALIGN(PAGE0.imm_max_mem) >> PAGE_SHIFT); set_pmem_entry(pmem_ranges,0UL,npages); npmem_ranges = 1; }
@@ -648,8 +648,8 @@ void __init do_device_inventory(void) struct resource res[3] = {0,}; unsigned int base; - base = ((unsigned long long) PAGE0->pad0[2] << 32) - | PAGE0->pad0[3]; /* SeaBIOS stored it here */ + base = ((unsigned long long) PAGE0.pad0[2] << 32) + | PAGE0.pad0[3]; /* SeaBIOS stored it here */ res[0].name = "fw_cfg"; res[0].start = base;
diff --git a/arch/parisc/kernel/kexec.c b/arch/parisc/kernel/kexec.c
index 5eb7f30edc1f..6b39b81a96da 100644
--- a/arch/parisc/kernel/kexec.c
+++ b/arch/parisc/kernel/kexec.c@@ -96,7 +96,7 @@ void machine_kexec(struct kimage *image) *(unsigned long *)(virt + kexec_cmdline_offset) = arch->cmdline; *(unsigned long *)(virt + kexec_initrd_start_offset) = arch->initrd_start; *(unsigned long *)(virt + kexec_initrd_end_offset) = arch->initrd_end; - *(unsigned long *)(virt + kexec_free_mem_offset) = PAGE0->mem_free; + *(unsigned long *)(virt + kexec_free_mem_offset) = PAGE0.mem_free; flush_cache_all(); flush_tlb_all();
diff --git a/arch/parisc/kernel/kexec_file.c b/arch/parisc/kernel/kexec_file.c
index 8c534204f0fd..619aeebc5800 100644
--- a/arch/parisc/kernel/kexec_file.c
+++ b/arch/parisc/kernel/kexec_file.c@@ -61,7 +61,7 @@ static void *elf_load(struct kimage *image, char *kernel_buf, kbuf.bufsz = kbuf.memsz = ALIGN(cmdline_len, 8); kbuf.buf_align = PAGE_SIZE; kbuf.top_down = false; - kbuf.buf_min = PAGE0->mem_free + PAGE_SIZE; + kbuf.buf_min = PAGE0.mem_free + PAGE_SIZE; kbuf.buf_max = kernel_load_addr; kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; ret = kexec_add_buffer(&kbuf);
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 2661cdd256ae..b635294184b9 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c@@ -218,8 +218,8 @@ static void pdc_console_init_force(void) ++pdc_console_initialized; /* If the console is duplex then copy the COUT parameters to CIN. */ - if (PAGE0->mem_cons.cl_class == CL_DUPLEX) - memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons)); + if (PAGE0.mem_cons.cl_class == CL_DUPLEX) + memcpy(&PAGE0.mem_kbd, &PAGE0.mem_cons, sizeof(PAGE0.mem_cons)); /* register the pdc console */ register_console(&pdc_cons);
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 1b6129e7d776..7872322336a5 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c@@ -234,7 +234,7 @@ void __init collect_boot_cpu_data(void) cr16_seed = get_cycles(); add_device_randomness(&cr16_seed, sizeof(cr16_seed)); - boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */ + boot_cpu_data.cpu_hz = 100 * PAGE0.mem_10msec; /* Hz of this PARISC */ /* get CPU-Model Information... */ #define p ((unsigned long *)&boot_cpu_data.pdc.model)
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index cceb09855e03..0168f7f83fdb 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c@@ -384,7 +384,7 @@ void __init start_parisc(void) struct pdc_coproc_cfg coproc_cfg; /* check QEMU/SeaBIOS marker in PAGE0 */ - running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0); + running_on_qemu = (memcmp(&PAGE0.pad0, "SeaBIOS", 8) == 0); cpunum = smp_processor_id();
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 9fb1e794831b..00283e41fc7f 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c@@ -237,10 +237,10 @@ void __init time_init(void) { unsigned long cr16_hz; - clocktick = (100 * PAGE0->mem_10msec) / HZ; + clocktick = (100 * PAGE0.mem_10msec) / HZ; start_cpu_itimer(); /* get CPU 0 started */ - cr16_hz = 100 * PAGE0->mem_10msec; /* Hz */ + cr16_hz = 100 * PAGE0.mem_10msec; /* Hz */ /* register as sched_clock source */ sched_clock_register(read_cr16_sched_clock, BITS_PER_LONG, cr16_hz);
@@ -277,7 +277,7 @@ static int __init init_cr16_clocksource(void) /* register at clocksource framework */ clocksource_register_hz(&clocksource_cr16, - 100 * PAGE0->mem_10msec); + 100 * PAGE0.mem_10msec); return 0; }
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 2769eb991f58..87abee841182 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S@@ -55,6 +55,9 @@ jiffies = jiffies_64; #endif SECTIONS { + . = __PAGE_OFFSET; + PAGE0 = .; + . = KERNEL_BINARY_TEXT_START; __init_begin = .;
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 3f7d6d5b56ac..733961eb25a1 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c@@ -283,7 +283,7 @@ static void __init setup_bootmem(void) #define PDC_CONSOLE_IO_IODC_SIZE 32768 - memblock_reserve(0UL, (unsigned long)(PAGE0->mem_free + + memblock_reserve(0UL, (unsigned long)(PAGE0.mem_free + PDC_CONSOLE_IO_IODC_SIZE)); memblock_reserve(__pa(KERNEL_BINARY_TEXT_START), (unsigned long)(_end - KERNEL_BINARY_TEXT_START));
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index e60690d38d67..9d4ccb8c75bd 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c@@ -1542,7 +1542,7 @@ static void sba_hw_init(struct sba_device *sba_dev) ** o reprogram serial port ** o unblock console output */ - if (PAGE0->mem_kbd.cl_class == CL_KEYBD) { + if (PAGE0.mem_kbd.cl_class == CL_KEYBD) { pdc_io_reset_devices(); }
@@ -1550,8 +1550,8 @@ static void sba_hw_init(struct sba_device *sba_dev) #if 0 -printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, - PAGE0->mem_boot.spa, PAGE0->mem_boot.pad, PAGE0->mem_boot.cl_class); +printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0.mem_boot.hpa, + PAGE0.mem_boot.spa, PAGE0.mem_boot.pad, PAGE0.mem_boot.cl_class); /* ** Need to deal with DMA from LAN.
@@ -1562,8 +1562,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, ** mem_boot hpa 0xf4008000 sba 0x0 pad 0x0 cl_class 0x1002 ** ARGH! invalid class. */ - if ((PAGE0->mem_boot.cl_class != CL_RANDOM) - && (PAGE0->mem_boot.cl_class != CL_SEQU)) { + if ((PAGE0.mem_boot.cl_class != CL_RANDOM) + && (PAGE0.mem_boot.cl_class != CL_SEQU)) { pdc_io_reset(); } #endif
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 1b451165311c..d5737d9fa8cf 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c@@ -395,7 +395,7 @@ static int __init sticonsole_init(void) pr_info("sticon: Initializing STI text console.\n"); console_lock(); err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, - PAGE0->mem_cons.cl_class != CL_DUPLEX); + PAGE0.mem_cons.cl_class != CL_DUPLEX); console_unlock(); return err;
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index f869b723494f..a6a6b5503ca1 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c@@ -966,7 +966,7 @@ static int __init sticore_pa_init(struct parisc_device *dev) if (!sti) sti = sti_try_rom_generic(hpa, hpa, NULL); if (!sti) - sti = sti_try_rom_generic(PAGE0->proc_sti, hpa, NULL); + sti = sti_try_rom_generic(PAGE0.proc_sti, hpa, NULL); if (!sti) return 1;