mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-26 20:40:24 +09:00
Merge 5.15.137 into android14-5.15-lts
Changes in 5.15.137
lib/Kconfig.debug: do not enable DEBUG_PREEMPT by default
Documentation: sysctl: align cells in second content column
xfs: don't expose internal symlink metadata buffers to the vfs
Bluetooth: hci_event: Ignore NULL link key
Bluetooth: Reject connection with the device which has same BD_ADDR
Bluetooth: Fix a refcnt underflow problem for hci_conn
Bluetooth: vhci: Fix race when opening vhci device
Bluetooth: hci_event: Fix coding style
Bluetooth: avoid memcmp() out of bounds warning
ice: fix over-shifted variable
ice: reset first in crash dump kernels
nfc: nci: fix possible NULL pointer dereference in send_acknowledge()
regmap: fix NULL deref on lookup
KVM: x86: Mask LVTPC when handling a PMI
x86/sev: Disable MMIO emulation from user mode
x86/sev: Check IOBM for IOIO exceptions from user-space
x86/sev: Check for user-space IOIO pointing to kernel space
tcp: check mptcp-level constraints for backlog coalescing
fs/ntfs3: Fix possible null-pointer dereference in hdr_find_e()
fs/ntfs3: fix panic about slab-out-of-bounds caused by ntfs_list_ea()
fs/ntfs3: fix deadlock in mark_as_free_ex
netfilter: nft_payload: fix wrong mac header matching
nvmet-tcp: Fix a possible UAF in queue intialization setup
drm/i915: Retry gtt fault when out of fence registers
ASoC: codecs: wcd938x-sdw: fix use after free on driver unbind
ASoC: codecs: wcd938x-sdw: fix runtime PM imbalance on probe errors
ASoC: codecs: wcd938x: drop bogus bind error handling
ASoC: codecs: wcd938x: fix unbind tear down order
qed: fix LL2 RX buffer allocation
xfrm: fix a data-race in xfrm_gen_index()
xfrm: interface: use DEV_STATS_INC()
net: ipv4: fix return value check in esp_remove_trailer
net: ipv6: fix return value check in esp_remove_trailer
net: rfkill: gpio: prevent value glitch during probe
tcp: fix excessive TLP and RACK timeouts from HZ rounding
tcp: tsq: relax tcp_small_queue_check() when rtx queue contains a single skb
tun: prevent negative ifindex
ipv4: fib: annotate races around nh->nh_saddr_genid and nh->nh_saddr
net: usb: smsc95xx: Fix an error code in smsc95xx_reset()
i40e: prevent crash on probe if hw registers have invalid values
net: dsa: bcm_sf2: Fix possible memory leak in bcm_sf2_mdio_register()
bonding: Return pointer to data after pull on skb
net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve
neighbor: tracing: Move pin6 inside CONFIG_IPV6=y section
netfilter: nft_set_rbtree: .deactivate fails if element has expired
netfilter: nf_tables: do not remove elements if set backend implements .abort
netfilter: nf_tables: revert do not remove elements if set backend implements .abort
net: pktgen: Fix interface flags printing
selftests/mm: fix awk usage in charge_reserved_hugetlb.sh and hugetlb_reparenting_test.sh that may cause error
serial: 8250: omap: Fix imprecise external abort for omap_8250_pm()
serial: 8250_omap: Fix errors with no_console_suspend
iio: Un-inline iio_buffer_enabled()
iio: core: Hide read accesses to iio_dev->currentmode
iio: core: introduce iio_device_{claim|release}_buffer_mode() APIs
iio: cros_ec: fix an use-after-free in cros_ec_sensors_push_data()
iio: adc: ad7192: Correct reference voltage
perf: Add irq and exception return branch types
perf/x86: Move branch classifier
perf/x86/lbr: Filter vsyscall addresses
drm/atomic-helper: relax unregistered connector check
powerpc/32s: Remove capability to disable KUEP at boottime
powerpc/32s: Do kuep_lock() and kuep_unlock() in assembly
powerpc/47x: Fix 47x syscall return crash
mctp: Allow local delivery to the null EID
mctp: perform route lookups under a RCU read-side lock
nfp: flower: avoid rmmod nfp crash issues
ksmbd: not allow to open file if delelete on close bit is set
ARM: dts: ti: omap: Fix noisy serial with overrun-throttle-ms for mapphone
fs-writeback: do not requeue a clean inode having skipped pages
btrfs: return -EUCLEAN for delayed tree ref with a ref count not equals to 1
btrfs: initialize start_slot in btrfs_log_prealloc_extents
i2c: mux: Avoid potential false error message in i2c_mux_add_adapter
overlayfs: set ctime when setting mtime and atime
gpio: timberdale: Fix potential deadlock on &tgpio->lock
ata: libata-core: Fix compilation warning in ata_dev_config_ncq()
ata: libata-eh: Fix compilation warning in ata_eh_link_report()
tracing: relax trace_event_eval_update() execution with cond_resched()
wifi: mwifiex: Sanity check tlv_len and tlv_bitmap_len
wifi: iwlwifi: Ensure ack flag is properly cleared.
HID: holtek: fix slab-out-of-bounds Write in holtek_kbd_input_event
Bluetooth: btusb: add shutdown function for QCA6174
Bluetooth: Avoid redundant authentication
Bluetooth: hci_core: Fix build warnings
wifi: cfg80211: Fix 6GHz scan configuration
wifi: mac80211: allow transmitting EAPOL frames with tainted key
wifi: cfg80211: avoid leaking stack data into trace
regulator/core: Revert "fix kobject release warning and memory leak in regulator_register()"
sky2: Make sure there is at least one frag_addr available
ipv4/fib: send notify when delete source address routes
drm: panel-orientation-quirks: Add quirk for One Mix 2S
btrfs: fix some -Wmaybe-uninitialized warnings in ioctl.c
btrfs: error out when COWing block using a stale transaction
btrfs: error when COWing block from a root that is being deleted
btrfs: error out when reallocating block for defrag using a stale transaction
HID: multitouch: Add required quirk for Synaptics 0xcd7e device
platform/x86: touchscreen_dmi: Add info for the Positivo C4128B
net/mlx5: Handle fw tracer change ownership event based on MTRC
Bluetooth: hci_event: Fix using memcmp when comparing keys
net: introduce a function to check if a netdev name is in use
net: move from strlcpy with unused retval to strscpy
net: fix ifname in netlink ntf during netns move
mtd: rawnand: qcom: Unmap the right resource upon probe failure
mtd: rawnand: pl353: Ensure program page operations are successful
mtd: rawnand: marvell: Ensure program page operations are successful
mtd: rawnand: arasan: Ensure program page operations are successful
mtd: spinand: micron: correct bitmask for ecc status
mtd: physmap-core: Restore map_rom fallback
mmc: mtk-sd: Use readl_poll_timeout_atomic in msdc_reset_hw
mmc: core: sdio: hold retuning if sdio in 1-bit mode
mmc: core: Capture correct oemid-bits for eMMC cards
Revert "pinctrl: avoid unsafe code pattern in find_pinctrl()"
pNFS: Fix a hang in nfs4_evict_inode()
NFSv4.1: fixup use EXCHGID4_FLAG_USE_PNFS_DS for DS server
ACPI: irq: Fix incorrect return value in acpi_register_gsi()
nvme-pci: add BOGUS_NID for Intel 0a54 device
nvme-rdma: do not try to stop unallocated queues
USB: serial: option: add Telit LE910C4-WWX 0x1035 composition
USB: serial: option: add entry for Sierra EM9191 with new firmware
USB: serial: option: add Fibocom to DELL custom modem FM101R-GL
perf: Disallow mis-matched inherited group reads
s390/pci: fix iommu bitmap allocation
selftests/ftrace: Add new test case which checks non unique symbol
s390/cio: fix a memleak in css_alloc_subchannel
platform/surface: platform_profile: Propagate error if profile registration fails
platform/x86: asus-wmi: Change ASUS_WMI_BRN_DOWN code from 0x20 to 0x2e
platform/x86: asus-wmi: Map 0x2a code, Ignore 0x2b and 0x2c events
gpio: vf610: set value before the direction to avoid a glitch
ASoC: pxa: fix a memory leak in probe()
serial: 8250: omap: Move uart_write() inside PM section
phy: mapphone-mdm6600: Fix runtime disable on probe
phy: mapphone-mdm6600: Fix runtime PM for remove
phy: mapphone-mdm6600: Fix pinctrl_pm handling for sleep pins
Bluetooth: hci_sock: fix slab oob read in create_monitor_event
Bluetooth: hci_sock: Correctly bounds check and pad HCI_MON_NEW_INDEX name
xfrm6: fix inet6_dev refcount underflow problem
Linux 5.15.137
Change-Id: I87cc61586cd29ad60368586cf3c4dca181eec9c2
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -31,18 +31,18 @@ see only some of them, depending on your kernel's configuration.
|
||||
|
||||
Table : Subdirectories in /proc/sys/net
|
||||
|
||||
========= =================== = ========== ==================
|
||||
========= =================== = ========== ===================
|
||||
Directory Content Directory Content
|
||||
========= =================== = ========== ==================
|
||||
802 E802 protocol mptcp Multipath TCP
|
||||
appletalk Appletalk protocol netfilter Network Filter
|
||||
========= =================== = ========== ===================
|
||||
802 E802 protocol mptcp Multipath TCP
|
||||
appletalk Appletalk protocol netfilter Network Filter
|
||||
ax25 AX25 netrom NET/ROM
|
||||
bridge Bridging rose X.25 PLP layer
|
||||
core General parameter tipc TIPC
|
||||
ethernet Ethernet protocol unix Unix domain sockets
|
||||
ipv4 IP version 4 x25 X.25 protocol
|
||||
bridge Bridging rose X.25 PLP layer
|
||||
core General parameter tipc TIPC
|
||||
ethernet Ethernet protocol unix Unix domain sockets
|
||||
ipv4 IP version 4 x25 X.25 protocol
|
||||
ipv6 IP version 6
|
||||
========= =================== = ========== ==================
|
||||
========= =================== = ========== ===================
|
||||
|
||||
1. /proc/sys/net/core - Network core options
|
||||
============================================
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 15
|
||||
SUBLEVEL = 136
|
||||
SUBLEVEL = 137
|
||||
EXTRAVERSION =
|
||||
NAME = Trick or Treat
|
||||
|
||||
|
||||
@@ -640,6 +640,7 @@
|
||||
&uart3 {
|
||||
interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
|
||||
&omap4_pmx_core 0x17c>;
|
||||
overrun-throttle-ms = <500>;
|
||||
};
|
||||
|
||||
&uart4 {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
extern struct static_key_false disable_kuap_key;
|
||||
extern struct static_key_false disable_kuep_key;
|
||||
|
||||
static __always_inline bool kuap_is_disabled(void)
|
||||
{
|
||||
@@ -21,41 +20,7 @@ static __always_inline bool kuap_is_disabled(void)
|
||||
|
||||
static __always_inline bool kuep_is_disabled(void)
|
||||
{
|
||||
return !IS_ENABLED(CONFIG_PPC_KUEP) || static_branch_unlikely(&disable_kuep_key);
|
||||
}
|
||||
|
||||
static inline void kuep_lock(void)
|
||||
{
|
||||
if (kuep_is_disabled())
|
||||
return;
|
||||
|
||||
update_user_segments(mfsr(0) | SR_NX);
|
||||
/*
|
||||
* This isync() shouldn't be necessary as the kernel is not excepted to
|
||||
* run any instruction in userspace soon after the update of segments,
|
||||
* but hash based cores (at least G3) seem to exhibit a random
|
||||
* behaviour when the 'isync' is not there. 603 cores don't have this
|
||||
* behaviour so don't do the 'isync' as it saves several CPU cycles.
|
||||
*/
|
||||
if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
|
||||
isync(); /* Context sync required after mtsr() */
|
||||
}
|
||||
|
||||
static inline void kuep_unlock(void)
|
||||
{
|
||||
if (kuep_is_disabled())
|
||||
return;
|
||||
|
||||
update_user_segments(mfsr(0) & ~SR_NX);
|
||||
/*
|
||||
* This isync() shouldn't be necessary as a 'rfi' will soon be executed
|
||||
* to return to userspace, but hash based cores (at least G3) seem to
|
||||
* exhibit a random behaviour when the 'isync' is not there. 603 cores
|
||||
* don't have this behaviour so don't do the 'isync' as it saves several
|
||||
* CPU cycles.
|
||||
*/
|
||||
if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
|
||||
isync(); /* Context sync required after mtsr() */
|
||||
return !IS_ENABLED(CONFIG_PPC_KUEP);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_KUAP
|
||||
|
||||
@@ -64,7 +64,82 @@ struct ppc_bat {
|
||||
#define SR_KP 0x20000000 /* User key */
|
||||
#define SR_KS 0x40000000 /* Supervisor key */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
|
||||
.macro uus_addi sr reg1 reg2 imm
|
||||
.if NUM_USER_SEGMENTS > \sr
|
||||
addi \reg1,\reg2,\imm
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro uus_mtsr sr reg1
|
||||
.if NUM_USER_SEGMENTS > \sr
|
||||
mtsr \sr, \reg1
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* This isync() shouldn't be necessary as the kernel is not excepted to run
|
||||
* any instruction in userspace soon after the update of segments and 'rfi'
|
||||
* instruction is used to return to userspace, but hash based cores
|
||||
* (at least G3) seem to exhibit a random behaviour when the 'isync' is not
|
||||
* there. 603 cores don't have this behaviour so don't do the 'isync' as it
|
||||
* saves several CPU cycles.
|
||||
*/
|
||||
.macro uus_isync
|
||||
#ifdef CONFIG_PPC_BOOK3S_604
|
||||
BEGIN_MMU_FTR_SECTION
|
||||
isync
|
||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro update_user_segments_by_4 tmp1 tmp2 tmp3 tmp4
|
||||
uus_addi 1, \tmp2, \tmp1, 0x111
|
||||
uus_addi 2, \tmp3, \tmp1, 0x222
|
||||
uus_addi 3, \tmp4, \tmp1, 0x333
|
||||
|
||||
uus_mtsr 0, \tmp1
|
||||
uus_mtsr 1, \tmp2
|
||||
uus_mtsr 2, \tmp3
|
||||
uus_mtsr 3, \tmp4
|
||||
|
||||
uus_addi 4, \tmp1, \tmp1, 0x444
|
||||
uus_addi 5, \tmp2, \tmp2, 0x444
|
||||
uus_addi 6, \tmp3, \tmp3, 0x444
|
||||
uus_addi 7, \tmp4, \tmp4, 0x444
|
||||
|
||||
uus_mtsr 4, \tmp1
|
||||
uus_mtsr 5, \tmp2
|
||||
uus_mtsr 6, \tmp3
|
||||
uus_mtsr 7, \tmp4
|
||||
|
||||
uus_addi 8, \tmp1, \tmp1, 0x444
|
||||
uus_addi 9, \tmp2, \tmp2, 0x444
|
||||
uus_addi 10, \tmp3, \tmp3, 0x444
|
||||
uus_addi 11, \tmp4, \tmp4, 0x444
|
||||
|
||||
uus_mtsr 8, \tmp1
|
||||
uus_mtsr 9, \tmp2
|
||||
uus_mtsr 10, \tmp3
|
||||
uus_mtsr 11, \tmp4
|
||||
|
||||
uus_addi 12, \tmp1, \tmp1, 0x444
|
||||
uus_addi 13, \tmp2, \tmp2, 0x444
|
||||
uus_addi 14, \tmp3, \tmp3, 0x444
|
||||
uus_addi 15, \tmp4, \tmp4, 0x444
|
||||
|
||||
uus_mtsr 12, \tmp1
|
||||
uus_mtsr 13, \tmp2
|
||||
uus_mtsr 14, \tmp3
|
||||
uus_mtsr 15, \tmp4
|
||||
|
||||
uus_isync
|
||||
.endm
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* This macro defines the mapping from contexts to VSIDs (virtual
|
||||
|
||||
@@ -139,12 +139,10 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
|
||||
if (!arch_irq_disabled_regs(regs))
|
||||
trace_hardirqs_off();
|
||||
|
||||
if (user_mode(regs)) {
|
||||
kuep_lock();
|
||||
if (user_mode(regs))
|
||||
account_cpu_user_entry();
|
||||
} else {
|
||||
else
|
||||
kuap_save_and_lock(regs);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
|
||||
@@ -38,11 +38,6 @@ void setup_kuep(bool disabled);
|
||||
static inline void setup_kuep(bool disabled) { }
|
||||
#endif /* CONFIG_PPC_KUEP */
|
||||
|
||||
#ifndef CONFIG_PPC_BOOK3S_32
|
||||
static inline void kuep_lock(void) { }
|
||||
static inline void kuep_unlock(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_KUAP
|
||||
void setup_kuap(bool disabled);
|
||||
#else
|
||||
|
||||
@@ -73,6 +73,34 @@ prepare_transfer_to_handler:
|
||||
_ASM_NOKPROBE_SYMBOL(prepare_transfer_to_handler)
|
||||
#endif /* CONFIG_PPC_BOOK3S_32 || CONFIG_E500 */
|
||||
|
||||
#if defined(CONFIG_PPC_KUEP) && defined(CONFIG_PPC_BOOK3S_32)
|
||||
.globl __kuep_lock
|
||||
__kuep_lock:
|
||||
mfsr r9,0
|
||||
rlwinm r9,r9,0,8,3
|
||||
oris r9,r9,SR_NX@h
|
||||
update_user_segments_by_4 r9, r10, r11, r12
|
||||
blr
|
||||
|
||||
__kuep_unlock:
|
||||
mfsr r9,0
|
||||
rlwinm r9,r9,0,8,2
|
||||
update_user_segments_by_4 r9, r10, r11, r12
|
||||
blr
|
||||
|
||||
.macro kuep_lock
|
||||
bl __kuep_lock
|
||||
.endm
|
||||
.macro kuep_unlock
|
||||
bl __kuep_unlock
|
||||
.endm
|
||||
#else
|
||||
.macro kuep_lock
|
||||
.endm
|
||||
.macro kuep_unlock
|
||||
.endm
|
||||
#endif
|
||||
|
||||
.globl transfer_to_syscall
|
||||
transfer_to_syscall:
|
||||
stw r11, GPR1(r1)
|
||||
@@ -93,6 +121,7 @@ transfer_to_syscall:
|
||||
SAVE_GPRS(3, 8, r1)
|
||||
addi r2,r10,-THREAD
|
||||
SAVE_NVGPRS(r1)
|
||||
kuep_lock
|
||||
|
||||
/* Calling convention has r9 = orig r0, r10 = regs */
|
||||
addi r10,r1,STACK_FRAME_OVERHEAD
|
||||
@@ -107,8 +136,10 @@ ret_from_syscall:
|
||||
lis r4,icache_44x_need_flush@ha
|
||||
lwz r5,icache_44x_need_flush@l(r4)
|
||||
cmplwi cr0,r5,0
|
||||
bne- 2f
|
||||
bne- .L44x_icache_flush
|
||||
#endif /* CONFIG_PPC_47x */
|
||||
.L44x_icache_flush_return:
|
||||
kuep_unlock
|
||||
lwz r4,_LINK(r1)
|
||||
lwz r5,_CCR(r1)
|
||||
mtlr r4
|
||||
@@ -143,10 +174,11 @@ syscall_exit_finish:
|
||||
b 1b
|
||||
|
||||
#ifdef CONFIG_44x
|
||||
2: li r7,0
|
||||
.L44x_icache_flush:
|
||||
li r7,0
|
||||
iccci r0,r0
|
||||
stw r7,icache_44x_need_flush@l(r4)
|
||||
b 1b
|
||||
b .L44x_icache_flush_return
|
||||
#endif /* CONFIG_44x */
|
||||
|
||||
.globl ret_from_fork
|
||||
@@ -272,6 +304,7 @@ interrupt_return:
|
||||
beq .Lkernel_interrupt_return
|
||||
bl interrupt_exit_user_prepare
|
||||
cmpwi r3,0
|
||||
kuep_unlock
|
||||
bne- .Lrestore_nvgprs
|
||||
|
||||
.Lfast_user_interrupt_return:
|
||||
|
||||
@@ -135,6 +135,12 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
|
||||
andi. r12,r9,MSR_PR
|
||||
bne 777f
|
||||
bl prepare_transfer_to_handler
|
||||
#ifdef CONFIG_PPC_KUEP
|
||||
b 778f
|
||||
777:
|
||||
bl __kuep_lock
|
||||
778:
|
||||
#endif
|
||||
777:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
@@ -931,7 +931,11 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
|
||||
_GLOBAL(load_segment_registers)
|
||||
li r0, NUM_USER_SEGMENTS /* load up user segment register values */
|
||||
mtctr r0 /* for context 0 */
|
||||
#ifdef CONFIG_PPC_KUEP
|
||||
lis r3, SR_NX@h /* Kp = 0, Ks = 0, VSID = 0 */
|
||||
#else
|
||||
li r3, 0 /* Kp = 0, Ks = 0, VSID = 0 */
|
||||
#endif
|
||||
li r4, 0
|
||||
3: mtsrin r3, r4
|
||||
addi r3, r3, 0x111 /* increment VSID */
|
||||
|
||||
@@ -83,8 +83,6 @@ notrace long system_call_exception(long r3, long r4, long r5,
|
||||
{
|
||||
syscall_fn f;
|
||||
|
||||
kuep_lock();
|
||||
|
||||
regs->orig_gpr3 = r3;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
|
||||
@@ -408,7 +406,6 @@ again:
|
||||
|
||||
/* Restore user access locks last */
|
||||
kuap_user_restore(regs);
|
||||
kuep_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3,18 +3,10 @@
|
||||
#include <asm/kup.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
struct static_key_false disable_kuep_key;
|
||||
|
||||
void setup_kuep(bool disabled)
|
||||
{
|
||||
if (!disabled)
|
||||
kuep_lock();
|
||||
|
||||
if (smp_processor_id() != boot_cpuid)
|
||||
return;
|
||||
|
||||
if (disabled)
|
||||
static_branch_enable(&disable_kuep_key);
|
||||
else
|
||||
pr_info("Activating Kernel Userspace Execution Prevention\n");
|
||||
pr_info("Activating Kernel Userspace Execution Prevention\n");
|
||||
}
|
||||
|
||||
@@ -542,6 +542,17 @@ static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||
s->dma_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long *bitmap_vzalloc(size_t bits, gfp_t flags)
|
||||
{
|
||||
size_t n = BITS_TO_LONGS(bits);
|
||||
size_t bytes;
|
||||
|
||||
if (unlikely(check_mul_overflow(n, sizeof(unsigned long), &bytes)))
|
||||
return NULL;
|
||||
|
||||
return vzalloc(bytes);
|
||||
}
|
||||
|
||||
int zpci_dma_init_device(struct zpci_dev *zdev)
|
||||
{
|
||||
@@ -578,13 +589,13 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
|
||||
zdev->end_dma - zdev->start_dma + 1);
|
||||
zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1;
|
||||
zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT;
|
||||
zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8);
|
||||
zdev->iommu_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL);
|
||||
if (!zdev->iommu_bitmap) {
|
||||
rc = -ENOMEM;
|
||||
goto free_dma_table;
|
||||
}
|
||||
if (!s390_iommu_strict) {
|
||||
zdev->lazy_bitmap = vzalloc(zdev->iommu_pages / 8);
|
||||
zdev->lazy_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL);
|
||||
if (!zdev->lazy_bitmap) {
|
||||
rc = -ENOMEM;
|
||||
goto free_bitmap;
|
||||
|
||||
@@ -105,6 +105,16 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,
|
||||
return ES_OK;
|
||||
}
|
||||
|
||||
static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size)
|
||||
{
|
||||
return ES_OK;
|
||||
}
|
||||
|
||||
static bool fault_in_kernel_space(unsigned long address)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef __init
|
||||
#undef __pa
|
||||
#define __init
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-y += core.o probe.o
|
||||
obj-y += core.o probe.o utils.o
|
||||
obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += rapl.o
|
||||
obj-y += amd/
|
||||
obj-$(CONFIG_X86_LOCAL_APIC) += msr.o
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <asm/perf_event.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/insn.h>
|
||||
|
||||
#include "../perf_event.h"
|
||||
|
||||
@@ -73,65 +72,6 @@ static const enum {
|
||||
|
||||
#define LBR_FROM_SIGNEXT_2MSB (BIT_ULL(60) | BIT_ULL(59))
|
||||
|
||||
/*
|
||||
* x86control flow change classification
|
||||
* x86control flow changes include branches, interrupts, traps, faults
|
||||
*/
|
||||
enum {
|
||||
X86_BR_NONE = 0, /* unknown */
|
||||
|
||||
X86_BR_USER = 1 << 0, /* branch target is user */
|
||||
X86_BR_KERNEL = 1 << 1, /* branch target is kernel */
|
||||
|
||||
X86_BR_CALL = 1 << 2, /* call */
|
||||
X86_BR_RET = 1 << 3, /* return */
|
||||
X86_BR_SYSCALL = 1 << 4, /* syscall */
|
||||
X86_BR_SYSRET = 1 << 5, /* syscall return */
|
||||
X86_BR_INT = 1 << 6, /* sw interrupt */
|
||||
X86_BR_IRET = 1 << 7, /* return from interrupt */
|
||||
X86_BR_JCC = 1 << 8, /* conditional */
|
||||
X86_BR_JMP = 1 << 9, /* jump */
|
||||
X86_BR_IRQ = 1 << 10,/* hw interrupt or trap or fault */
|
||||
X86_BR_IND_CALL = 1 << 11,/* indirect calls */
|
||||
X86_BR_ABORT = 1 << 12,/* transaction abort */
|
||||
X86_BR_IN_TX = 1 << 13,/* in transaction */
|
||||
X86_BR_NO_TX = 1 << 14,/* not in transaction */
|
||||
X86_BR_ZERO_CALL = 1 << 15,/* zero length call */
|
||||
X86_BR_CALL_STACK = 1 << 16,/* call stack */
|
||||
X86_BR_IND_JMP = 1 << 17,/* indirect jump */
|
||||
|
||||
X86_BR_TYPE_SAVE = 1 << 18,/* indicate to save branch type */
|
||||
|
||||
};
|
||||
|
||||
#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
|
||||
#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX)
|
||||
|
||||
#define X86_BR_ANY \
|
||||
(X86_BR_CALL |\
|
||||
X86_BR_RET |\
|
||||
X86_BR_SYSCALL |\
|
||||
X86_BR_SYSRET |\
|
||||
X86_BR_INT |\
|
||||
X86_BR_IRET |\
|
||||
X86_BR_JCC |\
|
||||
X86_BR_JMP |\
|
||||
X86_BR_IRQ |\
|
||||
X86_BR_ABORT |\
|
||||
X86_BR_IND_CALL |\
|
||||
X86_BR_IND_JMP |\
|
||||
X86_BR_ZERO_CALL)
|
||||
|
||||
#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
|
||||
|
||||
#define X86_BR_ANY_CALL \
|
||||
(X86_BR_CALL |\
|
||||
X86_BR_IND_CALL |\
|
||||
X86_BR_ZERO_CALL |\
|
||||
X86_BR_SYSCALL |\
|
||||
X86_BR_IRQ |\
|
||||
X86_BR_INT)
|
||||
|
||||
/*
|
||||
* Intel LBR_CTL bits
|
||||
*
|
||||
@@ -1168,219 +1108,6 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the type of control flow change at address "from"
|
||||
* instruction is not necessarily a branch (in case of interrupt).
|
||||
*
|
||||
* The branch type returned also includes the priv level of the
|
||||
* target of the control flow change (X86_BR_USER, X86_BR_KERNEL).
|
||||
*
|
||||
* If a branch type is unknown OR the instruction cannot be
|
||||
* decoded (e.g., text page not present), then X86_BR_NONE is
|
||||
* returned.
|
||||
*/
|
||||
static int branch_type(unsigned long from, unsigned long to, int abort)
|
||||
{
|
||||
struct insn insn;
|
||||
void *addr;
|
||||
int bytes_read, bytes_left;
|
||||
int ret = X86_BR_NONE;
|
||||
int ext, to_plm, from_plm;
|
||||
u8 buf[MAX_INSN_SIZE];
|
||||
int is64 = 0;
|
||||
|
||||
to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
|
||||
from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
|
||||
|
||||
/*
|
||||
* maybe zero if lbr did not fill up after a reset by the time
|
||||
* we get a PMU interrupt
|
||||
*/
|
||||
if (from == 0 || to == 0)
|
||||
return X86_BR_NONE;
|
||||
|
||||
if (abort)
|
||||
return X86_BR_ABORT | to_plm;
|
||||
|
||||
if (from_plm == X86_BR_USER) {
|
||||
/*
|
||||
* can happen if measuring at the user level only
|
||||
* and we interrupt in a kernel thread, e.g., idle.
|
||||
*/
|
||||
if (!current->mm)
|
||||
return X86_BR_NONE;
|
||||
|
||||
/* may fail if text not present */
|
||||
bytes_left = copy_from_user_nmi(buf, (void __user *)from,
|
||||
MAX_INSN_SIZE);
|
||||
bytes_read = MAX_INSN_SIZE - bytes_left;
|
||||
if (!bytes_read)
|
||||
return X86_BR_NONE;
|
||||
|
||||
addr = buf;
|
||||
} else {
|
||||
/*
|
||||
* The LBR logs any address in the IP, even if the IP just
|
||||
* faulted. This means userspace can control the from address.
|
||||
* Ensure we don't blindly read any address by validating it is
|
||||
* a known text address.
|
||||
*/
|
||||
if (kernel_text_address(from)) {
|
||||
addr = (void *)from;
|
||||
/*
|
||||
* Assume we can get the maximum possible size
|
||||
* when grabbing kernel data. This is not
|
||||
* _strictly_ true since we could possibly be
|
||||
* executing up next to a memory hole, but
|
||||
* it is very unlikely to be a problem.
|
||||
*/
|
||||
bytes_read = MAX_INSN_SIZE;
|
||||
} else {
|
||||
return X86_BR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* decoder needs to know the ABI especially
|
||||
* on 64-bit systems running 32-bit apps
|
||||
*/
|
||||
#ifdef CONFIG_X86_64
|
||||
is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs());
|
||||
#endif
|
||||
insn_init(&insn, addr, bytes_read, is64);
|
||||
if (insn_get_opcode(&insn))
|
||||
return X86_BR_ABORT;
|
||||
|
||||
switch (insn.opcode.bytes[0]) {
|
||||
case 0xf:
|
||||
switch (insn.opcode.bytes[1]) {
|
||||
case 0x05: /* syscall */
|
||||
case 0x34: /* sysenter */
|
||||
ret = X86_BR_SYSCALL;
|
||||
break;
|
||||
case 0x07: /* sysret */
|
||||
case 0x35: /* sysexit */
|
||||
ret = X86_BR_SYSRET;
|
||||
break;
|
||||
case 0x80 ... 0x8f: /* conditional */
|
||||
ret = X86_BR_JCC;
|
||||
break;
|
||||
default:
|
||||
ret = X86_BR_NONE;
|
||||
}
|
||||
break;
|
||||
case 0x70 ... 0x7f: /* conditional */
|
||||
ret = X86_BR_JCC;
|
||||
break;
|
||||
case 0xc2: /* near ret */
|
||||
case 0xc3: /* near ret */
|
||||
case 0xca: /* far ret */
|
||||
case 0xcb: /* far ret */
|
||||
ret = X86_BR_RET;
|
||||
break;
|
||||
case 0xcf: /* iret */
|
||||
ret = X86_BR_IRET;
|
||||
break;
|
||||
case 0xcc ... 0xce: /* int */
|
||||
ret = X86_BR_INT;
|
||||
break;
|
||||
case 0xe8: /* call near rel */
|
||||
if (insn_get_immediate(&insn) || insn.immediate1.value == 0) {
|
||||
/* zero length call */
|
||||
ret = X86_BR_ZERO_CALL;
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
case 0x9a: /* call far absolute */
|
||||
ret = X86_BR_CALL;
|
||||
break;
|
||||
case 0xe0 ... 0xe3: /* loop jmp */
|
||||
ret = X86_BR_JCC;
|
||||
break;
|
||||
case 0xe9 ... 0xeb: /* jmp */
|
||||
ret = X86_BR_JMP;
|
||||
break;
|
||||
case 0xff: /* call near absolute, call far absolute ind */
|
||||
if (insn_get_modrm(&insn))
|
||||
return X86_BR_ABORT;
|
||||
|
||||
ext = (insn.modrm.bytes[0] >> 3) & 0x7;
|
||||
switch (ext) {
|
||||
case 2: /* near ind call */
|
||||
case 3: /* far ind call */
|
||||
ret = X86_BR_IND_CALL;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
ret = X86_BR_IND_JMP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = X86_BR_NONE;
|
||||
}
|
||||
/*
|
||||
* interrupts, traps, faults (and thus ring transition) may
|
||||
* occur on any instructions. Thus, to classify them correctly,
|
||||
* we need to first look at the from and to priv levels. If they
|
||||
* are different and to is in the kernel, then it indicates
|
||||
* a ring transition. If the from instruction is not a ring
|
||||
* transition instr (syscall, systenter, int), then it means
|
||||
* it was a irq, trap or fault.
|
||||
*
|
||||
* we have no way of detecting kernel to kernel faults.
|
||||
*/
|
||||
if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL
|
||||
&& ret != X86_BR_SYSCALL && ret != X86_BR_INT)
|
||||
ret = X86_BR_IRQ;
|
||||
|
||||
/*
|
||||
* branch priv level determined by target as
|
||||
* is done by HW when LBR_SELECT is implemented
|
||||
*/
|
||||
if (ret != X86_BR_NONE)
|
||||
ret |= to_plm;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define X86_BR_TYPE_MAP_MAX 16
|
||||
|
||||
static int branch_map[X86_BR_TYPE_MAP_MAX] = {
|
||||
PERF_BR_CALL, /* X86_BR_CALL */
|
||||
PERF_BR_RET, /* X86_BR_RET */
|
||||
PERF_BR_SYSCALL, /* X86_BR_SYSCALL */
|
||||
PERF_BR_SYSRET, /* X86_BR_SYSRET */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_INT */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_IRET */
|
||||
PERF_BR_COND, /* X86_BR_JCC */
|
||||
PERF_BR_UNCOND, /* X86_BR_JMP */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_IRQ */
|
||||
PERF_BR_IND_CALL, /* X86_BR_IND_CALL */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_ABORT */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_IN_TX */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_NO_TX */
|
||||
PERF_BR_CALL, /* X86_BR_ZERO_CALL */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_CALL_STACK */
|
||||
PERF_BR_IND, /* X86_BR_IND_JMP */
|
||||
};
|
||||
|
||||
static int
|
||||
common_branch_type(int type)
|
||||
{
|
||||
int i;
|
||||
|
||||
type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */
|
||||
|
||||
if (type) {
|
||||
i = __ffs(type);
|
||||
if (i < X86_BR_TYPE_MAP_MAX)
|
||||
return branch_map[i];
|
||||
}
|
||||
|
||||
return PERF_BR_UNKNOWN;
|
||||
}
|
||||
|
||||
enum {
|
||||
ARCH_LBR_BR_TYPE_JCC = 0,
|
||||
ARCH_LBR_BR_TYPE_NEAR_IND_JMP = 1,
|
||||
|
||||
@@ -1181,6 +1181,68 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
|
||||
regs->ip = ip;
|
||||
}
|
||||
|
||||
/*
|
||||
* x86control flow change classification
|
||||
* x86control flow changes include branches, interrupts, traps, faults
|
||||
*/
|
||||
enum {
|
||||
X86_BR_NONE = 0, /* unknown */
|
||||
|
||||
X86_BR_USER = 1 << 0, /* branch target is user */
|
||||
X86_BR_KERNEL = 1 << 1, /* branch target is kernel */
|
||||
|
||||
X86_BR_CALL = 1 << 2, /* call */
|
||||
X86_BR_RET = 1 << 3, /* return */
|
||||
X86_BR_SYSCALL = 1 << 4, /* syscall */
|
||||
X86_BR_SYSRET = 1 << 5, /* syscall return */
|
||||
X86_BR_INT = 1 << 6, /* sw interrupt */
|
||||
X86_BR_IRET = 1 << 7, /* return from interrupt */
|
||||
X86_BR_JCC = 1 << 8, /* conditional */
|
||||
X86_BR_JMP = 1 << 9, /* jump */
|
||||
X86_BR_IRQ = 1 << 10,/* hw interrupt or trap or fault */
|
||||
X86_BR_IND_CALL = 1 << 11,/* indirect calls */
|
||||
X86_BR_ABORT = 1 << 12,/* transaction abort */
|
||||
X86_BR_IN_TX = 1 << 13,/* in transaction */
|
||||
X86_BR_NO_TX = 1 << 14,/* not in transaction */
|
||||
X86_BR_ZERO_CALL = 1 << 15,/* zero length call */
|
||||
X86_BR_CALL_STACK = 1 << 16,/* call stack */
|
||||
X86_BR_IND_JMP = 1 << 17,/* indirect jump */
|
||||
|
||||
X86_BR_TYPE_SAVE = 1 << 18,/* indicate to save branch type */
|
||||
|
||||
};
|
||||
|
||||
#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
|
||||
#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX)
|
||||
|
||||
#define X86_BR_ANY \
|
||||
(X86_BR_CALL |\
|
||||
X86_BR_RET |\
|
||||
X86_BR_SYSCALL |\
|
||||
X86_BR_SYSRET |\
|
||||
X86_BR_INT |\
|
||||
X86_BR_IRET |\
|
||||
X86_BR_JCC |\
|
||||
X86_BR_JMP |\
|
||||
X86_BR_IRQ |\
|
||||
X86_BR_ABORT |\
|
||||
X86_BR_IND_CALL |\
|
||||
X86_BR_IND_JMP |\
|
||||
X86_BR_ZERO_CALL)
|
||||
|
||||
#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
|
||||
|
||||
#define X86_BR_ANY_CALL \
|
||||
(X86_BR_CALL |\
|
||||
X86_BR_IND_CALL |\
|
||||
X86_BR_ZERO_CALL |\
|
||||
X86_BR_SYSCALL |\
|
||||
X86_BR_IRQ |\
|
||||
X86_BR_INT)
|
||||
|
||||
int common_branch_type(int type);
|
||||
int branch_type(unsigned long from, unsigned long to, int abort);
|
||||
|
||||
ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
|
||||
ssize_t intel_event_sysfs_show(char *page, u64 config);
|
||||
|
||||
|
||||
217
arch/x86/events/utils.c
Normal file
217
arch/x86/events/utils.c
Normal file
@@ -0,0 +1,217 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <asm/insn.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include "perf_event.h"
|
||||
|
||||
/*
|
||||
* return the type of control flow change at address "from"
|
||||
* instruction is not necessarily a branch (in case of interrupt).
|
||||
*
|
||||
* The branch type returned also includes the priv level of the
|
||||
* target of the control flow change (X86_BR_USER, X86_BR_KERNEL).
|
||||
*
|
||||
* If a branch type is unknown OR the instruction cannot be
|
||||
* decoded (e.g., text page not present), then X86_BR_NONE is
|
||||
* returned.
|
||||
*/
|
||||
int branch_type(unsigned long from, unsigned long to, int abort)
|
||||
{
|
||||
struct insn insn;
|
||||
void *addr;
|
||||
int bytes_read, bytes_left;
|
||||
int ret = X86_BR_NONE;
|
||||
int ext, to_plm, from_plm;
|
||||
u8 buf[MAX_INSN_SIZE];
|
||||
int is64 = 0;
|
||||
|
||||
to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
|
||||
from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
|
||||
|
||||
/*
|
||||
* maybe zero if lbr did not fill up after a reset by the time
|
||||
* we get a PMU interrupt
|
||||
*/
|
||||
if (from == 0 || to == 0)
|
||||
return X86_BR_NONE;
|
||||
|
||||
if (abort)
|
||||
return X86_BR_ABORT | to_plm;
|
||||
|
||||
if (from_plm == X86_BR_USER) {
|
||||
/*
|
||||
* can happen if measuring at the user level only
|
||||
* and we interrupt in a kernel thread, e.g., idle.
|
||||
*/
|
||||
if (!current->mm)
|
||||
return X86_BR_NONE;
|
||||
|
||||
/* may fail if text not present */
|
||||
bytes_left = copy_from_user_nmi(buf, (void __user *)from,
|
||||
MAX_INSN_SIZE);
|
||||
bytes_read = MAX_INSN_SIZE - bytes_left;
|
||||
if (!bytes_read)
|
||||
return X86_BR_NONE;
|
||||
|
||||
addr = buf;
|
||||
} else {
|
||||
/*
|
||||
* The LBR logs any address in the IP, even if the IP just
|
||||
* faulted. This means userspace can control the from address.
|
||||
* Ensure we don't blindly read any address by validating it is
|
||||
* a known text address and not a vsyscall address.
|
||||
*/
|
||||
if (kernel_text_address(from) && !in_gate_area_no_mm(from)) {
|
||||
addr = (void *)from;
|
||||
/*
|
||||
* Assume we can get the maximum possible size
|
||||
* when grabbing kernel data. This is not
|
||||
* _strictly_ true since we could possibly be
|
||||
* executing up next to a memory hole, but
|
||||
* it is very unlikely to be a problem.
|
||||
*/
|
||||
bytes_read = MAX_INSN_SIZE;
|
||||
} else {
|
||||
return X86_BR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* decoder needs to know the ABI especially
|
||||
* on 64-bit systems running 32-bit apps
|
||||
*/
|
||||
#ifdef CONFIG_X86_64
|
||||
is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs());
|
||||
#endif
|
||||
insn_init(&insn, addr, bytes_read, is64);
|
||||
if (insn_get_opcode(&insn))
|
||||
return X86_BR_ABORT;
|
||||
|
||||
switch (insn.opcode.bytes[0]) {
|
||||
case 0xf:
|
||||
switch (insn.opcode.bytes[1]) {
|
||||
case 0x05: /* syscall */
|
||||
case 0x34: /* sysenter */
|
||||
ret = X86_BR_SYSCALL;
|
||||
break;
|
||||
case 0x07: /* sysret */
|
||||
case 0x35: /* sysexit */
|
||||
ret = X86_BR_SYSRET;
|
||||
break;
|
||||
case 0x80 ... 0x8f: /* conditional */
|
||||
ret = X86_BR_JCC;
|
||||
break;
|
||||
default:
|
||||
ret = X86_BR_NONE;
|
||||
}
|
||||
break;
|
||||
case 0x70 ... 0x7f: /* conditional */
|
||||
ret = X86_BR_JCC;
|
||||
break;
|
||||
case 0xc2: /* near ret */
|
||||
case 0xc3: /* near ret */
|
||||
case 0xca: /* far ret */
|
||||
case 0xcb: /* far ret */
|
||||
ret = X86_BR_RET;
|
||||
break;
|
||||
case 0xcf: /* iret */
|
||||
ret = X86_BR_IRET;
|
||||
break;
|
||||
case 0xcc ... 0xce: /* int */
|
||||
ret = X86_BR_INT;
|
||||
break;
|
||||
case 0xe8: /* call near rel */
|
||||
if (insn_get_immediate(&insn) || insn.immediate1.value == 0) {
|
||||
/* zero length call */
|
||||
ret = X86_BR_ZERO_CALL;
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
case 0x9a: /* call far absolute */
|
||||
ret = X86_BR_CALL;
|
||||
break;
|
||||
case 0xe0 ... 0xe3: /* loop jmp */
|
||||
ret = X86_BR_JCC;
|
||||
break;
|
||||
case 0xe9 ... 0xeb: /* jmp */
|
||||
ret = X86_BR_JMP;
|
||||
break;
|
||||
case 0xff: /* call near absolute, call far absolute ind */
|
||||
if (insn_get_modrm(&insn))
|
||||
return X86_BR_ABORT;
|
||||
|
||||
ext = (insn.modrm.bytes[0] >> 3) & 0x7;
|
||||
switch (ext) {
|
||||
case 2: /* near ind call */
|
||||
case 3: /* far ind call */
|
||||
ret = X86_BR_IND_CALL;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
ret = X86_BR_IND_JMP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = X86_BR_NONE;
|
||||
}
|
||||
/*
|
||||
* interrupts, traps, faults (and thus ring transition) may
|
||||
* occur on any instructions. Thus, to classify them correctly,
|
||||
* we need to first look at the from and to priv levels. If they
|
||||
* are different and to is in the kernel, then it indicates
|
||||
* a ring transition. If the from instruction is not a ring
|
||||
* transition instr (syscall, systenter, int), then it means
|
||||
* it was a irq, trap or fault.
|
||||
*
|
||||
* we have no way of detecting kernel to kernel faults.
|
||||
*/
|
||||
if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL
|
||||
&& ret != X86_BR_SYSCALL && ret != X86_BR_INT)
|
||||
ret = X86_BR_IRQ;
|
||||
|
||||
/*
|
||||
* branch priv level determined by target as
|
||||
* is done by HW when LBR_SELECT is implemented
|
||||
*/
|
||||
if (ret != X86_BR_NONE)
|
||||
ret |= to_plm;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define X86_BR_TYPE_MAP_MAX 16
|
||||
|
||||
static int branch_map[X86_BR_TYPE_MAP_MAX] = {
|
||||
PERF_BR_CALL, /* X86_BR_CALL */
|
||||
PERF_BR_RET, /* X86_BR_RET */
|
||||
PERF_BR_SYSCALL, /* X86_BR_SYSCALL */
|
||||
PERF_BR_SYSRET, /* X86_BR_SYSRET */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_INT */
|
||||
PERF_BR_ERET, /* X86_BR_IRET */
|
||||
PERF_BR_COND, /* X86_BR_JCC */
|
||||
PERF_BR_UNCOND, /* X86_BR_JMP */
|
||||
PERF_BR_IRQ, /* X86_BR_IRQ */
|
||||
PERF_BR_IND_CALL, /* X86_BR_IND_CALL */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_ABORT */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_IN_TX */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_NO_TX */
|
||||
PERF_BR_CALL, /* X86_BR_ZERO_CALL */
|
||||
PERF_BR_UNKNOWN, /* X86_BR_CALL_STACK */
|
||||
PERF_BR_IND, /* X86_BR_IND_JMP */
|
||||
};
|
||||
|
||||
int common_branch_type(int type)
|
||||
{
|
||||
int i;
|
||||
|
||||
type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */
|
||||
|
||||
if (type) {
|
||||
i = __ffs(type);
|
||||
if (i < X86_BR_TYPE_MAP_MAX)
|
||||
return branch_map[i];
|
||||
}
|
||||
|
||||
return PERF_BR_UNKNOWN;
|
||||
}
|
||||
@@ -213,6 +213,23 @@ fail:
|
||||
sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST);
|
||||
}
|
||||
|
||||
static enum es_result vc_insn_string_check(struct es_em_ctxt *ctxt,
|
||||
unsigned long address,
|
||||
bool write)
|
||||
{
|
||||
if (user_mode(ctxt->regs) && fault_in_kernel_space(address)) {
|
||||
ctxt->fi.vector = X86_TRAP_PF;
|
||||
ctxt->fi.error_code = X86_PF_USER;
|
||||
ctxt->fi.cr2 = address;
|
||||
if (write)
|
||||
ctxt->fi.error_code |= X86_PF_WRITE;
|
||||
|
||||
return ES_EXCEPTION;
|
||||
}
|
||||
|
||||
return ES_OK;
|
||||
}
|
||||
|
||||
static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt,
|
||||
void *src, char *buf,
|
||||
unsigned int data_size,
|
||||
@@ -220,7 +237,12 @@ static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt,
|
||||
bool backwards)
|
||||
{
|
||||
int i, b = backwards ? -1 : 1;
|
||||
enum es_result ret = ES_OK;
|
||||
unsigned long address = (unsigned long)src;
|
||||
enum es_result ret;
|
||||
|
||||
ret = vc_insn_string_check(ctxt, address, false);
|
||||
if (ret != ES_OK)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
void *s = src + (i * data_size * b);
|
||||
@@ -241,7 +263,12 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt,
|
||||
bool backwards)
|
||||
{
|
||||
int i, s = backwards ? -1 : 1;
|
||||
enum es_result ret = ES_OK;
|
||||
unsigned long address = (unsigned long)dst;
|
||||
enum es_result ret;
|
||||
|
||||
ret = vc_insn_string_check(ctxt, address, true);
|
||||
if (ret != ES_OK)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
void *d = dst + (i * data_size * s);
|
||||
@@ -277,6 +304,9 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt,
|
||||
static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
|
||||
{
|
||||
struct insn *insn = &ctxt->insn;
|
||||
size_t size;
|
||||
u64 port;
|
||||
|
||||
*exitinfo = 0;
|
||||
|
||||
switch (insn->opcode.bytes[0]) {
|
||||
@@ -285,7 +315,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
|
||||
case 0x6d:
|
||||
*exitinfo |= IOIO_TYPE_INS;
|
||||
*exitinfo |= IOIO_SEG_ES;
|
||||
*exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
|
||||
port = ctxt->regs->dx & 0xffff;
|
||||
break;
|
||||
|
||||
/* OUTS opcodes */
|
||||
@@ -293,41 +323,43 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
|
||||
case 0x6f:
|
||||
*exitinfo |= IOIO_TYPE_OUTS;
|
||||
*exitinfo |= IOIO_SEG_DS;
|
||||
*exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
|
||||
port = ctxt->regs->dx & 0xffff;
|
||||
break;
|
||||
|
||||
/* IN immediate opcodes */
|
||||
case 0xe4:
|
||||
case 0xe5:
|
||||
*exitinfo |= IOIO_TYPE_IN;
|
||||
*exitinfo |= (u8)insn->immediate.value << 16;
|
||||
port = (u8)insn->immediate.value & 0xffff;
|
||||
break;
|
||||
|
||||
/* OUT immediate opcodes */
|
||||
case 0xe6:
|
||||
case 0xe7:
|
||||
*exitinfo |= IOIO_TYPE_OUT;
|
||||
*exitinfo |= (u8)insn->immediate.value << 16;
|
||||
port = (u8)insn->immediate.value & 0xffff;
|
||||
break;
|
||||
|
||||
/* IN register opcodes */
|
||||
case 0xec:
|
||||
case 0xed:
|
||||
*exitinfo |= IOIO_TYPE_IN;
|
||||
*exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
|
||||
port = ctxt->regs->dx & 0xffff;
|
||||
break;
|
||||
|
||||
/* OUT register opcodes */
|
||||
case 0xee:
|
||||
case 0xef:
|
||||
*exitinfo |= IOIO_TYPE_OUT;
|
||||
*exitinfo |= (ctxt->regs->dx & 0xffff) << 16;
|
||||
port = ctxt->regs->dx & 0xffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ES_DECODE_FAILED;
|
||||
}
|
||||
|
||||
*exitinfo |= port << 16;
|
||||
|
||||
switch (insn->opcode.bytes[0]) {
|
||||
case 0x6c:
|
||||
case 0x6e:
|
||||
@@ -337,12 +369,15 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
|
||||
case 0xee:
|
||||
/* Single byte opcodes */
|
||||
*exitinfo |= IOIO_DATA_8;
|
||||
size = 1;
|
||||
break;
|
||||
default:
|
||||
/* Length determined by instruction parsing */
|
||||
*exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16
|
||||
: IOIO_DATA_32;
|
||||
size = (insn->opnd_bytes == 2) ? 2 : 4;
|
||||
}
|
||||
|
||||
switch (insn->addr_bytes) {
|
||||
case 2:
|
||||
*exitinfo |= IOIO_ADDR_16;
|
||||
@@ -358,7 +393,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
|
||||
if (insn_has_rep_prefix(insn))
|
||||
*exitinfo |= IOIO_REP;
|
||||
|
||||
return ES_OK;
|
||||
return vc_ioio_check(ctxt, (u16)port, size);
|
||||
}
|
||||
|
||||
static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
|
||||
@@ -482,6 +482,33 @@ static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt
|
||||
return ES_OK;
|
||||
}
|
||||
|
||||
static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size)
|
||||
{
|
||||
BUG_ON(size > 4);
|
||||
|
||||
if (user_mode(ctxt->regs)) {
|
||||
struct thread_struct *t = ¤t->thread;
|
||||
struct io_bitmap *iobm = t->io_bitmap;
|
||||
size_t idx;
|
||||
|
||||
if (!iobm)
|
||||
goto fault;
|
||||
|
||||
for (idx = port; idx < port + size; ++idx) {
|
||||
if (test_bit(idx, iobm->bitmap))
|
||||
goto fault;
|
||||
}
|
||||
}
|
||||
|
||||
return ES_OK;
|
||||
|
||||
fault:
|
||||
ctxt->fi.vector = X86_TRAP_GP;
|
||||
ctxt->fi.error_code = 0;
|
||||
|
||||
return ES_EXCEPTION;
|
||||
}
|
||||
|
||||
/* Include code shared with pre-decompression boot stage */
|
||||
#include "sev-shared.c"
|
||||
|
||||
@@ -1004,6 +1031,9 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb,
|
||||
enum es_result ret;
|
||||
long *reg_data;
|
||||
|
||||
if (user_mode(ctxt->regs))
|
||||
return ES_UNSUPPORTED;
|
||||
|
||||
switch (insn->opcode.bytes[0]) {
|
||||
/* MMIO Write */
|
||||
case 0x88:
|
||||
|
||||
@@ -2411,13 +2411,17 @@ int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type)
|
||||
{
|
||||
u32 reg = kvm_lapic_get_reg(apic, lvt_type);
|
||||
int vector, mode, trig_mode;
|
||||
int r;
|
||||
|
||||
if (kvm_apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) {
|
||||
vector = reg & APIC_VECTOR_MASK;
|
||||
mode = reg & APIC_MODE_MASK;
|
||||
trig_mode = reg & APIC_LVT_LEVEL_TRIGGER;
|
||||
return __apic_accept_irq(apic, mode, vector, 1, trig_mode,
|
||||
NULL);
|
||||
|
||||
r = __apic_accept_irq(apic, mode, vector, 1, trig_mode, NULL);
|
||||
if (r && lvt_type == APIC_LVTPC)
|
||||
kvm_lapic_set_reg(apic, APIC_LVTPC, reg | APIC_LVT_MASKED);
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
|
||||
int polarity)
|
||||
{
|
||||
struct irq_fwspec fwspec;
|
||||
unsigned int irq;
|
||||
|
||||
if (WARN_ON(!acpi_gsi_domain_id)) {
|
||||
pr_warn("GSI: No registered irqchip, giving up\n");
|
||||
@@ -63,7 +64,11 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger,
|
||||
fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity);
|
||||
fwspec.param_count = 2;
|
||||
|
||||
return irq_create_fwspec_mapping(&fwspec);
|
||||
irq = irq_create_fwspec_mapping(&fwspec);
|
||||
if (!irq)
|
||||
return -EINVAL;
|
||||
|
||||
return irq;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_register_gsi);
|
||||
|
||||
|
||||
@@ -2382,7 +2382,7 @@ static int ata_dev_config_lba(struct ata_device *dev)
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
const u16 *id = dev->id;
|
||||
const char *lba_desc;
|
||||
char ncq_desc[24];
|
||||
char ncq_desc[32];
|
||||
int ret;
|
||||
|
||||
dev->flags |= ATA_DFLAG_LBA;
|
||||
|
||||
@@ -2223,7 +2223,7 @@ static void ata_eh_link_report(struct ata_link *link)
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
struct ata_queued_cmd *qc;
|
||||
const char *frozen, *desc;
|
||||
char tries_buf[6] = "";
|
||||
char tries_buf[16] = "";
|
||||
int tag, nr_failed = 0;
|
||||
|
||||
if (ehc->i.flags & ATA_EHI_QUIET)
|
||||
|
||||
@@ -1551,7 +1551,7 @@ static int dev_get_regmap_match(struct device *dev, void *res, void *data)
|
||||
|
||||
/* If the user didn't specify a name match any */
|
||||
if (data)
|
||||
return !strcmp((*r)->name, data);
|
||||
return (*r)->name && !strcmp((*r)->name, data);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -3949,6 +3949,7 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
|
||||
if (id->driver_info & BTUSB_QCA_ROME) {
|
||||
data->setup_on_usb = btusb_setup_qca;
|
||||
hdev->shutdown = btusb_shutdown_qca;
|
||||
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
||||
hdev->cmd_timeout = btusb_qca_cmd_timeout;
|
||||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||
|
||||
@@ -67,7 +67,10 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
struct vhci_data *data = hci_get_drvdata(hdev);
|
||||
|
||||
memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
|
||||
|
||||
mutex_lock(&data->open_mutex);
|
||||
skb_queue_tail(&data->readq, skb);
|
||||
mutex_unlock(&data->open_mutex);
|
||||
|
||||
wake_up_interruptible(&data->read_wait);
|
||||
return 0;
|
||||
|
||||
@@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
|
||||
unsigned offset, bool enabled)
|
||||
{
|
||||
struct timbgpio *tgpio = gpiochip_get_data(gpio);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
spin_lock(&tgpio->lock);
|
||||
spin_lock_irqsave(&tgpio->lock, flags);
|
||||
reg = ioread32(tgpio->membase + offset);
|
||||
|
||||
if (enabled)
|
||||
@@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index,
|
||||
reg &= ~(1 << index);
|
||||
|
||||
iowrite32(reg, tgpio->membase + offset);
|
||||
spin_unlock(&tgpio->lock);
|
||||
spin_unlock_irqrestore(&tgpio->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -127,14 +127,14 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
|
||||
unsigned long mask = BIT(gpio);
|
||||
u32 val;
|
||||
|
||||
vf610_gpio_set(chip, gpio, value);
|
||||
|
||||
if (port->sdata && port->sdata->have_paddr) {
|
||||
val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR);
|
||||
val |= mask;
|
||||
vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR);
|
||||
}
|
||||
|
||||
vf610_gpio_set(chip, gpio, value);
|
||||
|
||||
return pinctrl_gpio_direction_output(chip->base + gpio);
|
||||
}
|
||||
|
||||
|
||||
@@ -287,7 +287,8 @@ static int
|
||||
update_connector_routing(struct drm_atomic_state *state,
|
||||
struct drm_connector *connector,
|
||||
struct drm_connector_state *old_connector_state,
|
||||
struct drm_connector_state *new_connector_state)
|
||||
struct drm_connector_state *new_connector_state,
|
||||
bool added_by_user)
|
||||
{
|
||||
const struct drm_connector_helper_funcs *funcs;
|
||||
struct drm_encoder *new_encoder;
|
||||
@@ -338,9 +339,13 @@ update_connector_routing(struct drm_atomic_state *state,
|
||||
* there's a chance the connector may have been destroyed during the
|
||||
* process, but it's better to ignore that then cause
|
||||
* drm_atomic_helper_resume() to fail.
|
||||
*
|
||||
* Last, we want to ignore connector registration when the connector
|
||||
* was not pulled in the atomic state by user-space (ie, was pulled
|
||||
* in by the driver, e.g. when updating a DP-MST stream).
|
||||
*/
|
||||
if (!state->duplicated && drm_connector_is_unregistered(connector) &&
|
||||
crtc_state->active) {
|
||||
added_by_user && crtc_state->active) {
|
||||
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] is not registered\n",
|
||||
connector->base.id, connector->name);
|
||||
return -EINVAL;
|
||||
@@ -612,9 +617,12 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_state *old_connector_state, *new_connector_state;
|
||||
int i, ret;
|
||||
unsigned int connectors_mask = 0;
|
||||
unsigned int connectors_mask = 0, user_connectors_mask = 0;
|
||||
bool allow = false;
|
||||
|
||||
for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i)
|
||||
user_connectors_mask |= BIT(i);
|
||||
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
bool has_connectors =
|
||||
!!new_crtc_state->connector_mask;
|
||||
@@ -678,7 +686,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
|
||||
*/
|
||||
ret = update_connector_routing(state, connector,
|
||||
old_connector_state,
|
||||
new_connector_state);
|
||||
new_connector_state,
|
||||
BIT(i) & user_connectors_mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (old_connector_state->crtc) {
|
||||
|
||||
@@ -44,6 +44,14 @@ static const struct drm_dmi_panel_orientation_data gpd_micropc = {
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data gpd_onemix2s = {
|
||||
.width = 1200,
|
||||
.height = 1920,
|
||||
.bios_dates = (const char * const []){ "05/21/2018", "10/26/2018",
|
||||
"03/04/2019", NULL },
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data gpd_pocket = {
|
||||
.width = 1200,
|
||||
.height = 1920,
|
||||
@@ -329,6 +337,14 @@ static const struct dmi_system_id orientation_data[] = {
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"),
|
||||
},
|
||||
.driver_data = (void *)&lcd800x1280_rightside_up,
|
||||
}, { /* One Mix 2S (generic strings, also match on bios date) */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
|
||||
},
|
||||
.driver_data = (void *)&gpd_onemix2s,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -231,6 +231,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err)
|
||||
case 0:
|
||||
case -EAGAIN:
|
||||
case -ENOSPC: /* transient failure to evict? */
|
||||
case -ENOBUFS: /* temporarily out of fences? */
|
||||
case -ERESTARTSYS:
|
||||
case -EINTR:
|
||||
case -EBUSY:
|
||||
|
||||
@@ -130,6 +130,10 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type,
|
||||
return -ENODEV;
|
||||
|
||||
boot_hid = usb_get_intfdata(boot_interface);
|
||||
if (list_empty(&boot_hid->inputs)) {
|
||||
hid_err(hid, "no inputs found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
boot_hid_input = list_first_entry(&boot_hid->inputs,
|
||||
struct hid_input, list);
|
||||
|
||||
|
||||
@@ -2142,6 +2142,10 @@ static const struct hid_device_id mt_devices[] = {
|
||||
USB_DEVICE_ID_MTP_STM)},
|
||||
|
||||
/* Synaptics devices */
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
|
||||
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_SYNAPTICS, 0xcd7e) },
|
||||
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
|
||||
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_SYNAPTICS, 0xce08) },
|
||||
|
||||
@@ -340,7 +340,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
|
||||
priv->adap.lock_ops = &i2c_parent_lock_ops;
|
||||
|
||||
/* Sanity check on class */
|
||||
if (i2c_mux_parent_classes(parent) & class)
|
||||
if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED)
|
||||
dev_err(&parent->dev,
|
||||
"Segment %d behind mux can't share classes with ancestors\n",
|
||||
chan_id);
|
||||
|
||||
@@ -1525,7 +1525,7 @@ static int bmc150_accel_buffer_postenable(struct iio_dev *indio_dev)
|
||||
struct bmc150_accel_data *data = iio_priv(indio_dev);
|
||||
int ret = 0;
|
||||
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED)
|
||||
if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
@@ -1557,7 +1557,7 @@ static int bmc150_accel_buffer_predisable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct bmc150_accel_data *data = iio_priv(indio_dev);
|
||||
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED)
|
||||
if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
|
||||
@@ -177,6 +177,7 @@ struct ad7192_state {
|
||||
const struct ad7192_chip_info *chip_info;
|
||||
struct regulator *avdd;
|
||||
struct regulator *dvdd;
|
||||
struct regulator *vref;
|
||||
struct clk *mclk;
|
||||
u16 int_vref_mv;
|
||||
u32 fclk;
|
||||
@@ -962,10 +963,30 @@ static int ad7192_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regulator_get_voltage(st->avdd);
|
||||
if (ret < 0) {
|
||||
dev_err(&spi->dev, "Device tree error, reference voltage undefined\n");
|
||||
return ret;
|
||||
st->vref = devm_regulator_get_optional(&spi->dev, "vref");
|
||||
if (IS_ERR(st->vref)) {
|
||||
if (PTR_ERR(st->vref) != -ENODEV)
|
||||
return PTR_ERR(st->vref);
|
||||
|
||||
ret = regulator_get_voltage(st->avdd);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&spi->dev, ret,
|
||||
"Device tree error, AVdd voltage undefined\n");
|
||||
} else {
|
||||
ret = regulator_enable(st->vref);
|
||||
if (ret) {
|
||||
dev_err(&spi->dev, "Failed to enable specified Vref supply\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->vref);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regulator_get_voltage(st->vref);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&spi->dev, ret,
|
||||
"Device tree error, Vref voltage undefined\n");
|
||||
}
|
||||
st->int_vref_mv = ret / 1000;
|
||||
|
||||
|
||||
@@ -894,7 +894,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
|
||||
return at91_adc_configure_touch(st, true);
|
||||
|
||||
/* if we are not in triggered mode, we cannot enable the buffer. */
|
||||
if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES))
|
||||
if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES))
|
||||
return -EINVAL;
|
||||
|
||||
/* we continue with the triggered buffer */
|
||||
@@ -947,7 +947,7 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
|
||||
return at91_adc_configure_touch(st, false);
|
||||
|
||||
/* if we are not in triggered mode, nothing to do here */
|
||||
if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES))
|
||||
if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
||||
@@ -196,8 +196,11 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
|
||||
/*
|
||||
* Ignore samples if the buffer is not set: it is needed if the ODR is
|
||||
* set but the buffer is not enabled yet.
|
||||
*
|
||||
* Note: iio_device_claim_buffer_mode() returns -EBUSY if the buffer
|
||||
* is not enabled.
|
||||
*/
|
||||
if (!iio_buffer_enabled(indio_dev))
|
||||
if (iio_device_claim_buffer_mode(indio_dev) < 0)
|
||||
return 0;
|
||||
|
||||
out = (s16 *)st->samples;
|
||||
@@ -216,6 +219,7 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, st->samples,
|
||||
timestamp + delta);
|
||||
|
||||
iio_device_release_buffer_mode(indio_dev);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data);
|
||||
|
||||
@@ -184,6 +184,18 @@ int iio_device_id(struct iio_dev *indio_dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_device_id);
|
||||
|
||||
/**
|
||||
* iio_buffer_enabled() - helper function to test if the buffer is enabled
|
||||
* @indio_dev: IIO device structure for device
|
||||
*/
|
||||
bool iio_buffer_enabled(struct iio_dev *indio_dev)
|
||||
{
|
||||
return indio_dev->currentmode
|
||||
& (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE |
|
||||
INDIO_BUFFER_SOFTWARE);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_buffer_enabled);
|
||||
|
||||
/**
|
||||
* iio_sysfs_match_string_with_gaps - matches given string in an array with gaps
|
||||
* @array: array of strings
|
||||
@@ -2072,6 +2084,55 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_device_release_direct_mode);
|
||||
|
||||
/**
|
||||
* iio_device_claim_buffer_mode - Keep device in buffer mode
|
||||
* @indio_dev: the iio_dev associated with the device
|
||||
*
|
||||
* If the device is in buffer mode it is guaranteed to stay
|
||||
* that way until iio_device_release_buffer_mode() is called.
|
||||
*
|
||||
* Use with iio_device_release_buffer_mode().
|
||||
*
|
||||
* Returns: 0 on success, -EBUSY on failure.
|
||||
*/
|
||||
int iio_device_claim_buffer_mode(struct iio_dev *indio_dev)
|
||||
{
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
|
||||
if (iio_buffer_enabled(indio_dev))
|
||||
return 0;
|
||||
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return -EBUSY;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode);
|
||||
|
||||
/**
|
||||
* iio_device_release_buffer_mode - releases claim on buffer mode
|
||||
* @indio_dev: the iio_dev associated with the device
|
||||
*
|
||||
* Release the claim. Device is no longer guaranteed to stay
|
||||
* in buffer mode.
|
||||
*
|
||||
* Use with iio_device_claim_buffer_mode().
|
||||
*/
|
||||
void iio_device_release_buffer_mode(struct iio_dev *indio_dev)
|
||||
{
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode);
|
||||
|
||||
/**
|
||||
* iio_device_get_current_mode() - helper function providing read-only access to
|
||||
* the @currentmode variable
|
||||
* @indio_dev: IIO device structure for device
|
||||
*/
|
||||
int iio_device_get_current_mode(struct iio_dev *indio_dev)
|
||||
{
|
||||
return indio_dev->currentmode;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_device_get_current_mode);
|
||||
|
||||
subsys_initcall(iio_init);
|
||||
module_exit(iio_exit);
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ static int mmc_decode_cid(struct mmc_card *card)
|
||||
case 3: /* MMC v3.1 - v3.3 */
|
||||
case 4: /* MMC v4 */
|
||||
card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
|
||||
card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
|
||||
card->cid.oemid = UNSTUFF_BITS(resp, 104, 8);
|
||||
card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
|
||||
card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
|
||||
card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
|
||||
|
||||
@@ -1075,8 +1075,14 @@ static int mmc_sdio_resume(struct mmc_host *host)
|
||||
}
|
||||
err = mmc_sdio_reinit_card(host);
|
||||
} else if (mmc_card_wake_sdio_irq(host)) {
|
||||
/* We may have switched to 1-bit mode during suspend */
|
||||
/*
|
||||
* We may have switched to 1-bit mode during suspend,
|
||||
* need to hold retuning, because tuning only supprt
|
||||
* 4-bit mode or 8 bit mode.
|
||||
*/
|
||||
mmc_retune_hold_now(host);
|
||||
err = sdio_enable_4bit_bus(host->card);
|
||||
mmc_retune_release(host);
|
||||
}
|
||||
|
||||
if (err)
|
||||
|
||||
@@ -636,11 +636,11 @@ static void msdc_reset_hw(struct msdc_host *host)
|
||||
u32 val;
|
||||
|
||||
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST);
|
||||
readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0);
|
||||
readl_poll_timeout_atomic(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0);
|
||||
|
||||
sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR);
|
||||
readl_poll_timeout(host->base + MSDC_FIFOCS, val,
|
||||
!(val & MSDC_FIFOCS_CLR), 0, 0);
|
||||
readl_poll_timeout_atomic(host->base + MSDC_FIFOCS, val,
|
||||
!(val & MSDC_FIFOCS_CLR), 0, 0);
|
||||
|
||||
val = readl(host->base + MSDC_INT);
|
||||
writel(val, host->base + MSDC_INT);
|
||||
|
||||
@@ -556,6 +556,17 @@ static int physmap_flash_probe(struct platform_device *dev)
|
||||
if (info->probe_type) {
|
||||
info->mtds[i] = do_map_probe(info->probe_type,
|
||||
&info->maps[i]);
|
||||
|
||||
/* Fall back to mapping region as ROM */
|
||||
if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) &&
|
||||
strcmp(info->probe_type, "map_rom")) {
|
||||
dev_warn(&dev->dev,
|
||||
"map_probe() failed for type %s\n",
|
||||
info->probe_type);
|
||||
|
||||
info->mtds[i] = do_map_probe("map_rom",
|
||||
&info->maps[i]);
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
|
||||
|
||||
@@ -515,6 +515,7 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
|
||||
struct mtd_info *mtd = nand_to_mtd(chip);
|
||||
unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0);
|
||||
dma_addr_t dma_addr;
|
||||
u8 status;
|
||||
int ret;
|
||||
struct anfc_op nfc_op = {
|
||||
.pkt_reg =
|
||||
@@ -561,10 +562,21 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
|
||||
}
|
||||
|
||||
/* Spare data is not protected */
|
||||
if (oob_required)
|
||||
if (oob_required) {
|
||||
ret = nand_write_oob_std(chip, page);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* Check write status on the chip side */
|
||||
ret = nand_status_op(chip, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status & NAND_STATUS_FAIL)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
|
||||
|
||||
@@ -1148,6 +1148,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
|
||||
.ndcb[2] = NDCB2_ADDR5_PAGE(page),
|
||||
};
|
||||
unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0);
|
||||
u8 status;
|
||||
int ret;
|
||||
|
||||
/* NFCv2 needs more information about the operation being executed */
|
||||
@@ -1181,7 +1182,18 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
|
||||
|
||||
ret = marvell_nfc_wait_op(chip,
|
||||
PSEC_TO_MSEC(sdr->tPROG_max));
|
||||
return ret;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check write status on the chip side */
|
||||
ret = nand_status_op(chip, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status & NAND_STATUS_FAIL)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip,
|
||||
@@ -1610,6 +1622,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
|
||||
int data_len = lt->data_bytes;
|
||||
int spare_len = lt->spare_bytes;
|
||||
int chunk, ret;
|
||||
u8 status;
|
||||
|
||||
marvell_nfc_select_target(chip, chip->cur_cs);
|
||||
|
||||
@@ -1646,6 +1659,14 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check write status on the chip side */
|
||||
ret = nand_status_op(chip, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status & NAND_STATUS_FAIL)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -513,6 +513,7 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
|
||||
u32 addr1 = 0, addr2 = 0, row;
|
||||
u32 cmd_addr;
|
||||
int i, ret;
|
||||
u8 status;
|
||||
|
||||
ret = pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_APB);
|
||||
if (ret)
|
||||
@@ -565,6 +566,14 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
|
||||
if (ret)
|
||||
goto disable_ecc_engine;
|
||||
|
||||
/* Check write status on the chip side */
|
||||
ret = nand_status_op(chip, &status);
|
||||
if (ret)
|
||||
goto disable_ecc_engine;
|
||||
|
||||
if (status & NAND_STATUS_FAIL)
|
||||
ret = -EIO;
|
||||
|
||||
disable_ecc_engine:
|
||||
pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS);
|
||||
|
||||
|
||||
@@ -3093,7 +3093,7 @@ err_nandc_alloc:
|
||||
err_aon_clk:
|
||||
clk_disable_unprepare(nandc->core_clk);
|
||||
err_core_clk:
|
||||
dma_unmap_resource(dev, res->start, resource_size(res),
|
||||
dma_unmap_resource(dev, nandc->base_dma, resource_size(res),
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#define SPINAND_MFR_MICRON 0x2c
|
||||
|
||||
#define MICRON_STATUS_ECC_MASK GENMASK(7, 4)
|
||||
#define MICRON_STATUS_ECC_MASK GENMASK(6, 4)
|
||||
#define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4)
|
||||
#define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4)
|
||||
#define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
|
||||
|
||||
@@ -3722,7 +3722,7 @@ static inline const void *bond_pull_data(struct sk_buff *skb,
|
||||
if (likely(n <= hlen))
|
||||
return data;
|
||||
else if (skb && likely(pskb_may_pull(skb, n)))
|
||||
return skb->head;
|
||||
return skb->data;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -577,17 +577,16 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
|
||||
dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio");
|
||||
priv->master_mii_bus = of_mdio_find_bus(dn);
|
||||
if (!priv->master_mii_bus) {
|
||||
of_node_put(dn);
|
||||
return -EPROBE_DEFER;
|
||||
err = -EPROBE_DEFER;
|
||||
goto err_of_node_put;
|
||||
}
|
||||
|
||||
get_device(&priv->master_mii_bus->dev);
|
||||
priv->master_mii_dn = dn;
|
||||
|
||||
priv->slave_mii_bus = mdiobus_alloc();
|
||||
if (!priv->slave_mii_bus) {
|
||||
of_node_put(dn);
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto err_put_master_mii_bus_dev;
|
||||
}
|
||||
|
||||
priv->slave_mii_bus->priv = priv;
|
||||
@@ -644,11 +643,17 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
|
||||
}
|
||||
|
||||
err = mdiobus_register(priv->slave_mii_bus);
|
||||
if (err && dn) {
|
||||
mdiobus_free(priv->slave_mii_bus);
|
||||
of_node_put(dn);
|
||||
}
|
||||
if (err && dn)
|
||||
goto err_free_slave_mii_bus;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_slave_mii_bus:
|
||||
mdiobus_free(priv->slave_mii_bus);
|
||||
err_put_master_mii_bus_dev:
|
||||
put_device(&priv->master_mii_bus->dev);
|
||||
err_of_node_put:
|
||||
of_node_put(dn);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -656,6 +661,7 @@ static void bcm_sf2_mdio_unregister(struct bcm_sf2_priv *priv)
|
||||
{
|
||||
mdiobus_unregister(priv->slave_mii_bus);
|
||||
mdiobus_free(priv->slave_mii_bus);
|
||||
put_device(&priv->master_mii_bus->dev);
|
||||
of_node_put(priv->master_mii_dn);
|
||||
}
|
||||
|
||||
|
||||
@@ -1080,7 +1080,7 @@ void i40e_clear_hw(struct i40e_hw *hw)
|
||||
I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
|
||||
j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >>
|
||||
I40E_PFLAN_QALLOC_LASTQ_SHIFT;
|
||||
if (val & I40E_PFLAN_QALLOC_VALID_MASK)
|
||||
if (val & I40E_PFLAN_QALLOC_VALID_MASK && j >= base_queue)
|
||||
num_queues = (j - base_queue) + 1;
|
||||
else
|
||||
num_queues = 0;
|
||||
@@ -1090,7 +1090,7 @@ void i40e_clear_hw(struct i40e_hw *hw)
|
||||
I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT;
|
||||
j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >>
|
||||
I40E_PF_VT_PFALLOC_LASTVF_SHIFT;
|
||||
if (val & I40E_PF_VT_PFALLOC_VALID_MASK)
|
||||
if (val & I40E_PF_VT_PFALLOC_VALID_MASK && j >= i)
|
||||
num_vfs = (j - i) + 1;
|
||||
else
|
||||
num_vfs = 0;
|
||||
|
||||
@@ -954,8 +954,7 @@ static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi)
|
||||
|
||||
ctxt->info.q_opt_rss = ((lut_type << ICE_AQ_VSI_Q_OPT_RSS_LUT_S) &
|
||||
ICE_AQ_VSI_Q_OPT_RSS_LUT_M) |
|
||||
((hash_type << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) &
|
||||
ICE_AQ_VSI_Q_OPT_RSS_HASH_M);
|
||||
(hash_type & ICE_AQ_VSI_Q_OPT_RSS_HASH_M);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <generated/utsrelease.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include "ice.h"
|
||||
#include "ice_base.h"
|
||||
#include "ice_lib.h"
|
||||
@@ -4255,6 +4256,20 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* when under a kdump kernel initiate a reset before enabling the
|
||||
* device in order to clear out any pending DMA transactions. These
|
||||
* transactions can cause some systems to machine check when doing
|
||||
* the pcim_enable_device() below.
|
||||
*/
|
||||
if (is_kdump_kernel()) {
|
||||
pci_save_state(pdev);
|
||||
pci_clear_master(pdev);
|
||||
err = pcie_flr(pdev);
|
||||
if (err)
|
||||
return err;
|
||||
pci_restore_state(pdev);
|
||||
}
|
||||
|
||||
/* this driver uses devres, see
|
||||
* Documentation/driver-api/driver-model/devres.rst
|
||||
*/
|
||||
|
||||
@@ -2195,7 +2195,7 @@ struct rx_ring_info {
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t data_addr;
|
||||
DEFINE_DMA_UNMAP_LEN(data_size);
|
||||
dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
|
||||
dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT ?: 1];
|
||||
};
|
||||
|
||||
enum flow_control {
|
||||
|
||||
@@ -821,7 +821,7 @@ static void mlx5_fw_tracer_ownership_change(struct work_struct *work)
|
||||
|
||||
mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner);
|
||||
if (tracer->owner) {
|
||||
tracer->owner = false;
|
||||
mlx5_fw_tracer_ownership_acquire(tracer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,6 +210,7 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb)
|
||||
unsigned int msg_len = nfp_flower_cmsg_get_data_len(skb);
|
||||
struct nfp_flower_cmsg_merge_hint *msg;
|
||||
struct nfp_fl_payload *sub_flows[2];
|
||||
struct nfp_flower_priv *priv;
|
||||
int err, i, flow_cnt;
|
||||
|
||||
msg = nfp_flower_cmsg_get_data(skb);
|
||||
@@ -228,14 +229,15 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb)
|
||||
return;
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
priv = app->priv;
|
||||
mutex_lock(&priv->nfp_fl_lock);
|
||||
for (i = 0; i < flow_cnt; i++) {
|
||||
u32 ctx = be32_to_cpu(msg->flow[i].host_ctx);
|
||||
|
||||
sub_flows[i] = nfp_flower_get_fl_payload_from_ctx(app, ctx);
|
||||
if (!sub_flows[i]) {
|
||||
nfp_flower_cmsg_warn(app, "Invalid flow in merge hint\n");
|
||||
goto err_rtnl_unlock;
|
||||
goto err_mutex_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,8 +246,8 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb)
|
||||
if (err == -ENOMEM)
|
||||
nfp_flower_cmsg_warn(app, "Flow merge memory fail.\n");
|
||||
|
||||
err_rtnl_unlock:
|
||||
rtnl_unlock();
|
||||
err_mutex_unlock:
|
||||
mutex_unlock(&priv->nfp_fl_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1665,8 +1665,6 @@ nfp_fl_ct_offload_nft_flow(struct nfp_fl_ct_zone_entry *zt, struct flow_cls_offl
|
||||
struct nfp_fl_ct_flow_entry *ct_entry;
|
||||
struct netlink_ext_ack *extack = NULL;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
extack = flow->common.extack;
|
||||
switch (flow->command) {
|
||||
case FLOW_CLS_REPLACE:
|
||||
@@ -1709,9 +1707,13 @@ int nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data, void *cb
|
||||
|
||||
switch (type) {
|
||||
case TC_SETUP_CLSFLOWER:
|
||||
rtnl_lock();
|
||||
while (!mutex_trylock(&zt->priv->nfp_fl_lock)) {
|
||||
if (!zt->nft) /* avoid deadlock */
|
||||
return err;
|
||||
msleep(20);
|
||||
}
|
||||
err = nfp_fl_ct_offload_nft_flow(zt, flow);
|
||||
rtnl_unlock();
|
||||
mutex_unlock(&zt->priv->nfp_fl_lock);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
@@ -1739,6 +1741,7 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent)
|
||||
struct nfp_fl_ct_flow_entry *ct_entry;
|
||||
struct nfp_fl_ct_zone_entry *zt;
|
||||
struct rhashtable *m_table;
|
||||
struct nf_flowtable *nft;
|
||||
|
||||
if (!ct_map_ent)
|
||||
return -ENOENT;
|
||||
@@ -1755,8 +1758,12 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent)
|
||||
nfp_fl_ct_clean_flow_entry(ct_entry);
|
||||
kfree(ct_map_ent);
|
||||
|
||||
if (!zt->pre_ct_count) {
|
||||
zt->nft = NULL;
|
||||
if (!zt->pre_ct_count && zt->nft) {
|
||||
nft = zt->nft;
|
||||
zt->nft = NULL; /* avoid deadlock */
|
||||
nf_flow_table_offload_del_cb(nft,
|
||||
nfp_fl_ct_handle_nft_flow,
|
||||
zt);
|
||||
nfp_fl_ct_clean_nft_entries(zt);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -196,6 +196,7 @@ struct nfp_fl_internal_ports {
|
||||
* @ct_zone_table: Hash table used to store the different zones
|
||||
* @ct_zone_wc: Special zone entry for wildcarded zone matches
|
||||
* @ct_map_table: Hash table used to referennce ct flows
|
||||
* @nfp_fl_lock: Lock to protect the flow offload operation
|
||||
*/
|
||||
struct nfp_flower_priv {
|
||||
struct nfp_app *app;
|
||||
@@ -233,6 +234,7 @@ struct nfp_flower_priv {
|
||||
struct rhashtable ct_zone_table;
|
||||
struct nfp_fl_ct_zone_entry *ct_zone_wc;
|
||||
struct rhashtable ct_map_table;
|
||||
struct mutex nfp_fl_lock; /* Protect the flow operation */
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -530,6 +530,8 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count,
|
||||
if (err)
|
||||
goto err_free_stats_ctx_table;
|
||||
|
||||
mutex_init(&priv->nfp_fl_lock);
|
||||
|
||||
err = rhashtable_init(&priv->ct_zone_table, &nfp_zone_table_params);
|
||||
if (err)
|
||||
goto err_free_merge_table;
|
||||
|
||||
@@ -1009,8 +1009,6 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app,
|
||||
u64 parent_ctx = 0;
|
||||
int err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (sub_flow1 == sub_flow2 ||
|
||||
nfp_flower_is_merge_flow(sub_flow1) ||
|
||||
nfp_flower_is_merge_flow(sub_flow2))
|
||||
@@ -1662,19 +1660,30 @@ static int
|
||||
nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev,
|
||||
struct flow_cls_offload *flower)
|
||||
{
|
||||
struct nfp_flower_priv *priv = app->priv;
|
||||
int ret;
|
||||
|
||||
if (!eth_proto_is_802_3(flower->common.protocol))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&priv->nfp_fl_lock);
|
||||
switch (flower->command) {
|
||||
case FLOW_CLS_REPLACE:
|
||||
return nfp_flower_add_offload(app, netdev, flower);
|
||||
ret = nfp_flower_add_offload(app, netdev, flower);
|
||||
break;
|
||||
case FLOW_CLS_DESTROY:
|
||||
return nfp_flower_del_offload(app, netdev, flower);
|
||||
ret = nfp_flower_del_offload(app, netdev, flower);
|
||||
break;
|
||||
case FLOW_CLS_STATS:
|
||||
return nfp_flower_get_stats(app, netdev, flower);
|
||||
ret = nfp_flower_get_stats(app, netdev, flower);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&priv->nfp_fl_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type,
|
||||
@@ -1713,6 +1722,7 @@ static int nfp_flower_setup_tc_block(struct net_device *netdev,
|
||||
repr_priv = repr->app_priv;
|
||||
repr_priv->block_shared = f->block_shared;
|
||||
f->driver_block_list = &nfp_block_cb_list;
|
||||
f->unlocked_driver_cb = true;
|
||||
|
||||
switch (f->command) {
|
||||
case FLOW_BLOCK_BIND:
|
||||
@@ -1811,6 +1821,8 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct Qdisc *sch, str
|
||||
nfp_flower_internal_port_can_offload(app, netdev)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
f->unlocked_driver_cb = true;
|
||||
|
||||
switch (f->command) {
|
||||
case FLOW_BLOCK_BIND:
|
||||
cb_priv = nfp_flower_indr_block_cb_priv_lookup(app, netdev);
|
||||
|
||||
@@ -421,23 +421,29 @@ int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,
|
||||
{
|
||||
struct netlink_ext_ack *extack = flow->common.extack;
|
||||
struct nfp_flower_priv *fl_priv = app->priv;
|
||||
int ret;
|
||||
|
||||
if (!(fl_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "unsupported offload: loaded firmware does not support qos rate limit offload");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
mutex_lock(&fl_priv->nfp_fl_lock);
|
||||
switch (flow->command) {
|
||||
case TC_CLSMATCHALL_REPLACE:
|
||||
return nfp_flower_install_rate_limiter(app, netdev, flow,
|
||||
extack);
|
||||
ret = nfp_flower_install_rate_limiter(app, netdev, flow, extack);
|
||||
break;
|
||||
case TC_CLSMATCHALL_DESTROY:
|
||||
return nfp_flower_remove_rate_limiter(app, netdev, flow,
|
||||
extack);
|
||||
ret = nfp_flower_remove_rate_limiter(app, netdev, flow, extack);
|
||||
break;
|
||||
case TC_CLSMATCHALL_STATS:
|
||||
return nfp_flower_stats_rate_limiter(app, netdev, flow,
|
||||
extack);
|
||||
ret = nfp_flower_stats_rate_limiter(app, netdev, flow, extack);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&fl_priv->nfp_fl_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,10 @@ static void qed_ll2b_complete_tx_packet(void *cxt,
|
||||
static int qed_ll2_alloc_buffer(struct qed_dev *cdev,
|
||||
u8 **data, dma_addr_t *phys_addr)
|
||||
{
|
||||
*data = kmalloc(cdev->ll2->rx_size, GFP_ATOMIC);
|
||||
size_t size = cdev->ll2->rx_size + NET_SKB_PAD +
|
||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||||
|
||||
*data = kmalloc(size, GFP_ATOMIC);
|
||||
if (!(*data)) {
|
||||
DP_INFO(cdev, "Failed to allocate LL2 buffer data\n");
|
||||
return -ENOMEM;
|
||||
@@ -2548,7 +2551,7 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
|
||||
INIT_LIST_HEAD(&cdev->ll2->list);
|
||||
spin_lock_init(&cdev->ll2->lock);
|
||||
|
||||
cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN +
|
||||
cdev->ll2->rx_size = PRM_DMA_PAD_BYTES_NUM + ETH_HLEN +
|
||||
L1_CACHE_BYTES + params->mtu;
|
||||
|
||||
/* Allocate memory for LL2.
|
||||
|
||||
@@ -3010,10 +3010,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
|
||||
struct net *net = sock_net(&tfile->sk);
|
||||
struct tun_struct *tun;
|
||||
void __user* argp = (void __user*)arg;
|
||||
unsigned int ifindex, carrier;
|
||||
unsigned int carrier;
|
||||
struct ifreq ifr;
|
||||
kuid_t owner;
|
||||
kgid_t group;
|
||||
int ifindex;
|
||||
int sndbuf;
|
||||
int vnet_hdr_sz;
|
||||
int le;
|
||||
@@ -3069,7 +3070,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
|
||||
ret = -EFAULT;
|
||||
if (copy_from_user(&ifindex, argp, sizeof(ifindex)))
|
||||
goto unlock;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (ifindex < 0)
|
||||
goto unlock;
|
||||
ret = 0;
|
||||
tfile->ifindex = ifindex;
|
||||
goto unlock;
|
||||
|
||||
@@ -860,7 +860,7 @@ static int smsc95xx_reset(struct usbnet *dev)
|
||||
|
||||
if (timeout >= 100) {
|
||||
netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n");
|
||||
return ret;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
ret = smsc95xx_write_reg(dev, PM_CTRL, PM_CTL_PHY_RST_);
|
||||
|
||||
@@ -1445,6 +1445,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
||||
iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);
|
||||
|
||||
memset(&info->status, 0, sizeof(info->status));
|
||||
info->flags &= ~(IEEE80211_TX_STAT_ACK | IEEE80211_TX_STAT_TX_FILTERED);
|
||||
|
||||
/* inform mac80211 about what happened with the frame */
|
||||
switch (status & TX_STATUS_MSK) {
|
||||
@@ -1790,6 +1791,8 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
|
||||
*/
|
||||
if (!is_flush)
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
else
|
||||
info->flags &= ~IEEE80211_TX_STAT_ACK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -933,6 +933,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv,
|
||||
while (tlv_buf_left >= sizeof(*tlv_rxba)) {
|
||||
tlv_type = le16_to_cpu(tlv_rxba->header.type);
|
||||
tlv_len = le16_to_cpu(tlv_rxba->header.len);
|
||||
if (size_add(sizeof(tlv_rxba->header), tlv_len) > tlv_buf_left) {
|
||||
mwifiex_dbg(priv->adapter, WARN,
|
||||
"TLV size (%zu) overflows event_buf buf_left=%d\n",
|
||||
size_add(sizeof(tlv_rxba->header), tlv_len),
|
||||
tlv_buf_left);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tlv_type != TLV_TYPE_RXBA_SYNC) {
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"Wrong TLV id=0x%x\n", tlv_type);
|
||||
@@ -941,6 +949,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv,
|
||||
|
||||
tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num);
|
||||
tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len);
|
||||
if (size_add(sizeof(*tlv_rxba), tlv_bitmap_len) > tlv_buf_left) {
|
||||
mwifiex_dbg(priv->adapter, WARN,
|
||||
"TLV size (%zu) overflows event_buf buf_left=%d\n",
|
||||
size_add(sizeof(*tlv_rxba), tlv_bitmap_len),
|
||||
tlv_buf_left);
|
||||
return;
|
||||
}
|
||||
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"%pM tid=%d seq_num=%d bitmap_len=%d\n",
|
||||
tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num,
|
||||
|
||||
@@ -3307,7 +3307,8 @@ static const struct pci_device_id nvme_id_table[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x0a54), /* Intel P4500/P4600 */
|
||||
.driver_data = NVME_QUIRK_STRIPE_SIZE |
|
||||
NVME_QUIRK_DEALLOCATE_ZEROES |
|
||||
NVME_QUIRK_IGNORE_DEV_SUBNQN, },
|
||||
NVME_QUIRK_IGNORE_DEV_SUBNQN |
|
||||
NVME_QUIRK_BOGUS_NID, },
|
||||
{ PCI_VDEVICE(INTEL, 0x0a55), /* Dell Express Flash P4600 */
|
||||
.driver_data = NVME_QUIRK_STRIPE_SIZE |
|
||||
NVME_QUIRK_DEALLOCATE_ZEROES, },
|
||||
|
||||
@@ -645,6 +645,9 @@ static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue)
|
||||
|
||||
static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue)
|
||||
{
|
||||
if (!test_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags))
|
||||
return;
|
||||
|
||||
mutex_lock(&queue->queue_lock);
|
||||
if (test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags))
|
||||
__nvme_rdma_stop_queue(queue);
|
||||
|
||||
@@ -348,6 +348,7 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue)
|
||||
|
||||
static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status)
|
||||
{
|
||||
queue->rcv_state = NVMET_TCP_RECV_ERR;
|
||||
if (status == -EPIPE || status == -ECONNRESET)
|
||||
kernel_sock_shutdown(queue->sock, SHUT_RDWR);
|
||||
else
|
||||
@@ -894,15 +895,11 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
|
||||
iov.iov_len = sizeof(*icresp);
|
||||
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
|
||||
if (ret < 0)
|
||||
goto free_crypto;
|
||||
return ret; /* queue removal will cleanup */
|
||||
|
||||
queue->state = NVMET_TCP_Q_LIVE;
|
||||
nvmet_prepare_receive_pdu(queue);
|
||||
return 0;
|
||||
free_crypto:
|
||||
if (queue->hdr_digest || queue->data_digest)
|
||||
nvmet_tcp_free_crypto(queue);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue,
|
||||
|
||||
@@ -122,16 +122,10 @@ static int phy_mdm6600_power_on(struct phy *x)
|
||||
{
|
||||
struct phy_mdm6600 *ddata = phy_get_drvdata(x);
|
||||
struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE];
|
||||
int error;
|
||||
|
||||
if (!ddata->enabled)
|
||||
return -ENODEV;
|
||||
|
||||
error = pinctrl_pm_select_default_state(ddata->dev);
|
||||
if (error)
|
||||
dev_warn(ddata->dev, "%s: error with default_state: %i\n",
|
||||
__func__, error);
|
||||
|
||||
gpiod_set_value_cansleep(enable_gpio, 1);
|
||||
|
||||
/* Allow aggressive PM for USB, it's only needed for n_gsm port */
|
||||
@@ -160,11 +154,6 @@ static int phy_mdm6600_power_off(struct phy *x)
|
||||
|
||||
gpiod_set_value_cansleep(enable_gpio, 0);
|
||||
|
||||
error = pinctrl_pm_select_sleep_state(ddata->dev);
|
||||
if (error)
|
||||
dev_warn(ddata->dev, "%s: error with sleep_state: %i\n",
|
||||
__func__, error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -456,6 +445,7 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata)
|
||||
{
|
||||
struct gpio_desc *reset_gpio =
|
||||
ddata->ctrl_gpios[PHY_MDM6600_RESET];
|
||||
int error;
|
||||
|
||||
ddata->enabled = false;
|
||||
phy_mdm6600_cmd(ddata, PHY_MDM6600_CMD_BP_SHUTDOWN_REQ);
|
||||
@@ -471,6 +461,17 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata)
|
||||
} else {
|
||||
dev_err(ddata->dev, "Timed out powering down\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep reset gpio high with padconf internal pull-up resistor to
|
||||
* prevent modem from waking up during deeper SoC idle states. The
|
||||
* gpio bank lines can have glitches if not in the always-on wkup
|
||||
* domain.
|
||||
*/
|
||||
error = pinctrl_pm_select_sleep_state(ddata->dev);
|
||||
if (error)
|
||||
dev_warn(ddata->dev, "%s: error with sleep_state: %i\n",
|
||||
__func__, error);
|
||||
}
|
||||
|
||||
static void phy_mdm6600_deferred_power_on(struct work_struct *work)
|
||||
@@ -571,12 +572,6 @@ static int phy_mdm6600_probe(struct platform_device *pdev)
|
||||
ddata->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, ddata);
|
||||
|
||||
/* Active state selected in phy_mdm6600_power_on() */
|
||||
error = pinctrl_pm_select_sleep_state(ddata->dev);
|
||||
if (error)
|
||||
dev_warn(ddata->dev, "%s: error with sleep_state: %i\n",
|
||||
__func__, error);
|
||||
|
||||
error = phy_mdm6600_init_lines(ddata);
|
||||
if (error)
|
||||
return error;
|
||||
@@ -627,10 +622,12 @@ idle:
|
||||
pm_runtime_put_autosuspend(ddata->dev);
|
||||
|
||||
cleanup:
|
||||
if (error < 0)
|
||||
if (error < 0) {
|
||||
phy_mdm6600_device_power_off(ddata);
|
||||
pm_runtime_disable(ddata->dev);
|
||||
pm_runtime_dont_use_autosuspend(ddata->dev);
|
||||
pm_runtime_disable(ddata->dev);
|
||||
pm_runtime_dont_use_autosuspend(ddata->dev);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -639,6 +636,7 @@ static int phy_mdm6600_remove(struct platform_device *pdev)
|
||||
struct phy_mdm6600 *ddata = platform_get_drvdata(pdev);
|
||||
struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET];
|
||||
|
||||
pm_runtime_get_noresume(ddata->dev);
|
||||
pm_runtime_dont_use_autosuspend(ddata->dev);
|
||||
pm_runtime_put_sync(ddata->dev);
|
||||
pm_runtime_disable(ddata->dev);
|
||||
|
||||
@@ -1007,20 +1007,17 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev,
|
||||
|
||||
static struct pinctrl *find_pinctrl(struct device *dev)
|
||||
{
|
||||
struct pinctrl *entry, *p = NULL;
|
||||
struct pinctrl *p;
|
||||
|
||||
mutex_lock(&pinctrl_list_mutex);
|
||||
|
||||
list_for_each_entry(entry, &pinctrl_list, node) {
|
||||
if (entry->dev == dev) {
|
||||
p = entry;
|
||||
kref_get(&p->users);
|
||||
break;
|
||||
list_for_each_entry(p, &pinctrl_list, node)
|
||||
if (p->dev == dev) {
|
||||
mutex_unlock(&pinctrl_list_mutex);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&pinctrl_list_mutex);
|
||||
return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void pinctrl_free(struct pinctrl *p, bool inlist);
|
||||
@@ -1129,6 +1126,7 @@ struct pinctrl *pinctrl_get(struct device *dev)
|
||||
p = find_pinctrl(dev);
|
||||
if (p) {
|
||||
dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n");
|
||||
kref_get(&p->users);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,8 +159,7 @@ static int surface_platform_profile_probe(struct ssam_device *sdev)
|
||||
set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, tpd->handler.choices);
|
||||
set_bit(PLATFORM_PROFILE_PERFORMANCE, tpd->handler.choices);
|
||||
|
||||
platform_profile_register(&tpd->handler);
|
||||
return 0;
|
||||
return platform_profile_register(&tpd->handler);
|
||||
}
|
||||
|
||||
static void surface_platform_profile_remove(struct ssam_device *sdev)
|
||||
|
||||
@@ -518,6 +518,9 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
|
||||
static const struct key_entry asus_nb_wmi_keymap[] = {
|
||||
{ KE_KEY, ASUS_WMI_BRN_DOWN, { KEY_BRIGHTNESSDOWN } },
|
||||
{ KE_KEY, ASUS_WMI_BRN_UP, { KEY_BRIGHTNESSUP } },
|
||||
{ KE_KEY, 0x2a, { KEY_SELECTIVE_SCREENSHOT } },
|
||||
{ KE_IGNORE, 0x2b, }, /* PrintScreen (also send via PS/2) on newer models */
|
||||
{ KE_IGNORE, 0x2c, }, /* CapsLock (also send via PS/2) on newer models */
|
||||
{ KE_KEY, 0x30, { KEY_VOLUMEUP } },
|
||||
{ KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
|
||||
{ KE_KEY, 0x32, { KEY_MUTE } },
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <linux/i8042.h>
|
||||
|
||||
#define ASUS_WMI_KEY_IGNORE (-1)
|
||||
#define ASUS_WMI_BRN_DOWN 0x20
|
||||
#define ASUS_WMI_BRN_DOWN 0x2e
|
||||
#define ASUS_WMI_BRN_UP 0x2f
|
||||
|
||||
struct module;
|
||||
|
||||
@@ -743,6 +743,21 @@ static const struct ts_dmi_data pipo_w11_data = {
|
||||
.properties = pipo_w11_props,
|
||||
};
|
||||
|
||||
static const struct property_entry positivo_c4128b_props[] = {
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-y", 13),
|
||||
PROPERTY_ENTRY_U32("touchscreen-size-x", 1915),
|
||||
PROPERTY_ENTRY_U32("touchscreen-size-y", 1269),
|
||||
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-positivo-c4128b.fw"),
|
||||
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct ts_dmi_data positivo_c4128b_data = {
|
||||
.acpi_name = "MSSL1680:00",
|
||||
.properties = positivo_c4128b_props,
|
||||
};
|
||||
|
||||
static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = {
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-x", 32),
|
||||
PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
|
||||
@@ -1442,6 +1457,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Positivo C4128B */
|
||||
.driver_data = (void *)&positivo_c4128b_data,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "C4128B-1"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Point of View mobii wintab p800w (v2.0) */
|
||||
.driver_data = (void *)&pov_mobii_wintab_p800w_v20_data,
|
||||
|
||||
@@ -5649,15 +5649,11 @@ wash:
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
regulator_ena_gpio_free(rdev);
|
||||
mutex_unlock(®ulator_list_mutex);
|
||||
put_device(&rdev->dev);
|
||||
rdev = NULL;
|
||||
clean:
|
||||
if (dangling_of_gpiod)
|
||||
gpiod_put(config->ena_gpiod);
|
||||
if (rdev && rdev->dev.of_node)
|
||||
of_node_put(rdev->dev.of_node);
|
||||
kfree(rdev);
|
||||
kfree(config);
|
||||
put_device(&rdev->dev);
|
||||
rinse:
|
||||
if (dangling_cfg_gpiod)
|
||||
gpiod_put(cfg->ena_gpiod);
|
||||
|
||||
@@ -233,17 +233,19 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid,
|
||||
*/
|
||||
ret = dma_set_coherent_mask(&sch->dev, DMA_BIT_MASK(31));
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_lock;
|
||||
/*
|
||||
* But we don't have such restrictions imposed on the stuff that
|
||||
* is handled by the streaming API.
|
||||
*/
|
||||
ret = dma_set_mask(&sch->dev, DMA_BIT_MASK(64));
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_lock;
|
||||
|
||||
return sch;
|
||||
|
||||
err_lock:
|
||||
kfree(sch->lock);
|
||||
err:
|
||||
kfree(sch);
|
||||
return ERR_PTR(ret);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "8250.h"
|
||||
|
||||
#define DEFAULT_CLK_SPEED 48000000
|
||||
#define OMAP_UART_REGSHIFT 2
|
||||
|
||||
#define UART_ERRATA_i202_MDR1_ACCESS (1 << 0)
|
||||
#define OMAP_UART_WER_HAS_TX_WAKEUP (1 << 1)
|
||||
@@ -109,6 +110,7 @@
|
||||
#define UART_OMAP_RX_LVL 0x19
|
||||
|
||||
struct omap8250_priv {
|
||||
void __iomem *membase;
|
||||
int line;
|
||||
u8 habit;
|
||||
u8 mdr1;
|
||||
@@ -152,9 +154,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p);
|
||||
static inline void omap_8250_rx_dma_flush(struct uart_8250_port *p) { }
|
||||
#endif
|
||||
|
||||
static u32 uart_read(struct uart_8250_port *up, u32 reg)
|
||||
static u32 uart_read(struct omap8250_priv *priv, u32 reg)
|
||||
{
|
||||
return readl(up->port.membase + (reg << up->port.regshift));
|
||||
return readl(priv->membase + (reg << OMAP_UART_REGSHIFT));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -552,7 +554,7 @@ static void omap_serial_fill_features_erratas(struct uart_8250_port *up,
|
||||
u32 mvr, scheme;
|
||||
u16 revision, major, minor;
|
||||
|
||||
mvr = uart_read(up, UART_OMAP_MVER);
|
||||
mvr = uart_read(priv, UART_OMAP_MVER);
|
||||
|
||||
/* Check revision register scheme */
|
||||
scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT;
|
||||
@@ -1336,7 +1338,7 @@ static int omap8250_probe(struct platform_device *pdev)
|
||||
UPF_HARD_FLOW;
|
||||
up.port.private_data = priv;
|
||||
|
||||
up.port.regshift = 2;
|
||||
up.port.regshift = OMAP_UART_REGSHIFT;
|
||||
up.port.fifosize = 64;
|
||||
up.tx_loadsz = 64;
|
||||
up.capabilities = UART_CAP_FIFO;
|
||||
@@ -1397,6 +1399,8 @@ static int omap8250_probe(struct platform_device *pdev)
|
||||
DEFAULT_CLK_SPEED);
|
||||
}
|
||||
|
||||
priv->membase = membase;
|
||||
priv->line = -ENODEV;
|
||||
priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
|
||||
priv->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
|
||||
cpu_latency_qos_add_request(&priv->pm_qos_request, priv->latency);
|
||||
@@ -1404,6 +1408,8 @@ static int omap8250_probe(struct platform_device *pdev)
|
||||
|
||||
spin_lock_init(&priv->rx_dma_lock);
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
@@ -1465,7 +1471,6 @@ static int omap8250_probe(struct platform_device *pdev)
|
||||
goto err;
|
||||
}
|
||||
priv->line = ret;
|
||||
platform_set_drvdata(pdev, priv);
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
return 0;
|
||||
@@ -1487,11 +1492,12 @@ static int omap8250_remove(struct platform_device *pdev)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
serial8250_unregister_port(priv->line);
|
||||
priv->line = -ENODEV;
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
flush_work(&priv->qos_work);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
serial8250_unregister_port(priv->line);
|
||||
cpu_latency_qos_remove_request(&priv->pm_qos_request);
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
return 0;
|
||||
@@ -1521,7 +1527,7 @@ static int omap8250_suspend(struct device *dev)
|
||||
{
|
||||
struct omap8250_priv *priv = dev_get_drvdata(dev);
|
||||
struct uart_8250_port *up = serial8250_get_port(priv->line);
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
serial8250_suspend_port(priv->line);
|
||||
|
||||
@@ -1531,7 +1537,8 @@ static int omap8250_suspend(struct device *dev)
|
||||
if (!device_may_wakeup(dev))
|
||||
priv->wer = 0;
|
||||
serial_out(up, UART_OMAP_WER, priv->wer);
|
||||
err = pm_runtime_force_suspend(dev);
|
||||
if (uart_console(&up->port) && console_suspend_enabled)
|
||||
err = pm_runtime_force_suspend(dev);
|
||||
flush_work(&priv->qos_work);
|
||||
|
||||
return err;
|
||||
@@ -1540,11 +1547,15 @@ static int omap8250_suspend(struct device *dev)
|
||||
static int omap8250_resume(struct device *dev)
|
||||
{
|
||||
struct omap8250_priv *priv = dev_get_drvdata(dev);
|
||||
struct uart_8250_port *up = serial8250_get_port(priv->line);
|
||||
int err;
|
||||
|
||||
err = pm_runtime_force_resume(dev);
|
||||
if (err)
|
||||
return err;
|
||||
if (uart_console(&up->port) && console_suspend_enabled) {
|
||||
err = pm_runtime_force_resume(dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
serial8250_resume_port(priv->line);
|
||||
/* Paired with pm_runtime_resume_and_get() in omap8250_suspend() */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
@@ -1573,11 +1584,15 @@ static int omap8250_lost_context(struct uart_8250_port *up)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uart_write(struct omap8250_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
writel(val, priv->membase + (reg << OMAP_UART_REGSHIFT));
|
||||
}
|
||||
|
||||
/* TODO: in future, this should happen via API in drivers/reset/ */
|
||||
static int omap8250_soft_reset(struct device *dev)
|
||||
{
|
||||
struct omap8250_priv *priv = dev_get_drvdata(dev);
|
||||
struct uart_8250_port *up = serial8250_get_port(priv->line);
|
||||
int timeout = 100;
|
||||
int sysc;
|
||||
int syss;
|
||||
@@ -1591,20 +1606,20 @@ static int omap8250_soft_reset(struct device *dev)
|
||||
* needing omap8250_soft_reset() quirk. Do it in two writes as
|
||||
* recommended in the comment for omap8250_update_scr().
|
||||
*/
|
||||
serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1);
|
||||
serial_out(up, UART_OMAP_SCR,
|
||||
uart_write(priv, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1);
|
||||
uart_write(priv, UART_OMAP_SCR,
|
||||
OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL);
|
||||
|
||||
sysc = serial_in(up, UART_OMAP_SYSC);
|
||||
sysc = uart_read(priv, UART_OMAP_SYSC);
|
||||
|
||||
/* softreset the UART */
|
||||
sysc |= OMAP_UART_SYSC_SOFTRESET;
|
||||
serial_out(up, UART_OMAP_SYSC, sysc);
|
||||
uart_write(priv, UART_OMAP_SYSC, sysc);
|
||||
|
||||
/* By experiments, 1us enough for reset complete on AM335x */
|
||||
do {
|
||||
udelay(1);
|
||||
syss = serial_in(up, UART_OMAP_SYSS);
|
||||
syss = uart_read(priv, UART_OMAP_SYSS);
|
||||
} while (--timeout && !(syss & OMAP_UART_SYSS_RESETDONE));
|
||||
|
||||
if (!timeout) {
|
||||
@@ -1618,23 +1633,10 @@ static int omap8250_soft_reset(struct device *dev)
|
||||
static int omap8250_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct omap8250_priv *priv = dev_get_drvdata(dev);
|
||||
struct uart_8250_port *up;
|
||||
struct uart_8250_port *up = NULL;
|
||||
|
||||
/* In case runtime-pm tries this before we are setup */
|
||||
if (!priv)
|
||||
return 0;
|
||||
|
||||
up = serial8250_get_port(priv->line);
|
||||
/*
|
||||
* When using 'no_console_suspend', the console UART must not be
|
||||
* suspended. Since driver suspend is managed by runtime suspend,
|
||||
* preventing runtime suspend (by returning error) will keep device
|
||||
* active during suspend.
|
||||
*/
|
||||
if (priv->is_suspending && !console_suspend_enabled) {
|
||||
if (uart_console(&up->port))
|
||||
return -EBUSY;
|
||||
}
|
||||
if (priv->line >= 0)
|
||||
up = serial8250_get_port(priv->line);
|
||||
|
||||
if (priv->habit & UART_ERRATA_CLOCK_DISABLE) {
|
||||
int ret;
|
||||
@@ -1643,13 +1645,15 @@ static int omap8250_runtime_suspend(struct device *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Restore to UART mode after reset (for wakeup) */
|
||||
omap8250_update_mdr1(up, priv);
|
||||
/* Restore wakeup enable register */
|
||||
serial_out(up, UART_OMAP_WER, priv->wer);
|
||||
if (up) {
|
||||
/* Restore to UART mode after reset (for wakeup) */
|
||||
omap8250_update_mdr1(up, priv);
|
||||
/* Restore wakeup enable register */
|
||||
serial_out(up, UART_OMAP_WER, priv->wer);
|
||||
}
|
||||
}
|
||||
|
||||
if (up->dma && up->dma->rxchan)
|
||||
if (up && up->dma && up->dma->rxchan)
|
||||
omap_8250_rx_dma_flush(up);
|
||||
|
||||
priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
|
||||
@@ -1661,18 +1665,15 @@ static int omap8250_runtime_suspend(struct device *dev)
|
||||
static int omap8250_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct omap8250_priv *priv = dev_get_drvdata(dev);
|
||||
struct uart_8250_port *up;
|
||||
struct uart_8250_port *up = NULL;
|
||||
|
||||
/* In case runtime-pm tries this before we are setup */
|
||||
if (!priv)
|
||||
return 0;
|
||||
if (priv->line >= 0)
|
||||
up = serial8250_get_port(priv->line);
|
||||
|
||||
up = serial8250_get_port(priv->line);
|
||||
|
||||
if (omap8250_lost_context(up))
|
||||
if (up && omap8250_lost_context(up))
|
||||
omap8250_restore_regs(up);
|
||||
|
||||
if (up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2))
|
||||
if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2))
|
||||
omap_8250_rx_dma(up);
|
||||
|
||||
priv->latency = priv->calc_latency;
|
||||
|
||||
@@ -203,6 +203,9 @@ static void option_instat_callback(struct urb *urb);
|
||||
#define DELL_PRODUCT_5829E_ESIM 0x81e4
|
||||
#define DELL_PRODUCT_5829E 0x81e6
|
||||
|
||||
#define DELL_PRODUCT_FM101R 0x8213
|
||||
#define DELL_PRODUCT_FM101R_ESIM 0x8215
|
||||
|
||||
#define KYOCERA_VENDOR_ID 0x0c88
|
||||
#define KYOCERA_PRODUCT_KPC650 0x17da
|
||||
#define KYOCERA_PRODUCT_KPC680 0x180a
|
||||
@@ -1108,6 +1111,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = RSVD(0) | RSVD(6) },
|
||||
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM),
|
||||
.driver_info = RSVD(0) | RSVD(6) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R, 0xff) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R_ESIM, 0xff) },
|
||||
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */
|
||||
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
|
||||
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
|
||||
@@ -1290,6 +1295,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(0) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */
|
||||
.driver_info = NCTRL(0) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1035, 0xff) }, /* Telit LE910C4-WWX (ECM) */
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
|
||||
.driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
|
||||
@@ -2262,6 +2268,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
||||
{ } /* Terminating entry */
|
||||
|
||||
@@ -545,18 +545,30 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
u64 search_start;
|
||||
int ret;
|
||||
|
||||
if (test_bit(BTRFS_ROOT_DELETING, &root->state))
|
||||
btrfs_err(fs_info,
|
||||
"COW'ing blocks on a fs root that's being dropped");
|
||||
if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) {
|
||||
btrfs_abort_transaction(trans, -EUCLEAN);
|
||||
btrfs_crit(fs_info,
|
||||
"attempt to COW block %llu on root %llu that is being deleted",
|
||||
buf->start, btrfs_root_id(root));
|
||||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
if (trans->transaction != fs_info->running_transaction)
|
||||
WARN(1, KERN_CRIT "trans %llu running %llu\n",
|
||||
trans->transid,
|
||||
fs_info->running_transaction->transid);
|
||||
|
||||
if (trans->transid != fs_info->generation)
|
||||
WARN(1, KERN_CRIT "trans %llu running %llu\n",
|
||||
trans->transid, fs_info->generation);
|
||||
/*
|
||||
* COWing must happen through a running transaction, which always
|
||||
* matches the current fs generation (it's a transaction with a state
|
||||
* less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs
|
||||
* into error state to prevent the commit of any transaction.
|
||||
*/
|
||||
if (unlikely(trans->transaction != fs_info->running_transaction ||
|
||||
trans->transid != fs_info->generation)) {
|
||||
btrfs_abort_transaction(trans, -EUCLEAN);
|
||||
btrfs_crit(fs_info,
|
||||
"unexpected transaction when attempting to COW block %llu on root %llu, transaction %llu running transaction %llu fs generation %llu",
|
||||
buf->start, btrfs_root_id(root), trans->transid,
|
||||
fs_info->running_transaction->transid,
|
||||
fs_info->generation);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
if (!should_cow_block(trans, root, buf)) {
|
||||
*cow_ret = buf;
|
||||
@@ -668,8 +680,22 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
|
||||
int progress_passed = 0;
|
||||
struct btrfs_disk_key disk_key;
|
||||
|
||||
WARN_ON(trans->transaction != fs_info->running_transaction);
|
||||
WARN_ON(trans->transid != fs_info->generation);
|
||||
/*
|
||||
* COWing must happen through a running transaction, which always
|
||||
* matches the current fs generation (it's a transaction with a state
|
||||
* less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs
|
||||
* into error state to prevent the commit of any transaction.
|
||||
*/
|
||||
if (unlikely(trans->transaction != fs_info->running_transaction ||
|
||||
trans->transid != fs_info->generation)) {
|
||||
btrfs_abort_transaction(trans, -EUCLEAN);
|
||||
btrfs_crit(fs_info,
|
||||
"unexpected transaction when attempting to reallocate parent %llu for root %llu, transaction %llu running transaction %llu fs generation %llu",
|
||||
parent->start, btrfs_root_id(root), trans->transid,
|
||||
fs_info->running_transaction->transid,
|
||||
fs_info->generation);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
parent_nritems = btrfs_header_nritems(parent);
|
||||
blocksize = fs_info->nodesize;
|
||||
|
||||
@@ -1674,12 +1674,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
|
||||
parent = ref->parent;
|
||||
ref_root = ref->root;
|
||||
|
||||
if (node->ref_mod != 1) {
|
||||
if (unlikely(node->ref_mod != 1)) {
|
||||
btrfs_err(trans->fs_info,
|
||||
"btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu",
|
||||
"btree block %llu has %d references rather than 1: action %d ref_root %llu parent %llu",
|
||||
node->bytenr, node->ref_mod, node->action, ref_root,
|
||||
parent);
|
||||
return -EIO;
|
||||
return -EUCLEAN;
|
||||
}
|
||||
if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
|
||||
BUG_ON(!extent_op || !extent_op->update_flags);
|
||||
|
||||
@@ -3531,7 +3531,7 @@ static void get_block_group_info(struct list_head *groups_list,
|
||||
static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info,
|
||||
void __user *arg)
|
||||
{
|
||||
struct btrfs_ioctl_space_args space_args;
|
||||
struct btrfs_ioctl_space_args space_args = { 0 };
|
||||
struct btrfs_ioctl_space_info space;
|
||||
struct btrfs_ioctl_space_info *dest;
|
||||
struct btrfs_ioctl_space_info *dest_orig;
|
||||
@@ -4867,7 +4867,7 @@ static int _btrfs_ioctl_send(struct file *file, void __user *argp, bool compat)
|
||||
|
||||
if (compat) {
|
||||
#if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT)
|
||||
struct btrfs_ioctl_send_args_32 args32;
|
||||
struct btrfs_ioctl_send_args_32 args32 = { 0 };
|
||||
|
||||
ret = copy_from_user(&args32, argp, sizeof(args32));
|
||||
if (ret)
|
||||
|
||||
@@ -4446,7 +4446,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans,
|
||||
struct extent_buffer *leaf;
|
||||
int slot;
|
||||
int ins_nr = 0;
|
||||
int start_slot;
|
||||
int start_slot = 0;
|
||||
int ret;
|
||||
|
||||
if (!(inode->flags & BTRFS_INODE_PREALLOC))
|
||||
|
||||
@@ -1557,10 +1557,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
|
||||
|
||||
if (wbc->pages_skipped) {
|
||||
/*
|
||||
* writeback is not making progress due to locked
|
||||
* buffers. Skip this inode for now.
|
||||
* Writeback is not making progress due to locked buffers.
|
||||
* Skip this inode for now. Although having skipped pages
|
||||
* is odd for clean inodes, it can happen for some
|
||||
* filesystems so handle that gracefully.
|
||||
*/
|
||||
redirty_tail_locked(inode, wb);
|
||||
if (inode->i_state & I_DIRTY_ALL)
|
||||
redirty_tail_locked(inode, wb);
|
||||
else
|
||||
inode_cgwb_move_to_attached(inode, wb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ int ksmbd_query_inode_status(struct inode *inode)
|
||||
ci = __ksmbd_inode_lookup(inode);
|
||||
if (ci) {
|
||||
ret = KSMBD_INODE_STATUS_OK;
|
||||
if (ci->m_flags & S_DEL_PENDING)
|
||||
if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS))
|
||||
ret = KSMBD_INODE_STATUS_PENDING_DELETE;
|
||||
atomic_dec(&ci->m_count);
|
||||
}
|
||||
@@ -115,7 +115,7 @@ int ksmbd_query_inode_status(struct inode *inode)
|
||||
|
||||
bool ksmbd_inode_pending_delete(struct ksmbd_file *fp)
|
||||
{
|
||||
return (fp->f_ci->m_flags & S_DEL_PENDING);
|
||||
return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS));
|
||||
}
|
||||
|
||||
void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp)
|
||||
|
||||
@@ -8794,8 +8794,6 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre
|
||||
/* Save the EXCHANGE_ID verifier session trunk tests */
|
||||
memcpy(clp->cl_confirm.data, argp->verifier.data,
|
||||
sizeof(clp->cl_confirm.data));
|
||||
if (resp->flags & EXCHGID4_FLAG_USE_PNFS_DS)
|
||||
set_bit(NFS_CS_DS, &clp->cl_flags);
|
||||
out:
|
||||
trace_nfs4_exchange_id(clp, status);
|
||||
rpc_put_task(task);
|
||||
|
||||
@@ -2629,31 +2629,44 @@ pnfs_should_return_unused_layout(struct pnfs_layout_hdr *lo,
|
||||
return mode == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pnfs_layout_return_unused_byserver(struct nfs_server *server, void *data)
|
||||
static int pnfs_layout_return_unused_byserver(struct nfs_server *server,
|
||||
void *data)
|
||||
{
|
||||
const struct pnfs_layout_range *range = data;
|
||||
const struct cred *cred;
|
||||
struct pnfs_layout_hdr *lo;
|
||||
struct inode *inode;
|
||||
nfs4_stateid stateid;
|
||||
enum pnfs_iomode iomode;
|
||||
|
||||
restart:
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) {
|
||||
if (!pnfs_layout_can_be_returned(lo) ||
|
||||
inode = lo->plh_inode;
|
||||
if (!inode || !pnfs_layout_can_be_returned(lo) ||
|
||||
test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
|
||||
continue;
|
||||
inode = lo->plh_inode;
|
||||
spin_lock(&inode->i_lock);
|
||||
if (!pnfs_should_return_unused_layout(lo, range)) {
|
||||
if (!lo->plh_inode ||
|
||||
!pnfs_should_return_unused_layout(lo, range)) {
|
||||
spin_unlock(&inode->i_lock);
|
||||
continue;
|
||||
}
|
||||
pnfs_get_layout_hdr(lo);
|
||||
pnfs_set_plh_return_info(lo, range->iomode, 0);
|
||||
if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs,
|
||||
range, 0) != 0 ||
|
||||
!pnfs_prepare_layoutreturn(lo, &stateid, &cred, &iomode)) {
|
||||
spin_unlock(&inode->i_lock);
|
||||
rcu_read_unlock();
|
||||
pnfs_put_layout_hdr(lo);
|
||||
cond_resched();
|
||||
goto restart;
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
inode = pnfs_grab_inode_layout_hdr(lo);
|
||||
if (!inode)
|
||||
continue;
|
||||
rcu_read_unlock();
|
||||
pnfs_mark_layout_for_return(inode, range);
|
||||
iput(inode);
|
||||
pnfs_send_layoutreturn(lo, &stateid, &cred, iomode, false);
|
||||
pnfs_put_layout_hdr(lo);
|
||||
cond_resched();
|
||||
goto restart;
|
||||
}
|
||||
|
||||
@@ -2458,10 +2458,12 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim)
|
||||
{
|
||||
CLST end, i;
|
||||
struct wnd_bitmap *wnd = &sbi->used.bitmap;
|
||||
bool dirty = false;
|
||||
|
||||
down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
|
||||
if (!wnd_is_used(wnd, lcn, len)) {
|
||||
ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
|
||||
/* mark volume as dirty out of wnd->rw_lock */
|
||||
dirty = true;
|
||||
|
||||
end = lcn + len;
|
||||
len = 0;
|
||||
@@ -2493,6 +2495,8 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim)
|
||||
|
||||
out:
|
||||
up_write(&wnd->rw_lock);
|
||||
if (dirty)
|
||||
ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -729,6 +729,9 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx,
|
||||
u32 total = le32_to_cpu(hdr->total);
|
||||
u16 offs[128];
|
||||
|
||||
if (unlikely(!cmp))
|
||||
return NULL;
|
||||
|
||||
fill_table:
|
||||
if (end > total)
|
||||
return NULL;
|
||||
|
||||
@@ -209,7 +209,8 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer,
|
||||
size = le32_to_cpu(info->size);
|
||||
|
||||
/* Enumerate all xattrs. */
|
||||
for (ret = 0, off = 0; off < size; off += ea_size) {
|
||||
ret = 0;
|
||||
for (off = 0; off + sizeof(struct EA_FULL) < size; off += ea_size) {
|
||||
ea = Add2Ptr(ea_all, off);
|
||||
ea_size = unpacked_ea_size(ea);
|
||||
|
||||
@@ -217,6 +218,10 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer,
|
||||
break;
|
||||
|
||||
if (buffer) {
|
||||
/* Check if we can use field ea->name */
|
||||
if (off + ea_size > size)
|
||||
break;
|
||||
|
||||
if (ret + ea->name_len + 1 > bytes_per_buffer) {
|
||||
err = -ERANGE;
|
||||
goto out;
|
||||
|
||||
@@ -306,7 +306,7 @@ static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat)
|
||||
{
|
||||
struct iattr attr = {
|
||||
.ia_valid =
|
||||
ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET,
|
||||
ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_CTIME,
|
||||
.ia_atime = stat->atime,
|
||||
.ia_mtime = stat->mtime,
|
||||
};
|
||||
|
||||
@@ -511,27 +511,6 @@ xfs_vn_get_link(
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
STATIC const char *
|
||||
xfs_vn_get_link_inline(
|
||||
struct dentry *dentry,
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct xfs_inode *ip = XFS_I(inode);
|
||||
char *link;
|
||||
|
||||
ASSERT(ip->i_df.if_format == XFS_DINODE_FMT_LOCAL);
|
||||
|
||||
/*
|
||||
* The VFS crashes on a NULL pointer, so return -EFSCORRUPTED if
|
||||
* if_data is junk.
|
||||
*/
|
||||
link = ip->i_df.if_u1.if_data;
|
||||
if (XFS_IS_CORRUPT(ip->i_mount, !link))
|
||||
return ERR_PTR(-EFSCORRUPTED);
|
||||
return link;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
xfs_stat_blksize(
|
||||
struct xfs_inode *ip)
|
||||
@@ -1200,14 +1179,6 @@ static const struct inode_operations xfs_symlink_inode_operations = {
|
||||
.update_time = xfs_vn_update_time,
|
||||
};
|
||||
|
||||
static const struct inode_operations xfs_inline_symlink_inode_operations = {
|
||||
.get_link = xfs_vn_get_link_inline,
|
||||
.getattr = xfs_vn_getattr,
|
||||
.setattr = xfs_vn_setattr,
|
||||
.listxattr = xfs_vn_listxattr,
|
||||
.update_time = xfs_vn_update_time,
|
||||
};
|
||||
|
||||
/* Figure out if this file actually supports DAX. */
|
||||
static bool
|
||||
xfs_inode_supports_dax(
|
||||
@@ -1358,10 +1329,7 @@ xfs_setup_iops(
|
||||
inode->i_fop = &xfs_dir_file_operations;
|
||||
break;
|
||||
case S_IFLNK:
|
||||
if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL)
|
||||
inode->i_op = &xfs_inline_symlink_inode_operations;
|
||||
else
|
||||
inode->i_op = &xfs_symlink_inode_operations;
|
||||
inode->i_op = &xfs_symlink_inode_operations;
|
||||
break;
|
||||
default:
|
||||
inode->i_op = &xfs_inode_operations;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_ialloc.h"
|
||||
#include "xfs_error.h"
|
||||
|
||||
/* ----- Kernel only functions below ----- */
|
||||
int
|
||||
@@ -96,17 +97,15 @@ xfs_readlink_bmap_ilocked(
|
||||
|
||||
int
|
||||
xfs_readlink(
|
||||
struct xfs_inode *ip,
|
||||
char *link)
|
||||
struct xfs_inode *ip,
|
||||
char *link)
|
||||
{
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
xfs_fsize_t pathlen;
|
||||
int error = 0;
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
xfs_fsize_t pathlen;
|
||||
int error = -EFSCORRUPTED;
|
||||
|
||||
trace_xfs_readlink(ip);
|
||||
|
||||
ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_LOCAL);
|
||||
|
||||
if (xfs_is_shutdown(mp))
|
||||
return -EIO;
|
||||
|
||||
@@ -121,12 +120,22 @@ xfs_readlink(
|
||||
__func__, (unsigned long long) ip->i_ino,
|
||||
(long long) pathlen);
|
||||
ASSERT(0);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
|
||||
/*
|
||||
* The VFS crashes on a NULL pointer, so return -EFSCORRUPTED
|
||||
* if if_data is junk.
|
||||
*/
|
||||
if (XFS_IS_CORRUPT(ip->i_mount, !ip->i_df.if_u1.if_data))
|
||||
goto out;
|
||||
|
||||
error = xfs_readlink_bmap_ilocked(ip, link);
|
||||
memcpy(link, ip->i_df.if_u1.if_data, pathlen + 1);
|
||||
error = 0;
|
||||
} else {
|
||||
error = xfs_readlink_bmap_ilocked(ip, link);
|
||||
}
|
||||
|
||||
out:
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
|
||||
@@ -542,6 +542,8 @@ struct iio_dev {
|
||||
};
|
||||
|
||||
int iio_device_id(struct iio_dev *indio_dev);
|
||||
int iio_device_get_current_mode(struct iio_dev *indio_dev);
|
||||
bool iio_buffer_enabled(struct iio_dev *indio_dev);
|
||||
|
||||
const struct iio_chan_spec
|
||||
*iio_find_channel_from_si(struct iio_dev *indio_dev, int si);
|
||||
@@ -573,6 +575,8 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev,
|
||||
int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp);
|
||||
int iio_device_claim_direct_mode(struct iio_dev *indio_dev);
|
||||
void iio_device_release_direct_mode(struct iio_dev *indio_dev);
|
||||
int iio_device_claim_buffer_mode(struct iio_dev *indio_dev);
|
||||
void iio_device_release_buffer_mode(struct iio_dev *indio_dev);
|
||||
|
||||
extern struct bus_type iio_bus_type;
|
||||
|
||||
@@ -671,16 +675,6 @@ struct iio_dev *devm_iio_device_alloc(struct device *parent, int sizeof_priv);
|
||||
__printf(2, 3)
|
||||
struct iio_trigger *devm_iio_trigger_alloc(struct device *parent,
|
||||
const char *fmt, ...);
|
||||
/**
|
||||
* iio_buffer_enabled() - helper function to test if the buffer is enabled
|
||||
* @indio_dev: IIO device structure for device
|
||||
**/
|
||||
static inline bool iio_buffer_enabled(struct iio_dev *indio_dev)
|
||||
{
|
||||
return indio_dev->currentmode
|
||||
& (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE |
|
||||
INDIO_BUFFER_SOFTWARE);
|
||||
}
|
||||
|
||||
/**
|
||||
* iio_get_debugfs_dentry() - helper function to get the debugfs_dentry
|
||||
|
||||
@@ -3025,6 +3025,7 @@ struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags,
|
||||
struct net_device *dev_get_by_name(struct net *net, const char *name);
|
||||
struct net_device *dev_get_by_name_rcu(struct net *net, const char *name);
|
||||
struct net_device *__dev_get_by_name(struct net *net, const char *name);
|
||||
bool netdev_name_in_use(struct net *net, const char *name);
|
||||
int dev_alloc_name(struct net_device *dev, const char *name);
|
||||
int dev_open(struct net_device *dev, struct netlink_ext_ack *extack);
|
||||
void dev_close(struct net_device *dev);
|
||||
|
||||
@@ -663,6 +663,7 @@ struct perf_event {
|
||||
/* The cumulative AND of all event_caps for events in this group. */
|
||||
int group_caps;
|
||||
|
||||
unsigned int group_generation;
|
||||
struct perf_event *group_leader;
|
||||
struct pmu *pmu;
|
||||
void *pmu_private;
|
||||
|
||||
@@ -311,7 +311,7 @@ struct hci_dev {
|
||||
struct list_head list;
|
||||
struct mutex lock;
|
||||
|
||||
char name[8];
|
||||
const char *name;
|
||||
unsigned long flags;
|
||||
__u16 id;
|
||||
__u8 bus;
|
||||
|
||||
@@ -56,7 +56,7 @@ struct hci_mon_new_index {
|
||||
__u8 type;
|
||||
__u8 bus;
|
||||
bdaddr_t bdaddr;
|
||||
char name[8];
|
||||
char name[8] __nonstring;
|
||||
} __packed;
|
||||
#define HCI_MON_NEW_INDEX_SIZE 16
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ struct fib_info {
|
||||
int fib_nhs;
|
||||
bool fib_nh_is_v6;
|
||||
bool nh_updated;
|
||||
bool pfsrc_removed;
|
||||
struct nexthop *nh;
|
||||
struct rcu_head rcu;
|
||||
struct fib_nh fib_nh[];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user