Merge ~xnox/ubuntu/+source/linux/+git/focal:5.4-revocation-certs into ~ubuntu-kernel/ubuntu/+source/linux/+git/focal:master-next
- Git
- lp:~xnox/ubuntu/+source/linux/+git/focal
- 5.4-revocation-certs
- Merge into master-next
Status: | Needs review | ||||||||
---|---|---|---|---|---|---|---|---|---|
Proposed branch: | ~xnox/ubuntu/+source/linux/+git/focal:5.4-revocation-certs | ||||||||
Merge into: | ~ubuntu-kernel/ubuntu/+source/linux/+git/focal:master-next | ||||||||
Diff against target: |
4122 lines (+1416/-495) 127 files modified
Makefile (+1/-1) arch/arc/Kconfig (+1/-0) arch/arc/include/asm/syscalls.h (+1/-0) arch/arc/include/uapi/asm/unistd.h (+1/-0) arch/arc/kernel/entry.S (+12/-0) arch/arc/kernel/process.c (+3/-4) arch/arc/kernel/sys.c (+1/-0) arch/arc/kernel/vmlinux.lds.S (+2/-0) arch/arm/kernel/Makefile (+5/-1) arch/arm/kernel/return_address.c (+0/-4) arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts (+4/-0) arch/parisc/include/asm/string.h (+0/-15) arch/parisc/kernel/parisc_ksyms.c (+0/-4) arch/parisc/lib/Makefile (+2/-2) arch/parisc/lib/memset.c (+72/-0) arch/powerpc/boot/crt0.S (+0/-3) arch/x86/events/amd/ibs.c (+8/-0) arch/x86/events/amd/iommu.c (+26/-21) arch/x86/events/amd/power.c (+1/-0) arch/x86/events/intel/pt.c (+1/-1) arch/x86/events/intel/uncore_snbep.c (+1/-1) arch/x86/kernel/reboot.c (+2/-1) arch/x86/kernel/setup.c (+1/-0) arch/x86/kvm/mmu.c (+9/-1) arch/x86/platform/efi/efi.c (+3/-0) arch/xtensa/Kconfig (+1/-1) certs/.gitignore (+1/-0) certs/Kconfig (+8/-0) certs/Makefile (+17/-2) certs/blacklist.c (+24/-0) certs/common.c (+1/-0) certs/revocation_certificates.S (+21/-0) debian.master/config/annotations (+1/-0) debian.master/config/config.common.ubuntu (+1/-0) debian.master/upstream-stable (+1/-1) debian/revoked-certs/canonical-uefi-2012-all.pem (+86/-0) debian/rules (+13/-1) dev/null (+0/-136) drivers/block/Kconfig (+2/-2) drivers/block/cryptoloop.c (+2/-0) drivers/block/floppy.c (+13/-14) drivers/firmware/efi/Makefile (+1/-0) drivers/firmware/efi/arm-init.c (+1/-0) drivers/firmware/efi/efi.c (+6/-0) drivers/firmware/efi/mokvar-table.c (+362/-0) drivers/gpu/drm/drm_ioc32.c (+1/-3) drivers/gpu/drm/i915/gt/intel_timeline.c (+8/-0) drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c (+1/-1) drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h (+1/-0) drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c (+9/-0) drivers/gpu/ipu-v3/ipu-cpmem.c (+15/-15) drivers/infiniband/hw/bnxt_re/ib_verbs.c (+1/-0) drivers/infiniband/hw/efa/efa_main.c (+1/-0) drivers/infiniband/hw/hfi1/sdma.c (+4/-5) drivers/media/usb/stkwebcam/stk-webcam.c (+4/-2) drivers/mmc/host/sdhci-msm.c (+18/-0) drivers/net/can/usb/esd_usb2.c (+2/-2) drivers/net/dsa/mt7530.c (+1/-4) drivers/net/ethernet/apm/xgene-v2/main.c (+3/-1) drivers/net/ethernet/cadence/macb_ptp.c (+10/-1) drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h (+3/-0) drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c (+2/-11) drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c (+31/-1) drivers/net/ethernet/intel/e1000e/ich8lan.c (+13/-1) drivers/net/ethernet/intel/e1000e/ich8lan.h (+3/-0) drivers/net/ethernet/marvell/mvneta.c (+1/-1) drivers/net/ethernet/qlogic/qed/qed_ll2.c (+20/-0) drivers/net/ethernet/qlogic/qed/qed_main.c (+6/-1) drivers/net/ethernet/qlogic/qed/qed_rdma.c (+1/-2) drivers/net/ethernet/qlogic/qede/qede_main.c (+1/-1) drivers/net/ethernet/realtek/r8169_main.c (+1/-0) drivers/net/ethernet/xilinx/ll_temac_main.c (+1/-3) drivers/opp/of.c (+3/-2) drivers/pci/quirks.c (+6/-6) drivers/reset/reset-zynqmp.c (+2/-1) drivers/scsi/scsi_sysfs.c (+6/-3) drivers/tty/vt/vt_ioctl.c (+7/-4) drivers/usb/dwc3/gadget.c (+11/-12) drivers/usb/gadget/function/u_audio.c (+2/-3) drivers/usb/host/xhci-debugfs.c (+4/-2) drivers/usb/host/xhci-rcar.c (+7/-0) drivers/usb/host/xhci-trace.h (+4/-4) drivers/usb/host/xhci.h (+28/-24) drivers/usb/mtu3/mtu3_gadget.c (+2/-4) drivers/usb/serial/ch341.c (+0/-1) drivers/usb/serial/mos7720.c (+3/-1) drivers/usb/serial/option.c (+2/-0) drivers/vhost/vringh.c (+1/-1) drivers/virtio/virtio_pci_common.c (+7/-0) drivers/virtio/virtio_ring.c (+4/-2) fs/btrfs/btrfs_inode.h (+15/-0) fs/btrfs/file.c (+2/-8) fs/btrfs/inode.c (+2/-4) fs/btrfs/transaction.h (+1/-1) fs/btrfs/volumes.c (+1/-1) fs/crypto/hooks.c (+44/-0) fs/ext4/symlink.c (+10/-1) fs/f2fs/namei.c (+10/-1) fs/overlayfs/export.c (+1/-1) fs/proc/base.c (+10/-1) fs/ubifs/file.c (+11/-1) include/linux/efi.h (+34/-0) include/linux/fscrypt.h (+7/-0) include/linux/netdevice.h (+4/-0) include/linux/once.h (+2/-2) include/linux/oom.h (+2/-2) kernel/audit_tree.c (+1/-1) kernel/bpf/verifier.c (+55/-2) kernel/kthread.c (+29/-14) kernel/sched/fair.c (+1/-1) lib/once.c (+8/-3) mm/oom_kill.c (+10/-12) mm/page_alloc.c (+4/-4) net/core/rtnetlink.c (+2/-1) net/ipv4/icmp.c (+21/-2) net/ipv4/igmp.c (+2/-0) net/ipv4/ip_gre.c (+2/-0) net/netfilter/nf_conntrack_core.c (+22/-49) net/qrtr/qrtr.c (+1/-1) net/rds/ib_frmr.c (+2/-2) net/socket.c (+5/-1) scripts/Makefile (+1/-0) security/integrity/platform_certs/keyring_handler.c (+1/-0) security/integrity/platform_certs/load_uefi.c (+101/-37) sound/core/pcm_lib.c (+1/-1) sound/pci/hda/patch_realtek.c (+10/-0) sound/usb/quirks.c (+1/-0) |
||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Kernel Repositories | Pending | ||
Review via email: mp+409374@code.launchpad.net |
Commit message
Backport builtin revocation certificates and mokvar table driver
Description of the change
Unmerged commits
- 1b21f28... by Dimitri John Ledkov
-
UBUNTU: [Config] Configure CONFIG_
SYSTEM_ REVOCATION_ KEYS with revoked keys BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029
Signed-off-by: Dimitri John Ledkov <email address hidden>
Signed-off-by: Andrea Righi <email address hidden>
(cherry picked from commit 741f622c4dbc162b82f8c9045f9c6c 6446f57eb5)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden> - d764c30... by Dimitri John Ledkov
-
UBUNTU: [Packaging] Revoke 2012 UEFI signing certificate as built-in
BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029
Signed-off-by: Dimitri John Ledkov <email address hidden>
Signed-off-by: Andrea Righi <email address hidden>
(cherry picked from commit 3f72ce72f0b51b6da2638cdded93bb 32b9dad2ec)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 4598103... by Dimitri John Ledkov
-
UBUNTU: [Packaging] build canonical-
revoked- certs.pem from branch/arch certs BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029
Signed-off-by: Dimitri John Ledkov <email address hidden>
Signed-off-by: Andrea Righi <email address hidden>
(cherry picked from commit 3e44f229eef829ee30446519755125 69824c4e5f)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden> - e9905dd... by Tim Gardner
-
UBUNTU: SAUCE: Dump stack when X.509 certificates cannot be loaded
BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029 Signed-off-by: Tim Gardner <email address hidden>
(cherry picked from commit b5b4085dc5547a01593cd79dbf51bd 9108f84e9f)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden> - b496c6b... by Dimitri John Ledkov
-
UBUNTU: SAUCE: integrity: add informational messages when revoking certs
integrity_
load_cert( ) prints messages of the source and cert details
when adding certs as trusted. Mirror those messages in
uefi_revocation_list_x509( ) when adding certs as revoked. Sample dmesg with this change:
integrity: Platform Keyring initialized
integrity: Loading X.509 certificate: UEFI:db
integrity: Loaded X.509 cert 'Microsoft Corporation UEFI CA 2011: 13adbf4309bd82709c8cd54f316ed5 22988a1bd4'
integrity: Revoking X.509 certificate: UEFI:MokListXRT (MOKvar table)
blacklist: Revoked X.509 cert 'Canonical Ltd. Secure Boot Signing: 61482aa2830d0ab2ad5af10b7250da 9033ddcef0'
integrity: Loading X.509 certificate: UEFI:MokListRT (MOKvar table)
integrity: Loaded X.509 cert 'Canonical Ltd. Master Certificate Authority: ad91990bc22ab1f517048c23b6655a 268e345a63' BugLink: https:/
/bugs.launchpad .net/bugs/ 1928679
Signed-off-by: Dimitri John Ledkov <email address hidden>
Acked-by: Krzysztof Kozlowski <email address hidden>
Signed-off-by: Seth Forshee <email address hidden>
(cherry picked from commit ba9fb788f89cb81c5ed836db2355a7 a3b0f8c248)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden> - baec570... by Dimitri John Ledkov
-
UBUNTU: SAUCE: integrity: Load mokx certs from the EFI MOK config table
Refactor load_moklist_
certs() to load either MokListRT into db, or
MokListXRT into dbx. Call load_moklist_certs() twice - first to load
mokx certs into dbx, then mok certs into db.This thus now attempts to load mokx certs via the EFI MOKvar config
table first, and if that fails, via the EFI variable. Previously mokx
certs were only loaded via the EFI variable. Which fails when
MokListXRT is large. Instead of large MokListXRT variable, only
MokListXRT{1,2,3} are available which are not loaded. This is the case
with Ubuntu's 15.4 based shim. This patch is required to address
CVE-2020-26541 when certificates are revoked via MokListXRT.Fixes: ebd9c2ae369a ("integrity: Load mokx variables into the blacklist keyring")
BugLink: https://bugs.launchpad .net/bugs/ 1928679
Signed-off-by: Dimitri John Ledkov <email address hidden>
Acked-by: Krzysztof Kozlowski <email address hidden>
Signed-off-by: Seth Forshee <email address hidden>
(cherry picked from commit a9e3aae16235d6af12509a64f1337d a4485ccbae)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 9f88bce... by Linus Torvalds <email address hidden>
-
certs: add 'x509_revocatio
n_list' to gitignore BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029 Commit d1f044103dad ("certs: Add ability to preload revocation certs")
created a new generated file for revocation certs, but didn't tell git
to ignore it. Thus causing unnecessary "git status" noise after a
kernel build with CONFIG_SYSTEM_ REVOCATION_ LIST enabled. Add the proper gitignore magic.
Signed-off-by: Linus Torvalds <email address hidden>
(cherry picked from commit 81f202315856edb75a371f3376aa3a 47543c16f0)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 5b175c0... by Eric Snowberg <email address hidden>
-
integrity: Load mokx variables into the blacklist keyring
BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029 During boot the Secure Boot Forbidden Signature Database, dbx,
is loaded into the blacklist keyring. Systems booted with shim
have an equivalent Forbidden Signature Database called mokx.
Currently mokx is only used by shim and grub, the contents are
ignored by the kernel.Add the ability to load mokx into the blacklist keyring during boot.
Signed-off-by: Eric Snowberg <email address hidden>
Suggested-by: James Bottomley <email address hidden>
Signed-off-by: David Howells <email address hidden>
Reviewed-by: Jarkko Sakkinen <email address hidden>
cc: <email address hidden>
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v5
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v2
Link: https://<email address hidden>/ # v3
(cherry picked from commit ebd9c2ae369a45bdd9f8615484db09 be58fc242b)
Signed-off-by: Dimitri John Ledkov <email address hidden> - dd15cc5... by Eric Snowberg <email address hidden>
-
certs: Add ability to preload revocation certs
BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029 Add a new Kconfig option called SYSTEM_
REVOCATION_ KEYS. If set,
this option should be the filename of a PEM-formated file containing
X.509 certificates to be included in the default blacklist keyring.DH Changes:
- Make the new Kconfig option depend on SYSTEM_REVOCATION_ LIST.
- Fix SYSTEM_REVOCATION_ KEYS=n, but CONFIG_ SYSTEM_ REVOCATION_ LIST=y[ 1][2].
- Use CONFIG_SYSTEM_ REVOCATION_ LIST for extract-cert[3].
- Use CONFIG_SYSTEM_ REVOCATION_ LIST for revocation_ certificates. o[3]. Signed-off-by: Eric Snowberg <email address hidden>
Acked-by: Jarkko Sakkinen <email address hidden>
Signed-off-by: David Howells <email address hidden>
cc: Randy Dunlap <email address hidden>
cc: <email address hidden>
Link: https://<email address hidden>/ [1]
Link: https://<email address hidden>/ [2]
Link: https://<email address hidden>/ [3]
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v5
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v2
Link: https://<email address hidden>/ # v3
(cherry picked from commit d1f044103dad70c1cec0a8f3abdf00 834fec8b98)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 618e1a9... by Lenny Szubowicz <email address hidden>
-
integrity: Load certs from the EFI MOK config table
BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029 Because of system-specific EFI firmware limitations, EFI volatile
variables may not be capable of holding the required contents of
the Machine Owner Key (MOK) certificate store when the certificate
list grows above some size. Therefore, an EFI boot loader may pass
the MOK certs via a EFI configuration table created specifically for
this purpose to avoid this firmware limitation.An EFI configuration table is a much more primitive mechanism
compared to EFI variables and is well suited for one-way passage
of static information from a pre-OS environment to the kernel.This patch adds the support to load certs from the MokListRT
entry in the MOK variable configuration table, if it's present.
The pre-existing support to load certs from the MokListRT EFI
variable remains and is used if the EFI MOK configuration table
isn't present or can't be successfully used.Signed-off-by: Lenny Szubowicz <email address hidden>
Link: https://<email address hidden>
Signed-off-by: Ard Biesheuvel <email address hidden>
(cherry picked from commit 726bd8965a5f112d9601f7ce68effa 1e46e02bf2)
Signed-off-by: Dimitri John Ledkov <email address hidden>
Preview Diff
1 | diff --git a/Makefile b/Makefile |
2 | index 4b314dd..a2bb129 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,7 +1,7 @@ |
6 | # SPDX-License-Identifier: GPL-2.0 |
7 | VERSION = 5 |
8 | PATCHLEVEL = 4 |
9 | -SUBLEVEL = 143 |
10 | +SUBLEVEL = 145 |
11 | EXTRAVERSION = |
12 | NAME = Kleptomaniac Octopus |
13 | |
14 | diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig |
15 | index 8383155..a9d0b53 100644 |
16 | --- a/arch/arc/Kconfig |
17 | +++ b/arch/arc/Kconfig |
18 | @@ -29,6 +29,7 @@ config ARC |
19 | select GENERIC_SMP_IDLE_THREAD |
20 | select HAVE_ARCH_KGDB |
21 | select HAVE_ARCH_TRACEHOOK |
22 | + select HAVE_COPY_THREAD_TLS |
23 | select HAVE_DEBUG_STACKOVERFLOW |
24 | select HAVE_FUTEX_CMPXCHG if FUTEX |
25 | select HAVE_IOREMAP_PROT |
26 | diff --git a/arch/arc/include/asm/syscalls.h b/arch/arc/include/asm/syscalls.h |
27 | index 7ddba13..c3f4714 100644 |
28 | --- a/arch/arc/include/asm/syscalls.h |
29 | +++ b/arch/arc/include/asm/syscalls.h |
30 | @@ -11,6 +11,7 @@ |
31 | #include <linux/types.h> |
32 | |
33 | int sys_clone_wrapper(int, int, int, int, int); |
34 | +int sys_clone3_wrapper(void *, size_t); |
35 | int sys_cacheflush(uint32_t, uint32_t uint32_t); |
36 | int sys_arc_settls(void *); |
37 | int sys_arc_gettls(void); |
38 | diff --git a/arch/arc/include/uapi/asm/unistd.h b/arch/arc/include/uapi/asm/unistd.h |
39 | index 5eafa11..fa2713a 100644 |
40 | --- a/arch/arc/include/uapi/asm/unistd.h |
41 | +++ b/arch/arc/include/uapi/asm/unistd.h |
42 | @@ -21,6 +21,7 @@ |
43 | #define __ARCH_WANT_SET_GET_RLIMIT |
44 | #define __ARCH_WANT_SYS_EXECVE |
45 | #define __ARCH_WANT_SYS_CLONE |
46 | +#define __ARCH_WANT_SYS_CLONE3 |
47 | #define __ARCH_WANT_SYS_VFORK |
48 | #define __ARCH_WANT_SYS_FORK |
49 | #define __ARCH_WANT_TIME32_SYSCALLS |
50 | diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S |
51 | index b37ca85..cef1d3f 100644 |
52 | --- a/arch/arc/kernel/entry.S |
53 | +++ b/arch/arc/kernel/entry.S |
54 | @@ -35,6 +35,18 @@ ENTRY(sys_clone_wrapper) |
55 | b .Lret_from_system_call |
56 | END(sys_clone_wrapper) |
57 | |
58 | +ENTRY(sys_clone3_wrapper) |
59 | + SAVE_CALLEE_SAVED_USER |
60 | + bl @sys_clone3 |
61 | + DISCARD_CALLEE_SAVED_USER |
62 | + |
63 | + GET_CURR_THR_INFO_FLAGS r10 |
64 | + btst r10, TIF_SYSCALL_TRACE |
65 | + bnz tracesys_exit |
66 | + |
67 | + b .Lret_from_system_call |
68 | +END(sys_clone3_wrapper) |
69 | + |
70 | ENTRY(ret_from_fork) |
71 | ; when the forked child comes here from the __switch_to function |
72 | ; r0 has the last task pointer. |
73 | diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c |
74 | index e1889ce..bfd4cbe 100644 |
75 | --- a/arch/arc/kernel/process.c |
76 | +++ b/arch/arc/kernel/process.c |
77 | @@ -171,9 +171,8 @@ asmlinkage void ret_from_fork(void); |
78 | * | user_r25 | |
79 | * ------------------ <===== END of PAGE |
80 | */ |
81 | -int copy_thread(unsigned long clone_flags, |
82 | - unsigned long usp, unsigned long kthread_arg, |
83 | - struct task_struct *p) |
84 | +int copy_thread_tls(unsigned long clone_flags, unsigned long usp, |
85 | + unsigned long kthread_arg, struct task_struct *p, unsigned long tls) |
86 | { |
87 | struct pt_regs *c_regs; /* child's pt_regs */ |
88 | unsigned long *childksp; /* to unwind out of __switch_to() */ |
89 | @@ -231,7 +230,7 @@ int copy_thread(unsigned long clone_flags, |
90 | * set task's userland tls data ptr from 4th arg |
91 | * clone C-lib call is difft from clone sys-call |
92 | */ |
93 | - task_thread_info(p)->thr_ptr = regs->r3; |
94 | + task_thread_info(p)->thr_ptr = tls; |
95 | } else { |
96 | /* Normal fork case: set parent's TLS ptr in child */ |
97 | task_thread_info(p)->thr_ptr = |
98 | diff --git a/arch/arc/kernel/sys.c b/arch/arc/kernel/sys.c |
99 | index fddecc7..1069446 100644 |
100 | --- a/arch/arc/kernel/sys.c |
101 | +++ b/arch/arc/kernel/sys.c |
102 | @@ -7,6 +7,7 @@ |
103 | #include <asm/syscalls.h> |
104 | |
105 | #define sys_clone sys_clone_wrapper |
106 | +#define sys_clone3 sys_clone3_wrapper |
107 | |
108 | #undef __SYSCALL |
109 | #define __SYSCALL(nr, call) [nr] = (call), |
110 | diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S |
111 | index 6c693a9..0391b82 100644 |
112 | --- a/arch/arc/kernel/vmlinux.lds.S |
113 | +++ b/arch/arc/kernel/vmlinux.lds.S |
114 | @@ -88,6 +88,8 @@ SECTIONS |
115 | CPUIDLE_TEXT |
116 | LOCK_TEXT |
117 | KPROBES_TEXT |
118 | + IRQENTRY_TEXT |
119 | + SOFTIRQENTRY_TEXT |
120 | *(.fixup) |
121 | *(.gnu.warning) |
122 | } |
123 | diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile |
124 | index 8cad594..8b679e2 100644 |
125 | --- a/arch/arm/kernel/Makefile |
126 | +++ b/arch/arm/kernel/Makefile |
127 | @@ -17,10 +17,14 @@ CFLAGS_REMOVE_return_address.o = -pg |
128 | # Object file lists. |
129 | |
130 | obj-y := elf.o entry-common.o irq.o opcodes.o \ |
131 | - process.o ptrace.o reboot.o return_address.o \ |
132 | + process.o ptrace.o reboot.o \ |
133 | setup.o signal.o sigreturn_codes.o \ |
134 | stacktrace.o sys_arm.o time.o traps.o |
135 | |
136 | +ifneq ($(CONFIG_ARM_UNWIND),y) |
137 | +obj-$(CONFIG_FRAME_POINTER) += return_address.o |
138 | +endif |
139 | + |
140 | obj-$(CONFIG_ATAGS) += atags_parse.o |
141 | obj-$(CONFIG_ATAGS_PROC) += atags_proc.o |
142 | obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o |
143 | diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c |
144 | index b0d2f1f..7b42ac0 100644 |
145 | --- a/arch/arm/kernel/return_address.c |
146 | +++ b/arch/arm/kernel/return_address.c |
147 | @@ -7,8 +7,6 @@ |
148 | */ |
149 | #include <linux/export.h> |
150 | #include <linux/ftrace.h> |
151 | - |
152 | -#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) |
153 | #include <linux/sched.h> |
154 | |
155 | #include <asm/stacktrace.h> |
156 | @@ -53,6 +51,4 @@ void *return_address(unsigned int level) |
157 | return NULL; |
158 | } |
159 | |
160 | -#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */ |
161 | - |
162 | EXPORT_SYMBOL_GPL(return_address); |
163 | diff --git a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts |
164 | index a5f9a6a..9b989cc 100644 |
165 | --- a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts |
166 | +++ b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts |
167 | @@ -30,3 +30,7 @@ |
168 | }; |
169 | }; |
170 | }; |
171 | + |
172 | +&msmgpio { |
173 | + gpio-reserved-ranges = <85 4>; |
174 | +}; |
175 | diff --git a/arch/parisc/include/asm/string.h b/arch/parisc/include/asm/string.h |
176 | index 4a0c9db..f6e1132 100644 |
177 | --- a/arch/parisc/include/asm/string.h |
178 | +++ b/arch/parisc/include/asm/string.h |
179 | @@ -8,19 +8,4 @@ extern void * memset(void *, int, size_t); |
180 | #define __HAVE_ARCH_MEMCPY |
181 | void * memcpy(void * dest,const void *src,size_t count); |
182 | |
183 | -#define __HAVE_ARCH_STRLEN |
184 | -extern size_t strlen(const char *s); |
185 | - |
186 | -#define __HAVE_ARCH_STRCPY |
187 | -extern char *strcpy(char *dest, const char *src); |
188 | - |
189 | -#define __HAVE_ARCH_STRNCPY |
190 | -extern char *strncpy(char *dest, const char *src, size_t count); |
191 | - |
192 | -#define __HAVE_ARCH_STRCAT |
193 | -extern char *strcat(char *dest, const char *src); |
194 | - |
195 | -#define __HAVE_ARCH_MEMSET |
196 | -extern void *memset(void *, int, size_t); |
197 | - |
198 | #endif |
199 | diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c |
200 | index 8ed409e..e8a6a75 100644 |
201 | --- a/arch/parisc/kernel/parisc_ksyms.c |
202 | +++ b/arch/parisc/kernel/parisc_ksyms.c |
203 | @@ -17,10 +17,6 @@ |
204 | |
205 | #include <linux/string.h> |
206 | EXPORT_SYMBOL(memset); |
207 | -EXPORT_SYMBOL(strlen); |
208 | -EXPORT_SYMBOL(strcpy); |
209 | -EXPORT_SYMBOL(strncpy); |
210 | -EXPORT_SYMBOL(strcat); |
211 | |
212 | #include <linux/atomic.h> |
213 | EXPORT_SYMBOL(__xchg8); |
214 | diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile |
215 | index 2d7a997..7b19766 100644 |
216 | --- a/arch/parisc/lib/Makefile |
217 | +++ b/arch/parisc/lib/Makefile |
218 | @@ -3,7 +3,7 @@ |
219 | # Makefile for parisc-specific library files |
220 | # |
221 | |
222 | -lib-y := lusercopy.o bitops.o checksum.o io.o memcpy.o \ |
223 | - ucmpdi2.o delay.o string.o |
224 | +lib-y := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \ |
225 | + ucmpdi2.o delay.o |
226 | |
227 | obj-y := iomap.o |
228 | diff --git a/arch/parisc/lib/memset.c b/arch/parisc/lib/memset.c |
229 | new file mode 100644 |
230 | index 0000000..133e480 |
231 | --- /dev/null |
232 | +++ b/arch/parisc/lib/memset.c |
233 | @@ -0,0 +1,72 @@ |
234 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
235 | +#include <linux/types.h> |
236 | +#include <asm/string.h> |
237 | + |
238 | +#define OPSIZ (BITS_PER_LONG/8) |
239 | +typedef unsigned long op_t; |
240 | + |
241 | +void * |
242 | +memset (void *dstpp, int sc, size_t len) |
243 | +{ |
244 | + unsigned int c = sc; |
245 | + long int dstp = (long int) dstpp; |
246 | + |
247 | + if (len >= 8) |
248 | + { |
249 | + size_t xlen; |
250 | + op_t cccc; |
251 | + |
252 | + cccc = (unsigned char) c; |
253 | + cccc |= cccc << 8; |
254 | + cccc |= cccc << 16; |
255 | + if (OPSIZ > 4) |
256 | + /* Do the shift in two steps to avoid warning if long has 32 bits. */ |
257 | + cccc |= (cccc << 16) << 16; |
258 | + |
259 | + /* There are at least some bytes to set. |
260 | + No need to test for LEN == 0 in this alignment loop. */ |
261 | + while (dstp % OPSIZ != 0) |
262 | + { |
263 | + ((unsigned char *) dstp)[0] = c; |
264 | + dstp += 1; |
265 | + len -= 1; |
266 | + } |
267 | + |
268 | + /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ |
269 | + xlen = len / (OPSIZ * 8); |
270 | + while (xlen > 0) |
271 | + { |
272 | + ((op_t *) dstp)[0] = cccc; |
273 | + ((op_t *) dstp)[1] = cccc; |
274 | + ((op_t *) dstp)[2] = cccc; |
275 | + ((op_t *) dstp)[3] = cccc; |
276 | + ((op_t *) dstp)[4] = cccc; |
277 | + ((op_t *) dstp)[5] = cccc; |
278 | + ((op_t *) dstp)[6] = cccc; |
279 | + ((op_t *) dstp)[7] = cccc; |
280 | + dstp += 8 * OPSIZ; |
281 | + xlen -= 1; |
282 | + } |
283 | + len %= OPSIZ * 8; |
284 | + |
285 | + /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ |
286 | + xlen = len / OPSIZ; |
287 | + while (xlen > 0) |
288 | + { |
289 | + ((op_t *) dstp)[0] = cccc; |
290 | + dstp += OPSIZ; |
291 | + xlen -= 1; |
292 | + } |
293 | + len %= OPSIZ; |
294 | + } |
295 | + |
296 | + /* Write the last few bytes. */ |
297 | + while (len > 0) |
298 | + { |
299 | + ((unsigned char *) dstp)[0] = c; |
300 | + dstp += 1; |
301 | + len -= 1; |
302 | + } |
303 | + |
304 | + return dstpp; |
305 | +} |
306 | diff --git a/arch/parisc/lib/string.S b/arch/parisc/lib/string.S |
307 | deleted file mode 100644 |
308 | index 4a64264..0000000 |
309 | --- a/arch/parisc/lib/string.S |
310 | +++ /dev/null |
311 | @@ -1,136 +0,0 @@ |
312 | -// SPDX-License-Identifier: GPL-2.0 |
313 | -/* |
314 | - * PA-RISC assembly string functions |
315 | - * |
316 | - * Copyright (C) 2019 Helge Deller <deller@gmx.de> |
317 | - */ |
318 | - |
319 | -#include <asm/assembly.h> |
320 | -#include <linux/linkage.h> |
321 | - |
322 | - .section .text.hot |
323 | - .level PA_ASM_LEVEL |
324 | - |
325 | - t0 = r20 |
326 | - t1 = r21 |
327 | - t2 = r22 |
328 | - |
329 | -ENTRY_CFI(strlen, frame=0,no_calls) |
330 | - or,COND(<>) arg0,r0,ret0 |
331 | - b,l,n .Lstrlen_null_ptr,r0 |
332 | - depwi 0,31,2,ret0 |
333 | - cmpb,COND(<>) arg0,ret0,.Lstrlen_not_aligned |
334 | - ldw,ma 4(ret0),t0 |
335 | - cmpib,tr 0,r0,.Lstrlen_loop |
336 | - uxor,nbz r0,t0,r0 |
337 | -.Lstrlen_not_aligned: |
338 | - uaddcm arg0,ret0,t1 |
339 | - shladd t1,3,r0,t1 |
340 | - mtsar t1 |
341 | - depwi -1,%sar,32,t0 |
342 | - uxor,nbz r0,t0,r0 |
343 | -.Lstrlen_loop: |
344 | - b,l,n .Lstrlen_end_loop,r0 |
345 | - ldw,ma 4(ret0),t0 |
346 | - cmpib,tr 0,r0,.Lstrlen_loop |
347 | - uxor,nbz r0,t0,r0 |
348 | -.Lstrlen_end_loop: |
349 | - extrw,u,<> t0,7,8,r0 |
350 | - addib,tr,n -3,ret0,.Lstrlen_out |
351 | - extrw,u,<> t0,15,8,r0 |
352 | - addib,tr,n -2,ret0,.Lstrlen_out |
353 | - extrw,u,<> t0,23,8,r0 |
354 | - addi -1,ret0,ret0 |
355 | -.Lstrlen_out: |
356 | - bv r0(rp) |
357 | - uaddcm ret0,arg0,ret0 |
358 | -.Lstrlen_null_ptr: |
359 | - bv,n r0(rp) |
360 | -ENDPROC_CFI(strlen) |
361 | - |
362 | - |
363 | -ENTRY_CFI(strcpy, frame=0,no_calls) |
364 | - ldb 0(arg1),t0 |
365 | - stb t0,0(arg0) |
366 | - ldo 0(arg0),ret0 |
367 | - ldo 1(arg1),t1 |
368 | - cmpb,= r0,t0,2f |
369 | - ldo 1(arg0),t2 |
370 | -1: ldb 0(t1),arg1 |
371 | - stb arg1,0(t2) |
372 | - ldo 1(t1),t1 |
373 | - cmpb,<> r0,arg1,1b |
374 | - ldo 1(t2),t2 |
375 | -2: bv,n r0(rp) |
376 | -ENDPROC_CFI(strcpy) |
377 | - |
378 | - |
379 | -ENTRY_CFI(strncpy, frame=0,no_calls) |
380 | - ldb 0(arg1),t0 |
381 | - stb t0,0(arg0) |
382 | - ldo 1(arg1),t1 |
383 | - ldo 0(arg0),ret0 |
384 | - cmpb,= r0,t0,2f |
385 | - ldo 1(arg0),arg1 |
386 | -1: ldo -1(arg2),arg2 |
387 | - cmpb,COND(=),n r0,arg2,2f |
388 | - ldb 0(t1),arg0 |
389 | - stb arg0,0(arg1) |
390 | - ldo 1(t1),t1 |
391 | - cmpb,<> r0,arg0,1b |
392 | - ldo 1(arg1),arg1 |
393 | -2: bv,n r0(rp) |
394 | -ENDPROC_CFI(strncpy) |
395 | - |
396 | - |
397 | -ENTRY_CFI(strcat, frame=0,no_calls) |
398 | - ldb 0(arg0),t0 |
399 | - cmpb,= t0,r0,2f |
400 | - ldo 0(arg0),ret0 |
401 | - ldo 1(arg0),arg0 |
402 | -1: ldb 0(arg0),t1 |
403 | - cmpb,<>,n r0,t1,1b |
404 | - ldo 1(arg0),arg0 |
405 | -2: ldb 0(arg1),t2 |
406 | - stb t2,0(arg0) |
407 | - ldo 1(arg0),arg0 |
408 | - ldb 0(arg1),t0 |
409 | - cmpb,<> r0,t0,2b |
410 | - ldo 1(arg1),arg1 |
411 | - bv,n r0(rp) |
412 | -ENDPROC_CFI(strcat) |
413 | - |
414 | - |
415 | -ENTRY_CFI(memset, frame=0,no_calls) |
416 | - copy arg0,ret0 |
417 | - cmpb,COND(=) r0,arg0,4f |
418 | - copy arg0,t2 |
419 | - cmpb,COND(=) r0,arg2,4f |
420 | - ldo -1(arg2),arg3 |
421 | - subi -1,arg3,t0 |
422 | - subi 0,t0,t1 |
423 | - cmpiclr,COND(>=) 0,t1,arg2 |
424 | - ldo -1(t1),arg2 |
425 | - extru arg2,31,2,arg0 |
426 | -2: stb arg1,0(t2) |
427 | - ldo 1(t2),t2 |
428 | - addib,>= -1,arg0,2b |
429 | - ldo -1(arg3),arg3 |
430 | - cmpiclr,COND(<=) 4,arg2,r0 |
431 | - b,l,n 4f,r0 |
432 | -#ifdef CONFIG_64BIT |
433 | - depd,* r0,63,2,arg2 |
434 | -#else |
435 | - depw r0,31,2,arg2 |
436 | -#endif |
437 | - ldo 1(t2),t2 |
438 | -3: stb arg1,-1(t2) |
439 | - stb arg1,0(t2) |
440 | - stb arg1,1(t2) |
441 | - stb arg1,2(t2) |
442 | - addib,COND(>) -4,arg2,3b |
443 | - ldo 4(t2),t2 |
444 | -4: bv,n r0(rp) |
445 | -ENDPROC_CFI(memset) |
446 | - |
447 | - .end |
448 | diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S |
449 | index 92608f3..1d83966 100644 |
450 | --- a/arch/powerpc/boot/crt0.S |
451 | +++ b/arch/powerpc/boot/crt0.S |
452 | @@ -44,9 +44,6 @@ p_end: .long _end |
453 | p_pstack: .long _platform_stack_top |
454 | #endif |
455 | |
456 | - .globl _zimage_start |
457 | - /* Clang appears to require the .weak directive to be after the symbol |
458 | - * is defined. See https://bugs.llvm.org/show_bug.cgi?id=38921 */ |
459 | .weak _zimage_start |
460 | _zimage_start: |
461 | .globl _zimage_start_lib |
462 | diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c |
463 | index 3916988..ff07040 100644 |
464 | --- a/arch/x86/events/amd/ibs.c |
465 | +++ b/arch/x86/events/amd/ibs.c |
466 | @@ -90,6 +90,7 @@ struct perf_ibs { |
467 | unsigned long offset_mask[1]; |
468 | int offset_max; |
469 | unsigned int fetch_count_reset_broken : 1; |
470 | + unsigned int fetch_ignore_if_zero_rip : 1; |
471 | struct cpu_perf_ibs __percpu *pcpu; |
472 | |
473 | struct attribute **format_attrs; |
474 | @@ -663,6 +664,10 @@ fail: |
475 | if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) { |
476 | regs.flags &= ~PERF_EFLAGS_EXACT; |
477 | } else { |
478 | + /* Workaround for erratum #1197 */ |
479 | + if (perf_ibs->fetch_ignore_if_zero_rip && !(ibs_data.regs[1])) |
480 | + goto out; |
481 | + |
482 | set_linear_ip(®s, ibs_data.regs[1]); |
483 | regs.flags |= PERF_EFLAGS_EXACT; |
484 | } |
485 | @@ -756,6 +761,9 @@ static __init void perf_event_ibs_init(void) |
486 | if (boot_cpu_data.x86 >= 0x16 && boot_cpu_data.x86 <= 0x18) |
487 | perf_ibs_fetch.fetch_count_reset_broken = 1; |
488 | |
489 | + if (boot_cpu_data.x86 == 0x19 && boot_cpu_data.x86_model < 0x10) |
490 | + perf_ibs_fetch.fetch_ignore_if_zero_rip = 1; |
491 | + |
492 | perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch"); |
493 | |
494 | if (ibs_caps & IBS_CAPS_OPCNT) { |
495 | diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c |
496 | index 6a98a76..2da6139 100644 |
497 | --- a/arch/x86/events/amd/iommu.c |
498 | +++ b/arch/x86/events/amd/iommu.c |
499 | @@ -18,8 +18,6 @@ |
500 | #include "../perf_event.h" |
501 | #include "iommu.h" |
502 | |
503 | -#define COUNTER_SHIFT 16 |
504 | - |
505 | /* iommu pmu conf masks */ |
506 | #define GET_CSOURCE(x) ((x)->conf & 0xFFULL) |
507 | #define GET_DEVID(x) (((x)->conf >> 8) & 0xFFFFULL) |
508 | @@ -285,22 +283,31 @@ static void perf_iommu_start(struct perf_event *event, int flags) |
509 | WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); |
510 | hwc->state = 0; |
511 | |
512 | + /* |
513 | + * To account for power-gating, which prevents write to |
514 | + * the counter, we need to enable the counter |
515 | + * before setting up counter register. |
516 | + */ |
517 | + perf_iommu_enable_event(event); |
518 | + |
519 | if (flags & PERF_EF_RELOAD) { |
520 | - u64 prev_raw_count = local64_read(&hwc->prev_count); |
521 | + u64 count = 0; |
522 | struct amd_iommu *iommu = perf_event_2_iommu(event); |
523 | |
524 | + /* |
525 | + * Since the IOMMU PMU only support counting mode, |
526 | + * the counter always start with value zero. |
527 | + */ |
528 | amd_iommu_pc_set_reg(iommu, hwc->iommu_bank, hwc->iommu_cntr, |
529 | - IOMMU_PC_COUNTER_REG, &prev_raw_count); |
530 | + IOMMU_PC_COUNTER_REG, &count); |
531 | } |
532 | |
533 | - perf_iommu_enable_event(event); |
534 | perf_event_update_userpage(event); |
535 | - |
536 | } |
537 | |
538 | static void perf_iommu_read(struct perf_event *event) |
539 | { |
540 | - u64 count, prev, delta; |
541 | + u64 count; |
542 | struct hw_perf_event *hwc = &event->hw; |
543 | struct amd_iommu *iommu = perf_event_2_iommu(event); |
544 | |
545 | @@ -311,14 +318,11 @@ static void perf_iommu_read(struct perf_event *event) |
546 | /* IOMMU pc counter register is only 48 bits */ |
547 | count &= GENMASK_ULL(47, 0); |
548 | |
549 | - prev = local64_read(&hwc->prev_count); |
550 | - if (local64_cmpxchg(&hwc->prev_count, prev, count) != prev) |
551 | - return; |
552 | - |
553 | - /* Handle 48-bit counter overflow */ |
554 | - delta = (count << COUNTER_SHIFT) - (prev << COUNTER_SHIFT); |
555 | - delta >>= COUNTER_SHIFT; |
556 | - local64_add(delta, &event->count); |
557 | + /* |
558 | + * Since the counter always start with value zero, |
559 | + * simply just accumulate the count for the event. |
560 | + */ |
561 | + local64_add(count, &event->count); |
562 | } |
563 | |
564 | static void perf_iommu_stop(struct perf_event *event, int flags) |
565 | @@ -328,15 +332,16 @@ static void perf_iommu_stop(struct perf_event *event, int flags) |
566 | if (hwc->state & PERF_HES_UPTODATE) |
567 | return; |
568 | |
569 | + /* |
570 | + * To account for power-gating, in which reading the counter would |
571 | + * return zero, we need to read the register before disabling. |
572 | + */ |
573 | + perf_iommu_read(event); |
574 | + hwc->state |= PERF_HES_UPTODATE; |
575 | + |
576 | perf_iommu_disable_event(event); |
577 | WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); |
578 | hwc->state |= PERF_HES_STOPPED; |
579 | - |
580 | - if (hwc->state & PERF_HES_UPTODATE) |
581 | - return; |
582 | - |
583 | - perf_iommu_read(event); |
584 | - hwc->state |= PERF_HES_UPTODATE; |
585 | } |
586 | |
587 | static int perf_iommu_add(struct perf_event *event, int flags) |
588 | diff --git a/arch/x86/events/amd/power.c b/arch/x86/events/amd/power.c |
589 | index abef513..c4892b7 100644 |
590 | --- a/arch/x86/events/amd/power.c |
591 | +++ b/arch/x86/events/amd/power.c |
592 | @@ -217,6 +217,7 @@ static struct pmu pmu_class = { |
593 | .stop = pmu_event_stop, |
594 | .read = pmu_event_read, |
595 | .capabilities = PERF_PMU_CAP_NO_EXCLUDE, |
596 | + .module = THIS_MODULE, |
597 | }; |
598 | |
599 | static int power_cpu_exit(unsigned int cpu) |
600 | diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c |
601 | index 05e43d0..da289a4 100644 |
602 | --- a/arch/x86/events/intel/pt.c |
603 | +++ b/arch/x86/events/intel/pt.c |
604 | @@ -62,7 +62,7 @@ static struct pt_cap_desc { |
605 | PT_CAP(single_range_output, 0, CPUID_ECX, BIT(2)), |
606 | PT_CAP(output_subsys, 0, CPUID_ECX, BIT(3)), |
607 | PT_CAP(payloads_lip, 0, CPUID_ECX, BIT(31)), |
608 | - PT_CAP(num_address_ranges, 1, CPUID_EAX, 0x3), |
609 | + PT_CAP(num_address_ranges, 1, CPUID_EAX, 0x7), |
610 | PT_CAP(mtc_periods, 1, CPUID_EAX, 0xffff0000), |
611 | PT_CAP(cycle_thresholds, 1, CPUID_EBX, 0xffff), |
612 | PT_CAP(psb_periods, 1, CPUID_EBX, 0xffff0000), |
613 | diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c |
614 | index 40751af..9096a16 100644 |
615 | --- a/arch/x86/events/intel/uncore_snbep.c |
616 | +++ b/arch/x86/events/intel/uncore_snbep.c |
617 | @@ -4382,7 +4382,7 @@ static void snr_uncore_mmio_init_box(struct intel_uncore_box *box) |
618 | return; |
619 | |
620 | pci_read_config_dword(pdev, SNR_IMC_MMIO_BASE_OFFSET, &pci_dword); |
621 | - addr = (pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23; |
622 | + addr = ((resource_size_t)pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23; |
623 | |
624 | pci_read_config_dword(pdev, SNR_IMC_MMIO_MEM0_OFFSET, &pci_dword); |
625 | addr |= (pci_dword & SNR_IMC_MMIO_MEM0_MASK) << 12; |
626 | diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c |
627 | index c0a9648..cd11c07 100644 |
628 | --- a/arch/x86/kernel/reboot.c |
629 | +++ b/arch/x86/kernel/reboot.c |
630 | @@ -389,10 +389,11 @@ static const struct dmi_system_id reboot_dmi_table[] __initconst = { |
631 | }, |
632 | { /* Handle problems with rebooting on the OptiPlex 990. */ |
633 | .callback = set_pci_reboot, |
634 | - .ident = "Dell OptiPlex 990", |
635 | + .ident = "Dell OptiPlex 990 BIOS A0x", |
636 | .matches = { |
637 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
638 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), |
639 | + DMI_MATCH(DMI_BIOS_VERSION, "A0"), |
640 | }, |
641 | }, |
642 | { /* Handle problems with rebooting on Dell 300's */ |
643 | diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c |
644 | index 0607163..d4e3804 100644 |
645 | --- a/arch/x86/kernel/setup.c |
646 | +++ b/arch/x86/kernel/setup.c |
647 | @@ -1134,6 +1134,7 @@ void __init setup_arch(char **cmdline_p) |
648 | efi_fake_memmap(); |
649 | efi_find_mirror(); |
650 | efi_esrt_init(); |
651 | + efi_mokvar_table_init(); |
652 | |
653 | /* |
654 | * The EFI specification says that boot service code won't be |
655 | diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c |
656 | index 260c64c..d3877dd 100644 |
657 | --- a/arch/x86/kvm/mmu.c |
658 | +++ b/arch/x86/kvm/mmu.c |
659 | @@ -4666,7 +4666,15 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu, |
660 | void |
661 | reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context) |
662 | { |
663 | - bool uses_nx = context->nx || |
664 | + /* |
665 | + * KVM uses NX when TDP is disabled to handle a variety of scenarios, |
666 | + * notably for huge SPTEs if iTLB multi-hit mitigation is enabled and |
667 | + * to generate correct permissions for CR0.WP=0/CR4.SMEP=1/EFER.NX=0. |
668 | + * The iTLB multi-hit workaround can be toggled at any time, so assume |
669 | + * NX can be used by any non-nested shadow MMU to avoid having to reset |
670 | + * MMU contexts. Note, KVM forces EFER.NX=1 when TDP is disabled. |
671 | + */ |
672 | + bool uses_nx = context->nx || !tdp_enabled || |
673 | context->mmu_role.base.smep_andnot_wp; |
674 | struct rsvd_bits_validate *shadow_zero_check; |
675 | int i; |
676 | diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c |
677 | index ae1c5ba..4a83038 100644 |
678 | --- a/arch/x86/platform/efi/efi.c |
679 | +++ b/arch/x86/platform/efi/efi.c |
680 | @@ -87,6 +87,9 @@ static const unsigned long * const efi_tables[] = { |
681 | #endif |
682 | &efi.tpm_log, |
683 | &efi.tpm_final_log, |
684 | +#ifdef CONFIG_LOAD_UEFI_KEYS |
685 | + &efi.mokvar_table, |
686 | +#endif |
687 | }; |
688 | |
689 | u64 efi_setup; /* efi setup_data physical address */ |
690 | diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig |
691 | index 8352037..499bdd1 100644 |
692 | --- a/arch/xtensa/Kconfig |
693 | +++ b/arch/xtensa/Kconfig |
694 | @@ -27,7 +27,7 @@ config XTENSA |
695 | select HAVE_DMA_CONTIGUOUS |
696 | select HAVE_EXIT_THREAD |
697 | select HAVE_FUNCTION_TRACER |
698 | - select HAVE_FUTEX_CMPXCHG if !MMU |
699 | + select HAVE_FUTEX_CMPXCHG if !MMU && FUTEX |
700 | select HAVE_HW_BREAKPOINT if PERF_EVENTS |
701 | select HAVE_IRQ_TIME_ACCOUNTING |
702 | select HAVE_OPROFILE |
703 | diff --git a/certs/.gitignore b/certs/.gitignore |
704 | index f51aea4..6ce8116 100644 |
705 | --- a/certs/.gitignore |
706 | +++ b/certs/.gitignore |
707 | @@ -2,3 +2,4 @@ |
708 | # Generated files |
709 | # |
710 | x509_certificate_list |
711 | +x509_revocation_list |
712 | diff --git a/certs/Kconfig b/certs/Kconfig |
713 | index 76e469b..ab88d2a 100644 |
714 | --- a/certs/Kconfig |
715 | +++ b/certs/Kconfig |
716 | @@ -92,4 +92,12 @@ config SYSTEM_REVOCATION_LIST |
717 | blacklist keyring and implements a hook whereby a PKCS#7 message can |
718 | be checked to see if it matches such a certificate. |
719 | |
720 | +config SYSTEM_REVOCATION_KEYS |
721 | + string "X.509 certificates to be preloaded into the system blacklist keyring" |
722 | + depends on SYSTEM_REVOCATION_LIST |
723 | + help |
724 | + If set, this option should be the filename of a PEM-formatted file |
725 | + containing X.509 certificates to be included in the default blacklist |
726 | + keyring. |
727 | + |
728 | endmenu |
729 | diff --git a/certs/Makefile b/certs/Makefile |
730 | index f4b90ba..b6db52e 100644 |
731 | --- a/certs/Makefile |
732 | +++ b/certs/Makefile |
733 | @@ -4,7 +4,8 @@ |
734 | # |
735 | |
736 | obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o common.o |
737 | -obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o |
738 | +obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o |
739 | +obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o |
740 | ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),"") |
741 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o |
742 | else |
743 | @@ -29,7 +30,7 @@ $(obj)/x509_certificate_list: scripts/extract-cert $(SYSTEM_TRUSTED_KEYS_SRCPREF |
744 | $(call if_changed,extract_certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS)) |
745 | endif # CONFIG_SYSTEM_TRUSTED_KEYRING |
746 | |
747 | -clean-files := x509_certificate_list .x509.list |
748 | +clean-files := x509_certificate_list .x509.list x509_revocation_list |
749 | |
750 | ifeq ($(CONFIG_MODULE_SIG),y) |
751 | ############################################################################### |
752 | @@ -104,3 +105,17 @@ targets += signing_key.x509 |
753 | $(obj)/signing_key.x509: scripts/extract-cert $(X509_DEP) FORCE |
754 | $(call if_changed,extract_certs,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY)) |
755 | endif # CONFIG_MODULE_SIG |
756 | + |
757 | +ifeq ($(CONFIG_SYSTEM_REVOCATION_LIST),y) |
758 | + |
759 | +$(eval $(call config_filename,SYSTEM_REVOCATION_KEYS)) |
760 | + |
761 | +$(obj)/revocation_certificates.o: $(obj)/x509_revocation_list |
762 | + |
763 | +quiet_cmd_extract_certs = EXTRACT_CERTS $(patsubst "%",%,$(2)) |
764 | + cmd_extract_certs = scripts/extract-cert $(2) $@ |
765 | + |
766 | +targets += x509_revocation_list |
767 | +$(obj)/x509_revocation_list: scripts/extract-cert $(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(SYSTEM_REVOCATION_KEYS_FILENAME) FORCE |
768 | + $(call if_changed,extract_certs,$(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_REVOCATION_KEYS)) |
769 | +endif |
770 | diff --git a/certs/blacklist.c b/certs/blacklist.c |
771 | index 59b2f10..7638dfa 100644 |
772 | --- a/certs/blacklist.c |
773 | +++ b/certs/blacklist.c |
774 | @@ -16,9 +16,15 @@ |
775 | #include <linux/seq_file.h> |
776 | #include <keys/system_keyring.h> |
777 | #include "blacklist.h" |
778 | +#include "common.h" |
779 | |
780 | static struct key *blacklist_keyring; |
781 | |
782 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
783 | +extern __initconst const u8 revocation_certificate_list[]; |
784 | +extern __initconst const unsigned long revocation_certificate_list_size; |
785 | +#endif |
786 | + |
787 | /* |
788 | * The description must be a type prefix, a colon and then an even number of |
789 | * hex digits. The hash is kept in the description. |
790 | @@ -165,6 +171,9 @@ int add_key_to_revocation_list(const char *data, size_t size) |
791 | if (IS_ERR(key)) { |
792 | pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key)); |
793 | return PTR_ERR(key); |
794 | + } else { |
795 | + pr_notice("Revoked X.509 cert '%s'\n", |
796 | + key_ref_to_ptr(key)->description); |
797 | } |
798 | |
799 | return 0; |
800 | @@ -220,3 +229,18 @@ static int __init blacklist_init(void) |
801 | * Must be initialised before we try and load the keys into the keyring. |
802 | */ |
803 | device_initcall(blacklist_init); |
804 | + |
805 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
806 | +/* |
807 | + * Load the compiled-in list of revocation X.509 certificates. |
808 | + */ |
809 | +static __init int load_revocation_certificate_list(void) |
810 | +{ |
811 | + if (revocation_certificate_list_size) |
812 | + pr_notice("Loading compiled-in revocation X.509 certificates\n"); |
813 | + |
814 | + return load_certificate_list(revocation_certificate_list, revocation_certificate_list_size, |
815 | + blacklist_keyring); |
816 | +} |
817 | +late_initcall(load_revocation_certificate_list); |
818 | +#endif |
819 | diff --git a/certs/common.c b/certs/common.c |
820 | index 16a2208..23af4fc 100644 |
821 | --- a/certs/common.c |
822 | +++ b/certs/common.c |
823 | @@ -41,6 +41,7 @@ int load_certificate_list(const u8 cert_list[], |
824 | if (IS_ERR(key)) { |
825 | pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", |
826 | PTR_ERR(key)); |
827 | + WARN_ON_ONCE(1); |
828 | } else { |
829 | pr_notice("Loaded X.509 cert '%s'\n", |
830 | key_ref_to_ptr(key)->description); |
831 | diff --git a/certs/revocation_certificates.S b/certs/revocation_certificates.S |
832 | new file mode 100644 |
833 | index 0000000..f21aae8 |
834 | --- /dev/null |
835 | +++ b/certs/revocation_certificates.S |
836 | @@ -0,0 +1,21 @@ |
837 | +/* SPDX-License-Identifier: GPL-2.0 */ |
838 | +#include <linux/export.h> |
839 | +#include <linux/init.h> |
840 | + |
841 | + __INITRODATA |
842 | + |
843 | + .align 8 |
844 | + .globl revocation_certificate_list |
845 | +revocation_certificate_list: |
846 | +__revocation_list_start: |
847 | + .incbin "certs/x509_revocation_list" |
848 | +__revocation_list_end: |
849 | + |
850 | + .align 8 |
851 | + .globl revocation_certificate_list_size |
852 | +revocation_certificate_list_size: |
853 | +#ifdef CONFIG_64BIT |
854 | + .quad __revocation_list_end - __revocation_list_start |
855 | +#else |
856 | + .long __revocation_list_end - __revocation_list_start |
857 | +#endif |
858 | diff --git a/debian.master/config/annotations b/debian.master/config/annotations |
859 | index b23d62d..03b21b4 100644 |
860 | --- a/debian.master/config/annotations |
861 | +++ b/debian.master/config/annotations |
862 | @@ -364,6 +364,7 @@ CONFIG_SYSTEM_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': ' |
863 | CONFIG_SYSTEM_TRUSTED_KEYS policy<{'amd64': '"debian/canonical-certs.pem"', 'arm64': '"debian/canonical-certs.pem"', 'armhf': '"debian/canonical-certs.pem"', 'i386': '"debian/canonical-certs.pem"', 'ppc64el': '"debian/canonical-certs.pem"', 's390x': '"debian/canonical-certs.pem"'}> |
864 | CONFIG_SYSTEM_EXTRA_CERTIFICATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> |
865 | CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'i386': '4096', 'ppc64el': '4096', 's390x': '4096'}> |
866 | +CONFIG_SYSTEM_REVOCATION_KEYS policy<{'amd64': '"debian/canonical-revoked-certs.pem"', 'arm64': '"debian/canonical-revoked-certs.pem"', 'armhf': '"debian/canonical-revoked-certs.pem"', 'ppc64el': '"debian/canonical-revoked-certs.pem"', 's390x': '"debian/canonical-revoked-certs.pem"'}> |
867 | CONFIG_SECONDARY_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> |
868 | |
869 | # Menu: Cryptographic API >> Hardware crypto devices |
870 | diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu |
871 | index c6bb6db..bc171d7 100644 |
872 | --- a/debian.master/config/config.common.ubuntu |
873 | +++ b/debian.master/config/config.common.ubuntu |
874 | @@ -9925,6 +9925,7 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y |
875 | CONFIG_SYSTEM_DATA_VERIFICATION=y |
876 | CONFIG_SYSTEM_EXTRA_CERTIFICATE=y |
877 | CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096 |
878 | +CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem" |
879 | CONFIG_SYSTEM_REVOCATION_LIST=y |
880 | CONFIG_SYSTEM_TRUSTED_KEYRING=y |
881 | CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem" |
882 | diff --git a/debian.master/upstream-stable b/debian.master/upstream-stable |
883 | index f1840cb..f2e7f82 100644 |
884 | --- a/debian.master/upstream-stable |
885 | +++ b/debian.master/upstream-stable |
886 | @@ -1,3 +1,3 @@ |
887 | # The following upstream stable releases have been ported: |
888 | [upstream-stable] |
889 | - linux-5.4.y = v5.4.143 |
890 | + linux-5.4.y = v5.4.145 |
891 | diff --git a/debian/revoked-certs/canonical-uefi-2012-all.pem b/debian/revoked-certs/canonical-uefi-2012-all.pem |
892 | new file mode 100644 |
893 | index 0000000..06c116e |
894 | --- /dev/null |
895 | +++ b/debian/revoked-certs/canonical-uefi-2012-all.pem |
896 | @@ -0,0 +1,86 @@ |
897 | +Certificate: |
898 | + Data: |
899 | + Version: 3 (0x2) |
900 | + Serial Number: 1 (0x1) |
901 | + Signature Algorithm: sha256WithRSAEncryption |
902 | + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority |
903 | + Validity |
904 | + Not Before: Apr 12 11:39:08 2012 GMT |
905 | + Not After : Apr 11 11:39:08 2042 GMT |
906 | + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing |
907 | + Subject Public Key Info: |
908 | + Public Key Algorithm: rsaEncryption |
909 | + RSA Public-Key: (2048 bit) |
910 | + Modulus: |
911 | + 00:c9:5f:9b:62:8f:0b:b0:64:82:ac:be:c9:e2:62: |
912 | + e3:4b:d2:9f:1e:8a:d5:61:1a:2b:5d:38:f4:b7:ce: |
913 | + b9:9a:b8:43:b8:43:97:77:ab:4f:7f:0c:70:46:0b: |
914 | + fc:7f:6d:c6:6d:ea:80:5e:01:d2:b7:66:1e:87:de: |
915 | + 0d:6d:d0:41:97:a8:a5:af:0c:63:4f:f7:7c:c2:52: |
916 | + cc:a0:31:a9:bb:89:5d:99:1e:46:6f:55:73:b9:76: |
917 | + 69:ec:d7:c1:fc:21:d6:c6:07:e7:4f:bd:22:de:e4: |
918 | + a8:5b:2d:db:95:34:19:97:d6:28:4b:21:4c:ca:bb: |
919 | + 1d:79:a6:17:7f:5a:f9:67:e6:5c:78:45:3d:10:6d: |
920 | + b0:17:59:26:11:c5:57:e3:7f:4e:82:ba:f6:2c:4e: |
921 | + c8:37:4d:ff:85:15:84:47:e0:ed:3b:7c:7f:bc:af: |
922 | + e9:01:05:a7:0c:6f:c3:e9:8d:a3:ce:be:a6:e3:cd: |
923 | + 3c:b5:58:2c:9e:c2:03:1c:60:22:37:39:ff:41:02: |
924 | + c1:29:a4:65:51:ff:33:34:aa:42:15:f9:95:78:fc: |
925 | + 2d:f5:da:8a:85:7c:82:9d:fb:37:2c:6b:a5:a8:df: |
926 | + 7c:55:0b:80:2e:3c:b0:63:e1:cd:38:48:89:e8:14: |
927 | + 06:0b:82:bc:fd:d4:07:68:1b:0f:3e:d9:15:dd:94: |
928 | + 11:1b |
929 | + Exponent: 65537 (0x10001) |
930 | + X509v3 extensions: |
931 | + X509v3 Basic Constraints: critical |
932 | + CA:FALSE |
933 | + X509v3 Extended Key Usage: |
934 | + Code Signing, 1.3.6.1.4.1.311.10.3.6 |
935 | + Netscape Comment: |
936 | + OpenSSL Generated Certificate |
937 | + X509v3 Subject Key Identifier: |
938 | + 61:48:2A:A2:83:0D:0A:B2:AD:5A:F1:0B:72:50:DA:90:33:DD:CE:F0 |
939 | + X509v3 Authority Key Identifier: |
940 | + keyid:AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 |
941 | + |
942 | + Signature Algorithm: sha256WithRSAEncryption |
943 | + 8f:8a:a1:06:1f:29:b7:0a:4a:d5:c5:fd:81:ab:25:ea:c0:7d: |
944 | + e2:fc:6a:96:a0:79:93:67:ee:05:0e:25:12:25:e4:5a:f6:aa: |
945 | + 1a:f1:12:f3:05:8d:87:5e:f1:5a:5c:cb:8d:23:73:65:1d:15: |
946 | + b9:de:22:6b:d6:49:67:c9:a3:c6:d7:62:4e:5c:b5:f9:03:83: |
947 | + 40:81:dc:87:9c:3c:3f:1c:0d:51:9f:94:65:0a:84:48:67:e4: |
948 | + a2:f8:a6:4a:f0:e7:cd:cd:bd:94:e3:09:d2:5d:2d:16:1b:05: |
949 | + 15:0b:cb:44:b4:3e:61:42:22:c4:2a:5c:4e:c5:1d:a3:e2:e0: |
950 | + 52:b2:eb:f4:8b:2b:dc:38:39:5d:fb:88:a1:56:65:5f:2b:4f: |
951 | + 26:ff:06:78:10:12:eb:8c:5d:32:e3:c6:45:af:25:9b:a0:ff: |
952 | + 8e:ef:47:09:a3:e9:8b:37:92:92:69:76:7e:34:3b:92:05:67: |
953 | + 4e:b0:25:ed:bc:5e:5f:8f:b4:d6:ca:40:ff:e4:e2:31:23:0c: |
954 | + 85:25:ae:0c:55:01:ec:e5:47:5e:df:5b:bc:14:33:e3:c6:f5: |
955 | + 18:b6:d9:f7:dd:b3:b4:a1:31:d3:5a:5c:5d:7d:3e:bf:0a:e4: |
956 | + e4:e8:b4:59:7d:3b:b4:8c:a3:1b:b5:20:a3:b9:3e:84:6f:8c: |
957 | + 21:00:c3:39 |
958 | +-----BEGIN CERTIFICATE----- |
959 | +MIIEIDCCAwigAwIBAgIBATANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix |
960 | +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK |
961 | +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy |
962 | +IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMjA0MTIxMTM5MDhaFw00MjA0MTEx |
963 | +MTM5MDhaMH8xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEXMBUG |
964 | +A1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MSswKQYD |
965 | +VQQDDCJDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nMIIBIjANBgkq |
966 | +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyV+bYo8LsGSCrL7J4mLjS9KfHorVYRor |
967 | +XTj0t865mrhDuEOXd6tPfwxwRgv8f23GbeqAXgHSt2Yeh94NbdBBl6ilrwxjT/d8 |
968 | +wlLMoDGpu4ldmR5Gb1VzuXZp7NfB/CHWxgfnT70i3uSoWy3blTQZl9YoSyFMyrsd |
969 | +eaYXf1r5Z+ZceEU9EG2wF1kmEcVX439Ogrr2LE7IN03/hRWER+DtO3x/vK/pAQWn |
970 | +DG/D6Y2jzr6m4808tVgsnsIDHGAiNzn/QQLBKaRlUf8zNKpCFfmVePwt9dqKhXyC |
971 | +nfs3LGulqN98VQuALjywY+HNOEiJ6BQGC4K8/dQHaBsPPtkV3ZQRGwIDAQABo4Gg |
972 | +MIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUHAwMGCisGAQQBgjcK |
973 | +AwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl |
974 | +MB0GA1UdDgQWBBRhSCqigw0Ksq1a8QtyUNqQM93O8DAfBgNVHSMEGDAWgBStkZkL |
975 | +wiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEAj4qhBh8ptwpK1cX9 |
976 | +gasl6sB94vxqlqB5k2fuBQ4lEiXkWvaqGvES8wWNh17xWlzLjSNzZR0Vud4ia9ZJ |
977 | +Z8mjxtdiTly1+QODQIHch5w8PxwNUZ+UZQqESGfkovimSvDnzc29lOMJ0l0tFhsF |
978 | +FQvLRLQ+YUIixCpcTsUdo+LgUrLr9Isr3Dg5XfuIoVZlXytPJv8GeBAS64xdMuPG |
979 | +Ra8lm6D/ju9HCaPpizeSkml2fjQ7kgVnTrAl7bxeX4+01spA/+TiMSMMhSWuDFUB |
980 | +7OVHXt9bvBQz48b1GLbZ992ztKEx01pcXX0+vwrk5Oi0WX07tIyjG7Ugo7k+hG+M |
981 | +IQDDOQ== |
982 | +-----END CERTIFICATE----- |
983 | diff --git a/debian/rules b/debian/rules |
984 | index f8d53af..b10128a 100755 |
985 | --- a/debian/rules |
986 | +++ b/debian/rules |
987 | @@ -137,7 +137,7 @@ binary: binary-indep binary-arch |
988 | |
989 | build: build-arch build-indep |
990 | |
991 | -clean: debian/control debian/canonical-certs.pem |
992 | +clean: debian/control debian/canonical-certs.pem debian/canonical-revoked-certs.pem |
993 | dh_testdir |
994 | dh_testroot |
995 | dh_clean |
996 | @@ -247,3 +247,15 @@ debian/canonical-certs.pem: $(wildcard $(DROOT)/certs/*-all.pem) $(wildcard $(DR |
997 | fi; \ |
998 | done; \ |
999 | done >"$@" |
1000 | + |
1001 | +debian/canonical-revoked-certs.pem: $(wildcard $(DROOT)/revoked-certs/*-all.pem) $(wildcard $(DROOT)/revoked-certs/*-$(arch).pem) $(wildcard $(DEBIAN)/revoked-certs/*-all.pem) $(wildcard $(DEBIAN)/revoked-certs/*-$(arch).pem) |
1002 | + for cert in $(sort $(notdir $^)); \ |
1003 | + do \ |
1004 | + for dir in $(DEBIAN) $(DROOT); \ |
1005 | + do \ |
1006 | + if [ -f "$$dir/revoked-certs/$$cert" ]; then \ |
1007 | + cat "$$dir/revoked-certs/$$cert"; \ |
1008 | + break; \ |
1009 | + fi; \ |
1010 | + done; \ |
1011 | + done >"$@" |
1012 | diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig |
1013 | index 0fc27ac..9f67823 100644 |
1014 | --- a/drivers/block/Kconfig |
1015 | +++ b/drivers/block/Kconfig |
1016 | @@ -230,7 +230,7 @@ config BLK_DEV_LOOP_MIN_COUNT |
1017 | dynamically allocated with the /dev/loop-control interface. |
1018 | |
1019 | config BLK_DEV_CRYPTOLOOP |
1020 | - tristate "Cryptoloop Support" |
1021 | + tristate "Cryptoloop Support (DEPRECATED)" |
1022 | select CRYPTO |
1023 | select CRYPTO_CBC |
1024 | depends on BLK_DEV_LOOP |
1025 | @@ -242,7 +242,7 @@ config BLK_DEV_CRYPTOLOOP |
1026 | WARNING: This device is not safe for journaled file systems like |
1027 | ext3 or Reiserfs. Please use the Device Mapper crypto module |
1028 | instead, which can be configured to be on-disk compatible with the |
1029 | - cryptoloop device. |
1030 | + cryptoloop device. cryptoloop support will be removed in Linux 5.16. |
1031 | |
1032 | source "drivers/block/drbd/Kconfig" |
1033 | |
1034 | diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c |
1035 | index 3cabc33..f0a91fa 100644 |
1036 | --- a/drivers/block/cryptoloop.c |
1037 | +++ b/drivers/block/cryptoloop.c |
1038 | @@ -189,6 +189,8 @@ init_cryptoloop(void) |
1039 | |
1040 | if (rc) |
1041 | printk(KERN_ERR "cryptoloop: loop_register_transfer failed\n"); |
1042 | + else |
1043 | + pr_warn("the cryptoloop driver has been deprecated and will be removed in in Linux 5.16\n"); |
1044 | return rc; |
1045 | } |
1046 | |
1047 | diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c |
1048 | index 40ea1a4..ac97a1e 100644 |
1049 | --- a/drivers/block/floppy.c |
1050 | +++ b/drivers/block/floppy.c |
1051 | @@ -4063,22 +4063,21 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) |
1052 | if (UFDCS->rawcmd == 1) |
1053 | UFDCS->rawcmd = 2; |
1054 | |
1055 | - if (mode & (FMODE_READ|FMODE_WRITE)) { |
1056 | - UDRS->last_checked = 0; |
1057 | - clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags); |
1058 | - check_disk_change(bdev); |
1059 | - if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) |
1060 | - goto out; |
1061 | - if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags)) |
1062 | + if (!(mode & FMODE_NDELAY)) { |
1063 | + if (mode & (FMODE_READ|FMODE_WRITE)) { |
1064 | + UDRS->last_checked = 0; |
1065 | + clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags); |
1066 | + check_disk_change(bdev); |
1067 | + if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) |
1068 | + goto out; |
1069 | + if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags)) |
1070 | + goto out; |
1071 | + } |
1072 | + res = -EROFS; |
1073 | + if ((mode & FMODE_WRITE) && |
1074 | + !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) |
1075 | goto out; |
1076 | } |
1077 | - |
1078 | - res = -EROFS; |
1079 | - |
1080 | - if ((mode & FMODE_WRITE) && |
1081 | - !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) |
1082 | - goto out; |
1083 | - |
1084 | mutex_unlock(&open_lock); |
1085 | mutex_unlock(&floppy_mutex); |
1086 | return 0; |
1087 | diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile |
1088 | index 195b078..5bb7be5 100644 |
1089 | --- a/drivers/firmware/efi/Makefile |
1090 | +++ b/drivers/firmware/efi/Makefile |
1091 | @@ -27,6 +27,7 @@ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o |
1092 | obj-$(CONFIG_EFI) += secureboot.o |
1093 | obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o |
1094 | obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o |
1095 | +obj-$(CONFIG_LOAD_UEFI_KEYS) += mokvar-table.o |
1096 | |
1097 | arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o |
1098 | obj-$(CONFIG_ARM) += $(arm-obj-y) |
1099 | diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c |
1100 | index a4bed96..c4848c3 100644 |
1101 | --- a/drivers/firmware/efi/arm-init.c |
1102 | +++ b/drivers/firmware/efi/arm-init.c |
1103 | @@ -263,6 +263,7 @@ void __init efi_init(void) |
1104 | |
1105 | reserve_regions(); |
1106 | efi_esrt_init(); |
1107 | + efi_mokvar_table_init(); |
1108 | |
1109 | memblock_reserve(params.mmap & PAGE_MASK, |
1110 | PAGE_ALIGN(params.mmap_size + |
1111 | diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c |
1112 | index e812f45..828c195 100644 |
1113 | --- a/drivers/firmware/efi/efi.c |
1114 | +++ b/drivers/firmware/efi/efi.c |
1115 | @@ -53,6 +53,9 @@ struct efi __read_mostly efi = { |
1116 | .rng_seed = EFI_INVALID_TABLE_ADDR, |
1117 | .tpm_log = EFI_INVALID_TABLE_ADDR, |
1118 | .tpm_final_log = EFI_INVALID_TABLE_ADDR, |
1119 | +#ifdef CONFIG_LOAD_UEFI_KEYS |
1120 | + .mokvar_table = EFI_INVALID_TABLE_ADDR, |
1121 | +#endif |
1122 | .mem_reserve = EFI_INVALID_TABLE_ADDR, |
1123 | }; |
1124 | EXPORT_SYMBOL(efi); |
1125 | @@ -480,6 +483,9 @@ static __initdata efi_config_table_type_t common_tables[] = { |
1126 | #ifdef CONFIG_EFI_RCI2_TABLE |
1127 | {DELLEMC_EFI_RCI2_TABLE_GUID, NULL, &rci2_table_phys}, |
1128 | #endif |
1129 | +#ifdef CONFIG_LOAD_UEFI_KEYS |
1130 | + {LINUX_EFI_MOK_VARIABLE_TABLE_GUID, "MOKvar", &efi.mokvar_table}, |
1131 | +#endif |
1132 | {NULL_GUID, NULL, NULL}, |
1133 | }; |
1134 | |
1135 | diff --git a/drivers/firmware/efi/mokvar-table.c b/drivers/firmware/efi/mokvar-table.c |
1136 | new file mode 100644 |
1137 | index 0000000..38722d2 |
1138 | --- /dev/null |
1139 | +++ b/drivers/firmware/efi/mokvar-table.c |
1140 | @@ -0,0 +1,362 @@ |
1141 | +// SPDX-License-Identifier: GPL-2.0 |
1142 | +/* |
1143 | + * mokvar-table.c |
1144 | + * |
1145 | + * Copyright (c) 2020 Red Hat |
1146 | + * Author: Lenny Szubowicz <lszubowi@redhat.com> |
1147 | + * |
1148 | + * This module contains the kernel support for the Linux EFI Machine |
1149 | + * Owner Key (MOK) variable configuration table, which is identified by |
1150 | + * the LINUX_EFI_MOK_VARIABLE_TABLE_GUID. |
1151 | + * |
1152 | + * This EFI configuration table provides a more robust alternative to |
1153 | + * EFI volatile variables by which an EFI boot loader can pass the |
1154 | + * contents of the Machine Owner Key (MOK) certificate stores to the |
1155 | + * kernel during boot. If both the EFI MOK config table and corresponding |
1156 | + * EFI MOK variables are present, the table should be considered as |
1157 | + * more authoritative. |
1158 | + * |
1159 | + * This module includes code that validates and maps the EFI MOK table, |
1160 | + * if it's presence was detected very early in boot. |
1161 | + * |
1162 | + * Kernel interface routines are provided to walk through all the |
1163 | + * entries in the MOK config table or to search for a specific named |
1164 | + * entry. |
1165 | + * |
1166 | + * The contents of the individual named MOK config table entries are |
1167 | + * made available to user space via read-only sysfs binary files under: |
1168 | + * |
1169 | + * /sys/firmware/efi/mok-variables/ |
1170 | + * |
1171 | + */ |
1172 | +#define pr_fmt(fmt) "mokvar: " fmt |
1173 | + |
1174 | +#include <linux/capability.h> |
1175 | +#include <linux/efi.h> |
1176 | +#include <linux/init.h> |
1177 | +#include <linux/io.h> |
1178 | +#include <linux/kernel.h> |
1179 | +#include <linux/kobject.h> |
1180 | +#include <linux/list.h> |
1181 | +#include <linux/slab.h> |
1182 | + |
1183 | +#include <asm/early_ioremap.h> |
1184 | + |
1185 | +/* |
1186 | + * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table is a packed |
1187 | + * sequence of struct efi_mokvar_table_entry, one for each named |
1188 | + * MOK variable. The sequence is terminated by an entry with a |
1189 | + * completely NULL name and 0 data size. |
1190 | + * |
1191 | + * efi_mokvar_table_size is set to the computed size of the |
1192 | + * MOK config table by efi_mokvar_table_init(). This will be |
1193 | + * non-zero if and only if the table if present and has been |
1194 | + * validated by efi_mokvar_table_init(). |
1195 | + */ |
1196 | +static size_t efi_mokvar_table_size; |
1197 | + |
1198 | +/* |
1199 | + * efi_mokvar_table_va is the kernel virtual address at which the |
1200 | + * EFI MOK config table has been mapped by efi_mokvar_sysfs_init(). |
1201 | + */ |
1202 | +static struct efi_mokvar_table_entry *efi_mokvar_table_va; |
1203 | + |
1204 | +/* |
1205 | + * Each /sys/firmware/efi/mok-variables/ sysfs file is represented by |
1206 | + * an instance of struct efi_mokvar_sysfs_attr on efi_mokvar_sysfs_list. |
1207 | + * bin_attr.private points to the associated EFI MOK config table entry. |
1208 | + * |
1209 | + * This list is created during boot and then remains unchanged. |
1210 | + * So no synchronization is currently required to walk the list. |
1211 | + */ |
1212 | +struct efi_mokvar_sysfs_attr { |
1213 | + struct bin_attribute bin_attr; |
1214 | + struct list_head node; |
1215 | +}; |
1216 | + |
1217 | +static LIST_HEAD(efi_mokvar_sysfs_list); |
1218 | +static struct kobject *mokvar_kobj; |
1219 | + |
1220 | +/* |
1221 | + * efi_mokvar_table_init() - Early boot validation of EFI MOK config table |
1222 | + * |
1223 | + * If present, validate and compute the size of the EFI MOK variable |
1224 | + * configuration table. This table may be provided by an EFI boot loader |
1225 | + * as an alternative to ordinary EFI variables, due to platform-dependent |
1226 | + * limitations. The memory occupied by this table is marked as reserved. |
1227 | + * |
1228 | + * This routine must be called before efi_free_boot_services() in order |
1229 | + * to guarantee that it can mark the table as reserved. |
1230 | + * |
1231 | + * Implicit inputs: |
1232 | + * efi.mokvar_table: Physical address of EFI MOK variable config table |
1233 | + * or special value that indicates no such table. |
1234 | + * |
1235 | + * Implicit outputs: |
1236 | + * efi_mokvar_table_size: Computed size of EFI MOK variable config table. |
1237 | + * The table is considered present and valid if this |
1238 | + * is non-zero. |
1239 | + */ |
1240 | +void __init efi_mokvar_table_init(void) |
1241 | +{ |
1242 | + efi_memory_desc_t md; |
1243 | + void *va = NULL; |
1244 | + unsigned long cur_offset = 0; |
1245 | + unsigned long offset_limit; |
1246 | + unsigned long map_size = 0; |
1247 | + unsigned long map_size_needed = 0; |
1248 | + unsigned long size; |
1249 | + struct efi_mokvar_table_entry *mokvar_entry; |
1250 | + int err; |
1251 | + |
1252 | + if (!efi_enabled(EFI_MEMMAP)) |
1253 | + return; |
1254 | + |
1255 | + if (efi.mokvar_table == EFI_INVALID_TABLE_ADDR) |
1256 | + return; |
1257 | + /* |
1258 | + * The EFI MOK config table must fit within a single EFI memory |
1259 | + * descriptor range. |
1260 | + */ |
1261 | + err = efi_mem_desc_lookup(efi.mokvar_table, &md); |
1262 | + if (err) { |
1263 | + pr_warn("EFI MOKvar config table is not within the EFI memory map\n"); |
1264 | + return; |
1265 | + } |
1266 | + |
1267 | + offset_limit = efi_mem_desc_end(&md) - efi.mokvar_table; |
1268 | + |
1269 | + /* |
1270 | + * Validate the MOK config table. Since there is no table header |
1271 | + * from which we could get the total size of the MOK config table, |
1272 | + * we compute the total size as we validate each variably sized |
1273 | + * entry, remapping as necessary. |
1274 | + */ |
1275 | + err = -EINVAL; |
1276 | + while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) { |
1277 | + mokvar_entry = va + cur_offset; |
1278 | + map_size_needed = cur_offset + sizeof(*mokvar_entry); |
1279 | + if (map_size_needed > map_size) { |
1280 | + if (va) |
1281 | + early_memunmap(va, map_size); |
1282 | + /* |
1283 | + * Map a little more than the fixed size entry |
1284 | + * header, anticipating some data. It's safe to |
1285 | + * do so as long as we stay within current memory |
1286 | + * descriptor. |
1287 | + */ |
1288 | + map_size = min(map_size_needed + 2*EFI_PAGE_SIZE, |
1289 | + offset_limit); |
1290 | + va = early_memremap(efi.mokvar_table, map_size); |
1291 | + if (!va) { |
1292 | + pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n", |
1293 | + efi.mokvar_table, map_size); |
1294 | + return; |
1295 | + } |
1296 | + mokvar_entry = va + cur_offset; |
1297 | + } |
1298 | + |
1299 | + /* Check for last sentinel entry */ |
1300 | + if (mokvar_entry->name[0] == '\0') { |
1301 | + if (mokvar_entry->data_size != 0) |
1302 | + break; |
1303 | + err = 0; |
1304 | + break; |
1305 | + } |
1306 | + |
1307 | + /* Sanity check that the name is null terminated */ |
1308 | + size = strnlen(mokvar_entry->name, |
1309 | + sizeof(mokvar_entry->name)); |
1310 | + if (size >= sizeof(mokvar_entry->name)) |
1311 | + break; |
1312 | + |
1313 | + /* Advance to the next entry */ |
1314 | + cur_offset = map_size_needed + mokvar_entry->data_size; |
1315 | + } |
1316 | + |
1317 | + if (va) |
1318 | + early_memunmap(va, map_size); |
1319 | + if (err) { |
1320 | + pr_err("EFI MOKvar config table is not valid\n"); |
1321 | + return; |
1322 | + } |
1323 | + |
1324 | + if (md.type == EFI_BOOT_SERVICES_DATA) |
1325 | + efi_mem_reserve(efi.mokvar_table, map_size_needed); |
1326 | + |
1327 | + efi_mokvar_table_size = map_size_needed; |
1328 | +} |
1329 | + |
1330 | +/* |
1331 | + * efi_mokvar_entry_next() - Get next entry in the EFI MOK config table |
1332 | + * |
1333 | + * mokvar_entry: Pointer to current EFI MOK config table entry |
1334 | + * or null. Null indicates get first entry. |
1335 | + * Passed by reference. This is updated to the |
1336 | + * same value as the return value. |
1337 | + * |
1338 | + * Returns: Pointer to next EFI MOK config table entry |
1339 | + * or null, if there are no more entries. |
1340 | + * Same value is returned in the mokvar_entry |
1341 | + * parameter. |
1342 | + * |
1343 | + * This routine depends on the EFI MOK config table being entirely |
1344 | + * mapped with it's starting virtual address in efi_mokvar_table_va. |
1345 | + */ |
1346 | +struct efi_mokvar_table_entry *efi_mokvar_entry_next( |
1347 | + struct efi_mokvar_table_entry **mokvar_entry) |
1348 | +{ |
1349 | + struct efi_mokvar_table_entry *mokvar_cur; |
1350 | + struct efi_mokvar_table_entry *mokvar_next; |
1351 | + size_t size_cur; |
1352 | + |
1353 | + mokvar_cur = *mokvar_entry; |
1354 | + *mokvar_entry = NULL; |
1355 | + |
1356 | + if (efi_mokvar_table_va == NULL) |
1357 | + return NULL; |
1358 | + |
1359 | + if (mokvar_cur == NULL) { |
1360 | + mokvar_next = efi_mokvar_table_va; |
1361 | + } else { |
1362 | + if (mokvar_cur->name[0] == '\0') |
1363 | + return NULL; |
1364 | + size_cur = sizeof(*mokvar_cur) + mokvar_cur->data_size; |
1365 | + mokvar_next = (void *)mokvar_cur + size_cur; |
1366 | + } |
1367 | + |
1368 | + if (mokvar_next->name[0] == '\0') |
1369 | + return NULL; |
1370 | + |
1371 | + *mokvar_entry = mokvar_next; |
1372 | + return mokvar_next; |
1373 | +} |
1374 | + |
1375 | +/* |
1376 | + * efi_mokvar_entry_find() - Find EFI MOK config entry by name |
1377 | + * |
1378 | + * name: Name of the entry to look for. |
1379 | + * |
1380 | + * Returns: Pointer to EFI MOK config table entry if found; |
1381 | + * null otherwise. |
1382 | + * |
1383 | + * This routine depends on the EFI MOK config table being entirely |
1384 | + * mapped with it's starting virtual address in efi_mokvar_table_va. |
1385 | + */ |
1386 | +struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name) |
1387 | +{ |
1388 | + struct efi_mokvar_table_entry *mokvar_entry = NULL; |
1389 | + |
1390 | + while (efi_mokvar_entry_next(&mokvar_entry)) { |
1391 | + if (!strncmp(name, mokvar_entry->name, |
1392 | + sizeof(mokvar_entry->name))) |
1393 | + return mokvar_entry; |
1394 | + } |
1395 | + return NULL; |
1396 | +} |
1397 | + |
1398 | +/* |
1399 | + * efi_mokvar_sysfs_read() - sysfs binary file read routine |
1400 | + * |
1401 | + * Returns: Count of bytes read. |
1402 | + * |
1403 | + * Copy EFI MOK config table entry data for this mokvar sysfs binary file |
1404 | + * to the supplied buffer, starting at the specified offset into mokvar table |
1405 | + * entry data, for the specified count bytes. The copy is limited by the |
1406 | + * amount of data in this mokvar config table entry. |
1407 | + */ |
1408 | +static ssize_t efi_mokvar_sysfs_read(struct file *file, struct kobject *kobj, |
1409 | + struct bin_attribute *bin_attr, char *buf, |
1410 | + loff_t off, size_t count) |
1411 | +{ |
1412 | + struct efi_mokvar_table_entry *mokvar_entry = bin_attr->private; |
1413 | + |
1414 | + if (!capable(CAP_SYS_ADMIN)) |
1415 | + return 0; |
1416 | + |
1417 | + if (off >= mokvar_entry->data_size) |
1418 | + return 0; |
1419 | + if (count > mokvar_entry->data_size - off) |
1420 | + count = mokvar_entry->data_size - off; |
1421 | + |
1422 | + memcpy(buf, mokvar_entry->data + off, count); |
1423 | + return count; |
1424 | +} |
1425 | + |
1426 | +/* |
1427 | + * efi_mokvar_sysfs_init() - Map EFI MOK config table and create sysfs |
1428 | + * |
1429 | + * Map the EFI MOK variable config table for run-time use by the kernel |
1430 | + * and create the sysfs entries in /sys/firmware/efi/mok-variables/ |
1431 | + * |
1432 | + * This routine just returns if a valid EFI MOK variable config table |
1433 | + * was not found earlier during boot. |
1434 | + * |
1435 | + * This routine must be called during a "middle" initcall phase, i.e. |
1436 | + * after efi_mokvar_table_init() but before UEFI certs are loaded |
1437 | + * during late init. |
1438 | + * |
1439 | + * Implicit inputs: |
1440 | + * efi.mokvar_table: Physical address of EFI MOK variable config table |
1441 | + * or special value that indicates no such table. |
1442 | + * |
1443 | + * efi_mokvar_table_size: Computed size of EFI MOK variable config table. |
1444 | + * The table is considered present and valid if this |
1445 | + * is non-zero. |
1446 | + * |
1447 | + * Implicit outputs: |
1448 | + * efi_mokvar_table_va: Start virtual address of the EFI MOK config table. |
1449 | + */ |
1450 | +static int __init efi_mokvar_sysfs_init(void) |
1451 | +{ |
1452 | + void *config_va; |
1453 | + struct efi_mokvar_table_entry *mokvar_entry = NULL; |
1454 | + struct efi_mokvar_sysfs_attr *mokvar_sysfs = NULL; |
1455 | + int err = 0; |
1456 | + |
1457 | + if (efi_mokvar_table_size == 0) |
1458 | + return -ENOENT; |
1459 | + |
1460 | + config_va = memremap(efi.mokvar_table, efi_mokvar_table_size, |
1461 | + MEMREMAP_WB); |
1462 | + if (!config_va) { |
1463 | + pr_err("Failed to map EFI MOKvar config table\n"); |
1464 | + return -ENOMEM; |
1465 | + } |
1466 | + efi_mokvar_table_va = config_va; |
1467 | + |
1468 | + mokvar_kobj = kobject_create_and_add("mok-variables", efi_kobj); |
1469 | + if (!mokvar_kobj) { |
1470 | + pr_err("Failed to create EFI mok-variables sysfs entry\n"); |
1471 | + return -ENOMEM; |
1472 | + } |
1473 | + |
1474 | + while (efi_mokvar_entry_next(&mokvar_entry)) { |
1475 | + mokvar_sysfs = kzalloc(sizeof(*mokvar_sysfs), GFP_KERNEL); |
1476 | + if (!mokvar_sysfs) { |
1477 | + err = -ENOMEM; |
1478 | + break; |
1479 | + } |
1480 | + |
1481 | + sysfs_bin_attr_init(&mokvar_sysfs->bin_attr); |
1482 | + mokvar_sysfs->bin_attr.private = mokvar_entry; |
1483 | + mokvar_sysfs->bin_attr.attr.name = mokvar_entry->name; |
1484 | + mokvar_sysfs->bin_attr.attr.mode = 0400; |
1485 | + mokvar_sysfs->bin_attr.size = mokvar_entry->data_size; |
1486 | + mokvar_sysfs->bin_attr.read = efi_mokvar_sysfs_read; |
1487 | + |
1488 | + err = sysfs_create_bin_file(mokvar_kobj, |
1489 | + &mokvar_sysfs->bin_attr); |
1490 | + if (err) |
1491 | + break; |
1492 | + |
1493 | + list_add_tail(&mokvar_sysfs->node, &efi_mokvar_sysfs_list); |
1494 | + } |
1495 | + |
1496 | + if (err) { |
1497 | + pr_err("Failed to create some EFI mok-variables sysfs entries\n"); |
1498 | + kfree(mokvar_sysfs); |
1499 | + } |
1500 | + return err; |
1501 | +} |
1502 | +device_initcall(efi_mokvar_sysfs_init); |
1503 | diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c |
1504 | index 2cf053f..1c691bd 100644 |
1505 | --- a/drivers/gpu/drm/drm_ioc32.c |
1506 | +++ b/drivers/gpu/drm/drm_ioc32.c |
1507 | @@ -863,8 +863,6 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, |
1508 | req.request.sequence = req32.request.sequence; |
1509 | req.request.signal = req32.request.signal; |
1510 | err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED); |
1511 | - if (err) |
1512 | - return err; |
1513 | |
1514 | req32.reply.type = req.reply.type; |
1515 | req32.reply.sequence = req.reply.sequence; |
1516 | @@ -873,7 +871,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, |
1517 | if (copy_to_user(argp, &req32, sizeof(req32))) |
1518 | return -EFAULT; |
1519 | |
1520 | - return 0; |
1521 | + return err; |
1522 | } |
1523 | |
1524 | #if defined(CONFIG_X86) |
1525 | diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c |
1526 | index de2ec4f..bf24fe2 100644 |
1527 | --- a/drivers/gpu/drm/i915/gt/intel_timeline.c |
1528 | +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c |
1529 | @@ -290,6 +290,14 @@ void intel_timeline_fini(struct intel_timeline *timeline) |
1530 | i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj); |
1531 | |
1532 | i915_vma_put(timeline->hwsp_ggtt); |
1533 | + |
1534 | + /* |
1535 | + * A small race exists between intel_gt_retire_requests_timeout and |
1536 | + * intel_timeline_exit which could result in the syncmap not getting |
1537 | + * free'd. Rather than work to hard to seal this race, simply cleanup |
1538 | + * the syncmap on fini. |
1539 | + */ |
1540 | + i915_syncmap_free(&timeline->sync); |
1541 | } |
1542 | |
1543 | struct intel_timeline * |
1544 | diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |
1545 | index 818d21b..1d2837c 100644 |
1546 | --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |
1547 | +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |
1548 | @@ -419,7 +419,7 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps) |
1549 | return ret; |
1550 | } |
1551 | |
1552 | -static void |
1553 | +void |
1554 | nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior) |
1555 | { |
1556 | struct nvkm_dp *dp = nvkm_dp(outp); |
1557 | diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h |
1558 | index 428b3f4..e484d0c 100644 |
1559 | --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h |
1560 | +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h |
1561 | @@ -32,6 +32,7 @@ struct nvkm_dp { |
1562 | |
1563 | int nvkm_dp_new(struct nvkm_disp *, int index, struct dcb_output *, |
1564 | struct nvkm_outp **); |
1565 | +void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *); |
1566 | |
1567 | /* DPCD Receiver Capabilities */ |
1568 | #define DPCD_RC00_DPCD_REV 0x00000 |
1569 | diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c |
1570 | index c62030c..4b1c72f 100644 |
1571 | --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c |
1572 | +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c |
1573 | @@ -22,6 +22,7 @@ |
1574 | * Authors: Ben Skeggs |
1575 | */ |
1576 | #include "outp.h" |
1577 | +#include "dp.h" |
1578 | #include "ior.h" |
1579 | |
1580 | #include <subdev/bios.h> |
1581 | @@ -216,6 +217,14 @@ nvkm_outp_init_route(struct nvkm_outp *outp) |
1582 | if (!ior->arm.head || ior->arm.proto != proto) { |
1583 | OUTP_DBG(outp, "no heads (%x %d %d)", ior->arm.head, |
1584 | ior->arm.proto, proto); |
1585 | + |
1586 | + /* The EFI GOP driver on Ampere can leave unused DP links routed, |
1587 | + * which we don't expect. The DisableLT IED script *should* get |
1588 | + * us back to where we need to be. |
1589 | + */ |
1590 | + if (ior->func->route.get && !ior->arm.head && outp->info.type == DCB_OUTPUT_DP) |
1591 | + nvkm_dp_disable(outp, ior); |
1592 | + |
1593 | return; |
1594 | } |
1595 | |
1596 | diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c |
1597 | index a1c85d1..82b244c 100644 |
1598 | --- a/drivers/gpu/ipu-v3/ipu-cpmem.c |
1599 | +++ b/drivers/gpu/ipu-v3/ipu-cpmem.c |
1600 | @@ -585,21 +585,21 @@ static const struct ipu_rgb def_bgra_16 = { |
1601 | .bits_per_pixel = 16, |
1602 | }; |
1603 | |
1604 | -#define Y_OFFSET(pix, x, y) ((x) + pix->width * (y)) |
1605 | -#define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \ |
1606 | - (pix->width * ((y) / 2) / 2) + (x) / 2) |
1607 | -#define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \ |
1608 | - (pix->width * pix->height / 4) + \ |
1609 | - (pix->width * ((y) / 2) / 2) + (x) / 2) |
1610 | -#define U2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ |
1611 | - (pix->width * (y) / 2) + (x) / 2) |
1612 | -#define V2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ |
1613 | - (pix->width * pix->height / 2) + \ |
1614 | - (pix->width * (y) / 2) + (x) / 2) |
1615 | -#define UV_OFFSET(pix, x, y) ((pix->width * pix->height) + \ |
1616 | - (pix->width * ((y) / 2)) + (x)) |
1617 | -#define UV2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ |
1618 | - (pix->width * y) + (x)) |
1619 | +#define Y_OFFSET(pix, x, y) ((x) + pix->bytesperline * (y)) |
1620 | +#define U_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ |
1621 | + (pix->bytesperline * ((y) / 2) / 2) + (x) / 2) |
1622 | +#define V_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ |
1623 | + (pix->bytesperline * pix->height / 4) + \ |
1624 | + (pix->bytesperline * ((y) / 2) / 2) + (x) / 2) |
1625 | +#define U2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ |
1626 | + (pix->bytesperline * (y) / 2) + (x) / 2) |
1627 | +#define V2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ |
1628 | + (pix->bytesperline * pix->height / 2) + \ |
1629 | + (pix->bytesperline * (y) / 2) + (x) / 2) |
1630 | +#define UV_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ |
1631 | + (pix->bytesperline * ((y) / 2)) + (x)) |
1632 | +#define UV2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ |
1633 | + (pix->bytesperline * y) + (x)) |
1634 | |
1635 | #define NUM_ALPHA_CHANNELS 7 |
1636 | |
1637 | diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c |
1638 | index 970c259..3a439f7 100644 |
1639 | --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c |
1640 | +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c |
1641 | @@ -1404,6 +1404,7 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq, |
1642 | if (nq) |
1643 | nq->budget++; |
1644 | atomic_inc(&rdev->srq_count); |
1645 | + spin_lock_init(&srq->lock); |
1646 | |
1647 | return 0; |
1648 | |
1649 | diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c |
1650 | index 6c2e849..58be31f 100644 |
1651 | --- a/drivers/infiniband/hw/efa/efa_main.c |
1652 | +++ b/drivers/infiniband/hw/efa/efa_main.c |
1653 | @@ -342,6 +342,7 @@ static int efa_enable_msix(struct efa_dev *dev) |
1654 | } |
1655 | |
1656 | if (irq_num != msix_vecs) { |
1657 | + efa_disable_msix(dev); |
1658 | dev_err(&dev->pdev->dev, |
1659 | "Allocated %d MSI-X (out of %d requested)\n", |
1660 | irq_num, msix_vecs); |
1661 | diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c |
1662 | index c61b602..248be21 100644 |
1663 | --- a/drivers/infiniband/hw/hfi1/sdma.c |
1664 | +++ b/drivers/infiniband/hw/hfi1/sdma.c |
1665 | @@ -3056,6 +3056,7 @@ static void __sdma_process_event(struct sdma_engine *sde, |
1666 | static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) |
1667 | { |
1668 | int i; |
1669 | + struct sdma_desc *descp; |
1670 | |
1671 | /* Handle last descriptor */ |
1672 | if (unlikely((tx->num_desc == (MAX_DESC - 1)))) { |
1673 | @@ -3076,12 +3077,10 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) |
1674 | if (unlikely(tx->num_desc == MAX_DESC)) |
1675 | goto enomem; |
1676 | |
1677 | - tx->descp = kmalloc_array( |
1678 | - MAX_DESC, |
1679 | - sizeof(struct sdma_desc), |
1680 | - GFP_ATOMIC); |
1681 | - if (!tx->descp) |
1682 | + descp = kmalloc_array(MAX_DESC, sizeof(struct sdma_desc), GFP_ATOMIC); |
1683 | + if (!descp) |
1684 | goto enomem; |
1685 | + tx->descp = descp; |
1686 | |
1687 | /* reserve last descriptor for coalescing */ |
1688 | tx->desc_limit = MAX_DESC - 1; |
1689 | diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c |
1690 | index 21f90a8..7d6a4ff 100644 |
1691 | --- a/drivers/media/usb/stkwebcam/stk-webcam.c |
1692 | +++ b/drivers/media/usb/stkwebcam/stk-webcam.c |
1693 | @@ -1346,7 +1346,7 @@ static int stk_camera_probe(struct usb_interface *interface, |
1694 | if (!dev->isoc_ep) { |
1695 | pr_err("Could not find isoc-in endpoint\n"); |
1696 | err = -ENODEV; |
1697 | - goto error; |
1698 | + goto error_put; |
1699 | } |
1700 | dev->vsettings.palette = V4L2_PIX_FMT_RGB565; |
1701 | dev->vsettings.mode = MODE_VGA; |
1702 | @@ -1359,10 +1359,12 @@ static int stk_camera_probe(struct usb_interface *interface, |
1703 | |
1704 | err = stk_register_video_device(dev); |
1705 | if (err) |
1706 | - goto error; |
1707 | + goto error_put; |
1708 | |
1709 | return 0; |
1710 | |
1711 | +error_put: |
1712 | + usb_put_intf(interface); |
1713 | error: |
1714 | v4l2_ctrl_handler_free(hdl); |
1715 | v4l2_device_unregister(&dev->v4l2_dev); |
1716 | diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c |
1717 | index 8bed81c..8ab9630 100644 |
1718 | --- a/drivers/mmc/host/sdhci-msm.c |
1719 | +++ b/drivers/mmc/host/sdhci-msm.c |
1720 | @@ -1589,6 +1589,23 @@ out: |
1721 | __sdhci_msm_set_clock(host, clock); |
1722 | } |
1723 | |
1724 | +static void sdhci_msm_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) |
1725 | +{ |
1726 | + u32 count, start = 15; |
1727 | + |
1728 | + __sdhci_set_timeout(host, cmd); |
1729 | + count = sdhci_readb(host, SDHCI_TIMEOUT_CONTROL); |
1730 | + /* |
1731 | + * Update software timeout value if its value is less than hardware data |
1732 | + * timeout value. Qcom SoC hardware data timeout value was calculated |
1733 | + * using 4 * MCLK * 2^(count + 13). where MCLK = 1 / host->clock. |
1734 | + */ |
1735 | + if (cmd && cmd->data && host->clock > 400000 && |
1736 | + host->clock <= 50000000 && |
1737 | + ((1 << (count + start)) > (10 * host->clock))) |
1738 | + host->data_timeout = 22LL * NSEC_PER_SEC; |
1739 | +} |
1740 | + |
1741 | /* |
1742 | * Platform specific register write functions. This is so that, if any |
1743 | * register write needs to be followed up by platform specific actions, |
1744 | @@ -1753,6 +1770,7 @@ static const struct sdhci_ops sdhci_msm_ops = { |
1745 | .set_uhs_signaling = sdhci_msm_set_uhs_signaling, |
1746 | .write_w = sdhci_msm_writew, |
1747 | .write_b = sdhci_msm_writeb, |
1748 | + .set_timeout = sdhci_msm_set_timeout, |
1749 | }; |
1750 | |
1751 | static const struct sdhci_pltfm_data sdhci_msm_pdata = { |
1752 | diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c |
1753 | index 485e20e..8847942 100644 |
1754 | --- a/drivers/net/can/usb/esd_usb2.c |
1755 | +++ b/drivers/net/can/usb/esd_usb2.c |
1756 | @@ -224,8 +224,8 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, |
1757 | if (id == ESD_EV_CAN_ERROR_EXT) { |
1758 | u8 state = msg->msg.rx.data[0]; |
1759 | u8 ecc = msg->msg.rx.data[1]; |
1760 | - u8 txerr = msg->msg.rx.data[2]; |
1761 | - u8 rxerr = msg->msg.rx.data[3]; |
1762 | + u8 rxerr = msg->msg.rx.data[2]; |
1763 | + u8 txerr = msg->msg.rx.data[3]; |
1764 | |
1765 | skb = alloc_can_err_skb(priv->netdev, &cf); |
1766 | if (skb == NULL) { |
1767 | diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c |
1768 | index e1a3c33..2d8382e 100644 |
1769 | --- a/drivers/net/dsa/mt7530.c |
1770 | +++ b/drivers/net/dsa/mt7530.c |
1771 | @@ -842,11 +842,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, |
1772 | /* Remove this port from the port matrix of the other ports |
1773 | * in the same bridge. If the port is disabled, port matrix |
1774 | * is kept and not being setup until the port becomes enabled. |
1775 | - * And the other port's port matrix cannot be broken when the |
1776 | - * other port is still a VLAN-aware port. |
1777 | */ |
1778 | - if (dsa_is_user_port(ds, i) && i != port && |
1779 | - !dsa_port_is_vlan_filtering(&ds->ports[i])) { |
1780 | + if (dsa_is_user_port(ds, i) && i != port) { |
1781 | if (dsa_to_port(ds, i)->bridge_dev != bridge) |
1782 | continue; |
1783 | if (priv->ports[i].enable) |
1784 | diff --git a/drivers/net/ethernet/apm/xgene-v2/main.c b/drivers/net/ethernet/apm/xgene-v2/main.c |
1785 | index 02b4f3a..848be6b 100644 |
1786 | --- a/drivers/net/ethernet/apm/xgene-v2/main.c |
1787 | +++ b/drivers/net/ethernet/apm/xgene-v2/main.c |
1788 | @@ -677,11 +677,13 @@ static int xge_probe(struct platform_device *pdev) |
1789 | ret = register_netdev(ndev); |
1790 | if (ret) { |
1791 | netdev_err(ndev, "Failed to register netdev\n"); |
1792 | - goto err; |
1793 | + goto err_mdio_remove; |
1794 | } |
1795 | |
1796 | return 0; |
1797 | |
1798 | +err_mdio_remove: |
1799 | + xge_mdio_remove(ndev); |
1800 | err: |
1801 | free_netdev(ndev); |
1802 | |
1803 | diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c |
1804 | index 43a3f0d..f5aec28 100644 |
1805 | --- a/drivers/net/ethernet/cadence/macb_ptp.c |
1806 | +++ b/drivers/net/ethernet/cadence/macb_ptp.c |
1807 | @@ -275,6 +275,12 @@ void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb, |
1808 | |
1809 | if (GEM_BFEXT(DMA_RXVALID, desc->addr)) { |
1810 | desc_ptp = macb_ptp_desc(bp, desc); |
1811 | + /* Unlikely but check */ |
1812 | + if (!desc_ptp) { |
1813 | + dev_warn_ratelimited(&bp->pdev->dev, |
1814 | + "Timestamp not supported in BD\n"); |
1815 | + return; |
1816 | + } |
1817 | gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts); |
1818 | memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); |
1819 | shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); |
1820 | @@ -307,8 +313,11 @@ int gem_ptp_txstamp(struct macb_queue *queue, struct sk_buff *skb, |
1821 | if (CIRC_SPACE(head, tail, PTP_TS_BUFFER_SIZE) == 0) |
1822 | return -ENOMEM; |
1823 | |
1824 | - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
1825 | desc_ptp = macb_ptp_desc(queue->bp, desc); |
1826 | + /* Unlikely but check */ |
1827 | + if (!desc_ptp) |
1828 | + return -EINVAL; |
1829 | + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
1830 | tx_timestamp = &queue->tx_timestamps[head]; |
1831 | tx_timestamp->skb = skb; |
1832 | /* ensure ts_1/ts_2 is loaded after ctrl (TX_USED check) */ |
1833 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |
1834 | index 06bcdec..dbc11f4 100644 |
1835 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |
1836 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |
1837 | @@ -261,6 +261,9 @@ enum hclge_opcode_type { |
1838 | /* Led command */ |
1839 | HCLGE_OPC_LED_STATUS_CFG = 0xB000, |
1840 | |
1841 | + /* clear hardware resource command */ |
1842 | + HCLGE_OPC_CLEAR_HW_RESOURCE = 0x700B, |
1843 | + |
1844 | /* NCL config command */ |
1845 | HCLGE_OPC_QUERY_NCL_CONFIG = 0x7011, |
1846 | |
1847 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c |
1848 | index d6c3952..2e82c54 100644 |
1849 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c |
1850 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c |
1851 | @@ -281,21 +281,12 @@ static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) |
1852 | u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC]; |
1853 | struct hclge_vport *vport = hclge_get_vport(h); |
1854 | struct hclge_dev *hdev = vport->back; |
1855 | - u8 i, j, pfc_map, *prio_tc; |
1856 | int ret; |
1857 | + u8 i; |
1858 | |
1859 | memset(pfc, 0, sizeof(*pfc)); |
1860 | pfc->pfc_cap = hdev->pfc_max; |
1861 | - prio_tc = hdev->tm_info.prio_tc; |
1862 | - pfc_map = hdev->tm_info.hw_pfc_map; |
1863 | - |
1864 | - /* Pfc setting is based on TC */ |
1865 | - for (i = 0; i < hdev->tm_info.num_tc; i++) { |
1866 | - for (j = 0; j < HNAE3_MAX_USER_PRIO; j++) { |
1867 | - if ((prio_tc[j] == i) && (pfc_map & BIT(i))) |
1868 | - pfc->pfc_en |= BIT(j); |
1869 | - } |
1870 | - } |
1871 | + pfc->pfc_en = hdev->tm_info.pfc_en; |
1872 | |
1873 | ret = hclge_pfc_tx_stats_get(hdev, requests); |
1874 | if (ret) |
1875 | diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
1876 | index ab44a99..3bbcd46 100644 |
1877 | --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
1878 | +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c |
1879 | @@ -8230,7 +8230,11 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) |
1880 | static void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, |
1881 | bool writen_to_tbl) |
1882 | { |
1883 | - struct hclge_vport_vlan_cfg *vlan; |
1884 | + struct hclge_vport_vlan_cfg *vlan, *tmp; |
1885 | + |
1886 | + list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) |
1887 | + if (vlan->vlan_id == vlan_id) |
1888 | + return; |
1889 | |
1890 | vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); |
1891 | if (!vlan) |
1892 | @@ -9423,6 +9427,28 @@ static void hclge_clear_resetting_state(struct hclge_dev *hdev) |
1893 | } |
1894 | } |
1895 | |
1896 | +static int hclge_clear_hw_resource(struct hclge_dev *hdev) |
1897 | +{ |
1898 | + struct hclge_desc desc; |
1899 | + int ret; |
1900 | + |
1901 | + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CLEAR_HW_RESOURCE, false); |
1902 | + |
1903 | + ret = hclge_cmd_send(&hdev->hw, &desc, 1); |
1904 | + /* This new command is only supported by new firmware, it will |
1905 | + * fail with older firmware. Error value -EOPNOSUPP can only be |
1906 | + * returned by older firmware running this command, to keep code |
1907 | + * backward compatible we will override this value and return |
1908 | + * success. |
1909 | + */ |
1910 | + if (ret && ret != -EOPNOTSUPP) { |
1911 | + dev_err(&hdev->pdev->dev, |
1912 | + "failed to clear hw resource, ret = %d\n", ret); |
1913 | + return ret; |
1914 | + } |
1915 | + return 0; |
1916 | +} |
1917 | + |
1918 | static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) |
1919 | { |
1920 | struct pci_dev *pdev = ae_dev->pdev; |
1921 | @@ -9466,6 +9492,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) |
1922 | if (ret) |
1923 | goto err_cmd_uninit; |
1924 | |
1925 | + ret = hclge_clear_hw_resource(hdev); |
1926 | + if (ret) |
1927 | + goto err_cmd_uninit; |
1928 | + |
1929 | ret = hclge_get_cap(hdev); |
1930 | if (ret) { |
1931 | dev_err(&pdev->dev, "get hw capability error, ret = %d.\n", |
1932 | diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c |
1933 | index d31ba15..589c5db 100644 |
1934 | --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c |
1935 | +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c |
1936 | @@ -995,6 +995,8 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link) |
1937 | { |
1938 | u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) | |
1939 | link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND; |
1940 | + u16 max_ltr_enc_d = 0; /* maximum LTR decoded by platform */ |
1941 | + u16 lat_enc_d = 0; /* latency decoded */ |
1942 | u16 lat_enc = 0; /* latency encoded */ |
1943 | |
1944 | if (link) { |
1945 | @@ -1048,7 +1050,17 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link) |
1946 | E1000_PCI_LTR_CAP_LPT + 2, &max_nosnoop); |
1947 | max_ltr_enc = max_t(u16, max_snoop, max_nosnoop); |
1948 | |
1949 | - if (lat_enc > max_ltr_enc) |
1950 | + lat_enc_d = (lat_enc & E1000_LTRV_VALUE_MASK) * |
1951 | + (1U << (E1000_LTRV_SCALE_FACTOR * |
1952 | + ((lat_enc & E1000_LTRV_SCALE_MASK) |
1953 | + >> E1000_LTRV_SCALE_SHIFT))); |
1954 | + |
1955 | + max_ltr_enc_d = (max_ltr_enc & E1000_LTRV_VALUE_MASK) * |
1956 | + (1U << (E1000_LTRV_SCALE_FACTOR * |
1957 | + ((max_ltr_enc & E1000_LTRV_SCALE_MASK) |
1958 | + >> E1000_LTRV_SCALE_SHIFT))); |
1959 | + |
1960 | + if (lat_enc_d > max_ltr_enc_d) |
1961 | lat_enc = max_ltr_enc; |
1962 | } |
1963 | |
1964 | diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h |
1965 | index 1502895..e757896 100644 |
1966 | --- a/drivers/net/ethernet/intel/e1000e/ich8lan.h |
1967 | +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h |
1968 | @@ -274,8 +274,11 @@ |
1969 | |
1970 | /* Latency Tolerance Reporting */ |
1971 | #define E1000_LTRV 0x000F8 |
1972 | +#define E1000_LTRV_VALUE_MASK 0x000003FF |
1973 | #define E1000_LTRV_SCALE_MAX 5 |
1974 | #define E1000_LTRV_SCALE_FACTOR 5 |
1975 | +#define E1000_LTRV_SCALE_SHIFT 10 |
1976 | +#define E1000_LTRV_SCALE_MASK 0x00001C00 |
1977 | #define E1000_LTRV_REQ_SHIFT 15 |
1978 | #define E1000_LTRV_NOSNOOP_SHIFT 16 |
1979 | #define E1000_LTRV_SEND (1 << 30) |
1980 | diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c |
1981 | index 7b05430..64aa551 100644 |
1982 | --- a/drivers/net/ethernet/marvell/mvneta.c |
1983 | +++ b/drivers/net/ethernet/marvell/mvneta.c |
1984 | @@ -101,7 +101,7 @@ |
1985 | #define MVNETA_DESC_SWAP BIT(6) |
1986 | #define MVNETA_TX_BRST_SZ_MASK(burst) ((burst) << 22) |
1987 | #define MVNETA_PORT_STATUS 0x2444 |
1988 | -#define MVNETA_TX_IN_PRGRS BIT(1) |
1989 | +#define MVNETA_TX_IN_PRGRS BIT(0) |
1990 | #define MVNETA_TX_FIFO_EMPTY BIT(8) |
1991 | #define MVNETA_RX_MIN_FRAME_SIZE 0x247c |
1992 | /* Only exists on Armada XP and Armada 370 */ |
1993 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c |
1994 | index 19a1a58..c449ecc 100644 |
1995 | --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c |
1996 | +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c |
1997 | @@ -353,6 +353,9 @@ static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) |
1998 | unsigned long flags; |
1999 | int rc = -EINVAL; |
2000 | |
2001 | + if (!p_ll2_conn) |
2002 | + return rc; |
2003 | + |
2004 | spin_lock_irqsave(&p_tx->lock, flags); |
2005 | if (p_tx->b_completing_packet) { |
2006 | rc = -EBUSY; |
2007 | @@ -526,7 +529,16 @@ static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie) |
2008 | unsigned long flags = 0; |
2009 | int rc = 0; |
2010 | |
2011 | + if (!p_ll2_conn) |
2012 | + return rc; |
2013 | + |
2014 | spin_lock_irqsave(&p_rx->lock, flags); |
2015 | + |
2016 | + if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) { |
2017 | + spin_unlock_irqrestore(&p_rx->lock, flags); |
2018 | + return 0; |
2019 | + } |
2020 | + |
2021 | cq_new_idx = le16_to_cpu(*p_rx->p_fw_cons); |
2022 | cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain); |
2023 | |
2024 | @@ -847,6 +859,9 @@ static int qed_ll2_lb_rxq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) |
2025 | struct qed_ll2_info *p_ll2_conn = (struct qed_ll2_info *)p_cookie; |
2026 | int rc; |
2027 | |
2028 | + if (!p_ll2_conn) |
2029 | + return 0; |
2030 | + |
2031 | if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) |
2032 | return 0; |
2033 | |
2034 | @@ -870,6 +885,9 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) |
2035 | u16 new_idx = 0, num_bds = 0; |
2036 | int rc; |
2037 | |
2038 | + if (!p_ll2_conn) |
2039 | + return 0; |
2040 | + |
2041 | if (!QED_LL2_TX_REGISTERED(p_ll2_conn)) |
2042 | return 0; |
2043 | |
2044 | @@ -1642,6 +1660,8 @@ int qed_ll2_post_rx_buffer(void *cxt, |
2045 | if (!p_ll2_conn) |
2046 | return -EINVAL; |
2047 | p_rx = &p_ll2_conn->rx_queue; |
2048 | + if (!p_rx->set_prod_addr) |
2049 | + return -EIO; |
2050 | |
2051 | spin_lock_irqsave(&p_rx->lock, flags); |
2052 | if (!list_empty(&p_rx->free_descq)) |
2053 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c |
2054 | index bc1f5b3..1db4942 100644 |
2055 | --- a/drivers/net/ethernet/qlogic/qed/qed_main.c |
2056 | +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c |
2057 | @@ -559,7 +559,12 @@ static int qed_enable_msix(struct qed_dev *cdev, |
2058 | rc = cnt; |
2059 | } |
2060 | |
2061 | - if (rc > 0) { |
2062 | + /* For VFs, we should return with an error in case we didn't get the |
2063 | + * exact number of msix vectors as we requested. |
2064 | + * Not doing that will lead to a crash when starting queues for |
2065 | + * this VF. |
2066 | + */ |
2067 | + if ((IS_PF(cdev) && rc > 0) || (IS_VF(cdev) && rc == cnt)) { |
2068 | /* MSI-x configuration was achieved */ |
2069 | int_params->out.int_mode = QED_INT_MODE_MSIX; |
2070 | int_params->out.num_vectors = rc; |
2071 | diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c |
2072 | index 38b1f40..b291971 100644 |
2073 | --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c |
2074 | +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c |
2075 | @@ -1245,8 +1245,7 @@ qed_rdma_create_qp(void *rdma_cxt, |
2076 | |
2077 | if (!rdma_cxt || !in_params || !out_params || |
2078 | !p_hwfn->p_rdma_info->active) { |
2079 | - DP_ERR(p_hwfn->cdev, |
2080 | - "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", |
2081 | + pr_err("qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", |
2082 | rdma_cxt, in_params, out_params); |
2083 | return NULL; |
2084 | } |
2085 | diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c |
2086 | index ce3e62e..1133f6f 100644 |
2087 | --- a/drivers/net/ethernet/qlogic/qede/qede_main.c |
2088 | +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c |
2089 | @@ -1773,6 +1773,7 @@ static void qede_sync_free_irqs(struct qede_dev *edev) |
2090 | } |
2091 | |
2092 | edev->int_info.used_cnt = 0; |
2093 | + edev->int_info.msix_cnt = 0; |
2094 | } |
2095 | |
2096 | static int qede_req_msix_irqs(struct qede_dev *edev) |
2097 | @@ -2317,7 +2318,6 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode, |
2098 | goto out; |
2099 | err4: |
2100 | qede_sync_free_irqs(edev); |
2101 | - memset(&edev->int_info.msix_cnt, 0, sizeof(struct qed_int_info)); |
2102 | err3: |
2103 | qede_napi_disable_remove(edev); |
2104 | err2: |
2105 | diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c |
2106 | index 6ab8e35..a4793dd 100644 |
2107 | --- a/drivers/net/ethernet/realtek/r8169_main.c |
2108 | +++ b/drivers/net/ethernet/realtek/r8169_main.c |
2109 | @@ -4684,6 +4684,7 @@ static void rtl_hw_start_8168g(struct rtl8169_private *tp) |
2110 | rtl_eri_clear_bits(tp, 0x1b0, ERIAR_MASK_0011, BIT(12)); |
2111 | |
2112 | rtl_pcie_state_l2l3_disable(tp); |
2113 | + rtl_hw_aspm_clkreq_enable(tp, true); |
2114 | } |
2115 | |
2116 | static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) |
2117 | diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c |
2118 | index e85be21..dbd753b 100644 |
2119 | --- a/drivers/net/ethernet/xilinx/ll_temac_main.c |
2120 | +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c |
2121 | @@ -939,10 +939,8 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
2122 | wmb(); |
2123 | lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ |
2124 | |
2125 | - if (temac_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) { |
2126 | - netdev_info(ndev, "%s -> netif_stop_queue\n", __func__); |
2127 | + if (temac_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) |
2128 | netif_stop_queue(ndev); |
2129 | - } |
2130 | |
2131 | return NETDEV_TX_OK; |
2132 | } |
2133 | diff --git a/drivers/opp/of.c b/drivers/opp/of.c |
2134 | index 249738e..603c688 100644 |
2135 | --- a/drivers/opp/of.c |
2136 | +++ b/drivers/opp/of.c |
2137 | @@ -682,8 +682,9 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) |
2138 | } |
2139 | } |
2140 | |
2141 | - /* There should be one of more OPP defined */ |
2142 | - if (WARN_ON(!count)) { |
2143 | + /* There should be one or more OPPs defined */ |
2144 | + if (!count) { |
2145 | + dev_err(dev, "%s: no supported OPPs", __func__); |
2146 | ret = -ENOENT; |
2147 | goto remove_static_opp; |
2148 | } |
2149 | diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
2150 | index 4c9d9a5..2b3ff18 100644 |
2151 | --- a/drivers/pci/quirks.c |
2152 | +++ b/drivers/pci/quirks.c |
2153 | @@ -3261,12 +3261,12 @@ static void fixup_mpss_256(struct pci_dev *dev) |
2154 | { |
2155 | dev->pcie_mpss = 1; /* 256 bytes */ |
2156 | } |
2157 | -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, |
2158 | - PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0, fixup_mpss_256); |
2159 | -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, |
2160 | - PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256); |
2161 | -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, |
2162 | - PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256); |
2163 | +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, |
2164 | + PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0, fixup_mpss_256); |
2165 | +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, |
2166 | + PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256); |
2167 | +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, |
2168 | + PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256); |
2169 | |
2170 | /* |
2171 | * Intel 5000 and 5100 Memory controllers have an erratum with read completion |
2172 | diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c |
2173 | index 99e75d9..8a7473b 100644 |
2174 | --- a/drivers/reset/reset-zynqmp.c |
2175 | +++ b/drivers/reset/reset-zynqmp.c |
2176 | @@ -46,7 +46,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev, |
2177 | unsigned long id) |
2178 | { |
2179 | struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev); |
2180 | - int val, err; |
2181 | + int err; |
2182 | + u32 val; |
2183 | |
2184 | err = priv->eemi_ops->reset_get_status(ZYNQMP_RESET_ID + id, &val); |
2185 | if (err) |
2186 | diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c |
2187 | index 11592ec..6aeb79e 100644 |
2188 | --- a/drivers/scsi/scsi_sysfs.c |
2189 | +++ b/drivers/scsi/scsi_sysfs.c |
2190 | @@ -788,12 +788,15 @@ store_state_field(struct device *dev, struct device_attribute *attr, |
2191 | ret = scsi_device_set_state(sdev, state); |
2192 | /* |
2193 | * If the device state changes to SDEV_RUNNING, we need to |
2194 | - * rescan the device to revalidate it, and run the queue to |
2195 | - * avoid I/O hang. |
2196 | + * run the queue to avoid I/O hang, and rescan the device |
2197 | + * to revalidate it. Running the queue first is necessary |
2198 | + * because another thread may be waiting inside |
2199 | + * blk_mq_freeze_queue_wait() and because that call may be |
2200 | + * waiting for pending I/O to finish. |
2201 | */ |
2202 | if (ret == 0 && state == SDEV_RUNNING) { |
2203 | - scsi_rescan_device(dev); |
2204 | blk_mq_run_hw_queues(sdev->request_queue, true); |
2205 | + scsi_rescan_device(dev); |
2206 | } |
2207 | mutex_unlock(&sdev->state_mutex); |
2208 | |
2209 | diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c |
2210 | index 8989f28..e0853db 100644 |
2211 | --- a/drivers/tty/vt/vt_ioctl.c |
2212 | +++ b/drivers/tty/vt/vt_ioctl.c |
2213 | @@ -484,16 +484,19 @@ int vt_ioctl(struct tty_struct *tty, |
2214 | ret = -EINVAL; |
2215 | goto out; |
2216 | } |
2217 | - /* FIXME: this needs the console lock extending */ |
2218 | - if (vc->vc_mode == (unsigned char) arg) |
2219 | + console_lock(); |
2220 | + if (vc->vc_mode == (unsigned char) arg) { |
2221 | + console_unlock(); |
2222 | break; |
2223 | + } |
2224 | vc->vc_mode = (unsigned char) arg; |
2225 | - if (console != fg_console) |
2226 | + if (console != fg_console) { |
2227 | + console_unlock(); |
2228 | break; |
2229 | + } |
2230 | /* |
2231 | * explicitly blank/unblank the screen if switching modes |
2232 | */ |
2233 | - console_lock(); |
2234 | if (arg == KD_TEXT) |
2235 | do_unblank_screen(1); |
2236 | else |
2237 | diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c |
2238 | index 8a3752f..39a9ad1 100644 |
2239 | --- a/drivers/usb/dwc3/gadget.c |
2240 | +++ b/drivers/usb/dwc3/gadget.c |
2241 | @@ -894,19 +894,19 @@ static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) |
2242 | |
2243 | static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) |
2244 | { |
2245 | - struct dwc3_trb *tmp; |
2246 | u8 trbs_left; |
2247 | |
2248 | /* |
2249 | - * If enqueue & dequeue are equal than it is either full or empty. |
2250 | - * |
2251 | - * One way to know for sure is if the TRB right before us has HWO bit |
2252 | - * set or not. If it has, then we're definitely full and can't fit any |
2253 | - * more transfers in our ring. |
2254 | + * If the enqueue & dequeue are equal then the TRB ring is either full |
2255 | + * or empty. It's considered full when there are DWC3_TRB_NUM-1 of TRBs |
2256 | + * pending to be processed by the driver. |
2257 | */ |
2258 | if (dep->trb_enqueue == dep->trb_dequeue) { |
2259 | - tmp = dwc3_ep_prev_trb(dep, dep->trb_enqueue); |
2260 | - if (tmp->ctrl & DWC3_TRB_CTRL_HWO) |
2261 | + /* |
2262 | + * If there is any request remained in the started_list at |
2263 | + * this point, that means there is no TRB available. |
2264 | + */ |
2265 | + if (!list_empty(&dep->started_list)) |
2266 | return 0; |
2267 | |
2268 | return DWC3_TRB_NUM - 1; |
2269 | @@ -2012,10 +2012,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) |
2270 | |
2271 | ret = wait_for_completion_timeout(&dwc->ep0_in_setup, |
2272 | msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT)); |
2273 | - if (ret == 0) { |
2274 | - dev_err(dwc->dev, "timed out waiting for SETUP phase\n"); |
2275 | - return -ETIMEDOUT; |
2276 | - } |
2277 | + if (ret == 0) |
2278 | + dev_warn(dwc->dev, "timed out waiting for SETUP phase\n"); |
2279 | } |
2280 | |
2281 | /* |
2282 | @@ -2217,6 +2215,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) |
2283 | /* begin to receive SETUP packets */ |
2284 | dwc->ep0state = EP0_SETUP_PHASE; |
2285 | dwc->link_state = DWC3_LINK_STATE_SS_DIS; |
2286 | + dwc->delayed_status = false; |
2287 | dwc3_ep0_out_start(dwc); |
2288 | |
2289 | dwc3_gadget_enable_irq(dwc); |
2290 | diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c |
2291 | index 223029f..4e01ba0 100644 |
2292 | --- a/drivers/usb/gadget/function/u_audio.c |
2293 | +++ b/drivers/usb/gadget/function/u_audio.c |
2294 | @@ -349,8 +349,6 @@ static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep) |
2295 | if (!prm->ep_enabled) |
2296 | return; |
2297 | |
2298 | - prm->ep_enabled = false; |
2299 | - |
2300 | audio_dev = uac->audio_dev; |
2301 | params = &audio_dev->params; |
2302 | |
2303 | @@ -368,11 +366,12 @@ static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep) |
2304 | } |
2305 | } |
2306 | |
2307 | + prm->ep_enabled = false; |
2308 | + |
2309 | if (usb_ep_disable(ep)) |
2310 | dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); |
2311 | } |
2312 | |
2313 | - |
2314 | int u_audio_start_capture(struct g_audio *audio_dev) |
2315 | { |
2316 | struct snd_uac_chip *uac = audio_dev->uac; |
2317 | diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c |
2318 | index 448d7b1..f5c8e4e 100644 |
2319 | --- a/drivers/usb/host/xhci-debugfs.c |
2320 | +++ b/drivers/usb/host/xhci-debugfs.c |
2321 | @@ -197,12 +197,13 @@ static void xhci_ring_dump_segment(struct seq_file *s, |
2322 | int i; |
2323 | dma_addr_t dma; |
2324 | union xhci_trb *trb; |
2325 | + char str[XHCI_MSG_MAX]; |
2326 | |
2327 | for (i = 0; i < TRBS_PER_SEGMENT; i++) { |
2328 | trb = &seg->trbs[i]; |
2329 | dma = seg->dma + i * sizeof(*trb); |
2330 | seq_printf(s, "%pad: %s\n", &dma, |
2331 | - xhci_decode_trb(le32_to_cpu(trb->generic.field[0]), |
2332 | + xhci_decode_trb(str, XHCI_MSG_MAX, le32_to_cpu(trb->generic.field[0]), |
2333 | le32_to_cpu(trb->generic.field[1]), |
2334 | le32_to_cpu(trb->generic.field[2]), |
2335 | le32_to_cpu(trb->generic.field[3]))); |
2336 | @@ -340,9 +341,10 @@ static int xhci_portsc_show(struct seq_file *s, void *unused) |
2337 | { |
2338 | struct xhci_port *port = s->private; |
2339 | u32 portsc; |
2340 | + char str[XHCI_MSG_MAX]; |
2341 | |
2342 | portsc = readl(port->addr); |
2343 | - seq_printf(s, "%s\n", xhci_decode_portsc(portsc)); |
2344 | + seq_printf(s, "%s\n", xhci_decode_portsc(str, portsc)); |
2345 | |
2346 | return 0; |
2347 | } |
2348 | diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c |
2349 | index c1025d3..3da75b3 100644 |
2350 | --- a/drivers/usb/host/xhci-rcar.c |
2351 | +++ b/drivers/usb/host/xhci-rcar.c |
2352 | @@ -134,6 +134,13 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd) |
2353 | const struct soc_device_attribute *attr; |
2354 | const char *firmware_name; |
2355 | |
2356 | + /* |
2357 | + * According to the datasheet, "Upon the completion of FW Download, |
2358 | + * there is no need to write or reload FW". |
2359 | + */ |
2360 | + if (readl(regs + RCAR_USB3_DL_CTRL) & RCAR_USB3_DL_CTRL_FW_SUCCESS) |
2361 | + return 0; |
2362 | + |
2363 | attr = soc_device_match(rcar_quirks_match); |
2364 | if (attr) |
2365 | quirks = (uintptr_t)attr->data; |
2366 | diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h |
2367 | index 87da909..dab2af3 100644 |
2368 | --- a/drivers/usb/host/xhci-trace.h |
2369 | +++ b/drivers/usb/host/xhci-trace.h |
2370 | @@ -25,8 +25,6 @@ |
2371 | #include "xhci.h" |
2372 | #include "xhci-dbgcap.h" |
2373 | |
2374 | -#define XHCI_MSG_MAX 500 |
2375 | - |
2376 | DECLARE_EVENT_CLASS(xhci_log_msg, |
2377 | TP_PROTO(struct va_format *vaf), |
2378 | TP_ARGS(vaf), |
2379 | @@ -122,6 +120,7 @@ DECLARE_EVENT_CLASS(xhci_log_trb, |
2380 | __field(u32, field1) |
2381 | __field(u32, field2) |
2382 | __field(u32, field3) |
2383 | + __dynamic_array(char, str, XHCI_MSG_MAX) |
2384 | ), |
2385 | TP_fast_assign( |
2386 | __entry->type = ring->type; |
2387 | @@ -131,7 +130,7 @@ DECLARE_EVENT_CLASS(xhci_log_trb, |
2388 | __entry->field3 = le32_to_cpu(trb->field[3]); |
2389 | ), |
2390 | TP_printk("%s: %s", xhci_ring_type_string(__entry->type), |
2391 | - xhci_decode_trb(__entry->field0, __entry->field1, |
2392 | + xhci_decode_trb(__get_str(str), XHCI_MSG_MAX, __entry->field0, __entry->field1, |
2393 | __entry->field2, __entry->field3) |
2394 | ) |
2395 | ); |
2396 | @@ -523,6 +522,7 @@ DECLARE_EVENT_CLASS(xhci_log_portsc, |
2397 | TP_STRUCT__entry( |
2398 | __field(u32, portnum) |
2399 | __field(u32, portsc) |
2400 | + __dynamic_array(char, str, XHCI_MSG_MAX) |
2401 | ), |
2402 | TP_fast_assign( |
2403 | __entry->portnum = portnum; |
2404 | @@ -530,7 +530,7 @@ DECLARE_EVENT_CLASS(xhci_log_portsc, |
2405 | ), |
2406 | TP_printk("port-%d: %s", |
2407 | __entry->portnum, |
2408 | - xhci_decode_portsc(__entry->portsc) |
2409 | + xhci_decode_portsc(__get_str(str), __entry->portsc) |
2410 | ) |
2411 | ); |
2412 | |
2413 | diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h |
2414 | index 834f32f..02df309 100644 |
2415 | --- a/drivers/usb/host/xhci.h |
2416 | +++ b/drivers/usb/host/xhci.h |
2417 | @@ -22,6 +22,9 @@ |
2418 | #include "xhci-ext-caps.h" |
2419 | #include "pci-quirks.h" |
2420 | |
2421 | +/* max buffer size for trace and debug messages */ |
2422 | +#define XHCI_MSG_MAX 500 |
2423 | + |
2424 | /* xHCI PCI Configuration Registers */ |
2425 | #define XHCI_SBRN_OFFSET (0x60) |
2426 | |
2427 | @@ -2217,15 +2220,14 @@ static inline char *xhci_slot_state_string(u32 state) |
2428 | } |
2429 | } |
2430 | |
2431 | -static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2432 | - u32 field3) |
2433 | +static inline const char *xhci_decode_trb(char *str, size_t size, |
2434 | + u32 field0, u32 field1, u32 field2, u32 field3) |
2435 | { |
2436 | - static char str[256]; |
2437 | int type = TRB_FIELD_TO_TYPE(field3); |
2438 | |
2439 | switch (type) { |
2440 | case TRB_LINK: |
2441 | - sprintf(str, |
2442 | + snprintf(str, size, |
2443 | "LINK %08x%08x intr %d type '%s' flags %c:%c:%c:%c", |
2444 | field1, field0, GET_INTR_TARGET(field2), |
2445 | xhci_trb_type_string(type), |
2446 | @@ -2242,7 +2244,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2447 | case TRB_HC_EVENT: |
2448 | case TRB_DEV_NOTE: |
2449 | case TRB_MFINDEX_WRAP: |
2450 | - sprintf(str, |
2451 | + snprintf(str, size, |
2452 | "TRB %08x%08x status '%s' len %d slot %d ep %d type '%s' flags %c:%c", |
2453 | field1, field0, |
2454 | xhci_trb_comp_code_string(GET_COMP_CODE(field2)), |
2455 | @@ -2255,7 +2257,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2456 | |
2457 | break; |
2458 | case TRB_SETUP: |
2459 | - sprintf(str, "bRequestType %02x bRequest %02x wValue %02x%02x wIndex %02x%02x wLength %d length %d TD size %d intr %d type '%s' flags %c:%c:%c", |
2460 | + snprintf(str, size, |
2461 | + "bRequestType %02x bRequest %02x wValue %02x%02x wIndex %02x%02x wLength %d length %d TD size %d intr %d type '%s' flags %c:%c:%c", |
2462 | field0 & 0xff, |
2463 | (field0 & 0xff00) >> 8, |
2464 | (field0 & 0xff000000) >> 24, |
2465 | @@ -2272,7 +2275,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2466 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2467 | break; |
2468 | case TRB_DATA: |
2469 | - sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c", |
2470 | + snprintf(str, size, |
2471 | + "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c", |
2472 | field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), |
2473 | GET_INTR_TARGET(field2), |
2474 | xhci_trb_type_string(type), |
2475 | @@ -2285,7 +2289,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2476 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2477 | break; |
2478 | case TRB_STATUS: |
2479 | - sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c", |
2480 | + snprintf(str, size, |
2481 | + "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c", |
2482 | field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), |
2483 | GET_INTR_TARGET(field2), |
2484 | xhci_trb_type_string(type), |
2485 | @@ -2298,7 +2303,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2486 | case TRB_ISOC: |
2487 | case TRB_EVENT_DATA: |
2488 | case TRB_TR_NOOP: |
2489 | - sprintf(str, |
2490 | + snprintf(str, size, |
2491 | "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c:%c", |
2492 | field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), |
2493 | GET_INTR_TARGET(field2), |
2494 | @@ -2315,21 +2320,21 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2495 | |
2496 | case TRB_CMD_NOOP: |
2497 | case TRB_ENABLE_SLOT: |
2498 | - sprintf(str, |
2499 | + snprintf(str, size, |
2500 | "%s: flags %c", |
2501 | xhci_trb_type_string(type), |
2502 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2503 | break; |
2504 | case TRB_DISABLE_SLOT: |
2505 | case TRB_NEG_BANDWIDTH: |
2506 | - sprintf(str, |
2507 | + snprintf(str, size, |
2508 | "%s: slot %d flags %c", |
2509 | xhci_trb_type_string(type), |
2510 | TRB_TO_SLOT_ID(field3), |
2511 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2512 | break; |
2513 | case TRB_ADDR_DEV: |
2514 | - sprintf(str, |
2515 | + snprintf(str, size, |
2516 | "%s: ctx %08x%08x slot %d flags %c:%c", |
2517 | xhci_trb_type_string(type), |
2518 | field1, field0, |
2519 | @@ -2338,7 +2343,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2520 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2521 | break; |
2522 | case TRB_CONFIG_EP: |
2523 | - sprintf(str, |
2524 | + snprintf(str, size, |
2525 | "%s: ctx %08x%08x slot %d flags %c:%c", |
2526 | xhci_trb_type_string(type), |
2527 | field1, field0, |
2528 | @@ -2347,7 +2352,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2529 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2530 | break; |
2531 | case TRB_EVAL_CONTEXT: |
2532 | - sprintf(str, |
2533 | + snprintf(str, size, |
2534 | "%s: ctx %08x%08x slot %d flags %c", |
2535 | xhci_trb_type_string(type), |
2536 | field1, field0, |
2537 | @@ -2355,7 +2360,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2538 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2539 | break; |
2540 | case TRB_RESET_EP: |
2541 | - sprintf(str, |
2542 | + snprintf(str, size, |
2543 | "%s: ctx %08x%08x slot %d ep %d flags %c:%c", |
2544 | xhci_trb_type_string(type), |
2545 | field1, field0, |
2546 | @@ -2376,7 +2381,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2547 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2548 | break; |
2549 | case TRB_SET_DEQ: |
2550 | - sprintf(str, |
2551 | + snprintf(str, size, |
2552 | "%s: deq %08x%08x stream %d slot %d ep %d flags %c", |
2553 | xhci_trb_type_string(type), |
2554 | field1, field0, |
2555 | @@ -2387,14 +2392,14 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2556 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2557 | break; |
2558 | case TRB_RESET_DEV: |
2559 | - sprintf(str, |
2560 | + snprintf(str, size, |
2561 | "%s: slot %d flags %c", |
2562 | xhci_trb_type_string(type), |
2563 | TRB_TO_SLOT_ID(field3), |
2564 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2565 | break; |
2566 | case TRB_FORCE_EVENT: |
2567 | - sprintf(str, |
2568 | + snprintf(str, size, |
2569 | "%s: event %08x%08x vf intr %d vf id %d flags %c", |
2570 | xhci_trb_type_string(type), |
2571 | field1, field0, |
2572 | @@ -2403,14 +2408,14 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2573 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2574 | break; |
2575 | case TRB_SET_LT: |
2576 | - sprintf(str, |
2577 | + snprintf(str, size, |
2578 | "%s: belt %d flags %c", |
2579 | xhci_trb_type_string(type), |
2580 | TRB_TO_BELT(field3), |
2581 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2582 | break; |
2583 | case TRB_GET_BW: |
2584 | - sprintf(str, |
2585 | + snprintf(str, size, |
2586 | "%s: ctx %08x%08x slot %d speed %d flags %c", |
2587 | xhci_trb_type_string(type), |
2588 | field1, field0, |
2589 | @@ -2419,7 +2424,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2590 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2591 | break; |
2592 | case TRB_FORCE_HEADER: |
2593 | - sprintf(str, |
2594 | + snprintf(str, size, |
2595 | "%s: info %08x%08x%08x pkt type %d roothub port %d flags %c", |
2596 | xhci_trb_type_string(type), |
2597 | field2, field1, field0 & 0xffffffe0, |
2598 | @@ -2428,7 +2433,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, |
2599 | field3 & TRB_CYCLE ? 'C' : 'c'); |
2600 | break; |
2601 | default: |
2602 | - sprintf(str, |
2603 | + snprintf(str, size, |
2604 | "type '%s' -> raw %08x %08x %08x %08x", |
2605 | xhci_trb_type_string(type), |
2606 | field0, field1, field2, field3); |
2607 | @@ -2553,9 +2558,8 @@ static inline const char *xhci_portsc_link_state_string(u32 portsc) |
2608 | return "Unknown"; |
2609 | } |
2610 | |
2611 | -static inline const char *xhci_decode_portsc(u32 portsc) |
2612 | +static inline const char *xhci_decode_portsc(char *str, u32 portsc) |
2613 | { |
2614 | - static char str[256]; |
2615 | int ret; |
2616 | |
2617 | ret = sprintf(str, "%s %s %s Link:%s PortSpeed:%d ", |
2618 | diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c |
2619 | index 08db02f..619c459 100644 |
2620 | --- a/drivers/usb/mtu3/mtu3_gadget.c |
2621 | +++ b/drivers/usb/mtu3/mtu3_gadget.c |
2622 | @@ -72,14 +72,12 @@ static int mtu3_ep_enable(struct mtu3_ep *mep) |
2623 | u32 interval = 0; |
2624 | u32 mult = 0; |
2625 | u32 burst = 0; |
2626 | - int max_packet; |
2627 | int ret; |
2628 | |
2629 | desc = mep->desc; |
2630 | comp_desc = mep->comp_desc; |
2631 | mep->type = usb_endpoint_type(desc); |
2632 | - max_packet = usb_endpoint_maxp(desc); |
2633 | - mep->maxp = max_packet & GENMASK(10, 0); |
2634 | + mep->maxp = usb_endpoint_maxp(desc); |
2635 | |
2636 | switch (mtu->g.speed) { |
2637 | case USB_SPEED_SUPER: |
2638 | @@ -100,7 +98,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep) |
2639 | usb_endpoint_xfer_int(desc)) { |
2640 | interval = desc->bInterval; |
2641 | interval = clamp_val(interval, 1, 16) - 1; |
2642 | - burst = (max_packet & GENMASK(12, 11)) >> 11; |
2643 | + mult = usb_endpoint_maxp_mult(desc) - 1; |
2644 | } |
2645 | break; |
2646 | default: |
2647 | diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c |
2648 | index e9c39a4..a82ba9c 100644 |
2649 | --- a/drivers/usb/serial/ch341.c |
2650 | +++ b/drivers/usb/serial/ch341.c |
2651 | @@ -678,7 +678,6 @@ static struct usb_serial_driver ch341_device = { |
2652 | .owner = THIS_MODULE, |
2653 | .name = "ch341-uart", |
2654 | }, |
2655 | - .bulk_in_size = 512, |
2656 | .id_table = id_table, |
2657 | .num_ports = 1, |
2658 | .open = ch341_open, |
2659 | diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c |
2660 | index aefc1b5..f5caf38 100644 |
2661 | --- a/drivers/usb/serial/mos7720.c |
2662 | +++ b/drivers/usb/serial/mos7720.c |
2663 | @@ -226,8 +226,10 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, |
2664 | int status; |
2665 | |
2666 | buf = kmalloc(1, GFP_KERNEL); |
2667 | - if (!buf) |
2668 | + if (!buf) { |
2669 | + *data = 0; |
2670 | return -ENOMEM; |
2671 | + } |
2672 | |
2673 | status = usb_control_msg(usbdev, pipe, request, requesttype, value, |
2674 | index, buf, 1, MOS_WDR_TIMEOUT); |
2675 | diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c |
2676 | index 793530f..d42ca13 100644 |
2677 | --- a/drivers/usb/serial/option.c |
2678 | +++ b/drivers/usb/serial/option.c |
2679 | @@ -2074,6 +2074,8 @@ static const struct usb_device_id option_ids[] = { |
2680 | .driver_info = RSVD(4) | RSVD(5) }, |
2681 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ |
2682 | .driver_info = RSVD(6) }, |
2683 | + { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */ |
2684 | + { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */ |
2685 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ |
2686 | { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ |
2687 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ |
2688 | diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c |
2689 | index 026a37e..4653de0 100644 |
2690 | --- a/drivers/vhost/vringh.c |
2691 | +++ b/drivers/vhost/vringh.c |
2692 | @@ -331,7 +331,7 @@ __vringh_iov(struct vringh *vrh, u16 i, |
2693 | iov = wiov; |
2694 | else { |
2695 | iov = riov; |
2696 | - if (unlikely(wiov && wiov->i)) { |
2697 | + if (unlikely(wiov && wiov->used)) { |
2698 | vringh_bad("Readable desc %p after writable", |
2699 | &descs[i]); |
2700 | err = -EINVAL; |
2701 | diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c |
2702 | index 222d630..b35bb2d 100644 |
2703 | --- a/drivers/virtio/virtio_pci_common.c |
2704 | +++ b/drivers/virtio/virtio_pci_common.c |
2705 | @@ -576,6 +576,13 @@ static void virtio_pci_remove(struct pci_dev *pci_dev) |
2706 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); |
2707 | struct device *dev = get_device(&vp_dev->vdev.dev); |
2708 | |
2709 | + /* |
2710 | + * Device is marked broken on surprise removal so that virtio upper |
2711 | + * layers can abort any ongoing operation. |
2712 | + */ |
2713 | + if (!pci_device_is_present(pci_dev)) |
2714 | + virtio_break_device(&vp_dev->vdev); |
2715 | + |
2716 | pci_disable_sriov(pci_dev); |
2717 | |
2718 | unregister_virtio_device(&vp_dev->vdev); |
2719 | diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c |
2720 | index f6011c9..e442d40 100644 |
2721 | --- a/drivers/virtio/virtio_ring.c |
2722 | +++ b/drivers/virtio/virtio_ring.c |
2723 | @@ -2268,7 +2268,7 @@ bool virtqueue_is_broken(struct virtqueue *_vq) |
2724 | { |
2725 | struct vring_virtqueue *vq = to_vvq(_vq); |
2726 | |
2727 | - return vq->broken; |
2728 | + return READ_ONCE(vq->broken); |
2729 | } |
2730 | EXPORT_SYMBOL_GPL(virtqueue_is_broken); |
2731 | |
2732 | @@ -2283,7 +2283,9 @@ void virtio_break_device(struct virtio_device *dev) |
2733 | spin_lock(&dev->vqs_list_lock); |
2734 | list_for_each_entry(_vq, &dev->vqs, list) { |
2735 | struct vring_virtqueue *vq = to_vvq(_vq); |
2736 | - vq->broken = true; |
2737 | + |
2738 | + /* Pairs with READ_ONCE() in virtqueue_is_broken(). */ |
2739 | + WRITE_ONCE(vq->broken, true); |
2740 | } |
2741 | spin_unlock(&dev->vqs_list_lock); |
2742 | } |
2743 | diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h |
2744 | index f853835..f3ff57b 100644 |
2745 | --- a/fs/btrfs/btrfs_inode.h |
2746 | +++ b/fs/btrfs/btrfs_inode.h |
2747 | @@ -268,6 +268,21 @@ static inline void btrfs_mod_outstanding_extents(struct btrfs_inode *inode, |
2748 | mod); |
2749 | } |
2750 | |
2751 | +/* |
2752 | + * Called every time after doing a buffered, direct IO or memory mapped write. |
2753 | + * |
2754 | + * This is to ensure that if we write to a file that was previously fsynced in |
2755 | + * the current transaction, then try to fsync it again in the same transaction, |
2756 | + * we will know that there were changes in the file and that it needs to be |
2757 | + * logged. |
2758 | + */ |
2759 | +static inline void btrfs_set_inode_last_sub_trans(struct btrfs_inode *inode) |
2760 | +{ |
2761 | + spin_lock(&inode->lock); |
2762 | + inode->last_sub_trans = inode->root->log_transid; |
2763 | + spin_unlock(&inode->lock); |
2764 | +} |
2765 | + |
2766 | static inline int btrfs_inode_in_log(struct btrfs_inode *inode, u64 generation) |
2767 | { |
2768 | int ret = 0; |
2769 | diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c |
2770 | index 400b071..1279359 100644 |
2771 | --- a/fs/btrfs/file.c |
2772 | +++ b/fs/btrfs/file.c |
2773 | @@ -2004,14 +2004,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, |
2774 | |
2775 | inode_unlock(inode); |
2776 | |
2777 | - /* |
2778 | - * We also have to set last_sub_trans to the current log transid, |
2779 | - * otherwise subsequent syncs to a file that's been synced in this |
2780 | - * transaction will appear to have already occurred. |
2781 | - */ |
2782 | - spin_lock(&BTRFS_I(inode)->lock); |
2783 | - BTRFS_I(inode)->last_sub_trans = root->log_transid; |
2784 | - spin_unlock(&BTRFS_I(inode)->lock); |
2785 | + btrfs_set_inode_last_sub_trans(BTRFS_I(inode)); |
2786 | + |
2787 | if (num_written > 0) |
2788 | num_written = generic_write_sync(iocb, num_written); |
2789 | |
2790 | diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
2791 | index 54b607a..33b8fed 100644 |
2792 | --- a/fs/btrfs/inode.c |
2793 | +++ b/fs/btrfs/inode.c |
2794 | @@ -543,7 +543,7 @@ again: |
2795 | * inode has not been flagged as nocompress. This flag can |
2796 | * change at any time if we discover bad compression ratios. |
2797 | */ |
2798 | - if (nr_pages > 1 && inode_need_compress(inode, start, end)) { |
2799 | + if (inode_need_compress(inode, start, end)) { |
2800 | WARN_ON(pages); |
2801 | pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); |
2802 | if (!pages) { |
2803 | @@ -9250,9 +9250,7 @@ again: |
2804 | set_page_dirty(page); |
2805 | SetPageUptodate(page); |
2806 | |
2807 | - BTRFS_I(inode)->last_trans = fs_info->generation; |
2808 | - BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid; |
2809 | - BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit; |
2810 | + btrfs_set_inode_last_sub_trans(BTRFS_I(inode)); |
2811 | |
2812 | unlock_extent_cached(io_tree, page_start, page_end, &cached_state); |
2813 | |
2814 | diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h |
2815 | index d8a7d46..cbede32 100644 |
2816 | --- a/fs/btrfs/transaction.h |
2817 | +++ b/fs/btrfs/transaction.h |
2818 | @@ -160,7 +160,7 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans, |
2819 | spin_lock(&BTRFS_I(inode)->lock); |
2820 | BTRFS_I(inode)->last_trans = trans->transaction->transid; |
2821 | BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid; |
2822 | - BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit; |
2823 | + BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans - 1; |
2824 | spin_unlock(&BTRFS_I(inode)->lock); |
2825 | } |
2826 | |
2827 | diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c |
2828 | index 3e3529c..e882c79 100644 |
2829 | --- a/fs/btrfs/volumes.c |
2830 | +++ b/fs/btrfs/volumes.c |
2831 | @@ -2168,7 +2168,7 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, |
2832 | |
2833 | if (IS_ERR(device)) { |
2834 | if (PTR_ERR(device) == -ENOENT && |
2835 | - strcmp(device_path, "missing") == 0) |
2836 | + device_path && strcmp(device_path, "missing") == 0) |
2837 | ret = BTRFS_ERROR_DEV_MISSING_NOT_FOUND; |
2838 | else |
2839 | ret = PTR_ERR(device); |
2840 | diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c |
2841 | index a5a40a7..82575cf 100644 |
2842 | --- a/fs/crypto/hooks.c |
2843 | +++ b/fs/crypto/hooks.c |
2844 | @@ -305,3 +305,47 @@ err_kfree: |
2845 | return ERR_PTR(err); |
2846 | } |
2847 | EXPORT_SYMBOL_GPL(fscrypt_get_symlink); |
2848 | + |
2849 | +/** |
2850 | + * fscrypt_symlink_getattr() - set the correct st_size for encrypted symlinks |
2851 | + * @path: the path for the encrypted symlink being queried |
2852 | + * @stat: the struct being filled with the symlink's attributes |
2853 | + * |
2854 | + * Override st_size of encrypted symlinks to be the length of the decrypted |
2855 | + * symlink target (or the no-key encoded symlink target, if the key is |
2856 | + * unavailable) rather than the length of the encrypted symlink target. This is |
2857 | + * necessary for st_size to match the symlink target that userspace actually |
2858 | + * sees. POSIX requires this, and some userspace programs depend on it. |
2859 | + * |
2860 | + * This requires reading the symlink target from disk if needed, setting up the |
2861 | + * inode's encryption key if possible, and then decrypting or encoding the |
2862 | + * symlink target. This makes lstat() more heavyweight than is normally the |
2863 | + * case. However, decrypted symlink targets will be cached in ->i_link, so |
2864 | + * usually the symlink won't have to be read and decrypted again later if/when |
2865 | + * it is actually followed, readlink() is called, or lstat() is called again. |
2866 | + * |
2867 | + * Return: 0 on success, -errno on failure |
2868 | + */ |
2869 | +int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat) |
2870 | +{ |
2871 | + struct dentry *dentry = path->dentry; |
2872 | + struct inode *inode = d_inode(dentry); |
2873 | + const char *link; |
2874 | + DEFINE_DELAYED_CALL(done); |
2875 | + |
2876 | + /* |
2877 | + * To get the symlink target that userspace will see (whether it's the |
2878 | + * decrypted target or the no-key encoded target), we can just get it in |
2879 | + * the same way the VFS does during path resolution and readlink(). |
2880 | + */ |
2881 | + link = READ_ONCE(inode->i_link); |
2882 | + if (!link) { |
2883 | + link = inode->i_op->get_link(dentry, inode, &done); |
2884 | + if (IS_ERR(link)) |
2885 | + return PTR_ERR(link); |
2886 | + } |
2887 | + stat->size = strlen(link); |
2888 | + do_delayed_call(&done); |
2889 | + return 0; |
2890 | +} |
2891 | +EXPORT_SYMBOL_GPL(fscrypt_symlink_getattr); |
2892 | diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c |
2893 | index dd05af9..a9457fe 100644 |
2894 | --- a/fs/ext4/symlink.c |
2895 | +++ b/fs/ext4/symlink.c |
2896 | @@ -52,10 +52,19 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry, |
2897 | return paddr; |
2898 | } |
2899 | |
2900 | +static int ext4_encrypted_symlink_getattr(const struct path *path, |
2901 | + struct kstat *stat, u32 request_mask, |
2902 | + unsigned int query_flags) |
2903 | +{ |
2904 | + ext4_getattr(path, stat, request_mask, query_flags); |
2905 | + |
2906 | + return fscrypt_symlink_getattr(path, stat); |
2907 | +} |
2908 | + |
2909 | const struct inode_operations ext4_encrypted_symlink_inode_operations = { |
2910 | .get_link = ext4_encrypted_get_link, |
2911 | .setattr = ext4_setattr, |
2912 | - .getattr = ext4_getattr, |
2913 | + .getattr = ext4_encrypted_symlink_getattr, |
2914 | .listxattr = ext4_listxattr, |
2915 | }; |
2916 | |
2917 | diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c |
2918 | index 3a97ac5..81a18ba 100644 |
2919 | --- a/fs/f2fs/namei.c |
2920 | +++ b/fs/f2fs/namei.c |
2921 | @@ -1256,9 +1256,18 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry, |
2922 | return target; |
2923 | } |
2924 | |
2925 | +static int f2fs_encrypted_symlink_getattr(const struct path *path, |
2926 | + struct kstat *stat, u32 request_mask, |
2927 | + unsigned int query_flags) |
2928 | +{ |
2929 | + f2fs_getattr(path, stat, request_mask, query_flags); |
2930 | + |
2931 | + return fscrypt_symlink_getattr(path, stat); |
2932 | +} |
2933 | + |
2934 | const struct inode_operations f2fs_encrypted_symlink_inode_operations = { |
2935 | .get_link = f2fs_encrypted_get_link, |
2936 | - .getattr = f2fs_getattr, |
2937 | + .getattr = f2fs_encrypted_symlink_getattr, |
2938 | .setattr = f2fs_setattr, |
2939 | #ifdef CONFIG_F2FS_FS_XATTR |
2940 | .listxattr = f2fs_listxattr, |
2941 | diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c |
2942 | index 11dd817..19574ef 100644 |
2943 | --- a/fs/overlayfs/export.c |
2944 | +++ b/fs/overlayfs/export.c |
2945 | @@ -395,6 +395,7 @@ static struct dentry *ovl_lookup_real_one(struct dentry *connected, |
2946 | */ |
2947 | take_dentry_name_snapshot(&name, real); |
2948 | this = lookup_one_len(name.name.name, connected, name.name.len); |
2949 | + release_dentry_name_snapshot(&name); |
2950 | err = PTR_ERR(this); |
2951 | if (IS_ERR(this)) { |
2952 | goto fail; |
2953 | @@ -409,7 +410,6 @@ static struct dentry *ovl_lookup_real_one(struct dentry *connected, |
2954 | } |
2955 | |
2956 | out: |
2957 | - release_dentry_name_snapshot(&name); |
2958 | dput(parent); |
2959 | inode_unlock(dir); |
2960 | return this; |
2961 | diff --git a/fs/proc/base.c b/fs/proc/base.c |
2962 | index 7bbe0ee..b90db1d 100644 |
2963 | --- a/fs/proc/base.c |
2964 | +++ b/fs/proc/base.c |
2965 | @@ -549,8 +549,17 @@ static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns, |
2966 | { |
2967 | unsigned long totalpages = totalram_pages() + total_swap_pages; |
2968 | unsigned long points = 0; |
2969 | + long badness; |
2970 | + |
2971 | + badness = oom_badness(task, totalpages); |
2972 | + /* |
2973 | + * Special case OOM_SCORE_ADJ_MIN for all others scale the |
2974 | + * badness value into [0, 2000] range which we have been |
2975 | + * exporting for a long time so userspace might depend on it. |
2976 | + */ |
2977 | + if (badness != LONG_MIN) |
2978 | + points = (1000 + badness * 1000 / (long)totalpages) * 2 / 3; |
2979 | |
2980 | - points = oom_badness(task, totalpages) * 1000 / totalpages; |
2981 | seq_printf(m, "%lu\n", points); |
2982 | |
2983 | return 0; |
2984 | diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c |
2985 | index 8dada89..6069c63 100644 |
2986 | --- a/fs/ubifs/file.c |
2987 | +++ b/fs/ubifs/file.c |
2988 | @@ -1629,6 +1629,16 @@ static const char *ubifs_get_link(struct dentry *dentry, |
2989 | return fscrypt_get_symlink(inode, ui->data, ui->data_len, done); |
2990 | } |
2991 | |
2992 | +static int ubifs_symlink_getattr(const struct path *path, struct kstat *stat, |
2993 | + u32 request_mask, unsigned int query_flags) |
2994 | +{ |
2995 | + ubifs_getattr(path, stat, request_mask, query_flags); |
2996 | + |
2997 | + if (IS_ENCRYPTED(d_inode(path->dentry))) |
2998 | + return fscrypt_symlink_getattr(path, stat); |
2999 | + return 0; |
3000 | +} |
3001 | + |
3002 | const struct address_space_operations ubifs_file_address_operations = { |
3003 | .readpage = ubifs_readpage, |
3004 | .writepage = ubifs_writepage, |
3005 | @@ -1654,7 +1664,7 @@ const struct inode_operations ubifs_file_inode_operations = { |
3006 | const struct inode_operations ubifs_symlink_inode_operations = { |
3007 | .get_link = ubifs_get_link, |
3008 | .setattr = ubifs_setattr, |
3009 | - .getattr = ubifs_getattr, |
3010 | + .getattr = ubifs_symlink_getattr, |
3011 | #ifdef CONFIG_UBIFS_FS_XATTR |
3012 | .listxattr = ubifs_listxattr, |
3013 | #endif |
3014 | diff --git a/include/linux/efi.h b/include/linux/efi.h |
3015 | index 695c959..70e89ae 100644 |
3016 | --- a/include/linux/efi.h |
3017 | +++ b/include/linux/efi.h |
3018 | @@ -695,6 +695,7 @@ void efi_native_runtime_setup(void); |
3019 | #define LINUX_EFI_TPM_EVENT_LOG_GUID EFI_GUID(0xb7799cb0, 0xeca2, 0x4943, 0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa) |
3020 | #define LINUX_EFI_TPM_FINAL_LOG_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25) |
3021 | #define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2) |
3022 | +#define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89) |
3023 | |
3024 | /* OEM GUIDs */ |
3025 | #define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55) |
3026 | @@ -1004,6 +1005,7 @@ extern struct efi { |
3027 | unsigned long rng_seed; /* UEFI firmware random seed */ |
3028 | unsigned long tpm_log; /* TPM2 Event Log table */ |
3029 | unsigned long tpm_final_log; /* TPM2 Final Events Log table */ |
3030 | + unsigned long mokvar_table; /* MOK variable config table */ |
3031 | unsigned long mem_reserve; /* Linux EFI memreserve table */ |
3032 | efi_get_time_t *get_time; |
3033 | efi_set_time_t *set_time; |
3034 | @@ -1809,4 +1811,36 @@ struct linux_efi_memreserve { |
3035 | #define EFI_MEMRESERVE_COUNT(size) (((size) - sizeof(struct linux_efi_memreserve)) \ |
3036 | / sizeof(((struct linux_efi_memreserve *)0)->entry[0])) |
3037 | |
3038 | +/* |
3039 | + * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table can be provided |
3040 | + * to the kernel by an EFI boot loader. The table contains a packed |
3041 | + * sequence of these entries, one for each named MOK variable. |
3042 | + * The sequence is terminated by an entry with a completely NULL |
3043 | + * name and 0 data size. |
3044 | + */ |
3045 | +struct efi_mokvar_table_entry { |
3046 | + char name[256]; |
3047 | + u64 data_size; |
3048 | + u8 data[]; |
3049 | +} __attribute((packed)); |
3050 | + |
3051 | +#ifdef CONFIG_LOAD_UEFI_KEYS |
3052 | +extern void __init efi_mokvar_table_init(void); |
3053 | +extern struct efi_mokvar_table_entry *efi_mokvar_entry_next( |
3054 | + struct efi_mokvar_table_entry **mokvar_entry); |
3055 | +extern struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name); |
3056 | +#else |
3057 | +static inline void efi_mokvar_table_init(void) { } |
3058 | +static inline struct efi_mokvar_table_entry *efi_mokvar_entry_next( |
3059 | + struct efi_mokvar_table_entry **mokvar_entry) |
3060 | +{ |
3061 | + return NULL; |
3062 | +} |
3063 | +static inline struct efi_mokvar_table_entry *efi_mokvar_entry_find( |
3064 | + const char *name) |
3065 | +{ |
3066 | + return NULL; |
3067 | +} |
3068 | +#endif |
3069 | + |
3070 | #endif /* _LINUX_EFI_H */ |
3071 | diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h |
3072 | index 032e5bc..0d1a53d 100644 |
3073 | --- a/include/linux/fscrypt.h |
3074 | +++ b/include/linux/fscrypt.h |
3075 | @@ -298,6 +298,7 @@ extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target, |
3076 | extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr, |
3077 | unsigned int max_size, |
3078 | struct delayed_call *done); |
3079 | +int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat); |
3080 | static inline void fscrypt_set_ops(struct super_block *sb, |
3081 | const struct fscrypt_operations *s_cop) |
3082 | { |
3083 | @@ -585,6 +586,12 @@ static inline const char *fscrypt_get_symlink(struct inode *inode, |
3084 | return ERR_PTR(-EOPNOTSUPP); |
3085 | } |
3086 | |
3087 | +static inline int fscrypt_symlink_getattr(const struct path *path, |
3088 | + struct kstat *stat) |
3089 | +{ |
3090 | + return -EOPNOTSUPP; |
3091 | +} |
3092 | + |
3093 | static inline void fscrypt_set_ops(struct super_block *sb, |
3094 | const struct fscrypt_operations *s_cop) |
3095 | { |
3096 | diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h |
3097 | index edd3806..8f2cd0f 100644 |
3098 | --- a/include/linux/netdevice.h |
3099 | +++ b/include/linux/netdevice.h |
3100 | @@ -3684,6 +3684,10 @@ int netdev_rx_handler_register(struct net_device *dev, |
3101 | void netdev_rx_handler_unregister(struct net_device *dev); |
3102 | |
3103 | bool dev_valid_name(const char *name); |
3104 | +static inline bool is_socket_ioctl_cmd(unsigned int cmd) |
3105 | +{ |
3106 | + return _IOC_TYPE(cmd) == SOCK_IOC_TYPE; |
3107 | +} |
3108 | int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, |
3109 | bool *need_copyout); |
3110 | int dev_ifconf(struct net *net, struct ifconf *, int); |
3111 | diff --git a/include/linux/once.h b/include/linux/once.h |
3112 | index 9225ee6..ae6f4eb 100644 |
3113 | --- a/include/linux/once.h |
3114 | +++ b/include/linux/once.h |
3115 | @@ -7,7 +7,7 @@ |
3116 | |
3117 | bool __do_once_start(bool *done, unsigned long *flags); |
3118 | void __do_once_done(bool *done, struct static_key_true *once_key, |
3119 | - unsigned long *flags); |
3120 | + unsigned long *flags, struct module *mod); |
3121 | |
3122 | /* Call a function exactly once. The idea of DO_ONCE() is to perform |
3123 | * a function call such as initialization of random seeds, etc, only |
3124 | @@ -46,7 +46,7 @@ void __do_once_done(bool *done, struct static_key_true *once_key, |
3125 | if (unlikely(___ret)) { \ |
3126 | func(__VA_ARGS__); \ |
3127 | __do_once_done(&___done, &___once_key, \ |
3128 | - &___flags); \ |
3129 | + &___flags, THIS_MODULE); \ |
3130 | } \ |
3131 | } \ |
3132 | ___ret; \ |
3133 | diff --git a/include/linux/oom.h b/include/linux/oom.h |
3134 | index b9df343..2db9a14 100644 |
3135 | --- a/include/linux/oom.h |
3136 | +++ b/include/linux/oom.h |
3137 | @@ -48,7 +48,7 @@ struct oom_control { |
3138 | /* Used by oom implementation, do not set */ |
3139 | unsigned long totalpages; |
3140 | struct task_struct *chosen; |
3141 | - unsigned long chosen_points; |
3142 | + long chosen_points; |
3143 | |
3144 | /* Used to print the constraint info. */ |
3145 | enum oom_constraint constraint; |
3146 | @@ -108,7 +108,7 @@ static inline vm_fault_t check_stable_address_space(struct mm_struct *mm) |
3147 | |
3148 | bool __oom_reap_task_mm(struct mm_struct *mm); |
3149 | |
3150 | -extern unsigned long oom_badness(struct task_struct *p, |
3151 | +long oom_badness(struct task_struct *p, |
3152 | unsigned long totalpages); |
3153 | |
3154 | extern bool out_of_memory(struct oom_control *oc); |
3155 | diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c |
3156 | index e49c912..9dec631 100644 |
3157 | --- a/kernel/audit_tree.c |
3158 | +++ b/kernel/audit_tree.c |
3159 | @@ -595,7 +595,6 @@ static void prune_tree_chunks(struct audit_tree *victim, bool tagged) |
3160 | spin_lock(&hash_lock); |
3161 | } |
3162 | spin_unlock(&hash_lock); |
3163 | - put_tree(victim); |
3164 | } |
3165 | |
3166 | /* |
3167 | @@ -604,6 +603,7 @@ static void prune_tree_chunks(struct audit_tree *victim, bool tagged) |
3168 | static void prune_one(struct audit_tree *victim) |
3169 | { |
3170 | prune_tree_chunks(victim, false); |
3171 | + put_tree(victim); |
3172 | } |
3173 | |
3174 | /* trim the uncommitted chunks from tree */ |
3175 | diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c |
3176 | index 0b5a446..4deaf15 100644 |
3177 | --- a/kernel/bpf/verifier.c |
3178 | +++ b/kernel/bpf/verifier.c |
3179 | @@ -2778,6 +2778,41 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size) |
3180 | reg->smax_value = reg->umax_value; |
3181 | } |
3182 | |
3183 | +static bool bpf_map_is_rdonly(const struct bpf_map *map) |
3184 | +{ |
3185 | + return (map->map_flags & BPF_F_RDONLY_PROG) && map->frozen; |
3186 | +} |
3187 | + |
3188 | +static int bpf_map_direct_read(struct bpf_map *map, int off, int size, u64 *val) |
3189 | +{ |
3190 | + void *ptr; |
3191 | + u64 addr; |
3192 | + int err; |
3193 | + |
3194 | + err = map->ops->map_direct_value_addr(map, &addr, off); |
3195 | + if (err) |
3196 | + return err; |
3197 | + ptr = (void *)(long)addr + off; |
3198 | + |
3199 | + switch (size) { |
3200 | + case sizeof(u8): |
3201 | + *val = (u64)*(u8 *)ptr; |
3202 | + break; |
3203 | + case sizeof(u16): |
3204 | + *val = (u64)*(u16 *)ptr; |
3205 | + break; |
3206 | + case sizeof(u32): |
3207 | + *val = (u64)*(u32 *)ptr; |
3208 | + break; |
3209 | + case sizeof(u64): |
3210 | + *val = *(u64 *)ptr; |
3211 | + break; |
3212 | + default: |
3213 | + return -EINVAL; |
3214 | + } |
3215 | + return 0; |
3216 | +} |
3217 | + |
3218 | /* check whether memory at (regno + off) is accessible for t = (read | write) |
3219 | * if t==write, value_regno is a register which value is stored into memory |
3220 | * if t==read, value_regno is a register which will receive the value from memory |
3221 | @@ -2815,9 +2850,27 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn |
3222 | if (err) |
3223 | return err; |
3224 | err = check_map_access(env, regno, off, size, false); |
3225 | - if (!err && t == BPF_READ && value_regno >= 0) |
3226 | - mark_reg_unknown(env, regs, value_regno); |
3227 | + if (!err && t == BPF_READ && value_regno >= 0) { |
3228 | + struct bpf_map *map = reg->map_ptr; |
3229 | + |
3230 | + /* if map is read-only, track its contents as scalars */ |
3231 | + if (tnum_is_const(reg->var_off) && |
3232 | + bpf_map_is_rdonly(map) && |
3233 | + map->ops->map_direct_value_addr) { |
3234 | + int map_off = off + reg->var_off.value; |
3235 | + u64 val = 0; |
3236 | |
3237 | + err = bpf_map_direct_read(map, map_off, size, |
3238 | + &val); |
3239 | + if (err) |
3240 | + return err; |
3241 | + |
3242 | + regs[value_regno].type = SCALAR_VALUE; |
3243 | + __mark_reg_known(®s[value_regno], val); |
3244 | + } else { |
3245 | + mark_reg_unknown(env, regs, value_regno); |
3246 | + } |
3247 | + } |
3248 | } else if (reg->type == PTR_TO_CTX) { |
3249 | enum bpf_reg_type reg_type = SCALAR_VALUE; |
3250 | |
3251 | diff --git a/kernel/kthread.c b/kernel/kthread.c |
3252 | index 3086f2a..1d53f19 100644 |
3253 | --- a/kernel/kthread.c |
3254 | +++ b/kernel/kthread.c |
3255 | @@ -76,6 +76,25 @@ static inline struct kthread *to_kthread(struct task_struct *k) |
3256 | return (__force void *)k->set_child_tid; |
3257 | } |
3258 | |
3259 | +/* |
3260 | + * Variant of to_kthread() that doesn't assume @p is a kthread. |
3261 | + * |
3262 | + * Per construction; when: |
3263 | + * |
3264 | + * (p->flags & PF_KTHREAD) && p->set_child_tid |
3265 | + * |
3266 | + * the task is both a kthread and struct kthread is persistent. However |
3267 | + * PF_KTHREAD on it's own is not, kernel_thread() can exec() (See umh.c and |
3268 | + * begin_new_exec()). |
3269 | + */ |
3270 | +static inline struct kthread *__to_kthread(struct task_struct *p) |
3271 | +{ |
3272 | + void *kthread = (__force void *)p->set_child_tid; |
3273 | + if (kthread && !(p->flags & PF_KTHREAD)) |
3274 | + kthread = NULL; |
3275 | + return kthread; |
3276 | +} |
3277 | + |
3278 | void free_kthread_struct(struct task_struct *k) |
3279 | { |
3280 | struct kthread *kthread; |
3281 | @@ -176,10 +195,11 @@ void *kthread_data(struct task_struct *task) |
3282 | */ |
3283 | void *kthread_probe_data(struct task_struct *task) |
3284 | { |
3285 | - struct kthread *kthread = to_kthread(task); |
3286 | + struct kthread *kthread = __to_kthread(task); |
3287 | void *data = NULL; |
3288 | |
3289 | - probe_kernel_read(&data, &kthread->data, sizeof(data)); |
3290 | + if (kthread) |
3291 | + probe_kernel_read(&data, &kthread->data, sizeof(data)); |
3292 | return data; |
3293 | } |
3294 | |
3295 | @@ -502,9 +522,9 @@ void kthread_set_per_cpu(struct task_struct *k, int cpu) |
3296 | set_bit(KTHREAD_IS_PER_CPU, &kthread->flags); |
3297 | } |
3298 | |
3299 | -bool kthread_is_per_cpu(struct task_struct *k) |
3300 | +bool kthread_is_per_cpu(struct task_struct *p) |
3301 | { |
3302 | - struct kthread *kthread = to_kthread(k); |
3303 | + struct kthread *kthread = __to_kthread(p); |
3304 | if (!kthread) |
3305 | return false; |
3306 | |
3307 | @@ -1284,11 +1304,9 @@ EXPORT_SYMBOL(kthread_destroy_worker); |
3308 | */ |
3309 | void kthread_associate_blkcg(struct cgroup_subsys_state *css) |
3310 | { |
3311 | - struct kthread *kthread; |
3312 | + struct kthread *kthread = __to_kthread(current); |
3313 | + |
3314 | |
3315 | - if (!(current->flags & PF_KTHREAD)) |
3316 | - return; |
3317 | - kthread = to_kthread(current); |
3318 | if (!kthread) |
3319 | return; |
3320 | |
3321 | @@ -1310,13 +1328,10 @@ EXPORT_SYMBOL(kthread_associate_blkcg); |
3322 | */ |
3323 | struct cgroup_subsys_state *kthread_blkcg(void) |
3324 | { |
3325 | - struct kthread *kthread; |
3326 | + struct kthread *kthread = __to_kthread(current); |
3327 | |
3328 | - if (current->flags & PF_KTHREAD) { |
3329 | - kthread = to_kthread(current); |
3330 | - if (kthread) |
3331 | - return kthread->blkcg_css; |
3332 | - } |
3333 | + if (kthread) |
3334 | + return kthread->blkcg_css; |
3335 | return NULL; |
3336 | } |
3337 | EXPORT_SYMBOL(kthread_blkcg); |
3338 | diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c |
3339 | index 74cb20f..87d9fad 100644 |
3340 | --- a/kernel/sched/fair.c |
3341 | +++ b/kernel/sched/fair.c |
3342 | @@ -7301,7 +7301,7 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) |
3343 | return 0; |
3344 | |
3345 | /* Disregard pcpu kthreads; they are where they need to be. */ |
3346 | - if ((p->flags & PF_KTHREAD) && kthread_is_per_cpu(p)) |
3347 | + if (kthread_is_per_cpu(p)) |
3348 | return 0; |
3349 | |
3350 | if (!cpumask_test_cpu(env->dst_cpu, p->cpus_ptr)) { |
3351 | diff --git a/lib/once.c b/lib/once.c |
3352 | index 8b7d623..59149bf 100644 |
3353 | --- a/lib/once.c |
3354 | +++ b/lib/once.c |
3355 | @@ -3,10 +3,12 @@ |
3356 | #include <linux/spinlock.h> |
3357 | #include <linux/once.h> |
3358 | #include <linux/random.h> |
3359 | +#include <linux/module.h> |
3360 | |
3361 | struct once_work { |
3362 | struct work_struct work; |
3363 | struct static_key_true *key; |
3364 | + struct module *module; |
3365 | }; |
3366 | |
3367 | static void once_deferred(struct work_struct *w) |
3368 | @@ -16,10 +18,11 @@ static void once_deferred(struct work_struct *w) |
3369 | work = container_of(w, struct once_work, work); |
3370 | BUG_ON(!static_key_enabled(work->key)); |
3371 | static_branch_disable(work->key); |
3372 | + module_put(work->module); |
3373 | kfree(work); |
3374 | } |
3375 | |
3376 | -static void once_disable_jump(struct static_key_true *key) |
3377 | +static void once_disable_jump(struct static_key_true *key, struct module *mod) |
3378 | { |
3379 | struct once_work *w; |
3380 | |
3381 | @@ -29,6 +32,8 @@ static void once_disable_jump(struct static_key_true *key) |
3382 | |
3383 | INIT_WORK(&w->work, once_deferred); |
3384 | w->key = key; |
3385 | + w->module = mod; |
3386 | + __module_get(mod); |
3387 | schedule_work(&w->work); |
3388 | } |
3389 | |
3390 | @@ -53,11 +58,11 @@ bool __do_once_start(bool *done, unsigned long *flags) |
3391 | EXPORT_SYMBOL(__do_once_start); |
3392 | |
3393 | void __do_once_done(bool *done, struct static_key_true *once_key, |
3394 | - unsigned long *flags) |
3395 | + unsigned long *flags, struct module *mod) |
3396 | __releases(once_lock) |
3397 | { |
3398 | *done = true; |
3399 | spin_unlock_irqrestore(&once_lock, *flags); |
3400 | - once_disable_jump(once_key); |
3401 | + once_disable_jump(once_key, mod); |
3402 | } |
3403 | EXPORT_SYMBOL(__do_once_done); |
3404 | diff --git a/mm/oom_kill.c b/mm/oom_kill.c |
3405 | index 212e718..f1b810d 100644 |
3406 | --- a/mm/oom_kill.c |
3407 | +++ b/mm/oom_kill.c |
3408 | @@ -197,17 +197,17 @@ static bool is_dump_unreclaim_slabs(void) |
3409 | * predictable as possible. The goal is to return the highest value for the |
3410 | * task consuming the most memory to avoid subsequent oom failures. |
3411 | */ |
3412 | -unsigned long oom_badness(struct task_struct *p, unsigned long totalpages) |
3413 | +long oom_badness(struct task_struct *p, unsigned long totalpages) |
3414 | { |
3415 | long points; |
3416 | long adj; |
3417 | |
3418 | if (oom_unkillable_task(p)) |
3419 | - return 0; |
3420 | + return LONG_MIN; |
3421 | |
3422 | p = find_lock_task_mm(p); |
3423 | if (!p) |
3424 | - return 0; |
3425 | + return LONG_MIN; |
3426 | |
3427 | /* |
3428 | * Do not even consider tasks which are explicitly marked oom |
3429 | @@ -219,7 +219,7 @@ unsigned long oom_badness(struct task_struct *p, unsigned long totalpages) |
3430 | test_bit(MMF_OOM_SKIP, &p->mm->flags) || |
3431 | in_vfork(p)) { |
3432 | task_unlock(p); |
3433 | - return 0; |
3434 | + return LONG_MIN; |
3435 | } |
3436 | |
3437 | /* |
3438 | @@ -234,11 +234,7 @@ unsigned long oom_badness(struct task_struct *p, unsigned long totalpages) |
3439 | adj *= totalpages / 1000; |
3440 | points += adj; |
3441 | |
3442 | - /* |
3443 | - * Never return 0 for an eligible task regardless of the root bonus and |
3444 | - * oom_score_adj (oom_score_adj can't be OOM_SCORE_ADJ_MIN here). |
3445 | - */ |
3446 | - return points > 0 ? points : 1; |
3447 | + return points; |
3448 | } |
3449 | |
3450 | static const char * const oom_constraint_text[] = { |
3451 | @@ -311,7 +307,7 @@ static enum oom_constraint constrained_alloc(struct oom_control *oc) |
3452 | static int oom_evaluate_task(struct task_struct *task, void *arg) |
3453 | { |
3454 | struct oom_control *oc = arg; |
3455 | - unsigned long points; |
3456 | + long points; |
3457 | |
3458 | if (oom_unkillable_task(task)) |
3459 | goto next; |
3460 | @@ -337,12 +333,12 @@ static int oom_evaluate_task(struct task_struct *task, void *arg) |
3461 | * killed first if it triggers an oom, then select it. |
3462 | */ |
3463 | if (oom_task_origin(task)) { |
3464 | - points = ULONG_MAX; |
3465 | + points = LONG_MAX; |
3466 | goto select; |
3467 | } |
3468 | |
3469 | points = oom_badness(task, oc->totalpages); |
3470 | - if (!points || points < oc->chosen_points) |
3471 | + if (points == LONG_MIN || points < oc->chosen_points) |
3472 | goto next; |
3473 | |
3474 | select: |
3475 | @@ -366,6 +362,8 @@ abort: |
3476 | */ |
3477 | static void select_bad_process(struct oom_control *oc) |
3478 | { |
3479 | + oc->chosen_points = LONG_MIN; |
3480 | + |
3481 | if (is_memcg_oom(oc)) |
3482 | mem_cgroup_scan_tasks(oc->memcg, oom_evaluate_task, oc); |
3483 | else { |
3484 | diff --git a/mm/page_alloc.c b/mm/page_alloc.c |
3485 | index ac669d4..c6fb178 100644 |
3486 | --- a/mm/page_alloc.c |
3487 | +++ b/mm/page_alloc.c |
3488 | @@ -893,7 +893,7 @@ static inline void __free_one_page(struct page *page, |
3489 | unsigned int max_order; |
3490 | struct capture_control *capc = task_capc(zone); |
3491 | |
3492 | - max_order = min_t(unsigned int, MAX_ORDER, pageblock_order + 1); |
3493 | + max_order = min_t(unsigned int, MAX_ORDER - 1, pageblock_order); |
3494 | |
3495 | VM_BUG_ON(!zone_is_initialized(zone)); |
3496 | VM_BUG_ON_PAGE(page->flags & PAGE_FLAGS_CHECK_AT_PREP, page); |
3497 | @@ -906,7 +906,7 @@ static inline void __free_one_page(struct page *page, |
3498 | VM_BUG_ON_PAGE(bad_range(zone, page), page); |
3499 | |
3500 | continue_merging: |
3501 | - while (order < max_order - 1) { |
3502 | + while (order < max_order) { |
3503 | if (compaction_capture(capc, page, order, migratetype)) { |
3504 | __mod_zone_freepage_state(zone, -(1 << order), |
3505 | migratetype); |
3506 | @@ -932,7 +932,7 @@ continue_merging: |
3507 | pfn = combined_pfn; |
3508 | order++; |
3509 | } |
3510 | - if (max_order < MAX_ORDER) { |
3511 | + if (order < MAX_ORDER - 1) { |
3512 | /* If we are here, it means order is >= pageblock_order. |
3513 | * We want to prevent merge between freepages on isolate |
3514 | * pageblock and normal pageblock. Without this, pageblock |
3515 | @@ -953,7 +953,7 @@ continue_merging: |
3516 | is_migrate_isolate(buddy_mt))) |
3517 | goto done_merging; |
3518 | } |
3519 | - max_order++; |
3520 | + max_order = order + 1; |
3521 | goto continue_merging; |
3522 | } |
3523 | |
3524 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
3525 | index 0bad5db..6fbc9cb 100644 |
3526 | --- a/net/core/rtnetlink.c |
3527 | +++ b/net/core/rtnetlink.c |
3528 | @@ -2414,6 +2414,7 @@ static int do_setlink(const struct sk_buff *skb, |
3529 | return err; |
3530 | |
3531 | if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) { |
3532 | + const char *pat = ifname && ifname[0] ? ifname : NULL; |
3533 | struct net *net = rtnl_link_get_net_capable(skb, dev_net(dev), |
3534 | tb, CAP_NET_ADMIN); |
3535 | if (IS_ERR(net)) { |
3536 | @@ -2421,7 +2422,7 @@ static int do_setlink(const struct sk_buff *skb, |
3537 | goto errout; |
3538 | } |
3539 | |
3540 | - err = dev_change_net_namespace(dev, net, ifname); |
3541 | + err = dev_change_net_namespace(dev, net, pat); |
3542 | put_net(net); |
3543 | if (err) |
3544 | goto errout; |
3545 | diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c |
3546 | index c886122..f86f948 100644 |
3547 | --- a/net/ipv4/icmp.c |
3548 | +++ b/net/ipv4/icmp.c |
3549 | @@ -460,6 +460,23 @@ out_bh_enable: |
3550 | local_bh_enable(); |
3551 | } |
3552 | |
3553 | +/* |
3554 | + * The device used for looking up which routing table to use for sending an ICMP |
3555 | + * error is preferably the source whenever it is set, which should ensure the |
3556 | + * icmp error can be sent to the source host, else lookup using the routing |
3557 | + * table of the destination device, else use the main routing table (index 0). |
3558 | + */ |
3559 | +static struct net_device *icmp_get_route_lookup_dev(struct sk_buff *skb) |
3560 | +{ |
3561 | + struct net_device *route_lookup_dev = NULL; |
3562 | + |
3563 | + if (skb->dev) |
3564 | + route_lookup_dev = skb->dev; |
3565 | + else if (skb_dst(skb)) |
3566 | + route_lookup_dev = skb_dst(skb)->dev; |
3567 | + return route_lookup_dev; |
3568 | +} |
3569 | + |
3570 | static struct rtable *icmp_route_lookup(struct net *net, |
3571 | struct flowi4 *fl4, |
3572 | struct sk_buff *skb_in, |
3573 | @@ -468,6 +485,7 @@ static struct rtable *icmp_route_lookup(struct net *net, |
3574 | int type, int code, |
3575 | struct icmp_bxm *param) |
3576 | { |
3577 | + struct net_device *route_lookup_dev; |
3578 | struct rtable *rt, *rt2; |
3579 | struct flowi4 fl4_dec; |
3580 | int err; |
3581 | @@ -482,7 +500,8 @@ static struct rtable *icmp_route_lookup(struct net *net, |
3582 | fl4->flowi4_proto = IPPROTO_ICMP; |
3583 | fl4->fl4_icmp_type = type; |
3584 | fl4->fl4_icmp_code = code; |
3585 | - fl4->flowi4_oif = l3mdev_master_ifindex(skb_dst(skb_in)->dev); |
3586 | + route_lookup_dev = icmp_get_route_lookup_dev(skb_in); |
3587 | + fl4->flowi4_oif = l3mdev_master_ifindex(route_lookup_dev); |
3588 | |
3589 | security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4)); |
3590 | rt = ip_route_output_key_hash(net, fl4, skb_in); |
3591 | @@ -506,7 +525,7 @@ static struct rtable *icmp_route_lookup(struct net *net, |
3592 | if (err) |
3593 | goto relookup_failed; |
3594 | |
3595 | - if (inet_addr_type_dev_table(net, skb_dst(skb_in)->dev, |
3596 | + if (inet_addr_type_dev_table(net, route_lookup_dev, |
3597 | fl4_dec.saddr) == RTN_LOCAL) { |
3598 | rt2 = __ip_route_output_key(net, &fl4_dec); |
3599 | if (IS_ERR(rt2)) |
3600 | diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c |
3601 | index d2b1ae8..b1ecc91 100644 |
3602 | --- a/net/ipv4/igmp.c |
3603 | +++ b/net/ipv4/igmp.c |
3604 | @@ -2730,6 +2730,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u |
3605 | rv = 1; |
3606 | } else if (im) { |
3607 | if (src_addr) { |
3608 | + spin_lock_bh(&im->lock); |
3609 | for (psf = im->sources; psf; psf = psf->sf_next) { |
3610 | if (psf->sf_inaddr == src_addr) |
3611 | break; |
3612 | @@ -2740,6 +2741,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u |
3613 | im->sfcount[MCAST_EXCLUDE]; |
3614 | else |
3615 | rv = im->sfcount[MCAST_EXCLUDE] != 0; |
3616 | + spin_unlock_bh(&im->lock); |
3617 | } else |
3618 | rv = 1; /* unspecified source; tentatively allow */ |
3619 | } |
3620 | diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c |
3621 | index fedad3a..fd8298b 100644 |
3622 | --- a/net/ipv4/ip_gre.c |
3623 | +++ b/net/ipv4/ip_gre.c |
3624 | @@ -446,6 +446,8 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev, |
3625 | |
3626 | static int gre_handle_offloads(struct sk_buff *skb, bool csum) |
3627 | { |
3628 | + if (csum && skb_checksum_start(skb) < skb->data) |
3629 | + return -EINVAL; |
3630 | return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE); |
3631 | } |
3632 | |
3633 | diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c |
3634 | index 4a988ce..4bcc36e 100644 |
3635 | --- a/net/netfilter/nf_conntrack_core.c |
3636 | +++ b/net/netfilter/nf_conntrack_core.c |
3637 | @@ -66,22 +66,17 @@ EXPORT_SYMBOL_GPL(nf_conntrack_hash); |
3638 | |
3639 | struct conntrack_gc_work { |
3640 | struct delayed_work dwork; |
3641 | - u32 last_bucket; |
3642 | + u32 next_bucket; |
3643 | bool exiting; |
3644 | bool early_drop; |
3645 | - long next_gc_run; |
3646 | }; |
3647 | |
3648 | static __read_mostly struct kmem_cache *nf_conntrack_cachep; |
3649 | static DEFINE_SPINLOCK(nf_conntrack_locks_all_lock); |
3650 | static __read_mostly bool nf_conntrack_locks_all; |
3651 | |
3652 | -/* every gc cycle scans at most 1/GC_MAX_BUCKETS_DIV part of table */ |
3653 | -#define GC_MAX_BUCKETS_DIV 128u |
3654 | -/* upper bound of full table scan */ |
3655 | -#define GC_MAX_SCAN_JIFFIES (16u * HZ) |
3656 | -/* desired ratio of entries found to be expired */ |
3657 | -#define GC_EVICT_RATIO 50u |
3658 | +#define GC_SCAN_INTERVAL (120u * HZ) |
3659 | +#define GC_SCAN_MAX_DURATION msecs_to_jiffies(10) |
3660 | |
3661 | static struct conntrack_gc_work conntrack_gc_work; |
3662 | |
3663 | @@ -1226,17 +1221,13 @@ static void nf_ct_offload_timeout(struct nf_conn *ct) |
3664 | |
3665 | static void gc_worker(struct work_struct *work) |
3666 | { |
3667 | - unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u); |
3668 | - unsigned int i, goal, buckets = 0, expired_count = 0; |
3669 | - unsigned int nf_conntrack_max95 = 0; |
3670 | + unsigned long end_time = jiffies + GC_SCAN_MAX_DURATION; |
3671 | + unsigned int i, hashsz, nf_conntrack_max95 = 0; |
3672 | + unsigned long next_run = GC_SCAN_INTERVAL; |
3673 | struct conntrack_gc_work *gc_work; |
3674 | - unsigned int ratio, scanned = 0; |
3675 | - unsigned long next_run; |
3676 | - |
3677 | gc_work = container_of(work, struct conntrack_gc_work, dwork.work); |
3678 | |
3679 | - goal = nf_conntrack_htable_size / GC_MAX_BUCKETS_DIV; |
3680 | - i = gc_work->last_bucket; |
3681 | + i = gc_work->next_bucket; |
3682 | if (gc_work->early_drop) |
3683 | nf_conntrack_max95 = nf_conntrack_max / 100u * 95u; |
3684 | |
3685 | @@ -1244,22 +1235,21 @@ static void gc_worker(struct work_struct *work) |
3686 | struct nf_conntrack_tuple_hash *h; |
3687 | struct hlist_nulls_head *ct_hash; |
3688 | struct hlist_nulls_node *n; |
3689 | - unsigned int hashsz; |
3690 | struct nf_conn *tmp; |
3691 | |
3692 | - i++; |
3693 | rcu_read_lock(); |
3694 | |
3695 | nf_conntrack_get_ht(&ct_hash, &hashsz); |
3696 | - if (i >= hashsz) |
3697 | - i = 0; |
3698 | + if (i >= hashsz) { |
3699 | + rcu_read_unlock(); |
3700 | + break; |
3701 | + } |
3702 | |
3703 | hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[i], hnnode) { |
3704 | struct net *net; |
3705 | |
3706 | tmp = nf_ct_tuplehash_to_ctrack(h); |
3707 | |
3708 | - scanned++; |
3709 | if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) { |
3710 | nf_ct_offload_timeout(tmp); |
3711 | continue; |
3712 | @@ -1267,7 +1257,6 @@ static void gc_worker(struct work_struct *work) |
3713 | |
3714 | if (nf_ct_is_expired(tmp)) { |
3715 | nf_ct_gc_expired(tmp); |
3716 | - expired_count++; |
3717 | continue; |
3718 | } |
3719 | |
3720 | @@ -1299,7 +1288,14 @@ static void gc_worker(struct work_struct *work) |
3721 | */ |
3722 | rcu_read_unlock(); |
3723 | cond_resched(); |
3724 | - } while (++buckets < goal); |
3725 | + i++; |
3726 | + |
3727 | + if (time_after(jiffies, end_time) && i < hashsz) { |
3728 | + gc_work->next_bucket = i; |
3729 | + next_run = 0; |
3730 | + break; |
3731 | + } |
3732 | + } while (i < hashsz); |
3733 | |
3734 | if (gc_work->exiting) |
3735 | return; |
3736 | @@ -1310,40 +1306,17 @@ static void gc_worker(struct work_struct *work) |
3737 | * |
3738 | * This worker is only here to reap expired entries when system went |
3739 | * idle after a busy period. |
3740 | - * |
3741 | - * The heuristics below are supposed to balance conflicting goals: |
3742 | - * |
3743 | - * 1. Minimize time until we notice a stale entry |
3744 | - * 2. Maximize scan intervals to not waste cycles |
3745 | - * |
3746 | - * Normally, expire ratio will be close to 0. |
3747 | - * |
3748 | - * As soon as a sizeable fraction of the entries have expired |
3749 | - * increase scan frequency. |
3750 | */ |
3751 | - ratio = scanned ? expired_count * 100 / scanned : 0; |
3752 | - if (ratio > GC_EVICT_RATIO) { |
3753 | - gc_work->next_gc_run = min_interval; |
3754 | - } else { |
3755 | - unsigned int max = GC_MAX_SCAN_JIFFIES / GC_MAX_BUCKETS_DIV; |
3756 | - |
3757 | - BUILD_BUG_ON((GC_MAX_SCAN_JIFFIES / GC_MAX_BUCKETS_DIV) == 0); |
3758 | - |
3759 | - gc_work->next_gc_run += min_interval; |
3760 | - if (gc_work->next_gc_run > max) |
3761 | - gc_work->next_gc_run = max; |
3762 | + if (next_run) { |
3763 | + gc_work->early_drop = false; |
3764 | + gc_work->next_bucket = 0; |
3765 | } |
3766 | - |
3767 | - next_run = gc_work->next_gc_run; |
3768 | - gc_work->last_bucket = i; |
3769 | - gc_work->early_drop = false; |
3770 | queue_delayed_work(system_power_efficient_wq, &gc_work->dwork, next_run); |
3771 | } |
3772 | |
3773 | static void conntrack_gc_work_init(struct conntrack_gc_work *gc_work) |
3774 | { |
3775 | INIT_DEFERRABLE_WORK(&gc_work->dwork, gc_worker); |
3776 | - gc_work->next_gc_run = HZ; |
3777 | gc_work->exiting = false; |
3778 | } |
3779 | |
3780 | diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c |
3781 | index faea2ce..b97a786 100644 |
3782 | --- a/net/qrtr/qrtr.c |
3783 | +++ b/net/qrtr/qrtr.c |
3784 | @@ -314,7 +314,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) |
3785 | goto err; |
3786 | } |
3787 | |
3788 | - if (len != ALIGN(size, 4) + hdrlen) |
3789 | + if (!size || len != ALIGN(size, 4) + hdrlen) |
3790 | goto err; |
3791 | |
3792 | if (cb->dst_port != QRTR_PORT_CTRL && cb->type != QRTR_TYPE_DATA) |
3793 | diff --git a/net/rds/ib_frmr.c b/net/rds/ib_frmr.c |
3794 | index 06ecf9d..ef6acd7 100644 |
3795 | --- a/net/rds/ib_frmr.c |
3796 | +++ b/net/rds/ib_frmr.c |
3797 | @@ -131,9 +131,9 @@ static int rds_ib_post_reg_frmr(struct rds_ib_mr *ibmr) |
3798 | cpu_relax(); |
3799 | } |
3800 | |
3801 | - ret = ib_map_mr_sg_zbva(frmr->mr, ibmr->sg, ibmr->sg_len, |
3802 | + ret = ib_map_mr_sg_zbva(frmr->mr, ibmr->sg, ibmr->sg_dma_len, |
3803 | &off, PAGE_SIZE); |
3804 | - if (unlikely(ret != ibmr->sg_len)) |
3805 | + if (unlikely(ret != ibmr->sg_dma_len)) |
3806 | return ret < 0 ? ret : -EINVAL; |
3807 | |
3808 | if (cmpxchg(&frmr->fr_state, |
3809 | diff --git a/net/socket.c b/net/socket.c |
3810 | index b14917d..9435856 100644 |
3811 | --- a/net/socket.c |
3812 | +++ b/net/socket.c |
3813 | @@ -1053,7 +1053,7 @@ static long sock_do_ioctl(struct net *net, struct socket *sock, |
3814 | rtnl_unlock(); |
3815 | if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf))) |
3816 | err = -EFAULT; |
3817 | - } else { |
3818 | + } else if (is_socket_ioctl_cmd(cmd)) { |
3819 | struct ifreq ifr; |
3820 | bool need_copyout; |
3821 | if (copy_from_user(&ifr, argp, sizeof(struct ifreq))) |
3822 | @@ -1062,6 +1062,8 @@ static long sock_do_ioctl(struct net *net, struct socket *sock, |
3823 | if (!err && need_copyout) |
3824 | if (copy_to_user(argp, &ifr, sizeof(struct ifreq))) |
3825 | return -EFAULT; |
3826 | + } else { |
3827 | + err = -ENOTTY; |
3828 | } |
3829 | return err; |
3830 | } |
3831 | @@ -3228,6 +3230,8 @@ static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd, |
3832 | struct ifreq ifreq; |
3833 | u32 data32; |
3834 | |
3835 | + if (!is_socket_ioctl_cmd(cmd)) |
3836 | + return -ENOTTY; |
3837 | if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ)) |
3838 | return -EFAULT; |
3839 | if (get_user(data32, &u_ifreq32->ifr_data)) |
3840 | diff --git a/scripts/Makefile b/scripts/Makefile |
3841 | index b4b7d8b..cd3fb08 100644 |
3842 | --- a/scripts/Makefile |
3843 | +++ b/scripts/Makefile |
3844 | @@ -23,6 +23,7 @@ hostprogs-$(CONFIG_ASN1) += asn1_compiler |
3845 | hostprogs-$(CONFIG_MODULE_SIG_FORMAT) += sign-file |
3846 | hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert |
3847 | hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert |
3848 | +hostprogs-$(CONFIG_SYSTEM_REVOCATION_LIST) += extract-cert |
3849 | |
3850 | HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include |
3851 | HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include |
3852 | diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c |
3853 | index 5604bd5..9f85626 100644 |
3854 | --- a/security/integrity/platform_certs/keyring_handler.c |
3855 | +++ b/security/integrity/platform_certs/keyring_handler.c |
3856 | @@ -61,6 +61,7 @@ static __init void uefi_blacklist_binary(const char *source, |
3857 | static __init void uefi_revocation_list_x509(const char *source, |
3858 | const void *data, size_t len) |
3859 | { |
3860 | + pr_info("Revoking X.509 certificate: %s\n", source); |
3861 | add_key_to_revocation_list(data, len); |
3862 | } |
3863 | |
3864 | diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c |
3865 | index 9eaf3a3..12a1f63 100644 |
3866 | --- a/security/integrity/platform_certs/load_uefi.c |
3867 | +++ b/security/integrity/platform_certs/load_uefi.c |
3868 | @@ -34,45 +34,114 @@ static __init bool uefi_check_ignore_db(void) |
3869 | /* |
3870 | * Get a certificate list blob from the named EFI variable. |
3871 | */ |
3872 | -static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid, |
3873 | - unsigned long *size , void **cert_list, |
3874 | - efi_status_t *status) |
3875 | +static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, |
3876 | + unsigned long *size, efi_status_t *status) |
3877 | { |
3878 | unsigned long lsize = 4; |
3879 | unsigned long tmpdb[4]; |
3880 | void *db; |
3881 | |
3882 | *status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); |
3883 | - if (*status == EFI_NOT_FOUND) { |
3884 | - *size = 0; |
3885 | - *cert_list = NULL; |
3886 | - return 0; |
3887 | - } |
3888 | + if (*status == EFI_NOT_FOUND) |
3889 | + return NULL; |
3890 | |
3891 | if (*status != EFI_BUFFER_TOO_SMALL) { |
3892 | pr_err("Couldn't get size: %s (0x%lx)\n", |
3893 | efi_status_to_str(*status), *status); |
3894 | - return efi_status_to_err(*status); |
3895 | + return NULL; |
3896 | } |
3897 | |
3898 | db = kmalloc(lsize, GFP_KERNEL); |
3899 | if (!db) |
3900 | - return -ENOMEM; |
3901 | + return NULL; |
3902 | |
3903 | *status = efi.get_variable(name, guid, NULL, &lsize, db); |
3904 | if (*status != EFI_SUCCESS) { |
3905 | kfree(db); |
3906 | pr_err("Error reading db var: %s (0x%lx)\n", |
3907 | efi_status_to_str(*status), *status); |
3908 | - return efi_status_to_err(*status); |
3909 | + return NULL; |
3910 | } |
3911 | |
3912 | *size = lsize; |
3913 | - *cert_list = db; |
3914 | + return db; |
3915 | +} |
3916 | + |
3917 | +/* |
3918 | + * load_moklist_certs() - Load Mok(X)List certs |
3919 | + * @load_db: Load MokListRT into db when true; MokListXRT into dbx when false |
3920 | + * |
3921 | + * Load the certs contained in the UEFI MokList(X)RT database into the |
3922 | + * platform trusted/denied keyring. |
3923 | + * |
3924 | + * This routine checks the EFI MOK config table first. If and only if |
3925 | + * that fails, this routine uses the MokList(X)RT ordinary UEFI variable. |
3926 | + * |
3927 | + * Return: Status |
3928 | + */ |
3929 | +static int __init load_moklist_certs(const bool load_db) |
3930 | +{ |
3931 | + struct efi_mokvar_table_entry *mokvar_entry; |
3932 | + efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; |
3933 | + void *mok; |
3934 | + unsigned long moksize; |
3935 | + efi_status_t status; |
3936 | + int rc; |
3937 | + const char *mokvar_name = "MokListRT"; |
3938 | + /* Should be const, but get_cert_list() doesn't have it as const yet */ |
3939 | + efi_char16_t *efivar_name = L"MokListRT"; |
3940 | + const char *parse_mokvar_name = "UEFI:MokListRT (MOKvar table)"; |
3941 | + const char *parse_efivar_name = "UEFI:MokListRT"; |
3942 | + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *) = get_handler_for_db; |
3943 | + |
3944 | + if (!load_db) { |
3945 | + mokvar_name = "MokListXRT"; |
3946 | + efivar_name = L"MokListXRT"; |
3947 | + parse_mokvar_name = "UEFI:MokListXRT (MOKvar table)"; |
3948 | + parse_efivar_name = "UEFI:MokListXRT"; |
3949 | + get_handler_for_guid = get_handler_for_dbx; |
3950 | + } |
3951 | + |
3952 | + /* First try to load certs from the EFI MOKvar config table. |
3953 | + * It's not an error if the MOKvar config table doesn't exist |
3954 | + * or the MokListRT entry is not found in it. |
3955 | + */ |
3956 | + mokvar_entry = efi_mokvar_entry_find(mokvar_name); |
3957 | + if (mokvar_entry) { |
3958 | + rc = parse_efi_signature_list(parse_mokvar_name, |
3959 | + mokvar_entry->data, |
3960 | + mokvar_entry->data_size, |
3961 | + get_handler_for_guid); |
3962 | + /* All done if that worked. */ |
3963 | + if (!rc) |
3964 | + return rc; |
3965 | + |
3966 | + pr_err("Couldn't parse %s signatures from EFI MOKvar config table: %d\n", |
3967 | + mokvar_name, rc); |
3968 | + } |
3969 | + |
3970 | + /* Get MokListRT. It might not exist, so it isn't an error |
3971 | + * if we can't get it. |
3972 | + */ |
3973 | + mok = get_cert_list(efivar_name, &mok_var, &moksize, &status); |
3974 | + if (mok) { |
3975 | + rc = parse_efi_signature_list(parse_efivar_name, |
3976 | + mok, moksize, get_handler_for_guid); |
3977 | + kfree(mok); |
3978 | + if (rc) |
3979 | + pr_err("Couldn't parse %s signatures: %d\n", mokvar_name, rc); |
3980 | + return rc; |
3981 | + } |
3982 | + if (status == EFI_NOT_FOUND) |
3983 | + pr_debug("%s variable wasn't found\n", mokvar_name); |
3984 | + else |
3985 | + pr_info("Couldn't get UEFI %s\n", mokvar_name); |
3986 | return 0; |
3987 | } |
3988 | |
3989 | /* |
3990 | + * load_uefi_certs() - Load certs from UEFI sources |
3991 | + * |
3992 | * Load the certs contained in the UEFI databases into the platform trusted |
3993 | * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist |
3994 | * keyring. |
3995 | @@ -80,26 +149,25 @@ static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid, |
3996 | static int __init load_uefi_certs(void) |
3997 | { |
3998 | efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; |
3999 | - efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; |
4000 | - void *db = NULL, *dbx = NULL, *mok = NULL; |
4001 | - unsigned long dbsize = 0, dbxsize = 0, moksize = 0; |
4002 | + void *db = NULL, *dbx = NULL; |
4003 | + unsigned long dbsize = 0, dbxsize = 0; |
4004 | efi_status_t status; |
4005 | int rc = 0; |
4006 | |
4007 | if (!efi.get_variable) |
4008 | return false; |
4009 | |
4010 | - /* Get db, MokListRT, and dbx. They might not exist, so it isn't |
4011 | - * an error if we can't get them. |
4012 | + /* Get db and dbx. They might not exist, so it isn't an error |
4013 | + * if we can't get them. |
4014 | */ |
4015 | if (!uefi_check_ignore_db()) { |
4016 | - rc = get_cert_list(L"db", &secure_var, &dbsize, &db, &status); |
4017 | - if (rc < 0) { |
4018 | + db = get_cert_list(L"db", &secure_var, &dbsize, &status); |
4019 | + if (!db) { |
4020 | if (status == EFI_NOT_FOUND) |
4021 | pr_debug("MODSIGN: db variable wasn't found\n"); |
4022 | else |
4023 | pr_err("MODSIGN: Couldn't get UEFI db list\n"); |
4024 | - } else if (dbsize != 0) { |
4025 | + } else { |
4026 | rc = parse_efi_signature_list("UEFI:db", |
4027 | db, dbsize, get_handler_for_db); |
4028 | if (rc) |
4029 | @@ -109,27 +177,13 @@ static int __init load_uefi_certs(void) |
4030 | } |
4031 | } |
4032 | |
4033 | - rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok, &status); |
4034 | - if (rc < 0) { |
4035 | - if (status == EFI_NOT_FOUND) |
4036 | - pr_debug("MokListRT variable wasn't found\n"); |
4037 | - else |
4038 | - pr_info("Couldn't get UEFI MokListRT\n"); |
4039 | - } else if (moksize != 0) { |
4040 | - rc = parse_efi_signature_list("UEFI:MokListRT", |
4041 | - mok, moksize, get_handler_for_db); |
4042 | - if (rc) |
4043 | - pr_err("Couldn't parse MokListRT signatures: %d\n", rc); |
4044 | - kfree(mok); |
4045 | - } |
4046 | - |
4047 | - rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx, &status); |
4048 | - if (rc < 0) { |
4049 | + dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status); |
4050 | + if (!dbx) { |
4051 | if (status == EFI_NOT_FOUND) |
4052 | pr_debug("dbx variable wasn't found\n"); |
4053 | else |
4054 | pr_info("Couldn't get UEFI dbx list\n"); |
4055 | - } else if (dbxsize != 0) { |
4056 | + } else { |
4057 | rc = parse_efi_signature_list("UEFI:dbx", |
4058 | dbx, dbxsize, |
4059 | get_handler_for_dbx); |
4060 | @@ -138,6 +192,16 @@ static int __init load_uefi_certs(void) |
4061 | kfree(dbx); |
4062 | } |
4063 | |
4064 | + /* Load the MokListXRT certs */ |
4065 | + rc = load_moklist_certs(false); |
4066 | + if (rc) |
4067 | + pr_err("Couldn't parse mokx signatures: %d\n", rc); |
4068 | + |
4069 | + /* Load the MokListRT certs */ |
4070 | + rc = load_moklist_certs(true); |
4071 | + if (rc) |
4072 | + pr_err("Couldn't parse mok signatures: %d\n", rc); |
4073 | + |
4074 | return rc; |
4075 | } |
4076 | late_initcall(load_uefi_certs); |
4077 | diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c |
4078 | index 1662573..fd300c3 100644 |
4079 | --- a/sound/core/pcm_lib.c |
4080 | +++ b/sound/core/pcm_lib.c |
4081 | @@ -1736,7 +1736,7 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream, |
4082 | channels = params_channels(params); |
4083 | frame_size = snd_pcm_format_size(format, channels); |
4084 | if (frame_size > 0) |
4085 | - params->fifo_size /= (unsigned)frame_size; |
4086 | + params->fifo_size /= frame_size; |
4087 | } |
4088 | return 0; |
4089 | } |
4090 | diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c |
4091 | index dcf3545..59f88b3 100644 |
4092 | --- a/sound/pci/hda/patch_realtek.c |
4093 | +++ b/sound/pci/hda/patch_realtek.c |
4094 | @@ -9199,6 +9199,16 @@ static int patch_alc269(struct hda_codec *codec) |
4095 | |
4096 | snd_hda_pick_fixup(codec, alc269_fixup_models, |
4097 | alc269_fixup_tbl, alc269_fixups); |
4098 | + /* FIXME: both TX300 and ROG Strix G17 have the same SSID, and |
4099 | + * the quirk breaks the latter (bko#214101). |
4100 | + * Clear the wrong entry. |
4101 | + */ |
4102 | + if (codec->fixup_id == ALC282_FIXUP_ASUS_TX300 && |
4103 | + codec->core.vendor_id == 0x10ec0294) { |
4104 | + codec_dbg(codec, "Clear wrong fixup for ASUS ROG Strix G17\n"); |
4105 | + codec->fixup_id = HDA_FIXUP_ID_NOT_SET; |
4106 | + } |
4107 | + |
4108 | snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups, true); |
4109 | snd_hda_pick_pin_fixup(codec, alc269_fallback_pin_fixup_tbl, alc269_fixups, false); |
4110 | snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl, |
4111 | diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c |
4112 | index 4d20f3f..d5d8288 100644 |
4113 | --- a/sound/usb/quirks.c |
4114 | +++ b/sound/usb/quirks.c |
4115 | @@ -1841,6 +1841,7 @@ static const struct registration_quirk registration_quirks[] = { |
4116 | REG_QUIRK_ENTRY(0x0951, 0x16ed, 2), /* Kingston HyperX Cloud Alpha S */ |
4117 | REG_QUIRK_ENTRY(0x0951, 0x16ea, 2), /* Kingston HyperX Cloud Flight S */ |
4118 | REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2), /* JBL Quantum 600 */ |
4119 | + REG_QUIRK_ENTRY(0x0ecb, 0x1f47, 2), /* JBL Quantum 800 */ |
4120 | REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2), /* JBL Quantum 400 */ |
4121 | REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2), /* JBL Quantum 600 */ |
4122 | REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2), /* JBL Quantum 800 */ |