mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge branch 'android-4.14-stable' of https://android.googlesource.com/kernel/common into sheesh
* 'android-4.14-stable' of https://android.googlesource.com/kernel/common: Linux 4.14.277 Revert "net: micrel: fix KS8851_MLL Kconfig" ax25: Fix UAF bugs in ax25 timers ax25: Fix NULL pointer dereferences in ax25 timers ax25: fix NPD bug in ax25_disconnect ax25: fix UAF bug in ax25_send_control() ax25: Fix refcount leaks caused by ax25_cb_del() ax25: fix UAF bugs of net_device caused by rebinding operation ax25: fix reference count leaks of ax25_dev ax25: add refcount in ax25_dev to avoid UAF bugs block/compat_ioctl: fix range check in BLKGETSIZE staging: ion: Prevent incorrect reference counting behavour ext4: force overhead calculation if the s_overhead_cluster makes no sense ext4: fix overhead calculation to account for the reserved gdt blocks ext4: limit length to bitmap_maxbytes - blocksize in punch_hole ext4: fix symlink file size not match to file content ARC: entry: fix syscall_trace_exit argument e1000e: Fix possible overflow in LTR decoding ASoC: soc-dapm: fix two incorrect uses of list iterator openvswitch: fix OOB access in reserve_sfa_size() powerpc/perf: Fix power9 event alternatives dma: at_xdmac: fix a missing check on list iterator ata: pata_marvell: Check the 'bmdma_addr' beforing reading stat: fix inconsistency between struct stat and struct compat_stat net: macb: Restart tx only if queue pointer is lagging drm/msm/mdp5: check the return of kzalloc() brcmfmac: sdio: Fix undefined behavior due to shift overflowing the constant cifs: Check the IOCB_DIRECT flag, not O_DIRECT vxlan: fix error return code in vxlan_fdb_append ALSA: usb-audio: Fix undefined behavior due to shift overflowing the constant platform/x86: samsung-laptop: Fix an unsigned comparison which can never be negative ARM: vexpress/spc: Avoid negative array index when !SMP netlink: reset network and mac headers in netlink_dump() net/packet: fix packet_sock xmit return value checking dmaengine: imx-sdma: Fix error checking in sdma_event_remap tcp: Fix potential use-after-free due to double kfree() tcp: fix race condition when creating child sockets from syncookies ALSA: usb-audio: Clear MIDI port active flag after draining gfs2: assign rgrp glock before compute_bitstructs can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error path tracing: Dump stacktrace trigger to the corresponding instance tracing: Have traceon and traceoff trigger honor the instance mm: page_alloc: fix building error on -Werror=array-compare etherdevice: Adjust ether_addr* prototypes to silence -Wstringop-overead Linux 4.14.276 i2c: pasemi: Wait for write xfers to finish smp: Fix offline cpu check in flush_smp_call_function_queue() ARM: davinci: da850-evm: Avoid NULL pointer dereference ALSA: pcm: Test for "silence" field in struct "pcm_format_data" gcc-plugins: latent_entropy: use /dev/urandom mm: kmemleak: take a full lowmem check in kmemleak_*_phys() mm, page_alloc: fix build_zonerefs_node() drivers: net: slip: fix NPD bug in sl_tx_timeout() scsi: mvsas: Add PCI ID of RocketRaid 2640 gpu: ipu-v3: Fix dev_dbg frequency output ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs net: micrel: fix KS8851_MLL Kconfig scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024 scsi: target: tcmu: Fix possible page UAF Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer drm/amdkfd: Check for potential null return of kmalloc_array() drm/amd: Add USBC connector ID cifs: potential buffer overflow in handling symlinks nfc: nci: add flush_workqueue to prevent uaf net: ethernet: stmmac: fix altr_tse_pcs function when using a fixed-link mlxsw: i2c: Fix initialization error flow gpiolib: acpi: use correct format characters veth: Ensure eth header is in skb's linear part memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe xfrm: policy: match with both mark and mask on user interfaces cgroup: Use open-time cgroup namespace for process migration perm checks cgroup: Allocate cgroup_file_ctx for kernfs_open_file->priv cgroup: Use open-time credentials for process migraton perm checks mm/sparsemem: fix 'mem_section' will never be NULL gcc 12 warning arm64: module: remove (NOLOAD) from linker script mm: don't skip swap entry even if zap_details specified dmaengine: Revert "dmaengine: shdma: Fix runtime PM imbalance on error" tools build: Use $(shell ) instead of `` to get embedded libperl's ccopts perf: qcom_l2_pmu: fix an incorrect NULL check on list iterator arm64: patch_text: Fixup last cpu should be master btrfs: fix qgroup reserve overflow the qgroup limit x86/speculation: Restore speculation related MSRs during S3 resume x86/pm: Save the MSR validity status at context setup mm/mempolicy: fix mpol_new leak in shared_policy_replace mmmremap.c: avoid pointless invalidate_range_start/end on mremap(old_size=0) Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning" drbd: Fix five use after free bugs in get_initial_state drm/imx: Fix memory leak in imx_pd_connector_get_modes net: stmmac: Fix unset max_speed difference between DT and non-DT platforms scsi: zorro7xx: Fix a resource leak in zorro7xx_remove_one() drm/amdgpu: fix off by one in amdgpu_gfx_kiq_acquire() mm: fix race between MADV_FREE reclaim and blkdev direct IO read net: add missing SOF_TIMESTAMPING_OPT_ID support ipv6: add missing tx timestamping on IPPROTO_RAW parisc: Fix CPU affinity for Lasi, WAX and Dino chips jfs: prevent NULL deref in diFree virtio_console: eliminate anonymous module_init & module_exit serial: samsung_tty: do not unlock port->lock for uart_write_wakeup() NFS: swap-out must always use STABLE writes. NFS: swap IO handling is slightly different for O_DIRECT IO SUNRPC/call_alloc: async tasks mustn't block waiting for memory w1: w1_therm: fixes w1_seq for ds28ea00 sensors init/main.c: return 1 from handled __setup() functions Bluetooth: Fix use after free in hci_send_acl xtensa: fix DTC warning unit_address_format usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on omap5evm scsi: libfc: Fix use after free in fc_exch_abts_resp() MIPS: fix fortify panic when copying asm exception handlers bnxt_en: Eliminate unintended link toggle during FW reset macvtap: advertise link netns via netlink net/smc: correct settings of RMB window update limit scsi: aha152x: Fix aha152x_setup() __setup handler return value scsi: pm8001: Fix pm8001_mpi_task_abort_resp() dm ioctl: prevent potential spectre v1 gadget iommu/arm-smmu-v3: fix event handling soft lockup PCI: aardvark: Fix support for MSI interrupts powerpc: Set crashkernel offset to mid of RMA region power: supply: axp20x_battery: properly report current when discharging scsi: bfa: Replace snprintf() with sysfs_emit() scsi: mvsas: Replace snprintf() with sysfs_emit() powerpc: dts: t104xrdb: fix phy type for FMAN 4/5 ptp: replace snprintf with sysfs_emit ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111 KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs ARM: 9187/1: JIVE: fix return value of __setup handler rtc: wm8350: Handle error for wm8350_register_irq ubifs: Rectify space amount budget for mkdir/tmpfile operations KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated openvswitch: Fixed nd target mask field in the flow dump. ARM: dts: spear13xx: Update SPI dma properties ARM: dts: spear1340: Update serial node properties ASoC: topology: Allow TLV control to be either read or write ubi: fastmap: Return error code if memory allocation fails in add_aeb() mm/memcontrol: return 1 from cgroup.memory __setup() handler mm/mmap: return 1 from stack_guard_gap __setup() handler ACPI: CPPC: Avoid out of bounds access when parsing _CPC data ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl pinctrl: pinconf-generic: Print arguments for bias-pull-* gfs2: Make sure FITRIM minlen is rounded up to fs block size can: mcba_usb: properly check endpoint type can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path ubifs: rename_whiteout: correct old_dir size computing ubifs: setflags: Make dirtied_ino_d 8 bytes aligned ubifs: Add missing iput if do_tmpfile() failed in rename whiteout ubifs: rename_whiteout: Fix double free for whiteout_ui->data KVM: Prevent module exit until all VMs are freed scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair() scsi: qla2xxx: Fix warning for missing error code powerpc/lib/sstep: Fix build errors with newer binutils powerpc/lib/sstep: Fix 'sthcx' instruction mmc: host: Return an error when ->enable_sdio_irq() ops is missing media: hdpvr: initialize dev->worker at hdpvr_register_videodev video: fbdev: sm712fb: Fix crash in smtcfb_write() ARM: mmp: Fix failure to remove sram device ARM: tegra: tamonten: Fix I2C3 pad setting media: cx88-mpeg: clear interrupt status register before streaming video ASoC: soc-core: skip zero num_dai component in searching dai name video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of snprintf() video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf() ARM: dts: bcm2837: Add the missing L1/L2 cache information ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960 video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit video: fbdev: cirrusfb: check pixclock to avoid divide by zero video: fbdev: w100fb: Reset global state video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow ntfs: add sanity check on allocation size ext4: don't BUG if someone dirty pages without asking ext4 first spi: tegra20: Use of_device_get_match_data() PM: core: keep irq flags in device_pm_check_callbacks() ACPI/APEI: Limit printable size of BERT table data ACPICA: Avoid walking the ACPI Namespace if it is not there irqchip/nvic: Release nvic_base upon failure Fix incorrect type in assignment of ipv6 port for audit loop: use sysfs_emit() in the sysfs xxx show() selinux: use correct type for context length lib/test: use after free in register_test_dev_kmod() NFSv4/pNFS: Fix another issue with a list iterator pointing to the head net/x25: Fix null-ptr-deref caused by x25_disconnect qlcnic: dcb: default to returning -EOPNOTSUPP net: phy: broadcom: Fix brcm_fet_config_init() xen: fix is_xen_pmu() netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options jfs: fix divide error in dbNextAG kgdbts: fix return value of __setup handler kgdboc: fix return value of __setup handler tty: hvc: fix return value of __setup handler pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init NFS: remove unneeded check in decode_devicenotify_args() clk: tegra: tegra124-emc: Fix missing put_device() call in emc_ensure_emc_driver clk: clps711x: Terminate clk_div_table with sentinel element clk: loongson1: Terminate clk_div_table with sentinel element remoteproc: qcom_wcnss: Add missing of_node_put() in wcnss_alloc_memory_region clk: qcom: clk-rcg2: Update the frac table for pixel clock iio: adc: Add check for devm_request_threaded_irq serial: 8250: Fix race condition in RTS-after-send handling serial: 8250_mid: Balance reference count for PCI DMA device staging:iio:adc:ad7280a: Fix handing of device address bit reversing. pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add() mxser: fix xmit_buf leak in activate when LSR == 0xff mfd: asic3: Add missing iounmap() on error asic3_mfd_probe tcp: ensure PMTU updates are processed during fastopen i2c: mux: demux-pinctrl: do not deactivate a master that is not active af_netlink: Fix shift out of bounds in group mask calculation USB: storage: ums-realtek: fix error code in rts51x_read_mem() mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init MIPS: RB532: fix return value of __setup handler vxcan: enable local echo for sent CAN frames mfd: mc13xxx: Add check for mc13xxx_irq_request powerpc/sysdev: fix incorrect use to determine if list is empty PCI: Reduce warnings on possible RW1C corruption power: supply: wm8350-power: Add missing free in free_charger_irq power: supply: wm8350-power: Handle error for wm8350_register_irq i2c: xiic: Make bus names unique KVM: x86/emulator: Defer not-present segment check in __load_segment_descriptor() KVM: x86: Fix emulation in writing cr8 power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false return drm/tegra: Fix reference leak in tegra_dsi_ganged_probe ext2: correct max file size computing TOMOYO: fix __setup handlers return values scsi: pm8001: Fix abort all task initialization scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config() scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req() scsi: pm8001: Fix command initialization in pm80XX_send_read_log() dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS iwlwifi: Fix -EIO error code that is never returned HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init ray_cs: Check ioremap return value power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe ath9k_htc: fix uninit value bugs drm/edid: Don't clear formats if using deep color mtd: onenand: Check for error irq ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in msm8916_wcd_digital_probe ASoC: imx-es8328: Fix error return code in imx_es8328_probe() ASoC: mxs: Fix error handling in mxs_sgtl5000_probe ASoC: dmaengine: do not use a NULL prepare_slave_config() callback video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of ASoC: fsi: Add check for clk_enable ASoC: wm8350: Handle error for wm8350_register_irq ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe media: stk1160: If start stream fails, return buffers with VB2_BUF_STATE_QUEUED ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction memory: emif: check the pointer temp in get_device_details() memory: emif: Add check for setup_interrupts ASoC: atmel_ssc_dai: Handle errors for clk_enable ASoC: mxs-saif: Handle errors for clk_enable printk: fix return value of printk.devkmsg __setup handler arm64: dts: broadcom: Fix sata nodename arm64: dts: ns2: Fix spi-cpol and spi-cpha property ALSA: spi: Add check for clk_enable() ASoC: ti: davinci-i2s: Add check for clk_enable() media: usb: go7007: s2250-board: fix leak in probe() soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe ARM: dts: qcom: ipq4019: fix sleep clock video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name() video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe() media: coda: Fix missing put_device() call in coda_get_vdoa_data perf/x86/intel/pt: Fix address filter config for 32-bit kernel perf/core: Fix address filter parser for multiple filters sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa clocksource: acpi_pm: fix return value of __setup handler hwmon: (pmbus) Add Vin unit off handling crypto: ccp - ccp_dmaengine_unregister release dma channels ACPI: APEI: fix return value of __setup handlers crypto: vmx - add missing dependencies hwrng: atmel - disable trng on failure path PM: suspend: fix return value of __setup handler PM: hibernate: fix __setup handler error handling hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING hwmon: (pmbus) Add mutex to regulator ops spi: pxa2xx-pci: Balance reference count for PCI DMA device selftests/x86: Add validity check and allow field splitting spi: tegra114: Add missing IRQ check in tegra_spi_probe crypto: mxs-dcp - Fix scatterlist processing crypto: authenc - Fix sleep in atomic context in decrypt_tail PCI: pciehp: Clear cmd_busy bit in polling mode brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio brcmfmac: firmware: Allocate space for default boardrev in nvram media: davinci: vpif: fix unbalanced runtime PM get DEC: Limit PMAX memory probing to R3k systems lib/raid6/test: fix multiple definition linking error thermal: int340x: Increase bitmap size carl9170: fix missing bit-wise or operator for tx_params ARM: dts: exynos: add missing HDMI supplies on SMDK5420 ARM: dts: exynos: add missing HDMI supplies on SMDK5250 ARM: dts: exynos: fix UART3 pins configuration in Exynos5250 ARM: dts: at91: sama5d2: Fix PMERRLOC resource size video: fbdev: atari: Atari 2 bpp (STe) palette bugfix video: fbdev: sm712fb: Fix crash in smtcfb_read() drivers: hamradio: 6pack: fix UAF bug caused by mod_timer() ACPI: properties: Consistently return -ENOENT if there are no more references drbd: fix potential silent data corruption ALSA: cs4236: fix an incorrect NULL check on list iterator Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads" qed: validate and restrict untrusted VFs vlan promisc mode qed: display VF trust config scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands mempolicy: mbind_range() set_policy() after vma_merge() mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node jffs2: fix memory leak in jffs2_scan_medium jffs2: fix memory leak in jffs2_do_mount_fs jffs2: fix use-after-free in jffs2_clear_xattr_subsystem can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path pinctrl: samsung: drop pin banks references on error paths NFSD: prevent underflow in nfssvc_decode_writeargs() SUNRPC: avoid race between mod_timer() and del_timer_sync() Documentation: update stable tree link Documentation: add link to stable release candidate tree ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE clk: uniphier: Fix fixed-rate initialization iio: inkern: make a best effort on offset calculation iio: inkern: apply consumer scale when no channel scale is available iio: inkern: apply consumer scale on IIO_VAL_INT cases coresight: Fix TRCCONFIGR.QE sysfs interface USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c virtio-blk: Use blk_validate_block_size() to validate block size block: Add a helper to validate the block size tpm: fix reference counting for struct tpm_chip fuse: fix pipe buffer lifetime for direct_io af_key: add __GFP_ZERO flag for compose_sadb_supported in function pfkey_register spi: Fix erroneous sgs value with min_t() spi: Fix invalid sgs value ethernet: sun: Free the coherent when failing in probing virtio_console: break out of buf poll on remove netdevice: add the case if dev is NULL USB: serial: simple: add Nokia phone driver USB: serial: pl2303: add IBM device IDs ANDROID: incremental-fs: limit mount stack depth UPSTREAM: binderfs: use __u32 for device numbers Linux 4.14.275 arm64: Use the clearbhb instruction in mitigations arm64: add ID_AA64ISAR2_EL1 sys register KVM: arm64: Allow SMCCC_ARCH_WORKAROUND_3 to be discovered and migrated arm64: Mitigate spectre style branch history side channels KVM: arm64: Add templates for BHB mitigation sequences arm64: proton-pack: Report Spectre-BHB vulnerabilities as part of Spectre-v2 arm64: Add percpu vectors for EL1 arm64: entry: Add macro for reading symbol addresses from the trampoline arm64: entry: Add vectors that have the bhb mitigation sequences arm64: entry: Add non-kpti __bp_harden_el1_vectors for mitigations arm64: entry: Allow the trampoline text to occupy multiple pages arm64: entry: Make the kpti trampoline's kpti sequence optional arm64: entry: Move trampoline macros out of ifdef'd section arm64: entry: Don't assume tramp_vectors is the start of the vectors arm64: entry: Allow tramp_alias to access symbols after the 4K boundary arm64: entry: Move the trampoline data page before the text page arm64: entry: Free up another register on kpti's tramp_exit path arm64: entry: Make the trampoline cleanup optional arm64: entry.S: Add ventry overflow sanity checks arm64: Add Cortex-X2 CPU part definition arm64: Add Neoverse-N2, Cortex-A710 CPU part definition arm64: Add part number for Arm Cortex-A77 arm64: Add part number for Neoverse N1 arm64: Make ARM64_ERRATUM_1188873 depend on COMPAT arm64: Add silicon-errata.txt entry for ARM erratum 1188873 arm64: arch_timer: avoid unused function warning arm64: arch_timer: Add workaround for ARM erratum 1188873 Linux 4.14.274 llc: only change llc->dev when bind() succeeds mac80211: fix potential double free on mesh join crypto: qat - disable registration of algorithms ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3 ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board netfilter: nf_tables: initialize registers in nft_do_chain() drivers: net: xgene: Fix regression in CRC stripping ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec ALSA: cmipci: Restore aux vol on suspend/resume ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB ALSA: pcm: Add stream lock during PCM reset ioctl operations llc: fix netdevice reference leaks in llc_ui_bind() thermal: int340x: fix memory leak in int3400_notify() staging: fbtft: fb_st7789v: reset display before initialization esp: Fix possible buffer overflow in ESP transformation net: ipv6: fix skb_over_panic in __ip6_append_data nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION Linux 4.14.273 perf symbols: Fix symbol size calculation condition Input: aiptek - properly check endpoint type usb: gadget: Fix use-after-free bug by not setting udc->dev.driver usb: gadget: rndis: prevent integer overflow in rndis_set_response() net: handle ARPHRD_PIMREG in dev_is_mac_header_xmit() atm: eni: Add check for dma_map_single net/packet: fix slab-out-of-bounds access in packet_recvmsg() efi: fix return value of __setup handlers fs: sysfs_emit: Remove PAGE_SIZE alignment check kselftest/vm: fix tests build with old libc sfc: extend the locking on mcdi->seqno tcp: make tcp_read_sock() more robust nl80211: Update bss channel on channel switch for P2P_CLIENT atm: firestream: check the return value of ioremap() in fs_init() can: rcar_canfd: rcar_canfd_channel_probe(): register the CAN device when fully ready ARM: 9178/1: fix unmet dependency on BITREVERSE for HAVE_ARCH_BITREVERSE MIPS: smp: fill in sibling and core maps earlier ARM: dts: rockchip: fix a typo on rk3288 crypto-controller arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity xfrm: Fix xfrm migrate issues when address family changes sctp: fix the processing for INIT_ACK chunk sctp: fix the processing for INIT chunk Linux 4.14.272 btrfs: unlock newly allocated extent buffer after error ext4: add check to prevent attempting to resize an fs with sparse_super2 ARM: fix Thumb2 regression with Spectre BHB virtio: acknowledge all features before access virtio: unexport virtio_finalize_features staging: gdm724x: fix use after free in gdm_lte_rx() ARM: Spectre-BHB: provide empty stub for non-config selftests/memfd: clean up mapping in mfd_fail_write tracing: Ensure trace buffer is at least 4096 bytes large Revert "xen-netback: Check for hotplug-status existence before watching" Revert "xen-netback: remove 'hotplug-status' once it has served its purpose" net-sysfs: add check for netdevice being present to speed_show sctp: fix kernel-infoleak for SCTP sockets gpio: ts4900: Do not set DAT and OE together NFC: port100: fix use-after-free in port100_send_complete net/mlx5: Fix size field in bufferx_reg struct ax25: Fix NULL pointer dereference in ax25_kill_by_device net: ethernet: lpc_eth: Handle error for clk_enable net: ethernet: ti: cpts: Handle error for clk_enable ethernet: Fix error handling in xemaclite_of_probe qed: return status of qed_iov_get_link net: qlogic: check the return value of dma_alloc_coherent() in qed_vf_hw_prepare()
This commit is contained in:
commit
2abb319f4b
@ -57,6 +57,7 @@ stable kernels.
|
||||
| ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
|
||||
| ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 |
|
||||
| ARM | Cortex-A76 | #1286807 | ARM64_ERRATUM_1286807 |
|
||||
| ARM | Cortex-A76 | #1188873 | ARM64_ERRATUM_1188873 |
|
||||
| ARM | MMU-500 | #841119,#826419 | N/A |
|
||||
| | | | |
|
||||
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
|
||||
|
@ -171,7 +171,16 @@ Trees
|
||||
- The finalized and tagged releases of all stable kernels can be found
|
||||
in separate branches per version at:
|
||||
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
|
||||
|
||||
- The release candidate of all stable kernel versions can be found at:
|
||||
|
||||
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/
|
||||
|
||||
.. warning::
|
||||
The -stable-rc tree is a snapshot in time of the stable-queue tree and
|
||||
will change frequently, hence will be rebased often. It should only be
|
||||
used for testing purposes (e.g. to be consumed by CI systems).
|
||||
|
||||
|
||||
Review committee
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 271
|
||||
SUBLEVEL = 277
|
||||
EXTRAVERSION =
|
||||
NAME = Petit Gorille
|
||||
|
||||
|
@ -191,6 +191,7 @@ tracesys_exit:
|
||||
st r0, [sp, PT_r0] ; sys call return value in pt_regs
|
||||
|
||||
;POST Sys Call Ptrace Hook
|
||||
mov r0, sp ; pt_regs needed
|
||||
bl @syscall_trace_exit
|
||||
b ret_from_exception ; NOT ret_from_system_call at is saves r0 which
|
||||
; we'd done before calling post hook above
|
||||
|
@ -32,12 +32,26 @@
|
||||
#size-cells = <0>;
|
||||
enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit
|
||||
|
||||
/* Source for d/i-cache-line-size and d/i-cache-sets
|
||||
* https://developer.arm.com/documentation/ddi0500/e/level-1-memory-system
|
||||
* /about-the-l1-memory-system?lang=en
|
||||
*
|
||||
* Source for d/i-cache-size
|
||||
* https://magpi.raspberrypi.com/articles/raspberry-pi-3-specs-benchmarks
|
||||
*/
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x000000d8>;
|
||||
d-cache-size = <0x8000>;
|
||||
d-cache-line-size = <64>;
|
||||
d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
|
||||
i-cache-size = <0x8000>;
|
||||
i-cache-line-size = <64>;
|
||||
i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
|
||||
next-level-cache = <&l2>;
|
||||
};
|
||||
|
||||
cpu1: cpu@1 {
|
||||
@ -46,6 +60,13 @@
|
||||
reg = <1>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x000000e0>;
|
||||
d-cache-size = <0x8000>;
|
||||
d-cache-line-size = <64>;
|
||||
d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
|
||||
i-cache-size = <0x8000>;
|
||||
i-cache-line-size = <64>;
|
||||
i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
|
||||
next-level-cache = <&l2>;
|
||||
};
|
||||
|
||||
cpu2: cpu@2 {
|
||||
@ -54,6 +75,13 @@
|
||||
reg = <2>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x000000e8>;
|
||||
d-cache-size = <0x8000>;
|
||||
d-cache-line-size = <64>;
|
||||
d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
|
||||
i-cache-size = <0x8000>;
|
||||
i-cache-line-size = <64>;
|
||||
i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
|
||||
next-level-cache = <&l2>;
|
||||
};
|
||||
|
||||
cpu3: cpu@3 {
|
||||
@ -62,6 +90,27 @@
|
||||
reg = <3>;
|
||||
enable-method = "spin-table";
|
||||
cpu-release-addr = <0x0 0x000000f0>;
|
||||
d-cache-size = <0x8000>;
|
||||
d-cache-line-size = <64>;
|
||||
d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set
|
||||
i-cache-size = <0x8000>;
|
||||
i-cache-line-size = <64>;
|
||||
i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set
|
||||
next-level-cache = <&l2>;
|
||||
};
|
||||
|
||||
/* Source for cache-line-size + cache-sets
|
||||
* https://developer.arm.com/documentation/ddi0500
|
||||
* /e/level-2-memory-system/about-the-l2-memory-system?lang=en
|
||||
* Source for cache-size
|
||||
* https://datasheets.raspberrypi.com/cm/cm1-and-cm3-datasheet.pdf
|
||||
*/
|
||||
l2: l2-cache0 {
|
||||
compatible = "cache";
|
||||
cache-size = <0x80000>;
|
||||
cache-line-size = <64>;
|
||||
cache-sets = <512>; // 512KiB(size)/64(line-size)=8192ways/16-way set
|
||||
cache-level = <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -257,7 +257,7 @@
|
||||
};
|
||||
|
||||
uart3_data: uart3-data {
|
||||
samsung,pins = "gpa1-4", "gpa1-4";
|
||||
samsung,pins = "gpa1-4", "gpa1-5";
|
||||
samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
|
||||
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
|
||||
samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
|
||||
|
@ -117,6 +117,9 @@
|
||||
|
||||
&hdmi {
|
||||
hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
|
||||
vdd-supply = <&ldo8_reg>;
|
||||
vdd_osc-supply = <&ldo10_reg>;
|
||||
vdd_pll-supply = <&ldo8_reg>;
|
||||
};
|
||||
|
||||
&i2c_0 {
|
||||
|
@ -133,6 +133,9 @@
|
||||
hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hdmi_hpd_irq>;
|
||||
vdd-supply = <&ldo6_reg>;
|
||||
vdd_osc-supply = <&ldo7_reg>;
|
||||
vdd_pll-supply = <&ldo6_reg>;
|
||||
};
|
||||
|
||||
&hsi2c_4 {
|
||||
|
@ -93,7 +93,8 @@
|
||||
clocks {
|
||||
sleep_clk: sleep_clk {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <32768>;
|
||||
clock-frequency = <32000>;
|
||||
clock-output-names = "gcc_sleep_clk_src";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
|
@ -140,7 +140,9 @@
|
||||
reg = <0x108000 0x1000>;
|
||||
qcom,ipc = <&l2cc 0x8 2>;
|
||||
|
||||
interrupts = <0 19 0>, <0 21 0>, <0 22 0>;
|
||||
interrupts = <GIC_SPI 19 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 21 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 22 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "ack", "err", "wakeup";
|
||||
|
||||
regulators {
|
||||
@ -186,7 +188,7 @@
|
||||
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
|
||||
reg = <0x16440000 0x1000>,
|
||||
<0x16400000 0x1000>;
|
||||
interrupts = <0 154 0x0>;
|
||||
interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
|
||||
clock-names = "core", "iface";
|
||||
status = "disabled";
|
||||
@ -312,7 +314,7 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x16080000 0x1000>;
|
||||
interrupts = <0 147 0>;
|
||||
interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
|
||||
spi-max-frequency = <24000000>;
|
||||
cs-gpios = <&msmgpio 8 0>;
|
||||
|
||||
|
@ -943,7 +943,7 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
crypto: cypto-controller@ff8a0000 {
|
||||
crypto: crypto@ff8a0000 {
|
||||
compatible = "rockchip,rk3288-crypto";
|
||||
reg = <0x0 0xff8a0000 0x0 0x4000>;
|
||||
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
@ -1121,7 +1121,7 @@
|
||||
pmecc: ecc-engine@f8014070 {
|
||||
compatible = "atmel,sama5d2-pmecc";
|
||||
reg = <0xf8014070 0x490>,
|
||||
<0xf8014500 0x100>;
|
||||
<0xf8014500 0x200>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -142,9 +142,9 @@
|
||||
reg = <0xb4100000 0x1000>;
|
||||
interrupts = <0 105 0x4>;
|
||||
status = "disabled";
|
||||
dmas = <&dwdma0 12 0 1>,
|
||||
<&dwdma0 13 1 0>;
|
||||
dma-names = "tx", "rx";
|
||||
dmas = <&dwdma0 13 0 1>,
|
||||
<&dwdma0 12 1 0>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
thermal@e07008c4 {
|
||||
|
@ -290,9 +290,9 @@
|
||||
#size-cells = <0>;
|
||||
interrupts = <0 31 0x4>;
|
||||
status = "disabled";
|
||||
dmas = <&dwdma0 4 0 0>,
|
||||
<&dwdma0 5 0 0>;
|
||||
dma-names = "tx", "rx";
|
||||
dmas = <&dwdma0 5 0 0>,
|
||||
<&dwdma0 4 0 0>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
rtc@e0580000 {
|
||||
|
@ -183,8 +183,8 @@
|
||||
};
|
||||
conf_ata {
|
||||
nvidia,pins = "ata", "atb", "atc", "atd", "ate",
|
||||
"cdev1", "cdev2", "dap1", "dtb", "gma",
|
||||
"gmb", "gmc", "gmd", "gme", "gpu7",
|
||||
"cdev1", "cdev2", "dap1", "dtb", "dtf",
|
||||
"gma", "gmb", "gmc", "gmd", "gme", "gpu7",
|
||||
"gpv", "i2cp", "irrx", "irtx", "pta",
|
||||
"rm", "slxa", "slxk", "spia", "spib",
|
||||
"uac";
|
||||
@ -203,7 +203,7 @@
|
||||
};
|
||||
conf_crtp {
|
||||
nvidia,pins = "crtp", "dap2", "dap3", "dap4",
|
||||
"dtc", "dte", "dtf", "gpu", "sdio1",
|
||||
"dtc", "dte", "gpu", "sdio1",
|
||||
"slxc", "slxd", "spdi", "spdo", "spig",
|
||||
"uda";
|
||||
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_mmio.h>
|
||||
#include <asm/fpstate.h>
|
||||
#include <asm/spectre.h>
|
||||
#include <kvm/arm_arch_timer.h>
|
||||
|
||||
#define __KVM_HAVE_ARCH_INTC_INITIALIZED
|
||||
@ -324,4 +325,9 @@ static inline int kvm_arm_have_ssbd(void)
|
||||
return KVM_SSBD_UNKNOWN;
|
||||
}
|
||||
|
||||
static inline int kvm_arm_get_spectre_bhb_state(void)
|
||||
{
|
||||
/* 32bit guests don't need firmware for this */
|
||||
return SPECTRE_VULNERABLE; /* aka SMCCC_RET_NOT_SUPPORTED */
|
||||
}
|
||||
#endif /* __ARM_KVM_HOST_H__ */
|
||||
|
@ -25,7 +25,13 @@ enum {
|
||||
SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
|
||||
void spectre_v2_update_state(unsigned int state, unsigned int methods);
|
||||
#else
|
||||
static inline void spectre_v2_update_state(unsigned int state,
|
||||
unsigned int methods)
|
||||
{}
|
||||
#endif
|
||||
|
||||
int spectre_bhb_update_vectors(unsigned int method);
|
||||
|
||||
|
@ -1071,9 +1071,9 @@ vector_bhb_loop8_\name:
|
||||
|
||||
@ bhb workaround
|
||||
mov r0, #8
|
||||
1: b . + 4
|
||||
3: b . + 4
|
||||
subs r0, r0, #1
|
||||
bne 1b
|
||||
bne 3b
|
||||
dsb
|
||||
isb
|
||||
b 2b
|
||||
|
@ -1035,11 +1035,13 @@ static int __init da850_evm_config_emac(void)
|
||||
int ret;
|
||||
u32 val;
|
||||
struct davinci_soc_info *soc_info = &davinci_soc_info;
|
||||
u8 rmii_en = soc_info->emac_pdata->rmii_en;
|
||||
u8 rmii_en;
|
||||
|
||||
if (!machine_is_davinci_da850_evm())
|
||||
return 0;
|
||||
|
||||
rmii_en = soc_info->emac_pdata->rmii_en;
|
||||
|
||||
cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
|
||||
|
||||
val = __raw_readl(cfg_chip3_base);
|
||||
|
@ -75,6 +75,8 @@ static int sram_probe(struct platform_device *pdev)
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no memory resource defined\n");
|
||||
@ -110,8 +112,6 @@ static int sram_probe(struct platform_device *pdev)
|
||||
list_add(&info->node, &sram_bank_list);
|
||||
mutex_unlock(&sram_lock);
|
||||
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
||||
dev_info(&pdev->dev, "initialized\n");
|
||||
return 0;
|
||||
|
||||
@ -130,17 +130,19 @@ static int sram_remove(struct platform_device *pdev)
|
||||
struct sram_bank_info *info;
|
||||
|
||||
info = platform_get_drvdata(pdev);
|
||||
if (info == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&sram_lock);
|
||||
list_del(&info->node);
|
||||
mutex_unlock(&sram_lock);
|
||||
if (info->sram_size) {
|
||||
mutex_lock(&sram_lock);
|
||||
list_del(&info->node);
|
||||
mutex_unlock(&sram_lock);
|
||||
|
||||
gen_pool_destroy(info->gpool);
|
||||
iounmap(info->sram_virt);
|
||||
kfree(info->pool_name);
|
||||
}
|
||||
|
||||
gen_pool_destroy(info->gpool);
|
||||
iounmap(info->sram_virt);
|
||||
kfree(info->pool_name);
|
||||
kfree(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -241,11 +241,11 @@ static int __init jive_mtdset(char *options)
|
||||
unsigned long set;
|
||||
|
||||
if (options == NULL || options[0] == '\0')
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
if (kstrtoul(options, 10, &set)) {
|
||||
printk(KERN_ERR "failed to parse mtdset=%s\n", options);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (set) {
|
||||
@ -260,7 +260,7 @@ static int __init jive_mtdset(char *options)
|
||||
"using default.", set);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* parse the mtdset= option given to the kernel command line */
|
||||
|
@ -584,7 +584,7 @@ static int __init ve_spc_clk_init(void)
|
||||
}
|
||||
|
||||
cluster = topology_physical_package_id(cpu_dev->id);
|
||||
if (init_opp_table[cluster])
|
||||
if (cluster < 0 || init_opp_table[cluster])
|
||||
continue;
|
||||
|
||||
if (ve_init_opp_table(cpu_dev))
|
||||
|
@ -563,6 +563,7 @@ config ARM64_ERRATUM_1286807
|
||||
config ARM64_ERRATUM_1188873
|
||||
bool "Cortex-A76: MRC read following MRRC read of specific Generic Timer in AArch32 might give incorrect result"
|
||||
default y
|
||||
depends on COMPAT
|
||||
select ARM_ARCH_TIMER_OOL_WORKAROUND
|
||||
help
|
||||
This option adds work arounds for ARM Cortex-A76 erratum 1188873
|
||||
@ -1063,6 +1064,16 @@ config ARM64_SSBD
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config MITIGATE_SPECTRE_BRANCH_HISTORY
|
||||
bool "Mitigate Spectre style attacks against branch history" if EXPERT
|
||||
default y
|
||||
depends on HARDEN_BRANCH_PREDICTOR || !KVM
|
||||
help
|
||||
Speculation attacks against some high-performance processors can
|
||||
make use of branch history to influence future speculation.
|
||||
When taking an exception from user-space, a sequence of branches
|
||||
or a firmware call overwrites the branch history.
|
||||
|
||||
config ARM64_TAGGED_ADDR_ABI
|
||||
bool "Enable the tagged user addresses syscall ABI"
|
||||
default y
|
||||
|
@ -111,8 +111,8 @@
|
||||
compatible = "silabs,si3226x";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <5000000>;
|
||||
spi-cpha = <1>;
|
||||
spi-cpol = <1>;
|
||||
spi-cpha;
|
||||
spi-cpol;
|
||||
pl022,hierarchy = <0>;
|
||||
pl022,interface = <0>;
|
||||
pl022,slave-tx-disable = <0>;
|
||||
@ -135,8 +135,8 @@
|
||||
at25,byte-len = <0x8000>;
|
||||
at25,addr-mode = <2>;
|
||||
at25,page-size = <64>;
|
||||
spi-cpha = <1>;
|
||||
spi-cpol = <1>;
|
||||
spi-cpha;
|
||||
spi-cpol;
|
||||
pl022,hierarchy = <0>;
|
||||
pl022,interface = <0>;
|
||||
pl022,slave-tx-disable = <0>;
|
||||
|
@ -687,7 +687,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
sata: ahci@663f2000 {
|
||||
sata: sata@663f2000 {
|
||||
compatible = "brcm,iproc-ahci", "generic-ahci";
|
||||
reg = <0x663f2000 0x1000>;
|
||||
dma-coherent;
|
||||
|
@ -484,6 +484,12 @@
|
||||
};
|
||||
|
||||
&sdhci {
|
||||
/*
|
||||
* Signal integrity isn't great at 200MHz but 100MHz has proven stable
|
||||
* enough.
|
||||
*/
|
||||
max-frequency = <100000000>;
|
||||
|
||||
bus-width = <8>;
|
||||
mmc-hs400-1_8v;
|
||||
mmc-hs400-enhanced-strobe;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm64 4.14.271 Kernel Configuration
|
||||
# Linux/arm64 4.14.277 Kernel Configuration
|
||||
#
|
||||
CONFIG_ARM64=y
|
||||
CONFIG_64BIT=y
|
||||
@ -648,6 +648,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
|
||||
# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
|
||||
# CONFIG_PRINT_VMEMLAYOUT is not set
|
||||
# CONFIG_ARM64_SSBD is not set
|
||||
CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y
|
||||
CONFIG_ARM64_TAGGED_ADDR_ABI=y
|
||||
CONFIG_ARMV8_DEPRECATED=y
|
||||
CONFIG_SWP_EMULATION=y
|
||||
|
@ -117,6 +117,13 @@
|
||||
hint #20
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Clear Branch History instruction
|
||||
*/
|
||||
.macro clearbhb
|
||||
hint #22
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Sanitise a 64-bit bounded index wrt speculation, returning zero if out
|
||||
* of bounds.
|
||||
@ -570,4 +577,31 @@ alternative_endif
|
||||
.Ldone\@:
|
||||
.endm
|
||||
|
||||
.macro __mitigate_spectre_bhb_loop tmp
|
||||
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
|
||||
alternative_cb spectre_bhb_patch_loop_iter
|
||||
mov \tmp, #32 // Patched to correct the immediate
|
||||
alternative_cb_end
|
||||
.Lspectre_bhb_loop\@:
|
||||
b . + 4
|
||||
subs \tmp, \tmp, #1
|
||||
b.ne .Lspectre_bhb_loop\@
|
||||
dsb nsh
|
||||
isb
|
||||
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
|
||||
.endm
|
||||
|
||||
/* Save/restores x0-x3 to the stack */
|
||||
.macro __mitigate_spectre_bhb_fw
|
||||
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
|
||||
stp x0, x1, [sp, #-16]!
|
||||
stp x2, x3, [sp, #-16]!
|
||||
mov w0, #ARM_SMCCC_ARCH_WORKAROUND_3
|
||||
alternative_cb arm64_update_smccc_conduit
|
||||
nop // Patched to SMC/HVC #0
|
||||
alternative_cb_end
|
||||
ldp x2, x3, [sp], #16
|
||||
ldp x0, x1, [sp], #16
|
||||
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
|
||||
.endm
|
||||
#endif /* __ASM_ASSEMBLER_H */
|
||||
|
@ -36,6 +36,7 @@ struct cpuinfo_arm64 {
|
||||
u64 reg_id_aa64dfr1;
|
||||
u64 reg_id_aa64isar0;
|
||||
u64 reg_id_aa64isar1;
|
||||
u64 reg_id_aa64isar2;
|
||||
u64 reg_id_aa64mmfr0;
|
||||
u64 reg_id_aa64mmfr1;
|
||||
u64 reg_id_aa64mmfr2;
|
||||
|
@ -47,6 +47,7 @@
|
||||
#define ARM64_SSBS 27
|
||||
#define ARM64_HW_DBM 28
|
||||
#define ARM64_WORKAROUND_1188873 29
|
||||
#define ARM64_SPECTRE_BHB 29
|
||||
|
||||
#define ARM64_NCAPS 30
|
||||
|
||||
|
@ -462,6 +462,34 @@ static inline bool cpu_supports_mixed_endian_el0(void)
|
||||
return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
|
||||
}
|
||||
|
||||
static inline bool supports_csv2p3(int scope)
|
||||
{
|
||||
u64 pfr0;
|
||||
u8 csv2_val;
|
||||
|
||||
if (scope == SCOPE_LOCAL_CPU)
|
||||
pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1);
|
||||
else
|
||||
pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
|
||||
|
||||
csv2_val = cpuid_feature_extract_unsigned_field(pfr0,
|
||||
ID_AA64PFR0_CSV2_SHIFT);
|
||||
return csv2_val == 3;
|
||||
}
|
||||
|
||||
static inline bool supports_clearbhb(int scope)
|
||||
{
|
||||
u64 isar2;
|
||||
|
||||
if (scope == SCOPE_LOCAL_CPU)
|
||||
isar2 = read_sysreg_s(SYS_ID_AA64ISAR2_EL1);
|
||||
else
|
||||
isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
|
||||
|
||||
return cpuid_feature_extract_unsigned_field(isar2,
|
||||
ID_AA64ISAR2_CLEARBHB_SHIFT);
|
||||
}
|
||||
|
||||
static inline bool system_supports_32bit_el0(void)
|
||||
{
|
||||
return cpus_have_const_cap(ARM64_HAS_32BIT_EL0);
|
||||
@ -495,6 +523,17 @@ static inline int arm64_get_ssbd_state(void)
|
||||
|
||||
void arm64_set_ssbd_mitigation(bool state);
|
||||
|
||||
/* Watch out, ordering is important here. */
|
||||
enum mitigation_state {
|
||||
SPECTRE_UNAFFECTED,
|
||||
SPECTRE_MITIGATED,
|
||||
SPECTRE_VULNERABLE,
|
||||
};
|
||||
|
||||
enum mitigation_state arm64_get_spectre_bhb_state(void);
|
||||
bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
|
||||
u8 spectre_bhb_loop_affected(int scope);
|
||||
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
@ -92,6 +92,17 @@
|
||||
#define ARM_CPU_PART_KRYO4G 0x804
|
||||
#define ARM_CPU_PART_KRYO2XX_GOLD 0x800
|
||||
#define ARM_CPU_PART_KRYO2XX_SILVER 0x801
|
||||
#define ARM_CPU_PART_CORTEX_A35 0xD04
|
||||
#define ARM_CPU_PART_CORTEX_A55 0xD05
|
||||
#define ARM_CPU_PART_NEOVERSE_N1 0xD0C
|
||||
#define ARM_CPU_PART_CORTEX_A77 0xD0D
|
||||
#define ARM_CPU_PART_NEOVERSE_V1 0xD40
|
||||
#define ARM_CPU_PART_CORTEX_A78 0xD41
|
||||
#define ARM_CPU_PART_CORTEX_X1 0xD44
|
||||
#define ARM_CPU_PART_CORTEX_A710 0xD47
|
||||
#define ARM_CPU_PART_CORTEX_X2 0xD48
|
||||
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
|
||||
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
|
||||
|
||||
#define APM_CPU_PART_POTENZA 0x000
|
||||
|
||||
@ -120,6 +131,17 @@
|
||||
#define MIDR_KRYO3S MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO3S)
|
||||
#define MIDR_KRYO4S MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO4S)
|
||||
#define MIDR_KRYO4G MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO4G)
|
||||
#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
|
||||
#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
|
||||
#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
|
||||
#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
|
||||
#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
|
||||
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
|
||||
#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
|
||||
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
|
||||
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
|
||||
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
|
||||
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
|
||||
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
|
||||
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
|
||||
|
@ -59,9 +59,11 @@ enum fixed_addresses {
|
||||
#endif /* CONFIG_ACPI_APEI_GHES */
|
||||
|
||||
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
FIX_ENTRY_TRAMP_TEXT3,
|
||||
FIX_ENTRY_TRAMP_TEXT2,
|
||||
FIX_ENTRY_TRAMP_TEXT1,
|
||||
FIX_ENTRY_TRAMP_DATA,
|
||||
FIX_ENTRY_TRAMP_TEXT,
|
||||
#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT))
|
||||
#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT1))
|
||||
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
|
||||
__end_of_permanent_fixed_addresses,
|
||||
|
||||
|
@ -450,4 +450,9 @@ static inline int kvm_arm_have_ssbd(void)
|
||||
}
|
||||
}
|
||||
|
||||
static inline enum mitigation_state kvm_arm_get_spectre_bhb_state(void)
|
||||
{
|
||||
return arm64_get_spectre_bhb_state();
|
||||
}
|
||||
|
||||
#endif /* __ARM64_KVM_HOST_H__ */
|
||||
|
@ -358,7 +358,7 @@ static inline void *kvm_get_hyp_vector(void)
|
||||
struct bp_hardening_data *data = arm64_get_bp_hardening_data();
|
||||
void *vect = kvm_ksym_ref(__kvm_hyp_vector);
|
||||
|
||||
if (data->fn) {
|
||||
if (data->template_start) {
|
||||
vect = __bp_harden_hyp_vecs_start +
|
||||
data->hyp_vectors_slot * SZ_2K;
|
||||
|
||||
|
@ -35,7 +35,7 @@ typedef struct {
|
||||
*/
|
||||
#define ASID(mm) ((mm)->context.id.counter & 0xffff)
|
||||
|
||||
static inline bool arm64_kernel_unmapped_at_el0(void)
|
||||
static __always_inline bool arm64_kernel_unmapped_at_el0(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0) &&
|
||||
cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0);
|
||||
@ -46,6 +46,12 @@ typedef void (*bp_hardening_cb_t)(void);
|
||||
struct bp_hardening_data {
|
||||
int hyp_vectors_slot;
|
||||
bp_hardening_cb_t fn;
|
||||
|
||||
/*
|
||||
* template_start is only used by the BHB mitigation to identify the
|
||||
* hyp_vectors_slot sequence.
|
||||
*/
|
||||
const char *template_start;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
|
||||
|
@ -28,5 +28,11 @@ extern char __initdata_begin[], __initdata_end[];
|
||||
extern char __inittext_begin[], __inittext_end[];
|
||||
extern char __irqentry_text_start[], __irqentry_text_end[];
|
||||
extern char __mmuoff_data_start[], __mmuoff_data_end[];
|
||||
extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
|
||||
|
||||
static inline size_t entry_tramp_text_size(void)
|
||||
{
|
||||
return __entry_tramp_text_end - __entry_tramp_text_start;
|
||||
}
|
||||
|
||||
#endif /* __ASM_SECTIONS_H */
|
||||
|
@ -168,6 +168,7 @@
|
||||
|
||||
#define SYS_ID_AA64ISAR0_EL1 sys_reg(3, 0, 0, 6, 0)
|
||||
#define SYS_ID_AA64ISAR1_EL1 sys_reg(3, 0, 0, 6, 1)
|
||||
#define SYS_ID_AA64ISAR2_EL1 sys_reg(3, 0, 0, 6, 2)
|
||||
|
||||
#define SYS_ID_AA64MMFR0_EL1 sys_reg(3, 0, 0, 7, 0)
|
||||
#define SYS_ID_AA64MMFR1_EL1 sys_reg(3, 0, 0, 7, 1)
|
||||
@ -418,6 +419,9 @@
|
||||
#define ID_AA64ISAR1_JSCVT_SHIFT 12
|
||||
#define ID_AA64ISAR1_DPB_SHIFT 0
|
||||
|
||||
/* id_aa64isar2 */
|
||||
#define ID_AA64ISAR2_CLEARBHB_SHIFT 28
|
||||
|
||||
/* id_aa64pfr0 */
|
||||
#define ID_AA64PFR0_CSV3_SHIFT 60
|
||||
#define ID_AA64PFR0_CSV2_SHIFT 56
|
||||
@ -465,6 +469,7 @@
|
||||
#define ID_AA64MMFR0_TGRAN16_SUPPORTED 0x1
|
||||
|
||||
/* id_aa64mmfr1 */
|
||||
#define ID_AA64MMFR1_ECBHB_SHIFT 60
|
||||
#define ID_AA64MMFR1_PAN_SHIFT 20
|
||||
#define ID_AA64MMFR1_LOR_SHIFT 16
|
||||
#define ID_AA64MMFR1_HPD_SHIFT 12
|
||||
|
74
arch/arm64/include/asm/vectors.h
Normal file
74
arch/arm64/include/asm/vectors.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2022 ARM Ltd.
|
||||
*/
|
||||
#ifndef __ASM_VECTORS_H
|
||||
#define __ASM_VECTORS_H
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
extern char vectors[];
|
||||
extern char tramp_vectors[];
|
||||
extern char __bp_harden_el1_vectors[];
|
||||
|
||||
/*
|
||||
* Note: the order of this enum corresponds to two arrays in entry.S:
|
||||
* tramp_vecs and __bp_harden_el1_vectors. By default the canonical
|
||||
* 'full fat' vectors are used directly.
|
||||
*/
|
||||
enum arm64_bp_harden_el1_vectors {
|
||||
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
|
||||
/*
|
||||
* Perform the BHB loop mitigation, before branching to the canonical
|
||||
* vectors.
|
||||
*/
|
||||
EL1_VECTOR_BHB_LOOP,
|
||||
|
||||
/*
|
||||
* Make the SMC call for firmware mitigation, before branching to the
|
||||
* canonical vectors.
|
||||
*/
|
||||
EL1_VECTOR_BHB_FW,
|
||||
|
||||
/*
|
||||
* Use the ClearBHB instruction, before branching to the canonical
|
||||
* vectors.
|
||||
*/
|
||||
EL1_VECTOR_BHB_CLEAR_INSN,
|
||||
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
|
||||
|
||||
/*
|
||||
* Remap the kernel before branching to the canonical vectors.
|
||||
*/
|
||||
EL1_VECTOR_KPTI,
|
||||
};
|
||||
|
||||
#ifndef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
|
||||
#define EL1_VECTOR_BHB_LOOP -1
|
||||
#define EL1_VECTOR_BHB_FW -1
|
||||
#define EL1_VECTOR_BHB_CLEAR_INSN -1
|
||||
#endif /* !CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
|
||||
|
||||
/* The vectors to use on return from EL0. e.g. to remap the kernel */
|
||||
DECLARE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector);
|
||||
|
||||
#ifndef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
#define TRAMP_VALIAS 0
|
||||
#endif
|
||||
|
||||
static inline const char *
|
||||
arm64_get_bp_hardening_vector(enum arm64_bp_harden_el1_vectors slot)
|
||||
{
|
||||
if (arm64_kernel_unmapped_at_el0())
|
||||
return (char *)TRAMP_VALIAS + SZ_2K * slot;
|
||||
|
||||
WARN_ON_ONCE(slot == EL1_VECTOR_KPTI);
|
||||
|
||||
return __bp_harden_el1_vectors + SZ_2K * slot;
|
||||
}
|
||||
|
||||
#endif /* __ASM_VECTORS_H */
|
@ -66,3 +66,58 @@ ENTRY(__smccc_workaround_1_smc_start)
|
||||
ldp x0, x1, [sp, #(8 * 2)]
|
||||
add sp, sp, #(8 * 4)
|
||||
ENTRY(__smccc_workaround_1_smc_end)
|
||||
|
||||
ENTRY(__smccc_workaround_3_smc_start)
|
||||
sub sp, sp, #(8 * 4)
|
||||
stp x2, x3, [sp, #(8 * 0)]
|
||||
stp x0, x1, [sp, #(8 * 2)]
|
||||
mov w0, #ARM_SMCCC_ARCH_WORKAROUND_3
|
||||
smc #0
|
||||
ldp x2, x3, [sp, #(8 * 0)]
|
||||
ldp x0, x1, [sp, #(8 * 2)]
|
||||
add sp, sp, #(8 * 4)
|
||||
ENTRY(__smccc_workaround_3_smc_end)
|
||||
|
||||
ENTRY(__spectre_bhb_loop_k8_start)
|
||||
sub sp, sp, #(8 * 2)
|
||||
stp x0, x1, [sp, #(8 * 0)]
|
||||
mov x0, #8
|
||||
2: b . + 4
|
||||
subs x0, x0, #1
|
||||
b.ne 2b
|
||||
dsb nsh
|
||||
isb
|
||||
ldp x0, x1, [sp, #(8 * 0)]
|
||||
add sp, sp, #(8 * 2)
|
||||
ENTRY(__spectre_bhb_loop_k8_end)
|
||||
|
||||
ENTRY(__spectre_bhb_loop_k24_start)
|
||||
sub sp, sp, #(8 * 2)
|
||||
stp x0, x1, [sp, #(8 * 0)]
|
||||
mov x0, #24
|
||||
2: b . + 4
|
||||
subs x0, x0, #1
|
||||
b.ne 2b
|
||||
dsb nsh
|
||||
isb
|
||||
ldp x0, x1, [sp, #(8 * 0)]
|
||||
add sp, sp, #(8 * 2)
|
||||
ENTRY(__spectre_bhb_loop_k24_end)
|
||||
|
||||
ENTRY(__spectre_bhb_loop_k32_start)
|
||||
sub sp, sp, #(8 * 2)
|
||||
stp x0, x1, [sp, #(8 * 0)]
|
||||
mov x0, #32
|
||||
2: b . + 4
|
||||
subs x0, x0, #1
|
||||
b.ne 2b
|
||||
dsb nsh
|
||||
isb
|
||||
ldp x0, x1, [sp, #(8 * 0)]
|
||||
add sp, sp, #(8 * 2)
|
||||
ENTRY(__spectre_bhb_loop_k32_end)
|
||||
|
||||
ENTRY(__spectre_bhb_clearbhb_start)
|
||||
hint #22 /* aka clearbhb */
|
||||
isb
|
||||
ENTRY(__spectre_bhb_clearbhb_end)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/vectors.h>
|
||||
|
||||
static bool __maybe_unused
|
||||
is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
|
||||
@ -85,6 +86,16 @@ DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
|
||||
#ifdef CONFIG_KVM
|
||||
extern char __smccc_workaround_1_smc_start[];
|
||||
extern char __smccc_workaround_1_smc_end[];
|
||||
extern char __smccc_workaround_3_smc_start[];
|
||||
extern char __smccc_workaround_3_smc_end[];
|
||||
extern char __spectre_bhb_loop_k8_start[];
|
||||
extern char __spectre_bhb_loop_k8_end[];
|
||||
extern char __spectre_bhb_loop_k24_start[];
|
||||
extern char __spectre_bhb_loop_k24_end[];
|
||||
extern char __spectre_bhb_loop_k32_start[];
|
||||
extern char __spectre_bhb_loop_k32_end[];
|
||||
extern char __spectre_bhb_clearbhb_start[];
|
||||
extern char __spectre_bhb_clearbhb_end[];
|
||||
|
||||
static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
|
||||
const char *hyp_vecs_end)
|
||||
@ -98,12 +109,14 @@ static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
|
||||
__flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(bp_lock);
|
||||
static int last_slot = -1;
|
||||
|
||||
static void install_bp_hardening_cb(bp_hardening_cb_t fn,
|
||||
const char *hyp_vecs_start,
|
||||
const char *hyp_vecs_end)
|
||||
{
|
||||
static int last_slot = -1;
|
||||
static DEFINE_SPINLOCK(bp_lock);
|
||||
|
||||
int cpu, slot = -1;
|
||||
|
||||
spin_lock(&bp_lock);
|
||||
@ -124,6 +137,7 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn,
|
||||
|
||||
__this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot);
|
||||
__this_cpu_write(bp_hardening_data.fn, fn);
|
||||
__this_cpu_write(bp_hardening_data.template_start, hyp_vecs_start);
|
||||
spin_unlock(&bp_lock);
|
||||
}
|
||||
#else
|
||||
@ -728,6 +742,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
15, 15),
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.desc = "Spectre-BHB",
|
||||
.capability = ARM64_SPECTRE_BHB,
|
||||
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
|
||||
.matches = is_spectre_bhb_affected,
|
||||
.cpu_enable = spectre_bhb_enable_mitigation,
|
||||
},
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -738,14 +759,39 @@ ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
|
||||
return sprintf(buf, "Mitigation: __user pointer sanitization\n");
|
||||
}
|
||||
|
||||
static const char *get_bhb_affected_string(enum mitigation_state bhb_state)
|
||||
{
|
||||
switch (bhb_state) {
|
||||
case SPECTRE_UNAFFECTED:
|
||||
return "";
|
||||
default:
|
||||
case SPECTRE_VULNERABLE:
|
||||
return ", but not BHB";
|
||||
case SPECTRE_MITIGATED:
|
||||
return ", BHB";
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (__spectrev2_safe)
|
||||
return sprintf(buf, "Not affected\n");
|
||||
enum mitigation_state bhb_state = arm64_get_spectre_bhb_state();
|
||||
const char *bhb_str = get_bhb_affected_string(bhb_state);
|
||||
const char *v2_str = "Branch predictor hardening";
|
||||
|
||||
if (__spectrev2_safe) {
|
||||
if (bhb_state == SPECTRE_UNAFFECTED)
|
||||
return sprintf(buf, "Not affected\n");
|
||||
|
||||
/*
|
||||
* Platforms affected by Spectre-BHB can't report
|
||||
* "Not affected" for Spectre-v2.
|
||||
*/
|
||||
v2_str = "CSV2";
|
||||
}
|
||||
|
||||
if (__hardenbp_enab)
|
||||
return sprintf(buf, "Mitigation: Branch predictor hardening\n");
|
||||
return sprintf(buf, "Mitigation: %s%s\n", v2_str, bhb_str);
|
||||
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
@ -766,3 +812,334 @@ ssize_t cpu_show_spec_store_bypass(struct device *dev,
|
||||
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* We try to ensure that the mitigation state can never change as the result of
|
||||
* onlining a late CPU.
|
||||
*/
|
||||
static void update_mitigation_state(enum mitigation_state *oldp,
|
||||
enum mitigation_state new)
|
||||
{
|
||||
enum mitigation_state state;
|
||||
|
||||
do {
|
||||
state = READ_ONCE(*oldp);
|
||||
if (new <= state)
|
||||
break;
|
||||
} while (cmpxchg_relaxed(oldp, state, new) != state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Spectre BHB.
|
||||
*
|
||||
* A CPU is either:
|
||||
* - Mitigated by a branchy loop a CPU specific number of times, and listed
|
||||
* in our "loop mitigated list".
|
||||
* - Mitigated in software by the firmware Spectre v2 call.
|
||||
* - Has the ClearBHB instruction to perform the mitigation.
|
||||
* - Has the 'Exception Clears Branch History Buffer' (ECBHB) feature, so no
|
||||
* software mitigation in the vectors is needed.
|
||||
* - Has CSV2.3, so is unaffected.
|
||||
*/
|
||||
static enum mitigation_state spectre_bhb_state;
|
||||
|
||||
enum mitigation_state arm64_get_spectre_bhb_state(void)
|
||||
{
|
||||
return spectre_bhb_state;
|
||||
}
|
||||
|
||||
/*
|
||||
* This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any
|
||||
* SCOPE_SYSTEM call will give the right answer.
|
||||
*/
|
||||
u8 spectre_bhb_loop_affected(int scope)
|
||||
{
|
||||
u8 k = 0;
|
||||
static u8 max_bhb_k;
|
||||
|
||||
if (scope == SCOPE_LOCAL_CPU) {
|
||||
static const struct midr_range spectre_bhb_k32_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k24_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
|
||||
{},
|
||||
};
|
||||
static const struct midr_range spectre_bhb_k8_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
|
||||
{},
|
||||
};
|
||||
|
||||
if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
|
||||
k = 32;
|
||||
else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
|
||||
k = 24;
|
||||
else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
|
||||
k = 8;
|
||||
|
||||
max_bhb_k = max(max_bhb_k, k);
|
||||
} else {
|
||||
k = max_bhb_k;
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void)
|
||||
{
|
||||
int ret;
|
||||
struct arm_smccc_res res;
|
||||
|
||||
if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
|
||||
return SPECTRE_VULNERABLE;
|
||||
|
||||
switch (psci_ops.conduit) {
|
||||
case PSCI_CONDUIT_HVC:
|
||||
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
|
||||
ARM_SMCCC_ARCH_WORKAROUND_3, &res);
|
||||
break;
|
||||
|
||||
case PSCI_CONDUIT_SMC:
|
||||
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
|
||||
ARM_SMCCC_ARCH_WORKAROUND_3, &res);
|
||||
break;
|
||||
|
||||
default:
|
||||
return SPECTRE_VULNERABLE;
|
||||
}
|
||||
|
||||
ret = res.a0;
|
||||
switch (ret) {
|
||||
case SMCCC_RET_SUCCESS:
|
||||
return SPECTRE_MITIGATED;
|
||||
case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED:
|
||||
return SPECTRE_UNAFFECTED;
|
||||
default:
|
||||
case SMCCC_RET_NOT_SUPPORTED:
|
||||
return SPECTRE_VULNERABLE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_spectre_bhb_fw_affected(int scope)
|
||||
{
|
||||
static bool system_affected;
|
||||
enum mitigation_state fw_state;
|
||||
bool has_smccc = (psci_ops.smccc_version >= SMCCC_VERSION_1_1);
|
||||
static const struct midr_range spectre_bhb_firmware_mitigated_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
|
||||
{},
|
||||
};
|
||||
bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
|
||||
spectre_bhb_firmware_mitigated_list);
|
||||
|
||||
if (scope != SCOPE_LOCAL_CPU)
|
||||
return system_affected;
|
||||
|
||||
fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
|
||||
if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) {
|
||||
system_affected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool supports_ecbhb(int scope)
|
||||
{
|
||||
u64 mmfr1;
|
||||
|
||||
if (scope == SCOPE_LOCAL_CPU)
|
||||
mmfr1 = read_sysreg_s(SYS_ID_AA64MMFR1_EL1);
|
||||
else
|
||||
mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
|
||||
|
||||
return cpuid_feature_extract_unsigned_field(mmfr1,
|
||||
ID_AA64MMFR1_ECBHB_SHIFT);
|
||||
}
|
||||
|
||||
bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
|
||||
int scope)
|
||||
{
|
||||
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
|
||||
|
||||
if (supports_csv2p3(scope))
|
||||
return false;
|
||||
|
||||
if (supports_clearbhb(scope))
|
||||
return true;
|
||||
|
||||
if (spectre_bhb_loop_affected(scope))
|
||||
return true;
|
||||
|
||||
if (is_spectre_bhb_fw_affected(scope))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot)
|
||||
{
|
||||
const char *v = arm64_get_bp_hardening_vector(slot);
|
||||
|
||||
if (slot < 0)
|
||||
return;
|
||||
|
||||
__this_cpu_write(this_cpu_vector, v);
|
||||
|
||||
/*
|
||||
* When KPTI is in use, the vectors are switched when exiting to
|
||||
* user-space.
|
||||
*/
|
||||
if (arm64_kernel_unmapped_at_el0())
|
||||
return;
|
||||
|
||||
write_sysreg(v, vbar_el1);
|
||||
isb();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
static const char *kvm_bhb_get_vecs_end(const char *start)
|
||||
{
|
||||
if (start == __smccc_workaround_3_smc_start)
|
||||
return __smccc_workaround_3_smc_end;
|
||||
else if (start == __spectre_bhb_loop_k8_start)
|
||||
return __spectre_bhb_loop_k8_end;
|
||||
else if (start == __spectre_bhb_loop_k24_start)
|
||||
return __spectre_bhb_loop_k24_end;
|
||||
else if (start == __spectre_bhb_loop_k32_start)
|
||||
return __spectre_bhb_loop_k32_end;
|
||||
else if (start == __spectre_bhb_clearbhb_start)
|
||||
return __spectre_bhb_clearbhb_end;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void kvm_setup_bhb_slot(const char *hyp_vecs_start)
|
||||
{
|
||||
int cpu, slot = -1;
|
||||
const char *hyp_vecs_end;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_KVM) || !is_hyp_mode_available())
|
||||
return;
|
||||
|
||||
hyp_vecs_end = kvm_bhb_get_vecs_end(hyp_vecs_start);
|
||||
if (WARN_ON_ONCE(!hyp_vecs_start || !hyp_vecs_end))
|
||||
return;
|
||||
|
||||
spin_lock(&bp_lock);
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (per_cpu(bp_hardening_data.template_start, cpu) == hyp_vecs_start) {
|
||||
slot = per_cpu(bp_hardening_data.hyp_vectors_slot, cpu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot == -1) {
|
||||
last_slot++;
|
||||
BUG_ON(((__bp_harden_hyp_vecs_end - __bp_harden_hyp_vecs_start)
|
||||
/ SZ_2K) <= last_slot);
|
||||
slot = last_slot;
|
||||
__copy_hyp_vect_bpi(slot, hyp_vecs_start, hyp_vecs_end);
|
||||
}
|
||||
|
||||
__this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot);
|
||||
__this_cpu_write(bp_hardening_data.template_start, hyp_vecs_start);
|
||||
spin_unlock(&bp_lock);
|
||||
}
|
||||
#else
|
||||
#define __smccc_workaround_3_smc_start NULL
|
||||
#define __spectre_bhb_loop_k8_start NULL
|
||||
#define __spectre_bhb_loop_k24_start NULL
|
||||
#define __spectre_bhb_loop_k32_start NULL
|
||||
#define __spectre_bhb_clearbhb_start NULL
|
||||
|
||||
static void kvm_setup_bhb_slot(const char *hyp_vecs_start) { };
|
||||
#endif
|
||||
|
||||
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
|
||||
{
|
||||
enum mitigation_state fw_state, state = SPECTRE_VULNERABLE;
|
||||
|
||||
if (!is_spectre_bhb_affected(entry, SCOPE_LOCAL_CPU))
|
||||
return;
|
||||
|
||||
if (!__spectrev2_safe && !__hardenbp_enab) {
|
||||
/* No point mitigating Spectre-BHB alone. */
|
||||
} else if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) {
|
||||
pr_info_once("spectre-bhb mitigation disabled by compile time option\n");
|
||||
} else if (cpu_mitigations_off()) {
|
||||
pr_info_once("spectre-bhb mitigation disabled by command line option\n");
|
||||
} else if (supports_ecbhb(SCOPE_LOCAL_CPU)) {
|
||||
state = SPECTRE_MITIGATED;
|
||||
} else if (supports_clearbhb(SCOPE_LOCAL_CPU)) {
|
||||
kvm_setup_bhb_slot(__spectre_bhb_clearbhb_start);
|
||||
this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN);
|
||||
|
||||
state = SPECTRE_MITIGATED;
|
||||
} else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) {
|
||||
switch (spectre_bhb_loop_affected(SCOPE_SYSTEM)) {
|
||||
case 8:
|
||||
kvm_setup_bhb_slot(__spectre_bhb_loop_k8_start);
|
||||
break;
|
||||
case 24:
|
||||
kvm_setup_bhb_slot(__spectre_bhb_loop_k24_start);
|
||||
break;
|
||||
case 32:
|
||||
kvm_setup_bhb_slot(__spectre_bhb_loop_k32_start);
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
this_cpu_set_vectors(EL1_VECTOR_BHB_LOOP);
|
||||
|
||||
state = SPECTRE_MITIGATED;
|
||||
} else if (is_spectre_bhb_fw_affected(SCOPE_LOCAL_CPU)) {
|
||||
fw_state = spectre_bhb_get_cpu_fw_mitigation_state();
|
||||
if (fw_state == SPECTRE_MITIGATED) {
|
||||
kvm_setup_bhb_slot(__smccc_workaround_3_smc_start);
|
||||
this_cpu_set_vectors(EL1_VECTOR_BHB_FW);
|
||||
|
||||
/*
|
||||
* With WA3 in the vectors, the WA1 calls can be
|
||||
* removed.
|
||||
*/
|
||||
__this_cpu_write(bp_hardening_data.fn, NULL);
|
||||
|
||||
state = SPECTRE_MITIGATED;
|
||||
}
|
||||
}
|
||||
|
||||
update_mitigation_state(&spectre_bhb_state, state);
|
||||
}
|
||||
|
||||
/* Patched to correct the immediate */
|
||||
void __init spectre_bhb_patch_loop_iter(struct alt_instr *alt,
|
||||
__le32 *origptr, __le32 *updptr, int nr_inst)
|
||||
{
|
||||
u8 rd;
|
||||
u32 insn;
|
||||
u16 loop_count = spectre_bhb_loop_affected(SCOPE_SYSTEM);
|
||||
|
||||
BUG_ON(nr_inst != 1); /* MOV -> MOV */
|
||||
|
||||
if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY))
|
||||
return;
|
||||
|
||||
insn = le32_to_cpu(*origptr);
|
||||
rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn);
|
||||
insn = aarch64_insn_gen_movewide(rd, loop_count, 0,
|
||||
AARCH64_INSN_VARIANT_64BIT,
|
||||
AARCH64_INSN_MOVEWIDE_ZERO);
|
||||
*updptr++ = cpu_to_le32(insn);
|
||||
}
|
||||
|
@ -20,11 +20,13 @@
|
||||
|
||||
#include <linux/bsearch.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/stop_machine.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/cpu.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/cpu_ops.h>
|
||||
@ -32,6 +34,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/vectors.h>
|
||||
#include <asm/virt.h>
|
||||
|
||||
unsigned long elf_hwcap __read_mostly;
|
||||
@ -50,6 +53,8 @@ unsigned int compat_elf_hwcap2 __read_mostly;
|
||||
DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
|
||||
EXPORT_SYMBOL(cpu_hwcaps);
|
||||
|
||||
DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors;
|
||||
|
||||
static int dump_cpu_hwcaps(struct notifier_block *self, unsigned long v, void *p)
|
||||
{
|
||||
/* file-wide pr_fmt adds "CPU features: " prefix */
|
||||
@ -134,6 +139,11 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
|
||||
ARM64_FTR_END,
|
||||
};
|
||||
|
||||
static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_CLEARBHB_SHIFT, 4, 0),
|
||||
ARM64_FTR_END,
|
||||
};
|
||||
|
||||
static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV3_SHIFT, 4, 0),
|
||||
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV2_SHIFT, 4, 0),
|
||||
@ -362,6 +372,7 @@ static const struct __ftr_reg_entry {
|
||||
/* Op1 = 0, CRn = 0, CRm = 6 */
|
||||
ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0),
|
||||
ARM64_FTR_REG(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1),
|
||||
ARM64_FTR_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2),
|
||||
|
||||
/* Op1 = 0, CRn = 0, CRm = 7 */
|
||||
ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
|
||||
@ -507,6 +518,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
|
||||
init_cpu_ftr_reg(SYS_ID_AA64DFR1_EL1, info->reg_id_aa64dfr1);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64ISAR0_EL1, info->reg_id_aa64isar0);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64ISAR1_EL1, info->reg_id_aa64isar1);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64ISAR2_EL1, info->reg_id_aa64isar2);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64MMFR0_EL1, info->reg_id_aa64mmfr0);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64MMFR1_EL1, info->reg_id_aa64mmfr1);
|
||||
init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2);
|
||||
@ -618,6 +630,8 @@ void update_cpu_features(int cpu,
|
||||
info->reg_id_aa64isar0, boot->reg_id_aa64isar0);
|
||||
taint |= check_update_ftr_reg(SYS_ID_AA64ISAR1_EL1, cpu,
|
||||
info->reg_id_aa64isar1, boot->reg_id_aa64isar1);
|
||||
taint |= check_update_ftr_reg(SYS_ID_AA64ISAR2_EL1, cpu,
|
||||
info->reg_id_aa64isar2, boot->reg_id_aa64isar2);
|
||||
|
||||
/*
|
||||
* Differing PARange support is fine as long as all peripherals and
|
||||
@ -738,6 +752,7 @@ static u64 __read_sysreg_by_encoding(u32 sys_id)
|
||||
read_sysreg_case(SYS_ID_AA64MMFR2_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64ISAR0_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64ISAR1_EL1);
|
||||
read_sysreg_case(SYS_ID_AA64ISAR2_EL1);
|
||||
|
||||
read_sysreg_case(SYS_CNTFRQ_EL0);
|
||||
read_sysreg_case(SYS_CTR_EL0);
|
||||
@ -898,6 +913,12 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
|
||||
static bool kpti_applied = false;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (__this_cpu_read(this_cpu_vector) == vectors) {
|
||||
const char *v = arm64_get_bp_hardening_vector(EL1_VECTOR_KPTI);
|
||||
|
||||
__this_cpu_write(this_cpu_vector, v);
|
||||
}
|
||||
|
||||
if (kpti_applied)
|
||||
return;
|
||||
|
||||
|
@ -348,6 +348,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
|
||||
info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1);
|
||||
info->reg_id_aa64isar0 = read_cpuid(ID_AA64ISAR0_EL1);
|
||||
info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1);
|
||||
info->reg_id_aa64isar2 = read_cpuid(ID_AA64ISAR2_EL1);
|
||||
info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
|
||||
info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
|
||||
info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1);
|
||||
|
@ -74,18 +74,21 @@
|
||||
|
||||
.macro kernel_ventry, el, label, regsize = 64
|
||||
.align 7
|
||||
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
alternative_if ARM64_UNMAP_KERNEL_AT_EL0
|
||||
.Lventry_start\@:
|
||||
.if \el == 0
|
||||
/*
|
||||
* This must be the first instruction of the EL0 vector entries. It is
|
||||
* skipped by the trampoline vectors, to trigger the cleanup.
|
||||
*/
|
||||
b .Lskip_tramp_vectors_cleanup\@
|
||||
.if \regsize == 64
|
||||
mrs x30, tpidrro_el0
|
||||
msr tpidrro_el0, xzr
|
||||
.else
|
||||
mov x30, xzr
|
||||
.endif
|
||||
.Lskip_tramp_vectors_cleanup\@:
|
||||
.endif
|
||||
alternative_else_nop_endif
|
||||
#endif
|
||||
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
@ -131,11 +134,15 @@ alternative_else_nop_endif
|
||||
mrs x0, tpidrro_el0
|
||||
#endif
|
||||
b el\()\el\()_\label
|
||||
.org .Lventry_start\@ + 128 // Did we overflow the ventry slot?
|
||||
.endm
|
||||
|
||||
.macro tramp_alias, dst, sym
|
||||
.macro tramp_alias, dst, sym, tmp
|
||||
mov_q \dst, TRAMP_VALIAS
|
||||
add \dst, \dst, #(\sym - .entry.tramp.text)
|
||||
adr_l \tmp, \sym
|
||||
add \dst, \dst, \tmp
|
||||
adr_l \tmp, .entry.tramp.text
|
||||
sub \dst, \dst, \tmp
|
||||
.endm
|
||||
|
||||
// This macro corrupts x0-x3. It is the caller's duty
|
||||
@ -360,21 +367,25 @@ alternative_else_nop_endif
|
||||
ldp x24, x25, [sp, #16 * 12]
|
||||
ldp x26, x27, [sp, #16 * 13]
|
||||
ldp x28, x29, [sp, #16 * 14]
|
||||
ldr lr, [sp, #S_LR]
|
||||
add sp, sp, #S_FRAME_SIZE // restore sp
|
||||
|
||||
.if \el == 0
|
||||
alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
|
||||
alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
|
||||
ldr lr, [sp, #S_LR]
|
||||
add sp, sp, #S_FRAME_SIZE // restore sp
|
||||
eret
|
||||
alternative_else_nop_endif
|
||||
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
bne 4f
|
||||
msr far_el1, x30
|
||||
tramp_alias x30, tramp_exit_native
|
||||
msr far_el1, x29
|
||||
tramp_alias x30, tramp_exit_native, x29
|
||||
br x30
|
||||
4:
|
||||
tramp_alias x30, tramp_exit_compat
|
||||
tramp_alias x30, tramp_exit_compat, x29
|
||||
br x30
|
||||
#endif
|
||||
.else
|
||||
ldr lr, [sp, #S_LR]
|
||||
add sp, sp, #S_FRAME_SIZE // restore sp
|
||||
eret
|
||||
.endif
|
||||
.endm
|
||||
@ -1016,12 +1027,7 @@ __ni_sys_trace:
|
||||
|
||||
.popsection // .entry.text
|
||||
|
||||
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
/*
|
||||
* Exception vectors trampoline.
|
||||
*/
|
||||
.pushsection ".entry.tramp.text", "ax"
|
||||
|
||||
// Move from tramp_pg_dir to swapper_pg_dir
|
||||
.macro tramp_map_kernel, tmp
|
||||
mrs \tmp, ttbr1_el1
|
||||
sub \tmp, \tmp, #(SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE)
|
||||
@ -1053,12 +1059,47 @@ alternative_else_nop_endif
|
||||
*/
|
||||
.endm
|
||||
|
||||
.macro tramp_ventry, regsize = 64
|
||||
.macro tramp_data_page dst
|
||||
adr_l \dst, .entry.tramp.text
|
||||
sub \dst, \dst, PAGE_SIZE
|
||||
.endm
|
||||
|
||||
.macro tramp_data_read_var dst, var
|
||||
#ifdef CONFIG_RANDOMIZE_BASE
|
||||
tramp_data_page \dst
|
||||
add \dst, \dst, #:lo12:__entry_tramp_data_\var
|
||||
ldr \dst, [\dst]
|
||||
#else
|
||||
ldr \dst, =\var
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#define BHB_MITIGATION_NONE 0
|
||||
#define BHB_MITIGATION_LOOP 1
|
||||
#define BHB_MITIGATION_FW 2
|
||||
#define BHB_MITIGATION_INSN 3
|
||||
|
||||
.macro tramp_ventry, vector_start, regsize, kpti, bhb
|
||||
.align 7
|
||||
1:
|
||||
.if \regsize == 64
|
||||
msr tpidrro_el0, x30 // Restored in kernel_ventry
|
||||
.endif
|
||||
|
||||
.if \bhb == BHB_MITIGATION_LOOP
|
||||
/*
|
||||
* This sequence must appear before the first indirect branch. i.e. the
|
||||
* ret out of tramp_ventry. It appears here because x30 is free.
|
||||
*/
|
||||
__mitigate_spectre_bhb_loop x30
|
||||
.endif // \bhb == BHB_MITIGATION_LOOP
|
||||
|
||||
.if \bhb == BHB_MITIGATION_INSN
|
||||
clearbhb
|
||||
isb
|
||||
.endif // \bhb == BHB_MITIGATION_INSN
|
||||
|
||||
.if \kpti == 1
|
||||
/*
|
||||
* Defend against branch aliasing attacks by pushing a dummy
|
||||
* entry onto the return stack and using a RET instruction to
|
||||
@ -1068,43 +1109,75 @@ alternative_else_nop_endif
|
||||
b .
|
||||
2:
|
||||
tramp_map_kernel x30
|
||||
#ifdef CONFIG_RANDOMIZE_BASE
|
||||
adr x30, tramp_vectors + PAGE_SIZE
|
||||
alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
|
||||
ldr x30, [x30]
|
||||
#else
|
||||
ldr x30, =vectors
|
||||
#endif
|
||||
prfm plil1strm, [x30, #(1b - tramp_vectors)]
|
||||
tramp_data_read_var x30, vectors
|
||||
prfm plil1strm, [x30, #(1b - \vector_start)]
|
||||
msr vbar_el1, x30
|
||||
add x30, x30, #(1b - tramp_vectors)
|
||||
isb
|
||||
.else
|
||||
ldr x30, =vectors
|
||||
.endif // \kpti == 1
|
||||
|
||||
.if \bhb == BHB_MITIGATION_FW
|
||||
/*
|
||||
* The firmware sequence must appear before the first indirect branch.
|
||||
* i.e. the ret out of tramp_ventry. But it also needs the stack to be
|
||||
* mapped to save/restore the registers the SMC clobbers.
|
||||
*/
|
||||
__mitigate_spectre_bhb_fw
|
||||
.endif // \bhb == BHB_MITIGATION_FW
|
||||
|
||||
add x30, x30, #(1b - \vector_start + 4)
|
||||
ret
|
||||
.org 1b + 128 // Did we overflow the ventry slot?
|
||||
.endm
|
||||
|
||||
.macro tramp_exit, regsize = 64
|
||||
adr x30, tramp_vectors
|
||||
tramp_data_read_var x30, this_cpu_vector
|
||||
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
|
||||
mrs x29, tpidr_el1
|
||||
alternative_else
|
||||
mrs x29, tpidr_el2
|
||||
alternative_endif
|
||||
ldr x30, [x30, x29]
|
||||
|
||||
msr vbar_el1, x30
|
||||
tramp_unmap_kernel x30
|
||||
ldr lr, [sp, #S_LR]
|
||||
tramp_unmap_kernel x29
|
||||
.if \regsize == 64
|
||||
mrs x30, far_el1
|
||||
mrs x29, far_el1
|
||||
.endif
|
||||
add sp, sp, #S_FRAME_SIZE // restore sp
|
||||
eret
|
||||
.endm
|
||||
|
||||
.align 11
|
||||
ENTRY(tramp_vectors)
|
||||
.macro generate_tramp_vector, kpti, bhb
|
||||
.Lvector_start\@:
|
||||
.space 0x400
|
||||
|
||||
tramp_ventry
|
||||
tramp_ventry
|
||||
tramp_ventry
|
||||
tramp_ventry
|
||||
.rept 4
|
||||
tramp_ventry .Lvector_start\@, 64, \kpti, \bhb
|
||||
.endr
|
||||
.rept 4
|
||||
tramp_ventry .Lvector_start\@, 32, \kpti, \bhb
|
||||
.endr
|
||||
.endm
|
||||
|
||||
tramp_ventry 32
|
||||
tramp_ventry 32
|
||||
tramp_ventry 32
|
||||
tramp_ventry 32
|
||||
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
/*
|
||||
* Exception vectors trampoline.
|
||||
* The order must match __bp_harden_el1_vectors and the
|
||||
* arm64_bp_harden_el1_vectors enum.
|
||||
*/
|
||||
.pushsection ".entry.tramp.text", "ax"
|
||||
.align 11
|
||||
ENTRY(tramp_vectors)
|
||||
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
|
||||
generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_LOOP
|
||||
generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_FW
|
||||
generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_INSN
|
||||
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
|
||||
generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_NONE
|
||||
END(tramp_vectors)
|
||||
|
||||
ENTRY(tramp_exit_native)
|
||||
@ -1122,11 +1195,54 @@ END(tramp_exit_compat)
|
||||
.align PAGE_SHIFT
|
||||
.globl __entry_tramp_data_start
|
||||
__entry_tramp_data_start:
|
||||
__entry_tramp_data_vectors:
|
||||
.quad vectors
|
||||
#ifdef CONFIG_ARM_SDE_INTERFACE
|
||||
__entry_tramp_data___sdei_asm_trampoline_next_handler:
|
||||
.quad __sdei_asm_handler
|
||||
#endif /* CONFIG_ARM_SDE_INTERFACE */
|
||||
__entry_tramp_data_this_cpu_vector:
|
||||
.quad this_cpu_vector
|
||||
.popsection // .rodata
|
||||
#endif /* CONFIG_RANDOMIZE_BASE */
|
||||
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
|
||||
|
||||
/*
|
||||
* Exception vectors for spectre mitigations on entry from EL1 when
|
||||
* kpti is not in use.
|
||||
*/
|
||||
.macro generate_el1_vector, bhb
|
||||
.Lvector_start\@:
|
||||
kernel_ventry 1, sync_invalid // Synchronous EL1t
|
||||
kernel_ventry 1, irq_invalid // IRQ EL1t
|
||||
kernel_ventry 1, fiq_invalid // FIQ EL1t
|
||||
kernel_ventry 1, error_invalid // Error EL1t
|
||||
|
||||
kernel_ventry 1, sync // Synchronous EL1h
|
||||
kernel_ventry 1, irq // IRQ EL1h
|
||||
kernel_ventry 1, fiq_invalid // FIQ EL1h
|
||||
kernel_ventry 1, error_invalid // Error EL1h
|
||||
|
||||
.rept 4
|
||||
tramp_ventry .Lvector_start\@, 64, 0, \bhb
|
||||
.endr
|
||||
.rept 4
|
||||
tramp_ventry .Lvector_start\@, 32, 0, \bhb
|
||||
.endr
|
||||
.endm
|
||||
|
||||
/* The order must match tramp_vecs and the arm64_bp_harden_el1_vectors enum. */
|
||||
.pushsection ".entry.text", "ax"
|
||||
.align 11
|
||||
ENTRY(__bp_harden_el1_vectors)
|
||||
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
|
||||
generate_el1_vector bhb=BHB_MITIGATION_LOOP
|
||||
generate_el1_vector bhb=BHB_MITIGATION_FW
|
||||
generate_el1_vector bhb=BHB_MITIGATION_INSN
|
||||
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
|
||||
END(__bp_harden_el1_vectors)
|
||||
.popsection
|
||||
|
||||
/*
|
||||
* Special system call wrappers.
|
||||
*/
|
||||
|
@ -203,8 +203,8 @@ static int __kprobes aarch64_insn_patch_text_cb(void *arg)
|
||||
int i, ret = 0;
|
||||
struct aarch64_insn_patch *pp = arg;
|
||||
|
||||
/* The first CPU becomes master */
|
||||
if (atomic_inc_return(&pp->cpu_count) == 1) {
|
||||
/* The last CPU becomes master */
|
||||
if (atomic_inc_return(&pp->cpu_count) == num_online_cpus()) {
|
||||
for (i = 0; ret == 0 && i < pp->insn_cnt; i++)
|
||||
ret = aarch64_insn_patch_text_nosync(pp->text_addrs[i],
|
||||
pp->new_insns[i]);
|
||||
|
@ -270,7 +270,7 @@ ASSERT(__hibernate_exit_text_end - (__hibernate_exit_text_start & ~(SZ_4K - 1))
|
||||
<= SZ_4K, "Hibernate exit text too big or misaligned")
|
||||
#endif
|
||||
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE,
|
||||
ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE,
|
||||
"Entry trampoline text too big")
|
||||
#endif
|
||||
/*
|
||||
|
@ -135,6 +135,10 @@ el1_hvc_guest:
|
||||
/* ARM_SMCCC_ARCH_WORKAROUND_2 handling */
|
||||
eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_1 ^ \
|
||||
ARM_SMCCC_ARCH_WORKAROUND_2)
|
||||
cbz w1, wa_epilogue
|
||||
|
||||
eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_2 ^ \
|
||||
ARM_SMCCC_ARCH_WORKAROUND_3)
|
||||
cbnz w1, el1_trap
|
||||
|
||||
#ifdef CONFIG_ARM64_SSBD
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <asm/kvm_emulate.h>
|
||||
#include <asm/kvm_hyp.h>
|
||||
#include <asm/fpsimd.h>
|
||||
#include <asm/vectors.h>
|
||||
|
||||
extern struct exception_table_entry __start___kvm_ex_table;
|
||||
extern struct exception_table_entry __stop___kvm_ex_table;
|
||||
@ -110,17 +111,21 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
|
||||
|
||||
static void __hyp_text __deactivate_traps_vhe(void)
|
||||
{
|
||||
extern char vectors[]; /* kernel exception vectors */
|
||||
const char *host_vectors = vectors;
|
||||
u64 mdcr_el2 = read_sysreg(mdcr_el2);
|
||||
|
||||
mdcr_el2 &= MDCR_EL2_HPMN_MASK |
|
||||
MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT |
|
||||
MDCR_EL2_TPMS;
|
||||
|
||||
|
||||
write_sysreg(mdcr_el2, mdcr_el2);
|
||||
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
|
||||
write_sysreg(CPACR_EL1_FPEN, cpacr_el1);
|
||||
write_sysreg(vectors, vbar_el1);
|
||||
|
||||
if (!arm64_kernel_unmapped_at_el0())
|
||||
host_vectors = __this_cpu_read(this_cpu_vector);
|
||||
write_sysreg(host_vectors, vbar_el1);
|
||||
}
|
||||
|
||||
static void __hyp_text __deactivate_traps_nvhe(void)
|
||||
|
@ -579,6 +579,7 @@ early_param("rodata", parse_rodata);
|
||||
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
|
||||
static int __init map_entry_trampoline(void)
|
||||
{
|
||||
int i;
|
||||
extern char __entry_tramp_text_start[];
|
||||
|
||||
pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
|
||||
@ -589,11 +590,15 @@ static int __init map_entry_trampoline(void)
|
||||
|
||||
/* Map only the text into the trampoline page table */
|
||||
memset(tramp_pg_dir, 0, PGD_SIZE);
|
||||
__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
|
||||
prot, pgd_pgtable_alloc, 0);
|
||||
__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS,
|
||||
entry_tramp_text_size(), prot, pgd_pgtable_alloc,
|
||||
0);
|
||||
|
||||
/* Map both the text and data into the kernel page table */
|
||||
__set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
|
||||
for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++)
|
||||
__set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i,
|
||||
pa_start + i * PAGE_SIZE, prot);
|
||||
|
||||
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
|
||||
extern char __entry_tramp_data_start[];
|
||||
|
||||
|
@ -5,4 +5,4 @@
|
||||
|
||||
lib-y += init.o memory.o cmdline.o identify.o console.o
|
||||
|
||||
lib-$(CONFIG_32BIT) += locore.o
|
||||
lib-$(CONFIG_CPU_R3000) += locore.o
|
||||
|
@ -47,16 +47,11 @@
|
||||
*/
|
||||
#define REX_PROM_MAGIC 0x30464354
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
#define prom_is_rex(magic) 1 /* KN04 and KN05 are REX PROMs. */
|
||||
|
||||
#else /* !CONFIG_64BIT */
|
||||
|
||||
#define prom_is_rex(magic) ((magic) == REX_PROM_MAGIC)
|
||||
|
||||
#endif /* !CONFIG_64BIT */
|
||||
|
||||
/* KN04 and KN05 are REX PROMs, so only do the check for R3k systems. */
|
||||
static inline bool prom_is_rex(u32 magic)
|
||||
{
|
||||
return !IS_ENABLED(CONFIG_CPU_R3000) || magic == REX_PROM_MAGIC;
|
||||
}
|
||||
|
||||
/*
|
||||
* 3MIN/MAXINE PROM entry points for DS5000/1xx's, DS5000/xx's and
|
||||
|
@ -14,7 +14,7 @@ static inline void setup_8250_early_printk_port(unsigned long base,
|
||||
unsigned int reg_shift, unsigned int timeout) {}
|
||||
#endif
|
||||
|
||||
extern void set_handler(unsigned long offset, void *addr, unsigned long len);
|
||||
void set_handler(unsigned long offset, const void *addr, unsigned long len);
|
||||
extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
|
||||
|
||||
typedef void (*vi_handler_t)(void);
|
||||
|
@ -372,6 +372,9 @@ asmlinkage void start_secondary(void)
|
||||
cpu = smp_processor_id();
|
||||
cpu_data[cpu].udelay_val = loops_per_jiffy;
|
||||
|
||||
set_cpu_sibling_map(cpu);
|
||||
set_cpu_core_map(cpu);
|
||||
|
||||
cpumask_set_cpu(cpu, &cpu_coherent_mask);
|
||||
notify_cpu_starting(cpu);
|
||||
|
||||
@ -383,9 +386,6 @@ asmlinkage void start_secondary(void)
|
||||
/* The CPU is running and counters synchronised, now mark it online */
|
||||
set_cpu_online(cpu, true);
|
||||
|
||||
set_cpu_sibling_map(cpu);
|
||||
set_cpu_core_map(cpu);
|
||||
|
||||
calculate_cpu_foreign_map();
|
||||
|
||||
/*
|
||||
|
@ -2017,19 +2017,19 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
|
||||
* If no shadow set is selected then use the default handler
|
||||
* that does normal register saving and standard interrupt exit
|
||||
*/
|
||||
extern char except_vec_vi, except_vec_vi_lui;
|
||||
extern char except_vec_vi_ori, except_vec_vi_end;
|
||||
extern char rollback_except_vec_vi;
|
||||
char *vec_start = using_rollback_handler() ?
|
||||
&rollback_except_vec_vi : &except_vec_vi;
|
||||
extern const u8 except_vec_vi[], except_vec_vi_lui[];
|
||||
extern const u8 except_vec_vi_ori[], except_vec_vi_end[];
|
||||
extern const u8 rollback_except_vec_vi[];
|
||||
const u8 *vec_start = using_rollback_handler() ?
|
||||
rollback_except_vec_vi : except_vec_vi;
|
||||
#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
|
||||
const int lui_offset = &except_vec_vi_lui - vec_start + 2;
|
||||
const int ori_offset = &except_vec_vi_ori - vec_start + 2;
|
||||
const int lui_offset = except_vec_vi_lui - vec_start + 2;
|
||||
const int ori_offset = except_vec_vi_ori - vec_start + 2;
|
||||
#else
|
||||
const int lui_offset = &except_vec_vi_lui - vec_start;
|
||||
const int ori_offset = &except_vec_vi_ori - vec_start;
|
||||
const int lui_offset = except_vec_vi_lui - vec_start;
|
||||
const int ori_offset = except_vec_vi_ori - vec_start;
|
||||
#endif
|
||||
const int handler_len = &except_vec_vi_end - vec_start;
|
||||
const int handler_len = except_vec_vi_end - vec_start;
|
||||
|
||||
if (handler_len > VECTORSPACING) {
|
||||
/*
|
||||
@ -2249,7 +2249,7 @@ void per_cpu_trap_init(bool is_boot_cpu)
|
||||
}
|
||||
|
||||
/* Install CPU exception handler */
|
||||
void set_handler(unsigned long offset, void *addr, unsigned long size)
|
||||
void set_handler(unsigned long offset, const void *addr, unsigned long size)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
memcpy((void *)(ebase + offset), ((unsigned char *)addr - 1), size);
|
||||
|
@ -313,11 +313,9 @@ static int __init plat_setup_devices(void)
|
||||
static int __init setup_kmac(char *s)
|
||||
{
|
||||
printk(KERN_INFO "korina mac = %s\n", s);
|
||||
if (!mac_pton(s, korina_dev0_data.mac)) {
|
||||
if (!mac_pton(s, korina_dev0_data.mac))
|
||||
printk(KERN_ERR "Invalid mac\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("kmac=", setup_kmac);
|
||||
|
@ -139,12 +139,12 @@
|
||||
fman@400000 {
|
||||
ethernet@e6000 {
|
||||
phy-handle = <&phy_rgmii_0>;
|
||||
phy-connection-type = "rgmii";
|
||||
phy-connection-type = "rgmii-id";
|
||||
};
|
||||
|
||||
ethernet@e8000 {
|
||||
phy-handle = <&phy_rgmii_1>;
|
||||
phy-connection-type = "rgmii";
|
||||
phy-connection-type = "rgmii-id";
|
||||
};
|
||||
|
||||
mdio0: mdio@fc000 {
|
||||
|
@ -145,11 +145,18 @@ void __init reserve_crashkernel(void)
|
||||
if (!crashk_res.start) {
|
||||
#ifdef CONFIG_PPC64
|
||||
/*
|
||||
* On 64bit we split the RMO in half but cap it at half of
|
||||
* a small SLB (128MB) since the crash kernel needs to place
|
||||
* itself and some stacks to be in the first segment.
|
||||
* On the LPAR platform place the crash kernel to mid of
|
||||
* RMA size (512MB or more) to ensure the crash kernel
|
||||
* gets enough space to place itself and some stack to be
|
||||
* in the first segment. At the same time normal kernel
|
||||
* also get enough space to allocate memory for essential
|
||||
* system resource in the first segment. Keep the crash
|
||||
* kernel starts at 128MB offset on other platforms.
|
||||
*/
|
||||
crashk_res.start = min(0x8000000ULL, (ppc64_rma_size / 2));
|
||||
if (firmware_has_feature(FW_FEATURE_LPAR))
|
||||
crashk_res.start = ppc64_rma_size / 2;
|
||||
else
|
||||
crashk_res.start = min(0x8000000ULL, (ppc64_rma_size / 2));
|
||||
#else
|
||||
crashk_res.start = KDUMP_KERNELBASE;
|
||||
#endif
|
||||
|
@ -1356,6 +1356,12 @@ int __init early_init_dt_scan_rtas(unsigned long node,
|
||||
entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
|
||||
sizep = of_get_flat_dt_prop(node, "rtas-size", NULL);
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
/* need this feature to decide the crashkernel offset */
|
||||
if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL))
|
||||
powerpc_firmware_features |= FW_FEATURE_LPAR;
|
||||
#endif
|
||||
|
||||
if (basep && entryp && sizep) {
|
||||
rtas.base = *basep;
|
||||
rtas.entry = *entryp;
|
||||
|
@ -908,7 +908,10 @@ NOKPROBE_SYMBOL(emulate_dcbz);
|
||||
|
||||
#define __put_user_asmx(x, addr, err, op, cr) \
|
||||
__asm__ __volatile__( \
|
||||
".machine push\n" \
|
||||
".machine power8\n" \
|
||||
"1: " op " %2,0,%3\n" \
|
||||
".machine pop\n" \
|
||||
" mfcr %1\n" \
|
||||
"2:\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
@ -921,7 +924,10 @@ NOKPROBE_SYMBOL(emulate_dcbz);
|
||||
|
||||
#define __get_user_asmx(x, addr, err, op) \
|
||||
__asm__ __volatile__( \
|
||||
".machine push\n" \
|
||||
".machine power8\n" \
|
||||
"1: "op" %1,0,%2\n" \
|
||||
".machine pop\n" \
|
||||
"2:\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"3: li %0,%3\n" \
|
||||
@ -2776,7 +2782,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op)
|
||||
__put_user_asmx(op->val, ea, err, "stbcx.", cr);
|
||||
break;
|
||||
case 2:
|
||||
__put_user_asmx(op->val, ea, err, "stbcx.", cr);
|
||||
__put_user_asmx(op->val, ea, err, "sthcx.", cr);
|
||||
break;
|
||||
#endif
|
||||
case 4:
|
||||
|
@ -107,11 +107,11 @@ extern struct attribute_group isa207_pmu_format_group;
|
||||
|
||||
/* Table of alternatives, sorted by column 0 */
|
||||
static const unsigned int power9_event_alternatives[][MAX_ALT] = {
|
||||
{ PM_INST_DISP, PM_INST_DISP_ALT },
|
||||
{ PM_RUN_CYC_ALT, PM_RUN_CYC },
|
||||
{ PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL },
|
||||
{ PM_LD_MISS_L1, PM_LD_MISS_L1_ALT },
|
||||
{ PM_BR_2PATH, PM_BR_2PATH_ALT },
|
||||
{ PM_INST_DISP, PM_INST_DISP_ALT },
|
||||
{ PM_RUN_CYC_ALT, PM_RUN_CYC },
|
||||
{ PM_LD_MISS_L1, PM_LD_MISS_L1_ALT },
|
||||
{ PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL },
|
||||
};
|
||||
|
||||
static int power9_get_alternatives(u64 event, unsigned int flags, u64 alt[])
|
||||
|
@ -90,7 +90,7 @@ static LIST_HEAD(gtms);
|
||||
*/
|
||||
struct gtm_timer *gtm_get_timer16(void)
|
||||
{
|
||||
struct gtm *gtm = NULL;
|
||||
struct gtm *gtm;
|
||||
int i;
|
||||
|
||||
list_for_each_entry(gtm, >ms, list_node) {
|
||||
@ -107,7 +107,7 @@ struct gtm_timer *gtm_get_timer16(void)
|
||||
spin_unlock_irq(>m->lock);
|
||||
}
|
||||
|
||||
if (gtm)
|
||||
if (!list_empty(>ms))
|
||||
return ERR_PTR(-EBUSY);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ static u64 pt_config_filters(struct perf_event *event)
|
||||
pt->filters.filter[range].msr_b = filter->msr_b;
|
||||
}
|
||||
|
||||
rtit_ctl |= filter->config << pt_address_ranges[range].reg_off;
|
||||
rtit_ctl |= (u64)filter->config << pt_address_ranges[range].reg_off;
|
||||
}
|
||||
|
||||
return rtit_ctl;
|
||||
|
@ -57,15 +57,13 @@ struct compat_timeval {
|
||||
};
|
||||
|
||||
struct compat_stat {
|
||||
compat_dev_t st_dev;
|
||||
u16 __pad1;
|
||||
u32 st_dev;
|
||||
compat_ino_t st_ino;
|
||||
compat_mode_t st_mode;
|
||||
compat_nlink_t st_nlink;
|
||||
__compat_uid_t st_uid;
|
||||
__compat_gid_t st_gid;
|
||||
compat_dev_t st_rdev;
|
||||
u16 __pad2;
|
||||
u32 st_rdev;
|
||||
u32 st_size;
|
||||
u32 st_blksize;
|
||||
u32 st_blocks;
|
||||
|
@ -1343,6 +1343,17 @@ static int __init disable_acpi_pci(const struct dmi_system_id *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init disable_acpi_xsdt(const struct dmi_system_id *d)
|
||||
{
|
||||
if (!acpi_force) {
|
||||
pr_notice("%s detected: force use of acpi=rsdt\n", d->ident);
|
||||
acpi_gbl_do_not_use_xsdt = TRUE;
|
||||
} else {
|
||||
pr_notice("Warning: DMI blacklist says broken, but acpi XSDT forced\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init dmi_disable_acpi(const struct dmi_system_id *d)
|
||||
{
|
||||
if (!acpi_force) {
|
||||
@ -1463,6 +1474,19 @@ static const struct dmi_system_id acpi_dmi_table[] __initconst = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* Boxes that need ACPI XSDT use disabled due to corrupted tables
|
||||
*/
|
||||
{
|
||||
.callback = disable_acpi_xsdt,
|
||||
.ident = "Advantech DAC-BJ01",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Bearlake CRB Board"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "V1.12"),
|
||||
DMI_MATCH(DMI_BIOS_DATE, "02/01/2011"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -1682,11 +1682,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
goto exception;
|
||||
}
|
||||
|
||||
if (!seg_desc.p) {
|
||||
err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR;
|
||||
goto exception;
|
||||
}
|
||||
|
||||
dpl = seg_desc.dpl;
|
||||
|
||||
switch (seg) {
|
||||
@ -1726,6 +1721,10 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
case VCPU_SREG_TR:
|
||||
if (seg_desc.s || (seg_desc.type != 1 && seg_desc.type != 9))
|
||||
goto exception;
|
||||
if (!seg_desc.p) {
|
||||
err_vec = NP_VECTOR;
|
||||
goto exception;
|
||||
}
|
||||
old_desc = seg_desc;
|
||||
seg_desc.type |= 2; /* busy */
|
||||
ret = ctxt->ops->cmpxchg_emulated(ctxt, desc_addr, &old_desc, &seg_desc,
|
||||
@ -1750,6 +1749,11 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!seg_desc.p) {
|
||||
err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR;
|
||||
goto exception;
|
||||
}
|
||||
|
||||
if (seg_desc.s) {
|
||||
/* mark segment as accessed */
|
||||
if (!(seg_desc.type & 1)) {
|
||||
|
@ -260,6 +260,9 @@ static int synic_set_msr(struct kvm_vcpu_hv_synic *synic,
|
||||
case HV_X64_MSR_EOM: {
|
||||
int i;
|
||||
|
||||
if (!synic->active)
|
||||
break;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(synic->sint); i++)
|
||||
kvm_hv_notify_acked_sint(vcpu, i);
|
||||
break;
|
||||
@ -520,6 +523,12 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer)
|
||||
static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
|
||||
bool host)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
|
||||
struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
|
||||
|
||||
if (!synic->active && (!host || config))
|
||||
return 1;
|
||||
|
||||
trace_kvm_hv_stimer_set_config(stimer_to_vcpu(stimer)->vcpu_id,
|
||||
stimer->index, config, host);
|
||||
|
||||
@ -534,6 +543,12 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config,
|
||||
static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count,
|
||||
bool host)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer);
|
||||
struct kvm_vcpu_hv_synic *synic = vcpu_to_synic(vcpu);
|
||||
|
||||
if (!synic->active && (!host || count))
|
||||
return 1;
|
||||
|
||||
trace_kvm_hv_stimer_set_count(stimer_to_vcpu(stimer)->vcpu_id,
|
||||
stimer->index, count, host);
|
||||
|
||||
|
@ -1929,10 +1929,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data)
|
||||
|
||||
void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
|
||||
{
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
|
||||
apic_set_tpr(apic, ((cr8 & 0x0f) << 4)
|
||||
| (kvm_lapic_get_reg(apic, APIC_TASKPRI) & 4));
|
||||
apic_set_tpr(vcpu->arch.apic, (cr8 & 0x0f) << 4);
|
||||
}
|
||||
|
||||
u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
|
||||
|
@ -139,12 +139,10 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
/* MSR_K7_EVNTSELn */
|
||||
pmc = get_gp_pmc(pmu, msr, MSR_K7_EVNTSEL0);
|
||||
if (pmc) {
|
||||
if (data == pmc->eventsel)
|
||||
return 0;
|
||||
if (!(data & pmu->reserved_bits)) {
|
||||
data &= ~pmu->reserved_bits;
|
||||
if (data != pmc->eventsel)
|
||||
reprogram_gp_counter(pmc, data);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -41,7 +41,8 @@ static void msr_save_context(struct saved_context *ctxt)
|
||||
struct saved_msr *end = msr + ctxt->saved_msrs.num;
|
||||
|
||||
while (msr < end) {
|
||||
msr->valid = !rdmsrl_safe(msr->info.msr_no, &msr->info.reg.q);
|
||||
if (msr->valid)
|
||||
rdmsrl(msr->info.msr_no, msr->info.reg.q);
|
||||
msr++;
|
||||
}
|
||||
}
|
||||
@ -426,8 +427,10 @@ static int msr_build_context(const u32 *msr_id, const int num)
|
||||
}
|
||||
|
||||
for (i = saved_msrs->num, j = 0; i < total_num; i++, j++) {
|
||||
u64 dummy;
|
||||
|
||||
msr_array[i].info.msr_no = msr_id[j];
|
||||
msr_array[i].valid = false;
|
||||
msr_array[i].valid = !rdmsrl_safe(msr_id[j], &dummy);
|
||||
msr_array[i].info.reg.q = 0;
|
||||
}
|
||||
saved_msrs->num = total_num;
|
||||
@ -514,10 +517,24 @@ static int pm_cpu_check(const struct x86_cpu_id *c)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pm_save_spec_msr(void)
|
||||
{
|
||||
u32 spec_msr_id[] = {
|
||||
MSR_IA32_SPEC_CTRL,
|
||||
MSR_IA32_TSX_CTRL,
|
||||
MSR_TSX_FORCE_ABORT,
|
||||
MSR_IA32_MCU_OPT_CTRL,
|
||||
MSR_AMD64_LS_CFG,
|
||||
};
|
||||
|
||||
msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id));
|
||||
}
|
||||
|
||||
static int pm_check_save_msr(void)
|
||||
{
|
||||
dmi_check_system(msr_save_dmi_table);
|
||||
pm_cpu_check(msr_save_cpu_table);
|
||||
pm_save_spec_msr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -505,10 +505,7 @@ irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool is_xen_pmu(int cpu)
|
||||
{
|
||||
return (get_xenpmu_data() != NULL);
|
||||
}
|
||||
bool is_xen_pmu;
|
||||
|
||||
void xen_pmu_init(int cpu)
|
||||
{
|
||||
@ -519,7 +516,7 @@ void xen_pmu_init(int cpu)
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct xen_pmu_data) > PAGE_SIZE);
|
||||
|
||||
if (xen_hvm_domain())
|
||||
if (xen_hvm_domain() || (cpu != 0 && !is_xen_pmu))
|
||||
return;
|
||||
|
||||
xenpmu_data = (struct xen_pmu_data *)get_zeroed_page(GFP_KERNEL);
|
||||
@ -540,7 +537,8 @@ void xen_pmu_init(int cpu)
|
||||
per_cpu(xenpmu_shared, cpu).xenpmu_data = xenpmu_data;
|
||||
per_cpu(xenpmu_shared, cpu).flags = 0;
|
||||
|
||||
if (cpu == 0) {
|
||||
if (!is_xen_pmu) {
|
||||
is_xen_pmu = true;
|
||||
perf_register_guest_info_callbacks(&xen_guest_cbs);
|
||||
xen_pmu_arch_init();
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include <xen/interface/xenpmu.h>
|
||||
|
||||
extern bool is_xen_pmu;
|
||||
|
||||
irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);
|
||||
#ifdef CONFIG_XEN_HAVE_VPMU
|
||||
void xen_pmu_init(int cpu);
|
||||
@ -12,7 +14,6 @@ void xen_pmu_finish(int cpu);
|
||||
static inline void xen_pmu_init(int cpu) {}
|
||||
static inline void xen_pmu_finish(int cpu) {}
|
||||
#endif
|
||||
bool is_xen_pmu(int cpu);
|
||||
bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err);
|
||||
bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err);
|
||||
int pmu_apic_update(uint32_t reg);
|
||||
|
@ -126,7 +126,7 @@ int xen_smp_intr_init_pv(unsigned int cpu)
|
||||
per_cpu(xen_irq_work, cpu).irq = rc;
|
||||
per_cpu(xen_irq_work, cpu).name = callfunc_name;
|
||||
|
||||
if (is_xen_pmu(cpu)) {
|
||||
if (is_xen_pmu) {
|
||||
pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu);
|
||||
rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu,
|
||||
xen_pmu_irq_handler,
|
||||
|
@ -8,19 +8,19 @@
|
||||
reg = <0x00000000 0x08000000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
partition@0x0 {
|
||||
partition@0 {
|
||||
label = "data";
|
||||
reg = <0x00000000 0x06000000>;
|
||||
};
|
||||
partition@0x6000000 {
|
||||
partition@6000000 {
|
||||
label = "boot loader area";
|
||||
reg = <0x06000000 0x00800000>;
|
||||
};
|
||||
partition@0x6800000 {
|
||||
partition@6800000 {
|
||||
label = "kernel image";
|
||||
reg = <0x06800000 0x017e0000>;
|
||||
};
|
||||
partition@0x7fe0000 {
|
||||
partition@7fe0000 {
|
||||
label = "boot environment";
|
||||
reg = <0x07fe0000 0x00020000>;
|
||||
};
|
||||
|
@ -8,19 +8,19 @@
|
||||
reg = <0x08000000 0x01000000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
partition@0x0 {
|
||||
partition@0 {
|
||||
label = "boot loader area";
|
||||
reg = <0x00000000 0x00400000>;
|
||||
};
|
||||
partition@0x400000 {
|
||||
partition@400000 {
|
||||
label = "kernel image";
|
||||
reg = <0x00400000 0x00600000>;
|
||||
};
|
||||
partition@0xa00000 {
|
||||
partition@a00000 {
|
||||
label = "data";
|
||||
reg = <0x00a00000 0x005e0000>;
|
||||
};
|
||||
partition@0xfe0000 {
|
||||
partition@fe0000 {
|
||||
label = "boot environment";
|
||||
reg = <0x00fe0000 0x00020000>;
|
||||
};
|
||||
|
@ -8,11 +8,11 @@
|
||||
reg = <0x08000000 0x00400000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
partition@0x0 {
|
||||
partition@0 {
|
||||
label = "boot loader area";
|
||||
reg = <0x00000000 0x003f0000>;
|
||||
};
|
||||
partition@0x3f0000 {
|
||||
partition@3f0000 {
|
||||
label = "boot environment";
|
||||
reg = <0x003f0000 0x00010000>;
|
||||
};
|
||||
|
@ -391,7 +391,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
return 0;
|
||||
case BLKGETSIZE:
|
||||
size = i_size_read(bdev->bd_inode);
|
||||
if ((size >> 9) > ~0UL)
|
||||
if ((size >> 9) > ~(compat_ulong_t)0)
|
||||
return -EFBIG;
|
||||
return compat_put_ulong(arg, size >> 9);
|
||||
|
||||
|
@ -268,7 +268,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req,
|
||||
dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
|
||||
|
||||
skcipher_request_set_tfm(skreq, ctx->enc);
|
||||
skcipher_request_set_callback(skreq, aead_request_flags(req),
|
||||
skcipher_request_set_callback(skreq, flags,
|
||||
req->base.complete, req->base.data);
|
||||
skcipher_request_set_crypt(skreq, src, dst,
|
||||
req->cryptlen - authsize, req->iv);
|
||||
|
@ -203,6 +203,9 @@ acpi_ns_walk_namespace(acpi_object_type type,
|
||||
|
||||
if (start_node == ACPI_ROOT_OBJECT) {
|
||||
start_node = acpi_gbl_root_node;
|
||||
if (!start_node) {
|
||||
return_ACPI_STATUS(AE_NO_NAMESPACE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Null child means "get first node" */
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "BERT: " fmt
|
||||
#define ACPI_BERT_PRINT_MAX_LEN 1024
|
||||
|
||||
static int bert_disable;
|
||||
|
||||
@ -59,8 +60,11 @@ static void __init bert_print_all(struct acpi_bert_region *region,
|
||||
}
|
||||
|
||||
pr_info_once("Error records from previous boot:\n");
|
||||
|
||||
cper_estatus_print(KERN_INFO HW_ERR, estatus);
|
||||
if (region_len < ACPI_BERT_PRINT_MAX_LEN)
|
||||
cper_estatus_print(KERN_INFO HW_ERR, estatus);
|
||||
else
|
||||
pr_info_once("Max print length exceeded, table data is available at:\n"
|
||||
"/sys/firmware/acpi/tables/data/BERT");
|
||||
|
||||
/*
|
||||
* Because the boot error source is "one-time polled" type,
|
||||
@ -82,7 +86,7 @@ static int __init setup_bert_disable(char *str)
|
||||
{
|
||||
bert_disable = 1;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
__setup("bert_disable", setup_bert_disable);
|
||||
|
||||
|
@ -898,7 +898,7 @@ EXPORT_SYMBOL_GPL(erst_clear);
|
||||
static int __init setup_erst_disable(char *str)
|
||||
{
|
||||
erst_disable = 1;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("erst_disable", setup_erst_disable);
|
||||
|
@ -214,7 +214,7 @@ err:
|
||||
static int __init setup_hest_disable(char *str)
|
||||
{
|
||||
hest_disable = HEST_DISABLED;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("hest_disable", setup_hest_disable);
|
||||
|
@ -89,6 +89,10 @@ enum acpi_battery_files {
|
||||
|
||||
static const struct acpi_device_id battery_device_ids[] = {
|
||||
{"PNP0C0A", 0},
|
||||
|
||||
/* Microsoft Surface Go 3 */
|
||||
{"MSHW0146", 0},
|
||||
|
||||
{"", 0},
|
||||
};
|
||||
|
||||
@ -1183,6 +1187,14 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Microsoft Surface Go 3 */
|
||||
.callback = battery_notification_delay_quirk,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"),
|
||||
},
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
@ -678,6 +678,11 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
|
||||
cpc_obj = &out_obj->package.elements[0];
|
||||
if (cpc_obj->type == ACPI_TYPE_INTEGER) {
|
||||
num_ent = cpc_obj->integer.value;
|
||||
if (num_ent <= 1) {
|
||||
pr_debug("Unexpected _CPC NumEntries value (%d) for CPU:%d\n",
|
||||
num_ent, pr->id);
|
||||
goto out_free;
|
||||
}
|
||||
} else {
|
||||
pr_debug("Unexpected entry type(%d) for NumEntries\n",
|
||||
cpc_obj->type);
|
||||
|
@ -601,7 +601,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
|
||||
*/
|
||||
if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
|
||||
if (index)
|
||||
return -EINVAL;
|
||||
return -ENOENT;
|
||||
|
||||
ret = acpi_bus_get_device(obj->reference.handle, &device);
|
||||
if (ret)
|
||||
|
@ -356,6 +356,81 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a
|
||||
* working native and video interface. However the default detection
|
||||
* mechanism first registers the video interface before unregistering
|
||||
* it again and switching to the native interface during boot. This
|
||||
* results in a dangling SBIOS request for backlight change for some
|
||||
* reason, causing the backlight to switch to ~2% once per boot on the
|
||||
* first power cord connect or disconnect event. Setting the native
|
||||
* interface explicitly circumvents this buggy behaviour, by avoiding
|
||||
* the unregistering process.
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xRU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xRU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xRU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xRU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "AURA1501"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xRU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xNU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xNU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xNU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Desktops which falsely report a backlight and which our heuristics
|
||||
|
@ -4588,6 +4588,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||
ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
||||
{ "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM |
|
||||
ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
||||
{ "Samsung SSD 840 EVO*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
||||
ATA_HORKAGE_NO_DMA_LOG |
|
||||
ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
||||
{ "Samsung SSD 840*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
||||
ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
||||
{ "Samsung SSD 850*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
||||
|
@ -82,6 +82,8 @@ static int marvell_cable_detect(struct ata_port *ap)
|
||||
switch(ap->port_no)
|
||||
{
|
||||
case 0:
|
||||
if (!ap->ioaddr.bmdma_addr)
|
||||
return ATA_CBL_PATA_UNK;
|
||||
if (ioread8(ap->ioaddr.bmdma_addr + 1) & 1)
|
||||
return ATA_CBL_PATA40;
|
||||
return ATA_CBL_PATA80;
|
||||
|
@ -1114,6 +1114,8 @@ DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
|
||||
}
|
||||
paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(&eni_dev->pci_dev->dev, paddr))
|
||||
return enq_next;
|
||||
ENI_PRV_PADDR(skb) = paddr;
|
||||
/* prepare DMA queue entries */
|
||||
j = 0;
|
||||
|
@ -1692,6 +1692,8 @@ static int fs_init(struct fs_dev *dev)
|
||||
dev->hw_base = pci_resource_start(pci_dev, 0);
|
||||
|
||||
dev->base = ioremap(dev->hw_base, 0x1000);
|
||||
if (!dev->base)
|
||||
return 1;
|
||||
|
||||
reset_chip (dev);
|
||||
|
||||
|
@ -1917,7 +1917,9 @@ static bool pm_ops_is_empty(const struct dev_pm_ops *ops)
|
||||
|
||||
void device_pm_check_callbacks(struct device *dev)
|
||||
{
|
||||
spin_lock_irq(&dev->power.lock);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->power.lock, flags);
|
||||
dev->power.no_pm_callbacks =
|
||||
(!dev->bus || (pm_ops_is_empty(dev->bus->pm) &&
|
||||
!dev->bus->suspend && !dev->bus->resume)) &&
|
||||
@ -1927,5 +1929,5 @@ void device_pm_check_callbacks(struct device *dev)
|
||||
(!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) &&
|
||||
(!dev->driver || (pm_ops_is_empty(dev->driver->pm) &&
|
||||
!dev->driver->suspend && !dev->driver->resume));
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
spin_unlock_irqrestore(&dev->power.lock, flags);
|
||||
}
|
||||
|
@ -1690,22 +1690,22 @@ struct sib_info {
|
||||
};
|
||||
void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib);
|
||||
|
||||
extern void notify_resource_state(struct sk_buff *,
|
||||
extern int notify_resource_state(struct sk_buff *,
|
||||
unsigned int,
|
||||
struct drbd_resource *,
|
||||
struct resource_info *,
|
||||
enum drbd_notification_type);
|
||||
extern void notify_device_state(struct sk_buff *,
|
||||
extern int notify_device_state(struct sk_buff *,
|
||||
unsigned int,
|
||||
struct drbd_device *,
|
||||
struct device_info *,
|
||||
enum drbd_notification_type);
|
||||
extern void notify_connection_state(struct sk_buff *,
|
||||
extern int notify_connection_state(struct sk_buff *,
|
||||
unsigned int,
|
||||
struct drbd_connection *,
|
||||
struct connection_info *,
|
||||
enum drbd_notification_type);
|
||||
extern void notify_peer_device_state(struct sk_buff *,
|
||||
extern int notify_peer_device_state(struct sk_buff *,
|
||||
unsigned int,
|
||||
struct drbd_peer_device *,
|
||||
struct peer_device_info *,
|
||||
|
@ -4598,7 +4598,7 @@ static int nla_put_notification_header(struct sk_buff *msg,
|
||||
return drbd_notification_header_to_skb(msg, &nh, true);
|
||||
}
|
||||
|
||||
void notify_resource_state(struct sk_buff *skb,
|
||||
int notify_resource_state(struct sk_buff *skb,
|
||||
unsigned int seq,
|
||||
struct drbd_resource *resource,
|
||||
struct resource_info *resource_info,
|
||||
@ -4640,16 +4640,17 @@ void notify_resource_state(struct sk_buff *skb,
|
||||
if (err && err != -ESRCH)
|
||||
goto failed;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(skb);
|
||||
failed:
|
||||
drbd_err(resource, "Error %d while broadcasting event. Event seq:%u\n",
|
||||
err, seq);
|
||||
return err;
|
||||
}
|
||||
|
||||
void notify_device_state(struct sk_buff *skb,
|
||||
int notify_device_state(struct sk_buff *skb,
|
||||
unsigned int seq,
|
||||
struct drbd_device *device,
|
||||
struct device_info *device_info,
|
||||
@ -4689,16 +4690,17 @@ void notify_device_state(struct sk_buff *skb,
|
||||
if (err && err != -ESRCH)
|
||||
goto failed;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(skb);
|
||||
failed:
|
||||
drbd_err(device, "Error %d while broadcasting event. Event seq:%u\n",
|
||||
err, seq);
|
||||
return err;
|
||||
}
|
||||
|
||||
void notify_connection_state(struct sk_buff *skb,
|
||||
int notify_connection_state(struct sk_buff *skb,
|
||||
unsigned int seq,
|
||||
struct drbd_connection *connection,
|
||||
struct connection_info *connection_info,
|
||||
@ -4738,16 +4740,17 @@ void notify_connection_state(struct sk_buff *skb,
|
||||
if (err && err != -ESRCH)
|
||||
goto failed;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(skb);
|
||||
failed:
|
||||
drbd_err(connection, "Error %d while broadcasting event. Event seq:%u\n",
|
||||
err, seq);
|
||||
return err;
|
||||
}
|
||||
|
||||
void notify_peer_device_state(struct sk_buff *skb,
|
||||
int notify_peer_device_state(struct sk_buff *skb,
|
||||
unsigned int seq,
|
||||
struct drbd_peer_device *peer_device,
|
||||
struct peer_device_info *peer_device_info,
|
||||
@ -4788,13 +4791,14 @@ void notify_peer_device_state(struct sk_buff *skb,
|
||||
if (err && err != -ESRCH)
|
||||
goto failed;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(skb);
|
||||
failed:
|
||||
drbd_err(peer_device, "Error %d while broadcasting event. Event seq:%u\n",
|
||||
err, seq);
|
||||
return err;
|
||||
}
|
||||
|
||||
void notify_helper(enum drbd_notification_type type,
|
||||
@ -4845,7 +4849,7 @@ fail:
|
||||
err, seq);
|
||||
}
|
||||
|
||||
static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq)
|
||||
static int notify_initial_state_done(struct sk_buff *skb, unsigned int seq)
|
||||
{
|
||||
struct drbd_genlmsghdr *dh;
|
||||
int err;
|
||||
@ -4859,11 +4863,12 @@ static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq)
|
||||
if (nla_put_notification_header(skb, NOTIFY_EXISTS))
|
||||
goto nla_put_failure;
|
||||
genlmsg_end(skb, dh);
|
||||
return;
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
nlmsg_free(skb);
|
||||
pr_err("Error %d sending event. Event seq:%u\n", err, seq);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void free_state_changes(struct list_head *list)
|
||||
@ -4890,6 +4895,7 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
unsigned int seq = cb->args[2];
|
||||
unsigned int n;
|
||||
enum drbd_notification_type flags = 0;
|
||||
int err = 0;
|
||||
|
||||
/* There is no need for taking notification_mutex here: it doesn't
|
||||
matter if the initial state events mix with later state chage
|
||||
@ -4898,32 +4904,32 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
cb->args[5]--;
|
||||
if (cb->args[5] == 1) {
|
||||
notify_initial_state_done(skb, seq);
|
||||
err = notify_initial_state_done(skb, seq);
|
||||
goto out;
|
||||
}
|
||||
n = cb->args[4]++;
|
||||
if (cb->args[4] < cb->args[3])
|
||||
flags |= NOTIFY_CONTINUES;
|
||||
if (n < 1) {
|
||||
notify_resource_state_change(skb, seq, state_change->resource,
|
||||
err = notify_resource_state_change(skb, seq, state_change->resource,
|
||||
NOTIFY_EXISTS | flags);
|
||||
goto next;
|
||||
}
|
||||
n--;
|
||||
if (n < state_change->n_connections) {
|
||||
notify_connection_state_change(skb, seq, &state_change->connections[n],
|
||||
err = notify_connection_state_change(skb, seq, &state_change->connections[n],
|
||||
NOTIFY_EXISTS | flags);
|
||||
goto next;
|
||||
}
|
||||
n -= state_change->n_connections;
|
||||
if (n < state_change->n_devices) {
|
||||
notify_device_state_change(skb, seq, &state_change->devices[n],
|
||||
err = notify_device_state_change(skb, seq, &state_change->devices[n],
|
||||
NOTIFY_EXISTS | flags);
|
||||
goto next;
|
||||
}
|
||||
n -= state_change->n_devices;
|
||||
if (n < state_change->n_devices * state_change->n_connections) {
|
||||
notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n],
|
||||
err = notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n],
|
||||
NOTIFY_EXISTS | flags);
|
||||
goto next;
|
||||
}
|
||||
@ -4938,7 +4944,10 @@ next:
|
||||
cb->args[4] = 0;
|
||||
}
|
||||
out:
|
||||
return skb->len;
|
||||
if (err)
|
||||
return err;
|
||||
else
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
@ -207,7 +207,8 @@ void start_new_tl_epoch(struct drbd_connection *connection)
|
||||
void complete_master_bio(struct drbd_device *device,
|
||||
struct bio_and_error *m)
|
||||
{
|
||||
m->bio->bi_status = errno_to_blk_status(m->error);
|
||||
if (unlikely(m->error))
|
||||
m->bio->bi_status = errno_to_blk_status(m->error);
|
||||
bio_endio(m->bio);
|
||||
dec_ap_bio(device);
|
||||
}
|
||||
|
@ -1549,7 +1549,7 @@ int drbd_bitmap_io_from_worker(struct drbd_device *device,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void notify_resource_state_change(struct sk_buff *skb,
|
||||
int notify_resource_state_change(struct sk_buff *skb,
|
||||
unsigned int seq,
|
||||
struct drbd_resource_state_change *resource_state_change,
|
||||
enum drbd_notification_type type)
|
||||
@ -1562,10 +1562,10 @@ void notify_resource_state_change(struct sk_buff *skb,
|
||||
.res_susp_fen = resource_state_change->susp_fen[NEW],
|
||||
};
|
||||
|
||||
notify_resource_state(skb, seq, resource, &resource_info, type);
|
||||
return notify_resource_state(skb, seq, resource, &resource_info, type);
|
||||
}
|
||||
|
||||
void notify_connection_state_change(struct sk_buff *skb,
|
||||
int notify_connection_state_change(struct sk_buff *skb,
|
||||
unsigned int seq,
|
||||
struct drbd_connection_state_change *connection_state_change,
|
||||
enum drbd_notification_type type)
|
||||
@ -1576,10 +1576,10 @@ void notify_connection_state_change(struct sk_buff *skb,
|
||||
.conn_role = connection_state_change->peer_role[NEW],
|
||||
};
|
||||
|
||||
notify_connection_state(skb, seq, connection, &connection_info, type);
|
||||
return notify_connection_state(skb, seq, connection, &connection_info, type);
|
||||
}
|
||||
|
||||
void notify_device_state_change(struct sk_buff *skb,
|
||||
int notify_device_state_change(struct sk_buff *skb,
|
||||
unsigned int seq,
|
||||
struct drbd_device_state_change *device_state_change,
|
||||
enum drbd_notification_type type)
|
||||
@ -1589,10 +1589,10 @@ void notify_device_state_change(struct sk_buff *skb,
|
||||
.dev_disk_state = device_state_change->disk_state[NEW],
|
||||
};
|
||||
|
||||
notify_device_state(skb, seq, device, &device_info, type);
|
||||
return notify_device_state(skb, seq, device, &device_info, type);
|
||||
}
|
||||
|
||||
void notify_peer_device_state_change(struct sk_buff *skb,
|
||||
int notify_peer_device_state_change(struct sk_buff *skb,
|
||||
unsigned int seq,
|
||||
struct drbd_peer_device_state_change *p,
|
||||
enum drbd_notification_type type)
|
||||
@ -1606,7 +1606,7 @@ void notify_peer_device_state_change(struct sk_buff *skb,
|
||||
.peer_resync_susp_dependency = p->resync_susp_dependency[NEW],
|
||||
};
|
||||
|
||||
notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type);
|
||||
return notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type);
|
||||
}
|
||||
|
||||
static void broadcast_state_change(struct drbd_state_change *state_change)
|
||||
@ -1614,7 +1614,7 @@ static void broadcast_state_change(struct drbd_state_change *state_change)
|
||||
struct drbd_resource_state_change *resource_state_change = &state_change->resource[0];
|
||||
bool resource_state_has_changed;
|
||||
unsigned int n_device, n_connection, n_peer_device, n_peer_devices;
|
||||
void (*last_func)(struct sk_buff *, unsigned int, void *,
|
||||
int (*last_func)(struct sk_buff *, unsigned int, void *,
|
||||
enum drbd_notification_type) = NULL;
|
||||
void *uninitialized_var(last_arg);
|
||||
|
||||
|
@ -44,19 +44,19 @@ extern struct drbd_state_change *remember_old_state(struct drbd_resource *, gfp_
|
||||
extern void copy_old_to_new_state_change(struct drbd_state_change *);
|
||||
extern void forget_state_change(struct drbd_state_change *);
|
||||
|
||||
extern void notify_resource_state_change(struct sk_buff *,
|
||||
extern int notify_resource_state_change(struct sk_buff *,
|
||||
unsigned int,
|
||||
struct drbd_resource_state_change *,
|
||||
enum drbd_notification_type type);
|
||||
extern void notify_connection_state_change(struct sk_buff *,
|
||||
extern int notify_connection_state_change(struct sk_buff *,
|
||||
unsigned int,
|
||||
struct drbd_connection_state_change *,
|
||||
enum drbd_notification_type type);
|
||||
extern void notify_device_state_change(struct sk_buff *,
|
||||
extern int notify_device_state_change(struct sk_buff *,
|
||||
unsigned int,
|
||||
struct drbd_device_state_change *,
|
||||
enum drbd_notification_type type);
|
||||
extern void notify_peer_device_state_change(struct sk_buff *,
|
||||
extern int notify_peer_device_state_change(struct sk_buff *,
|
||||
unsigned int,
|
||||
struct drbd_peer_device_state_change *,
|
||||
enum drbd_notification_type type);
|
||||
|
@ -770,33 +770,33 @@ static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf)
|
||||
|
||||
static ssize_t loop_attr_offset_show(struct loop_device *lo, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_offset);
|
||||
return sysfs_emit(buf, "%llu\n", (unsigned long long)lo->lo_offset);
|
||||
}
|
||||
|
||||
static ssize_t loop_attr_sizelimit_show(struct loop_device *lo, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_sizelimit);
|
||||
return sysfs_emit(buf, "%llu\n", (unsigned long long)lo->lo_sizelimit);
|
||||
}
|
||||
|
||||
static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf)
|
||||
{
|
||||
int autoclear = (lo->lo_flags & LO_FLAGS_AUTOCLEAR);
|
||||
|
||||
return sprintf(buf, "%s\n", autoclear ? "1" : "0");
|
||||
return sysfs_emit(buf, "%s\n", autoclear ? "1" : "0");
|
||||
}
|
||||
|
||||
static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf)
|
||||
{
|
||||
int partscan = (lo->lo_flags & LO_FLAGS_PARTSCAN);
|
||||
|
||||
return sprintf(buf, "%s\n", partscan ? "1" : "0");
|
||||
return sysfs_emit(buf, "%s\n", partscan ? "1" : "0");
|
||||
}
|
||||
|
||||
static ssize_t loop_attr_dio_show(struct loop_device *lo, char *buf)
|
||||
{
|
||||
int dio = (lo->lo_flags & LO_FLAGS_DIRECT_IO);
|
||||
|
||||
return sprintf(buf, "%s\n", dio ? "1" : "0");
|
||||
return sysfs_emit(buf, "%s\n", dio ? "1" : "0");
|
||||
}
|
||||
|
||||
LOOP_ATTR_RO(backing_file);
|
||||
|
@ -968,9 +968,17 @@ static int virtblk_probe(struct virtio_device *vdev)
|
||||
err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE,
|
||||
struct virtio_blk_config, blk_size,
|
||||
&blk_size);
|
||||
if (!err)
|
||||
if (!err) {
|
||||
err = blk_validate_block_size(blk_size);
|
||||
if (err) {
|
||||
dev_err(&vdev->dev,
|
||||
"virtio_blk: invalid block size: 0x%x\n",
|
||||
blk_size);
|
||||
goto out_free_tags;
|
||||
}
|
||||
|
||||
blk_queue_logical_block_size(q, blk_size);
|
||||
else
|
||||
} else
|
||||
blk_size = queue_logical_block_size(q);
|
||||
|
||||
/* Use topology information if available */
|
||||
|
@ -95,6 +95,7 @@ static int atmel_trng_probe(struct platform_device *pdev)
|
||||
|
||||
err_register:
|
||||
clk_disable_unprepare(trng->clk);
|
||||
atmel_trng_disable(trng);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -134,14 +134,6 @@ static void tpm_dev_release(struct device *dev)
|
||||
kfree(chip);
|
||||
}
|
||||
|
||||
static void tpm_devs_release(struct device *dev)
|
||||
{
|
||||
struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
|
||||
|
||||
/* release the master device reference */
|
||||
put_device(&chip->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* tpm_class_shutdown() - prepare the TPM device for loss of power.
|
||||
* @dev: device to which the chip is associated.
|
||||
@ -205,7 +197,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
|
||||
chip->dev_num = rc;
|
||||
|
||||
device_initialize(&chip->dev);
|
||||
device_initialize(&chip->devs);
|
||||
|
||||
chip->dev.class = tpm_class;
|
||||
chip->dev.class->shutdown_pre = tpm_class_shutdown;
|
||||
@ -213,29 +204,12 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
|
||||
chip->dev.parent = pdev;
|
||||
chip->dev.groups = chip->groups;
|
||||
|
||||
chip->devs.parent = pdev;
|
||||
chip->devs.class = tpmrm_class;
|
||||
chip->devs.release = tpm_devs_release;
|
||||
/* get extra reference on main device to hold on
|
||||
* behalf of devs. This holds the chip structure
|
||||
* while cdevs is in use. The corresponding put
|
||||
* is in the tpm_devs_release (TPM2 only)
|
||||
*/
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
get_device(&chip->dev);
|
||||
|
||||
if (chip->dev_num == 0)
|
||||
chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
|
||||
else
|
||||
chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
|
||||
|
||||
chip->devs.devt =
|
||||
MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
|
||||
|
||||
rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
|
||||
if (rc)
|
||||
goto out;
|
||||
rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
@ -243,9 +217,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
|
||||
chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
|
||||
|
||||
cdev_init(&chip->cdev, &tpm_fops);
|
||||
cdev_init(&chip->cdevs, &tpmrm_fops);
|
||||
chip->cdev.owner = THIS_MODULE;
|
||||
chip->cdevs.owner = THIS_MODULE;
|
||||
|
||||
rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);
|
||||
if (rc) {
|
||||
@ -257,7 +229,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
|
||||
return chip;
|
||||
|
||||
out:
|
||||
put_device(&chip->devs);
|
||||
put_device(&chip->dev);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
@ -306,14 +277,9 @@ static int tpm_add_char_device(struct tpm_chip *chip)
|
||||
}
|
||||
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
|
||||
rc = cdev_device_add(&chip->cdevs, &chip->devs);
|
||||
if (rc) {
|
||||
dev_err(&chip->devs,
|
||||
"unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
|
||||
dev_name(&chip->devs), MAJOR(chip->devs.devt),
|
||||
MINOR(chip->devs.devt), rc);
|
||||
return rc;
|
||||
}
|
||||
rc = tpm_devs_add(chip);
|
||||
if (rc)
|
||||
goto err_del_cdev;
|
||||
}
|
||||
|
||||
/* Make the chip available. */
|
||||
@ -321,6 +287,10 @@ static int tpm_add_char_device(struct tpm_chip *chip)
|
||||
idr_replace(&dev_nums_idr, chip, chip->dev_num);
|
||||
mutex_unlock(&idr_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_del_cdev:
|
||||
cdev_device_del(&chip->cdev, &chip->dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -449,7 +419,7 @@ void tpm_chip_unregister(struct tpm_chip *chip)
|
||||
tpm_del_legacy_sysfs(chip);
|
||||
tpm_bios_log_teardown(chip);
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
cdev_device_del(&chip->cdevs, &chip->devs);
|
||||
tpm_devs_remove(chip);
|
||||
tpm_del_char_device(chip);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_chip_unregister);
|
||||
|
@ -593,4 +593,6 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
|
||||
u8 *cmd);
|
||||
int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
|
||||
u32 cc, u8 *buf, size_t *bufsiz);
|
||||
int tpm_devs_add(struct tpm_chip *chip);
|
||||
void tpm_devs_remove(struct tpm_chip *chip);
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user