Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'parisc-for-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc architecture updates from Helge Deller:
"PA-RISC now has a native eBPF JIT compiler for 32- and 64-bit kernels,
the LED driver was rewritten to use the Linux LED framework and most
of the parisc bootup code was switched to use *_initcall() functions.

Summary:

- add eBPF JIT compiler for 32- and 64-bit kernel

- LCD/LED driver rewrite to utilize Linux LED subsystem

- switch to generic mmap top-down layout and brk randomization

- kernel startup cleanup by loading most drivers via arch_initcall()"

* tag 'parisc-for-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: (31 commits)
parisc: ccio-dma: Create private runway procfs root entry
parisc: chassis: Do not overwrite string on LCD display
parisc: led: Rewrite LED/LCD driver to utilizize Linux LED subsystem
parisc: led: Fix LAN receive and transmit LEDs
parisc: lasi: Initialize LASI driver via arch_initcall()
parisc: asp: Initialize asp driver via arch_initcall()
parisc: wax: Initialize wax driver via arch_initcall()
parisc: iosapic: Convert I/O Sapic driver to use arch_initcall()
parisc: sba_iommu: Convert SBA IOMMU driver to use arch_initcall()
parisc: led: Move register_led_regions() to late_initcall()
parisc: lba: Convert LBA PCI bus driver to use arch_initcall()
parisc: gsc: Convert GSC bus driver to use arch_initcall()
parisc: ccio: Convert CCIO driver to use arch_initcall()
parisc: eisa: Convert HP EISA bus driver to use arch_initcall()
parisc: hppb: Convert HP PB bus driver to use arch_initcall()
parisc: dino: Convert dino PCI bus driver to use arch_initcall()
parisc: Makefile: Adjust order in which drivers should be loaded
parisc: led: Reduce CPU overhead for disk & lan LED computation
parisc: Avoid ioremap() for same addresss in iosapic_register()
parisc: unaligned: Simplify 32-bit assembly in emulate_std()
...

+4041 -927
+1 -1
arch/parisc/Kbuild
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - obj-y += mm/ kernel/ math-emu/ 2 + obj-y += mm/ kernel/ math-emu/ net/ 3 3 4 4 # for cleaning 5 5 subdir- += boot
+19
arch/parisc/Kconfig
··· 49 49 select TTY # Needed for pdc_cons.c 50 50 select HAS_IOPORT if PCI || EISA 51 51 select HAVE_DEBUG_STACKOVERFLOW 52 + select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT 53 + select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT 54 + select HAVE_ARCH_MMAP_RND_BITS 52 55 select HAVE_ARCH_AUDITSYSCALL 53 56 select HAVE_ARCH_HASH 54 57 select HAVE_ARCH_JUMP_LABEL ··· 59 56 select HAVE_ARCH_KFENCE 60 57 select HAVE_ARCH_SECCOMP_FILTER 61 58 select HAVE_ARCH_TRACEHOOK 59 + select HAVE_EBPF_JIT 60 + select ARCH_WANT_DEFAULT_BPF_JIT 62 61 select HAVE_REGS_AND_STACK_ACCESS_API 63 62 select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU 64 63 select GENERIC_SCHED_CLOCK ··· 128 123 bool 129 124 depends on SMP 130 125 default y 126 + 127 + config ARCH_MMAP_RND_BITS_MIN 128 + default 18 if 64BIT 129 + default 8 130 + 131 + config ARCH_MMAP_RND_COMPAT_BITS_MIN 132 + default 8 133 + 134 + config ARCH_MMAP_RND_BITS_MAX 135 + default 24 if 64BIT 136 + default 17 137 + 138 + config ARCH_MMAP_RND_COMPAT_BITS_MAX 139 + default 17 131 140 132 141 # unless you want to implement ACPI on PA-RISC ... ;-) 133 142 config PM
+1 -1
arch/parisc/Kconfig.debug
··· 13 13 14 14 config TLB_PTLOCK 15 15 bool "Use page table locks in TLB fault handler" 16 - depends on SMP 16 + depends on DEBUG_KERNEL && SMP 17 17 default n 18 18 help 19 19 Select this option to enable page table locking in the TLB
+1 -2
arch/parisc/include/asm/elf.h
··· 163 163 164 164 /* Format for the Elf64 Function descriptor */ 165 165 typedef struct elf64_fdesc { 166 - __u64 dummy[2]; /* FIXME: nothing uses these, why waste 167 - * the space */ 166 + __u64 dummy[2]; /* used by 64-bit eBPF and tracing functions */ 168 167 __u64 addr; 169 168 __u64 gp; 170 169 } Elf64_Fdesc;
+5 -11
arch/parisc/include/asm/led.h
··· 11 11 #define LED1 0x02 12 12 #define LED0 0x01 /* bottom (or furthest left) LED */ 13 13 14 - #define LED_LAN_TX LED0 /* for LAN transmit activity */ 15 - #define LED_LAN_RCV LED1 /* for LAN receive activity */ 14 + #define LED_LAN_RCV LED0 /* for LAN receive activity */ 15 + #define LED_LAN_TX LED1 /* for LAN transmit activity */ 16 16 #define LED_DISK_IO LED2 /* for disk activity */ 17 17 #define LED_HEARTBEAT LED3 /* heartbeat */ 18 18 ··· 25 25 #define LED_CMD_REG_NONE 0 /* NULL == no addr for the cmd register */ 26 26 27 27 /* register_led_driver() */ 28 - int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg); 29 - 30 - /* registers the LED regions for procfs */ 31 - void __init register_led_regions(void); 28 + int register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg); 32 29 33 30 #ifdef CONFIG_CHASSIS_LCD_LED 34 31 /* writes a string to the LCD display (if possible on this h/w) */ 35 - int lcd_print(const char *str); 32 + void lcd_print(const char *str); 36 33 #else 37 - #define lcd_print(str) 34 + #define lcd_print(str) do { } while (0) 38 35 #endif 39 - 40 - /* main LED initialization function (uses PDC) */ 41 - int __init led_init(void); 42 36 43 37 #endif /* LED_H */
-17
arch/parisc/include/asm/machdep.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _PARISC_MACHDEP_H 3 - #define _PARISC_MACHDEP_H 4 - 5 - #include <linux/notifier.h> 6 - 7 - #define MACH_RESTART 1 8 - #define MACH_HALT 2 9 - #define MACH_POWER_ON 3 10 - #define MACH_POWER_OFF 4 11 - 12 - extern struct notifier_block *mach_notifier; 13 - extern void pa7300lc_init(void); 14 - 15 - extern void (*cpu_lpmc)(int, struct pt_regs *); 16 - 17 - #endif
-8
arch/parisc/include/asm/processor.h
··· 313 313 extern int show_cpuinfo (struct seq_file *m, void *v); 314 314 315 315 /* driver code in driver/parisc */ 316 - extern void gsc_init(void); 317 316 extern void processor_init(void); 318 - extern void ccio_init(void); 319 - extern void hppb_init(void); 320 - extern void dino_init(void); 321 - extern void iosapic_init(void); 322 - extern void lba_init(void); 323 - extern void sba_init(void); 324 - extern void parisc_eisa_init(void); 325 317 struct parisc_device; 326 318 struct resource; 327 319 extern void sba_distributed_lmmio(struct parisc_device *, struct resource *);
+1 -1
arch/parisc/include/asm/ropes.h
··· 252 252 ** fixup_irq is to initialize PCI IRQ line support and 253 253 ** virtualize pcidev->irq value. To be called by pci_fixup_bus(). 254 254 */ 255 - extern void *iosapic_register(unsigned long hpa); 255 + extern void *iosapic_register(unsigned long hpa, void __iomem *vaddr); 256 256 extern int iosapic_fixup_irq(void *obj, struct pci_dev *pcidev); 257 257 258 258 #define LBA_FUNC_ID 0x0000 /* function id */
-3
arch/parisc/include/asm/runway.h
··· 2 2 #ifndef ASM_PARISC_RUNWAY_H 3 3 #define ASM_PARISC_RUNWAY_H 4 4 5 - /* declared in arch/parisc/kernel/setup.c */ 6 - extern struct proc_dir_entry * proc_runway_root; 7 - 8 5 #define RUNWAY_STATUS 0x10 9 6 #define RUNWAY_DEBUG 0x40 10 7
+1 -1
arch/parisc/kernel/Makefile
··· 6 6 extra-y := vmlinux.lds 7 7 8 8 obj-y := head.o cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \ 9 - pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ 9 + syscall.o entry.o sys_parisc.o firmware.o \ 10 10 ptrace.o hardware.o inventory.o drivers.o alternative.o \ 11 11 signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ 12 12 process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
-51
arch/parisc/kernel/pa7300lc.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * linux/arch/parisc/kernel/pa7300lc.c 4 - * - PA7300LC-specific functions 5 - * 6 - * Copyright (C) 2000 Philipp Rumpf */ 7 - 8 - #include <linux/sched.h> 9 - #include <linux/sched/debug.h> 10 - #include <linux/smp.h> 11 - #include <linux/kernel.h> 12 - #include <asm/io.h> 13 - #include <asm/ptrace.h> 14 - #include <asm/machdep.h> 15 - 16 - /* CPU register indices */ 17 - 18 - #define MIOC_STATUS 0xf040 19 - #define MIOC_CONTROL 0xf080 20 - #define MDERRADD 0xf0e0 21 - #define DMAERR 0xf0e8 22 - #define DIOERR 0xf0ec 23 - #define HIDMAMEM 0xf0f4 24 - 25 - /* this returns the HPA of the CPU it was called on */ 26 - static u32 cpu_hpa(void) 27 - { 28 - return 0xfffb0000; 29 - } 30 - 31 - static void pa7300lc_lpmc(int code, struct pt_regs *regs) 32 - { 33 - u32 hpa; 34 - printk(KERN_WARNING "LPMC on CPU %d\n", smp_processor_id()); 35 - 36 - show_regs(regs); 37 - 38 - hpa = cpu_hpa(); 39 - printk(KERN_WARNING 40 - "MIOC_CONTROL %08x\n" "MIOC_STATUS %08x\n" 41 - "MDERRADD %08x\n" "DMAERR %08x\n" 42 - "DIOERR %08x\n" "HIDMAMEM %08x\n", 43 - gsc_readl(hpa+MIOC_CONTROL), gsc_readl(hpa+MIOC_STATUS), 44 - gsc_readl(hpa+MDERRADD), gsc_readl(hpa+DMAERR), 45 - gsc_readl(hpa+DIOERR), gsc_readl(hpa+HIDMAMEM)); 46 - } 47 - 48 - void pa7300lc_init(void) 49 - { 50 - cpu_lpmc = pa7300lc_lpmc; 51 - }
+6
arch/parisc/kernel/pdc_chassis.c
··· 31 31 #include <asm/processor.h> 32 32 #include <asm/pdc.h> 33 33 #include <asm/pdcpat.h> 34 + #include <asm/led.h> 34 35 35 36 #define PDC_CHASSIS_VER "0.05" 36 37 ··· 235 234 } else retval = -1; 236 235 #endif /* CONFIG_64BIT */ 237 236 } /* if (pdc_chassis_enabled) */ 237 + 238 + /* if system has LCD display, update current string */ 239 + if (retval != -1 && IS_ENABLED(CONFIG_CHASSIS_LCD_LED)) 240 + lcd_print(NULL); 241 + 238 242 #endif /* CONFIG_PDC_CHASSIS */ 239 243 return retval; 240 244 }
-20
arch/parisc/kernel/process.c
··· 97 97 98 98 } 99 99 100 - void (*chassis_power_off)(void); 101 - 102 100 /* 103 101 * This routine is called from sys_reboot to actually turn off the 104 102 * machine 105 103 */ 106 104 void machine_power_off(void) 107 105 { 108 - /* If there is a registered power off handler, call it. */ 109 - if (chassis_power_off) 110 - chassis_power_off(); 111 - 112 106 /* Put the soft power button back under hardware control. 113 107 * If the user had already pressed the power button, the 114 108 * following call will immediately power off. */ ··· 277 283 return ip; 278 284 } while (count++ < MAX_UNWIND_ENTRIES); 279 285 return 0; 280 - } 281 - 282 - static inline unsigned long brk_rnd(void) 283 - { 284 - return (get_random_u32() & BRK_RND_MASK) << PAGE_SHIFT; 285 - } 286 - 287 - unsigned long arch_randomize_brk(struct mm_struct *mm) 288 - { 289 - unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); 290 - 291 - if (ret < mm->brk) 292 - return mm->brk; 293 - return ret; 294 286 }
+10 -3
arch/parisc/kernel/processor.c
··· 378 378 show_cpuinfo (struct seq_file *m, void *v) 379 379 { 380 380 unsigned long cpu; 381 + char cpu_name[60], *p; 382 + 383 + /* strip PA path from CPU name to not confuse lscpu */ 384 + strlcpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name)); 385 + p = strrchr(cpu_name, '['); 386 + if (p) 387 + *(--p) = 0; 381 388 382 389 for_each_online_cpu(cpu) { 383 - const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); 384 390 #ifdef CONFIG_SMP 391 + const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); 392 + 385 393 if (0 == cpuinfo->hpa) 386 394 continue; 387 395 #endif ··· 434 426 435 427 seq_printf(m, "model\t\t: %s - %s\n", 436 428 boot_cpu_data.pdc.sys_model_name, 437 - cpuinfo->dev ? 438 - cpuinfo->dev->name : "Unknown"); 429 + cpu_name); 439 430 440 431 seq_printf(m, "hversion\t: 0x%08x\n" 441 432 "sversion\t: 0x%08x\n",
-49
arch/parisc/kernel/setup.c
··· 31 31 #include <asm/sections.h> 32 32 #include <asm/pdc.h> 33 33 #include <asm/led.h> 34 - #include <asm/machdep.h> /* for pa7300lc_init() proto */ 35 34 #include <asm/pdc_chassis.h> 36 35 #include <asm/io.h> 37 36 #include <asm/setup.h> ··· 92 93 "the PA-RISC 1.1 or 2.0 architecture specification.\n"); 93 94 94 95 case pcxl2: 95 - pa7300lc_init(); 96 - break; 97 96 default: 98 97 break; 99 98 } ··· 142 145 do_memory_inventory(); /* probe for physical memory */ 143 146 parisc_cache_init(); 144 147 paging_init(); 145 - 146 - #ifdef CONFIG_CHASSIS_LCD_LED 147 - /* initialize the LCD/LED after boot_cpu_data is available ! */ 148 - led_init(); /* LCD/LED initialization */ 149 - #endif 150 148 151 149 #ifdef CONFIG_PA11 152 150 dma_ops_init(); ··· 273 281 274 282 apply_alternatives_all(); 275 283 parisc_setup_cache_timing(); 276 - 277 - /* These are in a non-obvious order, will fix when we have an iotree */ 278 - #if defined(CONFIG_IOSAPIC) 279 - iosapic_init(); 280 - #endif 281 - #if defined(CONFIG_IOMMU_SBA) 282 - sba_init(); 283 - #endif 284 - #if defined(CONFIG_PCI_LBA) 285 - lba_init(); 286 - #endif 287 - 288 - /* CCIO before any potential subdevices */ 289 - #if defined(CONFIG_IOMMU_CCIO) 290 - ccio_init(); 291 - #endif 292 - 293 - /* 294 - * Need to register Asp & Wax before the EISA adapters for the IRQ 295 - * regions. EISA must come before PCI to be sure it gets IRQ region 296 - * 0. 297 - */ 298 - #if defined(CONFIG_GSC_LASI) || defined(CONFIG_GSC_WAX) 299 - gsc_init(); 300 - #endif 301 - #ifdef CONFIG_EISA 302 - parisc_eisa_init(); 303 - #endif 304 - 305 - #if defined(CONFIG_HPPB) 306 - hppb_init(); 307 - #endif 308 - 309 - #if defined(CONFIG_GSC_DINO) 310 - dino_init(); 311 - #endif 312 - 313 - #ifdef CONFIG_CHASSIS_LCD_LED 314 - register_led_regions(); /* register LED port info in procfs */ 315 - #endif 316 - 317 284 return 0; 318 285 } 319 286 arch_initcall(parisc_init);
+1 -53
arch/parisc/kernel/sys_parisc.c
··· 161 161 } 162 162 163 163 info.flags = 0; 164 - info.low_limit = mm->mmap_legacy_base; 164 + info.low_limit = mm->mmap_base; 165 165 info.high_limit = mmap_upper_limit(NULL); 166 166 return vm_unmapped_area(&info); 167 167 } ··· 180 180 return arch_get_unmapped_area_common(filp, 181 181 addr, len, pgoff, flags, DOWN); 182 182 } 183 - 184 - static int mmap_is_legacy(void) 185 - { 186 - if (current->personality & ADDR_COMPAT_LAYOUT) 187 - return 1; 188 - 189 - /* parisc stack always grows up - so a unlimited stack should 190 - * not be an indicator to use the legacy memory layout. 191 - * if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) 192 - * return 1; 193 - */ 194 - 195 - return sysctl_legacy_va_layout; 196 - } 197 - 198 - static unsigned long mmap_rnd(void) 199 - { 200 - unsigned long rnd = 0; 201 - 202 - if (current->flags & PF_RANDOMIZE) 203 - rnd = get_random_u32() & MMAP_RND_MASK; 204 - 205 - return rnd << PAGE_SHIFT; 206 - } 207 - 208 - unsigned long arch_mmap_rnd(void) 209 - { 210 - return (get_random_u32() & MMAP_RND_MASK) << PAGE_SHIFT; 211 - } 212 - 213 - static unsigned long mmap_legacy_base(void) 214 - { 215 - return TASK_UNMAPPED_BASE + mmap_rnd(); 216 - } 217 - 218 - /* 219 - * This function, called very early during the creation of a new 220 - * process VM image, sets up which VM layout function to use: 221 - */ 222 - void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack) 223 - { 224 - mm->mmap_legacy_base = mmap_legacy_base(); 225 - mm->mmap_base = mmap_upper_limit(rlim_stack); 226 - 227 - if (mmap_is_legacy()) { 228 - mm->mmap_base = mm->mmap_legacy_base; 229 - mm->get_unmapped_area = arch_get_unmapped_area; 230 - } else { 231 - mm->get_unmapped_area = arch_get_unmapped_area_topdown; 232 - } 233 - } 234 - 235 183 236 184 asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, 237 185 unsigned long prot, unsigned long flags, unsigned long fd,
+1 -4
arch/parisc/kernel/traps.c
··· 335 335 show_regs(regs); 336 336 } 337 337 338 - void (*cpu_lpmc) (int code, struct pt_regs *regs) __read_mostly = default_trap; 339 - 340 - 341 338 static void transfer_pim_to_trap_frame(struct pt_regs *regs) 342 339 { 343 340 register int i; ··· 554 557 555 558 flush_cache_all(); 556 559 flush_tlb_all(); 557 - cpu_lpmc(5, regs); 560 + default_trap(code, regs); 558 561 return; 559 562 560 563 case PARISC_ITLB_TRAP:
+12 -13
arch/parisc/kernel/unaligned.c
··· 338 338 : "r19", "r20", "r21", "r22", "r1" ); 339 339 #else 340 340 { 341 - unsigned long valh = (val >> 32), vall = (val & 0xffffffffl); 342 341 __asm__ __volatile__ ( 343 - " mtsp %4, %%sr1\n" 344 - " zdep %2, 29, 2, %%r19\n" 345 - " dep %%r0, 31, 2, %3\n" 342 + " mtsp %3, %%sr1\n" 343 + " zdep %R1, 29, 2, %%r19\n" 344 + " dep %%r0, 31, 2, %2\n" 346 345 " mtsar %%r19\n" 347 346 " zvdepi -2, 32, %%r19\n" 348 - "1: ldw 0(%%sr1,%3),%%r20\n" 349 - "2: ldw 8(%%sr1,%3),%%r21\n" 350 - " vshd %1, %2, %%r1\n" 347 + "1: ldw 0(%%sr1,%2),%%r20\n" 348 + "2: ldw 8(%%sr1,%2),%%r21\n" 349 + " vshd %1, %R1, %%r1\n" 351 350 " vshd %%r0, %1, %1\n" 352 - " vshd %2, %%r0, %2\n" 351 + " vshd %R1, %%r0, %R1\n" 353 352 " and %%r20, %%r19, %%r20\n" 354 353 " andcm %%r21, %%r19, %%r21\n" 355 354 " or %1, %%r20, %1\n" 356 - " or %2, %%r21, %2\n" 357 - "3: stw %1,0(%%sr1,%3)\n" 358 - "4: stw %%r1,4(%%sr1,%3)\n" 359 - "5: stw %2,8(%%sr1,%3)\n" 355 + " or %R1, %%r21, %R1\n" 356 + "3: stw %1,0(%%sr1,%2)\n" 357 + "4: stw %%r1,4(%%sr1,%2)\n" 358 + "5: stw %R1,8(%%sr1,%2)\n" 360 359 "6: \n" 361 360 ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 6b) 362 361 ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 6b) ··· 363 364 ASM_EXCEPTIONTABLE_ENTRY_EFAULT(4b, 6b) 364 365 ASM_EXCEPTIONTABLE_ENTRY_EFAULT(5b, 6b) 365 366 : "+r" (ret) 366 - : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr) 367 + : "r" (val), "r" (regs->ior), "r" (regs->isr) 367 368 : "r19", "r20", "r21", "r1" ); 368 369 } 369 370 #endif
+9
arch/parisc/net/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + 3 + obj-$(CONFIG_BPF_JIT) += bpf_jit_core.o 4 + 5 + ifeq ($(CONFIG_64BIT),y) 6 + obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o 7 + else 8 + obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o 9 + endif
+479
arch/parisc/net/bpf_jit.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Common functionality for PARISC32 and PARISC64 BPF JIT compilers 4 + * 5 + * Copyright (c) 2023 Helge Deller <deller@gmx.de> 6 + * 7 + */ 8 + 9 + #ifndef _BPF_JIT_H 10 + #define _BPF_JIT_H 11 + 12 + #include <linux/bpf.h> 13 + #include <linux/filter.h> 14 + #include <asm/cacheflush.h> 15 + 16 + #define HPPA_JIT_DEBUG 0 17 + #define HPPA_JIT_REBOOT 0 18 + #define HPPA_JIT_DUMP 0 19 + 20 + #define OPTIMIZE_HPPA 1 /* enable some asm optimizations */ 21 + // echo 1 > /proc/sys/net/core/bpf_jit_enable 22 + 23 + #define HPPA_R(nr) nr /* use HPPA register #nr */ 24 + 25 + enum { 26 + HPPA_REG_ZERO = 0, /* The constant value 0 */ 27 + HPPA_REG_R1 = 1, /* used for addil */ 28 + HPPA_REG_RP = 2, /* Return address */ 29 + 30 + HPPA_REG_ARG7 = 19, /* ARG4-7 used in 64-bit ABI */ 31 + HPPA_REG_ARG6 = 20, 32 + HPPA_REG_ARG5 = 21, 33 + HPPA_REG_ARG4 = 22, 34 + 35 + HPPA_REG_ARG3 = 23, /* ARG0-3 in 32- and 64-bit ABI */ 36 + HPPA_REG_ARG2 = 24, 37 + HPPA_REG_ARG1 = 25, 38 + HPPA_REG_ARG0 = 26, 39 + HPPA_REG_GP = 27, /* Global pointer */ 40 + HPPA_REG_RET0 = 28, /* Return value, HI in 32-bit */ 41 + HPPA_REG_RET1 = 29, /* Return value, LOW in 32-bit */ 42 + HPPA_REG_SP = 30, /* Stack pointer */ 43 + HPPA_REG_R31 = 31, 44 + 45 + #ifdef CONFIG_64BIT 46 + HPPA_REG_TCC = 3, 47 + HPPA_REG_TCC_SAVED = 4, 48 + HPPA_REG_TCC_IN_INIT = HPPA_REG_R31, 49 + #else 50 + HPPA_REG_TCC = 18, 51 + HPPA_REG_TCC_SAVED = 17, 52 + HPPA_REG_TCC_IN_INIT = HPPA_REG_R31, 53 + #endif 54 + 55 + HPPA_REG_T0 = HPPA_REG_R1, /* Temporaries */ 56 + HPPA_REG_T1 = HPPA_REG_R31, 57 + HPPA_REG_T2 = HPPA_REG_ARG4, 58 + #ifndef CONFIG_64BIT 59 + HPPA_REG_T3 = HPPA_REG_ARG5, /* not used in 64-bit */ 60 + HPPA_REG_T4 = HPPA_REG_ARG6, 61 + HPPA_REG_T5 = HPPA_REG_ARG7, 62 + #endif 63 + }; 64 + 65 + struct hppa_jit_context { 66 + struct bpf_prog *prog; 67 + u32 *insns; /* HPPA insns */ 68 + int ninsns; 69 + int reg_seen_collect; 70 + int reg_seen; 71 + int body_len; 72 + int epilogue_offset; 73 + int prologue_len; 74 + int *offset; /* BPF to HPPA */ 75 + }; 76 + 77 + #define REG_SET_SEEN(ctx, nr) { if (ctx->reg_seen_collect) ctx->reg_seen |= BIT(nr); } 78 + #define REG_SET_SEEN_ALL(ctx) { if (ctx->reg_seen_collect) ctx->reg_seen = -1; } 79 + #define REG_FORCE_SEEN(ctx, nr) { ctx->reg_seen |= BIT(nr); } 80 + #define REG_WAS_SEEN(ctx, nr) (ctx->reg_seen & BIT(nr)) 81 + #define REG_ALL_SEEN(ctx) (ctx->reg_seen == -1) 82 + 83 + #define HPPA_INSN_SIZE 4 /* bytes per HPPA asm instruction */ 84 + #define REG_SIZE REG_SZ /* bytes per native "long" word */ 85 + 86 + /* subtract hppa displacement on branches which is .+8 */ 87 + #define HPPA_BRANCH_DISPLACEMENT 2 /* instructions */ 88 + 89 + /* asm statement indicator to execute delay slot */ 90 + #define EXEC_NEXT_INSTR 0 91 + #define NOP_NEXT_INSTR 1 92 + 93 + #define im11(val) (((u32)(val)) & 0x07ff) 94 + 95 + #define hppa_ldil(addr, reg) \ 96 + hppa_t5_insn(0x08, reg, ((u32)(addr)) >> 11) /* ldil im21,reg */ 97 + #define hppa_addil(addr, reg) \ 98 + hppa_t5_insn(0x0a, reg, ((u32)(addr)) >> 11) /* addil im21,reg -> result in gr1 */ 99 + #define hppa_ldo(im14, reg, target) \ 100 + hppa_t1_insn(0x0d, reg, target, im14) /* ldo val14(reg),target */ 101 + #define hppa_ldi(im14, reg) \ 102 + hppa_ldo(im14, HPPA_REG_ZERO, reg) /* ldi val14,reg */ 103 + #define hppa_or(reg1, reg2, target) \ 104 + hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x09, target) /* or reg1,reg2,target */ 105 + #define hppa_or_cond(reg1, reg2, cond, f, target) \ 106 + hppa_t6_insn(0x02, reg2, reg1, cond, f, 0x09, target) 107 + #define hppa_and(reg1, reg2, target) \ 108 + hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x08, target) /* and reg1,reg2,target */ 109 + #define hppa_and_cond(reg1, reg2, cond, f, target) \ 110 + hppa_t6_insn(0x02, reg2, reg1, cond, f, 0x08, target) 111 + #define hppa_xor(reg1, reg2, target) \ 112 + hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x0a, target) /* xor reg1,reg2,target */ 113 + #define hppa_add(reg1, reg2, target) \ 114 + hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x18, target) /* add reg1,reg2,target */ 115 + #define hppa_addc(reg1, reg2, target) \ 116 + hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x1c, target) /* add,c reg1,reg2,target */ 117 + #define hppa_sub(reg1, reg2, target) \ 118 + hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x10, target) /* sub reg1,reg2,target */ 119 + #define hppa_subb(reg1, reg2, target) \ 120 + hppa_t6_insn(0x02, reg2, reg1, 0, 0, 0x14, target) /* sub,b reg1,reg2,target */ 121 + #define hppa_nop() \ 122 + hppa_or(0,0,0) /* nop: or 0,0,0 */ 123 + #define hppa_addi(val11, reg, target) \ 124 + hppa_t7_insn(0x2d, reg, target, val11) /* addi im11,reg,target */ 125 + #define hppa_subi(val11, reg, target) \ 126 + hppa_t7_insn(0x25, reg, target, val11) /* subi im11,reg,target */ 127 + #define hppa_copy(reg, target) \ 128 + hppa_or(reg, HPPA_REG_ZERO, target) /* copy reg,target */ 129 + #define hppa_ldw(val14, reg, target) \ 130 + hppa_t1_insn(0x12, reg, target, val14) /* ldw im14(reg),target */ 131 + #define hppa_ldb(val14, reg, target) \ 132 + hppa_t1_insn(0x10, reg, target, val14) /* ldb im14(reg),target */ 133 + #define hppa_ldh(val14, reg, target) \ 134 + hppa_t1_insn(0x11, reg, target, val14) /* ldh im14(reg),target */ 135 + #define hppa_stw(reg, val14, base) \ 136 + hppa_t1_insn(0x1a, base, reg, val14) /* stw reg,im14(base) */ 137 + #define hppa_stb(reg, val14, base) \ 138 + hppa_t1_insn(0x18, base, reg, val14) /* stb reg,im14(base) */ 139 + #define hppa_sth(reg, val14, base) \ 140 + hppa_t1_insn(0x19, base, reg, val14) /* sth reg,im14(base) */ 141 + #define hppa_stwma(reg, val14, base) \ 142 + hppa_t1_insn(0x1b, base, reg, val14) /* stw,ma reg,im14(base) */ 143 + #define hppa_bv(reg, base, nop) \ 144 + hppa_t11_insn(0x3a, base, reg, 0x06, 0, nop) /* bv(,n) reg(base) */ 145 + #define hppa_be(offset, base) \ 146 + hppa_t12_insn(0x38, base, offset, 0x00, 1) /* be,n offset(0,base) */ 147 + #define hppa_be_l(offset, base, nop) \ 148 + hppa_t12_insn(0x39, base, offset, 0x00, nop) /* ble(,nop) offset(0,base) */ 149 + #define hppa_mtctl(reg, cr) \ 150 + hppa_t21_insn(0x00, cr, reg, 0xc2, 0) /* mtctl reg,cr */ 151 + #define hppa_mtsar(reg) \ 152 + hppa_mtctl(reg, 11) /* mtsar reg */ 153 + #define hppa_zdep(r, p, len, target) \ 154 + hppa_t10_insn(0x35, target, r, 0, 2, p, len) /* zdep r,a,b,t */ 155 + #define hppa_shl(r, len, target) \ 156 + hppa_zdep(r, len, len, lo(rd)) 157 + #define hppa_depwz(r, p, len, target) \ 158 + hppa_t10_insn(0x35, target, r, 0, 3, 31-(p), 32-(len)) /* depw,z r,p,len,ret1 */ 159 + #define hppa_depwz_sar(reg, target) \ 160 + hppa_t1_insn(0x35, target, reg, 0) /* depw,z reg,sar,32,target */ 161 + #define hppa_shrpw_sar(reg, target) \ 162 + hppa_t10_insn(0x34, reg, 0, 0, 0, 0, target) /* shrpw r0,reg,sar,target */ 163 + #define hppa_shrpw(r1, r2, p, target) \ 164 + hppa_t10_insn(0x34, r2, r1, 0, 2, 31-(p), target) /* shrpw r1,r2,p,target */ 165 + #define hppa_shd(r1, r2, p, target) \ 166 + hppa_t10_insn(0x34, r2, r1, 0, 2, 31-(p), target) /* shrpw r1,r2,p,tarfer */ 167 + #define hppa_extrws_sar(reg, target) \ 168 + hppa_t10_insn(0x34, reg, target, 0, 5, 0, 0) /* extrw,s reg,sar,32,ret0 */ 169 + #define hppa_extrws(reg, p, len, target) \ 170 + hppa_t10_insn(0x34, reg, target, 0, 7, p, len) /* extrw,s reg,p,len,target */ 171 + #define hppa_extru(r, p, len, target) \ 172 + hppa_t10_insn(0x34, r, target, 0, 6, p, 32-(len)) 173 + #define hppa_shr(r, len, target) \ 174 + hppa_extru(r, 31-(len), 32-(len), target) 175 + #define hppa_bl(imm17, rp) \ 176 + hppa_t12_insn(0x3a, rp, imm17, 0x00, 1) /* bl,n target_addr,rp */ 177 + #define hppa_sh2add(r1, r2, target) \ 178 + hppa_t6_insn(0x02, r2, r1, 0, 0, 0x1a, target) /* sh2add r1,r2,target */ 179 + 180 + #define hppa_combt(r1, r2, target_addr, condition, nop) \ 181 + hppa_t11_insn(IS_ENABLED(CONFIG_64BIT) ? 0x27 : 0x20, \ 182 + r2, r1, condition, target_addr, nop) /* combt,cond,n r1,r2,addr */ 183 + #define hppa_beq(r1, r2, target_addr) \ 184 + hppa_combt(r1, r2, target_addr, 1, NOP_NEXT_INSTR) 185 + #define hppa_blt(r1, r2, target_addr) \ 186 + hppa_combt(r1, r2, target_addr, 2, NOP_NEXT_INSTR) 187 + #define hppa_ble(r1, r2, target_addr) \ 188 + hppa_combt(r1, r2, target_addr, 3, NOP_NEXT_INSTR) 189 + #define hppa_bltu(r1, r2, target_addr) \ 190 + hppa_combt(r1, r2, target_addr, 4, NOP_NEXT_INSTR) 191 + #define hppa_bleu(r1, r2, target_addr) \ 192 + hppa_combt(r1, r2, target_addr, 5, NOP_NEXT_INSTR) 193 + 194 + #define hppa_combf(r1, r2, target_addr, condition, nop) \ 195 + hppa_t11_insn(IS_ENABLED(CONFIG_64BIT) ? 0x2f : 0x22, \ 196 + r2, r1, condition, target_addr, nop) /* combf,cond,n r1,r2,addr */ 197 + #define hppa_bne(r1, r2, target_addr) \ 198 + hppa_combf(r1, r2, target_addr, 1, NOP_NEXT_INSTR) 199 + #define hppa_bge(r1, r2, target_addr) \ 200 + hppa_combf(r1, r2, target_addr, 2, NOP_NEXT_INSTR) 201 + #define hppa_bgt(r1, r2, target_addr) \ 202 + hppa_combf(r1, r2, target_addr, 3, NOP_NEXT_INSTR) 203 + #define hppa_bgeu(r1, r2, target_addr) \ 204 + hppa_combf(r1, r2, target_addr, 4, NOP_NEXT_INSTR) 205 + #define hppa_bgtu(r1, r2, target_addr) \ 206 + hppa_combf(r1, r2, target_addr, 5, NOP_NEXT_INSTR) 207 + 208 + /* 64-bit instructions */ 209 + #ifdef CONFIG_64BIT 210 + #define hppa64_ldd_reg(reg, b, target) \ 211 + hppa_t10_insn(0x03, b, reg, 0, 0, 3<<1, target) 212 + #define hppa64_ldd_im5(im5, b, target) \ 213 + hppa_t10_insn(0x03, b, low_sign_unext(im5,5), 0, 1<<2, 3<<1, target) 214 + #define hppa64_ldd_im16(im16, b, target) \ 215 + hppa_t10_insn(0x14, b, target, 0, 0, 0, 0) | re_assemble_16(im16) 216 + #define hppa64_std_im5(src, im5, b) \ 217 + hppa_t10_insn(0x03, b, src, 0, 1<<2, 0xB<<1, low_sign_unext(im5,5)) 218 + #define hppa64_std_im16(src, im16, b) \ 219 + hppa_t10_insn(0x1c, b, src, 0, 0, 0, 0) | re_assemble_16(im16) 220 + #define hppa64_bl_long(offs22) \ 221 + hppa_t12_L_insn(0x3a, offs22, 1) 222 + #define hppa64_mtsarcm(reg) \ 223 + hppa_t21_insn(0x00, 11, reg, 0xc6, 0) 224 + #define hppa64_shrpd_sar(reg, target) \ 225 + hppa_t10_insn(0x34, reg, 0, 0, 0, 1<<4, target) 226 + #define hppa64_shladd(r1, sa, r2, target) \ 227 + hppa_t6_insn(0x02, r2, r1, 0, 0, 1<<4|1<<3|sa, target) 228 + #define hppa64_depdz_sar(reg, target) \ 229 + hppa_t21_insn(0x35, target, reg, 3<<3, 0) 230 + #define hppa_extrd_sar(reg, target, se) \ 231 + hppa_t10_insn(0x34, reg, target, 0, 0, 0, 0) | 2<<11 | (se&1)<<10 | 1<<9 | 1<<8 232 + #define hppa64_bve_l_rp(base) \ 233 + (0x3a << 26) | (base << 21) | 0xf000 234 + #define hppa64_permh_3210(r, target) \ 235 + (0x3e << 26) | (r << 21) | (r << 16) | (target) | 0x00006900 236 + #define hppa64_hshl(r, sa, target) \ 237 + (0x3e << 26) | (0 << 21) | (r << 16) | (sa << 6) | (target) | 0x00008800 238 + #define hppa64_hshr_u(r, sa, target) \ 239 + (0x3e << 26) | (r << 21) | (0 << 16) | (sa << 6) | (target) | 0x0000c800 240 + #endif 241 + 242 + struct hppa_jit_data { 243 + struct bpf_binary_header *header; 244 + u8 *image; 245 + struct hppa_jit_context ctx; 246 + }; 247 + 248 + static inline void bpf_fill_ill_insns(void *area, unsigned int size) 249 + { 250 + memset(area, 0, size); 251 + } 252 + 253 + static inline void bpf_flush_icache(void *start, void *end) 254 + { 255 + flush_icache_range((unsigned long)start, (unsigned long)end); 256 + } 257 + 258 + /* Emit a 4-byte HPPA instruction. */ 259 + static inline void emit(const u32 insn, struct hppa_jit_context *ctx) 260 + { 261 + if (ctx->insns) { 262 + ctx->insns[ctx->ninsns] = insn; 263 + } 264 + 265 + ctx->ninsns++; 266 + } 267 + 268 + static inline int epilogue_offset(struct hppa_jit_context *ctx) 269 + { 270 + int to = ctx->epilogue_offset, from = ctx->ninsns; 271 + 272 + return (to - from); 273 + } 274 + 275 + /* Return -1 or inverted cond. */ 276 + static inline int invert_bpf_cond(u8 cond) 277 + { 278 + switch (cond) { 279 + case BPF_JEQ: 280 + return BPF_JNE; 281 + case BPF_JGT: 282 + return BPF_JLE; 283 + case BPF_JLT: 284 + return BPF_JGE; 285 + case BPF_JGE: 286 + return BPF_JLT; 287 + case BPF_JLE: 288 + return BPF_JGT; 289 + case BPF_JNE: 290 + return BPF_JEQ; 291 + case BPF_JSGT: 292 + return BPF_JSLE; 293 + case BPF_JSLT: 294 + return BPF_JSGE; 295 + case BPF_JSGE: 296 + return BPF_JSLT; 297 + case BPF_JSLE: 298 + return BPF_JSGT; 299 + } 300 + return -1; 301 + } 302 + 303 + 304 + static inline signed long hppa_offset(int insn, int off, struct hppa_jit_context *ctx) 305 + { 306 + signed long from, to; 307 + 308 + off++; /* BPF branch is from PC+1 */ 309 + from = (insn > 0) ? ctx->offset[insn - 1] : 0; 310 + to = (insn + off > 0) ? ctx->offset[insn + off - 1] : 0; 311 + return (to - from); 312 + } 313 + 314 + /* does the signed value fits into a given number of bits ? */ 315 + static inline int check_bits_int(signed long val, int bits) 316 + { 317 + return ((val >= 0) && ((val >> bits) == 0)) || 318 + ((val < 0) && (((~((u32)val)) >> (bits-1)) == 0)); 319 + } 320 + 321 + /* can the signed value be used in relative code ? */ 322 + static inline int relative_bits_ok(signed long val, int bits) 323 + { 324 + return ((val >= 0) && (val < (1UL << (bits-1)))) || /* XXX */ 325 + ((val < 0) && (((~((unsigned long)val)) >> (bits-1)) == 0) 326 + && (val & (1UL << (bits-1)))); 327 + } 328 + 329 + /* can the signed value be used in relative branches ? */ 330 + static inline int relative_branch_ok(signed long val, int bits) 331 + { 332 + return ((val >= 0) && (val < (1UL << (bits-2)))) || /* XXX */ 333 + ((val < 0) && (((~((unsigned long)val)) < (1UL << (bits-2)))) 334 + && (val & (1UL << (bits-1)))); 335 + } 336 + 337 + 338 + #define is_5b_int(val) check_bits_int(val, 5) 339 + 340 + static inline unsigned sign_unext(unsigned x, unsigned len) 341 + { 342 + unsigned len_ones; 343 + 344 + len_ones = (1 << len) - 1; 345 + return x & len_ones; 346 + } 347 + 348 + static inline unsigned low_sign_unext(unsigned x, unsigned len) 349 + { 350 + unsigned temp; 351 + unsigned sign; 352 + 353 + sign = (x >> (len-1)) & 1; 354 + temp = sign_unext (x, len-1); 355 + return (temp << 1) | sign; 356 + } 357 + 358 + static inline unsigned re_assemble_12(unsigned as12) 359 + { 360 + return (( (as12 & 0x800) >> 11) 361 + | ((as12 & 0x400) >> (10 - 2)) 362 + | ((as12 & 0x3ff) << (1 + 2))); 363 + } 364 + 365 + static inline unsigned re_assemble_14(unsigned as14) 366 + { 367 + return (( (as14 & 0x1fff) << 1) 368 + | ((as14 & 0x2000) >> 13)); 369 + } 370 + 371 + #ifdef CONFIG_64BIT 372 + static inline unsigned re_assemble_16(unsigned as16) 373 + { 374 + unsigned s, t; 375 + 376 + /* Unusual 16-bit encoding, for wide mode only. */ 377 + t = (as16 << 1) & 0xffff; 378 + s = (as16 & 0x8000); 379 + return (t ^ s ^ (s >> 1)) | (s >> 15); 380 + } 381 + #endif 382 + 383 + static inline unsigned re_assemble_17(unsigned as17) 384 + { 385 + return (( (as17 & 0x10000) >> 16) 386 + | ((as17 & 0x0f800) << (16 - 11)) 387 + | ((as17 & 0x00400) >> (10 - 2)) 388 + | ((as17 & 0x003ff) << (1 + 2))); 389 + } 390 + 391 + static inline unsigned re_assemble_21(unsigned as21) 392 + { 393 + return (( (as21 & 0x100000) >> 20) 394 + | ((as21 & 0x0ffe00) >> 8) 395 + | ((as21 & 0x000180) << 7) 396 + | ((as21 & 0x00007c) << 14) 397 + | ((as21 & 0x000003) << 12)); 398 + } 399 + 400 + static inline unsigned re_assemble_22(unsigned as22) 401 + { 402 + return (( (as22 & 0x200000) >> 21) 403 + | ((as22 & 0x1f0000) << (21 - 16)) 404 + | ((as22 & 0x00f800) << (16 - 11)) 405 + | ((as22 & 0x000400) >> (10 - 2)) 406 + | ((as22 & 0x0003ff) << (1 + 2))); 407 + } 408 + 409 + /* Various HPPA instruction formats. */ 410 + /* see https://parisc.wiki.kernel.org/images-parisc/6/68/Pa11_acd.pdf, appendix C */ 411 + 412 + static inline u32 hppa_t1_insn(u8 opcode, u8 b, u8 r, s16 im14) 413 + { 414 + return ((opcode << 26) | (b << 21) | (r << 16) | re_assemble_14(im14)); 415 + } 416 + 417 + static inline u32 hppa_t5_insn(u8 opcode, u8 tr, u32 val21) 418 + { 419 + return ((opcode << 26) | (tr << 21) | re_assemble_21(val21)); 420 + } 421 + 422 + static inline u32 hppa_t6_insn(u8 opcode, u8 r2, u8 r1, u8 c, u8 f, u8 ext6, u16 t) 423 + { 424 + return ((opcode << 26) | (r2 << 21) | (r1 << 16) | (c << 13) | (f << 12) | 425 + (ext6 << 6) | t); 426 + } 427 + 428 + /* 7. Arithmetic immediate */ 429 + static inline u32 hppa_t7_insn(u8 opcode, u8 r, u8 t, u32 im11) 430 + { 431 + return ((opcode << 26) | (r << 21) | (t << 16) | low_sign_unext(im11, 11)); 432 + } 433 + 434 + /* 10. Shift instructions */ 435 + static inline u32 hppa_t10_insn(u8 opcode, u8 r2, u8 r1, u8 c, u8 ext3, u8 cp, u8 t) 436 + { 437 + return ((opcode << 26) | (r2 << 21) | (r1 << 16) | (c << 13) | 438 + (ext3 << 10) | (cp << 5) | t); 439 + } 440 + 441 + /* 11. Conditional branch instructions */ 442 + static inline u32 hppa_t11_insn(u8 opcode, u8 r2, u8 r1, u8 c, u32 w, u8 nop) 443 + { 444 + u32 ra = re_assemble_12(w); 445 + // ra = low_sign_unext(w,11) | (w & (1<<10) 446 + return ((opcode << 26) | (r2 << 21) | (r1 << 16) | (c << 13) | (nop << 1) | ra); 447 + } 448 + 449 + /* 12. Branch instructions */ 450 + static inline u32 hppa_t12_insn(u8 opcode, u8 rp, u32 w, u8 ext3, u8 nop) 451 + { 452 + return ((opcode << 26) | (rp << 21) | (ext3 << 13) | (nop << 1) | re_assemble_17(w)); 453 + } 454 + 455 + static inline u32 hppa_t12_L_insn(u8 opcode, u32 w, u8 nop) 456 + { 457 + return ((opcode << 26) | (0x05 << 13) | (nop << 1) | re_assemble_22(w)); 458 + } 459 + 460 + /* 21. Move to control register */ 461 + static inline u32 hppa_t21_insn(u8 opcode, u8 r2, u8 r1, u8 ext8, u8 t) 462 + { 463 + return ((opcode << 26) | (r2 << 21) | (r1 << 16) | (ext8 << 5) | t); 464 + } 465 + 466 + /* Helper functions called by jit code on HPPA32 and HPPA64. */ 467 + 468 + u64 hppa_div64(u64 div, u64 divisor); 469 + u64 hppa_div64_rem(u64 div, u64 divisor); 470 + 471 + /* Helper functions that emit HPPA instructions when possible. */ 472 + 473 + void bpf_jit_build_prologue(struct hppa_jit_context *ctx); 474 + void bpf_jit_build_epilogue(struct hppa_jit_context *ctx); 475 + 476 + int bpf_jit_emit_insn(const struct bpf_insn *insn, struct hppa_jit_context *ctx, 477 + bool extra_pass); 478 + 479 + #endif /* _BPF_JIT_H */
+1615
arch/parisc/net/bpf_jit_comp32.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * BPF JIT compiler for PA-RISC (32-bit) 4 + * 5 + * Copyright (c) 2023 Helge Deller <deller@gmx.de> 6 + * 7 + * The code is based on the BPF JIT compiler for RV64 by Björn Töpel and 8 + * the BPF JIT compiler for 32-bit ARM by Shubham Bansal and Mircea Gherzan. 9 + */ 10 + 11 + #include <linux/bpf.h> 12 + #include <linux/filter.h> 13 + #include <linux/libgcc.h> 14 + #include "bpf_jit.h" 15 + 16 + /* 17 + * Stack layout during BPF program execution (note: stack grows up): 18 + * 19 + * high 20 + * HPPA32 sp => +----------+ <= HPPA32 fp 21 + * | saved sp | 22 + * | saved rp | 23 + * | ... | HPPA32 callee-saved registers 24 + * | curr args| 25 + * | local var| 26 + * +----------+ <= (sp - 4 * NR_SAVED_REGISTERS) 27 + * | lo(R9) | 28 + * | hi(R9) | 29 + * | lo(FP) | JIT scratch space for BPF registers 30 + * | hi(FP) | 31 + * | ... | 32 + * +----------+ <= (sp - 4 * NR_SAVED_REGISTERS 33 + * | | - 4 * BPF_JIT_SCRATCH_REGS) 34 + * | | 35 + * | ... | BPF program stack 36 + * | | 37 + * | ... | Function call stack 38 + * | | 39 + * +----------+ 40 + * low 41 + */ 42 + 43 + enum { 44 + /* Stack layout - these are offsets from top of JIT scratch space. */ 45 + BPF_R8_HI, 46 + BPF_R8_LO, 47 + BPF_R9_HI, 48 + BPF_R9_LO, 49 + BPF_FP_HI, 50 + BPF_FP_LO, 51 + BPF_AX_HI, 52 + BPF_AX_LO, 53 + BPF_R0_TEMP_HI, 54 + BPF_R0_TEMP_LO, 55 + BPF_JIT_SCRATCH_REGS, 56 + }; 57 + 58 + /* Number of callee-saved registers stored to stack: rp, r3-r18. */ 59 + #define NR_SAVED_REGISTERS (18 - 3 + 1 + 8) 60 + 61 + /* Offset from fp for BPF registers stored on stack. */ 62 + #define STACK_OFFSET(k) (- (NR_SAVED_REGISTERS + k + 1)) 63 + #define STACK_ALIGN FRAME_SIZE 64 + 65 + #define EXIT_PTR_LOAD(reg) hppa_ldw(-0x08, HPPA_REG_SP, reg) 66 + #define EXIT_PTR_STORE(reg) hppa_stw(reg, -0x08, HPPA_REG_SP) 67 + #define EXIT_PTR_JUMP(reg, nop) hppa_bv(HPPA_REG_ZERO, reg, nop) 68 + 69 + #define TMP_REG_1 (MAX_BPF_JIT_REG + 0) 70 + #define TMP_REG_2 (MAX_BPF_JIT_REG + 1) 71 + #define TMP_REG_R0 (MAX_BPF_JIT_REG + 2) 72 + 73 + static const s8 regmap[][2] = { 74 + /* Return value from in-kernel function, and exit value from eBPF. */ 75 + [BPF_REG_0] = {HPPA_REG_RET0, HPPA_REG_RET1}, /* HI/LOW */ 76 + 77 + /* Arguments from eBPF program to in-kernel function. */ 78 + [BPF_REG_1] = {HPPA_R(3), HPPA_R(4)}, 79 + [BPF_REG_2] = {HPPA_R(5), HPPA_R(6)}, 80 + [BPF_REG_3] = {HPPA_R(7), HPPA_R(8)}, 81 + [BPF_REG_4] = {HPPA_R(9), HPPA_R(10)}, 82 + [BPF_REG_5] = {HPPA_R(11), HPPA_R(12)}, 83 + 84 + [BPF_REG_6] = {HPPA_R(13), HPPA_R(14)}, 85 + [BPF_REG_7] = {HPPA_R(15), HPPA_R(16)}, 86 + /* 87 + * Callee-saved registers that in-kernel function will preserve. 88 + * Stored on the stack. 89 + */ 90 + [BPF_REG_8] = {STACK_OFFSET(BPF_R8_HI), STACK_OFFSET(BPF_R8_LO)}, 91 + [BPF_REG_9] = {STACK_OFFSET(BPF_R9_HI), STACK_OFFSET(BPF_R9_LO)}, 92 + 93 + /* Read-only frame pointer to access BPF stack. Not needed. */ 94 + [BPF_REG_FP] = {STACK_OFFSET(BPF_FP_HI), STACK_OFFSET(BPF_FP_LO)}, 95 + 96 + /* Temporary register for blinding constants. Stored on the stack. */ 97 + [BPF_REG_AX] = {STACK_OFFSET(BPF_AX_HI), STACK_OFFSET(BPF_AX_LO)}, 98 + /* 99 + * Temporary registers used by the JIT to operate on registers stored 100 + * on the stack. Save t0 and t1 to be used as temporaries in generated 101 + * code. 102 + */ 103 + [TMP_REG_1] = {HPPA_REG_T3, HPPA_REG_T2}, 104 + [TMP_REG_2] = {HPPA_REG_T5, HPPA_REG_T4}, 105 + 106 + /* temporary space for BPF_R0 during libgcc and millicode calls */ 107 + [TMP_REG_R0] = {STACK_OFFSET(BPF_R0_TEMP_HI), STACK_OFFSET(BPF_R0_TEMP_LO)}, 108 + }; 109 + 110 + static s8 hi(const s8 *r) 111 + { 112 + return r[0]; 113 + } 114 + 115 + static s8 lo(const s8 *r) 116 + { 117 + return r[1]; 118 + } 119 + 120 + static void emit_hppa_copy(const s8 rs, const s8 rd, struct hppa_jit_context *ctx) 121 + { 122 + REG_SET_SEEN(ctx, rd); 123 + if (OPTIMIZE_HPPA && (rs == rd)) 124 + return; 125 + REG_SET_SEEN(ctx, rs); 126 + emit(hppa_copy(rs, rd), ctx); 127 + } 128 + 129 + static void emit_hppa_xor(const s8 r1, const s8 r2, const s8 r3, struct hppa_jit_context *ctx) 130 + { 131 + REG_SET_SEEN(ctx, r1); 132 + REG_SET_SEEN(ctx, r2); 133 + REG_SET_SEEN(ctx, r3); 134 + if (OPTIMIZE_HPPA && (r1 == r2)) { 135 + emit(hppa_copy(HPPA_REG_ZERO, r3), ctx); 136 + } else { 137 + emit(hppa_xor(r1, r2, r3), ctx); 138 + } 139 + } 140 + 141 + static void emit_imm(const s8 rd, s32 imm, struct hppa_jit_context *ctx) 142 + { 143 + u32 lower = im11(imm); 144 + 145 + REG_SET_SEEN(ctx, rd); 146 + if (OPTIMIZE_HPPA && relative_bits_ok(imm, 14)) { 147 + emit(hppa_ldi(imm, rd), ctx); 148 + return; 149 + } 150 + emit(hppa_ldil(imm, rd), ctx); 151 + if (OPTIMIZE_HPPA && (lower == 0)) 152 + return; 153 + emit(hppa_ldo(lower, rd, rd), ctx); 154 + } 155 + 156 + static void emit_imm32(const s8 *rd, s32 imm, struct hppa_jit_context *ctx) 157 + { 158 + /* Emit immediate into lower bits. */ 159 + REG_SET_SEEN(ctx, lo(rd)); 160 + emit_imm(lo(rd), imm, ctx); 161 + 162 + /* Sign-extend into upper bits. */ 163 + REG_SET_SEEN(ctx, hi(rd)); 164 + if (imm >= 0) 165 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 166 + else 167 + emit(hppa_ldi(-1, hi(rd)), ctx); 168 + } 169 + 170 + static void emit_imm64(const s8 *rd, s32 imm_hi, s32 imm_lo, 171 + struct hppa_jit_context *ctx) 172 + { 173 + emit_imm(hi(rd), imm_hi, ctx); 174 + emit_imm(lo(rd), imm_lo, ctx); 175 + } 176 + 177 + static void __build_epilogue(bool is_tail_call, struct hppa_jit_context *ctx) 178 + { 179 + const s8 *r0 = regmap[BPF_REG_0]; 180 + int i; 181 + 182 + if (is_tail_call) { 183 + /* 184 + * goto *(t0 + 4); 185 + * Skips first instruction of prologue which initializes tail 186 + * call counter. Assumes t0 contains address of target program, 187 + * see emit_bpf_tail_call. 188 + */ 189 + emit(hppa_ldo(1 * HPPA_INSN_SIZE, HPPA_REG_T0, HPPA_REG_T0), ctx); 190 + emit(hppa_bv(HPPA_REG_ZERO, HPPA_REG_T0, EXEC_NEXT_INSTR), ctx); 191 + /* in delay slot: */ 192 + emit(hppa_copy(HPPA_REG_TCC, HPPA_REG_TCC_IN_INIT), ctx); 193 + 194 + return; 195 + } 196 + 197 + /* load epilogue function pointer and jump to it. */ 198 + /* exit point is either directly below, or the outest TCC exit function */ 199 + emit(EXIT_PTR_LOAD(HPPA_REG_RP), ctx); 200 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 201 + 202 + /* NOTE: we are 32-bit and big-endian, so return lower 32-bit value */ 203 + emit_hppa_copy(lo(r0), HPPA_REG_RET0, ctx); 204 + 205 + /* Restore callee-saved registers. */ 206 + for (i = 3; i <= 18; i++) { 207 + if (OPTIMIZE_HPPA && !REG_WAS_SEEN(ctx, HPPA_R(i))) 208 + continue; 209 + emit(hppa_ldw(-REG_SIZE * (8 + (i-3)), HPPA_REG_SP, HPPA_R(i)), ctx); 210 + } 211 + 212 + /* load original return pointer (stored by outest TCC function) */ 213 + emit(hppa_ldw(-0x14, HPPA_REG_SP, HPPA_REG_RP), ctx); 214 + emit(hppa_bv(HPPA_REG_ZERO, HPPA_REG_RP, EXEC_NEXT_INSTR), ctx); 215 + /* in delay slot: */ 216 + emit(hppa_ldw(-0x04, HPPA_REG_SP, HPPA_REG_SP), ctx); 217 + } 218 + 219 + static bool is_stacked(s8 reg) 220 + { 221 + return reg < 0; 222 + } 223 + 224 + static const s8 *bpf_get_reg64_offset(const s8 *reg, const s8 *tmp, 225 + u16 offset_sp, struct hppa_jit_context *ctx) 226 + { 227 + if (is_stacked(hi(reg))) { 228 + emit(hppa_ldw(REG_SIZE * hi(reg) - offset_sp, HPPA_REG_SP, hi(tmp)), ctx); 229 + emit(hppa_ldw(REG_SIZE * lo(reg) - offset_sp, HPPA_REG_SP, lo(tmp)), ctx); 230 + reg = tmp; 231 + } 232 + REG_SET_SEEN(ctx, hi(reg)); 233 + REG_SET_SEEN(ctx, lo(reg)); 234 + return reg; 235 + } 236 + 237 + static const s8 *bpf_get_reg64(const s8 *reg, const s8 *tmp, 238 + struct hppa_jit_context *ctx) 239 + { 240 + return bpf_get_reg64_offset(reg, tmp, 0, ctx); 241 + } 242 + 243 + static const s8 *bpf_get_reg64_ref(const s8 *reg, const s8 *tmp, 244 + bool must_load, struct hppa_jit_context *ctx) 245 + { 246 + if (!OPTIMIZE_HPPA) 247 + return bpf_get_reg64(reg, tmp, ctx); 248 + 249 + if (is_stacked(hi(reg))) { 250 + if (must_load) 251 + emit(hppa_ldw(REG_SIZE * hi(reg), HPPA_REG_SP, hi(tmp)), ctx); 252 + reg = tmp; 253 + } 254 + REG_SET_SEEN(ctx, hi(reg)); 255 + REG_SET_SEEN(ctx, lo(reg)); 256 + return reg; 257 + } 258 + 259 + 260 + static void bpf_put_reg64(const s8 *reg, const s8 *src, 261 + struct hppa_jit_context *ctx) 262 + { 263 + if (is_stacked(hi(reg))) { 264 + emit(hppa_stw(hi(src), REG_SIZE * hi(reg), HPPA_REG_SP), ctx); 265 + emit(hppa_stw(lo(src), REG_SIZE * lo(reg), HPPA_REG_SP), ctx); 266 + } 267 + } 268 + 269 + static void bpf_save_R0(struct hppa_jit_context *ctx) 270 + { 271 + bpf_put_reg64(regmap[TMP_REG_R0], regmap[BPF_REG_0], ctx); 272 + } 273 + 274 + static void bpf_restore_R0(struct hppa_jit_context *ctx) 275 + { 276 + bpf_get_reg64(regmap[TMP_REG_R0], regmap[BPF_REG_0], ctx); 277 + } 278 + 279 + 280 + static const s8 *bpf_get_reg32(const s8 *reg, const s8 *tmp, 281 + struct hppa_jit_context *ctx) 282 + { 283 + if (is_stacked(lo(reg))) { 284 + emit(hppa_ldw(REG_SIZE * lo(reg), HPPA_REG_SP, lo(tmp)), ctx); 285 + reg = tmp; 286 + } 287 + REG_SET_SEEN(ctx, lo(reg)); 288 + return reg; 289 + } 290 + 291 + static const s8 *bpf_get_reg32_ref(const s8 *reg, const s8 *tmp, 292 + struct hppa_jit_context *ctx) 293 + { 294 + if (!OPTIMIZE_HPPA) 295 + return bpf_get_reg32(reg, tmp, ctx); 296 + 297 + if (is_stacked(hi(reg))) { 298 + reg = tmp; 299 + } 300 + REG_SET_SEEN(ctx, lo(reg)); 301 + return reg; 302 + } 303 + 304 + static void bpf_put_reg32(const s8 *reg, const s8 *src, 305 + struct hppa_jit_context *ctx) 306 + { 307 + if (is_stacked(lo(reg))) { 308 + REG_SET_SEEN(ctx, lo(src)); 309 + emit(hppa_stw(lo(src), REG_SIZE * lo(reg), HPPA_REG_SP), ctx); 310 + if (1 && !ctx->prog->aux->verifier_zext) { 311 + REG_SET_SEEN(ctx, hi(reg)); 312 + emit(hppa_stw(HPPA_REG_ZERO, REG_SIZE * hi(reg), HPPA_REG_SP), ctx); 313 + } 314 + } else if (1 && !ctx->prog->aux->verifier_zext) { 315 + REG_SET_SEEN(ctx, hi(reg)); 316 + emit_hppa_copy(HPPA_REG_ZERO, hi(reg), ctx); 317 + } 318 + } 319 + 320 + /* extern hppa millicode functions */ 321 + extern void $$mulI(void); 322 + extern void $$divU(void); 323 + extern void $$remU(void); 324 + 325 + static void emit_call_millicode(void *func, const s8 arg0, 326 + const s8 arg1, u8 opcode, struct hppa_jit_context *ctx) 327 + { 328 + u32 func_addr; 329 + 330 + emit_hppa_copy(arg0, HPPA_REG_ARG0, ctx); 331 + emit_hppa_copy(arg1, HPPA_REG_ARG1, ctx); 332 + 333 + /* libcgcc overwrites HPPA_REG_RET0/1, save temp. in dest. */ 334 + if (arg0 != HPPA_REG_RET1) 335 + bpf_save_R0(ctx); 336 + 337 + func_addr = (uintptr_t) dereference_function_descriptor(func); 338 + emit(hppa_ldil(func_addr, HPPA_REG_R31), ctx); 339 + /* skip the following be_l instruction if divisor is zero. */ 340 + if (BPF_OP(opcode) == BPF_DIV || BPF_OP(opcode) == BPF_MOD) { 341 + if (BPF_OP(opcode) == BPF_DIV) 342 + emit_hppa_copy(HPPA_REG_ZERO, HPPA_REG_RET1, ctx); 343 + else 344 + emit_hppa_copy(HPPA_REG_ARG0, HPPA_REG_RET1, ctx); 345 + emit(hppa_or_cond(HPPA_REG_ARG1, HPPA_REG_ZERO, 1, 0, HPPA_REG_ZERO), ctx); 346 + } 347 + /* Note: millicode functions use r31 as return pointer instead of rp */ 348 + emit(hppa_be_l(im11(func_addr) >> 2, HPPA_REG_R31, NOP_NEXT_INSTR), ctx); 349 + emit(hppa_nop(), ctx); /* this nop is needed here for delay slot */ 350 + 351 + /* Note: millicode functions return result in RET1, not RET0 */ 352 + emit_hppa_copy(HPPA_REG_RET1, arg0, ctx); 353 + 354 + /* restore HPPA_REG_RET0/1, temp. save in dest. */ 355 + if (arg0 != HPPA_REG_RET1) 356 + bpf_restore_R0(ctx); 357 + } 358 + 359 + static void emit_call_libgcc_ll(void *func, const s8 *arg0, 360 + const s8 *arg1, u8 opcode, struct hppa_jit_context *ctx) 361 + { 362 + u32 func_addr; 363 + 364 + emit_hppa_copy(lo(arg0), HPPA_REG_ARG0, ctx); 365 + emit_hppa_copy(hi(arg0), HPPA_REG_ARG1, ctx); 366 + emit_hppa_copy(lo(arg1), HPPA_REG_ARG2, ctx); 367 + emit_hppa_copy(hi(arg1), HPPA_REG_ARG3, ctx); 368 + 369 + /* libcgcc overwrites HPPA_REG_RET0/_RET1, so keep copy of R0 on stack */ 370 + if (hi(arg0) != HPPA_REG_RET0) 371 + bpf_save_R0(ctx); 372 + 373 + /* prepare stack */ 374 + emit(hppa_ldo(2 * FRAME_SIZE, HPPA_REG_SP, HPPA_REG_SP), ctx); 375 + 376 + func_addr = (uintptr_t) dereference_function_descriptor(func); 377 + emit(hppa_ldil(func_addr, HPPA_REG_R31), ctx); 378 + /* zero out the following be_l instruction if divisor is 0 (and set default values) */ 379 + if (BPF_OP(opcode) == BPF_DIV || BPF_OP(opcode) == BPF_MOD) { 380 + emit_hppa_copy(HPPA_REG_ZERO, HPPA_REG_RET0, ctx); 381 + if (BPF_OP(opcode) == BPF_DIV) 382 + emit_hppa_copy(HPPA_REG_ZERO, HPPA_REG_RET1, ctx); 383 + else 384 + emit_hppa_copy(HPPA_REG_ARG0, HPPA_REG_RET1, ctx); 385 + emit(hppa_or_cond(HPPA_REG_ARG2, HPPA_REG_ARG3, 1, 0, HPPA_REG_ZERO), ctx); 386 + } 387 + emit(hppa_be_l(im11(func_addr) >> 2, HPPA_REG_R31, EXEC_NEXT_INSTR), ctx); 388 + emit_hppa_copy(HPPA_REG_R31, HPPA_REG_RP, ctx); 389 + 390 + /* restore stack */ 391 + emit(hppa_ldo(-2 * FRAME_SIZE, HPPA_REG_SP, HPPA_REG_SP), ctx); 392 + 393 + emit_hppa_copy(HPPA_REG_RET0, hi(arg0), ctx); 394 + emit_hppa_copy(HPPA_REG_RET1, lo(arg0), ctx); 395 + 396 + /* restore HPPA_REG_RET0/_RET1 */ 397 + if (hi(arg0) != HPPA_REG_RET0) 398 + bpf_restore_R0(ctx); 399 + } 400 + 401 + static void emit_jump(s32 paoff, bool force_far, 402 + struct hppa_jit_context *ctx) 403 + { 404 + unsigned long pc, addr; 405 + 406 + /* Note: allocate 2 instructions for jumps if force_far is set. */ 407 + if (relative_bits_ok(paoff - HPPA_BRANCH_DISPLACEMENT, 17)) { 408 + /* use BL,short branch followed by nop() */ 409 + emit(hppa_bl(paoff - HPPA_BRANCH_DISPLACEMENT, HPPA_REG_ZERO), ctx); 410 + if (force_far) 411 + emit(hppa_nop(), ctx); 412 + return; 413 + } 414 + 415 + pc = (uintptr_t) &ctx->insns[ctx->ninsns]; 416 + addr = pc + (paoff * HPPA_INSN_SIZE); 417 + emit(hppa_ldil(addr, HPPA_REG_R31), ctx); 418 + emit(hppa_be_l(im11(addr) >> 2, HPPA_REG_R31, NOP_NEXT_INSTR), ctx); // be,l,n addr(sr4,r31), %sr0, %r31 419 + } 420 + 421 + static void emit_alu_i64(const s8 *dst, s32 imm, 422 + struct hppa_jit_context *ctx, const u8 op) 423 + { 424 + const s8 *tmp1 = regmap[TMP_REG_1]; 425 + const s8 *rd; 426 + 427 + if (0 && op == BPF_MOV) 428 + rd = bpf_get_reg64_ref(dst, tmp1, false, ctx); 429 + else 430 + rd = bpf_get_reg64(dst, tmp1, ctx); 431 + 432 + /* dst = dst OP imm */ 433 + switch (op) { 434 + case BPF_MOV: 435 + emit_imm32(rd, imm, ctx); 436 + break; 437 + case BPF_AND: 438 + emit_imm(HPPA_REG_T0, imm, ctx); 439 + emit(hppa_and(lo(rd), HPPA_REG_T0, lo(rd)), ctx); 440 + if (imm >= 0) 441 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 442 + break; 443 + case BPF_OR: 444 + emit_imm(HPPA_REG_T0, imm, ctx); 445 + emit(hppa_or(lo(rd), HPPA_REG_T0, lo(rd)), ctx); 446 + if (imm < 0) 447 + emit_imm(hi(rd), -1, ctx); 448 + break; 449 + case BPF_XOR: 450 + emit_imm(HPPA_REG_T0, imm, ctx); 451 + emit_hppa_xor(lo(rd), HPPA_REG_T0, lo(rd), ctx); 452 + if (imm < 0) { 453 + emit_imm(HPPA_REG_T0, -1, ctx); 454 + emit_hppa_xor(hi(rd), HPPA_REG_T0, hi(rd), ctx); 455 + } 456 + break; 457 + case BPF_LSH: 458 + if (imm == 0) 459 + break; 460 + if (imm > 32) { 461 + imm -= 32; 462 + emit(hppa_zdep(lo(rd), imm, imm, hi(rd)), ctx); 463 + emit_hppa_copy(HPPA_REG_ZERO, lo(rd), ctx); 464 + } else if (imm == 32) { 465 + emit_hppa_copy(lo(rd), hi(rd), ctx); 466 + emit_hppa_copy(HPPA_REG_ZERO, lo(rd), ctx); 467 + } else { 468 + emit(hppa_shd(hi(rd), lo(rd), 32 - imm, hi(rd)), ctx); 469 + emit(hppa_zdep(lo(rd), imm, imm, lo(rd)), ctx); 470 + } 471 + break; 472 + case BPF_RSH: 473 + if (imm == 0) 474 + break; 475 + if (imm > 32) { 476 + imm -= 32; 477 + emit(hppa_shr(hi(rd), imm, lo(rd)), ctx); 478 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 479 + } else if (imm == 32) { 480 + emit_hppa_copy(hi(rd), lo(rd), ctx); 481 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 482 + } else { 483 + emit(hppa_shrpw(hi(rd), lo(rd), imm, lo(rd)), ctx); 484 + emit(hppa_shr(hi(rd), imm, hi(rd)), ctx); 485 + } 486 + break; 487 + case BPF_ARSH: 488 + if (imm == 0) 489 + break; 490 + if (imm > 32) { 491 + imm -= 32; 492 + emit(hppa_extrws(hi(rd), 31 - imm, imm, lo(rd)), ctx); 493 + emit(hppa_extrws(hi(rd), 0, 31, hi(rd)), ctx); 494 + } else if (imm == 32) { 495 + emit_hppa_copy(hi(rd), lo(rd), ctx); 496 + emit(hppa_extrws(hi(rd), 0, 31, hi(rd)), ctx); 497 + } else { 498 + emit(hppa_shrpw(hi(rd), lo(rd), imm, lo(rd)), ctx); 499 + emit(hppa_extrws(hi(rd), 31 - imm, imm, hi(rd)), ctx); 500 + } 501 + break; 502 + default: 503 + WARN_ON(1); 504 + } 505 + 506 + bpf_put_reg64(dst, rd, ctx); 507 + } 508 + 509 + static void emit_alu_i32(const s8 *dst, s32 imm, 510 + struct hppa_jit_context *ctx, const u8 op) 511 + { 512 + const s8 *tmp1 = regmap[TMP_REG_1]; 513 + const s8 *rd = bpf_get_reg32(dst, tmp1, ctx); 514 + 515 + if (op == BPF_MOV) 516 + rd = bpf_get_reg32_ref(dst, tmp1, ctx); 517 + else 518 + rd = bpf_get_reg32(dst, tmp1, ctx); 519 + 520 + /* dst = dst OP imm */ 521 + switch (op) { 522 + case BPF_MOV: 523 + emit_imm(lo(rd), imm, ctx); 524 + break; 525 + case BPF_ADD: 526 + emit_imm(HPPA_REG_T0, imm, ctx); 527 + emit(hppa_add(lo(rd), HPPA_REG_T0, lo(rd)), ctx); 528 + break; 529 + case BPF_SUB: 530 + emit_imm(HPPA_REG_T0, imm, ctx); 531 + emit(hppa_sub(lo(rd), HPPA_REG_T0, lo(rd)), ctx); 532 + break; 533 + case BPF_AND: 534 + emit_imm(HPPA_REG_T0, imm, ctx); 535 + emit(hppa_and(lo(rd), HPPA_REG_T0, lo(rd)), ctx); 536 + break; 537 + case BPF_OR: 538 + emit_imm(HPPA_REG_T0, imm, ctx); 539 + emit(hppa_or(lo(rd), HPPA_REG_T0, lo(rd)), ctx); 540 + break; 541 + case BPF_XOR: 542 + emit_imm(HPPA_REG_T0, imm, ctx); 543 + emit_hppa_xor(lo(rd), HPPA_REG_T0, lo(rd), ctx); 544 + break; 545 + case BPF_LSH: 546 + if (imm != 0) 547 + emit(hppa_zdep(lo(rd), imm, imm, lo(rd)), ctx); 548 + break; 549 + case BPF_RSH: 550 + if (imm != 0) 551 + emit(hppa_shr(lo(rd), imm, lo(rd)), ctx); 552 + break; 553 + case BPF_ARSH: 554 + if (imm != 0) 555 + emit(hppa_extrws(lo(rd), 31 - imm, imm, lo(rd)), ctx); 556 + break; 557 + default: 558 + WARN_ON(1); 559 + } 560 + 561 + bpf_put_reg32(dst, rd, ctx); 562 + } 563 + 564 + static void emit_alu_r64(const s8 *dst, const s8 *src, 565 + struct hppa_jit_context *ctx, const u8 op) 566 + { 567 + const s8 *tmp1 = regmap[TMP_REG_1]; 568 + const s8 *tmp2 = regmap[TMP_REG_2]; 569 + const s8 *rd; 570 + const s8 *rs = bpf_get_reg64(src, tmp2, ctx); 571 + 572 + if (op == BPF_MOV) 573 + rd = bpf_get_reg64_ref(dst, tmp1, false, ctx); 574 + else 575 + rd = bpf_get_reg64(dst, tmp1, ctx); 576 + 577 + /* dst = dst OP src */ 578 + switch (op) { 579 + case BPF_MOV: 580 + emit_hppa_copy(lo(rs), lo(rd), ctx); 581 + emit_hppa_copy(hi(rs), hi(rd), ctx); 582 + break; 583 + case BPF_ADD: 584 + emit(hppa_add(lo(rd), lo(rs), lo(rd)), ctx); 585 + emit(hppa_addc(hi(rd), hi(rs), hi(rd)), ctx); 586 + break; 587 + case BPF_SUB: 588 + emit(hppa_sub(lo(rd), lo(rs), lo(rd)), ctx); 589 + emit(hppa_subb(hi(rd), hi(rs), hi(rd)), ctx); 590 + break; 591 + case BPF_AND: 592 + emit(hppa_and(lo(rd), lo(rs), lo(rd)), ctx); 593 + emit(hppa_and(hi(rd), hi(rs), hi(rd)), ctx); 594 + break; 595 + case BPF_OR: 596 + emit(hppa_or(lo(rd), lo(rs), lo(rd)), ctx); 597 + emit(hppa_or(hi(rd), hi(rs), hi(rd)), ctx); 598 + break; 599 + case BPF_XOR: 600 + emit_hppa_xor(lo(rd), lo(rs), lo(rd), ctx); 601 + emit_hppa_xor(hi(rd), hi(rs), hi(rd), ctx); 602 + break; 603 + case BPF_MUL: 604 + emit_call_libgcc_ll(__muldi3, rd, rs, op, ctx); 605 + break; 606 + case BPF_DIV: 607 + emit_call_libgcc_ll(&hppa_div64, rd, rs, op, ctx); 608 + break; 609 + case BPF_MOD: 610 + emit_call_libgcc_ll(&hppa_div64_rem, rd, rs, op, ctx); 611 + break; 612 + case BPF_LSH: 613 + emit_call_libgcc_ll(__ashldi3, rd, rs, op, ctx); 614 + break; 615 + case BPF_RSH: 616 + emit_call_libgcc_ll(__lshrdi3, rd, rs, op, ctx); 617 + break; 618 + case BPF_ARSH: 619 + emit_call_libgcc_ll(__ashrdi3, rd, rs, op, ctx); 620 + break; 621 + case BPF_NEG: 622 + emit(hppa_sub(HPPA_REG_ZERO, lo(rd), lo(rd)), ctx); 623 + emit(hppa_subb(HPPA_REG_ZERO, hi(rd), hi(rd)), ctx); 624 + break; 625 + default: 626 + WARN_ON(1); 627 + } 628 + 629 + bpf_put_reg64(dst, rd, ctx); 630 + } 631 + 632 + static void emit_alu_r32(const s8 *dst, const s8 *src, 633 + struct hppa_jit_context *ctx, const u8 op) 634 + { 635 + const s8 *tmp1 = regmap[TMP_REG_1]; 636 + const s8 *tmp2 = regmap[TMP_REG_2]; 637 + const s8 *rd; 638 + const s8 *rs = bpf_get_reg32(src, tmp2, ctx); 639 + 640 + if (op == BPF_MOV) 641 + rd = bpf_get_reg32_ref(dst, tmp1, ctx); 642 + else 643 + rd = bpf_get_reg32(dst, tmp1, ctx); 644 + 645 + /* dst = dst OP src */ 646 + switch (op) { 647 + case BPF_MOV: 648 + emit_hppa_copy(lo(rs), lo(rd), ctx); 649 + break; 650 + case BPF_ADD: 651 + emit(hppa_add(lo(rd), lo(rs), lo(rd)), ctx); 652 + break; 653 + case BPF_SUB: 654 + emit(hppa_sub(lo(rd), lo(rs), lo(rd)), ctx); 655 + break; 656 + case BPF_AND: 657 + emit(hppa_and(lo(rd), lo(rs), lo(rd)), ctx); 658 + break; 659 + case BPF_OR: 660 + emit(hppa_or(lo(rd), lo(rs), lo(rd)), ctx); 661 + break; 662 + case BPF_XOR: 663 + emit_hppa_xor(lo(rd), lo(rs), lo(rd), ctx); 664 + break; 665 + case BPF_MUL: 666 + emit_call_millicode($$mulI, lo(rd), lo(rs), op, ctx); 667 + break; 668 + case BPF_DIV: 669 + emit_call_millicode($$divU, lo(rd), lo(rs), op, ctx); 670 + break; 671 + case BPF_MOD: 672 + emit_call_millicode($$remU, lo(rd), lo(rs), op, ctx); 673 + break; 674 + case BPF_LSH: 675 + emit(hppa_subi(0x1f, lo(rs), HPPA_REG_T0), ctx); 676 + emit(hppa_mtsar(HPPA_REG_T0), ctx); 677 + emit(hppa_depwz_sar(lo(rd), lo(rd)), ctx); 678 + break; 679 + case BPF_RSH: 680 + emit(hppa_mtsar(lo(rs)), ctx); 681 + emit(hppa_shrpw_sar(lo(rd), lo(rd)), ctx); 682 + break; 683 + case BPF_ARSH: /* sign extending arithmetic shift right */ 684 + // emit(hppa_beq(lo(rs), HPPA_REG_ZERO, 2), ctx); 685 + emit(hppa_subi(0x1f, lo(rs), HPPA_REG_T0), ctx); 686 + emit(hppa_mtsar(HPPA_REG_T0), ctx); 687 + emit(hppa_extrws_sar(lo(rd), lo(rd)), ctx); 688 + break; 689 + case BPF_NEG: 690 + emit(hppa_sub(HPPA_REG_ZERO, lo(rd), lo(rd)), ctx); // sub r0,rd,rd 691 + break; 692 + default: 693 + WARN_ON(1); 694 + } 695 + 696 + bpf_put_reg32(dst, rd, ctx); 697 + } 698 + 699 + static int emit_branch_r64(const s8 *src1, const s8 *src2, s32 paoff, 700 + struct hppa_jit_context *ctx, const u8 op) 701 + { 702 + int e, s = ctx->ninsns; 703 + const s8 *tmp1 = regmap[TMP_REG_1]; 704 + const s8 *tmp2 = regmap[TMP_REG_2]; 705 + 706 + const s8 *rs1 = bpf_get_reg64(src1, tmp1, ctx); 707 + const s8 *rs2 = bpf_get_reg64(src2, tmp2, ctx); 708 + 709 + /* 710 + * NO_JUMP skips over the rest of the instructions and the 711 + * emit_jump, meaning the BPF branch is not taken. 712 + * JUMP skips directly to the emit_jump, meaning 713 + * the BPF branch is taken. 714 + * 715 + * The fallthrough case results in the BPF branch being taken. 716 + */ 717 + #define NO_JUMP(idx) (2 + (idx) - 1) 718 + #define JUMP(idx) (0 + (idx) - 1) 719 + 720 + switch (op) { 721 + case BPF_JEQ: 722 + emit(hppa_bne(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 723 + emit(hppa_bne(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 724 + break; 725 + case BPF_JGT: 726 + emit(hppa_bgtu(hi(rs1), hi(rs2), JUMP(2)), ctx); 727 + emit(hppa_bltu(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 728 + emit(hppa_bleu(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 729 + break; 730 + case BPF_JLT: 731 + emit(hppa_bltu(hi(rs1), hi(rs2), JUMP(2)), ctx); 732 + emit(hppa_bgtu(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 733 + emit(hppa_bgeu(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 734 + break; 735 + case BPF_JGE: 736 + emit(hppa_bgtu(hi(rs1), hi(rs2), JUMP(2)), ctx); 737 + emit(hppa_bltu(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 738 + emit(hppa_bltu(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 739 + break; 740 + case BPF_JLE: 741 + emit(hppa_bltu(hi(rs1), hi(rs2), JUMP(2)), ctx); 742 + emit(hppa_bgtu(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 743 + emit(hppa_bgtu(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 744 + break; 745 + case BPF_JNE: 746 + emit(hppa_bne(hi(rs1), hi(rs2), JUMP(1)), ctx); 747 + emit(hppa_beq(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 748 + break; 749 + case BPF_JSGT: 750 + emit(hppa_bgt(hi(rs1), hi(rs2), JUMP(2)), ctx); 751 + emit(hppa_blt(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 752 + emit(hppa_bleu(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 753 + break; 754 + case BPF_JSLT: 755 + emit(hppa_blt(hi(rs1), hi(rs2), JUMP(2)), ctx); 756 + emit(hppa_bgt(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 757 + emit(hppa_bgeu(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 758 + break; 759 + case BPF_JSGE: 760 + emit(hppa_bgt(hi(rs1), hi(rs2), JUMP(2)), ctx); 761 + emit(hppa_blt(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 762 + emit(hppa_bltu(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 763 + break; 764 + case BPF_JSLE: 765 + emit(hppa_blt(hi(rs1), hi(rs2), JUMP(2)), ctx); 766 + emit(hppa_bgt(hi(rs1), hi(rs2), NO_JUMP(1)), ctx); 767 + emit(hppa_bgtu(lo(rs1), lo(rs2), NO_JUMP(0)), ctx); 768 + break; 769 + case BPF_JSET: 770 + emit(hppa_and(hi(rs1), hi(rs2), HPPA_REG_T0), ctx); 771 + emit(hppa_and(lo(rs1), lo(rs2), HPPA_REG_T1), ctx); 772 + emit(hppa_bne(HPPA_REG_T0, HPPA_REG_ZERO, JUMP(1)), ctx); 773 + emit(hppa_beq(HPPA_REG_T1, HPPA_REG_ZERO, NO_JUMP(0)), ctx); 774 + break; 775 + default: 776 + WARN_ON(1); 777 + } 778 + 779 + #undef NO_JUMP 780 + #undef JUMP 781 + 782 + e = ctx->ninsns; 783 + /* Adjust for extra insns. */ 784 + paoff -= (e - s); 785 + emit_jump(paoff, true, ctx); 786 + return 0; 787 + } 788 + 789 + static int emit_bcc(u8 op, u8 rd, u8 rs, int paoff, struct hppa_jit_context *ctx) 790 + { 791 + int e, s; 792 + bool far = false; 793 + int off; 794 + 795 + if (op == BPF_JSET) { 796 + /* 797 + * BPF_JSET is a special case: it has no inverse so we always 798 + * treat it as a far branch. 799 + */ 800 + emit(hppa_and(rd, rs, HPPA_REG_T0), ctx); 801 + paoff -= 1; /* reduce offset due to hppa_and() above */ 802 + rd = HPPA_REG_T0; 803 + rs = HPPA_REG_ZERO; 804 + op = BPF_JNE; 805 + } 806 + 807 + s = ctx->ninsns; 808 + 809 + if (!relative_bits_ok(paoff - HPPA_BRANCH_DISPLACEMENT, 12)) { 810 + op = invert_bpf_cond(op); 811 + far = true; 812 + } 813 + 814 + /* 815 + * For a far branch, the condition is negated and we jump over the 816 + * branch itself, and the three instructions from emit_jump. 817 + * For a near branch, just use paoff. 818 + */ 819 + off = far ? (HPPA_BRANCH_DISPLACEMENT - 1) : paoff - HPPA_BRANCH_DISPLACEMENT; 820 + 821 + switch (op) { 822 + /* IF (dst COND src) JUMP off */ 823 + case BPF_JEQ: 824 + emit(hppa_beq(rd, rs, off), ctx); 825 + break; 826 + case BPF_JGT: 827 + emit(hppa_bgtu(rd, rs, off), ctx); 828 + break; 829 + case BPF_JLT: 830 + emit(hppa_bltu(rd, rs, off), ctx); 831 + break; 832 + case BPF_JGE: 833 + emit(hppa_bgeu(rd, rs, off), ctx); 834 + break; 835 + case BPF_JLE: 836 + emit(hppa_bleu(rd, rs, off), ctx); 837 + break; 838 + case BPF_JNE: 839 + emit(hppa_bne(rd, rs, off), ctx); 840 + break; 841 + case BPF_JSGT: 842 + emit(hppa_bgt(rd, rs, off), ctx); 843 + break; 844 + case BPF_JSLT: 845 + emit(hppa_blt(rd, rs, off), ctx); 846 + break; 847 + case BPF_JSGE: 848 + emit(hppa_bge(rd, rs, off), ctx); 849 + break; 850 + case BPF_JSLE: 851 + emit(hppa_ble(rd, rs, off), ctx); 852 + break; 853 + default: 854 + WARN_ON(1); 855 + } 856 + 857 + if (far) { 858 + e = ctx->ninsns; 859 + /* Adjust for extra insns. */ 860 + paoff -= (e - s); 861 + emit_jump(paoff, true, ctx); 862 + } 863 + return 0; 864 + } 865 + 866 + static int emit_branch_r32(const s8 *src1, const s8 *src2, s32 paoff, 867 + struct hppa_jit_context *ctx, const u8 op) 868 + { 869 + int e, s = ctx->ninsns; 870 + const s8 *tmp1 = regmap[TMP_REG_1]; 871 + const s8 *tmp2 = regmap[TMP_REG_2]; 872 + 873 + const s8 *rs1 = bpf_get_reg32(src1, tmp1, ctx); 874 + const s8 *rs2 = bpf_get_reg32(src2, tmp2, ctx); 875 + 876 + e = ctx->ninsns; 877 + /* Adjust for extra insns. */ 878 + paoff -= (e - s); 879 + 880 + if (emit_bcc(op, lo(rs1), lo(rs2), paoff, ctx)) 881 + return -1; 882 + 883 + return 0; 884 + } 885 + 886 + static void emit_call(bool fixed, u64 addr, struct hppa_jit_context *ctx) 887 + { 888 + const s8 *tmp = regmap[TMP_REG_1]; 889 + const s8 *r0 = regmap[BPF_REG_0]; 890 + const s8 *reg; 891 + const int offset_sp = 2 * STACK_ALIGN; 892 + 893 + /* prepare stack */ 894 + emit(hppa_ldo(offset_sp, HPPA_REG_SP, HPPA_REG_SP), ctx); 895 + 896 + /* load R1 & R2 in registers, R3-R5 to stack. */ 897 + reg = bpf_get_reg64_offset(regmap[BPF_REG_5], tmp, offset_sp, ctx); 898 + emit(hppa_stw(hi(reg), -0x48, HPPA_REG_SP), ctx); 899 + emit(hppa_stw(lo(reg), -0x44, HPPA_REG_SP), ctx); 900 + 901 + reg = bpf_get_reg64_offset(regmap[BPF_REG_4], tmp, offset_sp, ctx); 902 + emit(hppa_stw(hi(reg), -0x40, HPPA_REG_SP), ctx); 903 + emit(hppa_stw(lo(reg), -0x3c, HPPA_REG_SP), ctx); 904 + 905 + reg = bpf_get_reg64_offset(regmap[BPF_REG_3], tmp, offset_sp, ctx); 906 + emit(hppa_stw(hi(reg), -0x38, HPPA_REG_SP), ctx); 907 + emit(hppa_stw(lo(reg), -0x34, HPPA_REG_SP), ctx); 908 + 909 + reg = bpf_get_reg64_offset(regmap[BPF_REG_2], tmp, offset_sp, ctx); 910 + emit_hppa_copy(hi(reg), HPPA_REG_ARG3, ctx); 911 + emit_hppa_copy(lo(reg), HPPA_REG_ARG2, ctx); 912 + 913 + reg = bpf_get_reg64_offset(regmap[BPF_REG_1], tmp, offset_sp, ctx); 914 + emit_hppa_copy(hi(reg), HPPA_REG_ARG1, ctx); 915 + emit_hppa_copy(lo(reg), HPPA_REG_ARG0, ctx); 916 + 917 + /* backup TCC */ 918 + if (REG_WAS_SEEN(ctx, HPPA_REG_TCC)) 919 + emit(hppa_copy(HPPA_REG_TCC, HPPA_REG_TCC_SAVED), ctx); 920 + 921 + /* 922 + * Use ldil() to load absolute address. Don't use emit_imm as the 923 + * number of emitted instructions should not depend on the value of 924 + * addr. 925 + */ 926 + emit(hppa_ldil(addr, HPPA_REG_R31), ctx); 927 + emit(hppa_be_l(im11(addr) >> 2, HPPA_REG_R31, EXEC_NEXT_INSTR), ctx); 928 + /* set return address in delay slot */ 929 + emit_hppa_copy(HPPA_REG_R31, HPPA_REG_RP, ctx); 930 + 931 + /* restore TCC */ 932 + if (REG_WAS_SEEN(ctx, HPPA_REG_TCC)) 933 + emit(hppa_copy(HPPA_REG_TCC_SAVED, HPPA_REG_TCC), ctx); 934 + 935 + /* restore stack */ 936 + emit(hppa_ldo(-offset_sp, HPPA_REG_SP, HPPA_REG_SP), ctx); 937 + 938 + /* set return value. */ 939 + emit_hppa_copy(HPPA_REG_RET0, hi(r0), ctx); 940 + emit_hppa_copy(HPPA_REG_RET1, lo(r0), ctx); 941 + } 942 + 943 + static int emit_bpf_tail_call(int insn, struct hppa_jit_context *ctx) 944 + { 945 + /* 946 + * R1 -> &ctx 947 + * R2 -> &array 948 + * R3 -> index 949 + */ 950 + int off; 951 + const s8 *arr_reg = regmap[BPF_REG_2]; 952 + const s8 *idx_reg = regmap[BPF_REG_3]; 953 + struct bpf_array bpfa; 954 + struct bpf_prog bpfp; 955 + 956 + /* get address of TCC main exit function for error case into rp */ 957 + emit(EXIT_PTR_LOAD(HPPA_REG_RP), ctx); 958 + 959 + /* max_entries = array->map.max_entries; */ 960 + off = offsetof(struct bpf_array, map.max_entries); 961 + BUILD_BUG_ON(sizeof(bpfa.map.max_entries) != 4); 962 + emit(hppa_ldw(off, lo(arr_reg), HPPA_REG_T1), ctx); 963 + 964 + /* 965 + * if (index >= max_entries) 966 + * goto out; 967 + */ 968 + emit(hppa_bltu(lo(idx_reg), HPPA_REG_T1, 2 - HPPA_BRANCH_DISPLACEMENT), ctx); 969 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 970 + 971 + /* 972 + * if (--tcc < 0) 973 + * goto out; 974 + */ 975 + REG_FORCE_SEEN(ctx, HPPA_REG_TCC); 976 + emit(hppa_ldo(-1, HPPA_REG_TCC, HPPA_REG_TCC), ctx); 977 + emit(hppa_bge(HPPA_REG_TCC, HPPA_REG_ZERO, 2 - HPPA_BRANCH_DISPLACEMENT), ctx); 978 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 979 + 980 + /* 981 + * prog = array->ptrs[index]; 982 + * if (!prog) 983 + * goto out; 984 + */ 985 + BUILD_BUG_ON(sizeof(bpfa.ptrs[0]) != 4); 986 + emit(hppa_sh2add(lo(idx_reg), lo(arr_reg), HPPA_REG_T0), ctx); 987 + off = offsetof(struct bpf_array, ptrs); 988 + BUILD_BUG_ON(!relative_bits_ok(off, 11)); 989 + emit(hppa_ldw(off, HPPA_REG_T0, HPPA_REG_T0), ctx); 990 + emit(hppa_bne(HPPA_REG_T0, HPPA_REG_ZERO, 2 - HPPA_BRANCH_DISPLACEMENT), ctx); 991 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 992 + 993 + /* 994 + * tcc = temp_tcc; 995 + * goto *(prog->bpf_func + 4); 996 + */ 997 + off = offsetof(struct bpf_prog, bpf_func); 998 + BUILD_BUG_ON(!relative_bits_ok(off, 11)); 999 + BUILD_BUG_ON(sizeof(bpfp.bpf_func) != 4); 1000 + emit(hppa_ldw(off, HPPA_REG_T0, HPPA_REG_T0), ctx); 1001 + /* Epilogue jumps to *(t0 + 4). */ 1002 + __build_epilogue(true, ctx); 1003 + return 0; 1004 + } 1005 + 1006 + static int emit_load_r64(const s8 *dst, const s8 *src, s16 off, 1007 + struct hppa_jit_context *ctx, const u8 size) 1008 + { 1009 + const s8 *tmp1 = regmap[TMP_REG_1]; 1010 + const s8 *tmp2 = regmap[TMP_REG_2]; 1011 + const s8 *rd = bpf_get_reg64_ref(dst, tmp1, ctx->prog->aux->verifier_zext, ctx); 1012 + const s8 *rs = bpf_get_reg64(src, tmp2, ctx); 1013 + s8 srcreg; 1014 + 1015 + /* need to calculate address since offset does not fit in 14 bits? */ 1016 + if (relative_bits_ok(off, 14)) 1017 + srcreg = lo(rs); 1018 + else { 1019 + /* need to use R1 here, since addil puts result into R1 */ 1020 + srcreg = HPPA_REG_R1; 1021 + emit(hppa_addil(off, lo(rs)), ctx); 1022 + off = im11(off); 1023 + } 1024 + 1025 + /* LDX: dst = *(size *)(src + off) */ 1026 + switch (size) { 1027 + case BPF_B: 1028 + emit(hppa_ldb(off + 0, srcreg, lo(rd)), ctx); 1029 + if (!ctx->prog->aux->verifier_zext) 1030 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 1031 + break; 1032 + case BPF_H: 1033 + emit(hppa_ldh(off + 0, srcreg, lo(rd)), ctx); 1034 + if (!ctx->prog->aux->verifier_zext) 1035 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 1036 + break; 1037 + case BPF_W: 1038 + emit(hppa_ldw(off + 0, srcreg, lo(rd)), ctx); 1039 + if (!ctx->prog->aux->verifier_zext) 1040 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 1041 + break; 1042 + case BPF_DW: 1043 + emit(hppa_ldw(off + 0, srcreg, hi(rd)), ctx); 1044 + emit(hppa_ldw(off + 4, srcreg, lo(rd)), ctx); 1045 + break; 1046 + } 1047 + 1048 + bpf_put_reg64(dst, rd, ctx); 1049 + return 0; 1050 + } 1051 + 1052 + static int emit_store_r64(const s8 *dst, const s8 *src, s16 off, 1053 + struct hppa_jit_context *ctx, const u8 size, 1054 + const u8 mode) 1055 + { 1056 + const s8 *tmp1 = regmap[TMP_REG_1]; 1057 + const s8 *tmp2 = regmap[TMP_REG_2]; 1058 + const s8 *rd = bpf_get_reg64(dst, tmp1, ctx); 1059 + const s8 *rs = bpf_get_reg64(src, tmp2, ctx); 1060 + s8 dstreg; 1061 + 1062 + /* need to calculate address since offset does not fit in 14 bits? */ 1063 + if (relative_bits_ok(off, 14)) 1064 + dstreg = lo(rd); 1065 + else { 1066 + /* need to use R1 here, since addil puts result into R1 */ 1067 + dstreg = HPPA_REG_R1; 1068 + emit(hppa_addil(off, lo(rd)), ctx); 1069 + off = im11(off); 1070 + } 1071 + 1072 + /* ST: *(size *)(dst + off) = imm */ 1073 + switch (size) { 1074 + case BPF_B: 1075 + emit(hppa_stb(lo(rs), off + 0, dstreg), ctx); 1076 + break; 1077 + case BPF_H: 1078 + emit(hppa_sth(lo(rs), off + 0, dstreg), ctx); 1079 + break; 1080 + case BPF_W: 1081 + emit(hppa_stw(lo(rs), off + 0, dstreg), ctx); 1082 + break; 1083 + case BPF_DW: 1084 + emit(hppa_stw(hi(rs), off + 0, dstreg), ctx); 1085 + emit(hppa_stw(lo(rs), off + 4, dstreg), ctx); 1086 + break; 1087 + } 1088 + 1089 + return 0; 1090 + } 1091 + 1092 + static void emit_rev16(const s8 rd, struct hppa_jit_context *ctx) 1093 + { 1094 + emit(hppa_extru(rd, 23, 8, HPPA_REG_T1), ctx); 1095 + emit(hppa_depwz(rd, 23, 8, HPPA_REG_T1), ctx); 1096 + emit(hppa_extru(HPPA_REG_T1, 31, 16, rd), ctx); 1097 + } 1098 + 1099 + static void emit_rev32(const s8 rs, const s8 rd, struct hppa_jit_context *ctx) 1100 + { 1101 + emit(hppa_shrpw(rs, rs, 16, HPPA_REG_T1), ctx); 1102 + emit(hppa_depwz(HPPA_REG_T1, 15, 8, HPPA_REG_T1), ctx); 1103 + emit(hppa_shrpw(rs, HPPA_REG_T1, 8, rd), ctx); 1104 + } 1105 + 1106 + static void emit_zext64(const s8 *dst, struct hppa_jit_context *ctx) 1107 + { 1108 + const s8 *rd; 1109 + const s8 *tmp1 = regmap[TMP_REG_1]; 1110 + 1111 + rd = bpf_get_reg64(dst, tmp1, ctx); 1112 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 1113 + bpf_put_reg64(dst, rd, ctx); 1114 + } 1115 + 1116 + int bpf_jit_emit_insn(const struct bpf_insn *insn, struct hppa_jit_context *ctx, 1117 + bool extra_pass) 1118 + { 1119 + bool is64 = BPF_CLASS(insn->code) == BPF_ALU64 || 1120 + BPF_CLASS(insn->code) == BPF_JMP; 1121 + int s, e, paoff, i = insn - ctx->prog->insnsi; 1122 + u8 code = insn->code; 1123 + s16 off = insn->off; 1124 + s32 imm = insn->imm; 1125 + 1126 + const s8 *dst = regmap[insn->dst_reg]; 1127 + const s8 *src = regmap[insn->src_reg]; 1128 + const s8 *tmp1 = regmap[TMP_REG_1]; 1129 + const s8 *tmp2 = regmap[TMP_REG_2]; 1130 + 1131 + if (0) printk("CLASS %03d CODE %#02x ALU64:%d BPF_SIZE %#02x " 1132 + "BPF_CODE %#02x src_reg %d dst_reg %d\n", 1133 + BPF_CLASS(code), code, (code & BPF_ALU64) ? 1:0, BPF_SIZE(code), 1134 + BPF_OP(code), insn->src_reg, insn->dst_reg); 1135 + 1136 + switch (code) { 1137 + /* dst = src */ 1138 + case BPF_ALU64 | BPF_MOV | BPF_X: 1139 + 1140 + case BPF_ALU64 | BPF_ADD | BPF_X: 1141 + case BPF_ALU64 | BPF_ADD | BPF_K: 1142 + 1143 + case BPF_ALU64 | BPF_SUB | BPF_X: 1144 + case BPF_ALU64 | BPF_SUB | BPF_K: 1145 + 1146 + case BPF_ALU64 | BPF_AND | BPF_X: 1147 + case BPF_ALU64 | BPF_OR | BPF_X: 1148 + case BPF_ALU64 | BPF_XOR | BPF_X: 1149 + 1150 + case BPF_ALU64 | BPF_MUL | BPF_X: 1151 + case BPF_ALU64 | BPF_MUL | BPF_K: 1152 + 1153 + case BPF_ALU64 | BPF_DIV | BPF_X: 1154 + case BPF_ALU64 | BPF_DIV | BPF_K: 1155 + 1156 + case BPF_ALU64 | BPF_MOD | BPF_X: 1157 + case BPF_ALU64 | BPF_MOD | BPF_K: 1158 + 1159 + case BPF_ALU64 | BPF_LSH | BPF_X: 1160 + case BPF_ALU64 | BPF_RSH | BPF_X: 1161 + case BPF_ALU64 | BPF_ARSH | BPF_X: 1162 + if (BPF_SRC(code) == BPF_K) { 1163 + emit_imm32(tmp2, imm, ctx); 1164 + src = tmp2; 1165 + } 1166 + emit_alu_r64(dst, src, ctx, BPF_OP(code)); 1167 + break; 1168 + 1169 + /* dst = -dst */ 1170 + case BPF_ALU64 | BPF_NEG: 1171 + emit_alu_r64(dst, tmp2, ctx, BPF_OP(code)); 1172 + break; 1173 + 1174 + case BPF_ALU64 | BPF_MOV | BPF_K: 1175 + case BPF_ALU64 | BPF_AND | BPF_K: 1176 + case BPF_ALU64 | BPF_OR | BPF_K: 1177 + case BPF_ALU64 | BPF_XOR | BPF_K: 1178 + case BPF_ALU64 | BPF_LSH | BPF_K: 1179 + case BPF_ALU64 | BPF_RSH | BPF_K: 1180 + case BPF_ALU64 | BPF_ARSH | BPF_K: 1181 + emit_alu_i64(dst, imm, ctx, BPF_OP(code)); 1182 + break; 1183 + 1184 + case BPF_ALU | BPF_MOV | BPF_X: 1185 + if (imm == 1) { 1186 + /* Special mov32 for zext. */ 1187 + emit_zext64(dst, ctx); 1188 + break; 1189 + } 1190 + fallthrough; 1191 + /* dst = dst OP src */ 1192 + case BPF_ALU | BPF_ADD | BPF_X: 1193 + case BPF_ALU | BPF_SUB | BPF_X: 1194 + case BPF_ALU | BPF_AND | BPF_X: 1195 + case BPF_ALU | BPF_OR | BPF_X: 1196 + case BPF_ALU | BPF_XOR | BPF_X: 1197 + 1198 + case BPF_ALU | BPF_MUL | BPF_X: 1199 + case BPF_ALU | BPF_MUL | BPF_K: 1200 + 1201 + case BPF_ALU | BPF_DIV | BPF_X: 1202 + case BPF_ALU | BPF_DIV | BPF_K: 1203 + 1204 + case BPF_ALU | BPF_MOD | BPF_X: 1205 + case BPF_ALU | BPF_MOD | BPF_K: 1206 + 1207 + case BPF_ALU | BPF_LSH | BPF_X: 1208 + case BPF_ALU | BPF_RSH | BPF_X: 1209 + case BPF_ALU | BPF_ARSH | BPF_X: 1210 + if (BPF_SRC(code) == BPF_K) { 1211 + emit_imm32(tmp2, imm, ctx); 1212 + src = tmp2; 1213 + } 1214 + emit_alu_r32(dst, src, ctx, BPF_OP(code)); 1215 + break; 1216 + 1217 + /* dst = dst OP imm */ 1218 + case BPF_ALU | BPF_MOV | BPF_K: 1219 + case BPF_ALU | BPF_ADD | BPF_K: 1220 + case BPF_ALU | BPF_SUB | BPF_K: 1221 + case BPF_ALU | BPF_AND | BPF_K: 1222 + case BPF_ALU | BPF_OR | BPF_K: 1223 + case BPF_ALU | BPF_XOR | BPF_K: 1224 + case BPF_ALU | BPF_LSH | BPF_K: 1225 + case BPF_ALU | BPF_RSH | BPF_K: 1226 + case BPF_ALU | BPF_ARSH | BPF_K: 1227 + /* 1228 + * mul,div,mod are handled in the BPF_X case. 1229 + */ 1230 + emit_alu_i32(dst, imm, ctx, BPF_OP(code)); 1231 + break; 1232 + 1233 + /* dst = -dst */ 1234 + case BPF_ALU | BPF_NEG: 1235 + /* 1236 + * src is ignored---choose tmp2 as a dummy register since it 1237 + * is not on the stack. 1238 + */ 1239 + emit_alu_r32(dst, tmp2, ctx, BPF_OP(code)); 1240 + break; 1241 + 1242 + /* dst = BSWAP##imm(dst) */ 1243 + case BPF_ALU | BPF_END | BPF_FROM_BE: 1244 + { 1245 + const s8 *rd = bpf_get_reg64(dst, tmp1, ctx); 1246 + 1247 + switch (imm) { 1248 + case 16: 1249 + /* zero-extend 16 bits into 64 bits */ 1250 + emit(hppa_extru(lo(rd), 31, 16, lo(rd)), ctx); 1251 + fallthrough; 1252 + case 32: 1253 + /* zero-extend 32 bits into 64 bits */ 1254 + if (!ctx->prog->aux->verifier_zext) 1255 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 1256 + break; 1257 + case 64: 1258 + /* Do nothing. */ 1259 + break; 1260 + default: 1261 + pr_err("bpf-jit: BPF_END imm %d invalid\n", imm); 1262 + return -1; 1263 + } 1264 + 1265 + bpf_put_reg64(dst, rd, ctx); 1266 + break; 1267 + } 1268 + 1269 + case BPF_ALU | BPF_END | BPF_FROM_LE: 1270 + { 1271 + const s8 *rd = bpf_get_reg64(dst, tmp1, ctx); 1272 + 1273 + switch (imm) { 1274 + case 16: 1275 + emit_rev16(lo(rd), ctx); 1276 + if (!ctx->prog->aux->verifier_zext) 1277 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 1278 + break; 1279 + case 32: 1280 + emit_rev32(lo(rd), lo(rd), ctx); 1281 + if (!ctx->prog->aux->verifier_zext) 1282 + emit_hppa_copy(HPPA_REG_ZERO, hi(rd), ctx); 1283 + break; 1284 + case 64: 1285 + /* Swap upper and lower halves, then each half. */ 1286 + emit_hppa_copy(hi(rd), HPPA_REG_T0, ctx); 1287 + emit_rev32(lo(rd), hi(rd), ctx); 1288 + emit_rev32(HPPA_REG_T0, lo(rd), ctx); 1289 + break; 1290 + default: 1291 + pr_err("bpf-jit: BPF_END imm %d invalid\n", imm); 1292 + return -1; 1293 + } 1294 + 1295 + bpf_put_reg64(dst, rd, ctx); 1296 + break; 1297 + } 1298 + /* JUMP off */ 1299 + case BPF_JMP | BPF_JA: 1300 + paoff = hppa_offset(i, off, ctx); 1301 + emit_jump(paoff, false, ctx); 1302 + break; 1303 + /* function call */ 1304 + case BPF_JMP | BPF_CALL: 1305 + { 1306 + bool fixed; 1307 + int ret; 1308 + u64 addr; 1309 + 1310 + ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, &addr, 1311 + &fixed); 1312 + if (ret < 0) 1313 + return ret; 1314 + emit_call(fixed, addr, ctx); 1315 + break; 1316 + } 1317 + /* tail call */ 1318 + case BPF_JMP | BPF_TAIL_CALL: 1319 + REG_SET_SEEN_ALL(ctx); 1320 + if (emit_bpf_tail_call(i, ctx)) 1321 + return -1; 1322 + break; 1323 + /* IF (dst COND imm) JUMP off */ 1324 + case BPF_JMP | BPF_JEQ | BPF_X: 1325 + case BPF_JMP | BPF_JEQ | BPF_K: 1326 + case BPF_JMP32 | BPF_JEQ | BPF_X: 1327 + case BPF_JMP32 | BPF_JEQ | BPF_K: 1328 + 1329 + case BPF_JMP | BPF_JNE | BPF_X: 1330 + case BPF_JMP | BPF_JNE | BPF_K: 1331 + case BPF_JMP32 | BPF_JNE | BPF_X: 1332 + case BPF_JMP32 | BPF_JNE | BPF_K: 1333 + 1334 + case BPF_JMP | BPF_JLE | BPF_X: 1335 + case BPF_JMP | BPF_JLE | BPF_K: 1336 + case BPF_JMP32 | BPF_JLE | BPF_X: 1337 + case BPF_JMP32 | BPF_JLE | BPF_K: 1338 + 1339 + case BPF_JMP | BPF_JLT | BPF_X: 1340 + case BPF_JMP | BPF_JLT | BPF_K: 1341 + case BPF_JMP32 | BPF_JLT | BPF_X: 1342 + case BPF_JMP32 | BPF_JLT | BPF_K: 1343 + 1344 + case BPF_JMP | BPF_JGE | BPF_X: 1345 + case BPF_JMP | BPF_JGE | BPF_K: 1346 + case BPF_JMP32 | BPF_JGE | BPF_X: 1347 + case BPF_JMP32 | BPF_JGE | BPF_K: 1348 + 1349 + case BPF_JMP | BPF_JGT | BPF_X: 1350 + case BPF_JMP | BPF_JGT | BPF_K: 1351 + case BPF_JMP32 | BPF_JGT | BPF_X: 1352 + case BPF_JMP32 | BPF_JGT | BPF_K: 1353 + 1354 + case BPF_JMP | BPF_JSLE | BPF_X: 1355 + case BPF_JMP | BPF_JSLE | BPF_K: 1356 + case BPF_JMP32 | BPF_JSLE | BPF_X: 1357 + case BPF_JMP32 | BPF_JSLE | BPF_K: 1358 + 1359 + case BPF_JMP | BPF_JSLT | BPF_X: 1360 + case BPF_JMP | BPF_JSLT | BPF_K: 1361 + case BPF_JMP32 | BPF_JSLT | BPF_X: 1362 + case BPF_JMP32 | BPF_JSLT | BPF_K: 1363 + 1364 + case BPF_JMP | BPF_JSGE | BPF_X: 1365 + case BPF_JMP | BPF_JSGE | BPF_K: 1366 + case BPF_JMP32 | BPF_JSGE | BPF_X: 1367 + case BPF_JMP32 | BPF_JSGE | BPF_K: 1368 + 1369 + case BPF_JMP | BPF_JSGT | BPF_X: 1370 + case BPF_JMP | BPF_JSGT | BPF_K: 1371 + case BPF_JMP32 | BPF_JSGT | BPF_X: 1372 + case BPF_JMP32 | BPF_JSGT | BPF_K: 1373 + 1374 + case BPF_JMP | BPF_JSET | BPF_X: 1375 + case BPF_JMP | BPF_JSET | BPF_K: 1376 + case BPF_JMP32 | BPF_JSET | BPF_X: 1377 + case BPF_JMP32 | BPF_JSET | BPF_K: 1378 + paoff = hppa_offset(i, off, ctx); 1379 + if (BPF_SRC(code) == BPF_K) { 1380 + s = ctx->ninsns; 1381 + emit_imm32(tmp2, imm, ctx); 1382 + src = tmp2; 1383 + e = ctx->ninsns; 1384 + paoff -= (e - s); 1385 + } 1386 + if (is64) 1387 + emit_branch_r64(dst, src, paoff, ctx, BPF_OP(code)); 1388 + else 1389 + emit_branch_r32(dst, src, paoff, ctx, BPF_OP(code)); 1390 + break; 1391 + /* function return */ 1392 + case BPF_JMP | BPF_EXIT: 1393 + if (i == ctx->prog->len - 1) 1394 + break; 1395 + /* load epilogue function pointer and jump to it. */ 1396 + emit(EXIT_PTR_LOAD(HPPA_REG_RP), ctx); 1397 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 1398 + break; 1399 + 1400 + /* dst = imm64 */ 1401 + case BPF_LD | BPF_IMM | BPF_DW: 1402 + { 1403 + struct bpf_insn insn1 = insn[1]; 1404 + u32 upper = insn1.imm; 1405 + u32 lower = imm; 1406 + const s8 *rd = bpf_get_reg64_ref(dst, tmp1, false, ctx); 1407 + 1408 + if (0 && bpf_pseudo_func(insn)) { 1409 + WARN_ON(upper); /* we are 32-bit! */ 1410 + upper = 0; 1411 + lower = (uintptr_t) dereference_function_descriptor(lower); 1412 + } 1413 + 1414 + emit_imm64(rd, upper, lower, ctx); 1415 + bpf_put_reg64(dst, rd, ctx); 1416 + return 1; 1417 + } 1418 + 1419 + /* LDX: dst = *(size *)(src + off) */ 1420 + case BPF_LDX | BPF_MEM | BPF_B: 1421 + case BPF_LDX | BPF_MEM | BPF_H: 1422 + case BPF_LDX | BPF_MEM | BPF_W: 1423 + case BPF_LDX | BPF_MEM | BPF_DW: 1424 + if (emit_load_r64(dst, src, off, ctx, BPF_SIZE(code))) 1425 + return -1; 1426 + break; 1427 + 1428 + /* speculation barrier */ 1429 + case BPF_ST | BPF_NOSPEC: 1430 + break; 1431 + 1432 + /* ST: *(size *)(dst + off) = imm */ 1433 + case BPF_ST | BPF_MEM | BPF_B: 1434 + case BPF_ST | BPF_MEM | BPF_H: 1435 + case BPF_ST | BPF_MEM | BPF_W: 1436 + case BPF_ST | BPF_MEM | BPF_DW: 1437 + 1438 + case BPF_STX | BPF_MEM | BPF_B: 1439 + case BPF_STX | BPF_MEM | BPF_H: 1440 + case BPF_STX | BPF_MEM | BPF_W: 1441 + case BPF_STX | BPF_MEM | BPF_DW: 1442 + if (BPF_CLASS(code) == BPF_ST) { 1443 + emit_imm32(tmp2, imm, ctx); 1444 + src = tmp2; 1445 + } 1446 + 1447 + if (emit_store_r64(dst, src, off, ctx, BPF_SIZE(code), 1448 + BPF_MODE(code))) 1449 + return -1; 1450 + break; 1451 + 1452 + case BPF_STX | BPF_ATOMIC | BPF_W: 1453 + case BPF_STX | BPF_ATOMIC | BPF_DW: 1454 + pr_info_once( 1455 + "bpf-jit: not supported: atomic operation %02x ***\n", 1456 + insn->imm); 1457 + return -EFAULT; 1458 + 1459 + default: 1460 + pr_err("bpf-jit: unknown opcode %02x\n", code); 1461 + return -EINVAL; 1462 + } 1463 + 1464 + return 0; 1465 + } 1466 + 1467 + void bpf_jit_build_prologue(struct hppa_jit_context *ctx) 1468 + { 1469 + const s8 *tmp = regmap[TMP_REG_1]; 1470 + const s8 *dst, *reg; 1471 + int stack_adjust = 0; 1472 + int i; 1473 + unsigned long addr; 1474 + int bpf_stack_adjust; 1475 + 1476 + /* 1477 + * stack on hppa grows up, so if tail calls are used we need to 1478 + * allocate the maximum stack size 1479 + */ 1480 + if (REG_ALL_SEEN(ctx)) 1481 + bpf_stack_adjust = MAX_BPF_STACK; 1482 + else 1483 + bpf_stack_adjust = ctx->prog->aux->stack_depth; 1484 + bpf_stack_adjust = round_up(bpf_stack_adjust, STACK_ALIGN); 1485 + 1486 + /* make space for callee-saved registers. */ 1487 + stack_adjust += NR_SAVED_REGISTERS * REG_SIZE; 1488 + /* make space for BPF registers on stack. */ 1489 + stack_adjust += BPF_JIT_SCRATCH_REGS * REG_SIZE; 1490 + /* make space for BPF stack. */ 1491 + stack_adjust += bpf_stack_adjust; 1492 + /* round up for stack alignment. */ 1493 + stack_adjust = round_up(stack_adjust, STACK_ALIGN); 1494 + 1495 + /* 1496 + * The first instruction sets the tail-call-counter (TCC) register. 1497 + * This instruction is skipped by tail calls. 1498 + * Use a temporary register instead of a caller-saved register initially. 1499 + */ 1500 + emit(hppa_ldi(MAX_TAIL_CALL_CNT, HPPA_REG_TCC_IN_INIT), ctx); 1501 + 1502 + /* 1503 + * skip all initializations when called as BPF TAIL call. 1504 + */ 1505 + emit(hppa_ldi(MAX_TAIL_CALL_CNT, HPPA_REG_R1), ctx); 1506 + emit(hppa_bne(HPPA_REG_TCC_IN_INIT, HPPA_REG_R1, ctx->prologue_len - 2 - HPPA_BRANCH_DISPLACEMENT), ctx); 1507 + 1508 + /* set up hppa stack frame. */ 1509 + emit_hppa_copy(HPPA_REG_SP, HPPA_REG_R1, ctx); // copy sp,r1 (=prev_sp) 1510 + emit(hppa_ldo(stack_adjust, HPPA_REG_SP, HPPA_REG_SP), ctx); // ldo stack_adjust(sp),sp (increase stack) 1511 + emit(hppa_stw(HPPA_REG_R1, -REG_SIZE, HPPA_REG_SP), ctx); // stw prev_sp,-0x04(sp) 1512 + emit(hppa_stw(HPPA_REG_RP, -0x14, HPPA_REG_SP), ctx); // stw rp,-0x14(sp) 1513 + 1514 + REG_FORCE_SEEN(ctx, HPPA_REG_T0); 1515 + REG_FORCE_SEEN(ctx, HPPA_REG_T1); 1516 + REG_FORCE_SEEN(ctx, HPPA_REG_T2); 1517 + REG_FORCE_SEEN(ctx, HPPA_REG_T3); 1518 + REG_FORCE_SEEN(ctx, HPPA_REG_T4); 1519 + REG_FORCE_SEEN(ctx, HPPA_REG_T5); 1520 + 1521 + /* save callee-save registers. */ 1522 + for (i = 3; i <= 18; i++) { 1523 + if (OPTIMIZE_HPPA && !REG_WAS_SEEN(ctx, HPPA_R(i))) 1524 + continue; 1525 + emit(hppa_stw(HPPA_R(i), -REG_SIZE * (8 + (i-3)), HPPA_REG_SP), ctx); // stw ri,-save_area(sp) 1526 + } 1527 + 1528 + /* 1529 + * now really set the tail call counter (TCC) register. 1530 + */ 1531 + if (REG_WAS_SEEN(ctx, HPPA_REG_TCC)) 1532 + emit(hppa_ldi(MAX_TAIL_CALL_CNT, HPPA_REG_TCC), ctx); 1533 + 1534 + /* 1535 + * save epilogue function pointer for outer TCC call chain. 1536 + * The main TCC call stores the final RP on stack. 1537 + */ 1538 + addr = (uintptr_t) &ctx->insns[ctx->epilogue_offset]; 1539 + /* skip first two instructions of exit function, which jump to exit */ 1540 + addr += 2 * HPPA_INSN_SIZE; 1541 + emit(hppa_ldil(addr, HPPA_REG_T2), ctx); 1542 + emit(hppa_ldo(im11(addr), HPPA_REG_T2, HPPA_REG_T2), ctx); 1543 + emit(EXIT_PTR_STORE(HPPA_REG_T2), ctx); 1544 + 1545 + /* load R1 & R2 from registers, R3-R5 from stack. */ 1546 + /* use HPPA_REG_R1 which holds the old stack value */ 1547 + dst = regmap[BPF_REG_5]; 1548 + reg = bpf_get_reg64_ref(dst, tmp, false, ctx); 1549 + if (REG_WAS_SEEN(ctx, lo(reg)) | REG_WAS_SEEN(ctx, hi(reg))) { 1550 + if (REG_WAS_SEEN(ctx, hi(reg))) 1551 + emit(hppa_ldw(-0x48, HPPA_REG_R1, hi(reg)), ctx); 1552 + if (REG_WAS_SEEN(ctx, lo(reg))) 1553 + emit(hppa_ldw(-0x44, HPPA_REG_R1, lo(reg)), ctx); 1554 + bpf_put_reg64(dst, tmp, ctx); 1555 + } 1556 + 1557 + dst = regmap[BPF_REG_4]; 1558 + reg = bpf_get_reg64_ref(dst, tmp, false, ctx); 1559 + if (REG_WAS_SEEN(ctx, lo(reg)) | REG_WAS_SEEN(ctx, hi(reg))) { 1560 + if (REG_WAS_SEEN(ctx, hi(reg))) 1561 + emit(hppa_ldw(-0x40, HPPA_REG_R1, hi(reg)), ctx); 1562 + if (REG_WAS_SEEN(ctx, lo(reg))) 1563 + emit(hppa_ldw(-0x3c, HPPA_REG_R1, lo(reg)), ctx); 1564 + bpf_put_reg64(dst, tmp, ctx); 1565 + } 1566 + 1567 + dst = regmap[BPF_REG_3]; 1568 + reg = bpf_get_reg64_ref(dst, tmp, false, ctx); 1569 + if (REG_WAS_SEEN(ctx, lo(reg)) | REG_WAS_SEEN(ctx, hi(reg))) { 1570 + if (REG_WAS_SEEN(ctx, hi(reg))) 1571 + emit(hppa_ldw(-0x38, HPPA_REG_R1, hi(reg)), ctx); 1572 + if (REG_WAS_SEEN(ctx, lo(reg))) 1573 + emit(hppa_ldw(-0x34, HPPA_REG_R1, lo(reg)), ctx); 1574 + bpf_put_reg64(dst, tmp, ctx); 1575 + } 1576 + 1577 + dst = regmap[BPF_REG_2]; 1578 + reg = bpf_get_reg64_ref(dst, tmp, false, ctx); 1579 + if (REG_WAS_SEEN(ctx, lo(reg)) | REG_WAS_SEEN(ctx, hi(reg))) { 1580 + if (REG_WAS_SEEN(ctx, hi(reg))) 1581 + emit_hppa_copy(HPPA_REG_ARG3, hi(reg), ctx); 1582 + if (REG_WAS_SEEN(ctx, lo(reg))) 1583 + emit_hppa_copy(HPPA_REG_ARG2, lo(reg), ctx); 1584 + bpf_put_reg64(dst, tmp, ctx); 1585 + } 1586 + 1587 + dst = regmap[BPF_REG_1]; 1588 + reg = bpf_get_reg64_ref(dst, tmp, false, ctx); 1589 + if (REG_WAS_SEEN(ctx, lo(reg)) | REG_WAS_SEEN(ctx, hi(reg))) { 1590 + if (REG_WAS_SEEN(ctx, hi(reg))) 1591 + emit_hppa_copy(HPPA_REG_ARG1, hi(reg), ctx); 1592 + if (REG_WAS_SEEN(ctx, lo(reg))) 1593 + emit_hppa_copy(HPPA_REG_ARG0, lo(reg), ctx); 1594 + bpf_put_reg64(dst, tmp, ctx); 1595 + } 1596 + 1597 + /* Set up BPF frame pointer. */ 1598 + dst = regmap[BPF_REG_FP]; 1599 + reg = bpf_get_reg64_ref(dst, tmp, false, ctx); 1600 + if (REG_WAS_SEEN(ctx, lo(reg)) | REG_WAS_SEEN(ctx, hi(reg))) { 1601 + if (REG_WAS_SEEN(ctx, lo(reg))) 1602 + emit(hppa_ldo(-REG_SIZE * (NR_SAVED_REGISTERS + BPF_JIT_SCRATCH_REGS), 1603 + HPPA_REG_SP, lo(reg)), ctx); 1604 + if (REG_WAS_SEEN(ctx, hi(reg))) 1605 + emit_hppa_copy(HPPA_REG_ZERO, hi(reg), ctx); 1606 + bpf_put_reg64(dst, tmp, ctx); 1607 + } 1608 + 1609 + emit(hppa_nop(), ctx); 1610 + } 1611 + 1612 + void bpf_jit_build_epilogue(struct hppa_jit_context *ctx) 1613 + { 1614 + __build_epilogue(false, ctx); 1615 + }
+1209
arch/parisc/net/bpf_jit_comp64.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * BPF JIT compiler for PA-RISC (64-bit) 4 + * 5 + * Copyright(c) 2023 Helge Deller <deller@gmx.de> 6 + * 7 + * The code is based on the BPF JIT compiler for RV64 by Björn Töpel. 8 + * 9 + * TODO: 10 + * - check if bpf_jit_needs_zext() is needed (currently enabled) 11 + * - implement arch_prepare_bpf_trampoline(), poke(), ... 12 + */ 13 + 14 + #include <linux/bitfield.h> 15 + #include <linux/bpf.h> 16 + #include <linux/filter.h> 17 + #include <linux/libgcc.h> 18 + #include "bpf_jit.h" 19 + 20 + static const int regmap[] = { 21 + [BPF_REG_0] = HPPA_REG_RET0, 22 + [BPF_REG_1] = HPPA_R(5), 23 + [BPF_REG_2] = HPPA_R(6), 24 + [BPF_REG_3] = HPPA_R(7), 25 + [BPF_REG_4] = HPPA_R(8), 26 + [BPF_REG_5] = HPPA_R(9), 27 + [BPF_REG_6] = HPPA_R(10), 28 + [BPF_REG_7] = HPPA_R(11), 29 + [BPF_REG_8] = HPPA_R(12), 30 + [BPF_REG_9] = HPPA_R(13), 31 + [BPF_REG_FP] = HPPA_R(14), 32 + [BPF_REG_AX] = HPPA_R(15), 33 + }; 34 + 35 + /* 36 + * Stack layout during BPF program execution (note: stack grows up): 37 + * 38 + * high 39 + * HPPA64 sp => +----------+ <= HPPA64 fp 40 + * | saved sp | 41 + * | saved rp | 42 + * | ... | HPPA64 callee-saved registers 43 + * | curr args| 44 + * | local var| 45 + * +----------+ <= (BPF FP) 46 + * | | 47 + * | ... | BPF program stack 48 + * | | 49 + * | ... | Function call stack 50 + * | | 51 + * +----------+ 52 + * low 53 + */ 54 + 55 + /* Offset from fp for BPF registers stored on stack. */ 56 + #define STACK_ALIGN FRAME_SIZE 57 + 58 + #define EXIT_PTR_LOAD(reg) hppa64_ldd_im16(-FRAME_SIZE, HPPA_REG_SP, reg) 59 + #define EXIT_PTR_STORE(reg) hppa64_std_im16(reg, -FRAME_SIZE, HPPA_REG_SP) 60 + #define EXIT_PTR_JUMP(reg, nop) hppa_bv(HPPA_REG_ZERO, reg, nop) 61 + 62 + static u8 bpf_to_hppa_reg(int bpf_reg, struct hppa_jit_context *ctx) 63 + { 64 + u8 reg = regmap[bpf_reg]; 65 + 66 + REG_SET_SEEN(ctx, reg); 67 + return reg; 68 + }; 69 + 70 + static void emit_hppa_copy(const s8 rs, const s8 rd, struct hppa_jit_context *ctx) 71 + { 72 + REG_SET_SEEN(ctx, rd); 73 + if (OPTIMIZE_HPPA && (rs == rd)) 74 + return; 75 + REG_SET_SEEN(ctx, rs); 76 + emit(hppa_copy(rs, rd), ctx); 77 + } 78 + 79 + static void emit_hppa64_depd(u8 src, u8 pos, u8 len, u8 target, bool no_zero, struct hppa_jit_context *ctx) 80 + { 81 + int c; 82 + 83 + pos &= (BITS_PER_LONG - 1); 84 + pos = 63 - pos; 85 + len = 64 - len; 86 + c = (len < 32) ? 0x4 : 0; 87 + c |= (pos >= 32) ? 0x2 : 0; 88 + c |= (no_zero) ? 0x1 : 0; 89 + emit(hppa_t10_insn(0x3c, target, src, 0, c, pos & 0x1f, len & 0x1f), ctx); 90 + } 91 + 92 + static void emit_hppa64_shld(u8 src, int num, u8 target, struct hppa_jit_context *ctx) 93 + { 94 + emit_hppa64_depd(src, 63-num, 64-num, target, 0, ctx); 95 + } 96 + 97 + static void emit_hppa64_extrd(u8 src, u8 pos, u8 len, u8 target, bool signed_op, struct hppa_jit_context *ctx) 98 + { 99 + int c; 100 + 101 + pos &= (BITS_PER_LONG - 1); 102 + len = 64 - len; 103 + c = (len < 32) ? 0x4 : 0; 104 + c |= (pos >= 32) ? 0x2 : 0; 105 + c |= signed_op ? 0x1 : 0; 106 + emit(hppa_t10_insn(0x36, src, target, 0, c, pos & 0x1f, len & 0x1f), ctx); 107 + } 108 + 109 + static void emit_hppa64_extrw(u8 src, u8 pos, u8 len, u8 target, bool signed_op, struct hppa_jit_context *ctx) 110 + { 111 + int c; 112 + 113 + pos &= (32 - 1); 114 + len = 32 - len; 115 + c = 0x06 | (signed_op ? 1 : 0); 116 + emit(hppa_t10_insn(0x34, src, target, 0, c, pos, len), ctx); 117 + } 118 + 119 + #define emit_hppa64_zext32(r, target, ctx) \ 120 + emit_hppa64_extrd(r, 63, 32, target, false, ctx) 121 + #define emit_hppa64_sext32(r, target, ctx) \ 122 + emit_hppa64_extrd(r, 63, 32, target, true, ctx) 123 + 124 + static void emit_hppa64_shrd(u8 src, int num, u8 target, bool signed_op, struct hppa_jit_context *ctx) 125 + { 126 + emit_hppa64_extrd(src, 63-num, 64-num, target, signed_op, ctx); 127 + } 128 + 129 + static void emit_hppa64_shrw(u8 src, int num, u8 target, bool signed_op, struct hppa_jit_context *ctx) 130 + { 131 + emit_hppa64_extrw(src, 31-num, 32-num, target, signed_op, ctx); 132 + } 133 + 134 + /* Emit variable-length instructions for 32-bit imm */ 135 + static void emit_imm32(u8 rd, s32 imm, struct hppa_jit_context *ctx) 136 + { 137 + u32 lower = im11(imm); 138 + 139 + REG_SET_SEEN(ctx, rd); 140 + if (OPTIMIZE_HPPA && relative_bits_ok(imm, 14)) { 141 + emit(hppa_ldi(imm, rd), ctx); 142 + return; 143 + } 144 + if (OPTIMIZE_HPPA && lower == imm) { 145 + emit(hppa_ldo(lower, HPPA_REG_ZERO, rd), ctx); 146 + return; 147 + } 148 + emit(hppa_ldil(imm, rd), ctx); 149 + if (OPTIMIZE_HPPA && (lower == 0)) 150 + return; 151 + emit(hppa_ldo(lower, rd, rd), ctx); 152 + } 153 + 154 + static bool is_32b_int(s64 val) 155 + { 156 + return val == (s32) val; 157 + } 158 + 159 + /* Emit variable-length instructions for 64-bit imm */ 160 + static void emit_imm(u8 rd, s64 imm, u8 tmpreg, struct hppa_jit_context *ctx) 161 + { 162 + u32 upper32; 163 + 164 + /* get lower 32-bits into rd, sign extended */ 165 + emit_imm32(rd, imm, ctx); 166 + 167 + /* do we have upper 32-bits too ? */ 168 + if (OPTIMIZE_HPPA && is_32b_int(imm)) 169 + return; 170 + 171 + /* load upper 32-bits into lower tmpreg and deposit into rd */ 172 + upper32 = imm >> 32; 173 + if (upper32 || !OPTIMIZE_HPPA) { 174 + emit_imm32(tmpreg, upper32, ctx); 175 + emit_hppa64_depd(tmpreg, 31, 32, rd, 1, ctx); 176 + } else 177 + emit_hppa64_depd(HPPA_REG_ZERO, 31, 32, rd, 1, ctx); 178 + 179 + } 180 + 181 + static int emit_jump(signed long paoff, bool force_far, 182 + struct hppa_jit_context *ctx) 183 + { 184 + unsigned long pc, addr; 185 + 186 + /* Note: Use 2 instructions for jumps if force_far is set. */ 187 + if (relative_bits_ok(paoff - HPPA_BRANCH_DISPLACEMENT, 22)) { 188 + /* use BL,long branch followed by nop() */ 189 + emit(hppa64_bl_long(paoff - HPPA_BRANCH_DISPLACEMENT), ctx); 190 + if (force_far) 191 + emit(hppa_nop(), ctx); 192 + return 0; 193 + } 194 + 195 + pc = (uintptr_t) &ctx->insns[ctx->ninsns]; 196 + addr = pc + (paoff * HPPA_INSN_SIZE); 197 + /* even the 64-bit kernel runs in memory below 4GB */ 198 + if (WARN_ON_ONCE(addr >> 32)) 199 + return -E2BIG; 200 + emit(hppa_ldil(addr, HPPA_REG_R31), ctx); 201 + emit(hppa_be_l(im11(addr) >> 2, HPPA_REG_R31, NOP_NEXT_INSTR), ctx); 202 + return 0; 203 + } 204 + 205 + static void __build_epilogue(bool is_tail_call, struct hppa_jit_context *ctx) 206 + { 207 + int i; 208 + 209 + if (is_tail_call) { 210 + /* 211 + * goto *(t0 + 4); 212 + * Skips first instruction of prologue which initializes tail 213 + * call counter. Assumes t0 contains address of target program, 214 + * see emit_bpf_tail_call. 215 + */ 216 + emit(hppa_ldo(1 * HPPA_INSN_SIZE, HPPA_REG_T0, HPPA_REG_T0), ctx); 217 + emit(hppa_bv(HPPA_REG_ZERO, HPPA_REG_T0, EXEC_NEXT_INSTR), ctx); 218 + /* in delay slot: */ 219 + emit(hppa_copy(HPPA_REG_TCC, HPPA_REG_TCC_IN_INIT), ctx); 220 + 221 + return; 222 + } 223 + 224 + /* load epilogue function pointer and jump to it. */ 225 + /* exit point is either at next instruction, or the outest TCC exit function */ 226 + emit(EXIT_PTR_LOAD(HPPA_REG_RP), ctx); 227 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 228 + 229 + /* NOTE: we are 64-bit and big-endian, so return lower sign-extended 32-bit value */ 230 + emit_hppa64_sext32(regmap[BPF_REG_0], HPPA_REG_RET0, ctx); 231 + 232 + /* Restore callee-saved registers. */ 233 + for (i = 3; i <= 15; i++) { 234 + if (OPTIMIZE_HPPA && !REG_WAS_SEEN(ctx, HPPA_R(i))) 235 + continue; 236 + emit(hppa64_ldd_im16(-REG_SIZE * i, HPPA_REG_SP, HPPA_R(i)), ctx); 237 + } 238 + 239 + /* load original return pointer (stored by outest TCC function) */ 240 + emit(hppa64_ldd_im16(-2*REG_SIZE, HPPA_REG_SP, HPPA_REG_RP), ctx); 241 + emit(hppa_bv(HPPA_REG_ZERO, HPPA_REG_RP, EXEC_NEXT_INSTR), ctx); 242 + /* in delay slot: */ 243 + emit(hppa64_ldd_im5(-REG_SIZE, HPPA_REG_SP, HPPA_REG_SP), ctx); 244 + 245 + emit(hppa_nop(), ctx); // XXX WARUM einer zu wenig ?? 246 + } 247 + 248 + static int emit_branch(u8 op, u8 rd, u8 rs, signed long paoff, 249 + struct hppa_jit_context *ctx) 250 + { 251 + int e, s; 252 + bool far = false; 253 + int off; 254 + 255 + if (op == BPF_JSET) { 256 + /* 257 + * BPF_JSET is a special case: it has no inverse so translate 258 + * to and() function and compare against zero 259 + */ 260 + emit(hppa_and(rd, rs, HPPA_REG_T0), ctx); 261 + paoff -= 1; /* reduce offset due to hppa_and() above */ 262 + rd = HPPA_REG_T0; 263 + rs = HPPA_REG_ZERO; 264 + op = BPF_JNE; 265 + } 266 + 267 + /* set start after BPF_JSET */ 268 + s = ctx->ninsns; 269 + 270 + if (!relative_branch_ok(paoff - HPPA_BRANCH_DISPLACEMENT + 1, 12)) { 271 + op = invert_bpf_cond(op); 272 + far = true; 273 + } 274 + 275 + /* 276 + * For a far branch, the condition is negated and we jump over the 277 + * branch itself, and the two instructions from emit_jump. 278 + * For a near branch, just use paoff. 279 + */ 280 + off = far ? (2 - HPPA_BRANCH_DISPLACEMENT) : paoff - HPPA_BRANCH_DISPLACEMENT; 281 + 282 + switch (op) { 283 + /* IF (dst COND src) JUMP off */ 284 + case BPF_JEQ: 285 + emit(hppa_beq(rd, rs, off), ctx); 286 + break; 287 + case BPF_JGT: 288 + emit(hppa_bgtu(rd, rs, off), ctx); 289 + break; 290 + case BPF_JLT: 291 + emit(hppa_bltu(rd, rs, off), ctx); 292 + break; 293 + case BPF_JGE: 294 + emit(hppa_bgeu(rd, rs, off), ctx); 295 + break; 296 + case BPF_JLE: 297 + emit(hppa_bleu(rd, rs, off), ctx); 298 + break; 299 + case BPF_JNE: 300 + emit(hppa_bne(rd, rs, off), ctx); 301 + break; 302 + case BPF_JSGT: 303 + emit(hppa_bgt(rd, rs, off), ctx); 304 + break; 305 + case BPF_JSLT: 306 + emit(hppa_blt(rd, rs, off), ctx); 307 + break; 308 + case BPF_JSGE: 309 + emit(hppa_bge(rd, rs, off), ctx); 310 + break; 311 + case BPF_JSLE: 312 + emit(hppa_ble(rd, rs, off), ctx); 313 + break; 314 + default: 315 + WARN_ON(1); 316 + } 317 + 318 + if (far) { 319 + int ret; 320 + e = ctx->ninsns; 321 + /* Adjust for extra insns. */ 322 + paoff -= (e - s); 323 + ret = emit_jump(paoff, true, ctx); 324 + if (ret) 325 + return ret; 326 + } else { 327 + /* 328 + * always allocate 2 nops instead of the far branch to 329 + * reduce translation loops 330 + */ 331 + emit(hppa_nop(), ctx); 332 + emit(hppa_nop(), ctx); 333 + } 334 + return 0; 335 + } 336 + 337 + static void emit_zext_32(u8 reg, struct hppa_jit_context *ctx) 338 + { 339 + emit_hppa64_zext32(reg, reg, ctx); 340 + } 341 + 342 + static void emit_bpf_tail_call(int insn, struct hppa_jit_context *ctx) 343 + { 344 + /* 345 + * R1 -> &ctx 346 + * R2 -> &array 347 + * R3 -> index 348 + */ 349 + int off; 350 + const s8 arr_reg = regmap[BPF_REG_2]; 351 + const s8 idx_reg = regmap[BPF_REG_3]; 352 + struct bpf_array bpfa; 353 + struct bpf_prog bpfp; 354 + 355 + /* if there is any tail call, we need to save & restore all registers */ 356 + REG_SET_SEEN_ALL(ctx); 357 + 358 + /* get address of TCC main exit function for error case into rp */ 359 + emit(EXIT_PTR_LOAD(HPPA_REG_RP), ctx); 360 + 361 + /* max_entries = array->map.max_entries; */ 362 + off = offsetof(struct bpf_array, map.max_entries); 363 + BUILD_BUG_ON(sizeof(bpfa.map.max_entries) != 4); 364 + emit(hppa_ldw(off, arr_reg, HPPA_REG_T1), ctx); 365 + 366 + /* 367 + * if (index >= max_entries) 368 + * goto out; 369 + */ 370 + emit(hppa_bltu(idx_reg, HPPA_REG_T1, 2 - HPPA_BRANCH_DISPLACEMENT), ctx); 371 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 372 + 373 + /* 374 + * if (--tcc < 0) 375 + * goto out; 376 + */ 377 + REG_FORCE_SEEN(ctx, HPPA_REG_TCC); 378 + emit(hppa_ldo(-1, HPPA_REG_TCC, HPPA_REG_TCC), ctx); 379 + emit(hppa_bge(HPPA_REG_TCC, HPPA_REG_ZERO, 2 - HPPA_BRANCH_DISPLACEMENT), ctx); 380 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 381 + 382 + /* 383 + * prog = array->ptrs[index]; 384 + * if (!prog) 385 + * goto out; 386 + */ 387 + BUILD_BUG_ON(sizeof(bpfa.ptrs[0]) != 8); 388 + emit(hppa64_shladd(idx_reg, 3, arr_reg, HPPA_REG_T0), ctx); 389 + off = offsetof(struct bpf_array, ptrs); 390 + BUILD_BUG_ON(off < 16); 391 + emit(hppa64_ldd_im16(off, HPPA_REG_T0, HPPA_REG_T0), ctx); 392 + emit(hppa_bne(HPPA_REG_T0, HPPA_REG_ZERO, 2 - HPPA_BRANCH_DISPLACEMENT), ctx); 393 + emit(EXIT_PTR_JUMP(HPPA_REG_RP, NOP_NEXT_INSTR), ctx); 394 + 395 + /* 396 + * tcc = temp_tcc; 397 + * goto *(prog->bpf_func + 4); 398 + */ 399 + off = offsetof(struct bpf_prog, bpf_func); 400 + BUILD_BUG_ON(off < 16); 401 + BUILD_BUG_ON(sizeof(bpfp.bpf_func) != 8); 402 + emit(hppa64_ldd_im16(off, HPPA_REG_T0, HPPA_REG_T0), ctx); 403 + /* Epilogue jumps to *(t0 + 4). */ 404 + __build_epilogue(true, ctx); 405 + } 406 + 407 + static void init_regs(u8 *rd, u8 *rs, const struct bpf_insn *insn, 408 + struct hppa_jit_context *ctx) 409 + { 410 + u8 code = insn->code; 411 + 412 + switch (code) { 413 + case BPF_JMP | BPF_JA: 414 + case BPF_JMP | BPF_CALL: 415 + case BPF_JMP | BPF_EXIT: 416 + case BPF_JMP | BPF_TAIL_CALL: 417 + break; 418 + default: 419 + *rd = bpf_to_hppa_reg(insn->dst_reg, ctx); 420 + } 421 + 422 + if (code & (BPF_ALU | BPF_X) || code & (BPF_ALU64 | BPF_X) || 423 + code & (BPF_JMP | BPF_X) || code & (BPF_JMP32 | BPF_X) || 424 + code & BPF_LDX || code & BPF_STX) 425 + *rs = bpf_to_hppa_reg(insn->src_reg, ctx); 426 + } 427 + 428 + static void emit_zext_32_rd_rs(u8 *rd, u8 *rs, struct hppa_jit_context *ctx) 429 + { 430 + emit_hppa64_zext32(*rd, HPPA_REG_T2, ctx); 431 + *rd = HPPA_REG_T2; 432 + emit_hppa64_zext32(*rs, HPPA_REG_T1, ctx); 433 + *rs = HPPA_REG_T1; 434 + } 435 + 436 + static void emit_sext_32_rd_rs(u8 *rd, u8 *rs, struct hppa_jit_context *ctx) 437 + { 438 + emit_hppa64_sext32(*rd, HPPA_REG_T2, ctx); 439 + *rd = HPPA_REG_T2; 440 + emit_hppa64_sext32(*rs, HPPA_REG_T1, ctx); 441 + *rs = HPPA_REG_T1; 442 + } 443 + 444 + static void emit_zext_32_rd_t1(u8 *rd, struct hppa_jit_context *ctx) 445 + { 446 + emit_hppa64_zext32(*rd, HPPA_REG_T2, ctx); 447 + *rd = HPPA_REG_T2; 448 + emit_zext_32(HPPA_REG_T1, ctx); 449 + } 450 + 451 + static void emit_sext_32_rd(u8 *rd, struct hppa_jit_context *ctx) 452 + { 453 + emit_hppa64_sext32(*rd, HPPA_REG_T2, ctx); 454 + *rd = HPPA_REG_T2; 455 + } 456 + 457 + static bool is_signed_bpf_cond(u8 cond) 458 + { 459 + return cond == BPF_JSGT || cond == BPF_JSLT || 460 + cond == BPF_JSGE || cond == BPF_JSLE; 461 + } 462 + 463 + static void emit_call(u64 addr, bool fixed, struct hppa_jit_context *ctx) 464 + { 465 + const int offset_sp = 2*FRAME_SIZE; 466 + 467 + emit(hppa_ldo(offset_sp, HPPA_REG_SP, HPPA_REG_SP), ctx); 468 + 469 + emit_hppa_copy(regmap[BPF_REG_1], HPPA_REG_ARG0, ctx); 470 + emit_hppa_copy(regmap[BPF_REG_2], HPPA_REG_ARG1, ctx); 471 + emit_hppa_copy(regmap[BPF_REG_3], HPPA_REG_ARG2, ctx); 472 + emit_hppa_copy(regmap[BPF_REG_4], HPPA_REG_ARG3, ctx); 473 + emit_hppa_copy(regmap[BPF_REG_5], HPPA_REG_ARG4, ctx); 474 + 475 + /* Backup TCC. */ 476 + REG_FORCE_SEEN(ctx, HPPA_REG_TCC_SAVED); 477 + if (REG_WAS_SEEN(ctx, HPPA_REG_TCC)) 478 + emit(hppa_copy(HPPA_REG_TCC, HPPA_REG_TCC_SAVED), ctx); 479 + 480 + /* 481 + * Use ldil() to load absolute address. Don't use emit_imm as the 482 + * number of emitted instructions should not depend on the value of 483 + * addr. 484 + */ 485 + WARN_ON(addr >> 32); 486 + /* load function address and gp from Elf64_Fdesc descriptor */ 487 + emit(hppa_ldil(addr, HPPA_REG_R31), ctx); 488 + emit(hppa_ldo(im11(addr), HPPA_REG_R31, HPPA_REG_R31), ctx); 489 + emit(hppa64_ldd_im16(offsetof(struct elf64_fdesc, addr), 490 + HPPA_REG_R31, HPPA_REG_RP), ctx); 491 + emit(hppa64_bve_l_rp(HPPA_REG_RP), ctx); 492 + emit(hppa64_ldd_im16(offsetof(struct elf64_fdesc, gp), 493 + HPPA_REG_R31, HPPA_REG_GP), ctx); 494 + 495 + /* Restore TCC. */ 496 + if (REG_WAS_SEEN(ctx, HPPA_REG_TCC)) 497 + emit(hppa_copy(HPPA_REG_TCC_SAVED, HPPA_REG_TCC), ctx); 498 + 499 + emit(hppa_ldo(-offset_sp, HPPA_REG_SP, HPPA_REG_SP), ctx); 500 + 501 + /* Set return value. */ 502 + emit_hppa_copy(HPPA_REG_RET0, regmap[BPF_REG_0], ctx); 503 + } 504 + 505 + static void emit_call_libgcc_ll(void *func, const s8 arg0, 506 + const s8 arg1, u8 opcode, struct hppa_jit_context *ctx) 507 + { 508 + u64 func_addr; 509 + 510 + if (BPF_CLASS(opcode) == BPF_ALU) { 511 + emit_hppa64_zext32(arg0, HPPA_REG_ARG0, ctx); 512 + emit_hppa64_zext32(arg1, HPPA_REG_ARG1, ctx); 513 + } else { 514 + emit_hppa_copy(arg0, HPPA_REG_ARG0, ctx); 515 + emit_hppa_copy(arg1, HPPA_REG_ARG1, ctx); 516 + } 517 + 518 + /* libcgcc overwrites HPPA_REG_RET0, so keep copy in HPPA_REG_TCC_SAVED */ 519 + if (arg0 != HPPA_REG_RET0) { 520 + REG_SET_SEEN(ctx, HPPA_REG_TCC_SAVED); 521 + emit(hppa_copy(HPPA_REG_RET0, HPPA_REG_TCC_SAVED), ctx); 522 + } 523 + 524 + /* set up stack */ 525 + emit(hppa_ldo(FRAME_SIZE, HPPA_REG_SP, HPPA_REG_SP), ctx); 526 + 527 + func_addr = (uintptr_t) func; 528 + /* load function func_address and gp from Elf64_Fdesc descriptor */ 529 + emit_imm(HPPA_REG_R31, func_addr, arg0, ctx); 530 + emit(hppa64_ldd_im16(offsetof(struct elf64_fdesc, addr), 531 + HPPA_REG_R31, HPPA_REG_RP), ctx); 532 + /* skip the following bve_l instruction if divisor is 0. */ 533 + if (BPF_OP(opcode) == BPF_DIV || BPF_OP(opcode) == BPF_MOD) { 534 + if (BPF_OP(opcode) == BPF_DIV) 535 + emit_hppa_copy(HPPA_REG_ZERO, HPPA_REG_RET0, ctx); 536 + else { 537 + emit_hppa_copy(HPPA_REG_ARG0, HPPA_REG_RET0, ctx); 538 + } 539 + emit(hppa_beq(HPPA_REG_ARG1, HPPA_REG_ZERO, 2 - HPPA_BRANCH_DISPLACEMENT), ctx); 540 + } 541 + emit(hppa64_bve_l_rp(HPPA_REG_RP), ctx); 542 + emit(hppa64_ldd_im16(offsetof(struct elf64_fdesc, gp), 543 + HPPA_REG_R31, HPPA_REG_GP), ctx); 544 + 545 + emit(hppa_ldo(-FRAME_SIZE, HPPA_REG_SP, HPPA_REG_SP), ctx); 546 + 547 + emit_hppa_copy(HPPA_REG_RET0, arg0, ctx); 548 + 549 + /* restore HPPA_REG_RET0 */ 550 + if (arg0 != HPPA_REG_RET0) 551 + emit(hppa_copy(HPPA_REG_TCC_SAVED, HPPA_REG_RET0), ctx); 552 + } 553 + 554 + static void emit_store(const s8 rd, const s8 rs, s16 off, 555 + struct hppa_jit_context *ctx, const u8 size, 556 + const u8 mode) 557 + { 558 + s8 dstreg; 559 + 560 + /* need to calculate address since offset does not fit in 14 bits? */ 561 + if (relative_bits_ok(off, 14)) 562 + dstreg = rd; 563 + else { 564 + /* need to use R1 here, since addil puts result into R1 */ 565 + dstreg = HPPA_REG_R1; 566 + emit(hppa_addil(off, rd), ctx); 567 + off = im11(off); 568 + } 569 + 570 + switch (size) { 571 + case BPF_B: 572 + emit(hppa_stb(rs, off, dstreg), ctx); 573 + break; 574 + case BPF_H: 575 + emit(hppa_sth(rs, off, dstreg), ctx); 576 + break; 577 + case BPF_W: 578 + emit(hppa_stw(rs, off, dstreg), ctx); 579 + break; 580 + case BPF_DW: 581 + if (off & 7) { 582 + emit(hppa_ldo(off, dstreg, HPPA_REG_R1), ctx); 583 + emit(hppa64_std_im5(rs, 0, HPPA_REG_R1), ctx); 584 + } else if (off >= -16 && off <= 15) 585 + emit(hppa64_std_im5(rs, off, dstreg), ctx); 586 + else 587 + emit(hppa64_std_im16(rs, off, dstreg), ctx); 588 + break; 589 + } 590 + } 591 + 592 + int bpf_jit_emit_insn(const struct bpf_insn *insn, struct hppa_jit_context *ctx, 593 + bool extra_pass) 594 + { 595 + bool is64 = BPF_CLASS(insn->code) == BPF_ALU64 || 596 + BPF_CLASS(insn->code) == BPF_JMP; 597 + int s, e, ret, i = insn - ctx->prog->insnsi; 598 + s64 paoff; 599 + struct bpf_prog_aux *aux = ctx->prog->aux; 600 + u8 rd = -1, rs = -1, code = insn->code; 601 + s16 off = insn->off; 602 + s32 imm = insn->imm; 603 + 604 + init_regs(&rd, &rs, insn, ctx); 605 + 606 + switch (code) { 607 + /* dst = src */ 608 + case BPF_ALU | BPF_MOV | BPF_X: 609 + case BPF_ALU64 | BPF_MOV | BPF_X: 610 + if (imm == 1) { 611 + /* Special mov32 for zext */ 612 + emit_zext_32(rd, ctx); 613 + break; 614 + } 615 + if (!is64 && !aux->verifier_zext) 616 + emit_hppa64_zext32(rs, rd, ctx); 617 + else 618 + emit_hppa_copy(rs, rd, ctx); 619 + break; 620 + 621 + /* dst = dst OP src */ 622 + case BPF_ALU | BPF_ADD | BPF_X: 623 + case BPF_ALU64 | BPF_ADD | BPF_X: 624 + emit(hppa_add(rd, rs, rd), ctx); 625 + if (!is64 && !aux->verifier_zext) 626 + emit_zext_32(rd, ctx); 627 + break; 628 + case BPF_ALU | BPF_SUB | BPF_X: 629 + case BPF_ALU64 | BPF_SUB | BPF_X: 630 + emit(hppa_sub(rd, rs, rd), ctx); 631 + if (!is64 && !aux->verifier_zext) 632 + emit_zext_32(rd, ctx); 633 + break; 634 + case BPF_ALU | BPF_AND | BPF_X: 635 + case BPF_ALU64 | BPF_AND | BPF_X: 636 + emit(hppa_and(rd, rs, rd), ctx); 637 + if (!is64 && !aux->verifier_zext) 638 + emit_zext_32(rd, ctx); 639 + break; 640 + case BPF_ALU | BPF_OR | BPF_X: 641 + case BPF_ALU64 | BPF_OR | BPF_X: 642 + emit(hppa_or(rd, rs, rd), ctx); 643 + if (!is64 && !aux->verifier_zext) 644 + emit_zext_32(rd, ctx); 645 + break; 646 + case BPF_ALU | BPF_XOR | BPF_X: 647 + case BPF_ALU64 | BPF_XOR | BPF_X: 648 + emit(hppa_xor(rd, rs, rd), ctx); 649 + if (!is64 && !aux->verifier_zext && rs != rd) 650 + emit_zext_32(rd, ctx); 651 + break; 652 + case BPF_ALU | BPF_MUL | BPF_K: 653 + case BPF_ALU64 | BPF_MUL | BPF_K: 654 + emit_imm(HPPA_REG_T1, is64 ? (s64)(s32)imm : (u32)imm, HPPA_REG_T2, ctx); 655 + rs = HPPA_REG_T1; 656 + fallthrough; 657 + case BPF_ALU | BPF_MUL | BPF_X: 658 + case BPF_ALU64 | BPF_MUL | BPF_X: 659 + emit_call_libgcc_ll(__muldi3, rd, rs, code, ctx); 660 + if (!is64 && !aux->verifier_zext) 661 + emit_zext_32(rd, ctx); 662 + break; 663 + case BPF_ALU | BPF_DIV | BPF_K: 664 + case BPF_ALU64 | BPF_DIV | BPF_K: 665 + emit_imm(HPPA_REG_T1, is64 ? (s64)(s32)imm : (u32)imm, HPPA_REG_T2, ctx); 666 + rs = HPPA_REG_T1; 667 + fallthrough; 668 + case BPF_ALU | BPF_DIV | BPF_X: 669 + case BPF_ALU64 | BPF_DIV | BPF_X: 670 + emit_call_libgcc_ll(&hppa_div64, rd, rs, code, ctx); 671 + if (!is64 && !aux->verifier_zext) 672 + emit_zext_32(rd, ctx); 673 + break; 674 + case BPF_ALU | BPF_MOD | BPF_K: 675 + case BPF_ALU64 | BPF_MOD | BPF_K: 676 + emit_imm(HPPA_REG_T1, is64 ? (s64)(s32)imm : (u32)imm, HPPA_REG_T2, ctx); 677 + rs = HPPA_REG_T1; 678 + fallthrough; 679 + case BPF_ALU | BPF_MOD | BPF_X: 680 + case BPF_ALU64 | BPF_MOD | BPF_X: 681 + emit_call_libgcc_ll(&hppa_div64_rem, rd, rs, code, ctx); 682 + if (!is64 && !aux->verifier_zext) 683 + emit_zext_32(rd, ctx); 684 + break; 685 + 686 + case BPF_ALU | BPF_LSH | BPF_X: 687 + case BPF_ALU64 | BPF_LSH | BPF_X: 688 + emit_hppa64_sext32(rs, HPPA_REG_T0, ctx); 689 + emit(hppa64_mtsarcm(HPPA_REG_T0), ctx); 690 + if (is64) 691 + emit(hppa64_depdz_sar(rd, rd), ctx); 692 + else 693 + emit(hppa_depwz_sar(rd, rd), ctx); 694 + if (!is64 && !aux->verifier_zext) 695 + emit_zext_32(rd, ctx); 696 + break; 697 + case BPF_ALU | BPF_RSH | BPF_X: 698 + case BPF_ALU64 | BPF_RSH | BPF_X: 699 + emit(hppa_mtsar(rs), ctx); 700 + if (is64) 701 + emit(hppa64_shrpd_sar(rd, rd), ctx); 702 + else 703 + emit(hppa_shrpw_sar(rd, rd), ctx); 704 + if (!is64 && !aux->verifier_zext) 705 + emit_zext_32(rd, ctx); 706 + break; 707 + case BPF_ALU | BPF_ARSH | BPF_X: 708 + case BPF_ALU64 | BPF_ARSH | BPF_X: 709 + emit_hppa64_sext32(rs, HPPA_REG_T0, ctx); 710 + emit(hppa64_mtsarcm(HPPA_REG_T0), ctx); 711 + if (is64) 712 + emit(hppa_extrd_sar(rd, rd, 1), ctx); 713 + else 714 + emit(hppa_extrws_sar(rd, rd), ctx); 715 + if (!is64 && !aux->verifier_zext) 716 + emit_zext_32(rd, ctx); 717 + break; 718 + 719 + /* dst = -dst */ 720 + case BPF_ALU | BPF_NEG: 721 + case BPF_ALU64 | BPF_NEG: 722 + emit(hppa_sub(HPPA_REG_ZERO, rd, rd), ctx); 723 + if (!is64 && !aux->verifier_zext) 724 + emit_zext_32(rd, ctx); 725 + break; 726 + 727 + /* dst = BSWAP##imm(dst) */ 728 + case BPF_ALU | BPF_END | BPF_FROM_BE: 729 + switch (imm) { 730 + case 16: 731 + /* zero-extend 16 bits into 64 bits */ 732 + emit_hppa64_depd(HPPA_REG_ZERO, 63-16, 64-16, rd, 1, ctx); 733 + break; 734 + case 32: 735 + if (!aux->verifier_zext) 736 + emit_zext_32(rd, ctx); 737 + break; 738 + case 64: 739 + /* Do nothing */ 740 + break; 741 + } 742 + break; 743 + 744 + case BPF_ALU | BPF_END | BPF_FROM_LE: 745 + switch (imm) { 746 + case 16: 747 + emit(hppa_extru(rd, 31 - 8, 8, HPPA_REG_T1), ctx); 748 + emit(hppa_depwz(rd, 23, 8, HPPA_REG_T1), ctx); 749 + emit(hppa_extru(HPPA_REG_T1, 31, 16, rd), ctx); 750 + emit_hppa64_extrd(HPPA_REG_T1, 63, 16, rd, 0, ctx); 751 + break; 752 + case 32: 753 + emit(hppa_shrpw(rd, rd, 16, HPPA_REG_T1), ctx); 754 + emit_hppa64_depd(HPPA_REG_T1, 63-16, 8, HPPA_REG_T1, 1, ctx); 755 + emit(hppa_shrpw(rd, HPPA_REG_T1, 8, HPPA_REG_T1), ctx); 756 + emit_hppa64_extrd(HPPA_REG_T1, 63, 32, rd, 0, ctx); 757 + break; 758 + case 64: 759 + emit(hppa64_permh_3210(rd, HPPA_REG_T1), ctx); 760 + emit(hppa64_hshl(HPPA_REG_T1, 8, HPPA_REG_T2), ctx); 761 + emit(hppa64_hshr_u(HPPA_REG_T1, 8, HPPA_REG_T1), ctx); 762 + emit(hppa_or(HPPA_REG_T2, HPPA_REG_T1, rd), ctx); 763 + break; 764 + default: 765 + pr_err("bpf-jit: BPF_END imm %d invalid\n", imm); 766 + return -1; 767 + } 768 + break; 769 + 770 + /* dst = imm */ 771 + case BPF_ALU | BPF_MOV | BPF_K: 772 + case BPF_ALU64 | BPF_MOV | BPF_K: 773 + emit_imm(rd, imm, HPPA_REG_T2, ctx); 774 + if (!is64 && !aux->verifier_zext) 775 + emit_zext_32(rd, ctx); 776 + break; 777 + 778 + /* dst = dst OP imm */ 779 + case BPF_ALU | BPF_ADD | BPF_K: 780 + case BPF_ALU64 | BPF_ADD | BPF_K: 781 + if (relative_bits_ok(imm, 14)) { 782 + emit(hppa_ldo(imm, rd, rd), ctx); 783 + } else { 784 + emit_imm(HPPA_REG_T1, imm, HPPA_REG_T2, ctx); 785 + emit(hppa_add(rd, HPPA_REG_T1, rd), ctx); 786 + } 787 + if (!is64 && !aux->verifier_zext) 788 + emit_zext_32(rd, ctx); 789 + break; 790 + case BPF_ALU | BPF_SUB | BPF_K: 791 + case BPF_ALU64 | BPF_SUB | BPF_K: 792 + if (relative_bits_ok(-imm, 14)) { 793 + emit(hppa_ldo(-imm, rd, rd), ctx); 794 + } else { 795 + emit_imm(HPPA_REG_T1, imm, HPPA_REG_T2, ctx); 796 + emit(hppa_sub(rd, HPPA_REG_T1, rd), ctx); 797 + } 798 + if (!is64 && !aux->verifier_zext) 799 + emit_zext_32(rd, ctx); 800 + break; 801 + case BPF_ALU | BPF_AND | BPF_K: 802 + case BPF_ALU64 | BPF_AND | BPF_K: 803 + emit_imm(HPPA_REG_T1, imm, HPPA_REG_T2, ctx); 804 + emit(hppa_and(rd, HPPA_REG_T1, rd), ctx); 805 + if (!is64 && !aux->verifier_zext) 806 + emit_zext_32(rd, ctx); 807 + break; 808 + case BPF_ALU | BPF_OR | BPF_K: 809 + case BPF_ALU64 | BPF_OR | BPF_K: 810 + emit_imm(HPPA_REG_T1, imm, HPPA_REG_T2, ctx); 811 + emit(hppa_or(rd, HPPA_REG_T1, rd), ctx); 812 + if (!is64 && !aux->verifier_zext) 813 + emit_zext_32(rd, ctx); 814 + break; 815 + case BPF_ALU | BPF_XOR | BPF_K: 816 + case BPF_ALU64 | BPF_XOR | BPF_K: 817 + emit_imm(HPPA_REG_T1, imm, HPPA_REG_T2, ctx); 818 + emit(hppa_xor(rd, HPPA_REG_T1, rd), ctx); 819 + if (!is64 && !aux->verifier_zext) 820 + emit_zext_32(rd, ctx); 821 + break; 822 + case BPF_ALU | BPF_LSH | BPF_K: 823 + case BPF_ALU64 | BPF_LSH | BPF_K: 824 + if (imm != 0) { 825 + emit_hppa64_shld(rd, imm, rd, ctx); 826 + } 827 + 828 + if (!is64 && !aux->verifier_zext) 829 + emit_zext_32(rd, ctx); 830 + break; 831 + case BPF_ALU | BPF_RSH | BPF_K: 832 + case BPF_ALU64 | BPF_RSH | BPF_K: 833 + if (imm != 0) { 834 + if (is64) 835 + emit_hppa64_shrd(rd, imm, rd, false, ctx); 836 + else 837 + emit_hppa64_shrw(rd, imm, rd, false, ctx); 838 + } 839 + 840 + if (!is64 && !aux->verifier_zext) 841 + emit_zext_32(rd, ctx); 842 + break; 843 + case BPF_ALU | BPF_ARSH | BPF_K: 844 + case BPF_ALU64 | BPF_ARSH | BPF_K: 845 + if (imm != 0) { 846 + if (is64) 847 + emit_hppa64_shrd(rd, imm, rd, true, ctx); 848 + else 849 + emit_hppa64_shrw(rd, imm, rd, true, ctx); 850 + } 851 + 852 + if (!is64 && !aux->verifier_zext) 853 + emit_zext_32(rd, ctx); 854 + break; 855 + 856 + /* JUMP off */ 857 + case BPF_JMP | BPF_JA: 858 + paoff = hppa_offset(i, off, ctx); 859 + ret = emit_jump(paoff, false, ctx); 860 + if (ret) 861 + return ret; 862 + break; 863 + 864 + /* IF (dst COND src) JUMP off */ 865 + case BPF_JMP | BPF_JEQ | BPF_X: 866 + case BPF_JMP32 | BPF_JEQ | BPF_X: 867 + case BPF_JMP | BPF_JGT | BPF_X: 868 + case BPF_JMP32 | BPF_JGT | BPF_X: 869 + case BPF_JMP | BPF_JLT | BPF_X: 870 + case BPF_JMP32 | BPF_JLT | BPF_X: 871 + case BPF_JMP | BPF_JGE | BPF_X: 872 + case BPF_JMP32 | BPF_JGE | BPF_X: 873 + case BPF_JMP | BPF_JLE | BPF_X: 874 + case BPF_JMP32 | BPF_JLE | BPF_X: 875 + case BPF_JMP | BPF_JNE | BPF_X: 876 + case BPF_JMP32 | BPF_JNE | BPF_X: 877 + case BPF_JMP | BPF_JSGT | BPF_X: 878 + case BPF_JMP32 | BPF_JSGT | BPF_X: 879 + case BPF_JMP | BPF_JSLT | BPF_X: 880 + case BPF_JMP32 | BPF_JSLT | BPF_X: 881 + case BPF_JMP | BPF_JSGE | BPF_X: 882 + case BPF_JMP32 | BPF_JSGE | BPF_X: 883 + case BPF_JMP | BPF_JSLE | BPF_X: 884 + case BPF_JMP32 | BPF_JSLE | BPF_X: 885 + case BPF_JMP | BPF_JSET | BPF_X: 886 + case BPF_JMP32 | BPF_JSET | BPF_X: 887 + paoff = hppa_offset(i, off, ctx); 888 + if (!is64) { 889 + s = ctx->ninsns; 890 + if (is_signed_bpf_cond(BPF_OP(code))) 891 + emit_sext_32_rd_rs(&rd, &rs, ctx); 892 + else 893 + emit_zext_32_rd_rs(&rd, &rs, ctx); 894 + e = ctx->ninsns; 895 + 896 + /* Adjust for extra insns */ 897 + paoff -= (e - s); 898 + } 899 + if (BPF_OP(code) == BPF_JSET) { 900 + /* Adjust for and */ 901 + paoff -= 1; 902 + emit(hppa_and(rs, rd, HPPA_REG_T1), ctx); 903 + emit_branch(BPF_JNE, HPPA_REG_T1, HPPA_REG_ZERO, paoff, 904 + ctx); 905 + } else { 906 + emit_branch(BPF_OP(code), rd, rs, paoff, ctx); 907 + } 908 + break; 909 + 910 + /* IF (dst COND imm) JUMP off */ 911 + case BPF_JMP | BPF_JEQ | BPF_K: 912 + case BPF_JMP32 | BPF_JEQ | BPF_K: 913 + case BPF_JMP | BPF_JGT | BPF_K: 914 + case BPF_JMP32 | BPF_JGT | BPF_K: 915 + case BPF_JMP | BPF_JLT | BPF_K: 916 + case BPF_JMP32 | BPF_JLT | BPF_K: 917 + case BPF_JMP | BPF_JGE | BPF_K: 918 + case BPF_JMP32 | BPF_JGE | BPF_K: 919 + case BPF_JMP | BPF_JLE | BPF_K: 920 + case BPF_JMP32 | BPF_JLE | BPF_K: 921 + case BPF_JMP | BPF_JNE | BPF_K: 922 + case BPF_JMP32 | BPF_JNE | BPF_K: 923 + case BPF_JMP | BPF_JSGT | BPF_K: 924 + case BPF_JMP32 | BPF_JSGT | BPF_K: 925 + case BPF_JMP | BPF_JSLT | BPF_K: 926 + case BPF_JMP32 | BPF_JSLT | BPF_K: 927 + case BPF_JMP | BPF_JSGE | BPF_K: 928 + case BPF_JMP32 | BPF_JSGE | BPF_K: 929 + case BPF_JMP | BPF_JSLE | BPF_K: 930 + case BPF_JMP32 | BPF_JSLE | BPF_K: 931 + paoff = hppa_offset(i, off, ctx); 932 + s = ctx->ninsns; 933 + if (imm) { 934 + emit_imm(HPPA_REG_T1, imm, HPPA_REG_T2, ctx); 935 + rs = HPPA_REG_T1; 936 + } else { 937 + rs = HPPA_REG_ZERO; 938 + } 939 + if (!is64) { 940 + if (is_signed_bpf_cond(BPF_OP(code))) 941 + emit_sext_32_rd(&rd, ctx); 942 + else 943 + emit_zext_32_rd_t1(&rd, ctx); 944 + } 945 + e = ctx->ninsns; 946 + 947 + /* Adjust for extra insns */ 948 + paoff -= (e - s); 949 + emit_branch(BPF_OP(code), rd, rs, paoff, ctx); 950 + break; 951 + case BPF_JMP | BPF_JSET | BPF_K: 952 + case BPF_JMP32 | BPF_JSET | BPF_K: 953 + paoff = hppa_offset(i, off, ctx); 954 + s = ctx->ninsns; 955 + emit_imm(HPPA_REG_T1, imm, HPPA_REG_T2, ctx); 956 + emit(hppa_and(HPPA_REG_T1, rd, HPPA_REG_T1), ctx); 957 + /* For jset32, we should clear the upper 32 bits of t1, but 958 + * sign-extension is sufficient here and saves one instruction, 959 + * as t1 is used only in comparison against zero. 960 + */ 961 + if (!is64 && imm < 0) 962 + emit_hppa64_sext32(HPPA_REG_T1, HPPA_REG_T1, ctx); 963 + e = ctx->ninsns; 964 + paoff -= (e - s); 965 + emit_branch(BPF_JNE, HPPA_REG_T1, HPPA_REG_ZERO, paoff, ctx); 966 + break; 967 + /* function call */ 968 + case BPF_JMP | BPF_CALL: 969 + { 970 + bool fixed_addr; 971 + u64 addr; 972 + 973 + ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, 974 + &addr, &fixed_addr); 975 + if (ret < 0) 976 + return ret; 977 + 978 + REG_SET_SEEN_ALL(ctx); 979 + emit_call(addr, fixed_addr, ctx); 980 + break; 981 + } 982 + /* tail call */ 983 + case BPF_JMP | BPF_TAIL_CALL: 984 + emit_bpf_tail_call(i, ctx); 985 + break; 986 + 987 + /* function return */ 988 + case BPF_JMP | BPF_EXIT: 989 + if (i == ctx->prog->len - 1) 990 + break; 991 + 992 + paoff = epilogue_offset(ctx); 993 + ret = emit_jump(paoff, false, ctx); 994 + if (ret) 995 + return ret; 996 + break; 997 + 998 + /* dst = imm64 */ 999 + case BPF_LD | BPF_IMM | BPF_DW: 1000 + { 1001 + struct bpf_insn insn1 = insn[1]; 1002 + u64 imm64 = (u64)insn1.imm << 32 | (u32)imm; 1003 + if (bpf_pseudo_func(insn)) 1004 + imm64 = (uintptr_t)dereference_function_descriptor((void*)imm64); 1005 + emit_imm(rd, imm64, HPPA_REG_T2, ctx); 1006 + 1007 + return 1; 1008 + } 1009 + 1010 + /* LDX: dst = *(size *)(src + off) */ 1011 + case BPF_LDX | BPF_MEM | BPF_B: 1012 + case BPF_LDX | BPF_MEM | BPF_H: 1013 + case BPF_LDX | BPF_MEM | BPF_W: 1014 + case BPF_LDX | BPF_MEM | BPF_DW: 1015 + case BPF_LDX | BPF_PROBE_MEM | BPF_B: 1016 + case BPF_LDX | BPF_PROBE_MEM | BPF_H: 1017 + case BPF_LDX | BPF_PROBE_MEM | BPF_W: 1018 + case BPF_LDX | BPF_PROBE_MEM | BPF_DW: 1019 + { 1020 + u8 srcreg; 1021 + 1022 + /* need to calculate address since offset does not fit in 14 bits? */ 1023 + if (relative_bits_ok(off, 14)) 1024 + srcreg = rs; 1025 + else { 1026 + /* need to use R1 here, since addil puts result into R1 */ 1027 + srcreg = HPPA_REG_R1; 1028 + BUG_ON(rs == HPPA_REG_R1); 1029 + BUG_ON(rd == HPPA_REG_R1); 1030 + emit(hppa_addil(off, rs), ctx); 1031 + off = im11(off); 1032 + } 1033 + 1034 + switch (BPF_SIZE(code)) { 1035 + case BPF_B: 1036 + emit(hppa_ldb(off, srcreg, rd), ctx); 1037 + if (insn_is_zext(&insn[1])) 1038 + return 1; 1039 + break; 1040 + case BPF_H: 1041 + emit(hppa_ldh(off, srcreg, rd), ctx); 1042 + if (insn_is_zext(&insn[1])) 1043 + return 1; 1044 + break; 1045 + case BPF_W: 1046 + emit(hppa_ldw(off, srcreg, rd), ctx); 1047 + if (insn_is_zext(&insn[1])) 1048 + return 1; 1049 + break; 1050 + case BPF_DW: 1051 + if (off & 7) { 1052 + emit(hppa_ldo(off, srcreg, HPPA_REG_R1), ctx); 1053 + emit(hppa64_ldd_reg(HPPA_REG_ZERO, HPPA_REG_R1, rd), ctx); 1054 + } else if (off >= -16 && off <= 15) 1055 + emit(hppa64_ldd_im5(off, srcreg, rd), ctx); 1056 + else 1057 + emit(hppa64_ldd_im16(off, srcreg, rd), ctx); 1058 + break; 1059 + } 1060 + break; 1061 + } 1062 + /* speculation barrier */ 1063 + case BPF_ST | BPF_NOSPEC: 1064 + break; 1065 + 1066 + /* ST: *(size *)(dst + off) = imm */ 1067 + /* STX: *(size *)(dst + off) = src */ 1068 + case BPF_ST | BPF_MEM | BPF_B: 1069 + case BPF_ST | BPF_MEM | BPF_H: 1070 + case BPF_ST | BPF_MEM | BPF_W: 1071 + case BPF_ST | BPF_MEM | BPF_DW: 1072 + 1073 + case BPF_STX | BPF_MEM | BPF_B: 1074 + case BPF_STX | BPF_MEM | BPF_H: 1075 + case BPF_STX | BPF_MEM | BPF_W: 1076 + case BPF_STX | BPF_MEM | BPF_DW: 1077 + if (BPF_CLASS(code) == BPF_ST) { 1078 + emit_imm(HPPA_REG_T2, imm, HPPA_REG_T1, ctx); 1079 + rs = HPPA_REG_T2; 1080 + } 1081 + 1082 + emit_store(rd, rs, off, ctx, BPF_SIZE(code), BPF_MODE(code)); 1083 + break; 1084 + 1085 + case BPF_STX | BPF_ATOMIC | BPF_W: 1086 + case BPF_STX | BPF_ATOMIC | BPF_DW: 1087 + pr_info_once( 1088 + "bpf-jit: not supported: atomic operation %02x ***\n", 1089 + insn->imm); 1090 + return -EFAULT; 1091 + 1092 + default: 1093 + pr_err("bpf-jit: unknown opcode %02x\n", code); 1094 + return -EINVAL; 1095 + } 1096 + 1097 + return 0; 1098 + } 1099 + 1100 + void bpf_jit_build_prologue(struct hppa_jit_context *ctx) 1101 + { 1102 + int bpf_stack_adjust, stack_adjust, i; 1103 + unsigned long addr; 1104 + s8 reg; 1105 + 1106 + /* 1107 + * stack on hppa grows up, so if tail calls are used we need to 1108 + * allocate the maximum stack size 1109 + */ 1110 + if (REG_ALL_SEEN(ctx)) 1111 + bpf_stack_adjust = MAX_BPF_STACK; 1112 + else 1113 + bpf_stack_adjust = ctx->prog->aux->stack_depth; 1114 + bpf_stack_adjust = round_up(bpf_stack_adjust, STACK_ALIGN); 1115 + 1116 + stack_adjust = FRAME_SIZE + bpf_stack_adjust; 1117 + stack_adjust = round_up(stack_adjust, STACK_ALIGN); 1118 + 1119 + /* 1120 + * NOTE: We construct an Elf64_Fdesc descriptor here. 1121 + * The first 4 words initialize the TCC and compares them. 1122 + * Then follows the virtual address of the eBPF function, 1123 + * and the gp for this function. 1124 + * 1125 + * The first instruction sets the tail-call-counter (TCC) register. 1126 + * This instruction is skipped by tail calls. 1127 + * Use a temporary register instead of a caller-saved register initially. 1128 + */ 1129 + REG_FORCE_SEEN(ctx, HPPA_REG_TCC_IN_INIT); 1130 + emit(hppa_ldi(MAX_TAIL_CALL_CNT, HPPA_REG_TCC_IN_INIT), ctx); 1131 + 1132 + /* 1133 + * Skip all initializations when called as BPF TAIL call. 1134 + */ 1135 + emit(hppa_ldi(MAX_TAIL_CALL_CNT, HPPA_REG_R1), ctx); 1136 + emit(hppa_beq(HPPA_REG_TCC_IN_INIT, HPPA_REG_R1, 6 - HPPA_BRANCH_DISPLACEMENT), ctx); 1137 + emit(hppa64_bl_long(ctx->prologue_len - 3 - HPPA_BRANCH_DISPLACEMENT), ctx); 1138 + 1139 + /* store entry address of this eBPF function */ 1140 + addr = (uintptr_t) &ctx->insns[0]; 1141 + emit(addr >> 32, ctx); 1142 + emit(addr & 0xffffffff, ctx); 1143 + 1144 + /* store gp of this eBPF function */ 1145 + asm("copy %%r27,%0" : "=r" (addr) ); 1146 + emit(addr >> 32, ctx); 1147 + emit(addr & 0xffffffff, ctx); 1148 + 1149 + /* Set up hppa stack frame. */ 1150 + emit_hppa_copy(HPPA_REG_SP, HPPA_REG_R1, ctx); 1151 + emit(hppa_ldo(stack_adjust, HPPA_REG_SP, HPPA_REG_SP), ctx); 1152 + emit(hppa64_std_im5 (HPPA_REG_R1, -REG_SIZE, HPPA_REG_SP), ctx); 1153 + emit(hppa64_std_im16(HPPA_REG_RP, -2*REG_SIZE, HPPA_REG_SP), ctx); 1154 + 1155 + /* Save callee-save registers. */ 1156 + for (i = 3; i <= 15; i++) { 1157 + if (OPTIMIZE_HPPA && !REG_WAS_SEEN(ctx, HPPA_R(i))) 1158 + continue; 1159 + emit(hppa64_std_im16(HPPA_R(i), -REG_SIZE * i, HPPA_REG_SP), ctx); 1160 + } 1161 + 1162 + /* load function parameters; load all if we use tail functions */ 1163 + #define LOAD_PARAM(arg, dst) \ 1164 + if (REG_WAS_SEEN(ctx, regmap[dst]) || \ 1165 + REG_WAS_SEEN(ctx, HPPA_REG_TCC)) \ 1166 + emit_hppa_copy(arg, regmap[dst], ctx) 1167 + LOAD_PARAM(HPPA_REG_ARG0, BPF_REG_1); 1168 + LOAD_PARAM(HPPA_REG_ARG1, BPF_REG_2); 1169 + LOAD_PARAM(HPPA_REG_ARG2, BPF_REG_3); 1170 + LOAD_PARAM(HPPA_REG_ARG3, BPF_REG_4); 1171 + LOAD_PARAM(HPPA_REG_ARG4, BPF_REG_5); 1172 + #undef LOAD_PARAM 1173 + 1174 + REG_FORCE_SEEN(ctx, HPPA_REG_T0); 1175 + REG_FORCE_SEEN(ctx, HPPA_REG_T1); 1176 + REG_FORCE_SEEN(ctx, HPPA_REG_T2); 1177 + 1178 + /* 1179 + * Now really set the tail call counter (TCC) register. 1180 + */ 1181 + if (REG_WAS_SEEN(ctx, HPPA_REG_TCC)) 1182 + emit(hppa_ldi(MAX_TAIL_CALL_CNT, HPPA_REG_TCC), ctx); 1183 + 1184 + /* 1185 + * Save epilogue function pointer for outer TCC call chain. 1186 + * The main TCC call stores the final RP on stack. 1187 + */ 1188 + addr = (uintptr_t) &ctx->insns[ctx->epilogue_offset]; 1189 + /* skip first two instructions which jump to exit */ 1190 + addr += 2 * HPPA_INSN_SIZE; 1191 + emit_imm(HPPA_REG_T2, addr, HPPA_REG_T1, ctx); 1192 + emit(EXIT_PTR_STORE(HPPA_REG_T2), ctx); 1193 + 1194 + /* Set up BPF frame pointer. */ 1195 + reg = regmap[BPF_REG_FP]; /* -> HPPA_REG_FP */ 1196 + if (REG_WAS_SEEN(ctx, reg)) { 1197 + emit(hppa_ldo(-FRAME_SIZE, HPPA_REG_SP, reg), ctx); 1198 + } 1199 + } 1200 + 1201 + void bpf_jit_build_epilogue(struct hppa_jit_context *ctx) 1202 + { 1203 + __build_epilogue(false, ctx); 1204 + } 1205 + 1206 + bool bpf_jit_supports_kfunc_call(void) 1207 + { 1208 + return true; 1209 + }
+201
arch/parisc/net/bpf_jit_core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Common functionality for HPPA32 and HPPA64 BPF JIT compilers 4 + * 5 + * Copyright (c) 2023 Helge Deller <deller@gmx.de> 6 + * 7 + */ 8 + 9 + #include <linux/bpf.h> 10 + #include <linux/filter.h> 11 + #include "bpf_jit.h" 12 + 13 + /* Number of iterations to try until offsets converge. */ 14 + #define NR_JIT_ITERATIONS 35 15 + 16 + static int build_body(struct hppa_jit_context *ctx, bool extra_pass, int *offset) 17 + { 18 + const struct bpf_prog *prog = ctx->prog; 19 + int i; 20 + 21 + ctx->reg_seen_collect = true; 22 + for (i = 0; i < prog->len; i++) { 23 + const struct bpf_insn *insn = &prog->insnsi[i]; 24 + int ret; 25 + 26 + ret = bpf_jit_emit_insn(insn, ctx, extra_pass); 27 + /* BPF_LD | BPF_IMM | BPF_DW: skip the next instruction. */ 28 + if (ret > 0) 29 + i++; 30 + if (offset) 31 + offset[i] = ctx->ninsns; 32 + if (ret < 0) 33 + return ret; 34 + } 35 + ctx->reg_seen_collect = false; 36 + return 0; 37 + } 38 + 39 + bool bpf_jit_needs_zext(void) 40 + { 41 + return true; 42 + } 43 + 44 + struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) 45 + { 46 + unsigned int prog_size = 0, extable_size = 0; 47 + bool tmp_blinded = false, extra_pass = false; 48 + struct bpf_prog *tmp, *orig_prog = prog; 49 + int pass = 0, prev_ninsns = 0, prologue_len, i; 50 + struct hppa_jit_data *jit_data; 51 + struct hppa_jit_context *ctx; 52 + 53 + if (!prog->jit_requested) 54 + return orig_prog; 55 + 56 + tmp = bpf_jit_blind_constants(prog); 57 + if (IS_ERR(tmp)) 58 + return orig_prog; 59 + if (tmp != prog) { 60 + tmp_blinded = true; 61 + prog = tmp; 62 + } 63 + 64 + jit_data = prog->aux->jit_data; 65 + if (!jit_data) { 66 + jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); 67 + if (!jit_data) { 68 + prog = orig_prog; 69 + goto out; 70 + } 71 + prog->aux->jit_data = jit_data; 72 + } 73 + 74 + ctx = &jit_data->ctx; 75 + 76 + if (ctx->offset) { 77 + extra_pass = true; 78 + prog_size = sizeof(*ctx->insns) * ctx->ninsns; 79 + goto skip_init_ctx; 80 + } 81 + 82 + ctx->prog = prog; 83 + ctx->offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); 84 + if (!ctx->offset) { 85 + prog = orig_prog; 86 + goto out_offset; 87 + } 88 + for (i = 0; i < prog->len; i++) { 89 + prev_ninsns += 20; 90 + ctx->offset[i] = prev_ninsns; 91 + } 92 + 93 + for (i = 0; i < NR_JIT_ITERATIONS; i++) { 94 + pass++; 95 + ctx->ninsns = 0; 96 + if (build_body(ctx, extra_pass, ctx->offset)) { 97 + prog = orig_prog; 98 + goto out_offset; 99 + } 100 + ctx->body_len = ctx->ninsns; 101 + bpf_jit_build_prologue(ctx); 102 + ctx->prologue_len = ctx->ninsns - ctx->body_len; 103 + ctx->epilogue_offset = ctx->ninsns; 104 + bpf_jit_build_epilogue(ctx); 105 + 106 + if (ctx->ninsns == prev_ninsns) { 107 + if (jit_data->header) 108 + break; 109 + /* obtain the actual image size */ 110 + extable_size = prog->aux->num_exentries * 111 + sizeof(struct exception_table_entry); 112 + prog_size = sizeof(*ctx->insns) * ctx->ninsns; 113 + 114 + jit_data->header = 115 + bpf_jit_binary_alloc(prog_size + extable_size, 116 + &jit_data->image, 117 + sizeof(u32), 118 + bpf_fill_ill_insns); 119 + if (!jit_data->header) { 120 + prog = orig_prog; 121 + goto out_offset; 122 + } 123 + 124 + ctx->insns = (u32 *)jit_data->image; 125 + /* 126 + * Now, when the image is allocated, the image can 127 + * potentially shrink more (auipc/jalr -> jal). 128 + */ 129 + } 130 + prev_ninsns = ctx->ninsns; 131 + } 132 + 133 + if (i == NR_JIT_ITERATIONS) { 134 + pr_err("bpf-jit: image did not converge in <%d passes!\n", i); 135 + if (jit_data->header) 136 + bpf_jit_binary_free(jit_data->header); 137 + prog = orig_prog; 138 + goto out_offset; 139 + } 140 + 141 + if (extable_size) 142 + prog->aux->extable = (void *)ctx->insns + prog_size; 143 + 144 + skip_init_ctx: 145 + pass++; 146 + ctx->ninsns = 0; 147 + 148 + bpf_jit_build_prologue(ctx); 149 + if (build_body(ctx, extra_pass, NULL)) { 150 + bpf_jit_binary_free(jit_data->header); 151 + prog = orig_prog; 152 + goto out_offset; 153 + } 154 + bpf_jit_build_epilogue(ctx); 155 + 156 + if (HPPA_JIT_DEBUG || bpf_jit_enable > 1) { 157 + if (HPPA_JIT_DUMP) 158 + bpf_jit_dump(prog->len, prog_size, pass, ctx->insns); 159 + if (HPPA_JIT_REBOOT) 160 + { extern int machine_restart(char *); machine_restart(""); } 161 + } 162 + 163 + prog->bpf_func = (void *)ctx->insns; 164 + prog->jited = 1; 165 + prog->jited_len = prog_size; 166 + 167 + bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns); 168 + 169 + if (!prog->is_func || extra_pass) { 170 + bpf_jit_binary_lock_ro(jit_data->header); 171 + prologue_len = ctx->epilogue_offset - ctx->body_len; 172 + for (i = 0; i < prog->len; i++) 173 + ctx->offset[i] += prologue_len; 174 + bpf_prog_fill_jited_linfo(prog, ctx->offset); 175 + out_offset: 176 + kfree(ctx->offset); 177 + kfree(jit_data); 178 + prog->aux->jit_data = NULL; 179 + } 180 + out: 181 + if (HPPA_JIT_REBOOT) 182 + { extern int machine_restart(char *); machine_restart(""); } 183 + 184 + if (tmp_blinded) 185 + bpf_jit_prog_release_other(prog, prog == orig_prog ? 186 + tmp : orig_prog); 187 + return prog; 188 + } 189 + 190 + u64 hppa_div64(u64 div, u64 divisor) 191 + { 192 + div = div64_u64(div, divisor); 193 + return div; 194 + } 195 + 196 + u64 hppa_div64_rem(u64 div, u64 divisor) 197 + { 198 + u64 rem; 199 + div64_u64_rem(div, divisor, &rem); 200 + return rem; 201 + }
+2 -1
drivers/parisc/Kconfig
··· 100 100 101 101 config CHASSIS_LCD_LED 102 102 bool "Chassis LCD and LED support" 103 + depends on LEDS_CLASS=y 103 104 default y 104 - select VM_EVENT_COUNTERS 105 + select LEDS_TRIGGERS 105 106 help 106 107 Say Y here if you want to enable support for the Heartbeat, 107 108 Disk/Network activities LEDs on some PA-RISC machines,
+9 -7
drivers/parisc/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 # 3 - # Makefile for most of the non-PCI devices in PA-RISC machines 3 + # Makefile PCI and non-PCI devices in PA-RISC machines 4 + # 5 + # Keep the order below, e.g. 6 + # - ccio before any potential subdevices 7 + # - gsc is required before lasi and wax 8 + # - asp and wax before the EISA adapters for the IRQ regions 9 + # - EISA must come before PCI to be sure it gets IRQ region 4 10 # 5 11 6 - # I/O SAPIC is also on IA64 platforms. 7 - # The two could be merged into a common source some day. 8 12 obj-$(CONFIG_IOSAPIC) += iosapic.o 9 13 obj-$(CONFIG_IOMMU_SBA) += sba_iommu.o 10 14 obj-$(CONFIG_PCI_LBA) += lba_pci.o 11 15 obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o 12 16 13 17 obj-$(CONFIG_GSC) += gsc.o 14 - 15 - obj-$(CONFIG_HPPB) += hppb.o 16 - obj-$(CONFIG_GSC_DINO) += dino.o 17 18 obj-$(CONFIG_GSC_LASI) += lasi.o asp.o 18 19 obj-$(CONFIG_GSC_WAX) += wax.o 19 20 obj-$(CONFIG_EISA) += eisa.o eisa_enumerator.o eisa_eeprom.o 21 + obj-$(CONFIG_HPPB) += hppb.o 22 + obj-$(CONFIG_GSC_DINO) += dino.o 20 23 21 24 obj-$(CONFIG_SUPERIO) += superio.o 22 25 obj-$(CONFIG_CHASSIS_LCD_LED) += led.o 23 26 obj-$(CONFIG_PDC_STABLE) += pdc_stable.o 24 27 obj-y += power.o 25 -
+9 -2
drivers/parisc/asp.c
··· 4 4 * 5 5 * (c) Copyright 2000 The Puffin Group Inc. 6 6 * 7 - * by Helge Deller <deller@gmx.de> 7 + * (c) 2000-2023 by Helge Deller <deller@gmx.de> 8 8 */ 9 9 10 10 #include <linux/errno.h> ··· 118 118 { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00070 }, 119 119 { 0, } 120 120 }; 121 + MODULE_DEVICE_TABLE(parisc, asp_tbl); 121 122 122 - struct parisc_driver asp_driver __refdata = { 123 + static struct parisc_driver asp_driver __refdata = { 123 124 .name = "asp", 124 125 .id_table = asp_tbl, 125 126 .probe = asp_init_chip, 126 127 }; 128 + 129 + static int __init asp_init(void) 130 + { 131 + return register_parisc_driver(&asp_driver); 132 + } 133 + arch_initcall(asp_init);
+10 -15
drivers/parisc/ccio-dma.c
··· 8 8 ** (c) Copyright 2000 Ryan Bradetich 9 9 ** (c) Copyright 2000 Hewlett-Packard Company 10 10 ** 11 - ** 12 - ** 13 11 ** "Real Mode" operation refers to U2/Uturn chip operation. 14 12 ** U2/Uturn were designed to perform coherency checks w/o using 15 13 ** the I/O MMU - basically what x86 does. 16 - ** 17 - ** Philipp Rumpf has a "Real Mode" driver for PCX-W machines at: 18 - ** CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc 19 - ** cvs -z3 co linux/arch/parisc/kernel/dma-rm.c 20 - ** 21 - ** I've rewritten his code to work under TPG's tree. See ccio-rm-dma.c. 22 14 ** 23 15 ** Drawbacks of using Real Mode are: 24 16 ** o outbound DMA is slower - U2 won't prefetch data (GSC+ XQL signal). ··· 62 70 /* depends on proc fs support. But costs CPU performance. */ 63 71 #undef CCIO_COLLECT_STATS 64 72 #endif 65 - 66 - #include <asm/runway.h> /* for proc_runway_root */ 67 73 68 74 #ifdef DEBUG_CCIO_INIT 69 75 #define DBG_INIT(x...) printk(x) ··· 1557 1567 1558 1568 #ifdef CONFIG_PROC_FS 1559 1569 if (ioc_count == 0) { 1560 - proc_create_single(MODULE_NAME, 0, proc_runway_root, 1570 + struct proc_dir_entry *runway; 1571 + 1572 + runway = proc_mkdir("bus/runway", NULL); 1573 + if (runway) { 1574 + proc_create_single(MODULE_NAME, 0, runway, 1561 1575 ccio_proc_info); 1562 - proc_create_single(MODULE_NAME"-bitmap", 0, proc_runway_root, 1576 + proc_create_single(MODULE_NAME"-bitmap", 0, runway, 1563 1577 ccio_proc_bitmap_info); 1578 + } 1564 1579 } 1565 1580 #endif 1566 1581 ioc_count++; ··· 1577 1582 * 1578 1583 * Register this driver. 1579 1584 */ 1580 - void __init ccio_init(void) 1585 + static int __init ccio_init(void) 1581 1586 { 1582 - register_parisc_driver(&ccio_driver); 1587 + return register_parisc_driver(&ccio_driver); 1583 1588 } 1584 - 1589 + arch_initcall(ccio_init);
+3 -3
drivers/parisc/dino.c
··· 1084 1084 * This is the only routine which is NOT static. 1085 1085 * Must be called exactly once before pci_init(). 1086 1086 */ 1087 - void __init dino_init(void) 1087 + static int __init dino_init(void) 1088 1088 { 1089 - register_parisc_driver(&dino_driver); 1089 + return register_parisc_driver(&dino_driver); 1090 1090 } 1091 - 1091 + arch_initcall(dino_init);
+3 -2
drivers/parisc/eisa.c
··· 400 400 .probe = eisa_probe, 401 401 }; 402 402 403 - void __init parisc_eisa_init(void) 403 + static int __init parisc_eisa_init(void) 404 404 { 405 - register_parisc_driver(&eisa_driver); 405 + return register_parisc_driver(&eisa_driver); 406 406 } 407 + arch_initcall(parisc_eisa_init); 407 408 408 409 409 410 static unsigned int eisa_irq_configured;
-15
drivers/parisc/gsc.c
··· 258 258 259 259 return 0; 260 260 } 261 - 262 - extern struct parisc_driver lasi_driver; 263 - extern struct parisc_driver asp_driver; 264 - extern struct parisc_driver wax_driver; 265 - 266 - void __init gsc_init(void) 267 - { 268 - #ifdef CONFIG_GSC_LASI 269 - register_parisc_driver(&lasi_driver); 270 - register_parisc_driver(&asp_driver); 271 - #endif 272 - #ifdef CONFIG_GSC_WAX 273 - register_parisc_driver(&wax_driver); 274 - #endif 275 - }
+4 -3
drivers/parisc/hppb.c
··· 96 96 /** 97 97 * hppb_init - HP-PB bus initialization procedure. 98 98 * 99 - * Register this driver. 99 + * Register this driver. 100 100 */ 101 - void __init hppb_init(void) 101 + static int __init hppb_init(void) 102 102 { 103 - register_parisc_driver(&hppb_driver); 103 + return register_parisc_driver(&hppb_driver); 104 104 } 105 + arch_initcall(hppb_init);
+6 -6
drivers/parisc/iosapic.c
··· 348 348 } 349 349 350 350 351 - 352 - void __init iosapic_init(void) 351 + static int __init iosapic_init(void) 353 352 { 354 353 unsigned long cell = 0; 355 - 356 - DBG("iosapic_init()\n"); 357 354 358 355 #ifdef __LP64__ 359 356 if (is_pdc_pat()) { ··· 368 371 irt_num_entry = iosapic_load_irt(cell, &irt_cell); 369 372 if (irt_num_entry == 0) 370 373 irt_cell = NULL; /* old PDC w/o iosapic */ 374 + 375 + return 0; 371 376 } 377 + arch_initcall(iosapic_init); 372 378 373 379 374 380 /* ··· 890 890 ** o allocate and initialize isi_vector[] 891 891 ** o allocate irq region 892 892 */ 893 - void *iosapic_register(unsigned long hpa) 893 + void *iosapic_register(unsigned long hpa, void __iomem *vaddr) 894 894 { 895 895 struct iosapic_info *isi = NULL; 896 896 struct irt_entry *irte = irt_cell; ··· 919 919 return NULL; 920 920 } 921 921 922 - isi->addr = ioremap(hpa, 4096); 922 + isi->addr = vaddr; 923 923 isi->isi_hpa = hpa; 924 924 isi->isi_version = iosapic_rd_version(isi); 925 925 isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
+19 -18
drivers/parisc/lasi.c
··· 17 17 #include <linux/module.h> 18 18 #include <linux/pm.h> 19 19 #include <linux/types.h> 20 + #include <linux/reboot.h> 20 21 21 22 #include <asm/io.h> 22 23 #include <asm/hardware.h> ··· 146 145 * 1 to PWR_ON_L in the Power Control Register 147 146 * 148 147 */ 149 - 150 - static unsigned long lasi_power_off_hpa __read_mostly; 151 - 152 - static void lasi_power_off(void) 148 + static int lasi_power_off(struct sys_off_data *data) 153 149 { 154 - unsigned long datareg; 150 + struct gsc_asic *lasi = data->cb_data; 155 151 156 - /* calculate addr of the Power Control Register */ 157 - datareg = lasi_power_off_hpa + 0x0000C000; 152 + /* Power down the machine via Power Control Register */ 153 + gsc_writel(0x02, lasi->hpa + 0x0000C000); 158 154 159 - /* Power down the machine */ 160 - gsc_writel(0x02, datareg); 155 + /* might not be reached: */ 156 + return NOTIFY_DONE; 161 157 } 162 158 163 159 static int __init lasi_init_chip(struct parisc_device *dev) 164 160 { 165 - extern void (*chassis_power_off)(void); 166 161 struct gsc_asic *lasi; 167 162 int ret; 168 163 ··· 209 212 210 213 gsc_fixup_irqs(dev, lasi, lasi_choose_irq); 211 214 212 - /* initialize the power off function */ 213 - /* FIXME: Record the LASI HPA for the power off function. This should 214 - * ensure that only the first LASI (the one controlling the power off) 215 - * should set the HPA here */ 216 - lasi_power_off_hpa = lasi->hpa; 217 - chassis_power_off = lasi_power_off; 218 - 215 + /* register the LASI power off function */ 216 + register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, 217 + SYS_OFF_PRIO_DEFAULT, lasi_power_off, lasi); 218 + 219 219 return ret; 220 220 } 221 221 ··· 220 226 { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00081 }, 221 227 { 0, } 222 228 }; 229 + MODULE_DEVICE_TABLE(parisc, lasi_tbl); 223 230 224 - struct parisc_driver lasi_driver __refdata = { 231 + static struct parisc_driver lasi_driver __refdata = { 225 232 .name = "lasi", 226 233 .id_table = lasi_tbl, 227 234 .probe = lasi_init_chip, 228 235 }; 236 + 237 + static int __init lasi_init(void) 238 + { 239 + return register_parisc_driver(&lasi_driver); 240 + } 241 + arch_initcall(lasi_init);
+5 -3
drivers/parisc/lba_pci.c
··· 1535 1535 } 1536 1536 1537 1537 /* Tell I/O SAPIC driver we have a IRQ handler/region. */ 1538 - tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE); 1538 + tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE, 1539 + addr + LBA_IOSAPIC_BASE); 1539 1540 1540 1541 /* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't 1541 1542 ** have an IRT entry will get NULL back from iosapic code. ··· 1682 1681 ** One time initialization to let the world know the LBA was found. 1683 1682 ** Must be called exactly once before pci_init(). 1684 1683 */ 1685 - void __init lba_init(void) 1684 + static int __init lba_init(void) 1686 1685 { 1687 - register_parisc_driver(&lba_driver); 1686 + return register_parisc_driver(&lba_driver); 1688 1687 } 1688 + arch_initcall(lba_init); 1689 1689 1690 1690 /* 1691 1691 ** Initialize the IBASE/IMASK registers for LBA (Elroy).
+382 -607
drivers/parisc/led.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 - * Chassis LCD/LED driver for HP-PARISC workstations 3 + * Chassis LCD/LED driver for HP-PARISC workstations 4 4 * 5 - * (c) Copyright 2000 Red Hat Software 6 - * (c) Copyright 2000 Helge Deller <hdeller@redhat.com> 7 - * (c) Copyright 2001-2009 Helge Deller <deller@gmx.de> 8 - * (c) Copyright 2001 Randolph Chung <tausq@debian.org> 5 + * (c) Copyright 2000 Red Hat Software 6 + * (c) Copyright 2000 Helge Deller <hdeller@redhat.com> 7 + * (c) Copyright 2001 Randolph Chung <tausq@debian.org> 8 + * (c) Copyright 2000-2023 Helge Deller <deller@gmx.de> 9 9 * 10 - * TODO: 11 - * - speed-up calculations with inlined assembler 12 - * - interface to write to second row of LCD from /proc (if technically possible) 10 + * The control of the LEDs and LCDs on PARISC machines has to be done 11 + * completely in software. 13 12 * 14 - * Changes: 15 - * - Audit copy_from_user in led_proc_write. 16 - * Daniele Bellucci <bellucda@tiscali.it> 17 - * - Switch from using a tasklet to a work queue, so the led_LCD_driver 18 - * can sleep. 19 - * David Pye <dmp@davidmpye.dyndns.org> 13 + * The LEDs can be configured at runtime in /sys/class/leds/ 20 14 */ 21 15 22 16 #include <linux/module.h> 23 - #include <linux/stddef.h> /* for offsetof() */ 24 17 #include <linux/init.h> 25 18 #include <linux/types.h> 26 19 #include <linux/ioport.h> 27 20 #include <linux/utsname.h> 28 21 #include <linux/capability.h> 29 22 #include <linux/delay.h> 30 - #include <linux/netdevice.h> 31 - #include <linux/inetdevice.h> 32 - #include <linux/in.h> 33 - #include <linux/interrupt.h> 34 - #include <linux/kernel_stat.h> 35 23 #include <linux/reboot.h> 36 - #include <linux/proc_fs.h> 37 - #include <linux/seq_file.h> 38 - #include <linux/ctype.h> 39 - #include <linux/blkdev.h> 40 - #include <linux/workqueue.h> 41 - #include <linux/rcupdate.h> 24 + #include <linux/uaccess.h> 25 + #include <linux/leds.h> 26 + #include <linux/platform_device.h> 27 + 42 28 #include <asm/io.h> 43 29 #include <asm/processor.h> 44 30 #include <asm/hardware.h> 45 31 #include <asm/param.h> /* HZ */ 46 32 #include <asm/led.h> 47 33 #include <asm/pdc.h> 48 - #include <linux/uaccess.h> 49 34 50 - /* The control of the LEDs and LCDs on PARISC-machines have to be done 51 - completely in software. The necessary calculations are done in a work queue 52 - task which is scheduled regularly, and since the calculations may consume a 53 - relatively large amount of CPU time, some of the calculations can be 54 - turned off with the following variables (controlled via procfs) */ 35 + #define LED_HAS_LCD 1 36 + #define LED_HAS_LED 2 55 37 56 - static int led_type __read_mostly = -1; 57 - static unsigned char lastleds; /* LED state from most recent update */ 58 - static unsigned int led_heartbeat __read_mostly = 1; 59 - static unsigned int led_diskio __read_mostly = 1; 60 - static unsigned int led_lanrxtx __read_mostly = 1; 61 - static char lcd_text[32] __read_mostly; 62 - static char lcd_text_default[32] __read_mostly; 63 - static int lcd_no_led_support __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */ 64 - 65 - 66 - static struct workqueue_struct *led_wq; 67 - static void led_work_func(struct work_struct *); 68 - static DECLARE_DELAYED_WORK(led_task, led_work_func); 69 - 70 - #if 0 71 - #define DPRINTK(x) printk x 72 - #else 73 - #define DPRINTK(x) 74 - #endif 38 + static unsigned char led_type; /* bitmask of LED_HAS_XXX */ 39 + static unsigned char lastleds; /* LED state from most recent update */ 40 + static unsigned char lcd_new_text; 41 + static unsigned char lcd_text[20]; 42 + static unsigned char lcd_text_default[20]; 43 + static unsigned char lcd_no_led_support; /* KittyHawk doesn't support LED on its LCD */ 75 44 76 45 struct lcd_block { 77 46 unsigned char command; /* stores the command byte */ ··· 49 80 }; 50 81 51 82 /* Structure returned by PDC_RETURN_CHASSIS_INFO */ 52 - /* NOTE: we use unsigned long:16 two times, since the following member 83 + /* NOTE: we use unsigned long:16 two times, since the following member 53 84 lcd_cmd_reg_addr needs to be 64bit aligned on 64bit PA2.0-machines */ 54 85 struct pdc_chassis_lcd_info_ret_block { 55 86 unsigned long model:16; /* DISPLAY_MODEL_XXXX */ ··· 69 100 70 101 71 102 /* LCD_CMD and LCD_DATA for KittyHawk machines */ 72 - #define KITTYHAWK_LCD_CMD F_EXTEND(0xf0190000UL) /* 64bit-ready */ 73 - #define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD+1) 103 + #define KITTYHAWK_LCD_CMD F_EXTEND(0xf0190000UL) 104 + #define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD + 1) 74 105 75 - /* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's 106 + /* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's 76 107 * HP seems to have used Sharp/Hitachi HD44780 LCDs most of the time. */ 77 108 static struct pdc_chassis_lcd_info_ret_block 78 - lcd_info __attribute__((aligned(8))) __read_mostly = 109 + lcd_info __attribute__((aligned(8))) = 79 110 { 80 - .model = DISPLAY_MODEL_LCD, 111 + .model = DISPLAY_MODEL_NONE, 81 112 .lcd_width = 16, 82 113 .lcd_cmd_reg_addr = KITTYHAWK_LCD_CMD, 83 114 .lcd_data_reg_addr = KITTYHAWK_LCD_DATA, ··· 86 117 .reset_cmd2 = 0xc0, 87 118 }; 88 119 89 - 90 120 /* direct access to some of the lcd_info variables */ 91 - #define LCD_CMD_REG lcd_info.lcd_cmd_reg_addr 92 - #define LCD_DATA_REG lcd_info.lcd_data_reg_addr 121 + #define LCD_CMD_REG lcd_info.lcd_cmd_reg_addr 122 + #define LCD_DATA_REG lcd_info.lcd_data_reg_addr 93 123 #define LED_DATA_REG lcd_info.lcd_cmd_reg_addr /* LASI & ASP only */ 94 124 95 - #define LED_HASLCD 1 96 - #define LED_NOLCD 0 97 - 98 - /* The workqueue must be created at init-time */ 99 - static int start_task(void) 100 - { 101 - /* Display the default text now */ 102 - if (led_type == LED_HASLCD) lcd_print( lcd_text_default ); 103 - 104 - /* KittyHawk has no LED support on its LCD */ 105 - if (lcd_no_led_support) return 0; 106 - 107 - /* Create the work queue and queue the LED task */ 108 - led_wq = create_singlethread_workqueue("led_wq"); 109 - if (!led_wq) 110 - return -ENOMEM; 111 - 112 - queue_delayed_work(led_wq, &led_task, 0); 113 - 114 - return 0; 115 - } 116 - 117 - device_initcall(start_task); 118 - 119 125 /* ptr to LCD/LED-specific function */ 120 - static void (*led_func_ptr) (unsigned char) __read_mostly; 126 + static void (*led_func_ptr) (unsigned char); 121 127 122 - #ifdef CONFIG_PROC_FS 123 - static int led_proc_show(struct seq_file *m, void *v) 128 + 129 + static void lcd_print_now(void) 124 130 { 125 - switch ((long)m->private) 126 - { 127 - case LED_NOLCD: 128 - seq_printf(m, "Heartbeat: %d\n", led_heartbeat); 129 - seq_printf(m, "Disk IO: %d\n", led_diskio); 130 - seq_printf(m, "LAN Rx/Tx: %d\n", led_lanrxtx); 131 - break; 132 - case LED_HASLCD: 133 - seq_printf(m, "%s\n", lcd_text); 134 - break; 135 - default: 136 - return 0; 131 + int i; 132 + char *str = lcd_text; 133 + 134 + if (lcd_info.model != DISPLAY_MODEL_LCD) 135 + return; 136 + 137 + if (!lcd_new_text) 138 + return; 139 + lcd_new_text = 0; 140 + 141 + /* Set LCD Cursor to 1st character */ 142 + gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG); 143 + udelay(lcd_info.min_cmd_delay); 144 + 145 + /* Print the string */ 146 + for (i = 0; i < lcd_info.lcd_width; i++) { 147 + gsc_writeb(*str ? *str++ : ' ', LCD_DATA_REG); 148 + udelay(lcd_info.min_cmd_delay); 137 149 } 138 - return 0; 139 150 } 140 151 141 - static int led_proc_open(struct inode *inode, struct file *file) 142 - { 143 - return single_open(file, led_proc_show, pde_data(inode)); 144 - } 145 - 146 - 147 - static ssize_t led_proc_write(struct file *file, const char __user *buf, 148 - size_t count, loff_t *pos) 149 - { 150 - void *data = pde_data(file_inode(file)); 151 - char *cur, lbuf[32]; 152 - int d; 153 - 154 - if (!capable(CAP_SYS_ADMIN)) 155 - return -EACCES; 156 - 157 - if (count >= sizeof(lbuf)) 158 - count = sizeof(lbuf)-1; 159 - 160 - if (copy_from_user(lbuf, buf, count)) 161 - return -EFAULT; 162 - lbuf[count] = 0; 163 - 164 - cur = lbuf; 165 - 166 - switch ((long)data) 167 - { 168 - case LED_NOLCD: 169 - d = *cur++ - '0'; 170 - if (d != 0 && d != 1) goto parse_error; 171 - led_heartbeat = d; 172 - 173 - if (*cur++ != ' ') goto parse_error; 174 - 175 - d = *cur++ - '0'; 176 - if (d != 0 && d != 1) goto parse_error; 177 - led_diskio = d; 178 - 179 - if (*cur++ != ' ') goto parse_error; 180 - 181 - d = *cur++ - '0'; 182 - if (d != 0 && d != 1) goto parse_error; 183 - led_lanrxtx = d; 184 - 185 - break; 186 - case LED_HASLCD: 187 - if (*cur && cur[strlen(cur)-1] == '\n') 188 - cur[strlen(cur)-1] = 0; 189 - if (*cur == 0) 190 - cur = lcd_text_default; 191 - lcd_print(cur); 192 - break; 193 - default: 194 - return 0; 195 - } 196 - 197 - return count; 198 - 199 - parse_error: 200 - if ((long)data == LED_NOLCD) 201 - printk(KERN_CRIT "Parse error: expect \"n n n\" (n == 0 or 1) for heartbeat,\ndisk io and lan tx/rx indicators\n"); 202 - return -EINVAL; 203 - } 204 - 205 - static const struct proc_ops led_proc_ops = { 206 - .proc_open = led_proc_open, 207 - .proc_read = seq_read, 208 - .proc_lseek = seq_lseek, 209 - .proc_release = single_release, 210 - .proc_write = led_proc_write, 211 - }; 212 - 213 - static int __init led_create_procfs(void) 214 - { 215 - struct proc_dir_entry *proc_pdc_root = NULL; 216 - struct proc_dir_entry *ent; 217 - 218 - if (led_type == -1) return -1; 219 - 220 - proc_pdc_root = proc_mkdir("pdc", NULL); 221 - if (!proc_pdc_root) return -1; 222 - 223 - if (!lcd_no_led_support) 224 - { 225 - ent = proc_create_data("led", 0644, proc_pdc_root, 226 - &led_proc_ops, (void *)LED_NOLCD); /* LED */ 227 - if (!ent) return -1; 228 - } 229 - 230 - if (led_type == LED_HASLCD) 231 - { 232 - ent = proc_create_data("lcd", 0644, proc_pdc_root, 233 - &led_proc_ops, (void *)LED_HASLCD); /* LCD */ 234 - if (!ent) return -1; 235 - } 236 - 237 - return 0; 238 - } 239 - #endif 240 - 241 - /* 242 - ** 243 - ** led_ASP_driver() 244 - ** 152 + /** 153 + * lcd_print() 154 + * 155 + * @str: string to show on the LCD. If NULL, print current string again. 156 + * 157 + * Displays the given string on the LCD-Display of newer machines. 245 158 */ 159 + void lcd_print(const char *str) 160 + { 161 + /* copy display string to buffer for procfs */ 162 + if (str) 163 + strscpy(lcd_text, str, sizeof(lcd_text)); 164 + lcd_new_text = 1; 165 + 166 + /* print now if LCD without any LEDs */ 167 + if (led_type == LED_HAS_LCD) 168 + lcd_print_now(); 169 + } 170 + 246 171 #define LED_DATA 0x01 /* data to shift (0:on 1:off) */ 247 172 #define LED_STROBE 0x02 /* strobe to clock data */ 173 + 174 + /** 175 + * led_ASP_driver() - LED driver for the ASP controller chip 176 + * 177 + * @leds: bitmap representing the LED status 178 + */ 248 179 static void led_ASP_driver(unsigned char leds) 249 180 { 250 181 int i; ··· 159 290 } 160 291 } 161 292 162 - 163 - /* 164 - ** 165 - ** led_LASI_driver() 166 - ** 293 + /** 294 + * led_LASI_driver() - LED driver for the LASI controller chip 295 + * 296 + * @leds: bitmap representing the LED status 167 297 */ 168 298 static void led_LASI_driver(unsigned char leds) 169 299 { ··· 170 302 gsc_writeb( leds, LED_DATA_REG ); 171 303 } 172 304 173 - 174 - /* 175 - ** 176 - ** led_LCD_driver() 177 - ** 305 + /** 306 + * led_LCD_driver() - LED & LCD driver for LCD chips 307 + * 308 + * @leds: bitmap representing the LED status 178 309 */ 179 310 static void led_LCD_driver(unsigned char leds) 180 311 { 181 - static int i; 182 - static unsigned char mask[4] = { LED_HEARTBEAT, LED_DISK_IO, 312 + static const unsigned char mask[4] = { 313 + LED_HEARTBEAT, LED_DISK_IO, 183 314 LED_LAN_RCV, LED_LAN_TX }; 184 - 185 - static struct lcd_block * blockp[4] = { 315 + 316 + static struct lcd_block * const blockp[4] = { 186 317 &lcd_info.heartbeat, 187 318 &lcd_info.disk_io, 188 319 &lcd_info.lan_rcv, 189 320 &lcd_info.lan_tx 190 321 }; 322 + static unsigned char latest_leds; 323 + int i; 191 324 192 - /* Convert min_cmd_delay to milliseconds */ 193 - unsigned int msec_cmd_delay = 1 + (lcd_info.min_cmd_delay / 1000); 194 - 195 - for (i=0; i<4; ++i) 196 - { 197 - if ((leds & mask[i]) != (lastleds & mask[i])) 198 - { 199 - gsc_writeb( blockp[i]->command, LCD_CMD_REG ); 200 - msleep(msec_cmd_delay); 201 - 202 - gsc_writeb( leds & mask[i] ? blockp[i]->on : 203 - blockp[i]->off, LCD_DATA_REG ); 204 - msleep(msec_cmd_delay); 205 - } 325 + for (i = 0; i < 4; ++i) { 326 + if ((leds & mask[i]) == (latest_leds & mask[i])) 327 + continue; 328 + 329 + gsc_writeb( blockp[i]->command, LCD_CMD_REG ); 330 + udelay(lcd_info.min_cmd_delay); 331 + 332 + gsc_writeb( leds & mask[i] ? blockp[i]->on : 333 + blockp[i]->off, LCD_DATA_REG ); 334 + udelay(lcd_info.min_cmd_delay); 206 335 } 336 + latest_leds = leds; 337 + 338 + lcd_print_now(); 207 339 } 208 340 209 341 210 - /* 211 - ** 212 - ** led_get_net_activity() 213 - ** 214 - ** calculate if there was TX- or RX-throughput on the network interfaces 215 - ** (analog to dev_get_info() from net/core/dev.c) 216 - ** 342 + /** 343 + * lcd_system_halt() 344 + * 345 + * @nb: pointer to the notifier_block structure 346 + * @event: the event (SYS_RESTART, SYS_HALT or SYS_POWER_OFF) 347 + * @buf: pointer to a buffer (not used) 348 + * 349 + * Called by the reboot notifier chain at shutdown. Stops all 350 + * LED/LCD activities. 217 351 */ 218 - static __inline__ int led_get_net_activity(void) 219 - { 220 - #ifndef CONFIG_NET 221 - return 0; 222 - #else 223 - static u64 rx_total_last, tx_total_last; 224 - u64 rx_total, tx_total; 225 - struct net_device *dev; 226 - int retval; 227 - 228 - rx_total = tx_total = 0; 229 - 230 - /* we are running as a workqueue task, so we can use an RCU lookup */ 231 - rcu_read_lock(); 232 - for_each_netdev_rcu(&init_net, dev) { 233 - const struct rtnl_link_stats64 *stats; 234 - struct rtnl_link_stats64 temp; 235 - struct in_device *in_dev = __in_dev_get_rcu(dev); 236 - if (!in_dev || !in_dev->ifa_list) 237 - continue; 238 - if (ipv4_is_loopback(in_dev->ifa_list->ifa_local)) 239 - continue; 240 - stats = dev_get_stats(dev, &temp); 241 - rx_total += stats->rx_packets; 242 - tx_total += stats->tx_packets; 243 - } 244 - rcu_read_unlock(); 245 - 246 - retval = 0; 247 - 248 - if (rx_total != rx_total_last) { 249 - rx_total_last = rx_total; 250 - retval |= LED_LAN_RCV; 251 - } 252 - 253 - if (tx_total != tx_total_last) { 254 - tx_total_last = tx_total; 255 - retval |= LED_LAN_TX; 256 - } 257 - 258 - return retval; 259 - #endif 260 - } 261 - 262 - 263 - /* 264 - ** 265 - ** led_get_diskio_activity() 266 - ** 267 - ** calculate if there was disk-io in the system 268 - ** 269 - */ 270 - static __inline__ int led_get_diskio_activity(void) 271 - { 272 - static unsigned long last_pgpgin, last_pgpgout; 273 - unsigned long events[NR_VM_EVENT_ITEMS]; 274 - int changed; 275 - 276 - all_vm_events(events); 277 - 278 - /* Just use a very simple calculation here. Do not care about overflow, 279 - since we only want to know if there was activity or not. */ 280 - changed = (events[PGPGIN] != last_pgpgin) || 281 - (events[PGPGOUT] != last_pgpgout); 282 - last_pgpgin = events[PGPGIN]; 283 - last_pgpgout = events[PGPGOUT]; 284 - 285 - return (changed ? LED_DISK_IO : 0); 286 - } 287 - 288 - 289 - 290 - /* 291 - ** led_work_func() 292 - ** 293 - ** manages when and which chassis LCD/LED gets updated 294 - 295 - TODO: 296 - - display load average (older machines like 715/64 have 4 "free" LED's for that) 297 - - optimizations 298 - */ 299 - 300 - #define HEARTBEAT_LEN (HZ*10/100) 301 - #define HEARTBEAT_2ND_RANGE_START (HZ*28/100) 302 - #define HEARTBEAT_2ND_RANGE_END (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN) 303 - 304 - #define LED_UPDATE_INTERVAL (1 + (HZ*19/1000)) 305 - 306 - static void led_work_func (struct work_struct *unused) 352 + static int lcd_system_halt(struct notifier_block *nb, unsigned long event, void *buf) 307 353 { 308 - static unsigned long last_jiffies; 309 - static unsigned long count_HZ; /* counter in range 0..HZ */ 310 - unsigned char currentleds = 0; /* stores current value of the LEDs */ 354 + const char *txt; 311 355 312 - /* exit if not initialized */ 313 - if (!led_func_ptr) 314 - return; 315 - 316 - /* increment the heartbeat timekeeper */ 317 - count_HZ += jiffies - last_jiffies; 318 - last_jiffies = jiffies; 319 - if (count_HZ >= HZ) 320 - count_HZ = 0; 321 - 322 - if (likely(led_heartbeat)) 323 - { 324 - /* flash heartbeat-LED like a real heart 325 - * (2 x short then a long delay) 326 - */ 327 - if (count_HZ < HEARTBEAT_LEN || 328 - (count_HZ >= HEARTBEAT_2ND_RANGE_START && 329 - count_HZ < HEARTBEAT_2ND_RANGE_END)) 330 - currentleds |= LED_HEARTBEAT; 331 - } 332 - 333 - if (likely(led_lanrxtx)) currentleds |= led_get_net_activity(); 334 - if (likely(led_diskio)) currentleds |= led_get_diskio_activity(); 335 - 336 - /* blink LEDs if we got an Oops (HPMC) */ 337 - if (unlikely(oops_in_progress)) { 338 - if (boot_cpu_data.cpu_type >= pcxl2) { 339 - /* newer machines don't have loadavg. LEDs, so we 340 - * let all LEDs blink twice per second instead */ 341 - currentleds = (count_HZ <= (HZ/2)) ? 0 : 0xff; 342 - } else { 343 - /* old machines: blink loadavg. LEDs twice per second */ 344 - if (count_HZ <= (HZ/2)) 345 - currentleds &= ~(LED4|LED5|LED6|LED7); 346 - else 347 - currentleds |= (LED4|LED5|LED6|LED7); 348 - } 349 - } 350 - 351 - if (currentleds != lastleds) 352 - { 353 - led_func_ptr(currentleds); /* Update the LCD/LEDs */ 354 - lastleds = currentleds; 355 - } 356 - 357 - queue_delayed_work(led_wq, &led_task, LED_UPDATE_INTERVAL); 358 - } 359 - 360 - /* 361 - ** led_halt() 362 - ** 363 - ** called by the reboot notifier chain at shutdown and stops all 364 - ** LED/LCD activities. 365 - ** 366 - */ 367 - 368 - static int led_halt(struct notifier_block *, unsigned long, void *); 369 - 370 - static struct notifier_block led_notifier = { 371 - .notifier_call = led_halt, 372 - }; 373 - static int notifier_disabled = 0; 374 - 375 - static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) 376 - { 377 - char *txt; 378 - 379 - if (notifier_disabled) 380 - return NOTIFY_OK; 381 - 382 - notifier_disabled = 1; 383 356 switch (event) { 384 357 case SYS_RESTART: txt = "SYSTEM RESTART"; 385 358 break; ··· 230 521 break; 231 522 default: return NOTIFY_DONE; 232 523 } 233 - 234 - /* Cancel the work item and delete the queue */ 235 - if (led_wq) { 236 - cancel_delayed_work_sync(&led_task); 237 - destroy_workqueue(led_wq); 238 - led_wq = NULL; 239 - } 240 - 241 - if (lcd_info.model == DISPLAY_MODEL_LCD) 242 - lcd_print(txt); 243 - else 244 - if (led_func_ptr) 245 - led_func_ptr(0xff); /* turn all LEDs ON */ 246 - 524 + 525 + lcd_print(txt); 526 + 247 527 return NOTIFY_OK; 248 528 } 249 529 250 - /* 251 - ** register_led_driver() 252 - ** 253 - ** registers an external LED or LCD for usage by this driver. 254 - ** currently only LCD-, LASI- and ASP-style LCD/LED's are supported. 255 - ** 256 - */ 530 + static struct notifier_block lcd_system_halt_notifier = { 531 + .notifier_call = lcd_system_halt, 532 + }; 257 533 534 + static void set_led(struct led_classdev *led_cdev, enum led_brightness brightness); 535 + 536 + struct hppa_led { 537 + struct led_classdev led_cdev; 538 + unsigned char led_bit; 539 + }; 540 + #define to_hppa_led(d) container_of(d, struct hppa_led, led_cdev) 541 + 542 + typedef void (*set_handler)(struct led_classdev *, enum led_brightness); 543 + struct led_type { 544 + const char *name; 545 + set_handler handler; 546 + const char *default_trigger; 547 + }; 548 + 549 + #define NUM_LEDS_PER_BOARD 8 550 + struct hppa_drvdata { 551 + struct hppa_led leds[NUM_LEDS_PER_BOARD]; 552 + }; 553 + 554 + static void set_led(struct led_classdev *led_cdev, enum led_brightness brightness) 555 + { 556 + struct hppa_led *p = to_hppa_led(led_cdev); 557 + unsigned char led_bit = p->led_bit; 558 + 559 + if (brightness == LED_OFF) 560 + lastleds &= ~led_bit; 561 + else 562 + lastleds |= led_bit; 563 + 564 + if (led_func_ptr) 565 + led_func_ptr(lastleds); 566 + } 567 + 568 + 569 + static int hppa_led_generic_probe(struct platform_device *pdev, 570 + struct led_type *types) 571 + { 572 + struct hppa_drvdata *p; 573 + int i, err; 574 + 575 + p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); 576 + if (!p) 577 + return -ENOMEM; 578 + 579 + for (i = 0; i < NUM_LEDS_PER_BOARD; i++) { 580 + struct led_classdev *lp = &p->leds[i].led_cdev; 581 + 582 + p->leds[i].led_bit = BIT(i); 583 + lp->name = types[i].name; 584 + lp->brightness = LED_FULL; 585 + lp->brightness_set = types[i].handler; 586 + lp->default_trigger = types[i].default_trigger; 587 + err = led_classdev_register(&pdev->dev, lp); 588 + if (err) { 589 + dev_err(&pdev->dev, "Could not register %s LED\n", 590 + lp->name); 591 + for (i--; i >= 0; i--) 592 + led_classdev_unregister(&p->leds[i].led_cdev); 593 + return err; 594 + } 595 + } 596 + 597 + platform_set_drvdata(pdev, p); 598 + 599 + return 0; 600 + } 601 + 602 + static int platform_led_remove(struct platform_device *pdev) 603 + { 604 + struct hppa_drvdata *p = platform_get_drvdata(pdev); 605 + int i; 606 + 607 + for (i = 0; i < NUM_LEDS_PER_BOARD; i++) 608 + led_classdev_unregister(&p->leds[i].led_cdev); 609 + 610 + return 0; 611 + } 612 + 613 + static struct led_type mainboard_led_types[NUM_LEDS_PER_BOARD] = { 614 + { 615 + .name = "platform-lan-tx", 616 + .handler = set_led, 617 + .default_trigger = "tx", 618 + }, 619 + { 620 + .name = "platform-lan-rx", 621 + .handler = set_led, 622 + .default_trigger = "rx", 623 + }, 624 + { 625 + .name = "platform-disk", 626 + .handler = set_led, 627 + .default_trigger = "disk-activity", 628 + }, 629 + { 630 + .name = "platform-heartbeat", 631 + .handler = set_led, 632 + .default_trigger = "heartbeat", 633 + }, 634 + { 635 + .name = "platform-LED4", 636 + .handler = set_led, 637 + .default_trigger = "panic", 638 + }, 639 + { 640 + .name = "platform-LED5", 641 + .handler = set_led, 642 + .default_trigger = "panic", 643 + }, 644 + { 645 + .name = "platform-LED6", 646 + .handler = set_led, 647 + .default_trigger = "panic", 648 + }, 649 + { 650 + .name = "platform-LED7", 651 + .handler = set_led, 652 + .default_trigger = "panic", 653 + }, 654 + }; 655 + 656 + static int platform_led_probe(struct platform_device *pdev) 657 + { 658 + return hppa_led_generic_probe(pdev, mainboard_led_types); 659 + } 660 + 661 + MODULE_ALIAS("platform:platform-leds"); 662 + 663 + static struct platform_driver hppa_mainboard_led_driver = { 664 + .probe = platform_led_probe, 665 + .remove = platform_led_remove, 666 + .driver = { 667 + .name = "platform-leds", 668 + }, 669 + }; 670 + 671 + static struct platform_driver * const drivers[] = { 672 + &hppa_mainboard_led_driver, 673 + }; 674 + 675 + static struct platform_device platform_leds = { 676 + .name = "platform-leds", 677 + }; 678 + 679 + /** 680 + * register_led_driver() 681 + * 682 + * @model: model type, one of the DISPLAY_MODEL_XXXX values 683 + * @cmd_reg: physical address of cmd register for the LED/LCD 684 + * @data_reg: physical address of data register for the LED/LCD 685 + * 686 + * Registers a chassis LED or LCD which should be driven by this driver. 687 + * Only PDC-based, LASI- or ASP-style LEDs and LCDs are supported. 688 + */ 258 689 int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg) 259 690 { 260 - static int initialized; 261 - 262 - if (initialized || !data_reg) 691 + if (led_func_ptr || !data_reg) 263 692 return 1; 264 - 693 + 694 + /* No LEDs when running in QEMU */ 695 + if (running_on_qemu) 696 + return 1; 697 + 265 698 lcd_info.model = model; /* store the values */ 266 699 LCD_CMD_REG = (cmd_reg == LED_CMD_REG_NONE) ? 0 : cmd_reg; 267 700 268 701 switch (lcd_info.model) { 269 702 case DISPLAY_MODEL_LCD: 270 703 LCD_DATA_REG = data_reg; 271 - printk(KERN_INFO "LCD display at %lx,%lx registered\n", 704 + pr_info("led: LCD display at %#lx and %#lx\n", 272 705 LCD_CMD_REG , LCD_DATA_REG); 273 706 led_func_ptr = led_LCD_driver; 274 - led_type = LED_HASLCD; 707 + if (lcd_no_led_support) 708 + led_type = LED_HAS_LCD; 709 + else 710 + led_type = LED_HAS_LCD | LED_HAS_LED; 275 711 break; 276 712 277 713 case DISPLAY_MODEL_LASI: 278 - /* Skip to register LED in QEMU */ 279 - if (running_on_qemu) 280 - return 1; 281 714 LED_DATA_REG = data_reg; 282 715 led_func_ptr = led_LASI_driver; 283 - printk(KERN_INFO "LED display at %lx registered\n", LED_DATA_REG); 284 - led_type = LED_NOLCD; 716 + pr_info("led: LED display at %#lx\n", LED_DATA_REG); 717 + led_type = LED_HAS_LED; 285 718 break; 286 719 287 720 case DISPLAY_MODEL_OLD_ASP: 288 721 LED_DATA_REG = data_reg; 289 722 led_func_ptr = led_ASP_driver; 290 - printk(KERN_INFO "LED (ASP-style) display at %lx registered\n", 723 + pr_info("led: LED (ASP-style) display at %#lx\n", 291 724 LED_DATA_REG); 292 - led_type = LED_NOLCD; 725 + led_type = LED_HAS_LED; 293 726 break; 294 727 295 728 default: 296 - printk(KERN_ERR "%s: Wrong LCD/LED model %d !\n", 297 - __func__, lcd_info.model); 729 + pr_err("led: Unknown LCD/LED model type %d\n", lcd_info.model); 298 730 return 1; 299 731 } 300 - 301 - /* mark the LCD/LED driver now as initialized and 302 - * register to the reboot notifier chain */ 303 - initialized++; 304 - register_reboot_notifier(&led_notifier); 305 732 306 - /* Ensure the work is queued */ 307 - if (led_wq) { 308 - queue_delayed_work(led_wq, &led_task, 0); 309 - } 733 + platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 310 734 311 - return 0; 735 + return register_reboot_notifier(&lcd_system_halt_notifier); 312 736 } 313 737 314 - /* 315 - ** register_led_regions() 316 - ** 317 - ** register_led_regions() registers the LCD/LED regions for /procfs. 318 - ** At bootup - where the initialisation of the LCD/LED normally happens - 319 - ** not all internal structures of request_region() are properly set up, 320 - ** so that we delay the led-registration until after busdevices_init() 321 - ** has been executed. 322 - ** 738 + /** 739 + * early_led_init() 740 + * 741 + * early_led_init() is called early in the bootup-process and asks the 742 + * PDC for an usable chassis LCD or LED. If the PDC doesn't return any 743 + * info, then a LED might be detected by the LASI or ASP drivers later. 744 + * KittyHawk machines have often a buggy PDC, so that we explicitly check 745 + * for those machines here. 323 746 */ 747 + static int __init early_led_init(void) 748 + { 749 + struct pdc_chassis_info chassis_info; 750 + int ret; 324 751 325 - void __init register_led_regions(void) 752 + snprintf(lcd_text_default, sizeof(lcd_text_default), 753 + "Linux %s", init_utsname()->release); 754 + strcpy(lcd_text, lcd_text_default); 755 + lcd_new_text = 1; 756 + 757 + /* Work around the buggy PDC of KittyHawk-machines */ 758 + switch (CPU_HVERSION) { 759 + case 0x580: /* KittyHawk DC2-100 (K100) */ 760 + case 0x581: /* KittyHawk DC3-120 (K210) */ 761 + case 0x582: /* KittyHawk DC3 100 (K400) */ 762 + case 0x583: /* KittyHawk DC3 120 (K410) */ 763 + case 0x58B: /* KittyHawk DC2 100 (K200) */ 764 + pr_info("LCD on KittyHawk-Machine found.\n"); 765 + lcd_info.model = DISPLAY_MODEL_LCD; 766 + /* KittyHawk has no LED support on its LCD, so skip LED detection */ 767 + lcd_no_led_support = 1; 768 + goto found; /* use the preinitialized values of lcd_info */ 769 + } 770 + 771 + /* initialize the struct, so that we can check for valid return values */ 772 + chassis_info.actcnt = chassis_info.maxcnt = 0; 773 + 774 + ret = pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info)); 775 + if (ret != PDC_OK) { 776 + not_found: 777 + lcd_info.model = DISPLAY_MODEL_NONE; 778 + return 1; 779 + } 780 + 781 + /* check the results. Some machines have a buggy PDC */ 782 + if (chassis_info.actcnt <= 0 || chassis_info.actcnt != chassis_info.maxcnt) 783 + goto not_found; 784 + 785 + switch (lcd_info.model) { 786 + case DISPLAY_MODEL_LCD: /* LCD display */ 787 + if (chassis_info.actcnt < 788 + offsetof(struct pdc_chassis_lcd_info_ret_block, _pad)-1) 789 + goto not_found; 790 + if (!lcd_info.act_enable) { 791 + /* PDC tells LCD should not be used. */ 792 + goto not_found; 793 + } 794 + break; 795 + 796 + case DISPLAY_MODEL_NONE: /* no LED or LCD available */ 797 + goto not_found; 798 + 799 + case DISPLAY_MODEL_LASI: /* Lasi style 8 bit LED display */ 800 + if (chassis_info.actcnt != 8 && chassis_info.actcnt != 32) 801 + goto not_found; 802 + break; 803 + 804 + default: 805 + pr_warn("PDC reported unknown LCD/LED model %d\n", 806 + lcd_info.model); 807 + goto not_found; 808 + } 809 + 810 + found: 811 + /* register the LCD/LED driver */ 812 + return register_led_driver(lcd_info.model, LCD_CMD_REG, LCD_DATA_REG); 813 + } 814 + arch_initcall(early_led_init); 815 + 816 + /** 817 + * register_led_regions() 818 + * 819 + * Register_led_regions() registers the LCD/LED regions for /procfs. 820 + * At bootup - where the initialisation of the LCD/LED often happens 821 + * not all internal structures of request_region() are properly set up, 822 + * so that we delay the led-registration until after busdevices_init() 823 + * has been executed. 824 + */ 825 + static void __init register_led_regions(void) 326 826 { 327 827 switch (lcd_info.model) { 328 828 case DISPLAY_MODEL_LCD: ··· 545 627 } 546 628 } 547 629 548 - 549 - /* 550 - ** 551 - ** lcd_print() 552 - ** 553 - ** Displays the given string on the LCD-Display of newer machines. 554 - ** lcd_print() disables/enables the timer-based led work queue to 555 - ** avoid a race condition while writing the CMD/DATA register pair. 556 - ** 557 - */ 558 - int lcd_print( const char *str ) 630 + static int __init startup_leds(void) 559 631 { 560 - int i; 561 - 562 - if (!led_func_ptr || lcd_info.model != DISPLAY_MODEL_LCD) 563 - return 0; 564 - 565 - /* temporarily disable the led work task */ 566 - if (led_wq) 567 - cancel_delayed_work_sync(&led_task); 568 - 569 - /* copy display string to buffer for procfs */ 570 - strscpy(lcd_text, str, sizeof(lcd_text)); 571 - 572 - /* Set LCD Cursor to 1st character */ 573 - gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG); 574 - udelay(lcd_info.min_cmd_delay); 575 - 576 - /* Print the string */ 577 - for (i=0; i < lcd_info.lcd_width; i++) { 578 - if (str && *str) 579 - gsc_writeb(*str++, LCD_DATA_REG); 580 - else 581 - gsc_writeb(' ', LCD_DATA_REG); 582 - udelay(lcd_info.min_cmd_delay); 583 - } 584 - 585 - /* re-queue the work */ 586 - if (led_wq) { 587 - queue_delayed_work(led_wq, &led_task, 0); 588 - } 589 - 590 - return lcd_info.lcd_width; 632 + if (platform_device_register(&platform_leds)) 633 + printk(KERN_INFO "LED: failed to register LEDs\n"); 634 + register_led_regions(); 635 + return 0; 591 636 } 592 - 593 - /* 594 - ** led_init() 595 - ** 596 - ** led_init() is called very early in the bootup-process from setup.c 597 - ** and asks the PDC for an usable chassis LCD or LED. 598 - ** If the PDC doesn't return any info, then the LED 599 - ** is detected by lasi.c or asp.c and registered with the 600 - ** above functions lasi_led_init() or asp_led_init(). 601 - ** KittyHawk machines have often a buggy PDC, so that 602 - ** we explicitly check for those machines here. 603 - */ 604 - 605 - int __init led_init(void) 606 - { 607 - struct pdc_chassis_info chassis_info; 608 - int ret; 609 - 610 - snprintf(lcd_text_default, sizeof(lcd_text_default), 611 - "Linux %s", init_utsname()->release); 612 - 613 - /* Work around the buggy PDC of KittyHawk-machines */ 614 - switch (CPU_HVERSION) { 615 - case 0x580: /* KittyHawk DC2-100 (K100) */ 616 - case 0x581: /* KittyHawk DC3-120 (K210) */ 617 - case 0x582: /* KittyHawk DC3 100 (K400) */ 618 - case 0x583: /* KittyHawk DC3 120 (K410) */ 619 - case 0x58B: /* KittyHawk DC2 100 (K200) */ 620 - printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, " 621 - "LED detection skipped.\n", __FILE__, CPU_HVERSION); 622 - lcd_no_led_support = 1; 623 - goto found; /* use the preinitialized values of lcd_info */ 624 - } 625 - 626 - /* initialize the struct, so that we can check for valid return values */ 627 - lcd_info.model = DISPLAY_MODEL_NONE; 628 - chassis_info.actcnt = chassis_info.maxcnt = 0; 629 - 630 - ret = pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info)); 631 - if (ret == PDC_OK) { 632 - DPRINTK((KERN_INFO "%s: chassis info: model=%d (%s), " 633 - "lcd_width=%d, cmd_delay=%u,\n" 634 - "%s: sizecnt=%d, actcnt=%ld, maxcnt=%ld\n", 635 - __FILE__, lcd_info.model, 636 - (lcd_info.model==DISPLAY_MODEL_LCD) ? "LCD" : 637 - (lcd_info.model==DISPLAY_MODEL_LASI) ? "LED" : "unknown", 638 - lcd_info.lcd_width, lcd_info.min_cmd_delay, 639 - __FILE__, sizeof(lcd_info), 640 - chassis_info.actcnt, chassis_info.maxcnt)); 641 - DPRINTK((KERN_INFO "%s: cmd=%p, data=%p, reset1=%x, reset2=%x, act_enable=%d\n", 642 - __FILE__, lcd_info.lcd_cmd_reg_addr, 643 - lcd_info.lcd_data_reg_addr, lcd_info.reset_cmd1, 644 - lcd_info.reset_cmd2, lcd_info.act_enable )); 645 - 646 - /* check the results. Some machines have a buggy PDC */ 647 - if (chassis_info.actcnt <= 0 || chassis_info.actcnt != chassis_info.maxcnt) 648 - goto not_found; 649 - 650 - switch (lcd_info.model) { 651 - case DISPLAY_MODEL_LCD: /* LCD display */ 652 - if (chassis_info.actcnt < 653 - offsetof(struct pdc_chassis_lcd_info_ret_block, _pad)-1) 654 - goto not_found; 655 - if (!lcd_info.act_enable) { 656 - DPRINTK((KERN_INFO "PDC prohibited usage of the LCD.\n")); 657 - goto not_found; 658 - } 659 - break; 660 - 661 - case DISPLAY_MODEL_NONE: /* no LED or LCD available */ 662 - printk(KERN_INFO "PDC reported no LCD or LED.\n"); 663 - goto not_found; 664 - 665 - case DISPLAY_MODEL_LASI: /* Lasi style 8 bit LED display */ 666 - if (chassis_info.actcnt != 8 && chassis_info.actcnt != 32) 667 - goto not_found; 668 - break; 669 - 670 - default: 671 - printk(KERN_WARNING "PDC reported unknown LCD/LED model %d\n", 672 - lcd_info.model); 673 - goto not_found; 674 - } /* switch() */ 675 - 676 - found: 677 - /* register the LCD/LED driver */ 678 - register_led_driver(lcd_info.model, LCD_CMD_REG, LCD_DATA_REG); 679 - return 0; 680 - 681 - } else { /* if() */ 682 - DPRINTK((KERN_INFO "pdc_chassis_info call failed with retval = %d\n", ret)); 683 - } 684 - 685 - not_found: 686 - lcd_info.model = DISPLAY_MODEL_NONE; 687 - return 1; 688 - } 689 - 690 - static void __exit led_exit(void) 691 - { 692 - unregister_reboot_notifier(&led_notifier); 693 - return; 694 - } 695 - 696 - #ifdef CONFIG_PROC_FS 697 - module_init(led_create_procfs) 698 - #endif 637 + device_initcall(startup_leds);
+4 -3
drivers/parisc/sba_iommu.c
··· 121 121 MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART"); 122 122 #endif 123 123 124 - struct proc_dir_entry *proc_runway_root __ro_after_init; 124 + static struct proc_dir_entry *proc_runway_root __ro_after_init; 125 125 struct proc_dir_entry *proc_mckinley_root __ro_after_init; 126 126 127 127 /************************************ ··· 1994 1994 ** This is the only routine which is NOT static. 1995 1995 ** Must be called exactly once before pci_init(). 1996 1996 */ 1997 - void __init sba_init(void) 1997 + static int __init sba_init(void) 1998 1998 { 1999 - register_parisc_driver(&sba_driver); 1999 + return register_parisc_driver(&sba_driver); 2000 2000 } 2001 + arch_initcall(sba_init); 2001 2002 2002 2003 2003 2004 /**
+9 -3
drivers/parisc/wax.c
··· 4 4 * 5 5 * (c) Copyright 2000 The Puffin Group Inc. 6 6 * 7 - * by Helge Deller <deller@gmx.de> 7 + * (c) 2000-2023 by Helge Deller <deller@gmx.de> 8 8 */ 9 9 10 10 #include <linux/errno.h> ··· 121 121 } 122 122 123 123 static const struct parisc_device_id wax_tbl[] __initconst = { 124 - { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008e }, 124 + { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008e }, 125 125 { 0, } 126 126 }; 127 127 128 128 MODULE_DEVICE_TABLE(parisc, wax_tbl); 129 129 130 - struct parisc_driver wax_driver __refdata = { 130 + static struct parisc_driver wax_driver __refdata = { 131 131 .name = "wax", 132 132 .id_table = wax_tbl, 133 133 .probe = wax_init_chip, 134 134 }; 135 + 136 + static int __init wax_init(void) 137 + { 138 + return register_parisc_driver(&wax_driver); 139 + } 140 + arch_initcall(wax_init);
+4 -1
mm/util.c
··· 396 396 if (current->personality & ADDR_COMPAT_LAYOUT) 397 397 return 1; 398 398 399 - if (rlim_stack->rlim_cur == RLIM_INFINITY) 399 + /* On parisc the stack always grows up - so a unlimited stack should 400 + * not be an indicator to use the legacy memory layout. */ 401 + if (rlim_stack->rlim_cur == RLIM_INFINITY && 402 + !IS_ENABLED(CONFIG_STACK_GROWSUP)) 400 403 return 1; 401 404 402 405 return sysctl_legacy_va_layout;