Changes in 4.9.291 binder: use euid from cred instead of using task binder: use cred instead of task for selinux checks xhci: Fix USB 3.1 enumeration issues by increasing roothub power-on-good delay Input: elantench - fix misreporting trackpoint coordinates Input: i8042 - Add quirk for Fujitsu Lifebook T725 libata: fix read log timeout value ocfs2: fix data corruption on truncate mmc: dw_mmc: Dont wait for DRTO on Write RSP error parisc: Fix ptrace check on syscall return media: ite-cir: IR receiver stop working after receive overflow ALSA: ua101: fix division by zero at probe ALSA: 6fire: fix control and bulk message timeouts ALSA: line6: fix control and interrupt message timeouts ALSA: synth: missing check for possible NULL after the call to kstrdup ALSA: timer: Fix use-after-free problem ALSA: timer: Unconditionally unlink slave instances, too x86/irq: Ensure PI wakeup handler is unregistered before module unload sfc: Don't use netif_info before net_device setup hyperv/vmbus: include linux/bitops.h mmc: winbond: don't build on M68K bpf: Prevent increasing bpf_jit_limit above max xen/netfront: stop tx queues during live migration spi: spl022: fix Microwire full duplex mode watchdog: Fix OMAP watchdog early handling vmxnet3: do not stop tx queues after netif_device_detach() btrfs: fix lost error handling when replaying directory deletes hwmon: (pmbus/lm25066) Add offset coefficients regulator: s5m8767: do not use reset value as DVS voltage if GPIO DVS is disabled regulator: dt-bindings: samsung,s5m8767: correct s5m8767,pmic-buck-default-dvs-idx property EDAC/sb_edac: Fix top-of-high-memory value for Broadwell/Haswell mwifiex: fix division by zero in fw download path ath6kl: fix division by zero in send path ath6kl: fix control-message timeout PCI: Mark Atheros QCA6174 to avoid bus reset rtl8187: fix control-message timeouts evm: mark evm_fixmode as __ro_after_init wcn36xx: Fix HT40 capability for 2Ghz band mwifiex: Read a PCI register after writing the TX ring write pointer wcn36xx: handle connection loss indication RDMA/qedr: Fix NULL deref for query_qp on the GSI QP signal: Remove the bogus sigkill_pending in ptrace_stop signal/mips: Update (_save|_restore)_fp_context to fail with -EFAULT power: supply: max17042_battery: Prevent int underflow in set_soc_threshold power: supply: max17042_battery: use VFSOC for capacity when no rsns powerpc/85xx: Fix oops when mpc85xx_smp_guts_ids node cannot be found serial: core: Fix initializing and restoring termios speed ALSA: mixer: oss: Fix racy access to slots ALSA: mixer: fix deadlock in snd_mixer_oss_set_volume PCI: aardvark: Read all 16-bits from PCIE_MSI_PAYLOAD_REG quota: check block number when reading the block in quota file quota: correct error number in free_dqentry() iio: dac: ad5446: Fix ad5622_write() return value USB: serial: keyspan: fix memleak on probe errors USB: iowarrior: fix control-message timeouts Bluetooth: sco: Fix lock_sock() blockage by memcpy_from_msg() Bluetooth: fix use-after-free error in lock_sock_nested() platform/x86: wmi: do not fail if disabling fails MIPS: lantiq: dma: add small delay after reset MIPS: lantiq: dma: reset correct number of channel locking/lockdep: Avoid RCU-induced noinstr fail smackfs: Fix use-after-free in netlbl_catmap_walk() x86: Increase exception stack sizes media: mt9p031: Fix corrupted frame after restarting stream media: netup_unidvb: handle interrupt properly according to the firmware media: uvcvideo: Set capability in s_param media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe() media: mceusb: return without resubmitting URB in case of -EPROTO error. ia64: don't do IA64_CMPXCHG_DEBUG without CONFIG_PRINTK ACPICA: Avoid evaluating methods too early during system resume media: usb: dvd-usb: fix uninit-value bug in dibusb_read_eeprom_byte() tracefs: Have tracefs directories not set OTH permission bits by default ath: dfs_pattern_detector: Fix possible null-pointer dereference in channel_detector_create() ACPI: battery: Accept charges over the design capacity as full memstick: r592: Fix a UAF bug when removing the driver lib/xz: Avoid overlapping memcpy() with invalid input with in-place decompression lib/xz: Validate the value before assigning it to an enum variable tracing/cfi: Fix cmp_entries_* functions signature mismatch mwl8k: Fix use-after-free in mwl8k_fw_state_machine() PM: hibernate: Get block device exclusively in swsusp_check() iwlwifi: mvm: disable RX-diversity in powersave smackfs: use __GFP_NOFAIL for smk_cipso_doi() ARM: clang: Do not rely on lr register for stacktrace ARM: 9136/1: ARMv7-M uses BE-8, not BE-32 spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in bcm_qspi_probe() parisc: fix warning in flush_tlb_all parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling cgroup: Make rebind_subsystems() disable v2 controllers all at once media: dvb-usb: fix ununit-value in az6027_rc_query media: mtk-vpu: Fix a resource leak in the error handling path of 'mtk_vpu_probe()' media: si470x: Avoid card name truncation cpuidle: Fix kobject memory leaks in error paths ath9k: Fix potential interrupt storm on queue reset crypto: qat - detect PFVF collision after ACK crypto: qat - disregard spurious PFVF interrupts b43legacy: fix a lower bounds test b43: fix a lower bounds test memstick: avoid out-of-range warning memstick: jmb38x_ms: use appropriate free function in jmb38x_ms_alloc_host() hwmon: Fix possible memleak in __hwmon_device_register() ath10k: fix max antenna gain unit drm/msm: uninitialized variable in msm_gem_import() net: stream: don't purge sk_error_queue in sk_stream_kill_queues() mmc: mxs-mmc: disable regulator on error and in the remove function platform/x86: thinkpad_acpi: Fix bitwise vs. logical warning mwifiex: Send DELBA requests according to spec phy: micrel: ksz8041nl: do not use power down mode smackfs: use netlbl_cfg_cipsov4_del() for deleting cipso_v4_doi s390/gmap: don't unconditionally call pte_unmap_unlock() in __gmap_zap() irq: mips: avoid nested irq_enter() samples/kretprobes: Fix return value if register_kretprobe() failed libertas_tf: Fix possible memory leak in probe and disconnect libertas: Fix possible memory leak in probe and disconnect crypto: pcrypt - Delay write to padata->info RDMA/rxe: Fix wrong port_cap_flags ARM: s3c: irq-s3c24xx: Fix return value check for s3c24xx_init_intc() scsi: dc395: Fix error case unwinding MIPS: loongson64: make CPU_LOONGSON64 depends on MIPS_FP_SUPPORT JFS: fix memleak in jfs_mount arm: dts: omap3-gta04a4: accelerometer irq fix soc/tegra: Fix an error handling path in tegra_powergate_power_up() memory: fsl_ifc: fix leak of irq and nand_irq in fsl_ifc_ctrl_probe video: fbdev: chipsfb: use memset_io() instead of memset() serial: 8250_dw: Drop wrong use of ACPI_PTR() usb: gadget: hid: fix error code in do_config() power: supply: rt5033_battery: Change voltage values to µV scsi: csiostor: Uninitialized data in csio_ln_vnp_read_cbfn() RDMA/mlx4: Return missed an error if device doesn't support steering serial: xilinx_uartps: Fix race condition causing stuck TX power: supply: bq27xxx: Fix kernel crash on IRQ handler register error pnfs/flexfiles: Fix misplaced barrier in nfs4_ff_layout_prepare_ds drm/plane-helper: fix uninitialized variable reference PCI: aardvark: Don't spam about PIO Response Status fs: orangefs: fix error return code of orangefs_revalidate_lookup() mtd: spi-nor: hisi-sfc: Remove excessive clk_disable_unprepare() dmaengine: at_xdmac: fix AT_XDMAC_CC_PERID() macro auxdisplay: img-ascii-lcd: Fix lock-up when displaying empty string netfilter: nfnetlink_queue: fix OOB when mac header was cleared dmaengine: dmaengine_desc_callback_valid(): Check for `callback_result` m68k: set a default value for MEMORY_RESERVE watchdog: f71808e_wdt: fix inaccurate report in WDIOC_GETTIMEOUT scsi: qla2xxx: Turn off target reset during issue_lip i2c: xlr: Fix a resource leak in the error handling path of 'xlr_i2c_probe()' xen-pciback: Fix return in pm_ctrl_init() net: davinci_emac: Fix interrupt pacing disable ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses bonding: Fix a use-after-free problem when bond_sysfs_slave_add() failed mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and zs_unregister_migration() llc: fix out-of-bound array index in llc_sk_dev_hash() nfc: pn533: Fix double free when pn533_fill_fragment_skbs() fails vsock: prevent unnecessary refcnt inc for nonblocking connect USB: chipidea: fix interrupt deadlock ARM: 9156/1: drop cc-option fallbacks for architecture selection powerpc/bpf: Validate branch ranges powerpc/bpf: Fix BPF_SUB when imm == 0x80000000 mm, oom: pagefault_out_of_memory: don't force global OOM for dying tasks mm, oom: do not trigger out_of_memory from the #PF PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros net: mdio-mux: fix unbalanced put_device parisc/entry: fix trace test in syscall exit path PCI/MSI: Destroy sysfs before freeing entries scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq() usb: musb: tusb6010: check return value after calling platform_get_resource() scsi: advansys: Fix kernel pointer leak ARM: dts: omap: fix gpmc,mux-add-data type usb: host: ohci-tmio: check return value after calling platform_get_resource() tty: tty_buffer: Fix the softlockup issue in flush_to_ldisc MIPS: sni: Fix the build scsi: target: Fix ordered tag handling scsi: target: Fix alua_tg_pt_gps_count tracking powerpc/5200: dts: fix memory node unit name ALSA: gus: fix null pointer dereference on pointer block powerpc/dcr: Use cmplwi instead of 3-argument cmpli sh: check return code of request_irq maple: fix wrong return value of maple_bus_init(). sh: fix kconfig unmet dependency warning for FRAME_POINTER sh: define __BIG_ENDIAN for math-emu mips: BCM63XX: ensure that CPU_SUPPORTS_32BIT_KERNEL is set sched/core: Mitigate race cpus_share_cache()/update_top_cache_domain() net: bnx2x: fix variable dereferenced before check iavf: Fix for the false positive ASQ/ARQ errors while issuing VF reset mips: bcm63xx: add support for clk_get_parent() platform/x86: hp_accel: Fix an error handling path in 'lis3lv02d_probe()' NFC: reorganize the functions in nci_request NFC: reorder the logic in nfc_{un,}register_device perf/x86/intel/uncore: Fix filter_tid mask for CHA events on Skylake Server perf/x86/intel/uncore: Fix IIO event constraints for Skylake Server tun: fix bonding active backup with arp monitoring hexagon: export raw I/O routines for modules mm: kmemleak: slob: respect SLAB_NOLEAKTRACE flag btrfs: fix memory ordering between normal and ordered work functions parisc/sticon: fix reverse colors cfg80211: call cfg80211_stop_ap when switch from P2P_GO type drm/udl: fix control-message timeout drm/amdgpu: fix set scaling mode Full/Full aspect/Center not works on vga and dvi connectors batman-adv: Keep fragments equally sized batman-adv: Fix own OGM check in aggregated OGMs batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh batman-adv: Consider fragmentation for needed_headroom batman-adv: Reserve needed_*room for fragments batman-adv: Don't always reallocate the fragmentation skb head ASoC: DAPM: Cover regression by kctl change notification fix usb: max-3421: Use driver data instead of maintaining a list of bound devices soc/tegra: pmc: Fix imbalanced clock disabling in error code path Linux 4.9.291 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I23d798c10aebab1e51add60ccb34a8b289d49a4d
277 lines
11 KiB
C
277 lines
11 KiB
C
/*
|
|
* bpf_jit.h: BPF JIT compiler for PPC
|
|
*
|
|
* Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
|
|
* 2016 Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; version 2
|
|
* of the License.
|
|
*/
|
|
#ifndef _BPF_JIT_H
|
|
#define _BPF_JIT_H
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#include <asm/types.h>
|
|
|
|
#ifdef PPC64_ELF_ABI_v1
|
|
#define FUNCTION_DESCR_SIZE 24
|
|
#else
|
|
#define FUNCTION_DESCR_SIZE 0
|
|
#endif
|
|
|
|
/*
|
|
* 16-bit immediate helper macros: HA() is for use with sign-extending instrs
|
|
* (e.g. LD, ADDI). If the bottom 16 bits is "-ve", add another bit into the
|
|
* top half to negate the effect (i.e. 0xffff + 1 = 0x(1)0000).
|
|
*/
|
|
#define IMM_H(i) ((uintptr_t)(i)>>16)
|
|
#define IMM_HA(i) (((uintptr_t)(i)>>16) + \
|
|
(((uintptr_t)(i) & 0x8000) >> 15))
|
|
#define IMM_L(i) ((uintptr_t)(i) & 0xffff)
|
|
|
|
#define PLANT_INSTR(d, idx, instr) \
|
|
do { if (d) { (d)[idx] = instr; } idx++; } while (0)
|
|
#define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)
|
|
|
|
#define PPC_NOP() EMIT(PPC_INST_NOP)
|
|
#define PPC_BLR() EMIT(PPC_INST_BLR)
|
|
#define PPC_BLRL() EMIT(PPC_INST_BLRL)
|
|
#define PPC_MTLR(r) EMIT(PPC_INST_MTLR | ___PPC_RT(r))
|
|
#define PPC_BCTR() EMIT(PPC_INST_BCTR)
|
|
#define PPC_MTCTR(r) EMIT(PPC_INST_MTCTR | ___PPC_RT(r))
|
|
#define PPC_ADDI(d, a, i) EMIT(PPC_INST_ADDI | ___PPC_RT(d) | \
|
|
___PPC_RA(a) | IMM_L(i))
|
|
#define PPC_MR(d, a) PPC_OR(d, a, a)
|
|
#define PPC_LI(r, i) PPC_ADDI(r, 0, i)
|
|
#define PPC_ADDIS(d, a, i) EMIT(PPC_INST_ADDIS | \
|
|
___PPC_RT(d) | ___PPC_RA(a) | IMM_L(i))
|
|
#define PPC_LIS(r, i) PPC_ADDIS(r, 0, i)
|
|
#define PPC_STD(r, base, i) EMIT(PPC_INST_STD | ___PPC_RS(r) | \
|
|
___PPC_RA(base) | ((i) & 0xfffc))
|
|
#define PPC_STDX(r, base, b) EMIT(PPC_INST_STDX | ___PPC_RS(r) | \
|
|
___PPC_RA(base) | ___PPC_RB(b))
|
|
#define PPC_STDU(r, base, i) EMIT(PPC_INST_STDU | ___PPC_RS(r) | \
|
|
___PPC_RA(base) | ((i) & 0xfffc))
|
|
#define PPC_STW(r, base, i) EMIT(PPC_INST_STW | ___PPC_RS(r) | \
|
|
___PPC_RA(base) | IMM_L(i))
|
|
#define PPC_STWU(r, base, i) EMIT(PPC_INST_STWU | ___PPC_RS(r) | \
|
|
___PPC_RA(base) | IMM_L(i))
|
|
#define PPC_STH(r, base, i) EMIT(PPC_INST_STH | ___PPC_RS(r) | \
|
|
___PPC_RA(base) | IMM_L(i))
|
|
#define PPC_STB(r, base, i) EMIT(PPC_INST_STB | ___PPC_RS(r) | \
|
|
___PPC_RA(base) | IMM_L(i))
|
|
|
|
#define PPC_LBZ(r, base, i) EMIT(PPC_INST_LBZ | ___PPC_RT(r) | \
|
|
___PPC_RA(base) | IMM_L(i))
|
|
#define PPC_LD(r, base, i) EMIT(PPC_INST_LD | ___PPC_RT(r) | \
|
|
___PPC_RA(base) | ((i) & 0xfffc))
|
|
#define PPC_LDX(r, base, b) EMIT(PPC_INST_LDX | ___PPC_RT(r) | \
|
|
___PPC_RA(base) | ___PPC_RB(b))
|
|
#define PPC_LWZ(r, base, i) EMIT(PPC_INST_LWZ | ___PPC_RT(r) | \
|
|
___PPC_RA(base) | IMM_L(i))
|
|
#define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | ___PPC_RT(r) | \
|
|
___PPC_RA(base) | IMM_L(i))
|
|
#define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \
|
|
___PPC_RA(base) | ___PPC_RB(b))
|
|
#define PPC_LDBRX(r, base, b) EMIT(PPC_INST_LDBRX | ___PPC_RT(r) | \
|
|
___PPC_RA(base) | ___PPC_RB(b))
|
|
|
|
#define PPC_BPF_LDARX(t, a, b, eh) EMIT(PPC_INST_LDARX | ___PPC_RT(t) | \
|
|
___PPC_RA(a) | ___PPC_RB(b) | \
|
|
__PPC_EH(eh))
|
|
#define PPC_BPF_LWARX(t, a, b, eh) EMIT(PPC_INST_LWARX | ___PPC_RT(t) | \
|
|
___PPC_RA(a) | ___PPC_RB(b) | \
|
|
__PPC_EH(eh))
|
|
#define PPC_BPF_STWCX(s, a, b) EMIT(PPC_INST_STWCX | ___PPC_RS(s) | \
|
|
___PPC_RA(a) | ___PPC_RB(b))
|
|
#define PPC_BPF_STDCX(s, a, b) EMIT(PPC_INST_STDCX | ___PPC_RS(s) | \
|
|
___PPC_RA(a) | ___PPC_RB(b))
|
|
#define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i))
|
|
#define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i))
|
|
#define PPC_CMPW(a, b) EMIT(PPC_INST_CMPW | ___PPC_RA(a) | \
|
|
___PPC_RB(b))
|
|
#define PPC_CMPD(a, b) EMIT(PPC_INST_CMPD | ___PPC_RA(a) | \
|
|
___PPC_RB(b))
|
|
#define PPC_CMPLWI(a, i) EMIT(PPC_INST_CMPLWI | ___PPC_RA(a) | IMM_L(i))
|
|
#define PPC_CMPLDI(a, i) EMIT(PPC_INST_CMPLDI | ___PPC_RA(a) | IMM_L(i))
|
|
#define PPC_CMPLW(a, b) EMIT(PPC_INST_CMPLW | ___PPC_RA(a) | \
|
|
___PPC_RB(b))
|
|
#define PPC_CMPLD(a, b) EMIT(PPC_INST_CMPLD | ___PPC_RA(a) | \
|
|
___PPC_RB(b))
|
|
|
|
#define PPC_SUB(d, a, b) EMIT(PPC_INST_SUB | ___PPC_RT(d) | \
|
|
___PPC_RB(a) | ___PPC_RA(b))
|
|
#define PPC_ADD(d, a, b) EMIT(PPC_INST_ADD | ___PPC_RT(d) | \
|
|
___PPC_RA(a) | ___PPC_RB(b))
|
|
#define PPC_MULD(d, a, b) EMIT(PPC_INST_MULLD | ___PPC_RT(d) | \
|
|
___PPC_RA(a) | ___PPC_RB(b))
|
|
#define PPC_MULW(d, a, b) EMIT(PPC_INST_MULLW | ___PPC_RT(d) | \
|
|
___PPC_RA(a) | ___PPC_RB(b))
|
|
#define PPC_MULHWU(d, a, b) EMIT(PPC_INST_MULHWU | ___PPC_RT(d) | \
|
|
___PPC_RA(a) | ___PPC_RB(b))
|
|
#define PPC_MULI(d, a, i) EMIT(PPC_INST_MULLI | ___PPC_RT(d) | \
|
|
___PPC_RA(a) | IMM_L(i))
|
|
#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
|
|
___PPC_RA(a) | ___PPC_RB(b))
|
|
#define PPC_DIVDU(d, a, b) EMIT(PPC_INST_DIVDU | ___PPC_RT(d) | \
|
|
___PPC_RA(a) | ___PPC_RB(b))
|
|
#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(b))
|
|
#define PPC_ANDI(d, a, i) EMIT(PPC_INST_ANDI | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | IMM_L(i))
|
|
#define PPC_AND_DOT(d, a, b) EMIT(PPC_INST_ANDDOT | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(b))
|
|
#define PPC_OR(d, a, b) EMIT(PPC_INST_OR | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(b))
|
|
#define PPC_MR(d, a) PPC_OR(d, a, a)
|
|
#define PPC_ORI(d, a, i) EMIT(PPC_INST_ORI | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | IMM_L(i))
|
|
#define PPC_ORIS(d, a, i) EMIT(PPC_INST_ORIS | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | IMM_L(i))
|
|
#define PPC_XOR(d, a, b) EMIT(PPC_INST_XOR | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(b))
|
|
#define PPC_XORI(d, a, i) EMIT(PPC_INST_XORI | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | IMM_L(i))
|
|
#define PPC_XORIS(d, a, i) EMIT(PPC_INST_XORIS | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | IMM_L(i))
|
|
#define PPC_EXTSW(d, a) EMIT(PPC_INST_EXTSW | ___PPC_RA(d) | \
|
|
___PPC_RS(a))
|
|
#define PPC_SLW(d, a, s) EMIT(PPC_INST_SLW | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(s))
|
|
#define PPC_SLD(d, a, s) EMIT(PPC_INST_SLD | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(s))
|
|
#define PPC_SRW(d, a, s) EMIT(PPC_INST_SRW | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(s))
|
|
#define PPC_SRD(d, a, s) EMIT(PPC_INST_SRD | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(s))
|
|
#define PPC_SRAD(d, a, s) EMIT(PPC_INST_SRAD | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | ___PPC_RB(s))
|
|
#define PPC_SRADI(d, a, i) EMIT(PPC_INST_SRADI | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | __PPC_SH(i) | \
|
|
(((i) & 0x20) >> 4))
|
|
#define PPC_RLWINM(d, a, i, mb, me) EMIT(PPC_INST_RLWINM | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | __PPC_SH(i) | \
|
|
__PPC_MB(mb) | __PPC_ME(me))
|
|
#define PPC_RLWIMI(d, a, i, mb, me) EMIT(PPC_INST_RLWIMI | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | __PPC_SH(i) | \
|
|
__PPC_MB(mb) | __PPC_ME(me))
|
|
#define PPC_RLDICL(d, a, i, mb) EMIT(PPC_INST_RLDICL | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | __PPC_SH(i) | \
|
|
__PPC_MB64(mb) | (((i) & 0x20) >> 4))
|
|
#define PPC_RLDICR(d, a, i, me) EMIT(PPC_INST_RLDICR | ___PPC_RA(d) | \
|
|
___PPC_RS(a) | __PPC_SH(i) | \
|
|
__PPC_ME64(me) | (((i) & 0x20) >> 4))
|
|
|
|
/* slwi = rlwinm Rx, Ry, n, 0, 31-n */
|
|
#define PPC_SLWI(d, a, i) PPC_RLWINM(d, a, i, 0, 31-(i))
|
|
/* srwi = rlwinm Rx, Ry, 32-n, n, 31 */
|
|
#define PPC_SRWI(d, a, i) PPC_RLWINM(d, a, 32-(i), i, 31)
|
|
/* sldi = rldicr Rx, Ry, n, 63-n */
|
|
#define PPC_SLDI(d, a, i) PPC_RLDICR(d, a, i, 63-(i))
|
|
/* sldi = rldicl Rx, Ry, 64-n, n */
|
|
#define PPC_SRDI(d, a, i) PPC_RLDICL(d, a, 64-(i), i)
|
|
|
|
#define PPC_NEG(d, a) EMIT(PPC_INST_NEG | ___PPC_RT(d) | ___PPC_RA(a))
|
|
|
|
/* Long jump; (unconditional 'branch') */
|
|
#define PPC_JMP(dest) \
|
|
do { \
|
|
long offset = (long)(dest) - (ctx->idx * 4); \
|
|
if (offset < -0x2000000 || offset > 0x1fffffc || offset & 0x3) { \
|
|
pr_err_ratelimited("Branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
|
|
return -ERANGE; \
|
|
} \
|
|
EMIT(PPC_INST_BRANCH | (offset & 0x03fffffc)); \
|
|
} while (0)
|
|
/* "cond" here covers BO:BI fields. */
|
|
#define PPC_BCC_SHORT(cond, dest) \
|
|
do { \
|
|
long offset = (long)(dest) - (ctx->idx * 4); \
|
|
if (offset < -0x8000 || offset > 0x7fff || offset & 0x3) { \
|
|
pr_err_ratelimited("Conditional branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \
|
|
return -ERANGE; \
|
|
} \
|
|
EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \
|
|
} while (0)
|
|
|
|
/* Sign-extended 32-bit immediate load */
|
|
#define PPC_LI32(d, i) do { \
|
|
if ((int)(uintptr_t)(i) >= -32768 && \
|
|
(int)(uintptr_t)(i) < 32768) \
|
|
PPC_LI(d, i); \
|
|
else { \
|
|
PPC_LIS(d, IMM_H(i)); \
|
|
if (IMM_L(i)) \
|
|
PPC_ORI(d, d, IMM_L(i)); \
|
|
} } while(0)
|
|
|
|
#define PPC_LI64(d, i) do { \
|
|
if ((long)(i) >= -2147483648 && \
|
|
(long)(i) < 2147483648) \
|
|
PPC_LI32(d, i); \
|
|
else { \
|
|
if (!((uintptr_t)(i) & 0xffff800000000000ULL)) \
|
|
PPC_LI(d, ((uintptr_t)(i) >> 32) & 0xffff); \
|
|
else { \
|
|
PPC_LIS(d, ((uintptr_t)(i) >> 48)); \
|
|
if ((uintptr_t)(i) & 0x0000ffff00000000ULL) \
|
|
PPC_ORI(d, d, \
|
|
((uintptr_t)(i) >> 32) & 0xffff); \
|
|
} \
|
|
PPC_SLDI(d, d, 32); \
|
|
if ((uintptr_t)(i) & 0x00000000ffff0000ULL) \
|
|
PPC_ORIS(d, d, \
|
|
((uintptr_t)(i) >> 16) & 0xffff); \
|
|
if ((uintptr_t)(i) & 0x000000000000ffffULL) \
|
|
PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \
|
|
} } while (0)
|
|
|
|
#ifdef CONFIG_PPC64
|
|
#define PPC_FUNC_ADDR(d,i) do { PPC_LI64(d, i); } while(0)
|
|
#else
|
|
#define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0)
|
|
#endif
|
|
|
|
static inline bool is_nearbranch(int offset)
|
|
{
|
|
return (offset < 32768) && (offset >= -32768);
|
|
}
|
|
|
|
/*
|
|
* The fly in the ointment of code size changing from pass to pass is
|
|
* avoided by padding the short branch case with a NOP. If code size differs
|
|
* with different branch reaches we will have the issue of code moving from
|
|
* one pass to the next and will need a few passes to converge on a stable
|
|
* state.
|
|
*/
|
|
#define PPC_BCC(cond, dest) do { \
|
|
if (is_nearbranch((dest) - (ctx->idx * 4))) { \
|
|
PPC_BCC_SHORT(cond, dest); \
|
|
PPC_NOP(); \
|
|
} else { \
|
|
/* Flip the 'T or F' bit to invert comparison */ \
|
|
PPC_BCC_SHORT(cond ^ COND_CMP_TRUE, (ctx->idx+2)*4); \
|
|
PPC_JMP(dest); \
|
|
} } while(0)
|
|
|
|
/* To create a branch condition, select a bit of cr0... */
|
|
#define CR0_LT 0
|
|
#define CR0_GT 1
|
|
#define CR0_EQ 2
|
|
/* ...and modify BO[3] */
|
|
#define COND_CMP_TRUE 0x100
|
|
#define COND_CMP_FALSE 0x000
|
|
/* Together, they make all required comparisons: */
|
|
#define COND_GT (CR0_GT | COND_CMP_TRUE)
|
|
#define COND_GE (CR0_LT | COND_CMP_FALSE)
|
|
#define COND_EQ (CR0_EQ | COND_CMP_TRUE)
|
|
#define COND_NE (CR0_EQ | COND_CMP_FALSE)
|
|
#define COND_LT (CR0_LT | COND_CMP_TRUE)
|
|
|
|
#endif
|
|
|
|
#endif
|