Merge tag 'ASB-2022-09-05_4.19-stable' of https://android.googlesource.com/kernel/common into android13-4.19-kona

https://source.android.com/docs/security/bulletin/2022-09-01
CVE-2022-20399
CVE-2022-23960
CVE-2021-4083
CVE-2022-29582

* tag 'ASB-2022-09-05_4.19-stable' of https://android.googlesource.com/kernel/common:
  Linux 4.19.255
  x86/speculation: Add LFENCE to RSB fill sequence
  x86/speculation: Add RSB VM Exit protections
  macintosh/adb: fix oob read in do_adb_query() function
  ACPI: video: Shortening quirk list by identifying Clevo by board_name only
  ACPI: video: Force backlight native for some TongFang devices
  scsi: core: Fix race between handling STS_RESOURCE and completion
  mt7601u: add USB device ID for some versions of XiaoDu WiFi Dongle.
  ARM: crypto: comment out gcc warning that breaks clang builds
  perf symbol: Correct address for bss symbols
  netfilter: nf_queue: do not allow packet truncation below transport header offset
  sctp: fix sleep in atomic context bug in timer handlers
  i40e: Fix interface init with MSI interrupts (no MSI-X)
  tcp: Fix a data-race around sysctl_tcp_comp_sack_nr.
  tcp: Fix a data-race around sysctl_tcp_comp_sack_delay_ns.
  Documentation: fix sctp_wmem in ip-sysctl.rst
  tcp: Fix a data-race around sysctl_tcp_invalid_ratelimit.
  tcp: Fix a data-race around sysctl_tcp_autocorking.
  tcp: Fix a data-race around sysctl_tcp_min_rtt_wlen.
  tcp: Fix a data-race around sysctl_tcp_min_tso_segs.
  net: sungem_phy: Add of_node_put() for reference returned by of_get_parent()
  igmp: Fix data-races around sysctl_igmp_qrv.
  net: ping6: Fix memleak in ipv6_renew_options().
  tcp: Fix a data-race around sysctl_tcp_challenge_ack_limit.
  scsi: ufs: host: Hold reference returned by of_parse_phandle()
  tcp: Fix a data-race around sysctl_tcp_nometrics_save.
  tcp: Fix a data-race around sysctl_tcp_frto.
  tcp: Fix a data-race around sysctl_tcp_adv_win_scale.
  tcp: Fix a data-race around sysctl_tcp_app_win.
  tcp: Fix data-races around sysctl_tcp_dsack.
  s390/archrandom: prevent CPACF trng invocations in interrupt context
  ntfs: fix use-after-free in ntfs_ucsncmp()
  Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put
  FROMLIST: binder: fix UAF of ref->proc caused by race condition
  Linux 4.19.254
  PCI: hv: Fix interrupt mapping for multi-MSI
  PCI: hv: Reuse existing IRTE allocation in compose_msi_msg()
  PCI: hv: Fix hv_arch_irq_unmask() for multi-MSI
  PCI: hv: Fix multi-MSI to allow more than one MSI vector
  net: usb: ax88179_178a needs FLAG_SEND_ZLP
  tty: use new tty_insert_flip_string_and_push_buffer() in pty_write()
  tty: extract tty_flip_buffer_commit() from tty_flip_buffer_push()
  tty: drop tty_schedule_flip()
  tty: the rest, stop using tty_schedule_flip()
  tty: drivers/tty/, stop using tty_schedule_flip()
  serial: mvebu-uart: correctly report configured baudrate value
  Bluetooth: Fix bt_skb_sendmmsg not allocating partial chunks
  Bluetooth: SCO: Fix sco_send_frame returning skb->len
  Bluetooth: Fix passing NULL to PTR_ERR
  Bluetooth: RFCOMM: Replace use of memcpy_from_msg with bt_skb_sendmmsg
  Bluetooth: SCO: Replace use of memcpy_from_msg with bt_skb_sendmsg
  Bluetooth: Add bt_skb_sendmmsg helper
  Bluetooth: Add bt_skb_sendmsg helper
  ALSA: memalloc: Align buffer allocations in page size
  ima: remove the IMA_TEMPLATE Kconfig option
  dlm: fix pending remove if msg allocation fails
  HID: add ALWAYS_POLL quirk to lenovo pixart mouse
  HID: multitouch: add support for the Smart Tech panel
  HID: multitouch: Lenovo X1 Tablet Gen3 trackpoint and buttons
  HID: multitouch: simplify the application retrieval
  tilcdc: tilcdc_external: fix an incorrect NULL check on list iterator
  drm/tilcdc: Remove obsolete crtc_mode_valid() hack
  bpf: Make sure mac_header was set before using it
  mm/mempolicy: fix uninit-value in mpol_rebind_policy()
  Revert "Revert "char/random: silence a lockdep splat with printk()""
  tcp: Fix data-races around sysctl_tcp_max_reordering.
  tcp: Fix a data-race around sysctl_tcp_rfc1337.
  tcp: Fix a data-race around sysctl_tcp_stdurg.
  tcp: Fix a data-race around sysctl_tcp_retrans_collapse.
  tcp: Fix data-races around sysctl_tcp_slow_start_after_idle.
  tcp: Fix a data-race around sysctl_tcp_thin_linear_timeouts.
  tcp: Fix data-races around sysctl_tcp_recovery.
  tcp: Fix a data-race around sysctl_tcp_early_retrans.
  be2net: Fix buffer overflow in be_get_module_eeprom
  tcp: Fix data-races around sysctl_tcp_fastopen.
  tcp: Fix a data-race around sysctl_tcp_tw_reuse.
  tcp: Fix a data-race around sysctl_tcp_notsent_lowat.
  tcp: Fix data-races around some timeout sysctl knobs.
  tcp: Fix data-races around sysctl_tcp_reordering.
  igmp: Fix a data-race around sysctl_igmp_max_memberships.
  igmp: Fix data-races around sysctl_igmp_llm_reports.
  net/tls: Fix race in TLS device down flow
  net: stmmac: fix dma queue left shift overflow issue
  i2c: cadence: Change large transfer count reset logic to be unconditional
  tcp: Fix a data-race around sysctl_tcp_probe_interval.
  tcp: Fix a data-race around sysctl_tcp_probe_threshold.
  tcp: Fix data-races around sysctl_tcp_mtu_probing.
  tcp/dccp: Fix a data-race around sysctl_tcp_fwmark_accept.
  ip: Fix a data-race around sysctl_fwmark_reflect.
  ip: Fix data-races around sysctl_ip_nonlocal_bind.
  ip: Fix data-races around sysctl_ip_fwd_use_pmtu.
  perf/core: Fix data race between perf_event_set_output() and perf_mmap_close()
  pinctrl: ralink: Check for null return of devm_kcalloc
  power/reset: arm-versatile: Fix refcount leak in versatile_reboot_probe
  xfrm: xfrm_policy: fix a possible double xfrm_pols_put() in xfrm_bundle_lookup()
  xen/gntdev: Ignore failure to unmap INVALID_GRANT_HANDLE
  riscv: add as-options for modules with assembly compontents
  Revert "cgroup: Use separate src/dst nodes when preloading css_sets for migration"
  Linux 4.19.253
  can: m_can: m_can_tx_handler(): fix use after free of skb
  serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle
  serial: stm32: Clear prev values before setting RTS delays
  serial: 8250: fix return error code in serial8250_request_std_resource()
  tty: serial: samsung_tty: set dma burst_size to 1
  usb: dwc3: gadget: Fix event pending check
  usb: typec: add missing uevent when partner support PD
  USB: serial: ftdi_sio: add Belimo device ids
  signal handling: don't use BUG_ON() for debugging
  ARM: dts: stm32: use the correct clock source for CEC on stm32mp151
  x86: Clear .brk area at early boot
  irqchip: or1k-pic: Undefine mask_ack for level triggered hardware
  ASoC: wm5110: Fix DRE control
  ASoC: ops: Fix off by one in range control validation
  net: sfp: fix memory leak in sfp_probe()
  NFC: nxp-nci: don't print header length mismatch on i2c error
  net: tipc: fix possible refcount leak in tipc_sk_create()
  platform/x86: hp-wmi: Ignore Sanitization Mode event
  cpufreq: pmac32-cpufreq: Fix refcount leak bug
  netfilter: br_netfilter: do not skip all hooks with 0 priority
  virtio_mmio: Restore guest page size on resume
  virtio_mmio: Add missing PM calls to freeze/restore
  sfc: fix kernel panic when creating VF
  seg6: bpf: fix skb checksum in bpf_push_seg6_encap()
  seg6: fix skb checksum in SRv6 End.B6 and End.B6.Encaps behaviors
  seg6: fix skb checksum evaluation in SRH encapsulation/insertion
  sfc: fix use after free when disabling sriov
  ipv4: Fix data-races around sysctl_ip_dynaddr.
  icmp: Fix a data-race around sysctl_icmp_ratemask.
  icmp: Fix a data-race around sysctl_icmp_ratelimit.
  ARM: dts: sunxi: Fix SPI NOR campatible on Orange Pi Zero
  icmp: Fix data-races around sysctl.
  cipso: Fix data-races around sysctl.
  net: Fix data-races around sysctl_mem.
  inetpeer: Fix data-races around sysctl.
  ASoC: sgtl5000: Fix noise on shutdown/remove
  ARM: 9209/1: Spectre-BHB: avoid pr_info() every time a CPU comes out of idle
  ARM: dts: imx6qdl-ts7970: Fix ngpio typo and count
  nilfs2: fix incorrect masking of permission flags for symlinks
  cgroup: Use separate src/dst nodes when preloading css_sets for migration
  ARM: 9214/1: alignment: advance IT state after emulating Thumb instruction
  ARM: 9213/1: Print message about disabled Spectre workarounds only once
  net: sock: tracing: Fix sock_exceed_buf_limit not to dereference stale pointer
  tracing/histograms: Fix memory leak problem
  xen/netback: avoid entering xenvif_rx_next_skb() with an empty rx queue
  ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc221
  ALSA: hda/conexant: Apply quirk for another HP ProDesk 600 G3 model
  ALSA: hda - Add fixup for Dell Latitidue E5430

Change-Id: I2ea45f6f13cf904894563522f1bb35830dd0bf9e
This commit is contained in:
Michael Bestas 2022-11-24 03:23:44 +02:00
commit ee48262ac6
No known key found for this signature in database
GPG key ID: CC95044519BE6669
133 changed files with 1104 additions and 623 deletions

View file

@ -422,6 +422,14 @@ The possible values in this file are:
'RSB filling' Protection of RSB on context switch enabled
============= ===========================================
- EIBRS Post-barrier Return Stack Buffer (PBRSB) protection status:
=========================== =======================================================
'PBRSB-eIBRS: SW sequence' CPU is affected and protection of RSB on VMEXIT enabled
'PBRSB-eIBRS: Vulnerable' CPU is vulnerable
'PBRSB-eIBRS: Not affected' CPU is not affected by PBRSB
=========================== =======================================================
Full mitigation might require a microcode update from the CPU
vendor. When the necessary microcode is not available, the kernel will
report vulnerability.

View file

@ -820,7 +820,7 @@ cipso_cache_enable - BOOLEAN
cipso_cache_bucket_size - INTEGER
The CIPSO label cache consists of a fixed size hash table with each
hash bucket containing a number of cache entries. This variable limits
the number of entries in each hash bucket; the larger the value the
the number of entries in each hash bucket; the larger the value is, the
more CIPSO label mappings that can be cached. When the number of
entries in a given hash bucket reaches this limit adding new entries
causes the oldest entry in the bucket to be removed to make room.
@ -902,7 +902,7 @@ ip_nonlocal_bind - BOOLEAN
which can be quite useful - but may break some applications.
Default: 0
ip_dynaddr - BOOLEAN
ip_dynaddr - INTEGER
If set non-zero, enables support for dynamic addresses.
If set to a non-zero value larger than 1, a kernel log
message will be printed when dynamic address rewriting
@ -2189,7 +2189,14 @@ sctp_rmem - vector of 3 INTEGERs: min, default, max
Default: 4K
sctp_wmem - vector of 3 INTEGERs: min, default, max
Currently this tunable has no effect.
Only the first value ("min") is used, "default" and "max" are
ignored.
min: Minimum size of send buffer that can be used by SCTP sockets.
It is guaranteed to each SCTP socket (but not association) even
under moderate memory pressure.
Default: 4K
addr_scope_policy - INTEGER
Control IPv4 address scoping - draft-stewart-tsvwg-sctp-ipv4-00

View file

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 19
SUBLEVEL = 252
SUBLEVEL = 255
EXTRAVERSION =
NAME = "People's Front"

View file

@ -59,7 +59,7 @@ srmcons_do_receive_chars(struct tty_port *port)
} while((result.bits.status & 1) && (++loops < 10));
if (count)
tty_schedule_flip(port);
tty_flip_buffer_push(port);
return count;
}

View file

@ -226,7 +226,7 @@
reg = <0x28>;
#gpio-cells = <2>;
gpio-controller;
ngpio = <32>;
ngpios = <62>;
};
sgtl5000: codec@a {

View file

@ -413,7 +413,7 @@
compatible = "st,stm32-cec";
reg = <0x40016000 0x400>;
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc CEC_K>, <&clk_lse>;
clocks = <&rcc CEC_K>, <&rcc CEC>;
clock-names = "cec", "hdmi-cec";
status = "disabled";
};

View file

@ -170,7 +170,7 @@
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "mxicy,mx25l1606e", "winbond,w25q128";
compatible = "mxicy,mx25l1606e", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <40000000>;
};

View file

@ -167,5 +167,31 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \
})
/*
* Update ITSTATE after normal execution of an IT block instruction.
*
* The 8 IT state bits are split into two parts in CPSR:
* ITSTATE<1:0> are in CPSR<26:25>
* ITSTATE<7:2> are in CPSR<15:10>
*/
static inline unsigned long it_advance(unsigned long cpsr)
{
if ((cpsr & 0x06000400) == 0) {
/* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
cpsr &= ~PSR_IT_MASK;
} else {
/* We need to shift left ITSTATE<4:0> */
const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */
unsigned long it = cpsr & mask;
it <<= 1;
it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */
it &= mask;
cpsr &= ~mask;
cpsr |= it;
}
return cpsr;
}
#endif /* __ASSEMBLY__ */
#endif

View file

@ -29,8 +29,9 @@ MODULE_LICENSE("GPL");
* While older versions of GCC do not generate incorrect code, they fail to
* recognize the parallel nature of these functions, and emit plain ARM code,
* which is known to be slower than the optimized ARM code in asm-arm/xor.h.
*
* #warning This code requires at least version 4.6 of GCC
*/
#warning This code requires at least version 4.6 of GCC
#endif
#pragma GCC diagnostic ignored "-Wunused-variable"

View file

@ -936,6 +936,9 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (type == TYPE_LDST)
do_alignment_finish_ldst(addr, instr, regs, offset);
if (thumb_mode(regs))
regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
return 0;
bad_or_fault:

View file

@ -110,8 +110,7 @@ static unsigned int spectre_v2_install_workaround(unsigned int method)
#else
static unsigned int spectre_v2_install_workaround(unsigned int method)
{
pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n",
smp_processor_id());
pr_info_once("Spectre V2: workarounds disabled by configuration\n");
return SPECTRE_VULNERABLE;
}
@ -223,10 +222,10 @@ static int spectre_bhb_install_workaround(int method)
return SPECTRE_VULNERABLE;
spectre_bhb_method = method;
}
pr_info("CPU%u: Spectre BHB: using %s workaround\n",
smp_processor_id(), spectre_bhb_method_name(method));
pr_info("CPU%u: Spectre BHB: enabling %s workaround for all CPUs\n",
smp_processor_id(), spectre_bhb_method_name(method));
}
return SPECTRE_MITIGATED;
}

View file

@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/stddef.h>
#include <asm/probes.h>
#include <asm/ptrace.h>
#include <asm/kprobes.h>
void __init arm_probes_decode_init(void);
@ -43,31 +44,6 @@ void __init find_str_pc_offset(void);
#endif
/*
* Update ITSTATE after normal execution of an IT block instruction.
*
* The 8 IT state bits are split into two parts in CPSR:
* ITSTATE<1:0> are in CPSR<26:25>
* ITSTATE<7:2> are in CPSR<15:10>
*/
static inline unsigned long it_advance(unsigned long cpsr)
{
if ((cpsr & 0x06000400) == 0) {
/* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
cpsr &= ~PSR_IT_MASK;
} else {
/* We need to shift left ITSTATE<4:0> */
const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */
unsigned long it = cpsr & mask;
it <<= 1;
it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */
it &= mask;
cpsr &= ~mask;
cpsr |= it;
}
return cpsr;
}
static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
{
long cpsr = regs->ARM_cpsr;

View file

@ -66,6 +66,7 @@ ifeq ($(CONFIG_MODULE_SECTIONS),y)
endif
KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax)
# GCC versions that support the "-mstrict-align" option default to allowing
# unaligned accesses. While unaligned accesses are explicitly allowed in the

View file

@ -2,7 +2,7 @@
/*
* Kernel interface for the s390 arch_random_* functions
*
* Copyright IBM Corp. 2017, 2020
* Copyright IBM Corp. 2017, 2022
*
* Author: Harald Freudenberger <freude@de.ibm.com>
*
@ -14,6 +14,7 @@
#ifdef CONFIG_ARCH_RANDOM
#include <linux/static_key.h>
#include <linux/preempt.h>
#include <linux/atomic.h>
#include <asm/cpacf.h>
@ -32,7 +33,8 @@ static inline bool __must_check arch_get_random_int(unsigned int *v)
static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
{
if (static_branch_likely(&s390_arch_random_available)) {
if (static_branch_likely(&s390_arch_random_available) &&
in_task()) {
cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v));
atomic64_add(sizeof(*v), &s390_arch_random_counter);
return true;
@ -42,7 +44,8 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
{
if (static_branch_likely(&s390_arch_random_available)) {
if (static_branch_likely(&s390_arch_random_available) &&
in_task()) {
cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v));
atomic64_add(sizeof(*v), &s390_arch_random_counter);
return true;

View file

@ -283,6 +283,7 @@
#define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */
#define X86_FEATURE_FENCE_SWAPGS_USER (11*32+ 4) /* "" LFENCE in user entry SWAPGS path */
#define X86_FEATURE_FENCE_SWAPGS_KERNEL (11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */
#define X86_FEATURE_RSB_VMEXIT_LITE (11*32+ 6) /* "" Fill RSB on VM exit when EIBRS is enabled */
/* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */
#define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */
@ -395,5 +396,6 @@
#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
#define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */
#define X86_BUG_EIBRS_PBRSB X86_BUG(26) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
#endif /* _ASM_X86_CPUFEATURES_H */

View file

@ -120,6 +120,10 @@
* bit available to control VERW
* behavior.
*/
#define ARCH_CAP_PBRSB_NO BIT(24) /*
* Not susceptible to Post-Barrier
* Return Stack Buffer Predictions.
*/
#define MSR_IA32_FLUSH_CMD 0x0000010b
#define L1D_FLUSH BIT(0) /*

View file

@ -52,7 +52,17 @@
774: \
dec reg; \
jnz 771b; \
add $(BITS_PER_LONG/8) * nr, sp;
add $(BITS_PER_LONG/8) * nr, sp; \
/* barrier for jnz misprediction */ \
lfence;
/* Sequence to mitigate PBRSB on eIBRS CPUs */
#define __ISSUE_UNBALANCED_RET_GUARD(sp) \
call 881f; \
int3; \
881: \
add $(BITS_PER_LONG/8), sp; \
lfence;
#ifdef __ASSEMBLY__
@ -269,6 +279,13 @@ static inline void vmexit_fill_RSB(void)
: "=r" (loops), ASM_CALL_CONSTRAINT
: : "memory" );
#endif
asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE
ALTERNATIVE("jmp 920f",
__stringify(__ISSUE_UNBALANCED_RET_GUARD(%0)),
X86_FEATURE_RSB_VMEXIT_LITE)
"920:"
: ASM_CALL_CONSTRAINT
: : "memory" );
}
static __always_inline

View file

@ -1043,6 +1043,49 @@ static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
return SPECTRE_V2_RETPOLINE;
}
static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode)
{
/*
* Similar to context switches, there are two types of RSB attacks
* after VM exit:
*
* 1) RSB underflow
*
* 2) Poisoned RSB entry
*
* When retpoline is enabled, both are mitigated by filling/clearing
* the RSB.
*
* When IBRS is enabled, while #1 would be mitigated by the IBRS branch
* prediction isolation protections, RSB still needs to be cleared
* because of #2. Note that SMEP provides no protection here, unlike
* user-space-poisoned RSB entries.
*
* eIBRS should protect against RSB poisoning, but if the EIBRS_PBRSB
* bug is present then a LITE version of RSB protection is required,
* just a single call needs to retire before a RET is executed.
*/
switch (mode) {
case SPECTRE_V2_NONE:
/* These modes already fill RSB at vmexit */
case SPECTRE_V2_LFENCE:
case SPECTRE_V2_RETPOLINE:
case SPECTRE_V2_EIBRS_RETPOLINE:
return;
case SPECTRE_V2_EIBRS_LFENCE:
case SPECTRE_V2_EIBRS:
if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE);
pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n");
}
return;
}
pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation at VM exit");
dump_stack();
}
static void __init spectre_v2_select_mitigation(void)
{
enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@ -1135,6 +1178,8 @@ static void __init spectre_v2_select_mitigation(void)
setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n");
spectre_v2_determine_rsb_fill_type_at_vmexit(mode);
/*
* Retpoline means the kernel is safe because it has no indirect
* branches. Enhanced IBRS protects firmware too, so, enable restricted
@ -1867,6 +1912,19 @@ static char *ibpb_state(void)
return "";
}
static char *pbrsb_eibrs_state(void)
{
if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
if (boot_cpu_has(X86_FEATURE_RSB_VMEXIT_LITE) ||
boot_cpu_has(X86_FEATURE_RETPOLINE))
return ", PBRSB-eIBRS: SW sequence";
else
return ", PBRSB-eIBRS: Vulnerable";
} else {
return ", PBRSB-eIBRS: Not affected";
}
}
static ssize_t spectre_v2_show_state(char *buf)
{
if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
@ -1879,12 +1937,13 @@ static ssize_t spectre_v2_show_state(char *buf)
spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
return sprintf(buf, "%s%s%s%s%s%s\n",
return sprintf(buf, "%s%s%s%s%s%s%s\n",
spectre_v2_strings[spectre_v2_enabled],
ibpb_state(),
boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
stibp_state(),
boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
pbrsb_eibrs_state(),
spectre_v2_module_string());
}

View file

@ -954,6 +954,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
#define MSBDS_ONLY BIT(5)
#define NO_SWAPGS BIT(6)
#define NO_ITLB_MULTIHIT BIT(7)
#define NO_EIBRS_PBRSB BIT(8)
#define VULNWL(_vendor, _family, _model, _whitelist) \
{ X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
@ -990,7 +991,7 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
/*
* Technically, swapgs isn't serializing on AMD (despite it previously
@ -1000,7 +1001,9 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
* good enough for our purposes.
*/
VULNWL_INTEL(ATOM_TREMONT_X, NO_ITLB_MULTIHIT),
VULNWL_INTEL(ATOM_TREMONT, NO_EIBRS_PBRSB),
VULNWL_INTEL(ATOM_TREMONT_L, NO_EIBRS_PBRSB),
VULNWL_INTEL(ATOM_TREMONT_X, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
/* AMD Family 0xf - 0x12 */
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT),
@ -1154,6 +1157,11 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
!arch_cap_mmio_immune(ia32_cap))
setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA);
if (cpu_has(c, X86_FEATURE_IBRS_ENHANCED) &&
!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
!(ia32_cap & ARCH_CAP_PBRSB_NO))
setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB);
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
return;

View file

@ -383,6 +383,8 @@ static void __init clear_bss(void)
{
memset(__bss_start, 0,
(unsigned long) __bss_stop - (unsigned long) __bss_start);
memset(__brk_base, 0,
(unsigned long) __brk_limit - (unsigned long) __brk_base);
}
static unsigned long get_cmd_line_ptr(void)

View file

@ -10988,6 +10988,9 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
#endif
);
/* Eliminate branch target predictions from guest mode */
vmexit_fill_RSB();
vmx_enable_fb_clear(vmx);
/*
@ -11010,9 +11013,6 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
x86_spec_ctrl_restore_host(vmx->spec_ctrl, 0);
/* Eliminate branch target predictions from guest mode */
vmexit_fill_RSB();
/* All fields are clean at this point */
if (static_branch_unlikely(&enable_evmcs))
current_evmcs->hv_clean_fields |=

View file

@ -371,23 +371,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
.callback = video_detect_force_native,
.ident = "Clevo NL5xRU",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
},
},
{
.callback = video_detect_force_native,
.ident = "Clevo NL5xRU",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
},
},
{
.callback = video_detect_force_native,
.ident = "Clevo NL5xRU",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
},
},
@ -410,28 +393,60 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
{
.callback = video_detect_force_native,
.ident = "Clevo NL5xNU",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
},
},
/*
* The TongFang PF5PU1G, PF4NU1F, PF5NU1G, and PF5LUXG/TUXEDO BA15 Gen10,
* Pulse 14/15 Gen1, and Pulse 15 Gen2 have the same problem as the Clevo
* NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description
* above.
*/
{
.callback = video_detect_force_native,
.ident = "TongFang PF5PU1G",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "PF5PU1G"),
},
},
{
.callback = video_detect_force_native,
.ident = "TongFang PF4NU1F",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "PF4NU1F"),
},
},
{
.callback = video_detect_force_native,
.ident = "TongFang PF4NU1F",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
DMI_MATCH(DMI_BOARD_NAME, "PULSE1401"),
},
},
{
.callback = video_detect_force_native,
.ident = "Clevo NL5xNU",
.ident = "TongFang PF5NU1G",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
DMI_MATCH(DMI_BOARD_NAME, "PF5NU1G"),
},
},
{
.callback = video_detect_force_native,
.ident = "Clevo NL5xNU",
.ident = "TongFang PF5NU1G",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
DMI_MATCH(DMI_BOARD_NAME, "PULSE1501"),
},
},
{
.callback = video_detect_force_native,
.ident = "TongFang PF5LUXG",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
},
},
/*
* Desktops which falsely report a backlight and which our heuristics
* for this do not catch.

View file

@ -183,8 +183,8 @@ static void __cold process_random_ready_list(void)
#define warn_unseeded_randomness() \
if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \
pr_notice("%s called from %pS with crng_init=%d\n", \
__func__, (void *)_RET_IP_, crng_init)
printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \
__func__, (void *)_RET_IP_, crng_init)
/*********************************************************************

View file

@ -474,6 +474,10 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
if (slew_done_gpio_np)
slew_done_gpio = read_gpio(slew_done_gpio_np);
of_node_put(volt_gpio_np);
of_node_put(freq_gpio_np);
of_node_put(slew_done_gpio_np);
/* If we use the frequency GPIOs, calculate the min/max speeds based
* on the bus frequencies
*/

View file

@ -657,9 +657,6 @@ static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc,
static int tilcdc_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
struct drm_display_mode *mode = &state->mode;
int ret;
/* If we are not active we don't care */
if (!state->active)
return 0;
@ -671,12 +668,6 @@ static int tilcdc_crtc_atomic_check(struct drm_crtc *crtc,
return -EINVAL;
}
ret = tilcdc_crtc_mode_valid(crtc, mode);
if (ret) {
dev_dbg(crtc->dev->dev, "Mode \"%s\" not valid", mode->name);
return -EINVAL;
}
return 0;
}
@ -728,13 +719,6 @@ static const struct drm_crtc_funcs tilcdc_crtc_funcs = {
.disable_vblank = tilcdc_crtc_disable_vblank,
};
static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = {
.mode_fixup = tilcdc_crtc_mode_fixup,
.atomic_check = tilcdc_crtc_atomic_check,
.atomic_enable = tilcdc_crtc_atomic_enable,
.atomic_disable = tilcdc_crtc_atomic_disable,
};
int tilcdc_crtc_max_width(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@ -749,7 +733,9 @@ int tilcdc_crtc_max_width(struct drm_crtc *crtc)
return max_width;
}
int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
static enum drm_mode_status
tilcdc_crtc_mode_valid(struct drm_crtc *crtc,
const struct drm_display_mode *mode)
{
struct tilcdc_drm_private *priv = crtc->dev->dev_private;
unsigned int bandwidth;
@ -837,6 +823,14 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
return MODE_OK;
}
static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = {
.mode_valid = tilcdc_crtc_mode_valid,
.mode_fixup = tilcdc_crtc_mode_fixup,
.atomic_check = tilcdc_crtc_atomic_check,
.atomic_enable = tilcdc_crtc_atomic_enable,
.atomic_disable = tilcdc_crtc_atomic_disable,
};
void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
const struct tilcdc_panel_info *info)
{

View file

@ -202,7 +202,6 @@ static void tilcdc_fini(struct drm_device *dev)
drm_irq_uninstall(dev);
drm_mode_config_cleanup(dev);
tilcdc_remove_external_device(dev);
if (priv->clk)
clk_put(priv->clk);

View file

@ -89,7 +89,6 @@ struct tilcdc_drm_private {
struct drm_encoder *external_encoder;
struct drm_connector *external_connector;
const struct drm_connector_helper_funcs *connector_funcs;
bool is_registered;
bool is_componentized;
@ -171,7 +170,6 @@ void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
const struct tilcdc_panel_info *info);
void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc,
bool simulate_vesa_sync);
int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode);
int tilcdc_crtc_max_width(struct drm_crtc *crtc);
void tilcdc_crtc_shutdown(struct drm_crtc *crtc);
int tilcdc_crtc_update_fb(struct drm_crtc *crtc,

View file

@ -40,64 +40,6 @@ static const struct tilcdc_panel_info panel_info_default = {
.raster_order = 0,
};
static int tilcdc_external_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct tilcdc_drm_private *priv = connector->dev->dev_private;
int ret;
ret = tilcdc_crtc_mode_valid(priv->crtc, mode);
if (ret != MODE_OK)
return ret;
BUG_ON(priv->external_connector != connector);
BUG_ON(!priv->connector_funcs);
/* If the connector has its own mode_valid call it. */
if (!IS_ERR(priv->connector_funcs) &&
priv->connector_funcs->mode_valid)
return priv->connector_funcs->mode_valid(connector, mode);
return MODE_OK;
}
static int tilcdc_add_external_connector(struct drm_device *dev,
struct drm_connector *connector)
{
struct tilcdc_drm_private *priv = dev->dev_private;
struct drm_connector_helper_funcs *connector_funcs;
/* There should never be more than one connector */
if (WARN_ON(priv->external_connector))
return -EINVAL;
priv->external_connector = connector;
connector_funcs = devm_kzalloc(dev->dev, sizeof(*connector_funcs),
GFP_KERNEL);
if (!connector_funcs)
return -ENOMEM;
/* connector->helper_private contains always struct
* connector_helper_funcs pointer. For tilcdc crtc to have a
* say if a specific mode is Ok, we need to install our own
* helper functions. In our helper functions we copy
* everything else but use our own mode_valid() (above).
*/
if (connector->helper_private) {
priv->connector_funcs = connector->helper_private;
*connector_funcs = *priv->connector_funcs;
} else {
priv->connector_funcs = ERR_PTR(-ENOENT);
}
connector_funcs->mode_valid = tilcdc_external_mode_valid;
drm_connector_helper_add(connector, connector_funcs);
dev_dbg(dev->dev, "External connector '%s' connected\n",
connector->name);
return 0;
}
static
struct drm_connector *tilcdc_encoder_find_connector(struct drm_device *ddev,
struct drm_encoder *encoder)
@ -118,40 +60,30 @@ struct drm_connector *tilcdc_encoder_find_connector(struct drm_device *ddev,
int tilcdc_add_component_encoder(struct drm_device *ddev)
{
struct tilcdc_drm_private *priv = ddev->dev_private;
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_encoder *encoder = NULL, *iter;
list_for_each_entry(encoder, &ddev->mode_config.encoder_list, head)
if (encoder->possible_crtcs & (1 << priv->crtc->index))
list_for_each_entry(iter, &ddev->mode_config.encoder_list, head)
if (iter->possible_crtcs & (1 << priv->crtc->index)) {
encoder = iter;
break;
}
if (!encoder) {
dev_err(ddev->dev, "%s: No suitable encoder found\n", __func__);
return -ENODEV;
}
connector = tilcdc_encoder_find_connector(ddev, encoder);
priv->external_connector =
tilcdc_encoder_find_connector(ddev, encoder);
if (!connector)
if (!priv->external_connector)
return -ENODEV;
/* Only tda998x is supported at the moment. */
tilcdc_crtc_set_simulate_vesa_sync(priv->crtc, true);
tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_tda998x);
return tilcdc_add_external_connector(ddev, connector);
}
void tilcdc_remove_external_device(struct drm_device *dev)
{
struct tilcdc_drm_private *priv = dev->dev_private;
/* Restore the original helper functions, if any. */
if (IS_ERR(priv->connector_funcs))
drm_connector_helper_add(priv->external_connector, NULL);
else if (priv->connector_funcs)
drm_connector_helper_add(priv->external_connector,
priv->connector_funcs);
return 0;
}
static const struct drm_encoder_funcs tilcdc_external_encoder_funcs = {
@ -162,7 +94,6 @@ static
int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
{
struct tilcdc_drm_private *priv = ddev->dev_private;
struct drm_connector *connector;
int ret;
priv->external_encoder->possible_crtcs = BIT(0);
@ -175,13 +106,12 @@ int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_default);
connector = tilcdc_encoder_find_connector(ddev, priv->external_encoder);
if (!connector)
priv->external_connector =
tilcdc_encoder_find_connector(ddev, priv->external_encoder);
if (!priv->external_connector)
return -ENODEV;
ret = tilcdc_add_external_connector(ddev, connector);
return ret;
return 0;
}
int tilcdc_attach_external_device(struct drm_device *ddev)

View file

@ -19,7 +19,6 @@
#define __TILCDC_EXTERNAL_H__
int tilcdc_add_component_encoder(struct drm_device *dev);
void tilcdc_remove_external_device(struct drm_device *dev);
int tilcdc_get_external_components(struct device *dev,
struct component_match **match);
int tilcdc_attach_external_device(struct drm_device *ddev);

View file

@ -174,14 +174,6 @@ static int panel_connector_get_modes(struct drm_connector *connector)
return i;
}
static int panel_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct tilcdc_drm_private *priv = connector->dev->dev_private;
/* our only constraints are what the crtc can generate: */
return tilcdc_crtc_mode_valid(priv->crtc, mode);
}
static struct drm_encoder *panel_connector_best_encoder(
struct drm_connector *connector)
{
@ -199,7 +191,6 @@ static const struct drm_connector_funcs panel_connector_funcs = {
static const struct drm_connector_helper_funcs panel_connector_helper_funcs = {
.get_modes = panel_connector_get_modes,
.mode_valid = panel_connector_mode_valid,
.best_encoder = panel_connector_best_encoder,
};

View file

@ -183,14 +183,6 @@ static int tfp410_connector_get_modes(struct drm_connector *connector)
return ret;
}
static int tfp410_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct tilcdc_drm_private *priv = connector->dev->dev_private;
/* our only constraints are what the crtc can generate: */
return tilcdc_crtc_mode_valid(priv->crtc, mode);
}
static struct drm_encoder *tfp410_connector_best_encoder(
struct drm_connector *connector)
{
@ -209,7 +201,6 @@ static const struct drm_connector_funcs tfp410_connector_funcs = {
static const struct drm_connector_helper_funcs tfp410_connector_helper_funcs = {
.get_modes = tfp410_connector_get_modes,
.mode_valid = tfp410_connector_mode_valid,
.best_encoder = tfp410_connector_best_encoder,
};

View file

@ -727,6 +727,8 @@
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085
#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3
#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d
#define USB_VENDOR_ID_LG 0x1fd2
#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064

View file

@ -72,6 +72,7 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_STICKY_FINGERS BIT(16)
#define MT_QUIRK_ASUS_CUSTOM_UP BIT(17)
#define MT_QUIRK_WIN8_PTP_BUTTONS BIT(18)
#define MT_QUIRK_SEPARATE_APP_REPORT BIT(19)
#define MT_INPUTMODE_TOUCHSCREEN 0x02
#define MT_INPUTMODE_TOUCHPAD 0x03
@ -107,6 +108,7 @@ struct mt_usages {
struct mt_application {
struct list_head list;
unsigned int application;
unsigned int report_id;
struct list_head mt_usages; /* mt usages list */
__s32 quirks;
@ -207,6 +209,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
#define MT_CLS_VTL 0x0110
#define MT_CLS_GOOGLE 0x0111
#define MT_CLS_RAZER_BLADE_STEALTH 0x0112
#define MT_CLS_SMART_TECH 0x0113
#define MT_DEFAULT_MAXCONTACT 10
#define MT_MAX_MAXCONTACT 250
@ -357,6 +360,12 @@ static const struct mt_class mt_classes[] = {
MT_QUIRK_CONTACT_CNT_ACCURATE |
MT_QUIRK_WIN8_PTP_BUTTONS,
},
{ .name = MT_CLS_SMART_TECH,
.quirks = MT_QUIRK_ALWAYS_VALID |
MT_QUIRK_IGNORE_DUPLICATES |
MT_QUIRK_CONTACT_CNT_ACCURATE |
MT_QUIRK_SEPARATE_APP_REPORT,
},
{ }
};
@ -513,8 +522,9 @@ static struct mt_usages *mt_allocate_usage(struct hid_device *hdev,
}
static struct mt_application *mt_allocate_application(struct mt_device *td,
unsigned int application)
struct hid_report *report)
{
unsigned int application = report->application;
struct mt_application *mt_application;
mt_application = devm_kzalloc(&td->hdev->dev, sizeof(*mt_application),
@ -539,6 +549,7 @@ static struct mt_application *mt_allocate_application(struct mt_device *td,
mt_application->scantime = DEFAULT_ZERO;
mt_application->raw_cc = DEFAULT_ZERO;
mt_application->quirks = td->mtclass.quirks;
mt_application->report_id = report->id;
list_add_tail(&mt_application->list, &td->applications);
@ -546,19 +557,23 @@ static struct mt_application *mt_allocate_application(struct mt_device *td,
}
static struct mt_application *mt_find_application(struct mt_device *td,
unsigned int application)
struct hid_report *report)
{
unsigned int application = report->application;
struct mt_application *tmp, *mt_application = NULL;
list_for_each_entry(tmp, &td->applications, list) {
if (application == tmp->application) {
mt_application = tmp;
break;
if (!(td->mtclass.quirks & MT_QUIRK_SEPARATE_APP_REPORT) ||
tmp->report_id == report->id) {
mt_application = tmp;
break;
}
}
}
if (!mt_application)
mt_application = mt_allocate_application(td, application);
mt_application = mt_allocate_application(td, report);
return mt_application;
}
@ -575,7 +590,7 @@ static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
return NULL;
rdata->report = report;
rdata->application = mt_find_application(td, report->application);
rdata->application = mt_find_application(td, report);
if (!rdata->application) {
devm_kfree(&td->hdev->dev, rdata);
@ -1332,6 +1347,13 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
return mt_touch_input_mapping(hdev, hi, field, usage, bit, max,
application);
/*
* some egalax touchscreens have "application == DG_TOUCHSCREEN"
* for the stylus. Overwrite the hid_input application
*/
if (field->physical == HID_DG_STYLUS)
hi->application = HID_DG_STYLUS;
/* let hid-core decide for the others */
return 0;
}
@ -1520,14 +1542,12 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
struct mt_device *td = hid_get_drvdata(hdev);
char *name;
const char *suffix = NULL;
unsigned int application = 0;
struct mt_report_data *rdata;
struct mt_application *mt_application = NULL;
struct hid_report *report;
int ret;
list_for_each_entry(report, &hi->reports, hidinput_list) {
application = report->application;
rdata = mt_find_report_data(td, report);
if (!rdata) {
hid_err(hdev, "failed to allocate data for report\n");
@ -1542,46 +1562,36 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
if (ret)
return ret;
}
/*
* some egalax touchscreens have "application == DG_TOUCHSCREEN"
* for the stylus. Check this first, and then rely on
* the application field.
*/
if (report->field[0]->physical == HID_DG_STYLUS) {
suffix = "Pen";
/* force BTN_STYLUS to allow tablet matching in udev */
__set_bit(BTN_STYLUS, hi->input->keybit);
}
}
if (!suffix) {
switch (application) {
case HID_GD_KEYBOARD:
case HID_GD_KEYPAD:
case HID_GD_MOUSE:
case HID_DG_TOUCHPAD:
case HID_GD_SYSTEM_CONTROL:
case HID_CP_CONSUMER_CONTROL:
case HID_GD_WIRELESS_RADIO_CTLS:
case HID_GD_SYSTEM_MULTIAXIS:
/* already handled by hid core */
break;
case HID_DG_TOUCHSCREEN:
/* we do not set suffix = "Touchscreen" */
hi->input->name = hdev->name;
break;
case HID_DG_STYLUS:
/* force BTN_STYLUS to allow tablet matching in udev */
__set_bit(BTN_STYLUS, hi->input->keybit);
break;
case HID_VD_ASUS_CUSTOM_MEDIA_KEYS:
suffix = "Custom Media Keys";
break;
default:
suffix = "UNKNOWN";
break;
}
switch (hi->application) {
case HID_GD_KEYBOARD:
case HID_GD_KEYPAD:
case HID_GD_MOUSE:
case HID_DG_TOUCHPAD:
case HID_GD_SYSTEM_CONTROL:
case HID_CP_CONSUMER_CONTROL:
case HID_GD_WIRELESS_RADIO_CTLS:
case HID_GD_SYSTEM_MULTIAXIS:
/* already handled by hid core */
break;
case HID_DG_TOUCHSCREEN:
/* we do not set suffix = "Touchscreen" */
hi->input->name = hdev->name;
break;
case HID_DG_STYLUS:
/* force BTN_STYLUS to allow tablet matching in udev */
__set_bit(BTN_STYLUS, hi->input->keybit);
break;
case HID_VD_ASUS_CUSTOM_MEDIA_KEYS:
suffix = "Custom Media Keys";
break;
case HID_DG_PEN:
suffix = "Stylus";
break;
default:
suffix = "UNKNOWN";
break;
}
if (suffix) {
@ -1805,6 +1815,12 @@ static const struct hid_device_id mt_devices[] = {
USB_VENDOR_ID_LENOVO,
USB_DEVICE_ID_LENOVO_X1_TAB) },
/* Lenovo X1 TAB Gen 3 */
{ .driver_data = MT_CLS_WIN_8_DUAL,
HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
USB_VENDOR_ID_LENOVO,
USB_DEVICE_ID_LENOVO_X1_TAB3) },
/* Anton devices */
{ .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
MT_USB_DEVICE(USB_VENDOR_ID_ANTON,
@ -2040,6 +2056,10 @@ static const struct hid_device_id mt_devices[] = {
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
USB_VENDOR_ID_SYNAPTICS, 0x8323) },
/* Smart Tech panels */
{ .driver_data = MT_CLS_SMART_TECH,
MT_USB_DEVICE(0x0b8c, 0x0092)},
/* Stantum panels */
{ .driver_data = MT_CLS_CONFIDENCE,
MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,

View file

@ -111,6 +111,7 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET },

View file

@ -203,9 +203,9 @@ static inline bool cdns_is_holdquirk(struct cdns_i2c *id, bool hold_wrkaround)
*/
static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
{
unsigned int isr_status, avail_bytes, updatetx;
unsigned int isr_status, avail_bytes;
unsigned int bytes_to_send;
bool hold_quirk;
bool updatetx;
struct cdns_i2c *id = ptr;
/* Signal completion only after everything is updated */
int done_flag = 0;
@ -224,11 +224,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
* Check if transfer size register needs to be updated again for a
* large data receive operation.
*/
updatetx = 0;
if (id->recv_count > id->curr_recv_count)
updatetx = 1;
hold_quirk = (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx;
updatetx = id->recv_count > id->curr_recv_count;
/* When receiving, handle data interrupt and completion interrupt */
if (id->p_recv_buf &&
@ -251,7 +247,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
id->recv_count--;
id->curr_recv_count--;
if (cdns_is_holdquirk(id, hold_quirk))
if (cdns_is_holdquirk(id, updatetx))
break;
}
@ -262,7 +258,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
* maintain transfer size non-zero while performing a large
* receive operation.
*/
if (cdns_is_holdquirk(id, hold_quirk)) {
if (cdns_is_holdquirk(id, updatetx)) {
/* wait while fifo is full */
while (cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET) !=
(id->curr_recv_count - CDNS_I2C_FIFO_DEPTH))
@ -284,22 +280,6 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
CDNS_I2C_XFER_SIZE_OFFSET);
id->curr_recv_count = id->recv_count;
}
} else if (id->recv_count && !hold_quirk &&
!id->curr_recv_count) {
/* Set the slave address in address register*/
cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK,
CDNS_I2C_ADDR_OFFSET);
if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) {
cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE,
CDNS_I2C_XFER_SIZE_OFFSET);
id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE;
} else {
cdns_i2c_writereg(id->recv_count,
CDNS_I2C_XFER_SIZE_OFFSET);
id->curr_recv_count = id->recv_count;
}
}
/* Clear hold (if not repeated start) and signal completion */

View file

@ -70,7 +70,6 @@ static struct or1k_pic_dev or1k_pic_level = {
.name = "or1k-PIC-level",
.irq_unmask = or1k_pic_unmask,
.irq_mask = or1k_pic_mask,
.irq_mask_ack = or1k_pic_mask_ack,
},
.handle = handle_level_irq,
.flags = IRQ_LEVEL | IRQ_NOPROBE,

View file

@ -645,7 +645,7 @@ do_adb_query(struct adb_request *req)
switch(req->data[1]) {
case ADB_QUERY_GETDEVINFO:
if (req->nbytes < 3)
if (req->nbytes < 3 || req->data[2] >= 16)
break;
mutex_lock(&adb_handler_mutex);
req->reply[0] = adb_handler[req->data[2]].original_address;

View file

@ -1438,8 +1438,6 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
M_CAN_FIFO_DATA(i / 4),
*(u32 *)(cf->data + i));
can_put_echo_skb(skb, dev, 0);
if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
cccr = m_can_read(priv, M_CAN_CCCR);
cccr &= ~(CCCR_CMR_MASK << CCCR_CMR_SHIFT);
@ -1456,6 +1454,9 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
m_can_write(priv, M_CAN_CCCR, cccr);
}
m_can_write(priv, M_CAN_TXBTIE, 0x1);
can_put_echo_skb(skb, dev, 0);
m_can_write(priv, M_CAN_TXBAR, 0x1);
/* End of xmit function for version 3.0.x */
} else {

View file

@ -2291,7 +2291,7 @@ err:
/* Uses sync mcc */
int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
u8 page_num, u8 *data)
u8 page_num, u32 off, u32 len, u8 *data)
{
struct be_dma_mem cmd;
struct be_mcc_wrb *wrb;
@ -2325,10 +2325,10 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
req->port = cpu_to_le32(adapter->hba_port_num);
req->page_num = cpu_to_le32(page_num);
status = be_mcc_notify_wait(adapter);
if (!status) {
if (!status && len > 0) {
struct be_cmd_resp_port_type *resp = cmd.va;
memcpy(data, resp->page_data, PAGE_DATA_LEN);
memcpy(data, resp->page_data + off, len);
}
err:
mutex_unlock(&adapter->mcc_lock);
@ -2419,7 +2419,7 @@ int be_cmd_query_cable_type(struct be_adapter *adapter)
int status;
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
page_data);
0, PAGE_DATA_LEN, page_data);
if (!status) {
switch (adapter->phy.interface_type) {
case PHY_TYPE_QSFP:
@ -2444,7 +2444,7 @@ int be_cmd_query_sfp_info(struct be_adapter *adapter)
int status;
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
page_data);
0, PAGE_DATA_LEN, page_data);
if (!status) {
strlcpy(adapter->phy.vendor_name, page_data +
SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1);

View file

@ -2431,7 +2431,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon,
int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num,
u32 *state);
int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
u8 page_num, u8 *data);
u8 page_num, u32 off, u32 len, u8 *data);
int be_cmd_query_cable_type(struct be_adapter *adapter);
int be_cmd_query_sfp_info(struct be_adapter *adapter);
int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,

View file

@ -1342,7 +1342,7 @@ static int be_get_module_info(struct net_device *netdev,
return -EOPNOTSUPP;
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
page_data);
0, PAGE_DATA_LEN, page_data);
if (!status) {
if (!page_data[SFP_PLUS_SFF_8472_COMP]) {
modinfo->type = ETH_MODULE_SFF_8079;
@ -1360,25 +1360,32 @@ static int be_get_module_eeprom(struct net_device *netdev,
{
struct be_adapter *adapter = netdev_priv(netdev);
int status;
u32 begin, end;
if (!check_privilege(adapter, MAX_PRIVILEGES))
return -EOPNOTSUPP;
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
data);
if (status)
goto err;
begin = eeprom->offset;
end = eeprom->offset + eeprom->len;
if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) {
status = be_cmd_read_port_transceiver_data(adapter,
TR_PAGE_A2,
data +
PAGE_DATA_LEN);
if (begin < PAGE_DATA_LEN) {
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, begin,
min_t(u32, end, PAGE_DATA_LEN) - begin,
data);
if (status)
goto err;
data += PAGE_DATA_LEN - begin;
begin = PAGE_DATA_LEN;
}
if (end > PAGE_DATA_LEN) {
status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A2,
begin - PAGE_DATA_LEN,
end - begin, data);
if (status)
goto err;
}
if (eeprom->offset)
memcpy(data, data + eeprom->offset, eeprom->len);
err:
return be_cmd_status(status);
}

View file

@ -1808,11 +1808,15 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
* non-zero req_queue_pairs says that user requested a new
* queue count via ethtool's set_channels, so use this
* value for queues distribution across traffic classes
* We need at least one queue pair for the interface
* to be usable as we see in else statement.
*/
if (vsi->req_queue_pairs > 0)
vsi->num_queue_pairs = vsi->req_queue_pairs;
else if (pf->flags & I40E_FLAG_MSIX_ENABLED)
vsi->num_queue_pairs = pf->num_lan_msix;
else
vsi->num_queue_pairs = 1;
}
/* Number of queues per enabled TC */

View file

@ -2059,7 +2059,10 @@ static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx)
efx_update_sw_stats(efx, stats);
out:
/* releasing a DMA coherent buffer with BH disabled can panic */
spin_unlock_bh(&efx->stats_lock);
efx_nic_free_buffer(efx, &stats_buf);
spin_lock_bh(&efx->stats_lock);
return rc;
}

View file

@ -415,8 +415,9 @@ fail1:
static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force)
{
struct pci_dev *dev = efx->pci_dev;
struct efx_ef10_nic_data *nic_data = efx->nic_data;
unsigned int vfs_assigned = pci_vfs_assigned(dev);
int rc = 0;
int i, rc = 0;
if (vfs_assigned && !force) {
netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; "
@ -424,10 +425,13 @@ static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force)
return -EBUSY;
}
if (!vfs_assigned)
if (!vfs_assigned) {
for (i = 0; i < efx->vf_count; i++)
nic_data->vf[i].pci_dev = NULL;
pci_disable_sriov(dev);
else
} else {
rc = -EBUSY;
}
efx_ef10_sriov_free_vf_vswitching(efx);
efx->vf_count = 0;

View file

@ -222,6 +222,9 @@ static void dwmac4_map_mtl_dma(struct mac_device_info *hw, u32 queue, u32 chan)
if (queue == 0 || queue == 4) {
value &= ~MTL_RXQ_DMA_Q04MDMACH_MASK;
value |= MTL_RXQ_DMA_Q04MDMACH(chan);
} else if (queue > 4) {
value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue - 4);
value |= MTL_RXQ_DMA_QXMDMACH(chan, queue - 4);
} else {
value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue);
value |= MTL_RXQ_DMA_QXMDMACH(chan, queue);

View file

@ -1811,7 +1811,7 @@ static int sfp_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sfp);
err = devm_add_action(sfp->dev, sfp_cleanup, sfp);
err = devm_add_action_or_reset(sfp->dev, sfp_cleanup, sfp);
if (err < 0)
return err;

View file

@ -453,6 +453,7 @@ static int bcm5421_init(struct mii_phy* phy)
int can_low_power = 1;
if (np == NULL || of_get_property(np, "no-autolowpower", NULL))
can_low_power = 0;
of_node_put(np);
if (can_low_power) {
/* Enable automatic low-power */
sungem_phy_write(phy, 0x1c, 0x9002);

View file

@ -1974,7 +1974,7 @@ static const struct driver_info ax88179_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@ -1987,7 +1987,7 @@ static const struct driver_info ax88178a_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@ -2000,7 +2000,7 @@ static const struct driver_info cypress_GX3_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@ -2013,7 +2013,7 @@ static const struct driver_info dlink_dub1312_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@ -2026,7 +2026,7 @@ static const struct driver_info sitecom_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@ -2039,7 +2039,7 @@ static const struct driver_info samsung_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@ -2052,7 +2052,7 @@ static const struct driver_info lenovo_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};
@ -2065,7 +2065,7 @@ static const struct driver_info belkin_info = {
.link_reset = ax88179_link_reset,
.reset = ax88179_reset,
.stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
};

View file

@ -34,6 +34,7 @@ static const struct usb_device_id mt7601u_device_table[] = {
{ USB_DEVICE(0x2717, 0x4106) },
{ USB_DEVICE(0x2955, 0x0001) },
{ USB_DEVICE(0x2955, 0x1001) },
{ USB_DEVICE(0x2955, 0x1003) },
{ USB_DEVICE(0x2a5f, 0x1000) },
{ USB_DEVICE(0x7392, 0x7710) },
{ 0, }

View file

@ -482,6 +482,7 @@ void xenvif_rx_action(struct xenvif_queue *queue)
queue->rx_copy.completed = &completed_skbs;
while (xenvif_rx_ring_slots_available(queue) &&
!skb_queue_empty(&queue->rx_queue) &&
work_done < RX_BATCH_SIZE) {
xenvif_rx_skb(queue);
work_done++;

View file

@ -138,7 +138,9 @@ static int nxp_nci_i2c_fw_read(struct nxp_nci_i2c_phy *phy,
skb_put_data(*skb, &header, NXP_NCI_FW_HDR_LEN);
r = i2c_master_recv(client, skb_put(*skb, frame_len), frame_len);
if (r != frame_len) {
if (r < 0) {
goto fw_read_exit_free_skb;
} else if (r != frame_len) {
nfc_err(&client->dev,
"Invalid frame length: %u (expected %zu)\n",
r, frame_len);
@ -182,7 +184,9 @@ static int nxp_nci_i2c_nci_read(struct nxp_nci_i2c_phy *phy,
return 0;
r = i2c_master_recv(client, skb_put(*skb, header.plen), header.plen);
if (r != header.plen) {
if (r < 0) {
goto nci_read_exit_free_skb;
} else if (r != header.plen) {
nfc_err(&client->dev,
"Invalid frame payload length: %u (expected %u)\n",
r, header.plen);

View file

@ -831,6 +831,10 @@ static void hv_int_desc_free(struct hv_pci_dev *hpdev,
u8 buffer[sizeof(struct pci_delete_interrupt)];
} ctxt;
if (!int_desc->vector_count) {
kfree(int_desc);
return;
}
memset(&ctxt, 0, sizeof(ctxt));
int_pkt = (struct pci_delete_interrupt *)&ctxt.pkt.message;
int_pkt->message_type.type =
@ -893,6 +897,28 @@ static void hv_irq_mask(struct irq_data *data)
pci_msi_mask_irq(data);
}
static unsigned int hv_msi_get_int_vector(struct irq_data *data)
{
struct irq_cfg *cfg = irqd_cfg(data);
return cfg->vector;
}
static int hv_msi_prepare(struct irq_domain *domain, struct device *dev,
int nvec, msi_alloc_info_t *info)
{
int ret = pci_msi_prepare(domain, dev, nvec, info);
/*
* By using the interrupt remapper in the hypervisor IOMMU, contiguous
* CPU vectors is not needed for multi-MSI
*/
if (info->type == X86_IRQ_ALLOC_TYPE_MSI)
info->flags &= ~X86_IRQ_ALLOC_CONTIGUOUS_VECTORS;
return ret;
}
/**
* hv_irq_unmask() - "Unmask" the IRQ by setting its current
* affinity.
@ -908,6 +934,7 @@ static void hv_irq_unmask(struct irq_data *data)
struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
struct irq_cfg *cfg = irqd_cfg(data);
struct retarget_msi_interrupt *params;
struct tran_int_desc *int_desc;
struct hv_pcibus_device *hbus;
struct cpumask *dest;
struct pci_bus *pbus;
@ -922,6 +949,7 @@ static void hv_irq_unmask(struct irq_data *data)
pdev = msi_desc_to_pci_dev(msi_desc);
pbus = pdev->bus;
hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
int_desc = data->chip_data;
spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags);
@ -929,8 +957,8 @@ static void hv_irq_unmask(struct irq_data *data)
memset(params, 0, sizeof(*params));
params->partition_id = HV_PARTITION_ID_SELF;
params->int_entry.source = 1; /* MSI(-X) */
params->int_entry.address = msi_desc->msg.address_lo;
params->int_entry.data = msi_desc->msg.data;
params->int_entry.address = int_desc->address & 0xffffffff;
params->int_entry.data = int_desc->data;
params->device_id = (hbus->hdev->dev_instance.b[5] << 24) |
(hbus->hdev->dev_instance.b[4] << 16) |
(hbus->hdev->dev_instance.b[7] << 8) |
@ -1018,12 +1046,12 @@ static void hv_pci_compose_compl(void *context, struct pci_response *resp,
static u32 hv_compose_msi_req_v1(
struct pci_create_interrupt *int_pkt, struct cpumask *affinity,
u32 slot, u8 vector)
u32 slot, u8 vector, u8 vector_count)
{
int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
int_pkt->wslot.slot = slot;
int_pkt->int_desc.vector = vector;
int_pkt->int_desc.vector_count = 1;
int_pkt->int_desc.vector_count = vector_count;
int_pkt->int_desc.delivery_mode = dest_Fixed;
/*
@ -1037,14 +1065,14 @@ static u32 hv_compose_msi_req_v1(
static u32 hv_compose_msi_req_v2(
struct pci_create_interrupt2 *int_pkt, struct cpumask *affinity,
u32 slot, u8 vector)
u32 slot, u8 vector, u8 vector_count)
{
int cpu;
int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE2;
int_pkt->wslot.slot = slot;
int_pkt->int_desc.vector = vector;
int_pkt->int_desc.vector_count = 1;
int_pkt->int_desc.vector_count = vector_count;
int_pkt->int_desc.delivery_mode = dest_Fixed;
/*
@ -1072,7 +1100,6 @@ static u32 hv_compose_msi_req_v2(
*/
static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
{
struct irq_cfg *cfg = irqd_cfg(data);
struct hv_pcibus_device *hbus;
struct hv_pci_dev *hpdev;
struct pci_bus *pbus;
@ -1081,6 +1108,8 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
unsigned long flags;
struct compose_comp_ctxt comp;
struct tran_int_desc *int_desc;
struct msi_desc *msi_desc;
u8 vector, vector_count;
struct {
struct pci_packet pci_pkt;
union {
@ -1092,7 +1121,17 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
u32 size;
int ret;
pdev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data));
/* Reuse the previous allocation */
if (data->chip_data) {
int_desc = data->chip_data;
msg->address_hi = int_desc->address >> 32;
msg->address_lo = int_desc->address & 0xffffffff;
msg->data = int_desc->data;
return;
}
msi_desc = irq_data_get_msi_desc(data);
pdev = msi_desc_to_pci_dev(msi_desc);
dest = irq_data_get_effective_affinity_mask(data);
pbus = pdev->bus;
hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
@ -1100,17 +1139,40 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
if (!hpdev)
goto return_null_message;
/* Free any previous message that might have already been composed. */
if (data->chip_data) {
int_desc = data->chip_data;
data->chip_data = NULL;
hv_int_desc_free(hpdev, int_desc);
}
int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC);
if (!int_desc)
goto drop_reference;
if (!msi_desc->msi_attrib.is_msix && msi_desc->nvec_used > 1) {
/*
* If this is not the first MSI of Multi MSI, we already have
* a mapping. Can exit early.
*/
if (msi_desc->irq != data->irq) {
data->chip_data = int_desc;
int_desc->address = msi_desc->msg.address_lo |
(u64)msi_desc->msg.address_hi << 32;
int_desc->data = msi_desc->msg.data +
(data->irq - msi_desc->irq);
msg->address_hi = msi_desc->msg.address_hi;
msg->address_lo = msi_desc->msg.address_lo;
msg->data = int_desc->data;
put_pcichild(hpdev);
return;
}
/*
* The vector we select here is a dummy value. The correct
* value gets sent to the hypervisor in unmask(). This needs
* to be aligned with the count, and also not zero. Multi-msi
* is powers of 2 up to 32, so 32 will always work here.
*/
vector = 32;
vector_count = msi_desc->nvec_used;
} else {
vector = hv_msi_get_int_vector(data);
vector_count = 1;
}
memset(&ctxt, 0, sizeof(ctxt));
init_completion(&comp.comp_pkt.host_event);
ctxt.pci_pkt.completion_func = hv_pci_compose_compl;
@ -1121,14 +1183,16 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
dest,
hpdev->desc.win_slot.slot,
cfg->vector);
vector,
vector_count);
break;
case PCI_PROTOCOL_VERSION_1_2:
size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
dest,
hpdev->desc.win_slot.slot,
cfg->vector);
vector,
vector_count);
break;
default:
@ -1240,7 +1304,7 @@ static irq_hw_number_t hv_msi_domain_ops_get_hwirq(struct msi_domain_info *info,
static struct msi_domain_ops hv_msi_ops = {
.get_hwirq = hv_msi_domain_ops_get_hwirq,
.msi_prepare = pci_msi_prepare,
.msi_prepare = hv_msi_prepare,
.set_desc = pci_msi_set_desc,
.msi_free = hv_msi_free,
};

View file

@ -75,6 +75,7 @@ enum hp_wmi_event_ids {
HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D,
HPWMI_PEAKSHIFT_PERIOD = 0x0F,
HPWMI_BATTERY_CHARGE_PERIOD = 0x10,
HPWMI_SANITIZATION_MODE = 0x17,
};
struct bios_args {
@ -631,6 +632,8 @@ static void hp_wmi_notify(u32 value, void *context)
break;
case HPWMI_BATTERY_CHARGE_PERIOD:
break;
case HPWMI_SANITIZATION_MODE:
break;
default:
pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
break;

View file

@ -150,6 +150,7 @@ static int __init versatile_reboot_probe(void)
versatile_reboot_type = (enum versatile_reboot)reboot_id->data;
syscon_regmap = syscon_node_to_regmap(np);
of_node_put(np);
if (IS_ERR(syscon_regmap))
return PTR_ERR(syscon_regmap);

View file

@ -56,7 +56,7 @@ static inline void
kbd_put_queue(struct tty_port *port, int ch)
{
tty_insert_flip_char(port, ch, 0);
tty_schedule_flip(port);
tty_flip_buffer_push(port);
}
static inline void
@ -64,5 +64,5 @@ kbd_puts_queue(struct tty_port *port, char *cp)
{
while (*cp)
tty_insert_flip_char(port, *cp++, 0);
tty_schedule_flip(port);
tty_flip_buffer_push(port);
}

View file

@ -2161,8 +2161,7 @@ out_put_budget:
case BLK_STS_OK:
break;
case BLK_STS_RESOURCE:
if (atomic_read(&sdev->device_busy) ||
scsi_device_blocked(sdev))
if (scsi_device_blocked(sdev))
ret = BLK_STS_DEV_RESOURCE;
break;
default:

View file

@ -149,9 +149,20 @@ out:
return ret;
}
static bool phandle_exists(const struct device_node *np,
const char *phandle_name, int index)
{
struct device_node *parse_np = of_parse_phandle(np, phandle_name, index);
if (parse_np)
of_node_put(parse_np);
return parse_np != NULL;
}
#define MAX_PROP_SIZE 32
static int ufshcd_populate_vreg(struct device *dev, const char *name,
struct ufs_vreg **out_vreg)
struct ufs_vreg **out_vreg)
{
int len, ret = 0;
char prop_name[MAX_PROP_SIZE];
@ -166,7 +177,7 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name,
}
snprintf(prop_name, MAX_PROP_SIZE, "%s-supply", name);
if (!of_parse_phandle(np, prop_name, 0)) {
if (!phandle_exists(np, prop_name, 0)) {
dev_info(dev, "%s: Unable to find %s regulator, assuming enabled\n",
__func__, prop_name);
goto out;

View file

@ -267,6 +267,8 @@ static int rt2880_pinmux_pins(struct rt2880_priv *p)
p->func[i]->pin_count,
sizeof(int),
GFP_KERNEL);
if (!p->func[i]->pins)
return -ENOMEM;
for (j = 0; j < p->func[i]->pin_count; j++)
p->func[i]->pins[j] = p->func[i]->pin_first + j;

View file

@ -88,7 +88,7 @@ static int spk_ttyio_receive_buf2(struct tty_struct *tty,
}
if (!ldisc_data->buf_free)
/* ttyio_in will tty_schedule_flip */
/* ttyio_in will tty_flip_buffer_push */
return 0;
/* Make sure the consumer has read buf before we have seen
@ -321,7 +321,7 @@ static unsigned char ttyio_in(int timeout)
mb();
ldisc_data->buf_free = true;
/* Let TTY push more characters */
tty_schedule_flip(speakup_tty->port);
tty_flip_buffer_push(speakup_tty->port);
return rv;
}

View file

@ -556,7 +556,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
}
info->idle_stats.recv_idle = jiffies;
}
tty_schedule_flip(port);
tty_flip_buffer_push(port);
/* end of service */
cyy_writeb(info, CyRIR, save_xir & 0x3f);
@ -996,7 +996,7 @@ static void cyz_handle_rx(struct cyclades_port *info)
mod_timer(&info->rx_full_timer, jiffies + 1);
#endif
info->idle_stats.recv_idle = jiffies;
tty_schedule_flip(&info->port);
tty_flip_buffer_push(&info->port);
/* Update rx_get */
cy_writel(&buf_ctrl->rx_get, new_rx_get);
@ -1172,7 +1172,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
if (delta_count)
wake_up_interruptible(&info->port.delta_msr_wait);
if (special_count)
tty_schedule_flip(&info->port);
tty_flip_buffer_push(&info->port);
}
}

View file

@ -151,7 +151,7 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id)
address = (unsigned long)(void *)buf;
goldfish_tty_rw(qtty, address, count, 0);
tty_schedule_flip(&qtty->port);
tty_flip_buffer_push(&qtty->port);
return IRQ_HANDLED;
}

View file

@ -1393,7 +1393,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
if (inited && !tty_throttled(tty) &&
MoxaPortRxQueue(p) > 0) { /* RX */
MoxaPortReadData(p);
tty_schedule_flip(&p->port);
tty_flip_buffer_push(&p->port);
}
} else {
clear_bit(EMPTYWAIT, &p->statusflags);
@ -1418,7 +1418,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
tty_insert_flip_char(&p->port, 0, TTY_BREAK);
tty_schedule_flip(&p->port);
tty_flip_buffer_push(&p->port);
}
if (intr & IntrLine)

View file

@ -111,21 +111,11 @@ static void pty_unthrottle(struct tty_struct *tty)
static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
{
struct tty_struct *to = tty->link;
unsigned long flags;
if (tty->stopped)
if (tty->stopped || !c)
return 0;
if (c > 0) {
spin_lock_irqsave(&to->port->lock, flags);
/* Stuff the data into the input queue of the other end */
c = tty_insert_flip_string(to->port, buf, c);
spin_unlock_irqrestore(&to->port->lock, flags);
/* And shovel */
if (c)
tty_flip_buffer_push(to->port);
}
return c;
return tty_insert_flip_string_and_push_buffer(to->port, buf, c);
}
/**

View file

@ -2917,8 +2917,10 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
case UPIO_MEM32BE:
case UPIO_MEM16:
case UPIO_MEM:
if (!port->mapbase)
if (!port->mapbase) {
ret = -EINVAL;
break;
}
if (!request_mem_region(port->mapbase, size, "serial")) {
ret = -EBUSY;

View file

@ -1335,6 +1335,15 @@ static void pl011_stop_rx(struct uart_port *port)
pl011_dma_rx_stop(uap);
}
static void pl011_throttle_rx(struct uart_port *port)
{
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
pl011_stop_rx(port);
spin_unlock_irqrestore(&port->lock, flags);
}
static void pl011_enable_ms(struct uart_port *port)
{
struct uart_amba_port *uap =
@ -1728,9 +1737,10 @@ static int pl011_allocate_irq(struct uart_amba_port *uap)
*/
static void pl011_enable_interrupts(struct uart_amba_port *uap)
{
unsigned long flags;
unsigned int i;
spin_lock_irq(&uap->port.lock);
spin_lock_irqsave(&uap->port.lock, flags);
/* Clear out any spuriously appearing RX interrupts */
pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
@ -1752,7 +1762,14 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
if (!pl011_dma_rx_running(uap))
uap->im |= UART011_RXIM;
pl011_write(uap->im, uap, REG_IMSC);
spin_unlock_irq(&uap->port.lock);
spin_unlock_irqrestore(&uap->port.lock, flags);
}
static void pl011_unthrottle_rx(struct uart_port *port)
{
struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
pl011_enable_interrupts(uap);
}
static int pl011_startup(struct uart_port *port)
@ -2127,6 +2144,8 @@ static const struct uart_ops amba_pl011_pops = {
.stop_tx = pl011_stop_tx,
.start_tx = pl011_start_tx,
.stop_rx = pl011_stop_rx,
.throttle = pl011_throttle_rx,
.unthrottle = pl011_unthrottle_rx,
.enable_ms = pl011_enable_ms,
.break_ctl = pl011_break_ctl,
.startup = pl011_startup,

View file

@ -341,7 +341,7 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id)
LPC32XX_HSUART_IIR(port->membase));
port->icount.overrun++;
tty_insert_flip_char(tport, 0, TTY_OVERRUN);
tty_schedule_flip(tport);
tty_flip_buffer_push(tport);
}
/* Data received? */

View file

@ -442,14 +442,14 @@ static void mvebu_uart_shutdown(struct uart_port *port)
}
}
static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
static unsigned int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
{
struct mvebu_uart *mvuart = to_mvuart(port);
unsigned int d_divisor, m_divisor;
u32 brdv;
if (IS_ERR(mvuart->clk))
return -PTR_ERR(mvuart->clk);
return 0;
/*
* The baudrate is derived from the UART clock thanks to two divisors:
@ -469,7 +469,7 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
brdv |= d_divisor;
writel(brdv, port->membase + UART_BRDV);
return 0;
return DIV_ROUND_CLOSEST(port->uartclk, d_divisor * m_divisor);
}
static void mvebu_uart_set_termios(struct uart_port *port,
@ -506,15 +506,11 @@ static void mvebu_uart_set_termios(struct uart_port *port,
max_baud = 230400;
baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud);
if (mvebu_uart_baud_rate_set(port, baud)) {
/* No clock available, baudrate cannot be changed */
if (old)
baud = uart_get_baud_rate(port, old, NULL,
min_baud, max_baud);
} else {
tty_termios_encode_baud_rate(termios, baud, baud);
uart_update_timeout(port, termios->c_cflag, baud);
}
baud = mvebu_uart_baud_rate_set(port, baud);
/* In case baudrate cannot be changed, report previous old value */
if (baud == 0 && old)
baud = tty_termios_baud_rate(old);
/* Only the following flag changes are supported */
if (old) {
@ -525,6 +521,11 @@ static void mvebu_uart_set_termios(struct uart_port *port,
termios->c_cflag |= CS8;
}
if (baud != 0) {
tty_termios_encode_baud_rate(termios, baud, baud);
uart_update_timeout(port, termios->c_cflag, baud);
}
spin_unlock_irqrestore(&port->lock, flags);
}

View file

@ -238,8 +238,7 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
/* Enable tx dma mode */
ucon = rd_regl(port, S3C2410_UCON);
ucon &= ~(S3C64XX_UCON_TXBURST_MASK | S3C64XX_UCON_TXMODE_MASK);
ucon |= (dma_get_cache_alignment() >= 16) ?
S3C64XX_UCON_TXBURST_16 : S3C64XX_UCON_TXBURST_1;
ucon |= S3C64XX_UCON_TXBURST_1;
ucon |= S3C64XX_UCON_TXMODE_DMA;
wr_regl(port, S3C2410_UCON, ucon);
@ -512,7 +511,7 @@ static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
S3C64XX_UCON_DMASUS_EN |
S3C64XX_UCON_TIMEOUT_EN |
S3C64XX_UCON_RXMODE_MASK);
ucon |= S3C64XX_UCON_RXBURST_16 |
ucon |= S3C64XX_UCON_RXBURST_1 |
0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
S3C64XX_UCON_EMPTYINT_EN |
S3C64XX_UCON_TIMEOUT_EN |

View file

@ -72,6 +72,8 @@ static void stm32_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE,
*cr3 |= USART_CR3_DEM;
over8 = *cr1 & USART_CR1_OVER8;
*cr1 &= ~(USART_CR1_DEDT_MASK | USART_CR1_DEAT_MASK);
if (over8)
rs485_deat_dedt = delay_ADE * baud * 8;
else

View file

@ -389,27 +389,6 @@ int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag)
}
EXPORT_SYMBOL(__tty_insert_flip_char);
/**
* tty_schedule_flip - push characters to ldisc
* @port: tty port to push from
*
* Takes any pending buffers and transfers their ownership to the
* ldisc side of the queue. It then schedules those characters for
* processing by the line discipline.
*/
void tty_schedule_flip(struct tty_port *port)
{
struct tty_bufhead *buf = &port->buf;
/* paired w/ acquire in flush_to_ldisc(); ensures
* flush_to_ldisc() sees buffer data.
*/
smp_store_release(&buf->tail->commit, buf->tail->used);
queue_work(system_unbound_wq, &buf->work);
}
EXPORT_SYMBOL(tty_schedule_flip);
/**
* tty_prepare_flip_string - make room for characters
* @port: tty port
@ -539,6 +518,15 @@ static void flush_to_ldisc(struct work_struct *work)
}
static inline void tty_flip_buffer_commit(struct tty_buffer *tail)
{
/*
* Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees
* buffer data.
*/
smp_store_release(&tail->commit, tail->used);
}
/**
* tty_flip_buffer_push - terminal
* @port: tty port to push
@ -552,10 +540,44 @@ static void flush_to_ldisc(struct work_struct *work)
void tty_flip_buffer_push(struct tty_port *port)
{
tty_schedule_flip(port);
struct tty_bufhead *buf = &port->buf;
tty_flip_buffer_commit(buf->tail);
queue_work(system_unbound_wq, &buf->work);
}
EXPORT_SYMBOL(tty_flip_buffer_push);
/**
* tty_insert_flip_string_and_push_buffer - add characters to the tty buffer and
* push
* @port: tty port
* @chars: characters
* @size: size
*
* The function combines tty_insert_flip_string() and tty_flip_buffer_push()
* with the exception of properly holding the @port->lock.
*
* To be used only internally (by pty currently).
*
* Returns: the number added.
*/
int tty_insert_flip_string_and_push_buffer(struct tty_port *port,
const unsigned char *chars, size_t size)
{
struct tty_bufhead *buf = &port->buf;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
size = tty_insert_flip_string(port, chars, size);
if (size)
tty_flip_buffer_commit(buf->tail);
spin_unlock_irqrestore(&port->lock, flags);
queue_work(system_unbound_wq, &buf->work);
return size;
}
/**
* tty_buffer_init - prepare a tty buffer structure
* @tty: tty to initialise

View file

@ -310,7 +310,7 @@ int kbd_rate(struct kbd_repeat *rpt)
static void put_queue(struct vc_data *vc, int ch)
{
tty_insert_flip_char(&vc->port, ch, 0);
tty_schedule_flip(&vc->port);
tty_flip_buffer_push(&vc->port);
}
static void puts_queue(struct vc_data *vc, char *cp)
@ -319,7 +319,7 @@ static void puts_queue(struct vc_data *vc, char *cp)
tty_insert_flip_char(&vc->port, *cp, 0);
cp++;
}
tty_schedule_flip(&vc->port);
tty_flip_buffer_push(&vc->port);
}
static void applkey(struct vc_data *vc, int key, char mode)
@ -564,7 +564,7 @@ static void fn_inc_console(struct vc_data *vc)
static void fn_send_intr(struct vc_data *vc)
{
tty_insert_flip_char(&vc->port, 0, TTY_BREAK);
tty_schedule_flip(&vc->port);
tty_flip_buffer_push(&vc->port);
}
static void fn_scroll_forw(struct vc_data *vc)

View file

@ -1838,7 +1838,7 @@ static void respond_string(const char *p, struct tty_port *port)
tty_insert_flip_char(port, *p, 0);
p++;
}
tty_schedule_flip(port);
tty_flip_buffer_push(port);
}
static void cursor_report(struct vc_data *vc, struct tty_struct *tty)

View file

@ -4137,7 +4137,6 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
dwc->bh_handled_evt_cnt[dwc->irq_dbg_index] += (evt->count / 4);
evt->count = 0;
evt->flags &= ~DWC3_EVENT_PENDING;
ret = IRQ_HANDLED;
/* Unmask interrupt */
@ -4150,6 +4149,9 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
}
/* Keep the clearing of DWC3_EVENT_PENDING at the end */
evt->flags &= ~DWC3_EVENT_PENDING;
return ret;
}

View file

@ -1013,6 +1013,9 @@ static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) },
{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) },
{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) },
/* Belimo Automation devices */
{ USB_DEVICE(FTDI_VID, BELIMO_ZTH_PID) },
{ USB_DEVICE(FTDI_VID, BELIMO_ZIP_PID) },
/* ICP DAS I-756xU devices */
{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) },
{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },

View file

@ -1568,6 +1568,12 @@
#define CHETCO_SEASMART_LITE_PID 0xA5AE /* SeaSmart Lite USB Adapter */
#define CHETCO_SEASMART_ANALOG_PID 0xA5AF /* SeaSmart Analog Adapter */
/*
* Belimo Automation
*/
#define BELIMO_ZTH_PID 0x8050
#define BELIMO_ZIP_PID 0xC811
/*
* Unjo AB
*/

View file

@ -1396,6 +1396,7 @@ void typec_set_pwr_opmode(struct typec_port *port,
partner->usb_pd = 1;
sysfs_notify(&partner_dev->kobj, NULL,
"supports_usb_power_delivery");
kobject_uevent(&partner_dev->kobj, KOBJ_CHANGE);
}
put_device(partner_dev);
}

View file

@ -66,6 +66,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/virtio.h>
@ -508,6 +509,28 @@ static const struct virtio_config_ops virtio_mmio_config_ops = {
.bus_name = vm_bus_name,
};
#ifdef CONFIG_PM_SLEEP
static int virtio_mmio_freeze(struct device *dev)
{
struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
return virtio_device_freeze(&vm_dev->vdev);
}
static int virtio_mmio_restore(struct device *dev)
{
struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
if (vm_dev->version == 1)
writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
return virtio_device_restore(&vm_dev->vdev);
}
static const struct dev_pm_ops virtio_mmio_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(virtio_mmio_freeze, virtio_mmio_restore)
};
#endif
static void virtio_mmio_release_dev(struct device *_d)
{
@ -761,6 +784,9 @@ static struct platform_driver virtio_mmio_driver = {
.name = "virtio-mmio",
.of_match_table = virtio_mmio_match,
.acpi_match_table = ACPI_PTR(virtio_mmio_acpi_match),
#ifdef CONFIG_PM_SLEEP
.pm = &virtio_mmio_pm_ops,
#endif
},
};

View file

@ -416,7 +416,8 @@ static void __unmap_grant_pages_done(int result,
unsigned int offset = data->unmap_ops - map->unmap_ops;
for (i = 0; i < data->count; i++) {
WARN_ON(map->unmap_ops[offset+i].status);
WARN_ON(map->unmap_ops[offset+i].status &&
map->unmap_ops[offset+i].handle != -1);
pr_debug("unmap handle=%d st=%d\n",
map->unmap_ops[offset+i].handle,
map->unmap_ops[offset+i].status);

View file

@ -4069,13 +4069,14 @@ static void send_repeat_remove(struct dlm_ls *ls, char *ms_name, int len)
rv = _create_message(ls, sizeof(struct dlm_message) + len,
dir_nodeid, DLM_MSG_REMOVE, &ms, &mh);
if (rv)
return;
goto out;
memcpy(ms->m_extra, name, len);
ms->m_hash = hash;
send_message(mh, ms);
out:
spin_lock(&ls->ls_remove_spin);
ls->ls_remove_len = 0;
memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN);

View file

@ -198,6 +198,9 @@ static inline int nilfs_acl_chmod(struct inode *inode)
static inline int nilfs_init_acl(struct inode *inode, struct inode *dir)
{
if (S_ISLNK(inode->i_mode))
return 0;
inode->i_mode &= ~current_umask();
return 0;
}

View file

@ -606,8 +606,12 @@ static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
a = (ATTR_RECORD*)((u8*)ctx->attr +
le32_to_cpu(ctx->attr->length));
for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) {
if ((u8*)a < (u8*)ctx->mrec || (u8*)a > (u8*)ctx->mrec +
le32_to_cpu(ctx->mrec->bytes_allocated))
u8 *mrec_end = (u8 *)ctx->mrec +
le32_to_cpu(ctx->mrec->bytes_allocated);
u8 *name_end = (u8 *)a + le16_to_cpu(a->name_offset) +
a->name_length * sizeof(ntfschar);
if ((u8*)a < (u8*)ctx->mrec || (u8*)a > mrec_end ||
name_end > mrec_end)
break;
ctx->attr = a;
if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) ||

View file

@ -12,7 +12,6 @@ extern int tty_insert_flip_string_fixed_flag(struct tty_port *port,
extern int tty_prepare_flip_string(struct tty_port *port,
unsigned char **chars, size_t size);
extern void tty_flip_buffer_push(struct tty_port *port);
void tty_schedule_flip(struct tty_port *port);
int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag);
static inline int tty_insert_flip_char(struct tty_port *port,
@ -40,4 +39,7 @@ static inline int tty_insert_flip_string(struct tty_port *port,
extern void tty_buffer_lock_exclusive(struct tty_port *port);
extern void tty_buffer_unlock_exclusive(struct tty_port *port);
int tty_insert_flip_string_and_push_buffer(struct tty_port *port,
const unsigned char *chars, size_t cnt);
#endif /* _LINUX_TTY_FLIP_H */

View file

@ -370,6 +370,71 @@ out:
return NULL;
}
/* Shall not be called with lock_sock held */
static inline struct sk_buff *bt_skb_sendmsg(struct sock *sk,
struct msghdr *msg,
size_t len, size_t mtu,
size_t headroom, size_t tailroom)
{
struct sk_buff *skb;
size_t size = min_t(size_t, len, mtu);
int err;
skb = bt_skb_send_alloc(sk, size + headroom + tailroom,
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
return ERR_PTR(err);
skb_reserve(skb, headroom);
skb_tailroom_reserve(skb, mtu, tailroom);
if (!copy_from_iter_full(skb_put(skb, size), size, &msg->msg_iter)) {
kfree_skb(skb);
return ERR_PTR(-EFAULT);
}
skb->priority = sk->sk_priority;
return skb;
}
/* Similar to bt_skb_sendmsg but can split the msg into multiple fragments
* accourding to the MTU.
*/
static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk,
struct msghdr *msg,
size_t len, size_t mtu,
size_t headroom, size_t tailroom)
{
struct sk_buff *skb, **frag;
skb = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom);
if (IS_ERR_OR_NULL(skb))
return skb;
len -= skb->len;
if (!len)
return skb;
/* Add remaining data over MTU as continuation fragments */
frag = &skb_shinfo(skb)->frag_list;
while (len) {
struct sk_buff *tmp;
tmp = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom);
if (IS_ERR(tmp)) {
return skb;
}
len -= tmp->len;
*frag = tmp;
frag = &(*frag)->next;
}
return skb;
}
int bt_to_errno(u16 code);
void hci_sock_set_flag(struct sock *sk, int nr);

View file

@ -798,6 +798,7 @@ enum {
};
void l2cap_chan_hold(struct l2cap_chan *c);
struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c);
void l2cap_chan_put(struct l2cap_chan *c);
static inline void l2cap_chan_lock(struct l2cap_chan *chan)

View file

@ -111,7 +111,8 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
{
if (!sk->sk_mark && sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept)
if (!sk->sk_mark &&
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
return skb->mark;
return sk->sk_mark;
@ -357,7 +358,7 @@ static inline bool inet_get_convert_csum(struct sock *sk)
static inline bool inet_can_nonlocal_bind(struct net *net,
struct inet_sock *inet)
{
return net->ipv4.sysctl_ip_nonlocal_bind ||
return READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind) ||
inet->freebind || inet->transparent;
}

View file

@ -346,7 +346,7 @@ void ipfrag_init(void);
void ip_static_sysctl_init(void);
#define IP4_REPLY_MARK(net, mark) \
((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0)
(READ_ONCE((net)->ipv4.sysctl_fwmark_reflect) ? (mark) : 0)
static inline bool ip_is_fragment(const struct iphdr *iph)
{
@ -407,7 +407,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
struct net *net = dev_net(dst->dev);
unsigned int mtu;
if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
ip_mtu_locked(dst) ||
!forwarding)
return dst_mtu(dst);

View file

@ -1399,7 +1399,7 @@ void __sk_mem_reclaim(struct sock *sk, int amount);
/* sysctl_mem values are in pages, we convert them in SK_MEM_QUANTUM units */
static inline long sk_prot_mem_limits(const struct sock *sk, int index)
{
long val = sk->sk_prot->sysctl_mem[index];
long val = READ_ONCE(sk->sk_prot->sysctl_mem[index]);
#if PAGE_SIZE > SK_MEM_QUANTUM
val <<= PAGE_SHIFT - SK_MEM_QUANTUM_SHIFT;

View file

@ -1355,8 +1355,8 @@ static inline void tcp_slow_start_after_idle_check(struct sock *sk)
struct tcp_sock *tp = tcp_sk(sk);
s32 delta;
if (!sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle || tp->packets_out ||
ca_ops->cong_control)
if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle) ||
tp->packets_out || ca_ops->cong_control)
return;
delta = tcp_jiffies32 - tp->lsndtime;
if (delta > inet_csk(sk)->icsk_rto)
@ -1371,7 +1371,7 @@ void tcp_select_initial_window(const struct sock *sk, int __space,
static inline int tcp_win_from_space(const struct sock *sk, int space)
{
int tcp_adv_win_scale = sock_net(sk)->ipv4.sysctl_tcp_adv_win_scale;
int tcp_adv_win_scale = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_adv_win_scale);
return tcp_adv_win_scale <= 0 ?
(space>>(-tcp_adv_win_scale)) :
@ -1446,7 +1446,8 @@ static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)
static inline int tcp_fin_time(const struct sock *sk)
{
int fin_timeout = tcp_sk(sk)->linger2 ? : sock_net(sk)->ipv4.sysctl_tcp_fin_timeout;
int fin_timeout = tcp_sk(sk)->linger2 ? :
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fin_timeout);
const int rto = inet_csk(sk)->icsk_rto;
if (fin_timeout < (rto << 2) - (rto >> 1))
@ -1891,7 +1892,7 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr);
static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp)
{
struct net *net = sock_net((struct sock *)tp);
return tp->notsent_lowat ?: net->ipv4.sysctl_tcp_notsent_lowat;
return tp->notsent_lowat ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat);
}
static inline bool tcp_stream_memory_free(const struct sock *sk)

View file

@ -97,7 +97,7 @@ TRACE_EVENT(sock_exceed_buf_limit,
TP_STRUCT__entry(
__array(char, name, 32)
__field(long *, sysctl_mem)
__array(long, sysctl_mem, 3)
__field(long, allocated)
__field(int, sysctl_rmem)
__field(int, rmem_alloc)
@ -109,7 +109,9 @@ TRACE_EVENT(sock_exceed_buf_limit,
TP_fast_assign(
strncpy(__entry->name, prot->name, 32);
__entry->sysctl_mem = prot->sysctl_mem;
__entry->sysctl_mem[0] = READ_ONCE(prot->sysctl_mem[0]);
__entry->sysctl_mem[1] = READ_ONCE(prot->sysctl_mem[1]);
__entry->sysctl_mem[2] = READ_ONCE(prot->sysctl_mem[2]);
__entry->allocated = allocated;
__entry->sysctl_rmem = sk_get_rmem0(sk, prot);
__entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc);

View file

@ -66,11 +66,13 @@ void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, uns
{
u8 *ptr = NULL;
if (k >= SKF_NET_OFF)
if (k >= SKF_NET_OFF) {
ptr = skb_network_header(skb) + k - SKF_NET_OFF;
else if (k >= SKF_LL_OFF)
} else if (k >= SKF_LL_OFF) {
if (unlikely(!skb_mac_header_was_set(skb)))
return NULL;
ptr = skb_mac_header(skb) + k - SKF_LL_OFF;
}
if (ptr >= skb->head && ptr + size <= skb_tail_pointer(skb))
return ptr;

View file

@ -5880,10 +5880,10 @@ again:
if (!atomic_inc_not_zero(&event->rb->mmap_count)) {
/*
* Raced against perf_mmap_close() through
* perf_event_set_output(). Try again, hope for better
* luck.
* Raced against perf_mmap_close(); remove the
* event and try again.
*/
ring_buffer_attach(event, NULL);
mutex_unlock(&event->mmap_mutex);
goto again;
}
@ -10690,14 +10690,25 @@ err_size:
goto out;
}
static void mutex_lock_double(struct mutex *a, struct mutex *b)
{
if (b < a)
swap(a, b);
mutex_lock(a);
mutex_lock_nested(b, SINGLE_DEPTH_NESTING);
}
static int
perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
{
struct ring_buffer *rb = NULL;
int ret = -EINVAL;
if (!output_event)
if (!output_event) {
mutex_lock(&event->mmap_mutex);
goto set;
}
/* don't allow circular references */
if (event == output_event)
@ -10735,8 +10746,15 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
event->pmu != output_event->pmu)
goto out;
/*
* Hold both mmap_mutex to serialize against perf_mmap_close(). Since
* output_event is already on rb->event_list, and the list iteration
* restarts after every removal, it is guaranteed this new event is
* observed *OR* if output_event is already removed, it's guaranteed we
* observe !rb->mmap_count.
*/
mutex_lock_double(&event->mmap_mutex, &output_event->mmap_mutex);
set:
mutex_lock(&event->mmap_mutex);
/* Can't redirect output if we've got an active mmap() */
if (atomic_read(&event->mmap_count))
goto unlock;
@ -10746,6 +10764,12 @@ set:
rb = ring_buffer_get(output_event);
if (!rb)
goto unlock;
/* did we race against perf_mmap_close() */
if (!atomic_read(&rb->mmap_count)) {
ring_buffer_put(rb);
goto unlock;
}
}
ring_buffer_attach(event, rb);
@ -10753,20 +10777,13 @@ set:
ret = 0;
unlock:
mutex_unlock(&event->mmap_mutex);
if (output_event)
mutex_unlock(&output_event->mmap_mutex);
out:
return ret;
}
static void mutex_lock_double(struct mutex *a, struct mutex *b)
{
if (b < a)
swap(a, b);
mutex_lock(a);
mutex_lock_nested(b, SINGLE_DEPTH_NESTING);
}
static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id)
{
bool nmi_safe = false;

View file

@ -1846,12 +1846,12 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
bool autoreap = false;
u64 utime, stime;
BUG_ON(sig == -1);
WARN_ON_ONCE(sig == -1);
/* do_notify_parent_cldstop should have been called instead. */
BUG_ON(task_is_stopped_or_traced(tsk));
/* do_notify_parent_cldstop should have been called instead. */
WARN_ON_ONCE(task_is_stopped_or_traced(tsk));
BUG_ON(!tsk->ptrace &&
WARN_ON_ONCE(!tsk->ptrace &&
(tsk->group_leader != tsk || !thread_group_empty(tsk)));
/* Wake up all pidfd waiters */

View file

@ -4266,6 +4266,8 @@ static int parse_var_defs(struct hist_trigger_data *hist_data)
s = kstrdup(field_str, GFP_KERNEL);
if (!s) {
kfree(hist_data->attrs->var_defs.name[n_vars]);
hist_data->attrs->var_defs.name[n_vars] = NULL;
ret = -ENOMEM;
goto free;
}

View file

@ -348,7 +348,7 @@ static void mpol_rebind_preferred(struct mempolicy *pol,
*/
static void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask)
{
if (!pol)
if (!pol || pol->mode == MPOL_LOCAL)
return;
if (!mpol_store_user_nodemask(pol) && !(pol->flags & MPOL_F_LOCAL) &&
nodes_equal(pol->w.cpuset_mems_allowed, *newmask))

View file

@ -113,7 +113,8 @@ static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
}
/* Find channel with given SCID.
* Returns locked channel. */
* Returns a reference locked channel.
*/
static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
u16 cid)
{
@ -121,15 +122,19 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
mutex_lock(&conn->chan_lock);
c = __l2cap_get_chan_by_scid(conn, cid);
if (c)
l2cap_chan_lock(c);
if (c) {
/* Only lock if chan reference is not 0 */
c = l2cap_chan_hold_unless_zero(c);
if (c)
l2cap_chan_lock(c);
}
mutex_unlock(&conn->chan_lock);
return c;
}
/* Find channel with given DCID.
* Returns locked channel.
* Returns a reference locked channel.
*/
static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
u16 cid)
@ -138,8 +143,12 @@ static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
mutex_lock(&conn->chan_lock);
c = __l2cap_get_chan_by_dcid(conn, cid);
if (c)
l2cap_chan_lock(c);
if (c) {
/* Only lock if chan reference is not 0 */
c = l2cap_chan_hold_unless_zero(c);
if (c)
l2cap_chan_lock(c);
}
mutex_unlock(&conn->chan_lock);
return c;
@ -164,8 +173,12 @@ static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn,
mutex_lock(&conn->chan_lock);
c = __l2cap_get_chan_by_ident(conn, ident);
if (c)
l2cap_chan_lock(c);
if (c) {
/* Only lock if chan reference is not 0 */
c = l2cap_chan_hold_unless_zero(c);
if (c)
l2cap_chan_lock(c);
}
mutex_unlock(&conn->chan_lock);
return c;
@ -491,6 +504,16 @@ void l2cap_chan_hold(struct l2cap_chan *c)
kref_get(&c->kref);
}
struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
{
BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref));
if (!kref_get_unless_zero(&c->kref))
return NULL;
return c;
}
void l2cap_chan_put(struct l2cap_chan *c)
{
BT_DBG("chan %p orig refcnt %d", c, kref_read(&c->kref));
@ -1803,7 +1826,10 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
src_match = !bacmp(&c->src, src);
dst_match = !bacmp(&c->dst, dst);
if (src_match && dst_match) {
l2cap_chan_hold(c);
c = l2cap_chan_hold_unless_zero(c);
if (!c)
continue;
read_unlock(&chan_list_lock);
return c;
}
@ -1818,7 +1844,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
}
if (c1)
l2cap_chan_hold(c1);
c1 = l2cap_chan_hold_unless_zero(c1);
read_unlock(&chan_list_lock);
@ -4204,6 +4230,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
unlock:
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
return err;
}
@ -4316,6 +4343,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
done:
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
return err;
}
@ -5044,6 +5072,7 @@ send_move_response:
l2cap_send_move_chan_rsp(chan, result);
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
return 0;
}
@ -5136,6 +5165,7 @@ static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result)
}
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
}
static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
@ -5165,6 +5195,7 @@ static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid,
l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED);
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
}
static int l2cap_move_channel_rsp(struct l2cap_conn *conn,
@ -5228,6 +5259,7 @@ static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid);
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
return 0;
}
@ -5263,6 +5295,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
}
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
return 0;
}
@ -5635,12 +5668,11 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
if (credits > max_credits) {
BT_ERR("LE credits overflow");
l2cap_send_disconn_req(chan, ECONNRESET);
l2cap_chan_unlock(chan);
/* Return 0 so that we don't trigger an unnecessary
* command reject packet.
*/
return 0;
goto unlock;
}
chan->tx_credits += credits;
@ -5651,7 +5683,9 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn,
if (chan->tx_credits)
chan->ops->resume(chan);
unlock:
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
return 0;
}
@ -6949,6 +6983,7 @@ drop:
done:
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
}
static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
@ -7353,7 +7388,7 @@ static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c,
if (src_type != c->src_type)
continue;
l2cap_chan_hold(c);
c = l2cap_chan_hold_unless_zero(c);
read_unlock(&chan_list_lock);
return c;
}

View file

@ -552,22 +552,58 @@ struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel)
return dlc;
}
int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
static int rfcomm_dlc_send_frag(struct rfcomm_dlc *d, struct sk_buff *frag)
{
int len = skb->len;
if (d->state != BT_CONNECTED)
return -ENOTCONN;
int len = frag->len;
BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
if (len > d->mtu)
return -EINVAL;
rfcomm_make_uih(skb, d->addr);
skb_queue_tail(&d->tx_queue, skb);
rfcomm_make_uih(frag, d->addr);
__skb_queue_tail(&d->tx_queue, frag);
if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
return len;
}
int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
{
unsigned long flags;
struct sk_buff *frag, *next;
int len;
if (d->state != BT_CONNECTED)
return -ENOTCONN;
frag = skb_shinfo(skb)->frag_list;
skb_shinfo(skb)->frag_list = NULL;
/* Queue all fragments atomically. */
spin_lock_irqsave(&d->tx_queue.lock, flags);
len = rfcomm_dlc_send_frag(d, skb);
if (len < 0 || !frag)
goto unlock;
for (; frag; frag = next) {
int ret;
next = frag->next;
ret = rfcomm_dlc_send_frag(d, frag);
if (ret < 0) {
kfree_skb(frag);
goto unlock;
}
len += ret;
}
unlock:
spin_unlock_irqrestore(&d->tx_queue.lock, flags);
if (len > 0 && !test_bit(RFCOMM_TX_THROTTLED, &d->flags))
rfcomm_schedule();
return len;
}

View file

@ -578,47 +578,21 @@ static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg,
lock_sock(sk);
sent = bt_sock_wait_ready(sk, msg->msg_flags);
if (sent)
goto done;
while (len) {
size_t size = min_t(size_t, len, d->mtu);
int err;
skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb) {
if (sent == 0)
sent = err;
break;
}
skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
err = memcpy_from_msg(skb_put(skb, size), msg, size);
if (err) {
kfree_skb(skb);
if (sent == 0)
sent = err;
break;
}
skb->priority = sk->sk_priority;
err = rfcomm_dlc_send(d, skb);
if (err < 0) {
kfree_skb(skb);
if (sent == 0)
sent = err;
break;
}
sent += size;
len -= size;
}
done:
release_sock(sk);
if (sent)
return sent;
skb = bt_skb_sendmmsg(sk, msg, len, d->mtu, RFCOMM_SKB_HEAD_RESERVE,
RFCOMM_SKB_TAIL_RESERVE);
if (IS_ERR(skb))
return PTR_ERR(skb);
sent = rfcomm_dlc_send(d, skb);
if (sent < 0)
kfree_skb(skb);
return sent;
}

View file

@ -279,12 +279,10 @@ static int sco_connect(struct hci_dev *hdev, struct sock *sk)
return err;
}
static int sco_send_frame(struct sock *sk, void *buf, int len,
unsigned int msg_flags)
static int sco_send_frame(struct sock *sk, struct sk_buff *skb)
{
struct sco_conn *conn = sco_pi(sk)->conn;
struct sk_buff *skb;
int err;
int len = skb->len;
/* Check outgoing MTU */
if (len > conn->mtu)
@ -292,11 +290,6 @@ static int sco_send_frame(struct sock *sk, void *buf, int len,
BT_DBG("sk %p len %d", sk, len);
skb = bt_skb_send_alloc(sk, len, msg_flags & MSG_DONTWAIT, &err);
if (!skb)
return err;
memcpy(skb_put(skb, len), buf, len);
hci_send_sco(conn->hcon, skb);
return len;
@ -715,7 +708,7 @@ static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len)
{
struct sock *sk = sock->sk;
void *buf;
struct sk_buff *skb;
int err;
BT_DBG("sock %p, sk %p", sock, sk);
@ -727,24 +720,21 @@ static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg,
if (msg->msg_flags & MSG_OOB)
return -EOPNOTSUPP;
buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (memcpy_from_msg(buf, msg, len)) {
kfree(buf);
return -EFAULT;
}
skb = bt_skb_sendmsg(sk, msg, len, len, 0, 0);
if (IS_ERR(skb))
return PTR_ERR(skb);
lock_sock(sk);
if (sk->sk_state == BT_CONNECTED)
err = sco_send_frame(sk, buf, len, msg->msg_flags);
err = sco_send_frame(sk, skb);
else
err = -ENOTCONN;
release_sock(sk);
kfree(buf);
if (err < 0)
kfree_skb(skb);
return err;
}

View file

@ -1001,9 +1001,24 @@ int br_nf_hook_thresh(unsigned int hook, struct net *net,
return okfn(net, sk, skb);
ops = nf_hook_entries_get_hook_ops(e);
for (i = 0; i < e->num_hook_entries &&
ops[i]->priority <= NF_BR_PRI_BRNF; i++)
;
for (i = 0; i < e->num_hook_entries; i++) {
/* These hooks have already been called */
if (ops[i]->priority < NF_BR_PRI_BRNF)
continue;
/* These hooks have not been called yet, run them. */
if (ops[i]->priority > NF_BR_PRI_BRNF)
break;
/* take a closer look at NF_BR_PRI_BRNF. */
if (ops[i]->hook == br_nf_pre_routing) {
/* This hook diverted the skb to this function,
* hooks after this have not been run yet.
*/
i++;
break;
}
}
nf_hook_state_init(&state, hook, NFPROTO_BRIDGE, indev, outdev,
sk, net, okfn);

View file

@ -4570,7 +4570,6 @@ static int bpf_push_seg6_encap(struct sk_buff *skb, u32 type, void *hdr, u32 len
if (err)
return err;
ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
return seg6_lookup_nexthop(skb, NULL, 0);

Some files were not shown because too many files have changed in this diff Show more