mirror of
https://github.com/armbian/build.git
synced 2025-08-15 07:36:57 +02:00
6885 lines
228 KiB
Diff
6885 lines
228 KiB
Diff
diff --git a/Documentation/scheduler/sched-capacity.rst b/Documentation/scheduler/sched-capacity.rst
|
||
index e2c1cf7431588e..de414b33dd2abd 100644
|
||
--- a/Documentation/scheduler/sched-capacity.rst
|
||
+++ b/Documentation/scheduler/sched-capacity.rst
|
||
@@ -39,14 +39,15 @@ per Hz, leading to::
|
||
-------------------
|
||
|
||
Two different capacity values are used within the scheduler. A CPU's
|
||
-``capacity_orig`` is its maximum attainable capacity, i.e. its maximum
|
||
-attainable performance level. A CPU's ``capacity`` is its ``capacity_orig`` to
|
||
-which some loss of available performance (e.g. time spent handling IRQs) is
|
||
-subtracted.
|
||
+``original capacity`` is its maximum attainable capacity, i.e. its maximum
|
||
+attainable performance level. This original capacity is returned by
|
||
+the function arch_scale_cpu_capacity(). A CPU's ``capacity`` is its ``original
|
||
+capacity`` to which some loss of available performance (e.g. time spent
|
||
+handling IRQs) is subtracted.
|
||
|
||
Note that a CPU's ``capacity`` is solely intended to be used by the CFS class,
|
||
-while ``capacity_orig`` is class-agnostic. The rest of this document will use
|
||
-the term ``capacity`` interchangeably with ``capacity_orig`` for the sake of
|
||
+while ``original capacity`` is class-agnostic. The rest of this document will use
|
||
+the term ``capacity`` interchangeably with ``original capacity`` for the sake of
|
||
brevity.
|
||
|
||
1.3 Platform examples
|
||
diff --git a/Makefile b/Makefile
|
||
index b1dfe3df7dfc9d..23e90df5785c84 100644
|
||
--- a/Makefile
|
||
+++ b/Makefile
|
||
@@ -1,7 +1,7 @@
|
||
# SPDX-License-Identifier: GPL-2.0
|
||
VERSION = 6
|
||
PATCHLEVEL = 6
|
||
-SUBLEVEL = 88
|
||
+SUBLEVEL = 89
|
||
EXTRAVERSION =
|
||
NAME = Pinguïn Aangedreven
|
||
|
||
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi
|
||
index 39110c1232e0da..db10b4b46cca9d 100644
|
||
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi
|
||
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000.dtsi
|
||
@@ -196,13 +196,6 @@ key-power {
|
||
wakeup-event-action = <EV_ACT_ASSERTED>;
|
||
wakeup-source;
|
||
};
|
||
-
|
||
- key-suspend {
|
||
- label = "Suspend";
|
||
- gpios = <&gpio TEGRA234_MAIN_GPIO(G, 2) GPIO_ACTIVE_LOW>;
|
||
- linux,input-type = <EV_KEY>;
|
||
- linux,code = <KEY_SLEEP>;
|
||
- };
|
||
};
|
||
|
||
fan: pwm-fan {
|
||
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
|
||
index 623cf80639decc..25aa993abebcea 100644
|
||
--- a/arch/loongarch/Kconfig
|
||
+++ b/arch/loongarch/Kconfig
|
||
@@ -59,6 +59,7 @@ config LOONGARCH
|
||
select ARCH_SUPPORTS_NUMA_BALANCING
|
||
select ARCH_USE_BUILTIN_BSWAP
|
||
select ARCH_USE_CMPXCHG_LOCKREF
|
||
+ select ARCH_USE_MEMTEST
|
||
select ARCH_USE_QUEUED_RWLOCKS
|
||
select ARCH_USE_QUEUED_SPINLOCKS
|
||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
|
||
diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h
|
||
index f3ddaed9ef7f08..a5b63c84f8541a 100644
|
||
--- a/arch/loongarch/include/asm/ptrace.h
|
||
+++ b/arch/loongarch/include/asm/ptrace.h
|
||
@@ -33,9 +33,9 @@ struct pt_regs {
|
||
unsigned long __last[];
|
||
} __aligned(8);
|
||
|
||
-static inline int regs_irqs_disabled(struct pt_regs *regs)
|
||
+static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
|
||
{
|
||
- return arch_irqs_disabled_flags(regs->csr_prmd);
|
||
+ return !(regs->csr_prmd & CSR_PRMD_PIE);
|
||
}
|
||
|
||
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
|
||
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
|
||
index d59052c03d9b7e..2b4b99b4e6c94e 100644
|
||
--- a/arch/loongarch/kernel/traps.c
|
||
+++ b/arch/loongarch/kernel/traps.c
|
||
@@ -527,9 +527,10 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs)
|
||
die_if_kernel("Kernel ale access", regs);
|
||
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr);
|
||
#else
|
||
+ bool pie = regs_irqs_disabled(regs);
|
||
unsigned int *pc;
|
||
|
||
- if (regs->csr_prmd & CSR_PRMD_PIE)
|
||
+ if (!pie)
|
||
local_irq_enable();
|
||
|
||
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr);
|
||
@@ -556,7 +557,7 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs)
|
||
die_if_kernel("Kernel ale access", regs);
|
||
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr);
|
||
out:
|
||
- if (regs->csr_prmd & CSR_PRMD_PIE)
|
||
+ if (!pie)
|
||
local_irq_disable();
|
||
#endif
|
||
irqentry_exit(regs, state);
|
||
@@ -588,12 +589,13 @@ static void bug_handler(struct pt_regs *regs)
|
||
asmlinkage void noinstr do_bce(struct pt_regs *regs)
|
||
{
|
||
bool user = user_mode(regs);
|
||
+ bool pie = regs_irqs_disabled(regs);
|
||
unsigned long era = exception_era(regs);
|
||
u64 badv = 0, lower = 0, upper = ULONG_MAX;
|
||
union loongarch_instruction insn;
|
||
irqentry_state_t state = irqentry_enter(regs);
|
||
|
||
- if (regs->csr_prmd & CSR_PRMD_PIE)
|
||
+ if (!pie)
|
||
local_irq_enable();
|
||
|
||
current->thread.trap_nr = read_csr_excode();
|
||
@@ -659,7 +661,7 @@ asmlinkage void noinstr do_bce(struct pt_regs *regs)
|
||
force_sig_bnderr((void __user *)badv, (void __user *)lower, (void __user *)upper);
|
||
|
||
out:
|
||
- if (regs->csr_prmd & CSR_PRMD_PIE)
|
||
+ if (!pie)
|
||
local_irq_disable();
|
||
|
||
irqentry_exit(regs, state);
|
||
@@ -677,11 +679,12 @@ asmlinkage void noinstr do_bce(struct pt_regs *regs)
|
||
asmlinkage void noinstr do_bp(struct pt_regs *regs)
|
||
{
|
||
bool user = user_mode(regs);
|
||
+ bool pie = regs_irqs_disabled(regs);
|
||
unsigned int opcode, bcode;
|
||
unsigned long era = exception_era(regs);
|
||
irqentry_state_t state = irqentry_enter(regs);
|
||
|
||
- if (regs->csr_prmd & CSR_PRMD_PIE)
|
||
+ if (!pie)
|
||
local_irq_enable();
|
||
|
||
if (__get_inst(&opcode, (u32 *)era, user))
|
||
@@ -747,7 +750,7 @@ asmlinkage void noinstr do_bp(struct pt_regs *regs)
|
||
}
|
||
|
||
out:
|
||
- if (regs->csr_prmd & CSR_PRMD_PIE)
|
||
+ if (!pie)
|
||
local_irq_disable();
|
||
|
||
irqentry_exit(regs, state);
|
||
@@ -982,6 +985,7 @@ static void init_restore_lbt(void)
|
||
|
||
asmlinkage void noinstr do_lbt(struct pt_regs *regs)
|
||
{
|
||
+ bool pie = regs_irqs_disabled(regs);
|
||
irqentry_state_t state = irqentry_enter(regs);
|
||
|
||
/*
|
||
@@ -991,7 +995,7 @@ asmlinkage void noinstr do_lbt(struct pt_regs *regs)
|
||
* (including the user using 'MOVGR2GCSR' to turn on TM, which
|
||
* will not trigger the BTE), we need to check PRMD first.
|
||
*/
|
||
- if (regs->csr_prmd & CSR_PRMD_PIE)
|
||
+ if (!pie)
|
||
local_irq_enable();
|
||
|
||
if (!cpu_has_lbt) {
|
||
@@ -1005,7 +1009,7 @@ asmlinkage void noinstr do_lbt(struct pt_regs *regs)
|
||
preempt_enable();
|
||
|
||
out:
|
||
- if (regs->csr_prmd & CSR_PRMD_PIE)
|
||
+ if (!pie)
|
||
local_irq_disable();
|
||
|
||
irqentry_exit(regs, state);
|
||
diff --git a/arch/loongarch/mm/hugetlbpage.c b/arch/loongarch/mm/hugetlbpage.c
|
||
index 1e76fcb83093dd..41308429f44612 100644
|
||
--- a/arch/loongarch/mm/hugetlbpage.c
|
||
+++ b/arch/loongarch/mm/hugetlbpage.c
|
||
@@ -47,7 +47,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
|
||
pmd = pmd_offset(pud, addr);
|
||
}
|
||
}
|
||
- return (pte_t *) pmd;
|
||
+ return pmd_none(pmdp_get(pmd)) ? NULL : (pte_t *) pmd;
|
||
}
|
||
|
||
int pmd_huge(pmd_t pmd)
|
||
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
|
||
index 4dd53427f65785..a5bf96993bb1a6 100644
|
||
--- a/arch/loongarch/mm/init.c
|
||
+++ b/arch/loongarch/mm/init.c
|
||
@@ -64,9 +64,6 @@ void __init paging_init(void)
|
||
{
|
||
unsigned long max_zone_pfns[MAX_NR_ZONES];
|
||
|
||
-#ifdef CONFIG_ZONE_DMA
|
||
- max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
|
||
-#endif
|
||
#ifdef CONFIG_ZONE_DMA32
|
||
max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
|
||
#endif
|
||
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
|
||
index 696b40beb774f5..8494466740ccad 100644
|
||
--- a/arch/mips/include/asm/mips-cm.h
|
||
+++ b/arch/mips/include/asm/mips-cm.h
|
||
@@ -47,6 +47,16 @@ extern phys_addr_t __mips_cm_phys_base(void);
|
||
*/
|
||
extern int mips_cm_is64;
|
||
|
||
+/*
|
||
+ * mips_cm_is_l2_hci_broken - determine if HCI is broken
|
||
+ *
|
||
+ * Some CM reports show that Hardware Cache Initialization is
|
||
+ * complete, but in reality it's not the case. They also incorrectly
|
||
+ * indicate that Hardware Cache Initialization is supported. This
|
||
+ * flags allows warning about this broken feature.
|
||
+ */
|
||
+extern bool mips_cm_is_l2_hci_broken;
|
||
+
|
||
/**
|
||
* mips_cm_error_report - Report CM cache errors
|
||
*/
|
||
@@ -85,6 +95,18 @@ static inline bool mips_cm_present(void)
|
||
#endif
|
||
}
|
||
|
||
+/**
|
||
+ * mips_cm_update_property - update property from the device tree
|
||
+ *
|
||
+ * Retrieve the properties from the device tree if a CM node exist and
|
||
+ * update the internal variable based on this.
|
||
+ */
|
||
+#ifdef CONFIG_MIPS_CM
|
||
+extern void mips_cm_update_property(void);
|
||
+#else
|
||
+static inline void mips_cm_update_property(void) {}
|
||
+#endif
|
||
+
|
||
/**
|
||
* mips_cm_has_l2sync - determine whether an L2-only sync region is present
|
||
*
|
||
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
|
||
index 3f00788b08718d..4f75160f08949f 100644
|
||
--- a/arch/mips/kernel/mips-cm.c
|
||
+++ b/arch/mips/kernel/mips-cm.c
|
||
@@ -5,6 +5,7 @@
|
||
*/
|
||
|
||
#include <linux/errno.h>
|
||
+#include <linux/of.h>
|
||
#include <linux/percpu.h>
|
||
#include <linux/spinlock.h>
|
||
|
||
@@ -14,6 +15,7 @@
|
||
void __iomem *mips_gcr_base;
|
||
void __iomem *mips_cm_l2sync_base;
|
||
int mips_cm_is64;
|
||
+bool mips_cm_is_l2_hci_broken;
|
||
|
||
static char *cm2_tr[8] = {
|
||
"mem", "gcr", "gic", "mmio",
|
||
@@ -243,6 +245,18 @@ static void mips_cm_probe_l2sync(void)
|
||
mips_cm_l2sync_base = ioremap(addr, MIPS_CM_L2SYNC_SIZE);
|
||
}
|
||
|
||
+void mips_cm_update_property(void)
|
||
+{
|
||
+ struct device_node *cm_node;
|
||
+
|
||
+ cm_node = of_find_compatible_node(of_root, NULL, "mobileye,eyeq6-cm");
|
||
+ if (!cm_node)
|
||
+ return;
|
||
+ pr_info("HCI (Hardware Cache Init for the L2 cache) in GCR_L2_RAM_CONFIG from the CM3 is broken");
|
||
+ mips_cm_is_l2_hci_broken = true;
|
||
+ of_node_put(cm_node);
|
||
+}
|
||
+
|
||
int mips_cm_probe(void)
|
||
{
|
||
phys_addr_t addr;
|
||
diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c
|
||
index 0f9b3b5914cf69..b70b67adb855f6 100644
|
||
--- a/arch/parisc/kernel/pdt.c
|
||
+++ b/arch/parisc/kernel/pdt.c
|
||
@@ -63,6 +63,7 @@ static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss;
|
||
#define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL)
|
||
#define PDT_ADDR_SINGLE_ERR 1UL
|
||
|
||
+#ifdef CONFIG_PROC_FS
|
||
/* report PDT entries via /proc/meminfo */
|
||
void arch_report_meminfo(struct seq_file *m)
|
||
{
|
||
@@ -74,6 +75,7 @@ void arch_report_meminfo(struct seq_file *m)
|
||
seq_printf(m, "PDT_cur_entries: %7lu\n",
|
||
pdt_status.pdt_entries);
|
||
}
|
||
+#endif
|
||
|
||
static int get_info_pat_new(void)
|
||
{
|
||
diff --git a/arch/riscv/include/asm/alternative-macros.h b/arch/riscv/include/asm/alternative-macros.h
|
||
index 721ec275ce57e3..231d777d936c2d 100644
|
||
--- a/arch/riscv/include/asm/alternative-macros.h
|
||
+++ b/arch/riscv/include/asm/alternative-macros.h
|
||
@@ -115,24 +115,19 @@
|
||
\old_c
|
||
.endm
|
||
|
||
-#define _ALTERNATIVE_CFG(old_c, ...) \
|
||
- ALTERNATIVE_CFG old_c
|
||
-
|
||
-#define _ALTERNATIVE_CFG_2(old_c, ...) \
|
||
- ALTERNATIVE_CFG old_c
|
||
+#define __ALTERNATIVE_CFG(old_c, ...) ALTERNATIVE_CFG old_c
|
||
+#define __ALTERNATIVE_CFG_2(old_c, ...) ALTERNATIVE_CFG old_c
|
||
|
||
#else /* !__ASSEMBLY__ */
|
||
|
||
-#define __ALTERNATIVE_CFG(old_c) \
|
||
- old_c "\n"
|
||
+#define __ALTERNATIVE_CFG(old_c, ...) old_c "\n"
|
||
+#define __ALTERNATIVE_CFG_2(old_c, ...) old_c "\n"
|
||
|
||
-#define _ALTERNATIVE_CFG(old_c, ...) \
|
||
- __ALTERNATIVE_CFG(old_c)
|
||
+#endif /* __ASSEMBLY__ */
|
||
|
||
-#define _ALTERNATIVE_CFG_2(old_c, ...) \
|
||
- __ALTERNATIVE_CFG(old_c)
|
||
+#define _ALTERNATIVE_CFG(old_c, ...) __ALTERNATIVE_CFG(old_c)
|
||
+#define _ALTERNATIVE_CFG_2(old_c, ...) __ALTERNATIVE_CFG_2(old_c)
|
||
|
||
-#endif /* __ASSEMBLY__ */
|
||
#endif /* CONFIG_RISCV_ALTERNATIVE */
|
||
|
||
/*
|
||
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
|
||
index b16352083ff987..f0be263b334ced 100644
|
||
--- a/arch/s390/kvm/intercept.c
|
||
+++ b/arch/s390/kvm/intercept.c
|
||
@@ -94,7 +94,7 @@ static int handle_validity(struct kvm_vcpu *vcpu)
|
||
|
||
vcpu->stat.exit_validity++;
|
||
trace_kvm_s390_intercept_validity(vcpu, viwhy);
|
||
- KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%pK)", viwhy,
|
||
+ KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%p)", viwhy,
|
||
current->pid, vcpu->kvm);
|
||
|
||
/* do not warn on invalid runtime instrumentation mode */
|
||
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
|
||
index efaebba5ee19c7..fe4841104ed924 100644
|
||
--- a/arch/s390/kvm/interrupt.c
|
||
+++ b/arch/s390/kvm/interrupt.c
|
||
@@ -3161,7 +3161,7 @@ void kvm_s390_gisa_clear(struct kvm *kvm)
|
||
if (!gi->origin)
|
||
return;
|
||
gisa_clear_ipm(gi->origin);
|
||
- VM_EVENT(kvm, 3, "gisa 0x%pK cleared", gi->origin);
|
||
+ VM_EVENT(kvm, 3, "gisa 0x%p cleared", gi->origin);
|
||
}
|
||
|
||
void kvm_s390_gisa_init(struct kvm *kvm)
|
||
@@ -3178,7 +3178,7 @@ void kvm_s390_gisa_init(struct kvm *kvm)
|
||
gi->timer.function = gisa_vcpu_kicker;
|
||
memset(gi->origin, 0, sizeof(struct kvm_s390_gisa));
|
||
gi->origin->next_alert = (u32)virt_to_phys(gi->origin);
|
||
- VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin);
|
||
+ VM_EVENT(kvm, 3, "gisa 0x%p initialized", gi->origin);
|
||
}
|
||
|
||
void kvm_s390_gisa_enable(struct kvm *kvm)
|
||
@@ -3219,7 +3219,7 @@ void kvm_s390_gisa_destroy(struct kvm *kvm)
|
||
process_gib_alert_list();
|
||
hrtimer_cancel(&gi->timer);
|
||
gi->origin = NULL;
|
||
- VM_EVENT(kvm, 3, "gisa 0x%pK destroyed", gisa);
|
||
+ VM_EVENT(kvm, 3, "gisa 0x%p destroyed", gisa);
|
||
}
|
||
|
||
void kvm_s390_gisa_disable(struct kvm *kvm)
|
||
@@ -3468,7 +3468,7 @@ int __init kvm_s390_gib_init(u8 nisc)
|
||
}
|
||
}
|
||
|
||
- KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc);
|
||
+ KVM_EVENT(3, "gib 0x%p (nisc=%d) initialized", gib, gib->nisc);
|
||
goto out;
|
||
|
||
out_unreg_gal:
|
||
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
|
||
index 348d030d2660ca..890d850f51f076 100644
|
||
--- a/arch/s390/kvm/kvm-s390.c
|
||
+++ b/arch/s390/kvm/kvm-s390.c
|
||
@@ -990,7 +990,7 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
|
||
}
|
||
mutex_unlock(&kvm->lock);
|
||
VM_EVENT(kvm, 3, "SET: max guest address: %lu", new_limit);
|
||
- VM_EVENT(kvm, 3, "New guest asce: 0x%pK",
|
||
+ VM_EVENT(kvm, 3, "New guest asce: 0x%p",
|
||
(void *) kvm->arch.gmap->asce);
|
||
break;
|
||
}
|
||
@@ -3418,7 +3418,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
||
kvm_s390_gisa_init(kvm);
|
||
INIT_LIST_HEAD(&kvm->arch.pv.need_cleanup);
|
||
kvm->arch.pv.set_aside = NULL;
|
||
- KVM_EVENT(3, "vm 0x%pK created by pid %u", kvm, current->pid);
|
||
+ KVM_EVENT(3, "vm 0x%p created by pid %u", kvm, current->pid);
|
||
|
||
return 0;
|
||
out_err:
|
||
@@ -3481,7 +3481,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
|
||
kvm_s390_destroy_adapters(kvm);
|
||
kvm_s390_clear_float_irqs(kvm);
|
||
kvm_s390_vsie_destroy(kvm);
|
||
- KVM_EVENT(3, "vm 0x%pK destroyed", kvm);
|
||
+ KVM_EVENT(3, "vm 0x%p destroyed", kvm);
|
||
}
|
||
|
||
/* Section: vcpu related */
|
||
@@ -3602,7 +3602,7 @@ static int sca_switch_to_extended(struct kvm *kvm)
|
||
|
||
free_page((unsigned long)old_sca);
|
||
|
||
- VM_EVENT(kvm, 2, "Switched to ESCA (0x%pK -> 0x%pK)",
|
||
+ VM_EVENT(kvm, 2, "Switched to ESCA (0x%p -> 0x%p)",
|
||
old_sca, kvm->arch.sca);
|
||
return 0;
|
||
}
|
||
@@ -3974,7 +3974,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||
goto out_free_sie_block;
|
||
}
|
||
|
||
- VM_EVENT(vcpu->kvm, 3, "create cpu %d at 0x%pK, sie block at 0x%pK",
|
||
+ VM_EVENT(vcpu->kvm, 3, "create cpu %d at 0x%p, sie block at 0x%p",
|
||
vcpu->vcpu_id, vcpu, vcpu->arch.sie_block);
|
||
trace_kvm_s390_create_vcpu(vcpu->vcpu_id, vcpu, vcpu->arch.sie_block);
|
||
|
||
diff --git a/arch/s390/kvm/trace-s390.h b/arch/s390/kvm/trace-s390.h
|
||
index 6f0209d45164f0..9c5f546a2e1a3c 100644
|
||
--- a/arch/s390/kvm/trace-s390.h
|
||
+++ b/arch/s390/kvm/trace-s390.h
|
||
@@ -56,7 +56,7 @@ TRACE_EVENT(kvm_s390_create_vcpu,
|
||
__entry->sie_block = sie_block;
|
||
),
|
||
|
||
- TP_printk("create cpu %d at 0x%pK, sie block at 0x%pK",
|
||
+ TP_printk("create cpu %d at 0x%p, sie block at 0x%p",
|
||
__entry->id, __entry->vcpu, __entry->sie_block)
|
||
);
|
||
|
||
@@ -255,7 +255,7 @@ TRACE_EVENT(kvm_s390_enable_css,
|
||
__entry->kvm = kvm;
|
||
),
|
||
|
||
- TP_printk("enabling channel I/O support (kvm @ %pK)\n",
|
||
+ TP_printk("enabling channel I/O support (kvm @ %p)\n",
|
||
__entry->kvm)
|
||
);
|
||
|
||
diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S
|
||
index 2143358d0c4c74..78fd2442b49dcd 100644
|
||
--- a/arch/x86/entry/entry.S
|
||
+++ b/arch/x86/entry/entry.S
|
||
@@ -16,7 +16,7 @@
|
||
|
||
SYM_FUNC_START(entry_ibpb)
|
||
movl $MSR_IA32_PRED_CMD, %ecx
|
||
- movl $PRED_CMD_IBPB, %eax
|
||
+ movl _ASM_RIP(x86_pred_cmd), %eax
|
||
xorl %edx, %edx
|
||
wrmsr
|
||
|
||
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
|
||
index 1458ccaa6a0579..ad63bd408cd900 100644
|
||
--- a/arch/x86/events/core.c
|
||
+++ b/arch/x86/events/core.c
|
||
@@ -623,7 +623,7 @@ int x86_pmu_hw_config(struct perf_event *event)
|
||
if (event->attr.type == event->pmu->type)
|
||
event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
|
||
|
||
- if (!event->attr.freq && x86_pmu.limit_period) {
|
||
+ if (is_sampling_event(event) && !event->attr.freq && x86_pmu.limit_period) {
|
||
s64 left = event->attr.sample_period;
|
||
x86_pmu.limit_period(event, &left);
|
||
if (left > event->attr.sample_period)
|
||
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
|
||
index ca8eed1d496ab4..2bec0c89a95c27 100644
|
||
--- a/arch/x86/include/asm/asm.h
|
||
+++ b/arch/x86/include/asm/asm.h
|
||
@@ -229,9 +229,6 @@ register unsigned long current_stack_pointer asm(_ASM_SP);
|
||
#define _ASM_EXTABLE_UA(from, to) \
|
||
_ASM_EXTABLE_TYPE(from, to, EX_TYPE_UACCESS)
|
||
|
||
-#define _ASM_EXTABLE_CPY(from, to) \
|
||
- _ASM_EXTABLE_TYPE(from, to, EX_TYPE_COPY)
|
||
-
|
||
#define _ASM_EXTABLE_FAULT(from, to) \
|
||
_ASM_EXTABLE_TYPE(from, to, EX_TYPE_FAULT)
|
||
|
||
diff --git a/arch/x86/include/asm/extable_fixup_types.h b/arch/x86/include/asm/extable_fixup_types.h
|
||
index 991e31cfde94cc..afad9c0b07e0c8 100644
|
||
--- a/arch/x86/include/asm/extable_fixup_types.h
|
||
+++ b/arch/x86/include/asm/extable_fixup_types.h
|
||
@@ -36,7 +36,7 @@
|
||
#define EX_TYPE_DEFAULT 1
|
||
#define EX_TYPE_FAULT 2
|
||
#define EX_TYPE_UACCESS 3
|
||
-#define EX_TYPE_COPY 4
|
||
+/* unused, was: #define EX_TYPE_COPY 4 */
|
||
#define EX_TYPE_CLEAR_FS 5
|
||
#define EX_TYPE_FPU_RESTORE 6
|
||
#define EX_TYPE_BPF 7
|
||
diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
|
||
index f81a851c46dca5..652c0137e909f3 100644
|
||
--- a/arch/x86/include/asm/intel-family.h
|
||
+++ b/arch/x86/include/asm/intel-family.h
|
||
@@ -159,6 +159,8 @@
|
||
#define INTEL_FAM6_GRANITERAPIDS_D 0xAE
|
||
#define INTEL_GRANITERAPIDS_D IFM(6, 0xAE)
|
||
|
||
+#define INTEL_BARTLETTLAKE IFM(6, 0xD7) /* Raptor Cove */
|
||
+
|
||
/* "Hybrid" Processors (P-Core/E-Core) */
|
||
|
||
#define INTEL_FAM6_LAKEFIELD 0x8A /* Sunny Cove / Tremont */
|
||
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
|
||
index 7df458a6553eb2..78545f7e9cc6ca 100644
|
||
--- a/arch/x86/kernel/cpu/bugs.c
|
||
+++ b/arch/x86/kernel/cpu/bugs.c
|
||
@@ -1574,7 +1574,7 @@ static void __init spec_ctrl_disable_kernel_rrsba(void)
|
||
rrsba_disabled = true;
|
||
}
|
||
|
||
-static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode)
|
||
+static void __init spectre_v2_select_rsb_mitigation(enum spectre_v2_mitigation mode)
|
||
{
|
||
/*
|
||
* Similar to context switches, there are two types of RSB attacks
|
||
@@ -1598,27 +1598,30 @@ static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_
|
||
*/
|
||
switch (mode) {
|
||
case SPECTRE_V2_NONE:
|
||
- return;
|
||
+ break;
|
||
|
||
- case SPECTRE_V2_EIBRS_LFENCE:
|
||
case SPECTRE_V2_EIBRS:
|
||
+ case SPECTRE_V2_EIBRS_LFENCE:
|
||
+ case SPECTRE_V2_EIBRS_RETPOLINE:
|
||
if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
|
||
- setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE);
|
||
pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n");
|
||
+ setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE);
|
||
}
|
||
- return;
|
||
+ break;
|
||
|
||
- case SPECTRE_V2_EIBRS_RETPOLINE:
|
||
case SPECTRE_V2_RETPOLINE:
|
||
case SPECTRE_V2_LFENCE:
|
||
case SPECTRE_V2_IBRS:
|
||
+ pr_info("Spectre v2 / SpectreRSB: Filling RSB on context switch and VMEXIT\n");
|
||
+ setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
|
||
setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT);
|
||
- pr_info("Spectre v2 / SpectreRSB : Filling RSB on VMEXIT\n");
|
||
- return;
|
||
- }
|
||
+ break;
|
||
|
||
- pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation at VM exit");
|
||
- dump_stack();
|
||
+ default:
|
||
+ pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation\n");
|
||
+ dump_stack();
|
||
+ break;
|
||
+ }
|
||
}
|
||
|
||
/*
|
||
@@ -1844,10 +1847,7 @@ static void __init spectre_v2_select_mitigation(void)
|
||
*
|
||
* FIXME: Is this pointless for retbleed-affected AMD?
|
||
*/
|
||
- setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
|
||
- pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n");
|
||
-
|
||
- spectre_v2_determine_rsb_fill_type_at_vmexit(mode);
|
||
+ spectre_v2_select_rsb_mitigation(mode);
|
||
|
||
/*
|
||
* Retpoline protects the kernel, but doesn't protect firmware. IBRS
|
||
diff --git a/arch/x86/kernel/cpu/mce/severity.c b/arch/x86/kernel/cpu/mce/severity.c
|
||
index c4477162c07d13..9c5754229d6ed3 100644
|
||
--- a/arch/x86/kernel/cpu/mce/severity.c
|
||
+++ b/arch/x86/kernel/cpu/mce/severity.c
|
||
@@ -288,14 +288,12 @@ static noinstr int error_context(struct mce *m, struct pt_regs *regs)
|
||
copy_user = is_copy_from_user(regs);
|
||
instrumentation_end();
|
||
|
||
- switch (fixup_type) {
|
||
- case EX_TYPE_UACCESS:
|
||
- case EX_TYPE_COPY:
|
||
- if (!copy_user)
|
||
- return IN_KERNEL;
|
||
- m->kflags |= MCE_IN_KERNEL_COPYIN;
|
||
- fallthrough;
|
||
+ if (copy_user) {
|
||
+ m->kflags |= MCE_IN_KERNEL_COPYIN | MCE_IN_KERNEL_RECOV;
|
||
+ return IN_KERNEL_RECOV;
|
||
+ }
|
||
|
||
+ switch (fixup_type) {
|
||
case EX_TYPE_FAULT_MCE_SAFE:
|
||
case EX_TYPE_DEFAULT_MCE_SAFE:
|
||
m->kflags |= MCE_IN_KERNEL_RECOV;
|
||
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
|
||
index 80e262bb627fe1..cb9852ad609893 100644
|
||
--- a/arch/x86/kernel/i8253.c
|
||
+++ b/arch/x86/kernel/i8253.c
|
||
@@ -46,7 +46,8 @@ bool __init pit_timer_init(void)
|
||
* VMMs otherwise steal CPU time just to pointlessly waggle
|
||
* the (masked) IRQ.
|
||
*/
|
||
- clockevent_i8253_disable();
|
||
+ scoped_guard(irq)
|
||
+ clockevent_i8253_disable();
|
||
return false;
|
||
}
|
||
clockevent_i8253_init(true);
|
||
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
|
||
index 4b74ea91f4e6bb..6970b11a6b4c62 100644
|
||
--- a/arch/x86/kvm/svm/avic.c
|
||
+++ b/arch/x86/kvm/svm/avic.c
|
||
@@ -820,7 +820,7 @@ static int svm_ir_list_add(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi)
|
||
* Allocating new amd_iommu_pi_data, which will get
|
||
* add to the per-vcpu ir_list.
|
||
*/
|
||
- ir = kzalloc(sizeof(struct amd_svm_iommu_ir), GFP_KERNEL_ACCOUNT);
|
||
+ ir = kzalloc(sizeof(struct amd_svm_iommu_ir), GFP_ATOMIC | __GFP_ACCOUNT);
|
||
if (!ir) {
|
||
ret = -ENOMEM;
|
||
goto out;
|
||
@@ -896,6 +896,7 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
||
{
|
||
struct kvm_kernel_irq_routing_entry *e;
|
||
struct kvm_irq_routing_table *irq_rt;
|
||
+ bool enable_remapped_mode = true;
|
||
int idx, ret = 0;
|
||
|
||
if (!kvm_arch_has_assigned_device(kvm) ||
|
||
@@ -933,6 +934,8 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
||
kvm_vcpu_apicv_active(&svm->vcpu)) {
|
||
struct amd_iommu_pi_data pi;
|
||
|
||
+ enable_remapped_mode = false;
|
||
+
|
||
/* Try to enable guest_mode in IRTE */
|
||
pi.base = __sme_set(page_to_phys(svm->avic_backing_page) &
|
||
AVIC_HPA_MASK);
|
||
@@ -951,33 +954,6 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
||
*/
|
||
if (!ret && pi.is_guest_mode)
|
||
svm_ir_list_add(svm, &pi);
|
||
- } else {
|
||
- /* Use legacy mode in IRTE */
|
||
- struct amd_iommu_pi_data pi;
|
||
-
|
||
- /**
|
||
- * Here, pi is used to:
|
||
- * - Tell IOMMU to use legacy mode for this interrupt.
|
||
- * - Retrieve ga_tag of prior interrupt remapping data.
|
||
- */
|
||
- pi.prev_ga_tag = 0;
|
||
- pi.is_guest_mode = false;
|
||
- ret = irq_set_vcpu_affinity(host_irq, &pi);
|
||
-
|
||
- /**
|
||
- * Check if the posted interrupt was previously
|
||
- * setup with the guest_mode by checking if the ga_tag
|
||
- * was cached. If so, we need to clean up the per-vcpu
|
||
- * ir_list.
|
||
- */
|
||
- if (!ret && pi.prev_ga_tag) {
|
||
- int id = AVIC_GATAG_TO_VCPUID(pi.prev_ga_tag);
|
||
- struct kvm_vcpu *vcpu;
|
||
-
|
||
- vcpu = kvm_get_vcpu_by_id(kvm, id);
|
||
- if (vcpu)
|
||
- svm_ir_list_del(to_svm(vcpu), &pi);
|
||
- }
|
||
}
|
||
|
||
if (!ret && svm) {
|
||
@@ -993,6 +969,34 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
||
}
|
||
|
||
ret = 0;
|
||
+ if (enable_remapped_mode) {
|
||
+ /* Use legacy mode in IRTE */
|
||
+ struct amd_iommu_pi_data pi;
|
||
+
|
||
+ /**
|
||
+ * Here, pi is used to:
|
||
+ * - Tell IOMMU to use legacy mode for this interrupt.
|
||
+ * - Retrieve ga_tag of prior interrupt remapping data.
|
||
+ */
|
||
+ pi.prev_ga_tag = 0;
|
||
+ pi.is_guest_mode = false;
|
||
+ ret = irq_set_vcpu_affinity(host_irq, &pi);
|
||
+
|
||
+ /**
|
||
+ * Check if the posted interrupt was previously
|
||
+ * setup with the guest_mode by checking if the ga_tag
|
||
+ * was cached. If so, we need to clean up the per-vcpu
|
||
+ * ir_list.
|
||
+ */
|
||
+ if (!ret && pi.prev_ga_tag) {
|
||
+ int id = AVIC_GATAG_TO_VCPUID(pi.prev_ga_tag);
|
||
+ struct kvm_vcpu *vcpu;
|
||
+
|
||
+ vcpu = kvm_get_vcpu_by_id(kvm, id);
|
||
+ if (vcpu)
|
||
+ svm_ir_list_del(to_svm(vcpu), &pi);
|
||
+ }
|
||
+ }
|
||
out:
|
||
srcu_read_unlock(&kvm->irq_srcu, idx);
|
||
return ret;
|
||
diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c
|
||
index af662312fd0778..b54e0cb86e5d61 100644
|
||
--- a/arch/x86/kvm/vmx/posted_intr.c
|
||
+++ b/arch/x86/kvm/vmx/posted_intr.c
|
||
@@ -274,6 +274,7 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
||
{
|
||
struct kvm_kernel_irq_routing_entry *e;
|
||
struct kvm_irq_routing_table *irq_rt;
|
||
+ bool enable_remapped_mode = true;
|
||
struct kvm_lapic_irq irq;
|
||
struct kvm_vcpu *vcpu;
|
||
struct vcpu_data vcpu_info;
|
||
@@ -312,21 +313,8 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
||
|
||
kvm_set_msi_irq(kvm, e, &irq);
|
||
if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) ||
|
||
- !kvm_irq_is_postable(&irq)) {
|
||
- /*
|
||
- * Make sure the IRTE is in remapped mode if
|
||
- * we don't handle it in posted mode.
|
||
- */
|
||
- ret = irq_set_vcpu_affinity(host_irq, NULL);
|
||
- if (ret < 0) {
|
||
- printk(KERN_INFO
|
||
- "failed to back to remapped mode, irq: %u\n",
|
||
- host_irq);
|
||
- goto out;
|
||
- }
|
||
-
|
||
+ !kvm_irq_is_postable(&irq))
|
||
continue;
|
||
- }
|
||
|
||
vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu));
|
||
vcpu_info.vector = irq.vector;
|
||
@@ -334,11 +322,12 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
||
trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi,
|
||
vcpu_info.vector, vcpu_info.pi_desc_addr, set);
|
||
|
||
- if (set)
|
||
- ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
|
||
- else
|
||
- ret = irq_set_vcpu_affinity(host_irq, NULL);
|
||
+ if (!set)
|
||
+ continue;
|
||
|
||
+ enable_remapped_mode = false;
|
||
+
|
||
+ ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
|
||
if (ret < 0) {
|
||
printk(KERN_INFO "%s: failed to update PI IRTE\n",
|
||
__func__);
|
||
@@ -346,6 +335,9 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
|
||
}
|
||
}
|
||
|
||
+ if (enable_remapped_mode)
|
||
+ ret = irq_set_vcpu_affinity(host_irq, NULL);
|
||
+
|
||
ret = 0;
|
||
out:
|
||
srcu_read_unlock(&kvm->irq_srcu, idx);
|
||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
||
index 2a2dbeb56897d8..f67fe8a65820c8 100644
|
||
--- a/arch/x86/kvm/x86.c
|
||
+++ b/arch/x86/kvm/x86.c
|
||
@@ -13297,7 +13297,8 @@ int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
|
||
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
|
||
struct kvm_kernel_irq_routing_entry *new)
|
||
{
|
||
- if (new->type != KVM_IRQ_ROUTING_MSI)
|
||
+ if (old->type != KVM_IRQ_ROUTING_MSI ||
|
||
+ new->type != KVM_IRQ_ROUTING_MSI)
|
||
return true;
|
||
|
||
return !!memcmp(&old->msi, &new->msi, sizeof(new->msi));
|
||
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
|
||
index 271dcb2deabc31..2354c0156e51c9 100644
|
||
--- a/arch/x86/mm/extable.c
|
||
+++ b/arch/x86/mm/extable.c
|
||
@@ -163,13 +163,6 @@ static bool ex_handler_uaccess(const struct exception_table_entry *fixup,
|
||
return ex_handler_default(fixup, regs);
|
||
}
|
||
|
||
-static bool ex_handler_copy(const struct exception_table_entry *fixup,
|
||
- struct pt_regs *regs, int trapnr)
|
||
-{
|
||
- WARN_ONCE(trapnr == X86_TRAP_GP, "General protection fault in user access. Non-canonical address?");
|
||
- return ex_handler_fault(fixup, regs, trapnr);
|
||
-}
|
||
-
|
||
static bool ex_handler_msr(const struct exception_table_entry *fixup,
|
||
struct pt_regs *regs, bool wrmsr, bool safe, int reg)
|
||
{
|
||
@@ -267,8 +260,6 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
|
||
return ex_handler_fault(e, regs, trapnr);
|
||
case EX_TYPE_UACCESS:
|
||
return ex_handler_uaccess(e, regs, trapnr, fault_addr);
|
||
- case EX_TYPE_COPY:
|
||
- return ex_handler_copy(e, regs, trapnr);
|
||
case EX_TYPE_CLEAR_FS:
|
||
return ex_handler_clear_fs(e, regs);
|
||
case EX_TYPE_FPU_RESTORE:
|
||
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
|
||
index df1794a5e38a57..4872bb082b1935 100644
|
||
--- a/arch/x86/mm/tlb.c
|
||
+++ b/arch/x86/mm/tlb.c
|
||
@@ -392,9 +392,9 @@ static void cond_mitigation(struct task_struct *next)
|
||
prev_mm = this_cpu_read(cpu_tlbstate.last_user_mm_spec);
|
||
|
||
/*
|
||
- * Avoid user/user BTB poisoning by flushing the branch predictor
|
||
- * when switching between processes. This stops one process from
|
||
- * doing Spectre-v2 attacks on another.
|
||
+ * Avoid user->user BTB/RSB poisoning by flushing them when switching
|
||
+ * between processes. This stops one process from doing Spectre-v2
|
||
+ * attacks on another.
|
||
*
|
||
* Both, the conditional and the always IBPB mode use the mm
|
||
* pointer to avoid the IBPB when switching between tasks of the
|
||
diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S
|
||
index c4365a05ab83b3..fc46b4dfbd7475 100644
|
||
--- a/arch/x86/platform/pvh/head.S
|
||
+++ b/arch/x86/platform/pvh/head.S
|
||
@@ -100,7 +100,12 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
|
||
xor %edx, %edx
|
||
wrmsr
|
||
|
||
- call xen_prepare_pvh
|
||
+ /* Call xen_prepare_pvh() via the kernel virtual mapping */
|
||
+ leaq xen_prepare_pvh(%rip), %rax
|
||
+ subq phys_base(%rip), %rax
|
||
+ addq $__START_KERNEL_map, %rax
|
||
+ ANNOTATE_RETPOLINE_SAFE
|
||
+ call *%rax
|
||
|
||
/* startup_64 expects boot_params in %rsi. */
|
||
mov $_pa(pvh_bootparams), %rsi
|
||
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c
|
||
index 5b84b0f7cc178f..3378670286535a 100644
|
||
--- a/crypto/crypto_null.c
|
||
+++ b/crypto/crypto_null.c
|
||
@@ -17,10 +17,10 @@
|
||
#include <crypto/internal/skcipher.h>
|
||
#include <linux/init.h>
|
||
#include <linux/module.h>
|
||
-#include <linux/mm.h>
|
||
+#include <linux/spinlock.h>
|
||
#include <linux/string.h>
|
||
|
||
-static DEFINE_MUTEX(crypto_default_null_skcipher_lock);
|
||
+static DEFINE_SPINLOCK(crypto_default_null_skcipher_lock);
|
||
static struct crypto_sync_skcipher *crypto_default_null_skcipher;
|
||
static int crypto_default_null_skcipher_refcnt;
|
||
|
||
@@ -152,23 +152,32 @@ MODULE_ALIAS_CRYPTO("cipher_null");
|
||
|
||
struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void)
|
||
{
|
||
+ struct crypto_sync_skcipher *ntfm = NULL;
|
||
struct crypto_sync_skcipher *tfm;
|
||
|
||
- mutex_lock(&crypto_default_null_skcipher_lock);
|
||
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
|
||
tfm = crypto_default_null_skcipher;
|
||
|
||
if (!tfm) {
|
||
- tfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
|
||
- if (IS_ERR(tfm))
|
||
- goto unlock;
|
||
-
|
||
- crypto_default_null_skcipher = tfm;
|
||
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
|
||
+
|
||
+ ntfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0);
|
||
+ if (IS_ERR(ntfm))
|
||
+ return ntfm;
|
||
+
|
||
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
|
||
+ tfm = crypto_default_null_skcipher;
|
||
+ if (!tfm) {
|
||
+ tfm = ntfm;
|
||
+ ntfm = NULL;
|
||
+ crypto_default_null_skcipher = tfm;
|
||
+ }
|
||
}
|
||
|
||
crypto_default_null_skcipher_refcnt++;
|
||
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
|
||
|
||
-unlock:
|
||
- mutex_unlock(&crypto_default_null_skcipher_lock);
|
||
+ crypto_free_sync_skcipher(ntfm);
|
||
|
||
return tfm;
|
||
}
|
||
@@ -176,12 +185,16 @@ EXPORT_SYMBOL_GPL(crypto_get_default_null_skcipher);
|
||
|
||
void crypto_put_default_null_skcipher(void)
|
||
{
|
||
- mutex_lock(&crypto_default_null_skcipher_lock);
|
||
+ struct crypto_sync_skcipher *tfm = NULL;
|
||
+
|
||
+ spin_lock_bh(&crypto_default_null_skcipher_lock);
|
||
if (!--crypto_default_null_skcipher_refcnt) {
|
||
- crypto_free_sync_skcipher(crypto_default_null_skcipher);
|
||
+ tfm = crypto_default_null_skcipher;
|
||
crypto_default_null_skcipher = NULL;
|
||
}
|
||
- mutex_unlock(&crypto_default_null_skcipher_lock);
|
||
+ spin_unlock_bh(&crypto_default_null_skcipher_lock);
|
||
+
|
||
+ crypto_free_sync_skcipher(tfm);
|
||
}
|
||
EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher);
|
||
|
||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
|
||
index 115994dfefec1e..77d6af61158936 100644
|
||
--- a/drivers/acpi/ec.c
|
||
+++ b/drivers/acpi/ec.c
|
||
@@ -2301,6 +2301,34 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
|
||
DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"),
|
||
},
|
||
},
|
||
+ /*
|
||
+ * Lenovo Legion Go S; touchscreen blocks HW sleep when woken up from EC
|
||
+ * https://gitlab.freedesktop.org/drm/amd/-/issues/3929
|
||
+ */
|
||
+ {
|
||
+ .matches = {
|
||
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||
+ DMI_MATCH(DMI_PRODUCT_NAME, "83L3"),
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ .matches = {
|
||
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||
+ DMI_MATCH(DMI_PRODUCT_NAME, "83N6"),
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ .matches = {
|
||
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||
+ DMI_MATCH(DMI_PRODUCT_NAME, "83Q2"),
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ .matches = {
|
||
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||
+ DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"),
|
||
+ }
|
||
+ },
|
||
{ },
|
||
};
|
||
|
||
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
|
||
index a35dd0e41c2704..f73ce6e13065dd 100644
|
||
--- a/drivers/acpi/pptt.c
|
||
+++ b/drivers/acpi/pptt.c
|
||
@@ -229,7 +229,7 @@ static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr,
|
||
node_entry = ACPI_PTR_DIFF(node, table_hdr);
|
||
entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
|
||
sizeof(struct acpi_table_pptt));
|
||
- proc_sz = sizeof(struct acpi_pptt_processor *);
|
||
+ proc_sz = sizeof(struct acpi_pptt_processor);
|
||
|
||
while ((unsigned long)entry + proc_sz < table_end) {
|
||
cpu_node = (struct acpi_pptt_processor *)entry;
|
||
@@ -270,7 +270,7 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct acpi_table_he
|
||
table_end = (unsigned long)table_hdr + table_hdr->length;
|
||
entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
|
||
sizeof(struct acpi_table_pptt));
|
||
- proc_sz = sizeof(struct acpi_pptt_processor *);
|
||
+ proc_sz = sizeof(struct acpi_pptt_processor);
|
||
|
||
/* find the processor structure associated with this cpuid */
|
||
while ((unsigned long)entry + proc_sz < table_end) {
|
||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
|
||
index 5377d094bf7548..6a1460d35447cc 100644
|
||
--- a/drivers/ata/libata-scsi.c
|
||
+++ b/drivers/ata/libata-scsi.c
|
||
@@ -2354,8 +2354,8 @@ static unsigned int ata_msense_control_ata_feature(struct ata_device *dev,
|
||
*/
|
||
put_unaligned_be16(ATA_FEATURE_SUB_MPAGE_LEN - 4, &buf[2]);
|
||
|
||
- if (dev->flags & ATA_DFLAG_CDL)
|
||
- buf[4] = 0x02; /* Support T2A and T2B pages */
|
||
+ if (dev->flags & ATA_DFLAG_CDL_ENABLED)
|
||
+ buf[4] = 0x02; /* T2A and T2B pages enabled */
|
||
else
|
||
buf[4] = 0;
|
||
|
||
@@ -3764,12 +3764,11 @@ static int ata_mselect_control_spg0(struct ata_queued_cmd *qc,
|
||
}
|
||
|
||
/*
|
||
- * Translate MODE SELECT control mode page, sub-pages f2h (ATA feature mode
|
||
+ * Translate MODE SELECT control mode page, sub-page f2h (ATA feature mode
|
||
* page) into a SET FEATURES command.
|
||
*/
|
||
-static unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
|
||
- const u8 *buf, int len,
|
||
- u16 *fp)
|
||
+static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
|
||
+ const u8 *buf, int len, u16 *fp)
|
||
{
|
||
struct ata_device *dev = qc->dev;
|
||
struct ata_taskfile *tf = &qc->tf;
|
||
@@ -3787,17 +3786,27 @@ static unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc,
|
||
/* Check cdl_ctrl */
|
||
switch (buf[0] & 0x03) {
|
||
case 0:
|
||
- /* Disable CDL */
|
||
+ /* Disable CDL if it is enabled */
|
||
+ if (!(dev->flags & ATA_DFLAG_CDL_ENABLED))
|
||
+ return 0;
|
||
+ ata_dev_dbg(dev, "Disabling CDL\n");
|
||
cdl_action = 0;
|
||
dev->flags &= ~ATA_DFLAG_CDL_ENABLED;
|
||
break;
|
||
case 0x02:
|
||
- /* Enable CDL T2A/T2B: NCQ priority must be disabled */
|
||
+ /*
|
||
+ * Enable CDL if not already enabled. Since this is mutually
|
||
+ * exclusive with NCQ priority, allow this only if NCQ priority
|
||
+ * is disabled.
|
||
+ */
|
||
+ if (dev->flags & ATA_DFLAG_CDL_ENABLED)
|
||
+ return 0;
|
||
if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) {
|
||
ata_dev_err(dev,
|
||
"NCQ priority must be disabled to enable CDL\n");
|
||
return -EINVAL;
|
||
}
|
||
+ ata_dev_dbg(dev, "Enabling CDL\n");
|
||
cdl_action = 1;
|
||
dev->flags |= ATA_DFLAG_CDL_ENABLED;
|
||
break;
|
||
diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c
|
||
index d56a5d508ccd7b..8b690f59df27d6 100644
|
||
--- a/drivers/auxdisplay/hd44780.c
|
||
+++ b/drivers/auxdisplay/hd44780.c
|
||
@@ -313,13 +313,13 @@ static int hd44780_probe(struct platform_device *pdev)
|
||
fail3:
|
||
kfree(hd);
|
||
fail2:
|
||
- kfree(lcd);
|
||
+ charlcd_free(lcd);
|
||
fail1:
|
||
kfree(hdc);
|
||
return ret;
|
||
}
|
||
|
||
-static int hd44780_remove(struct platform_device *pdev)
|
||
+static void hd44780_remove(struct platform_device *pdev)
|
||
{
|
||
struct charlcd *lcd = platform_get_drvdata(pdev);
|
||
struct hd44780_common *hdc = lcd->drvdata;
|
||
@@ -328,8 +328,7 @@ static int hd44780_remove(struct platform_device *pdev)
|
||
kfree(hdc->hd44780);
|
||
kfree(lcd->drvdata);
|
||
|
||
- kfree(lcd);
|
||
- return 0;
|
||
+ charlcd_free(lcd);
|
||
}
|
||
|
||
static const struct of_device_id hd44780_of_match[] = {
|
||
@@ -340,7 +339,7 @@ MODULE_DEVICE_TABLE(of, hd44780_of_match);
|
||
|
||
static struct platform_driver hd44780_driver = {
|
||
.probe = hd44780_probe,
|
||
- .remove = hd44780_remove,
|
||
+ .remove_new = hd44780_remove,
|
||
.driver = {
|
||
.name = "hd44780",
|
||
.of_match_table = hd44780_of_match,
|
||
diff --git a/drivers/base/base.h b/drivers/base/base.h
|
||
index a8e3d8165232fd..0b491449b022a1 100644
|
||
--- a/drivers/base/base.h
|
||
+++ b/drivers/base/base.h
|
||
@@ -73,6 +73,7 @@ static inline void subsys_put(struct subsys_private *sp)
|
||
kset_put(&sp->subsys);
|
||
}
|
||
|
||
+struct subsys_private *bus_to_subsys(const struct bus_type *bus);
|
||
struct subsys_private *class_to_subsys(const struct class *class);
|
||
|
||
struct driver_private {
|
||
@@ -179,6 +180,22 @@ int driver_add_groups(struct device_driver *drv, const struct attribute_group **
|
||
void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups);
|
||
void device_driver_detach(struct device *dev);
|
||
|
||
+static inline void device_set_driver(struct device *dev, const struct device_driver *drv)
|
||
+{
|
||
+ /*
|
||
+ * Majority (all?) read accesses to dev->driver happens either
|
||
+ * while holding device lock or in bus/driver code that is only
|
||
+ * invoked when the device is bound to a driver and there is no
|
||
+ * concern of the pointer being changed while it is being read.
|
||
+ * However when reading device's uevent file we read driver pointer
|
||
+ * without taking device lock (so we do not block there for
|
||
+ * arbitrary amount of time). We use WRITE_ONCE() here to prevent
|
||
+ * tearing so that READ_ONCE() can safely be used in uevent code.
|
||
+ */
|
||
+ // FIXME - this cast should not be needed "soon"
|
||
+ WRITE_ONCE(dev->driver, (struct device_driver *)drv);
|
||
+}
|
||
+
|
||
int devres_release_all(struct device *dev);
|
||
void device_block_probing(void);
|
||
void device_unblock_probing(void);
|
||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
|
||
index d4361ad3b433f5..b97e13a52c3308 100644
|
||
--- a/drivers/base/bus.c
|
||
+++ b/drivers/base/bus.c
|
||
@@ -57,7 +57,7 @@ static int __must_check bus_rescan_devices_helper(struct device *dev,
|
||
* NULL. A call to subsys_put() must be done when finished with the pointer in
|
||
* order for it to be properly freed.
|
||
*/
|
||
-static struct subsys_private *bus_to_subsys(const struct bus_type *bus)
|
||
+struct subsys_private *bus_to_subsys(const struct bus_type *bus)
|
||
{
|
||
struct subsys_private *sp = NULL;
|
||
struct kobject *kobj;
|
||
diff --git a/drivers/base/core.c b/drivers/base/core.c
|
||
index 8e2caa9eb5cd41..a192ce5bb8f902 100644
|
||
--- a/drivers/base/core.c
|
||
+++ b/drivers/base/core.c
|
||
@@ -2570,6 +2570,35 @@ static const char *dev_uevent_name(const struct kobject *kobj)
|
||
return NULL;
|
||
}
|
||
|
||
+/*
|
||
+ * Try filling "DRIVER=<name>" uevent variable for a device. Because this
|
||
+ * function may race with binding and unbinding the device from a driver,
|
||
+ * we need to be careful. Binding is generally safe, at worst we miss the
|
||
+ * fact that the device is already bound to a driver (but the driver
|
||
+ * information that is delivered through uevents is best-effort, it may
|
||
+ * become obsolete as soon as it is generated anyways). Unbinding is more
|
||
+ * risky as driver pointer is transitioning to NULL, so READ_ONCE() should
|
||
+ * be used to make sure we are dealing with the same pointer, and to
|
||
+ * ensure that driver structure is not going to disappear from under us
|
||
+ * we take bus' drivers klist lock. The assumption that only registered
|
||
+ * driver can be bound to a device, and to unregister a driver bus code
|
||
+ * will take the same lock.
|
||
+ */
|
||
+static void dev_driver_uevent(const struct device *dev, struct kobj_uevent_env *env)
|
||
+{
|
||
+ struct subsys_private *sp = bus_to_subsys(dev->bus);
|
||
+
|
||
+ if (sp) {
|
||
+ scoped_guard(spinlock, &sp->klist_drivers.k_lock) {
|
||
+ struct device_driver *drv = READ_ONCE(dev->driver);
|
||
+ if (drv)
|
||
+ add_uevent_var(env, "DRIVER=%s", drv->name);
|
||
+ }
|
||
+
|
||
+ subsys_put(sp);
|
||
+ }
|
||
+}
|
||
+
|
||
static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
|
||
{
|
||
const struct device *dev = kobj_to_dev(kobj);
|
||
@@ -2601,8 +2630,8 @@ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
|
||
if (dev->type && dev->type->name)
|
||
add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
|
||
|
||
- if (dev->driver)
|
||
- add_uevent_var(env, "DRIVER=%s", dev->driver->name);
|
||
+ /* Add "DRIVER=%s" variable if the device is bound to a driver */
|
||
+ dev_driver_uevent(dev, env);
|
||
|
||
/* Add common DT information about the device */
|
||
of_device_uevent(dev, env);
|
||
@@ -2672,11 +2701,8 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
|
||
if (!env)
|
||
return -ENOMEM;
|
||
|
||
- /* Synchronize with really_probe() */
|
||
- device_lock(dev);
|
||
/* let the kset specific function add its keys */
|
||
retval = kset->uevent_ops->uevent(&dev->kobj, env);
|
||
- device_unlock(dev);
|
||
if (retval)
|
||
goto out;
|
||
|
||
@@ -3691,7 +3717,7 @@ int device_add(struct device *dev)
|
||
device_pm_remove(dev);
|
||
dpm_sysfs_remove(dev);
|
||
DPMError:
|
||
- dev->driver = NULL;
|
||
+ device_set_driver(dev, NULL);
|
||
bus_remove_device(dev);
|
||
BusError:
|
||
device_remove_attrs(dev);
|
||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
|
||
index 0c3725c3eefa46..7e2fb159bb895b 100644
|
||
--- a/drivers/base/dd.c
|
||
+++ b/drivers/base/dd.c
|
||
@@ -550,7 +550,7 @@ static void device_unbind_cleanup(struct device *dev)
|
||
arch_teardown_dma_ops(dev);
|
||
kfree(dev->dma_range_map);
|
||
dev->dma_range_map = NULL;
|
||
- dev->driver = NULL;
|
||
+ device_set_driver(dev, NULL);
|
||
dev_set_drvdata(dev, NULL);
|
||
if (dev->pm_domain && dev->pm_domain->dismiss)
|
||
dev->pm_domain->dismiss(dev);
|
||
@@ -629,7 +629,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
|
||
}
|
||
|
||
re_probe:
|
||
- dev->driver = drv;
|
||
+ device_set_driver(dev, drv);
|
||
|
||
/* If using pinctrl, bind pins now before probing */
|
||
ret = pinctrl_bind_pins(dev);
|
||
@@ -1014,7 +1014,7 @@ static int __device_attach(struct device *dev, bool allow_async)
|
||
if (ret == 0)
|
||
ret = 1;
|
||
else {
|
||
- dev->driver = NULL;
|
||
+ device_set_driver(dev, NULL);
|
||
ret = 0;
|
||
}
|
||
} else {
|
||
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
|
||
index 8a6c1146df00fd..455e2a2b149f4b 100644
|
||
--- a/drivers/block/loop.c
|
||
+++ b/drivers/block/loop.c
|
||
@@ -441,7 +441,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
|
||
cmd->iocb.ki_filp = file;
|
||
cmd->iocb.ki_complete = lo_rw_aio_complete;
|
||
cmd->iocb.ki_flags = IOCB_DIRECT;
|
||
- cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
|
||
+ cmd->iocb.ki_ioprio = req_get_ioprio(rq);
|
||
|
||
if (rw == ITER_SOURCE)
|
||
ret = call_write_iter(file, &cmd->iocb, &iter);
|
||
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
|
||
index f7dd455dd0dd3c..dda466f9181acf 100644
|
||
--- a/drivers/char/misc.c
|
||
+++ b/drivers/char/misc.c
|
||
@@ -315,7 +315,7 @@ static int __init misc_init(void)
|
||
goto fail_remove;
|
||
|
||
err = -EIO;
|
||
- if (register_chrdev(MISC_MAJOR, "misc", &misc_fops))
|
||
+ if (__register_chrdev(MISC_MAJOR, 0, MINORMASK + 1, "misc", &misc_fops))
|
||
goto fail_printk;
|
||
return 0;
|
||
|
||
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
|
||
index 796ab9a4e48fa1..80e0f485170a8f 100644
|
||
--- a/drivers/char/virtio_console.c
|
||
+++ b/drivers/char/virtio_console.c
|
||
@@ -1612,8 +1612,8 @@ static void handle_control_message(struct virtio_device *vdev,
|
||
break;
|
||
case VIRTIO_CONSOLE_RESIZE: {
|
||
struct {
|
||
- __u16 rows;
|
||
- __u16 cols;
|
||
+ __virtio16 rows;
|
||
+ __virtio16 cols;
|
||
} size;
|
||
|
||
if (!is_console_port(port))
|
||
@@ -1621,7 +1621,8 @@ static void handle_control_message(struct virtio_device *vdev,
|
||
|
||
memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt),
|
||
sizeof(size));
|
||
- set_console_size(port, size.rows, size.cols);
|
||
+ set_console_size(port, virtio16_to_cpu(vdev, size.rows),
|
||
+ virtio16_to_cpu(vdev, size.cols));
|
||
|
||
port->cons.hvc->irq_requested = 1;
|
||
resize_console(port);
|
||
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
|
||
index 5bbd036f5295f5..8474099e2cac19 100644
|
||
--- a/drivers/clk/clk.c
|
||
+++ b/drivers/clk/clk.c
|
||
@@ -5216,6 +5216,10 @@ of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec)
|
||
if (!clkspec)
|
||
return ERR_PTR(-EINVAL);
|
||
|
||
+ /* Check if node in clkspec is in disabled/fail state */
|
||
+ if (!of_device_is_available(clkspec->np))
|
||
+ return ERR_PTR(-ENOENT);
|
||
+
|
||
mutex_lock(&of_clk_mutex);
|
||
list_for_each_entry(provider, &of_clk_providers, link) {
|
||
if (provider->node == clkspec->np) {
|
||
diff --git a/drivers/clk/renesas/r9a07g043-cpg.c b/drivers/clk/renesas/r9a07g043-cpg.c
|
||
index 6c6bc79b2e9cec..865d47800791bd 100644
|
||
--- a/drivers/clk/renesas/r9a07g043-cpg.c
|
||
+++ b/drivers/clk/renesas/r9a07g043-cpg.c
|
||
@@ -14,6 +14,17 @@
|
||
|
||
#include "rzg2l-cpg.h"
|
||
|
||
+/* Specific registers. */
|
||
+#define CPG_PL2SDHI_DSEL (0x218)
|
||
+
|
||
+/* Clock select configuration. */
|
||
+#define SEL_SDHI0 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
||
+#define SEL_SDHI1 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
||
+
|
||
+/* Clock status configuration. */
|
||
+#define SEL_SDHI0_STS SEL_PLL_PACK(CPG_CLKSTATUS, 28, 1)
|
||
+#define SEL_SDHI1_STS SEL_PLL_PACK(CPG_CLKSTATUS, 29, 1)
|
||
+
|
||
enum clk_ids {
|
||
/* Core Clock Outputs exported to DT */
|
||
LAST_DT_CORE_CLK = R9A07G043_CLK_P0_DIV2,
|
||
@@ -75,8 +86,12 @@ static const struct clk_div_table dtable_1_32[] = {
|
||
|
||
/* Mux clock tables */
|
||
static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
|
||
+#ifdef CONFIG_ARM64
|
||
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
|
||
-static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
||
+#endif
|
||
+static const char * const sel_sdhi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
||
+
|
||
+static const u32 mtable_sdhi[] = { 1, 2, 3 };
|
||
|
||
static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
|
||
/* External Clock Inputs */
|
||
@@ -120,11 +135,18 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
|
||
DEF_DIV("P2", R9A07G043_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32),
|
||
DEF_FIXED("M0", R9A07G043_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
|
||
DEF_FIXED("ZT", R9A07G043_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1),
|
||
+#ifdef CONFIG_ARM64
|
||
DEF_MUX("HP", R9A07G043_CLK_HP, SEL_PLL6_2, sel_pll6_2),
|
||
+#endif
|
||
+#ifdef CONFIG_RISCV
|
||
+ DEF_FIXED("HP", R9A07G043_CLK_HP, CLK_PLL6_250, 1, 1),
|
||
+#endif
|
||
DEF_FIXED("SPI0", R9A07G043_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
|
||
DEF_FIXED("SPI1", R9A07G043_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
|
||
- DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, sel_shdi),
|
||
- DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, sel_shdi),
|
||
+ DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_sdhi,
|
||
+ mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||
+ DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_sdhi,
|
||
+ mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4),
|
||
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4),
|
||
};
|
||
diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c
|
||
index c597414a94d8a0..48404cafea3f51 100644
|
||
--- a/drivers/clk/renesas/r9a07g044-cpg.c
|
||
+++ b/drivers/clk/renesas/r9a07g044-cpg.c
|
||
@@ -15,6 +15,17 @@
|
||
|
||
#include "rzg2l-cpg.h"
|
||
|
||
+/* Specific registers. */
|
||
+#define CPG_PL2SDHI_DSEL (0x218)
|
||
+
|
||
+/* Clock select configuration. */
|
||
+#define SEL_SDHI0 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
||
+#define SEL_SDHI1 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
||
+
|
||
+/* Clock status configuration. */
|
||
+#define SEL_SDHI0_STS SEL_PLL_PACK(CPG_CLKSTATUS, 28, 1)
|
||
+#define SEL_SDHI1_STS SEL_PLL_PACK(CPG_CLKSTATUS, 29, 1)
|
||
+
|
||
enum clk_ids {
|
||
/* Core Clock Outputs exported to DT */
|
||
LAST_DT_CORE_CLK = R9A07G054_CLK_DRP_A,
|
||
@@ -95,9 +106,11 @@ static const struct clk_div_table dtable_16_128[] = {
|
||
static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
|
||
static const char * const sel_pll5_4[] = { ".pll5_foutpostdiv", ".pll5_fout1ph0" };
|
||
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
|
||
-static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
||
+static const char * const sel_sdhi[] = { ".clk_533", ".clk_400", ".clk_266" };
|
||
static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" };
|
||
|
||
+static const u32 mtable_sdhi[] = { 1, 2, 3 };
|
||
+
|
||
static const struct {
|
||
struct cpg_core_clk common[56];
|
||
#ifdef CONFIG_CLK_R9A07G054
|
||
@@ -163,8 +176,10 @@ static const struct {
|
||
DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2, sel_pll6_2),
|
||
DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
|
||
DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
|
||
- DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, sel_shdi),
|
||
- DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, sel_shdi),
|
||
+ DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_sdhi,
|
||
+ mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||
+ DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_sdhi,
|
||
+ mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
|
||
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
|
||
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
|
||
DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8),
|
||
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
|
||
index f8dbb092b9f1b2..77eefb6ee4538a 100644
|
||
--- a/drivers/clk/renesas/rzg2l-cpg.c
|
||
+++ b/drivers/clk/renesas/rzg2l-cpg.c
|
||
@@ -56,15 +56,37 @@
|
||
#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff)
|
||
#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff)
|
||
|
||
+#define CPG_WEN_BIT BIT(16)
|
||
+
|
||
#define MAX_VCLK_FREQ (148500000)
|
||
|
||
-struct sd_hw_data {
|
||
+/**
|
||
+ * struct clk_hw_data - clock hardware data
|
||
+ * @hw: clock hw
|
||
+ * @conf: clock configuration (register offset, shift, width)
|
||
+ * @sconf: clock status configuration (register offset, shift, width)
|
||
+ * @priv: CPG private data structure
|
||
+ */
|
||
+struct clk_hw_data {
|
||
struct clk_hw hw;
|
||
u32 conf;
|
||
+ u32 sconf;
|
||
struct rzg2l_cpg_priv *priv;
|
||
};
|
||
|
||
-#define to_sd_hw_data(_hw) container_of(_hw, struct sd_hw_data, hw)
|
||
+#define to_clk_hw_data(_hw) container_of(_hw, struct clk_hw_data, hw)
|
||
+
|
||
+/**
|
||
+ * struct sd_mux_hw_data - SD MUX clock hardware data
|
||
+ * @hw_data: clock hw data
|
||
+ * @mtable: clock mux table
|
||
+ */
|
||
+struct sd_mux_hw_data {
|
||
+ struct clk_hw_data hw_data;
|
||
+ const u32 *mtable;
|
||
+};
|
||
+
|
||
+#define to_sd_mux_hw_data(_hw) container_of(_hw, struct sd_mux_hw_data, hw_data)
|
||
|
||
struct rzg2l_pll5_param {
|
||
u32 pl5_fracin;
|
||
@@ -121,6 +143,76 @@ static void rzg2l_cpg_del_clk_provider(void *data)
|
||
of_clk_del_provider(data);
|
||
}
|
||
|
||
+/* Must be called in atomic context. */
|
||
+static int rzg2l_cpg_wait_clk_update_done(void __iomem *base, u32 conf)
|
||
+{
|
||
+ u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf);
|
||
+ u32 off = GET_REG_OFFSET(conf);
|
||
+ u32 val;
|
||
+
|
||
+ return readl_poll_timeout_atomic(base + off, val, !(val & bitmask), 10, 200);
|
||
+}
|
||
+
|
||
+int rzg2l_cpg_sd_clk_mux_notifier(struct notifier_block *nb, unsigned long event,
|
||
+ void *data)
|
||
+{
|
||
+ struct clk_notifier_data *cnd = data;
|
||
+ struct clk_hw *hw = __clk_get_hw(cnd->clk);
|
||
+ struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||
+ struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||
+ u32 off = GET_REG_OFFSET(clk_hw_data->conf);
|
||
+ u32 shift = GET_SHIFT(clk_hw_data->conf);
|
||
+ const u32 clk_src_266 = 3;
|
||
+ unsigned long flags;
|
||
+ int ret;
|
||
+
|
||
+ if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266))
|
||
+ return NOTIFY_DONE;
|
||
+
|
||
+ spin_lock_irqsave(&priv->rmw_lock, flags);
|
||
+
|
||
+ /*
|
||
+ * As per the HW manual, we should not directly switch from 533 MHz to
|
||
+ * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz)
|
||
+ * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first,
|
||
+ * and then switch to the target setting (2’b01 (533 MHz) or 2’b10
|
||
+ * (400 MHz)).
|
||
+ * Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock
|
||
+ * switching register is prohibited.
|
||
+ * The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and
|
||
+ * the index to value mapping is done by adding 1 to the index.
|
||
+ */
|
||
+
|
||
+ writel((CPG_WEN_BIT | clk_src_266) << shift, priv->base + off);
|
||
+
|
||
+ /* Wait for the update done. */
|
||
+ ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);
|
||
+
|
||
+ spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||
+
|
||
+ if (ret)
|
||
+ dev_err(priv->dev, "failed to switch to safe clk source\n");
|
||
+
|
||
+ return notifier_from_errno(ret);
|
||
+}
|
||
+
|
||
+static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk *core,
|
||
+ struct rzg2l_cpg_priv *priv)
|
||
+{
|
||
+ struct notifier_block *nb;
|
||
+
|
||
+ if (!core->notifier)
|
||
+ return 0;
|
||
+
|
||
+ nb = devm_kzalloc(priv->dev, sizeof(*nb), GFP_KERNEL);
|
||
+ if (!nb)
|
||
+ return -ENOMEM;
|
||
+
|
||
+ nb->notifier_call = core->notifier;
|
||
+
|
||
+ return clk_notifier_register(hw->clk, nb);
|
||
+}
|
||
+
|
||
static struct clk * __init
|
||
rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,
|
||
struct clk **clks,
|
||
@@ -183,63 +275,44 @@ rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core,
|
||
|
||
static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
||
{
|
||
- struct sd_hw_data *hwdata = to_sd_hw_data(hw);
|
||
- struct rzg2l_cpg_priv *priv = hwdata->priv;
|
||
- u32 off = GET_REG_OFFSET(hwdata->conf);
|
||
- u32 shift = GET_SHIFT(hwdata->conf);
|
||
- const u32 clk_src_266 = 2;
|
||
- u32 msk, val, bitmask;
|
||
+ struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||
+ struct sd_mux_hw_data *sd_mux_hw_data = to_sd_mux_hw_data(clk_hw_data);
|
||
+ struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||
+ u32 off = GET_REG_OFFSET(clk_hw_data->conf);
|
||
+ u32 shift = GET_SHIFT(clk_hw_data->conf);
|
||
unsigned long flags;
|
||
+ u32 val;
|
||
int ret;
|
||
|
||
- /*
|
||
- * As per the HW manual, we should not directly switch from 533 MHz to
|
||
- * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz)
|
||
- * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first,
|
||
- * and then switch to the target setting (2’b01 (533 MHz) or 2’b10
|
||
- * (400 MHz)).
|
||
- * Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock
|
||
- * switching register is prohibited.
|
||
- * The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and
|
||
- * the index to value mapping is done by adding 1 to the index.
|
||
- */
|
||
- bitmask = (GENMASK(GET_WIDTH(hwdata->conf) - 1, 0) << shift) << 16;
|
||
- msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS;
|
||
+ val = clk_mux_index_to_val(sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, index);
|
||
+
|
||
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||
- if (index != clk_src_266) {
|
||
- writel(bitmask | ((clk_src_266 + 1) << shift), priv->base + off);
|
||
-
|
||
- ret = readl_poll_timeout_atomic(priv->base + CPG_CLKSTATUS, val,
|
||
- !(val & msk), 10,
|
||
- CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US);
|
||
- if (ret)
|
||
- goto unlock;
|
||
- }
|
||
|
||
- writel(bitmask | ((index + 1) << shift), priv->base + off);
|
||
+ writel((CPG_WEN_BIT | val) << shift, priv->base + off);
|
||
+
|
||
+ /* Wait for the update done. */
|
||
+ ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);
|
||
|
||
- ret = readl_poll_timeout_atomic(priv->base + CPG_CLKSTATUS, val,
|
||
- !(val & msk), 10,
|
||
- CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US);
|
||
-unlock:
|
||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||
|
||
if (ret)
|
||
- dev_err(priv->dev, "failed to switch clk source\n");
|
||
+ dev_err(priv->dev, "Failed to switch parent\n");
|
||
|
||
return ret;
|
||
}
|
||
|
||
static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw)
|
||
{
|
||
- struct sd_hw_data *hwdata = to_sd_hw_data(hw);
|
||
- struct rzg2l_cpg_priv *priv = hwdata->priv;
|
||
- u32 val = readl(priv->base + GET_REG_OFFSET(hwdata->conf));
|
||
+ struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);
|
||
+ struct sd_mux_hw_data *sd_mux_hw_data = to_sd_mux_hw_data(clk_hw_data);
|
||
+ struct rzg2l_cpg_priv *priv = clk_hw_data->priv;
|
||
+ u32 val;
|
||
|
||
- val >>= GET_SHIFT(hwdata->conf);
|
||
- val &= GENMASK(GET_WIDTH(hwdata->conf) - 1, 0);
|
||
+ val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf));
|
||
+ val >>= GET_SHIFT(clk_hw_data->conf);
|
||
+ val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0);
|
||
|
||
- return val ? val - 1 : 0;
|
||
+ return clk_mux_val_to_index(hw, sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, val);
|
||
}
|
||
|
||
static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = {
|
||
@@ -253,31 +326,40 @@ rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core,
|
||
void __iomem *base,
|
||
struct rzg2l_cpg_priv *priv)
|
||
{
|
||
- struct sd_hw_data *clk_hw_data;
|
||
+ struct sd_mux_hw_data *sd_mux_hw_data;
|
||
struct clk_init_data init;
|
||
struct clk_hw *clk_hw;
|
||
int ret;
|
||
|
||
- clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
|
||
- if (!clk_hw_data)
|
||
+ sd_mux_hw_data = devm_kzalloc(priv->dev, sizeof(*sd_mux_hw_data), GFP_KERNEL);
|
||
+ if (!sd_mux_hw_data)
|
||
return ERR_PTR(-ENOMEM);
|
||
|
||
- clk_hw_data->priv = priv;
|
||
- clk_hw_data->conf = core->conf;
|
||
+ sd_mux_hw_data->hw_data.priv = priv;
|
||
+ sd_mux_hw_data->hw_data.conf = core->conf;
|
||
+ sd_mux_hw_data->hw_data.sconf = core->sconf;
|
||
+ sd_mux_hw_data->mtable = core->mtable;
|
||
|
||
init.name = GET_SHIFT(core->conf) ? "sd1" : "sd0";
|
||
init.ops = &rzg2l_cpg_sd_clk_mux_ops;
|
||
- init.flags = 0;
|
||
+ init.flags = core->flag;
|
||
init.num_parents = core->num_parents;
|
||
init.parent_names = core->parent_names;
|
||
|
||
- clk_hw = &clk_hw_data->hw;
|
||
+ clk_hw = &sd_mux_hw_data->hw_data.hw;
|
||
clk_hw->init = &init;
|
||
|
||
ret = devm_clk_hw_register(priv->dev, clk_hw);
|
||
if (ret)
|
||
return ERR_PTR(ret);
|
||
|
||
+ ret = rzg2l_register_notifier(clk_hw, core, priv);
|
||
+ if (ret) {
|
||
+ dev_err(priv->dev, "Failed to register notifier for %s\n",
|
||
+ core->name);
|
||
+ return ERR_PTR(ret);
|
||
+ }
|
||
+
|
||
return clk_hw->clk;
|
||
}
|
||
|
||
diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h
|
||
index 91e9c2569f801b..e662459cc6d963 100644
|
||
--- a/drivers/clk/renesas/rzg2l-cpg.h
|
||
+++ b/drivers/clk/renesas/rzg2l-cpg.h
|
||
@@ -9,6 +9,8 @@
|
||
#ifndef __RENESAS_RZG2L_CPG_H__
|
||
#define __RENESAS_RZG2L_CPG_H__
|
||
|
||
+#include <linux/notifier.h>
|
||
+
|
||
#define CPG_SIPLL5_STBY (0x140)
|
||
#define CPG_SIPLL5_CLK1 (0x144)
|
||
#define CPG_SIPLL5_CLK3 (0x14C)
|
||
@@ -19,7 +21,6 @@
|
||
#define CPG_PL2_DDIV (0x204)
|
||
#define CPG_PL3A_DDIV (0x208)
|
||
#define CPG_PL6_DDIV (0x210)
|
||
-#define CPG_PL2SDHI_DSEL (0x218)
|
||
#define CPG_CLKSTATUS (0x280)
|
||
#define CPG_PL3_SSEL (0x408)
|
||
#define CPG_PL6_SSEL (0x414)
|
||
@@ -43,8 +44,6 @@
|
||
#define CPG_CLKSTATUS_SELSDHI0_STS BIT(28)
|
||
#define CPG_CLKSTATUS_SELSDHI1_STS BIT(29)
|
||
|
||
-#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 200
|
||
-
|
||
/* n = 0/1/2 for PLL1/4/6 */
|
||
#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n))
|
||
#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n))
|
||
@@ -69,9 +68,6 @@
|
||
#define SEL_PLL6_2 SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1)
|
||
#define SEL_GPU2 SEL_PLL_PACK(CPG_PL6_SSEL, 12, 1)
|
||
|
||
-#define SEL_SDHI0 DDIV_PACK(CPG_PL2SDHI_DSEL, 0, 2)
|
||
-#define SEL_SDHI1 DDIV_PACK(CPG_PL2SDHI_DSEL, 4, 2)
|
||
-
|
||
#define EXTAL_FREQ_IN_MEGA_HZ (24)
|
||
|
||
/**
|
||
@@ -90,10 +86,13 @@ struct cpg_core_clk {
|
||
unsigned int mult;
|
||
unsigned int type;
|
||
unsigned int conf;
|
||
+ unsigned int sconf;
|
||
const struct clk_div_table *dtable;
|
||
+ const u32 *mtable;
|
||
const char * const *parent_names;
|
||
- int flag;
|
||
- int mux_flags;
|
||
+ notifier_fn_t notifier;
|
||
+ u32 flag;
|
||
+ u32 mux_flags;
|
||
int num_parents;
|
||
};
|
||
|
||
@@ -151,10 +150,11 @@ enum clk_types {
|
||
.parent_names = _parent_names, \
|
||
.num_parents = ARRAY_SIZE(_parent_names), \
|
||
.mux_flags = CLK_MUX_READ_ONLY)
|
||
-#define DEF_SD_MUX(_name, _id, _conf, _parent_names) \
|
||
- DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, \
|
||
+#define DEF_SD_MUX(_name, _id, _conf, _sconf, _parent_names, _mtable, _clk_flags, _notifier) \
|
||
+ DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, .sconf = _sconf, \
|
||
.parent_names = _parent_names, \
|
||
- .num_parents = ARRAY_SIZE(_parent_names))
|
||
+ .num_parents = ARRAY_SIZE(_parent_names), \
|
||
+ .mtable = _mtable, .flag = _clk_flags, .notifier = _notifier)
|
||
#define DEF_PLL5_FOUTPOSTDIV(_name, _id, _parent) \
|
||
DEF_TYPE(_name, _id, CLK_TYPE_SIPLL5, .parent = _parent)
|
||
#define DEF_PLL5_4_MUX(_name, _id, _conf, _parent_names) \
|
||
@@ -273,4 +273,6 @@ extern const struct rzg2l_cpg_info r9a07g044_cpg_info;
|
||
extern const struct rzg2l_cpg_info r9a07g054_cpg_info;
|
||
extern const struct rzg2l_cpg_info r9a09g011_cpg_info;
|
||
|
||
+int rzg2l_cpg_sd_clk_mux_notifier(struct notifier_block *nb, unsigned long event, void *data);
|
||
+
|
||
#endif
|
||
diff --git a/drivers/comedi/drivers/jr3_pci.c b/drivers/comedi/drivers/jr3_pci.c
|
||
index 951c23fa0369ea..75dce1ff24193b 100644
|
||
--- a/drivers/comedi/drivers/jr3_pci.c
|
||
+++ b/drivers/comedi/drivers/jr3_pci.c
|
||
@@ -758,7 +758,7 @@ static void jr3_pci_detach(struct comedi_device *dev)
|
||
struct jr3_pci_dev_private *devpriv = dev->private;
|
||
|
||
if (devpriv)
|
||
- del_timer_sync(&devpriv->timer);
|
||
+ timer_shutdown_sync(&devpriv->timer);
|
||
|
||
comedi_pci_detach(dev);
|
||
}
|
||
diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c
|
||
index 021f423705e1b1..9ba6b09775f617 100644
|
||
--- a/drivers/cpufreq/apple-soc-cpufreq.c
|
||
+++ b/drivers/cpufreq/apple-soc-cpufreq.c
|
||
@@ -103,11 +103,17 @@ static const struct of_device_id apple_soc_cpufreq_of_match[] = {
|
||
|
||
static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu)
|
||
{
|
||
- struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
|
||
- struct apple_cpu_priv *priv = policy->driver_data;
|
||
+ struct cpufreq_policy *policy;
|
||
+ struct apple_cpu_priv *priv;
|
||
struct cpufreq_frequency_table *p;
|
||
unsigned int pstate;
|
||
|
||
+ policy = cpufreq_cpu_get_raw(cpu);
|
||
+ if (unlikely(!policy))
|
||
+ return 0;
|
||
+
|
||
+ priv = policy->driver_data;
|
||
+
|
||
if (priv->info->cur_pstate_mask) {
|
||
u64 reg = readq_relaxed(priv->reg_base + APPLE_DVFS_STATUS);
|
||
|
||
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
|
||
index c8447ecad797e7..aa34af940cb53b 100644
|
||
--- a/drivers/cpufreq/cppc_cpufreq.c
|
||
+++ b/drivers/cpufreq/cppc_cpufreq.c
|
||
@@ -773,7 +773,7 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
|
||
int ret;
|
||
|
||
if (!policy)
|
||
- return -ENODEV;
|
||
+ return 0;
|
||
|
||
cpu_data = policy->driver_data;
|
||
|
||
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
|
||
index 079940c69ee0ba..e4989764efe2a8 100644
|
||
--- a/drivers/cpufreq/scmi-cpufreq.c
|
||
+++ b/drivers/cpufreq/scmi-cpufreq.c
|
||
@@ -33,11 +33,17 @@ static const struct scmi_perf_proto_ops *perf_ops;
|
||
|
||
static unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
|
||
{
|
||
- struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
|
||
- struct scmi_data *priv = policy->driver_data;
|
||
+ struct cpufreq_policy *policy;
|
||
+ struct scmi_data *priv;
|
||
unsigned long rate;
|
||
int ret;
|
||
|
||
+ policy = cpufreq_cpu_get_raw(cpu);
|
||
+ if (unlikely(!policy))
|
||
+ return 0;
|
||
+
|
||
+ priv = policy->driver_data;
|
||
+
|
||
ret = perf_ops->freq_get(ph, priv->domain_id, &rate, false);
|
||
if (ret)
|
||
return 0;
|
||
diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
|
||
index bfc2e65e1e5022..2aef39bff7d6f5 100644
|
||
--- a/drivers/cpufreq/scpi-cpufreq.c
|
||
+++ b/drivers/cpufreq/scpi-cpufreq.c
|
||
@@ -29,9 +29,16 @@ static struct scpi_ops *scpi_ops;
|
||
|
||
static unsigned int scpi_cpufreq_get_rate(unsigned int cpu)
|
||
{
|
||
- struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
|
||
- struct scpi_data *priv = policy->driver_data;
|
||
- unsigned long rate = clk_get_rate(priv->clk);
|
||
+ struct cpufreq_policy *policy;
|
||
+ struct scpi_data *priv;
|
||
+ unsigned long rate;
|
||
+
|
||
+ policy = cpufreq_cpu_get_raw(cpu);
|
||
+ if (unlikely(!policy))
|
||
+ return 0;
|
||
+
|
||
+ priv = policy->driver_data;
|
||
+ rate = clk_get_rate(priv->clk);
|
||
|
||
return rate / 1000;
|
||
}
|
||
diff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c
|
||
index c77f482d2a97e9..5bc809146ffea0 100644
|
||
--- a/drivers/crypto/atmel-sha204a.c
|
||
+++ b/drivers/crypto/atmel-sha204a.c
|
||
@@ -107,6 +107,12 @@ static int atmel_sha204a_probe(struct i2c_client *client)
|
||
i2c_priv->hwrng.name = dev_name(&client->dev);
|
||
i2c_priv->hwrng.read = atmel_sha204a_rng_read;
|
||
|
||
+ /*
|
||
+ * According to review by Bill Cox [1], this HWRNG has very low entropy.
|
||
+ * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
|
||
+ */
|
||
+ i2c_priv->hwrng.quality = 1;
|
||
+
|
||
ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng);
|
||
if (ret)
|
||
dev_warn(&client->dev, "failed to register RNG (%d)\n", ret);
|
||
diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
|
||
index 0caa57dafc525a..b1e60542351a66 100644
|
||
--- a/drivers/crypto/ccp/sp-pci.c
|
||
+++ b/drivers/crypto/ccp/sp-pci.c
|
||
@@ -577,6 +577,7 @@ static const struct pci_device_id sp_pci_table[] = {
|
||
{ PCI_VDEVICE(AMD, 0x14CA), (kernel_ulong_t)&dev_vdata[5] },
|
||
{ PCI_VDEVICE(AMD, 0x15C7), (kernel_ulong_t)&dev_vdata[6] },
|
||
{ PCI_VDEVICE(AMD, 0x1649), (kernel_ulong_t)&dev_vdata[6] },
|
||
+ { PCI_VDEVICE(AMD, 0x1134), (kernel_ulong_t)&dev_vdata[7] },
|
||
{ PCI_VDEVICE(AMD, 0x17E0), (kernel_ulong_t)&dev_vdata[7] },
|
||
{ PCI_VDEVICE(AMD, 0x156E), (kernel_ulong_t)&dev_vdata[8] },
|
||
/* Last entry must be zero */
|
||
diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
|
||
index bab4592db647f7..92ef68849fbea8 100644
|
||
--- a/drivers/cxl/core/regs.c
|
||
+++ b/drivers/cxl/core/regs.c
|
||
@@ -478,7 +478,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri
|
||
resource_size_t rcrb = ri->base;
|
||
void __iomem *addr;
|
||
u32 bar0, bar1;
|
||
- u16 cmd;
|
||
u32 id;
|
||
|
||
if (which == CXL_RCRB_UPSTREAM)
|
||
@@ -500,7 +499,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri
|
||
}
|
||
|
||
id = readl(addr + PCI_VENDOR_ID);
|
||
- cmd = readw(addr + PCI_COMMAND);
|
||
bar0 = readl(addr + PCI_BASE_ADDRESS_0);
|
||
bar1 = readl(addr + PCI_BASE_ADDRESS_1);
|
||
iounmap(addr);
|
||
@@ -515,8 +513,6 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri
|
||
dev_err(dev, "Failed to access Downstream Port RCRB\n");
|
||
return CXL_RESOURCE_NONE;
|
||
}
|
||
- if (!(cmd & PCI_COMMAND_MEMORY))
|
||
- return CXL_RESOURCE_NONE;
|
||
/* The RCRB is a Memory Window, and the MEM_TYPE_1M bit is obsolete */
|
||
if (bar0 & (PCI_BASE_ADDRESS_MEM_TYPE_1M | PCI_BASE_ADDRESS_SPACE_IO))
|
||
return CXL_RESOURCE_NONE;
|
||
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
|
||
index d1fcdd1f9aaed3..373282beeb6068 100644
|
||
--- a/drivers/dma-buf/udmabuf.c
|
||
+++ b/drivers/dma-buf/udmabuf.c
|
||
@@ -214,7 +214,7 @@ static long udmabuf_create(struct miscdevice *device,
|
||
if (!ubuf)
|
||
return -ENOMEM;
|
||
|
||
- pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
|
||
+ pglimit = ((u64)size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
|
||
for (i = 0; i < head->count; i++) {
|
||
if (!IS_ALIGNED(list[i].offset, PAGE_SIZE))
|
||
goto err;
|
||
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
|
||
index ffe621695e472b..78b8a97b236376 100644
|
||
--- a/drivers/dma/dmatest.c
|
||
+++ b/drivers/dma/dmatest.c
|
||
@@ -827,9 +827,9 @@ static int dmatest_func(void *data)
|
||
} else {
|
||
dma_async_issue_pending(chan);
|
||
|
||
- wait_event_freezable_timeout(thread->done_wait,
|
||
- done->done,
|
||
- msecs_to_jiffies(params->timeout));
|
||
+ wait_event_timeout(thread->done_wait,
|
||
+ done->done,
|
||
+ msecs_to_jiffies(params->timeout));
|
||
|
||
status = dma_async_is_tx_complete(chan, cookie, NULL,
|
||
NULL);
|
||
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
|
||
index cec9e8f29bbdfe..a0a2a0f75bba46 100644
|
||
--- a/drivers/gpio/gpiolib-of.c
|
||
+++ b/drivers/gpio/gpiolib-of.c
|
||
@@ -247,6 +247,9 @@ static void of_gpio_set_polarity_by_property(const struct device_node *np,
|
||
{ "fsl,imx8qm-fec", "phy-reset-gpios", "phy-reset-active-high" },
|
||
{ "fsl,s32v234-fec", "phy-reset-gpios", "phy-reset-active-high" },
|
||
#endif
|
||
+#if IS_ENABLED(CONFIG_MMC_ATMELMCI)
|
||
+ { "atmel,hsmci", "cd-gpios", "cd-inverted" },
|
||
+#endif
|
||
#if IS_ENABLED(CONFIG_PCI_IMX6)
|
||
{ "fsl,imx6q-pcie", "reset-gpio", "reset-gpio-active-high" },
|
||
{ "fsl,imx6sx-pcie", "reset-gpio", "reset-gpio-active-high" },
|
||
@@ -272,9 +275,6 @@ static void of_gpio_set_polarity_by_property(const struct device_node *np,
|
||
#if IS_ENABLED(CONFIG_REGULATOR_GPIO)
|
||
{ "regulator-gpio", "enable-gpio", "enable-active-high" },
|
||
{ "regulator-gpio", "enable-gpios", "enable-active-high" },
|
||
-#endif
|
||
-#if IS_ENABLED(CONFIG_MMC_ATMELMCI)
|
||
- { "atmel,hsmci", "cd-gpios", "cd-inverted" },
|
||
#endif
|
||
};
|
||
unsigned int i;
|
||
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
||
index 28f2b4022d34e3..e6bc590533194d 100644
|
||
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
||
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
||
@@ -2789,16 +2789,16 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
|
||
for (k = 0; k < dc_state->stream_count; k++) {
|
||
bundle->stream_update.stream = dc_state->streams[k];
|
||
|
||
- for (m = 0; m < dc_state->stream_status->plane_count; m++) {
|
||
+ for (m = 0; m < dc_state->stream_status[k].plane_count; m++) {
|
||
bundle->surface_updates[m].surface =
|
||
- dc_state->stream_status->plane_states[m];
|
||
+ dc_state->stream_status[k].plane_states[m];
|
||
bundle->surface_updates[m].surface->force_full_update =
|
||
true;
|
||
}
|
||
|
||
update_planes_and_stream_adapter(dm->dc,
|
||
UPDATE_TYPE_FULL,
|
||
- dc_state->stream_status->plane_count,
|
||
+ dc_state->stream_status[k].plane_count,
|
||
dc_state->streams[k],
|
||
&bundle->stream_update,
|
||
bundle->surface_updates);
|
||
@@ -9590,6 +9590,9 @@ static bool should_reset_plane(struct drm_atomic_state *state,
|
||
if (adev->ip_versions[DCE_HWIP][0] < IP_VERSION(3, 2, 0) && state->allow_modeset)
|
||
return true;
|
||
|
||
+ if (amdgpu_in_reset(adev) && state->allow_modeset)
|
||
+ return true;
|
||
+
|
||
/* Exit early if we know that we're adding or removing the plane. */
|
||
if (old_plane_state->crtc != new_plane_state->crtc)
|
||
return true;
|
||
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
|
||
index 70a25949142c0d..74b0c85944bd61 100644
|
||
--- a/drivers/iio/adc/ad7768-1.c
|
||
+++ b/drivers/iio/adc/ad7768-1.c
|
||
@@ -142,7 +142,7 @@ static const struct iio_chan_spec ad7768_channels[] = {
|
||
.channel = 0,
|
||
.scan_index = 0,
|
||
.scan_type = {
|
||
- .sign = 'u',
|
||
+ .sign = 's',
|
||
.realbits = 24,
|
||
.storagebits = 32,
|
||
.shift = 8,
|
||
@@ -370,12 +370,11 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
|
||
return ret;
|
||
|
||
ret = ad7768_scan_direct(indio_dev);
|
||
- if (ret >= 0)
|
||
- *val = ret;
|
||
|
||
iio_device_release_direct_mode(indio_dev);
|
||
if (ret < 0)
|
||
return ret;
|
||
+ *val = sign_extend32(ret, chan->scan_type.realbits - 1);
|
||
|
||
return IIO_VAL_INT;
|
||
|
||
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c
|
||
index 11155e0fb8395c..35d777976c2952 100644
|
||
--- a/drivers/infiniband/hw/qib/qib_fs.c
|
||
+++ b/drivers/infiniband/hw/qib/qib_fs.c
|
||
@@ -55,6 +55,7 @@ static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
|
||
struct inode *inode = new_inode(dir->i_sb);
|
||
|
||
if (!inode) {
|
||
+ dput(dentry);
|
||
error = -EPERM;
|
||
goto bail;
|
||
}
|
||
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
|
||
index 95bd7c25ba6f36..83c5d786686d07 100644
|
||
--- a/drivers/iommu/amd/iommu.c
|
||
+++ b/drivers/iommu/amd/iommu.c
|
||
@@ -3619,7 +3619,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
|
||
* we should not modify the IRTE
|
||
*/
|
||
if (!dev_data || !dev_data->use_vapic)
|
||
- return 0;
|
||
+ return -EINVAL;
|
||
|
||
ir_data->cfg = irqd_cfg(data);
|
||
pi_data->ir_data = ir_data;
|
||
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
|
||
index d83c2c85962c37..683e8721e3b498 100644
|
||
--- a/drivers/irqchip/irq-gic-v2m.c
|
||
+++ b/drivers/irqchip/irq-gic-v2m.c
|
||
@@ -454,7 +454,7 @@ static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
|
||
#ifdef CONFIG_ACPI
|
||
static int acpi_num_msi;
|
||
|
||
-static __init struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
|
||
+static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
|
||
{
|
||
struct v2m_data *data;
|
||
|
||
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
|
||
index 82102a4c5d6883..f8215a8f656a46 100644
|
||
--- a/drivers/mailbox/pcc.c
|
||
+++ b/drivers/mailbox/pcc.c
|
||
@@ -313,6 +313,10 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
|
||
int ret;
|
||
|
||
pchan = chan->con_priv;
|
||
+
|
||
+ if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack))
|
||
+ return IRQ_NONE;
|
||
+
|
||
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE &&
|
||
!pchan->chan_in_use)
|
||
return IRQ_NONE;
|
||
@@ -330,13 +334,16 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
|
||
return IRQ_NONE;
|
||
}
|
||
|
||
- if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack))
|
||
- return IRQ_NONE;
|
||
-
|
||
+ /*
|
||
+ * Clear this flag after updating interrupt ack register and just
|
||
+ * before mbox_chan_received_data() which might call pcc_send_data()
|
||
+ * where the flag is set again to start new transfer. This is
|
||
+ * required to avoid any possible race in updatation of this flag.
|
||
+ */
|
||
+ pchan->chan_in_use = false;
|
||
mbox_chan_received_data(chan, NULL);
|
||
|
||
check_and_ack(pchan, chan);
|
||
- pchan->chan_in_use = false;
|
||
|
||
return IRQ_HANDLED;
|
||
}
|
||
diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c
|
||
index 1ae37e693de045..d080e21df666d9 100644
|
||
--- a/drivers/mcb/mcb-parse.c
|
||
+++ b/drivers/mcb/mcb-parse.c
|
||
@@ -101,7 +101,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus,
|
||
|
||
ret = mcb_device_register(bus, mdev);
|
||
if (ret < 0)
|
||
- goto err;
|
||
+ return ret;
|
||
|
||
return 0;
|
||
|
||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
|
||
index 65309da1dca340..8b25287c89ed6d 100644
|
||
--- a/drivers/md/raid1.c
|
||
+++ b/drivers/md/raid1.c
|
||
@@ -2061,14 +2061,9 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
|
||
if (!rdev_set_badblocks(rdev, sect, s, 0))
|
||
abort = 1;
|
||
}
|
||
- if (abort) {
|
||
- conf->recovery_disabled =
|
||
- mddev->recovery_disabled;
|
||
- set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||
- md_done_sync(mddev, r1_bio->sectors, 0);
|
||
- put_buf(r1_bio);
|
||
+ if (abort)
|
||
return 0;
|
||
- }
|
||
+
|
||
/* Try next page */
|
||
sectors -= s;
|
||
sect += s;
|
||
@@ -2207,10 +2202,21 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio)
|
||
int disks = conf->raid_disks * 2;
|
||
struct bio *wbio;
|
||
|
||
- if (!test_bit(R1BIO_Uptodate, &r1_bio->state))
|
||
- /* ouch - failed to read all of that. */
|
||
- if (!fix_sync_read_error(r1_bio))
|
||
+ if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) {
|
||
+ /*
|
||
+ * ouch - failed to read all of that.
|
||
+ * No need to fix read error for check/repair
|
||
+ * because all member disks are read.
|
||
+ */
|
||
+ if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) ||
|
||
+ !fix_sync_read_error(r1_bio)) {
|
||
+ conf->recovery_disabled = mddev->recovery_disabled;
|
||
+ set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||
+ md_done_sync(mddev, r1_bio->sectors, 0);
|
||
+ put_buf(r1_bio);
|
||
return;
|
||
+ }
|
||
+ }
|
||
|
||
if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
|
||
process_checks(r1_bio);
|
||
diff --git a/drivers/media/test-drivers/vimc/vimc-streamer.c b/drivers/media/test-drivers/vimc/vimc-streamer.c
|
||
index 807551a5143b78..15d863f97cbf96 100644
|
||
--- a/drivers/media/test-drivers/vimc/vimc-streamer.c
|
||
+++ b/drivers/media/test-drivers/vimc/vimc-streamer.c
|
||
@@ -59,6 +59,12 @@ static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream)
|
||
continue;
|
||
|
||
sd = media_entity_to_v4l2_subdev(ved->ent);
|
||
+ /*
|
||
+ * Do not call .s_stream() to stop an already
|
||
+ * stopped/unstarted subdev.
|
||
+ */
|
||
+ if (!v4l2_subdev_is_streaming(sd))
|
||
+ continue;
|
||
v4l2_subdev_call(sd, video, s_stream, 0);
|
||
}
|
||
}
|
||
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
|
||
index a32ef739eb4490..5f115438d07228 100644
|
||
--- a/drivers/media/v4l2-core/v4l2-subdev.c
|
||
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
|
||
@@ -363,12 +363,8 @@ static int call_s_stream(struct v4l2_subdev *sd, int enable)
|
||
* The .s_stream() operation must never be called to start or stop an
|
||
* already started or stopped subdev. Catch offenders but don't return
|
||
* an error yet to avoid regressions.
|
||
- *
|
||
- * As .s_stream() is mutually exclusive with the .enable_streams() and
|
||
- * .disable_streams() operation, we can use the enabled_streams field
|
||
- * to store the subdev streaming state.
|
||
*/
|
||
- if (WARN_ON(!!sd->enabled_streams == !!enable))
|
||
+ if (WARN_ON(sd->s_stream_enabled == !!enable))
|
||
return 0;
|
||
|
||
ret = sd->ops->video->s_stream(sd, enable);
|
||
@@ -379,7 +375,7 @@ static int call_s_stream(struct v4l2_subdev *sd, int enable)
|
||
}
|
||
|
||
if (!ret) {
|
||
- sd->enabled_streams = enable ? BIT(0) : 0;
|
||
+ sd->s_stream_enabled = enable;
|
||
|
||
#if IS_REACHABLE(CONFIG_LEDS_CLASS)
|
||
if (!IS_ERR_OR_NULL(sd->privacy_led)) {
|
||
@@ -1929,37 +1925,43 @@ static int v4l2_subdev_enable_streams_fallback(struct v4l2_subdev *sd, u32 pad,
|
||
u64 streams_mask)
|
||
{
|
||
struct device *dev = sd->entity.graph_obj.mdev->dev;
|
||
- unsigned int i;
|
||
int ret;
|
||
|
||
/*
|
||
* The subdev doesn't implement pad-based stream enable, fall back
|
||
- * on the .s_stream() operation. This can only be done for subdevs that
|
||
- * have a single source pad, as sd->enabled_streams is global to the
|
||
- * subdev.
|
||
+ * to the .s_stream() operation.
|
||
*/
|
||
if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))
|
||
return -EOPNOTSUPP;
|
||
|
||
- for (i = 0; i < sd->entity.num_pads; ++i) {
|
||
- if (i != pad && sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
|
||
- return -EOPNOTSUPP;
|
||
- }
|
||
+ /*
|
||
+ * .s_stream() means there is no streams support, so the only allowed
|
||
+ * stream is the implicit stream 0.
|
||
+ */
|
||
+ if (streams_mask != BIT_ULL(0))
|
||
+ return -EOPNOTSUPP;
|
||
+
|
||
+ /*
|
||
+ * We use a 64-bit bitmask for tracking enabled pads, so only subdevices
|
||
+ * with 64 pads or less can be supported.
|
||
+ */
|
||
+ if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)
|
||
+ return -EOPNOTSUPP;
|
||
|
||
- if (sd->enabled_streams & streams_mask) {
|
||
- dev_dbg(dev, "set of streams %#llx already enabled on %s:%u\n",
|
||
- streams_mask, sd->entity.name, pad);
|
||
+ if (sd->enabled_pads & BIT_ULL(pad)) {
|
||
+ dev_dbg(dev, "pad %u already enabled on %s\n",
|
||
+ pad, sd->entity.name);
|
||
return -EALREADY;
|
||
}
|
||
|
||
- /* Start streaming when the first streams are enabled. */
|
||
- if (!sd->enabled_streams) {
|
||
+ /* Start streaming when the first pad is enabled. */
|
||
+ if (!sd->enabled_pads) {
|
||
ret = v4l2_subdev_call(sd, video, s_stream, 1);
|
||
if (ret)
|
||
return ret;
|
||
}
|
||
|
||
- sd->enabled_streams |= streams_mask;
|
||
+ sd->enabled_pads |= BIT_ULL(pad);
|
||
|
||
return 0;
|
||
}
|
||
@@ -2046,37 +2048,43 @@ static int v4l2_subdev_disable_streams_fallback(struct v4l2_subdev *sd, u32 pad,
|
||
u64 streams_mask)
|
||
{
|
||
struct device *dev = sd->entity.graph_obj.mdev->dev;
|
||
- unsigned int i;
|
||
int ret;
|
||
|
||
/*
|
||
- * If the subdev doesn't implement pad-based stream enable, fall back
|
||
- * on the .s_stream() operation. This can only be done for subdevs that
|
||
- * have a single source pad, as sd->enabled_streams is global to the
|
||
- * subdev.
|
||
+ * If the subdev doesn't implement pad-based stream enable, fall back
|
||
+ * to the .s_stream() operation.
|
||
*/
|
||
if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))
|
||
return -EOPNOTSUPP;
|
||
|
||
- for (i = 0; i < sd->entity.num_pads; ++i) {
|
||
- if (i != pad && sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
|
||
- return -EOPNOTSUPP;
|
||
- }
|
||
+ /*
|
||
+ * .s_stream() means there is no streams support, so the only allowed
|
||
+ * stream is the implicit stream 0.
|
||
+ */
|
||
+ if (streams_mask != BIT_ULL(0))
|
||
+ return -EOPNOTSUPP;
|
||
+
|
||
+ /*
|
||
+ * We use a 64-bit bitmask for tracking enabled pads, so only subdevices
|
||
+ * with 64 pads or less can be supported.
|
||
+ */
|
||
+ if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)
|
||
+ return -EOPNOTSUPP;
|
||
|
||
- if ((sd->enabled_streams & streams_mask) != streams_mask) {
|
||
- dev_dbg(dev, "set of streams %#llx already disabled on %s:%u\n",
|
||
- streams_mask, sd->entity.name, pad);
|
||
+ if (!(sd->enabled_pads & BIT_ULL(pad))) {
|
||
+ dev_dbg(dev, "pad %u already disabled on %s\n",
|
||
+ pad, sd->entity.name);
|
||
return -EALREADY;
|
||
}
|
||
|
||
/* Stop streaming when the last streams are disabled. */
|
||
- if (!(sd->enabled_streams & ~streams_mask)) {
|
||
+ if (!(sd->enabled_pads & ~BIT_ULL(pad))) {
|
||
ret = v4l2_subdev_call(sd, video, s_stream, 0);
|
||
if (ret)
|
||
return ret;
|
||
}
|
||
|
||
- sd->enabled_streams &= ~streams_mask;
|
||
+ sd->enabled_pads &= ~BIT_ULL(pad);
|
||
|
||
return 0;
|
||
}
|
||
@@ -2232,6 +2240,31 @@ void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
|
||
}
|
||
EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event);
|
||
|
||
+bool v4l2_subdev_is_streaming(struct v4l2_subdev *sd)
|
||
+{
|
||
+ struct v4l2_subdev_state *state;
|
||
+
|
||
+ if (!v4l2_subdev_has_op(sd, pad, enable_streams))
|
||
+ return sd->s_stream_enabled;
|
||
+
|
||
+ if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS))
|
||
+ return !!sd->enabled_pads;
|
||
+
|
||
+ state = v4l2_subdev_get_locked_active_state(sd);
|
||
+
|
||
+ for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {
|
||
+ const struct v4l2_subdev_stream_config *cfg;
|
||
+
|
||
+ cfg = &state->stream_configs.configs[i];
|
||
+
|
||
+ if (cfg->enabled)
|
||
+ return true;
|
||
+ }
|
||
+
|
||
+ return false;
|
||
+}
|
||
+EXPORT_SYMBOL_GPL(v4l2_subdev_is_streaming);
|
||
+
|
||
int v4l2_subdev_get_privacy_led(struct v4l2_subdev *sd)
|
||
{
|
||
#if IS_REACHABLE(CONFIG_LEDS_CLASS)
|
||
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
|
||
index 5b861dbff27e9a..6c24426104ba6f 100644
|
||
--- a/drivers/misc/lkdtm/perms.c
|
||
+++ b/drivers/misc/lkdtm/perms.c
|
||
@@ -28,6 +28,13 @@ static const unsigned long rodata = 0xAA55AA55;
|
||
/* This is marked __ro_after_init, so it should ultimately be .rodata. */
|
||
static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
|
||
|
||
+/*
|
||
+ * This is a pointer to do_nothing() which is initialized at runtime rather
|
||
+ * than build time to avoid objtool IBT validation warnings caused by an
|
||
+ * inlined unrolled memcpy() in execute_location().
|
||
+ */
|
||
+static void __ro_after_init *do_nothing_ptr;
|
||
+
|
||
/*
|
||
* This just returns to the caller. It is designed to be copied into
|
||
* non-executable memory regions.
|
||
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
|
||
{
|
||
void (*func)(void);
|
||
func_desc_t fdesc;
|
||
- void *do_nothing_text = dereference_function_descriptor(do_nothing);
|
||
|
||
- pr_info("attempting ok execution at %px\n", do_nothing_text);
|
||
+ pr_info("attempting ok execution at %px\n", do_nothing_ptr);
|
||
do_nothing();
|
||
|
||
if (write == CODE_WRITE) {
|
||
- memcpy(dst, do_nothing_text, EXEC_SIZE);
|
||
+ memcpy(dst, do_nothing_ptr, EXEC_SIZE);
|
||
flush_icache_range((unsigned long)dst,
|
||
(unsigned long)dst + EXEC_SIZE);
|
||
}
|
||
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
|
||
|
||
void __init lkdtm_perms_init(void)
|
||
{
|
||
+ do_nothing_ptr = dereference_function_descriptor(do_nothing);
|
||
+
|
||
/* Make sure we can write to __ro_after_init values during __init */
|
||
ro_after_init |= 0xAA;
|
||
}
|
||
diff --git a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c
|
||
index 3c1359d8d4e692..55b892f982e93e 100644
|
||
--- a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c
|
||
+++ b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c
|
||
@@ -37,6 +37,7 @@
|
||
struct pci1xxxx_gpio {
|
||
struct auxiliary_device *aux_dev;
|
||
void __iomem *reg_base;
|
||
+ raw_spinlock_t wa_lock;
|
||
struct gpio_chip gpio;
|
||
spinlock_t lock;
|
||
int irq_base;
|
||
@@ -164,7 +165,7 @@ static void pci1xxxx_gpio_irq_ack(struct irq_data *data)
|
||
unsigned long flags;
|
||
|
||
spin_lock_irqsave(&priv->lock, flags);
|
||
- pci1xxx_assign_bit(priv->reg_base, INTR_STAT_OFFSET(gpio), (gpio % 32), true);
|
||
+ writel(BIT(gpio % 32), priv->reg_base + INTR_STAT_OFFSET(gpio));
|
||
spin_unlock_irqrestore(&priv->lock, flags);
|
||
}
|
||
|
||
@@ -254,6 +255,7 @@ static irqreturn_t pci1xxxx_gpio_irq_handler(int irq, void *dev_id)
|
||
struct pci1xxxx_gpio *priv = dev_id;
|
||
struct gpio_chip *gc = &priv->gpio;
|
||
unsigned long int_status = 0;
|
||
+ unsigned long wa_flags;
|
||
unsigned long flags;
|
||
u8 pincount;
|
||
int bit;
|
||
@@ -277,7 +279,9 @@ static irqreturn_t pci1xxxx_gpio_irq_handler(int irq, void *dev_id)
|
||
writel(BIT(bit), priv->reg_base + INTR_STATUS_OFFSET(gpiobank));
|
||
spin_unlock_irqrestore(&priv->lock, flags);
|
||
irq = irq_find_mapping(gc->irq.domain, (bit + (gpiobank * 32)));
|
||
- handle_nested_irq(irq);
|
||
+ raw_spin_lock_irqsave(&priv->wa_lock, wa_flags);
|
||
+ generic_handle_irq(irq);
|
||
+ raw_spin_unlock_irqrestore(&priv->wa_lock, wa_flags);
|
||
}
|
||
}
|
||
spin_lock_irqsave(&priv->lock, flags);
|
||
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
|
||
index a4668ddd94551a..4adfa5af162f1d 100644
|
||
--- a/drivers/misc/mei/hw-me-regs.h
|
||
+++ b/drivers/misc/mei/hw-me-regs.h
|
||
@@ -117,6 +117,7 @@
|
||
|
||
#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
|
||
|
||
+#define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */
|
||
#define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */
|
||
|
||
/*
|
||
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
|
||
index 6826cc50d29f36..93b98a7f4c7fd9 100644
|
||
--- a/drivers/misc/mei/pci-me.c
|
||
+++ b/drivers/misc/mei/pci-me.c
|
||
@@ -124,6 +124,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
|
||
|
||
{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
|
||
|
||
+ {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)},
|
||
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)},
|
||
|
||
/* required last entry */
|
||
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
|
||
index 945d08531de376..82808cc373f68b 100644
|
||
--- a/drivers/mmc/host/sdhci-msm.c
|
||
+++ b/drivers/mmc/host/sdhci-msm.c
|
||
@@ -1866,7 +1866,7 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
|
||
if (!(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
|
||
return 0;
|
||
|
||
- ice = of_qcom_ice_get(dev);
|
||
+ ice = devm_of_qcom_ice_get(dev);
|
||
if (ice == ERR_PTR(-EOPNOTSUPP)) {
|
||
dev_warn(dev, "Disabling inline encryption support\n");
|
||
ice = NULL;
|
||
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
|
||
index 90ab2f1058ce0e..2d18a03d927421 100644
|
||
--- a/drivers/net/dsa/mt7530.c
|
||
+++ b/drivers/net/dsa/mt7530.c
|
||
@@ -2596,6 +2596,9 @@ mt7531_setup_common(struct dsa_switch *ds)
|
||
struct mt7530_priv *priv = ds->priv;
|
||
int ret, i;
|
||
|
||
+ ds->assisted_learning_on_cpu_port = true;
|
||
+ ds->mtu_enforcement_ingress = true;
|
||
+
|
||
mt753x_trap_frames(priv);
|
||
|
||
/* Enable and reset MIB counters */
|
||
@@ -2735,9 +2738,6 @@ mt7531_setup(struct dsa_switch *ds)
|
||
|
||
mt7531_setup_common(ds);
|
||
|
||
- ds->assisted_learning_on_cpu_port = true;
|
||
- ds->mtu_enforcement_ingress = true;
|
||
-
|
||
return 0;
|
||
}
|
||
|
||
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
||
index da7260e505a2e4..ef52d1ae27d694 100644
|
||
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||
@@ -5047,6 +5047,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||
.port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
|
||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||
+ .port_set_policy = mv88e6352_port_set_policy,
|
||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||
.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
|
||
.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
|
||
@@ -5071,8 +5072,10 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||
.reset = mv88e6352_g1_reset,
|
||
- .vtu_getnext = mv88e6185_g1_vtu_getnext,
|
||
- .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||
+ .stu_getnext = mv88e6352_g1_stu_getnext,
|
||
+ .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
|
||
.gpio_ops = &mv88e6352_gpio_ops,
|
||
.avb_ops = &mv88e6352_avb_ops,
|
||
.ptp_ops = &mv88e6352_ptp_ops,
|
||
@@ -5097,6 +5100,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||
.port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
|
||
.port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
|
||
.port_tag_remap = mv88e6095_port_tag_remap,
|
||
+ .port_set_policy = mv88e6352_port_set_policy,
|
||
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
|
||
.port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
|
||
.port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
|
||
@@ -5120,8 +5124,10 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||
.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
|
||
.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
|
||
.reset = mv88e6352_g1_reset,
|
||
- .vtu_getnext = mv88e6185_g1_vtu_getnext,
|
||
- .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||
+ .vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||
+ .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||
+ .stu_getnext = mv88e6352_g1_stu_getnext,
|
||
+ .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
|
||
.gpio_ops = &mv88e6352_gpio_ops,
|
||
.avb_ops = &mv88e6352_avb_ops,
|
||
.ptp_ops = &mv88e6352_ptp_ops,
|
||
@@ -5713,7 +5719,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||
.global1_addr = 0x1b,
|
||
.global2_addr = 0x1c,
|
||
.age_time_coeff = 3750,
|
||
- .atu_move_port_mask = 0x1f,
|
||
+ .atu_move_port_mask = 0xf,
|
||
.g1_irqs = 9,
|
||
.g2_irqs = 10,
|
||
.pvt = true,
|
||
@@ -6114,9 +6120,11 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||
.num_databases = 4096,
|
||
.num_macs = 8192,
|
||
.num_ports = 7,
|
||
- .num_internal_phys = 5,
|
||
+ .num_internal_phys = 2,
|
||
+ .internal_phys_offset = 3,
|
||
.num_gpio = 15,
|
||
.max_vid = 4095,
|
||
+ .max_sid = 63,
|
||
.port_base_addr = 0x10,
|
||
.phy_base_addr = 0x0,
|
||
.global1_addr = 0x1b,
|
||
@@ -6139,9 +6147,11 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||
.num_databases = 4096,
|
||
.num_macs = 8192,
|
||
.num_ports = 7,
|
||
- .num_internal_phys = 5,
|
||
+ .num_internal_phys = 2,
|
||
+ .internal_phys_offset = 3,
|
||
.num_gpio = 15,
|
||
.max_vid = 4095,
|
||
+ .max_sid = 63,
|
||
.port_base_addr = 0x10,
|
||
.phy_base_addr = 0x0,
|
||
.global1_addr = 0x1b,
|
||
@@ -6150,6 +6160,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||
.g1_irqs = 8,
|
||
.g2_irqs = 10,
|
||
.atu_move_port_mask = 0xf,
|
||
+ .pvt = true,
|
||
.multi_chip = true,
|
||
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
|
||
.ptp_support = true,
|
||
@@ -6172,7 +6183,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||
.global1_addr = 0x1b,
|
||
.global2_addr = 0x1c,
|
||
.age_time_coeff = 3750,
|
||
- .atu_move_port_mask = 0x1f,
|
||
+ .atu_move_port_mask = 0xf,
|
||
.g1_irqs = 9,
|
||
.g2_irqs = 10,
|
||
.pvt = true,
|
||
diff --git a/drivers/net/ethernet/amd/pds_core/adminq.c b/drivers/net/ethernet/amd/pds_core/adminq.c
|
||
index ea773cfa0af67b..733f133d69e75f 100644
|
||
--- a/drivers/net/ethernet/amd/pds_core/adminq.c
|
||
+++ b/drivers/net/ethernet/amd/pds_core/adminq.c
|
||
@@ -5,11 +5,6 @@
|
||
|
||
#include "core.h"
|
||
|
||
-struct pdsc_wait_context {
|
||
- struct pdsc_qcq *qcq;
|
||
- struct completion wait_completion;
|
||
-};
|
||
-
|
||
static int pdsc_process_notifyq(struct pdsc_qcq *qcq)
|
||
{
|
||
union pds_core_notifyq_comp *comp;
|
||
@@ -110,10 +105,10 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq)
|
||
q_info = &q->info[q->tail_idx];
|
||
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||
|
||
- /* Copy out the completion data */
|
||
- memcpy(q_info->dest, comp, sizeof(*comp));
|
||
-
|
||
- complete_all(&q_info->wc->wait_completion);
|
||
+ if (!completion_done(&q_info->completion)) {
|
||
+ memcpy(q_info->dest, comp, sizeof(*comp));
|
||
+ complete(&q_info->completion);
|
||
+ }
|
||
|
||
if (cq->tail_idx == cq->num_descs - 1)
|
||
cq->done_color = !cq->done_color;
|
||
@@ -166,8 +161,7 @@ irqreturn_t pdsc_adminq_isr(int irq, void *data)
|
||
static int __pdsc_adminq_post(struct pdsc *pdsc,
|
||
struct pdsc_qcq *qcq,
|
||
union pds_core_adminq_cmd *cmd,
|
||
- union pds_core_adminq_comp *comp,
|
||
- struct pdsc_wait_context *wc)
|
||
+ union pds_core_adminq_comp *comp)
|
||
{
|
||
struct pdsc_queue *q = &qcq->q;
|
||
struct pdsc_q_info *q_info;
|
||
@@ -209,9 +203,9 @@ static int __pdsc_adminq_post(struct pdsc *pdsc,
|
||
/* Post the request */
|
||
index = q->head_idx;
|
||
q_info = &q->info[index];
|
||
- q_info->wc = wc;
|
||
q_info->dest = comp;
|
||
memcpy(q_info->desc, cmd, sizeof(*cmd));
|
||
+ reinit_completion(&q_info->completion);
|
||
|
||
dev_dbg(pdsc->dev, "head_idx %d tail_idx %d\n",
|
||
q->head_idx, q->tail_idx);
|
||
@@ -235,16 +229,13 @@ int pdsc_adminq_post(struct pdsc *pdsc,
|
||
union pds_core_adminq_comp *comp,
|
||
bool fast_poll)
|
||
{
|
||
- struct pdsc_wait_context wc = {
|
||
- .wait_completion =
|
||
- COMPLETION_INITIALIZER_ONSTACK(wc.wait_completion),
|
||
- };
|
||
unsigned long poll_interval = 1;
|
||
unsigned long poll_jiffies;
|
||
unsigned long time_limit;
|
||
unsigned long time_start;
|
||
unsigned long time_done;
|
||
unsigned long remaining;
|
||
+ struct completion *wc;
|
||
int err = 0;
|
||
int index;
|
||
|
||
@@ -254,20 +245,19 @@ int pdsc_adminq_post(struct pdsc *pdsc,
|
||
return -ENXIO;
|
||
}
|
||
|
||
- wc.qcq = &pdsc->adminqcq;
|
||
- index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc);
|
||
+ index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp);
|
||
if (index < 0) {
|
||
err = index;
|
||
goto err_out;
|
||
}
|
||
|
||
+ wc = &pdsc->adminqcq.q.info[index].completion;
|
||
time_start = jiffies;
|
||
time_limit = time_start + HZ * pdsc->devcmd_timeout;
|
||
do {
|
||
/* Timeslice the actual wait to catch IO errors etc early */
|
||
poll_jiffies = msecs_to_jiffies(poll_interval);
|
||
- remaining = wait_for_completion_timeout(&wc.wait_completion,
|
||
- poll_jiffies);
|
||
+ remaining = wait_for_completion_timeout(wc, poll_jiffies);
|
||
if (remaining)
|
||
break;
|
||
|
||
@@ -296,9 +286,11 @@ int pdsc_adminq_post(struct pdsc *pdsc,
|
||
dev_dbg(pdsc->dev, "%s: elapsed %d msecs\n",
|
||
__func__, jiffies_to_msecs(time_done - time_start));
|
||
|
||
- /* Check the results */
|
||
- if (time_after_eq(time_done, time_limit))
|
||
+ /* Check the results and clear an un-completed timeout */
|
||
+ if (time_after_eq(time_done, time_limit) && !completion_done(wc)) {
|
||
err = -ETIMEDOUT;
|
||
+ complete(wc);
|
||
+ }
|
||
|
||
dev_dbg(pdsc->dev, "read admin queue completion idx %d:\n", index);
|
||
dynamic_hex_dump("comp ", DUMP_PREFIX_OFFSET, 16, 1,
|
||
diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c
|
||
index fd1a5149c00319..fb7a5403e630db 100644
|
||
--- a/drivers/net/ethernet/amd/pds_core/auxbus.c
|
||
+++ b/drivers/net/ethernet/amd/pds_core/auxbus.c
|
||
@@ -107,9 +107,6 @@ int pds_client_adminq_cmd(struct pds_auxiliary_dev *padev,
|
||
dev_dbg(pf->dev, "%s: %s opcode %d\n",
|
||
__func__, dev_name(&padev->aux_dev.dev), req->opcode);
|
||
|
||
- if (pf->state)
|
||
- return -ENXIO;
|
||
-
|
||
/* Wrap the client's request */
|
||
cmd.client_request.opcode = PDS_AQ_CMD_CLIENT_CMD;
|
||
cmd.client_request.client_id = cpu_to_le16(padev->client_id);
|
||
diff --git a/drivers/net/ethernet/amd/pds_core/core.c b/drivers/net/ethernet/amd/pds_core/core.c
|
||
index eb73c921dc1ed9..b3fa867c8ccd91 100644
|
||
--- a/drivers/net/ethernet/amd/pds_core/core.c
|
||
+++ b/drivers/net/ethernet/amd/pds_core/core.c
|
||
@@ -169,8 +169,10 @@ static void pdsc_q_map(struct pdsc_queue *q, void *base, dma_addr_t base_pa)
|
||
q->base = base;
|
||
q->base_pa = base_pa;
|
||
|
||
- for (i = 0, cur = q->info; i < q->num_descs; i++, cur++)
|
||
+ for (i = 0, cur = q->info; i < q->num_descs; i++, cur++) {
|
||
cur->desc = base + (i * q->desc_size);
|
||
+ init_completion(&cur->completion);
|
||
+ }
|
||
}
|
||
|
||
static void pdsc_cq_map(struct pdsc_cq *cq, void *base, dma_addr_t base_pa)
|
||
diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h
|
||
index f410f7d132056b..858bebf7977624 100644
|
||
--- a/drivers/net/ethernet/amd/pds_core/core.h
|
||
+++ b/drivers/net/ethernet/amd/pds_core/core.h
|
||
@@ -96,7 +96,7 @@ struct pdsc_q_info {
|
||
unsigned int bytes;
|
||
unsigned int nbufs;
|
||
struct pdsc_buf_info bufs[PDS_CORE_MAX_FRAGS];
|
||
- struct pdsc_wait_context *wc;
|
||
+ struct completion completion;
|
||
void *dest;
|
||
};
|
||
|
||
diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c
|
||
index 971d4278280d65..0032e8e3518117 100644
|
||
--- a/drivers/net/ethernet/amd/pds_core/devlink.c
|
||
+++ b/drivers/net/ethernet/amd/pds_core/devlink.c
|
||
@@ -101,7 +101,7 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||
.fw_control.opcode = PDS_CORE_CMD_FW_CONTROL,
|
||
.fw_control.oper = PDS_CORE_FW_GET_LIST,
|
||
};
|
||
- struct pds_core_fw_list_info fw_list;
|
||
+ struct pds_core_fw_list_info fw_list = {};
|
||
struct pdsc *pdsc = devlink_priv(dl);
|
||
union pds_core_dev_comp comp;
|
||
char buf[32];
|
||
@@ -114,8 +114,6 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||
if (!err)
|
||
memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list));
|
||
mutex_unlock(&pdsc->devcmd_lock);
|
||
- if (err && err != -EIO)
|
||
- return err;
|
||
|
||
listlen = min(fw_list.num_fw_slots, ARRAY_SIZE(fw_list.fw_names));
|
||
for (i = 0; i < listlen; i++) {
|
||
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||
index c201ea20e40476..dc89dbc13b251f 100644
|
||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||
@@ -3949,11 +3949,27 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
|
||
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
|
||
|
||
if (mtk_is_netsys_v3_or_greater(eth)) {
|
||
- /* PSE should not drop port1, port8 and port9 packets */
|
||
- mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
|
||
+ /* PSE dummy page mechanism */
|
||
+ mtk_w32(eth, PSE_DUMMY_WORK_GDM(1) | PSE_DUMMY_WORK_GDM(2) |
|
||
+ PSE_DUMMY_WORK_GDM(3) | DUMMY_PAGE_THR, PSE_DUMY_REQ);
|
||
+
|
||
+ /* PSE free buffer drop threshold */
|
||
+ mtk_w32(eth, 0x00600009, PSE_IQ_REV(8));
|
||
+
|
||
+ /* PSE should not drop port8, port9 and port13 packets from
|
||
+ * WDMA Tx
|
||
+ */
|
||
+ mtk_w32(eth, 0x00002300, PSE_DROP_CFG);
|
||
+
|
||
+ /* PSE should drop packets to port8, port9 and port13 on WDMA Rx
|
||
+ * ring full
|
||
+ */
|
||
+ mtk_w32(eth, 0x00002300, PSE_PPE_DROP(0));
|
||
+ mtk_w32(eth, 0x00002300, PSE_PPE_DROP(1));
|
||
+ mtk_w32(eth, 0x00002300, PSE_PPE_DROP(2));
|
||
|
||
/* GDM and CDM Threshold */
|
||
- mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
|
||
+ mtk_w32(eth, 0x08000707, MTK_CDMW0_THRES);
|
||
mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
|
||
|
||
/* Disable GDM1 RX CRC stripping */
|
||
@@ -3970,7 +3986,7 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
|
||
mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
|
||
|
||
/* PSE should drop packets to port 8/9 on WDMA Rx ring full */
|
||
- mtk_w32(eth, 0x00000300, PSE_PPE0_DROP);
|
||
+ mtk_w32(eth, 0x00000300, PSE_PPE_DROP(0));
|
||
|
||
/* PSE Free Queue Flow Control */
|
||
mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2);
|
||
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||
index 403219d987eff5..d1c7b5f1ee4a9c 100644
|
||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||
@@ -149,7 +149,15 @@
|
||
#define PSE_FQFC_CFG1 0x100
|
||
#define PSE_FQFC_CFG2 0x104
|
||
#define PSE_DROP_CFG 0x108
|
||
-#define PSE_PPE0_DROP 0x110
|
||
+#define PSE_PPE_DROP(x) (0x110 + ((x) * 0x4))
|
||
+
|
||
+/* PSE Last FreeQ Page Request Control */
|
||
+#define PSE_DUMY_REQ 0x10C
|
||
+/* PSE_DUMY_REQ is not a typo but actually called like that also in
|
||
+ * MediaTek's datasheet
|
||
+ */
|
||
+#define PSE_DUMMY_WORK_GDM(x) BIT(16 + (x))
|
||
+#define DUMMY_PAGE_THR 0x1
|
||
|
||
/* PSE Input Queue Reservation Register*/
|
||
#define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2))
|
||
diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c
|
||
index 0b88635f4fbca9..623607fd2cefd3 100644
|
||
--- a/drivers/net/phy/microchip.c
|
||
+++ b/drivers/net/phy/microchip.c
|
||
@@ -31,47 +31,6 @@ static int lan88xx_write_page(struct phy_device *phydev, int page)
|
||
return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page);
|
||
}
|
||
|
||
-static int lan88xx_phy_config_intr(struct phy_device *phydev)
|
||
-{
|
||
- int rc;
|
||
-
|
||
- if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
|
||
- /* unmask all source and clear them before enable */
|
||
- rc = phy_write(phydev, LAN88XX_INT_MASK, 0x7FFF);
|
||
- rc = phy_read(phydev, LAN88XX_INT_STS);
|
||
- rc = phy_write(phydev, LAN88XX_INT_MASK,
|
||
- LAN88XX_INT_MASK_MDINTPIN_EN_ |
|
||
- LAN88XX_INT_MASK_LINK_CHANGE_);
|
||
- } else {
|
||
- rc = phy_write(phydev, LAN88XX_INT_MASK, 0);
|
||
- if (rc)
|
||
- return rc;
|
||
-
|
||
- /* Ack interrupts after they have been disabled */
|
||
- rc = phy_read(phydev, LAN88XX_INT_STS);
|
||
- }
|
||
-
|
||
- return rc < 0 ? rc : 0;
|
||
-}
|
||
-
|
||
-static irqreturn_t lan88xx_handle_interrupt(struct phy_device *phydev)
|
||
-{
|
||
- int irq_status;
|
||
-
|
||
- irq_status = phy_read(phydev, LAN88XX_INT_STS);
|
||
- if (irq_status < 0) {
|
||
- phy_error(phydev);
|
||
- return IRQ_NONE;
|
||
- }
|
||
-
|
||
- if (!(irq_status & LAN88XX_INT_STS_LINK_CHANGE_))
|
||
- return IRQ_NONE;
|
||
-
|
||
- phy_trigger_machine(phydev);
|
||
-
|
||
- return IRQ_HANDLED;
|
||
-}
|
||
-
|
||
static int lan88xx_suspend(struct phy_device *phydev)
|
||
{
|
||
struct lan88xx_priv *priv = phydev->priv;
|
||
@@ -392,8 +351,9 @@ static struct phy_driver microchip_phy_driver[] = {
|
||
.config_aneg = lan88xx_config_aneg,
|
||
.link_change_notify = lan88xx_link_change_notify,
|
||
|
||
- .config_intr = lan88xx_phy_config_intr,
|
||
- .handle_interrupt = lan88xx_handle_interrupt,
|
||
+ /* Interrupt handling is broken, do not define related
|
||
+ * functions to force polling.
|
||
+ */
|
||
|
||
.suspend = lan88xx_suspend,
|
||
.resume = genphy_resume,
|
||
diff --git a/drivers/net/phy/phy_led_triggers.c b/drivers/net/phy/phy_led_triggers.c
|
||
index f550576eb9dae7..6f9d8da76c4dfb 100644
|
||
--- a/drivers/net/phy/phy_led_triggers.c
|
||
+++ b/drivers/net/phy/phy_led_triggers.c
|
||
@@ -91,9 +91,8 @@ int phy_led_triggers_register(struct phy_device *phy)
|
||
if (!phy->phy_num_led_triggers)
|
||
return 0;
|
||
|
||
- phy->led_link_trigger = devm_kzalloc(&phy->mdio.dev,
|
||
- sizeof(*phy->led_link_trigger),
|
||
- GFP_KERNEL);
|
||
+ phy->led_link_trigger = kzalloc(sizeof(*phy->led_link_trigger),
|
||
+ GFP_KERNEL);
|
||
if (!phy->led_link_trigger) {
|
||
err = -ENOMEM;
|
||
goto out_clear;
|
||
@@ -103,10 +102,9 @@ int phy_led_triggers_register(struct phy_device *phy)
|
||
if (err)
|
||
goto out_free_link;
|
||
|
||
- phy->phy_led_triggers = devm_kcalloc(&phy->mdio.dev,
|
||
- phy->phy_num_led_triggers,
|
||
- sizeof(struct phy_led_trigger),
|
||
- GFP_KERNEL);
|
||
+ phy->phy_led_triggers = kcalloc(phy->phy_num_led_triggers,
|
||
+ sizeof(struct phy_led_trigger),
|
||
+ GFP_KERNEL);
|
||
if (!phy->phy_led_triggers) {
|
||
err = -ENOMEM;
|
||
goto out_unreg_link;
|
||
@@ -127,11 +125,11 @@ int phy_led_triggers_register(struct phy_device *phy)
|
||
out_unreg:
|
||
while (i--)
|
||
phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
|
||
- devm_kfree(&phy->mdio.dev, phy->phy_led_triggers);
|
||
+ kfree(phy->phy_led_triggers);
|
||
out_unreg_link:
|
||
phy_led_trigger_unregister(phy->led_link_trigger);
|
||
out_free_link:
|
||
- devm_kfree(&phy->mdio.dev, phy->led_link_trigger);
|
||
+ kfree(phy->led_link_trigger);
|
||
phy->led_link_trigger = NULL;
|
||
out_clear:
|
||
phy->phy_num_led_triggers = 0;
|
||
@@ -145,8 +143,13 @@ void phy_led_triggers_unregister(struct phy_device *phy)
|
||
|
||
for (i = 0; i < phy->phy_num_led_triggers; i++)
|
||
phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
|
||
+ kfree(phy->phy_led_triggers);
|
||
+ phy->phy_led_triggers = NULL;
|
||
|
||
- if (phy->led_link_trigger)
|
||
+ if (phy->led_link_trigger) {
|
||
phy_led_trigger_unregister(phy->led_link_trigger);
|
||
+ kfree(phy->led_link_trigger);
|
||
+ phy->led_link_trigger = NULL;
|
||
+ }
|
||
}
|
||
EXPORT_SYMBOL_GPL(phy_led_triggers_unregister);
|
||
diff --git a/drivers/net/vmxnet3/vmxnet3_xdp.c b/drivers/net/vmxnet3/vmxnet3_xdp.c
|
||
index 616ecc38d1726c..5f470499e60024 100644
|
||
--- a/drivers/net/vmxnet3/vmxnet3_xdp.c
|
||
+++ b/drivers/net/vmxnet3/vmxnet3_xdp.c
|
||
@@ -397,7 +397,7 @@ vmxnet3_process_xdp(struct vmxnet3_adapter *adapter,
|
||
|
||
xdp_init_buff(&xdp, PAGE_SIZE, &rq->xdp_rxq);
|
||
xdp_prepare_buff(&xdp, page_address(page), rq->page_pool->p.offset,
|
||
- rbi->len, false);
|
||
+ rcd->len, false);
|
||
xdp_buff_clear_frags_flag(&xdp);
|
||
|
||
xdp_prog = rcu_dereference(rq->adapter->xdp_bpf_prog);
|
||
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
|
||
index bcb5651f18e0f5..0115f8f5b7245f 100644
|
||
--- a/drivers/net/xen-netfront.c
|
||
+++ b/drivers/net/xen-netfront.c
|
||
@@ -985,20 +985,27 @@ static u32 xennet_run_xdp(struct netfront_queue *queue, struct page *pdata,
|
||
act = bpf_prog_run_xdp(prog, xdp);
|
||
switch (act) {
|
||
case XDP_TX:
|
||
- get_page(pdata);
|
||
xdpf = xdp_convert_buff_to_frame(xdp);
|
||
+ if (unlikely(!xdpf)) {
|
||
+ trace_xdp_exception(queue->info->netdev, prog, act);
|
||
+ break;
|
||
+ }
|
||
+ get_page(pdata);
|
||
err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
|
||
- if (unlikely(!err))
|
||
+ if (unlikely(err <= 0)) {
|
||
+ if (err < 0)
|
||
+ trace_xdp_exception(queue->info->netdev, prog, act);
|
||
xdp_return_frame_rx_napi(xdpf);
|
||
- else if (unlikely(err < 0))
|
||
- trace_xdp_exception(queue->info->netdev, prog, act);
|
||
+ }
|
||
break;
|
||
case XDP_REDIRECT:
|
||
get_page(pdata);
|
||
err = xdp_do_redirect(queue->info->netdev, xdp, prog);
|
||
*need_xdp_flush = true;
|
||
- if (unlikely(err))
|
||
+ if (unlikely(err)) {
|
||
trace_xdp_exception(queue->info->netdev, prog, act);
|
||
+ xdp_return_buff(xdp);
|
||
+ }
|
||
break;
|
||
case XDP_PASS:
|
||
case XDP_DROP:
|
||
diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c
|
||
index d687e8c2cc78dc..63ceed89b62ef9 100644
|
||
--- a/drivers/ntb/hw/amd/ntb_hw_amd.c
|
||
+++ b/drivers/ntb/hw/amd/ntb_hw_amd.c
|
||
@@ -1318,6 +1318,7 @@ static const struct pci_device_id amd_ntb_pci_tbl[] = {
|
||
{ PCI_VDEVICE(AMD, 0x148b), (kernel_ulong_t)&dev_data[1] },
|
||
{ PCI_VDEVICE(AMD, 0x14c0), (kernel_ulong_t)&dev_data[1] },
|
||
{ PCI_VDEVICE(AMD, 0x14c3), (kernel_ulong_t)&dev_data[1] },
|
||
+ { PCI_VDEVICE(AMD, 0x155a), (kernel_ulong_t)&dev_data[1] },
|
||
{ PCI_VDEVICE(HYGON, 0x145b), (kernel_ulong_t)&dev_data[0] },
|
||
{ 0, }
|
||
};
|
||
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c
|
||
index 48823b53ede3e9..22aaa60d2d3846 100644
|
||
--- a/drivers/ntb/hw/idt/ntb_hw_idt.c
|
||
+++ b/drivers/ntb/hw/idt/ntb_hw_idt.c
|
||
@@ -1041,7 +1041,7 @@ static inline char *idt_get_mw_name(enum idt_mw_type mw_type)
|
||
static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
|
||
unsigned char *mw_cnt)
|
||
{
|
||
- struct idt_mw_cfg mws[IDT_MAX_NR_MWS], *ret_mws;
|
||
+ struct idt_mw_cfg *mws;
|
||
const struct idt_ntb_bar *bars;
|
||
enum idt_mw_type mw_type;
|
||
unsigned char widx, bidx, en_cnt;
|
||
@@ -1049,6 +1049,11 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
|
||
int aprt_size;
|
||
u32 data;
|
||
|
||
+ mws = devm_kcalloc(&ndev->ntb.pdev->dev, IDT_MAX_NR_MWS,
|
||
+ sizeof(*mws), GFP_KERNEL);
|
||
+ if (!mws)
|
||
+ return ERR_PTR(-ENOMEM);
|
||
+
|
||
/* Retrieve the array of the BARs registers */
|
||
bars = portdata_tbl[port].bars;
|
||
|
||
@@ -1103,16 +1108,7 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port,
|
||
}
|
||
}
|
||
|
||
- /* Allocate memory for memory window descriptors */
|
||
- ret_mws = devm_kcalloc(&ndev->ntb.pdev->dev, *mw_cnt, sizeof(*ret_mws),
|
||
- GFP_KERNEL);
|
||
- if (!ret_mws)
|
||
- return ERR_PTR(-ENOMEM);
|
||
-
|
||
- /* Copy the info of detected memory windows */
|
||
- memcpy(ret_mws, mws, (*mw_cnt)*sizeof(*ret_mws));
|
||
-
|
||
- return ret_mws;
|
||
+ return mws;
|
||
}
|
||
|
||
/*
|
||
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
|
||
index f00665ad0c11a3..c6b0637e61debd 100644
|
||
--- a/drivers/nvme/host/core.c
|
||
+++ b/drivers/nvme/host/core.c
|
||
@@ -3972,6 +3972,15 @@ static void nvme_scan_work(struct work_struct *work)
|
||
nvme_scan_ns_sequential(ctrl);
|
||
}
|
||
mutex_unlock(&ctrl->scan_lock);
|
||
+
|
||
+ /* Requeue if we have missed AENs */
|
||
+ if (test_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events))
|
||
+ nvme_queue_scan(ctrl);
|
||
+#ifdef CONFIG_NVME_MULTIPATH
|
||
+ else if (ctrl->ana_log_buf)
|
||
+ /* Re-read the ANA log page to not miss updates */
|
||
+ queue_work(nvme_wq, &ctrl->ana_work);
|
||
+#endif
|
||
}
|
||
|
||
/*
|
||
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
|
||
index 32283301199f01..119afdfe4b91e9 100644
|
||
--- a/drivers/nvme/host/multipath.c
|
||
+++ b/drivers/nvme/host/multipath.c
|
||
@@ -426,7 +426,7 @@ static bool nvme_available_path(struct nvme_ns_head *head)
|
||
struct nvme_ns *ns;
|
||
|
||
if (!test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags))
|
||
- return NULL;
|
||
+ return false;
|
||
|
||
list_for_each_entry_srcu(ns, &head->list, siblings,
|
||
srcu_read_lock_held(&head->srcu)) {
|
||
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
|
||
index d40d5a4ea932e0..570c58d2b5a585 100644
|
||
--- a/drivers/nvme/target/fc.c
|
||
+++ b/drivers/nvme/target/fc.c
|
||
@@ -1030,33 +1030,24 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
|
||
struct nvmet_fc_hostport *newhost, *match = NULL;
|
||
unsigned long flags;
|
||
|
||
+ /*
|
||
+ * Caller holds a reference on tgtport.
|
||
+ */
|
||
+
|
||
/* if LLDD not implemented, leave as NULL */
|
||
if (!hosthandle)
|
||
return NULL;
|
||
|
||
- /*
|
||
- * take reference for what will be the newly allocated hostport if
|
||
- * we end up using a new allocation
|
||
- */
|
||
- if (!nvmet_fc_tgtport_get(tgtport))
|
||
- return ERR_PTR(-EINVAL);
|
||
-
|
||
spin_lock_irqsave(&tgtport->lock, flags);
|
||
match = nvmet_fc_match_hostport(tgtport, hosthandle);
|
||
spin_unlock_irqrestore(&tgtport->lock, flags);
|
||
|
||
- if (match) {
|
||
- /* no new allocation - release reference */
|
||
- nvmet_fc_tgtport_put(tgtport);
|
||
+ if (match)
|
||
return match;
|
||
- }
|
||
|
||
newhost = kzalloc(sizeof(*newhost), GFP_KERNEL);
|
||
- if (!newhost) {
|
||
- /* no new allocation - release reference */
|
||
- nvmet_fc_tgtport_put(tgtport);
|
||
+ if (!newhost)
|
||
return ERR_PTR(-ENOMEM);
|
||
- }
|
||
|
||
spin_lock_irqsave(&tgtport->lock, flags);
|
||
match = nvmet_fc_match_hostport(tgtport, hosthandle);
|
||
@@ -1065,6 +1056,7 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
|
||
kfree(newhost);
|
||
newhost = match;
|
||
} else {
|
||
+ nvmet_fc_tgtport_get(tgtport);
|
||
newhost->tgtport = tgtport;
|
||
newhost->hosthandle = hosthandle;
|
||
INIT_LIST_HEAD(&newhost->host_list);
|
||
@@ -1099,7 +1091,8 @@ static void
|
||
nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc)
|
||
{
|
||
nvmet_fc_tgtport_get(assoc->tgtport);
|
||
- queue_work(nvmet_wq, &assoc->del_work);
|
||
+ if (!queue_work(nvmet_wq, &assoc->del_work))
|
||
+ nvmet_fc_tgtport_put(assoc->tgtport);
|
||
}
|
||
|
||
static struct nvmet_fc_tgt_assoc *
|
||
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
|
||
index b278ab4338ceb5..d5c1b2a126a560 100644
|
||
--- a/drivers/of/resolver.c
|
||
+++ b/drivers/of/resolver.c
|
||
@@ -262,25 +262,22 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
|
||
*/
|
||
int of_resolve_phandles(struct device_node *overlay)
|
||
{
|
||
- struct device_node *child, *local_fixups, *refnode;
|
||
- struct device_node *tree_symbols, *overlay_fixups;
|
||
+ struct device_node *child, *refnode;
|
||
+ struct device_node *overlay_fixups;
|
||
+ struct device_node __free(device_node) *local_fixups = NULL;
|
||
struct property *prop;
|
||
const char *refpath;
|
||
phandle phandle, phandle_delta;
|
||
int err;
|
||
|
||
- tree_symbols = NULL;
|
||
-
|
||
if (!overlay) {
|
||
pr_err("null overlay\n");
|
||
- err = -EINVAL;
|
||
- goto out;
|
||
+ return -EINVAL;
|
||
}
|
||
|
||
if (!of_node_check_flag(overlay, OF_DETACHED)) {
|
||
pr_err("overlay not detached\n");
|
||
- err = -EINVAL;
|
||
- goto out;
|
||
+ return -EINVAL;
|
||
}
|
||
|
||
phandle_delta = live_tree_max_phandle() + 1;
|
||
@@ -292,7 +289,7 @@ int of_resolve_phandles(struct device_node *overlay)
|
||
|
||
err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta);
|
||
if (err)
|
||
- goto out;
|
||
+ return err;
|
||
|
||
overlay_fixups = NULL;
|
||
|
||
@@ -301,16 +298,13 @@ int of_resolve_phandles(struct device_node *overlay)
|
||
overlay_fixups = child;
|
||
}
|
||
|
||
- if (!overlay_fixups) {
|
||
- err = 0;
|
||
- goto out;
|
||
- }
|
||
+ if (!overlay_fixups)
|
||
+ return 0;
|
||
|
||
- tree_symbols = of_find_node_by_path("/__symbols__");
|
||
+ struct device_node __free(device_node) *tree_symbols = of_find_node_by_path("/__symbols__");
|
||
if (!tree_symbols) {
|
||
pr_err("no symbols in root of device tree.\n");
|
||
- err = -EINVAL;
|
||
- goto out;
|
||
+ return -EINVAL;
|
||
}
|
||
|
||
for_each_property_of_node(overlay_fixups, prop) {
|
||
@@ -324,14 +318,12 @@ int of_resolve_phandles(struct device_node *overlay)
|
||
if (err) {
|
||
pr_err("node label '%s' not found in live devicetree symbols table\n",
|
||
prop->name);
|
||
- goto out;
|
||
+ return err;
|
||
}
|
||
|
||
refnode = of_find_node_by_path(refpath);
|
||
- if (!refnode) {
|
||
- err = -ENOENT;
|
||
- goto out;
|
||
- }
|
||
+ if (!refnode)
|
||
+ return -ENOENT;
|
||
|
||
phandle = refnode->phandle;
|
||
of_node_put(refnode);
|
||
@@ -341,11 +333,8 @@ int of_resolve_phandles(struct device_node *overlay)
|
||
break;
|
||
}
|
||
|
||
-out:
|
||
if (err)
|
||
pr_err("overlay phandle fixup failed: %d\n", err);
|
||
- of_node_put(tree_symbols);
|
||
-
|
||
return err;
|
||
}
|
||
EXPORT_SYMBOL_GPL(of_resolve_phandles);
|
||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
|
||
index 8e5d818c29a983..b7cec139d816ba 100644
|
||
--- a/drivers/pci/probe.c
|
||
+++ b/drivers/pci/probe.c
|
||
@@ -885,6 +885,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
||
resource_size_t offset, next_offset;
|
||
LIST_HEAD(resources);
|
||
struct resource *res, *next_res;
|
||
+ bool bus_registered = false;
|
||
char addr[64], *fmt;
|
||
const char *name;
|
||
int err;
|
||
@@ -948,6 +949,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
||
name = dev_name(&bus->dev);
|
||
|
||
err = device_register(&bus->dev);
|
||
+ bus_registered = true;
|
||
if (err)
|
||
goto unregister;
|
||
|
||
@@ -1031,12 +1033,15 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
|
||
unregister:
|
||
put_device(&bridge->dev);
|
||
device_del(&bridge->dev);
|
||
-
|
||
free:
|
||
#ifdef CONFIG_PCI_DOMAINS_GENERIC
|
||
pci_bus_release_domain_nr(bus, parent);
|
||
#endif
|
||
- kfree(bus);
|
||
+ if (bus_registered)
|
||
+ put_device(&bus->dev);
|
||
+ else
|
||
+ kfree(bus);
|
||
+
|
||
return err;
|
||
}
|
||
|
||
diff --git a/drivers/pinctrl/renesas/pinctrl-rza2.c b/drivers/pinctrl/renesas/pinctrl-rza2.c
|
||
index c5d733216508e8..df660b7e1300ca 100644
|
||
--- a/drivers/pinctrl/renesas/pinctrl-rza2.c
|
||
+++ b/drivers/pinctrl/renesas/pinctrl-rza2.c
|
||
@@ -243,6 +243,9 @@ static int rza2_gpio_register(struct rza2_pinctrl_priv *priv)
|
||
int ret;
|
||
|
||
chip.label = devm_kasprintf(priv->dev, GFP_KERNEL, "%pOFn", np);
|
||
+ if (!chip.label)
|
||
+ return -ENOMEM;
|
||
+
|
||
chip.parent = priv->dev;
|
||
chip.ngpio = priv->npins;
|
||
|
||
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
|
||
index 374d80dc6d17ab..bec22a001a5dd5 100644
|
||
--- a/drivers/regulator/rk808-regulator.c
|
||
+++ b/drivers/regulator/rk808-regulator.c
|
||
@@ -267,8 +267,8 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
|
||
|
||
static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
|
||
{
|
||
- int rid = rdev_get_id(rdev);
|
||
- int ctr_bit, reg;
|
||
+ unsigned int rid = rdev_get_id(rdev);
|
||
+ unsigned int ctr_bit, reg;
|
||
|
||
reg = RK806_POWER_FPWM_EN0 + rid / 8;
|
||
ctr_bit = rid % 8;
|
||
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
|
||
index 905986c616559b..73848f764559b4 100644
|
||
--- a/drivers/rtc/rtc-pcf85063.c
|
||
+++ b/drivers/rtc/rtc-pcf85063.c
|
||
@@ -35,6 +35,7 @@
|
||
#define PCF85063_REG_CTRL1_CAP_SEL BIT(0)
|
||
#define PCF85063_REG_CTRL1_STOP BIT(5)
|
||
#define PCF85063_REG_CTRL1_EXT_TEST BIT(7)
|
||
+#define PCF85063_REG_CTRL1_SWR 0x58
|
||
|
||
#define PCF85063_REG_CTRL2 0x01
|
||
#define PCF85063_CTRL2_AF BIT(6)
|
||
@@ -589,7 +590,7 @@ static int pcf85063_probe(struct i2c_client *client)
|
||
|
||
i2c_set_clientdata(client, pcf85063);
|
||
|
||
- err = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL1, &tmp);
|
||
+ err = regmap_read(pcf85063->regmap, PCF85063_REG_SC, &tmp);
|
||
if (err) {
|
||
dev_err(&client->dev, "RTC chip is not present\n");
|
||
return err;
|
||
@@ -599,6 +600,22 @@ static int pcf85063_probe(struct i2c_client *client)
|
||
if (IS_ERR(pcf85063->rtc))
|
||
return PTR_ERR(pcf85063->rtc);
|
||
|
||
+ /*
|
||
+ * If a Power loss is detected, SW reset the device.
|
||
+ * From PCF85063A datasheet:
|
||
+ * There is a low probability that some devices will have corruption
|
||
+ * of the registers after the automatic power-on reset...
|
||
+ */
|
||
+ if (tmp & PCF85063_REG_SC_OS) {
|
||
+ dev_warn(&client->dev,
|
||
+ "POR issue detected, sending a SW reset\n");
|
||
+ err = regmap_write(pcf85063->regmap, PCF85063_REG_CTRL1,
|
||
+ PCF85063_REG_CTRL1_SWR);
|
||
+ if (err < 0)
|
||
+ dev_warn(&client->dev,
|
||
+ "SW reset failed, trying to continue\n");
|
||
+ }
|
||
+
|
||
err = pcf85063_load_capacitance(pcf85063, client->dev.of_node,
|
||
config->force_cap_7000 ? 7000 : 0);
|
||
if (err < 0)
|
||
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
|
||
index e5d947c763ea5d..6a030ba38bf360 100644
|
||
--- a/drivers/s390/char/sclp_con.c
|
||
+++ b/drivers/s390/char/sclp_con.c
|
||
@@ -263,6 +263,19 @@ static struct console sclp_console =
|
||
.index = 0 /* ttyS0 */
|
||
};
|
||
|
||
+/*
|
||
+ * Release allocated pages.
|
||
+ */
|
||
+static void __init __sclp_console_free_pages(void)
|
||
+{
|
||
+ struct list_head *page, *p;
|
||
+
|
||
+ list_for_each_safe(page, p, &sclp_con_pages) {
|
||
+ list_del(page);
|
||
+ free_page((unsigned long)page);
|
||
+ }
|
||
+}
|
||
+
|
||
/*
|
||
* called by console_init() in drivers/char/tty_io.c at boot-time.
|
||
*/
|
||
@@ -282,6 +295,10 @@ sclp_console_init(void)
|
||
/* Allocate pages for output buffering */
|
||
for (i = 0; i < sclp_console_pages; i++) {
|
||
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||
+ if (!page) {
|
||
+ __sclp_console_free_pages();
|
||
+ return -ENOMEM;
|
||
+ }
|
||
list_add_tail(page, &sclp_con_pages);
|
||
}
|
||
sclp_conbuf = NULL;
|
||
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
|
||
index 892c18d2f87e90..d3edacb6ee148b 100644
|
||
--- a/drivers/s390/char/sclp_tty.c
|
||
+++ b/drivers/s390/char/sclp_tty.c
|
||
@@ -490,6 +490,17 @@ static const struct tty_operations sclp_ops = {
|
||
.flush_buffer = sclp_tty_flush_buffer,
|
||
};
|
||
|
||
+/* Release allocated pages. */
|
||
+static void __init __sclp_tty_free_pages(void)
|
||
+{
|
||
+ struct list_head *page, *p;
|
||
+
|
||
+ list_for_each_safe(page, p, &sclp_tty_pages) {
|
||
+ list_del(page);
|
||
+ free_page((unsigned long)page);
|
||
+ }
|
||
+}
|
||
+
|
||
static int __init
|
||
sclp_tty_init(void)
|
||
{
|
||
@@ -516,6 +527,7 @@ sclp_tty_init(void)
|
||
for (i = 0; i < MAX_KMEM_PAGES; i++) {
|
||
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||
if (page == NULL) {
|
||
+ __sclp_tty_free_pages();
|
||
tty_driver_kref_put(driver);
|
||
return -ENOMEM;
|
||
}
|
||
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
|
||
index f78c5f8a49ffac..7e64661d215bd2 100644
|
||
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
|
||
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
|
||
@@ -911,8 +911,28 @@ static void hisi_sas_phyup_work_common(struct work_struct *work,
|
||
container_of(work, typeof(*phy), works[event]);
|
||
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||
+ struct asd_sas_port *sas_port = sas_phy->port;
|
||
+ struct hisi_sas_port *port = phy->port;
|
||
+ struct device *dev = hisi_hba->dev;
|
||
+ struct domain_device *port_dev;
|
||
int phy_no = sas_phy->id;
|
||
|
||
+ if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags) &&
|
||
+ sas_port && port && (port->id != phy->port_id)) {
|
||
+ dev_info(dev, "phy%d's hw port id changed from %d to %llu\n",
|
||
+ phy_no, port->id, phy->port_id);
|
||
+ port_dev = sas_port->port_dev;
|
||
+ if (port_dev && !dev_is_expander(port_dev->dev_type)) {
|
||
+ /*
|
||
+ * Set the device state to gone to block
|
||
+ * sending IO to the device.
|
||
+ */
|
||
+ set_bit(SAS_DEV_GONE, &port_dev->state);
|
||
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
|
||
+ return;
|
||
+ }
|
||
+ }
|
||
+
|
||
phy->wait_phyup_cnt = 0;
|
||
if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP)
|
||
hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
|
||
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
|
||
index ee2da8e49d4cfb..a9d6dac4133466 100644
|
||
--- a/drivers/scsi/pm8001/pm8001_sas.c
|
||
+++ b/drivers/scsi/pm8001/pm8001_sas.c
|
||
@@ -719,6 +719,7 @@ static void pm8001_dev_gone_notify(struct domain_device *dev)
|
||
spin_lock_irqsave(&pm8001_ha->lock, flags);
|
||
}
|
||
PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id);
|
||
+ pm8001_ha->phy[pm8001_dev->attached_phy].phy_attached = 0;
|
||
pm8001_free_dev(pm8001_dev);
|
||
} else {
|
||
pm8001_dbg(pm8001_ha, DISC, "Found dev has gone.\n");
|
||
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
|
||
index 22bdce0bc32792..9c0142a010bac1 100644
|
||
--- a/drivers/scsi/scsi.c
|
||
+++ b/drivers/scsi/scsi.c
|
||
@@ -693,26 +693,23 @@ void scsi_cdl_check(struct scsi_device *sdev)
|
||
*/
|
||
int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
|
||
{
|
||
- struct scsi_mode_data data;
|
||
- struct scsi_sense_hdr sshdr;
|
||
- struct scsi_vpd *vpd;
|
||
- bool is_ata = false;
|
||
char buf[64];
|
||
+ bool is_ata;
|
||
int ret;
|
||
|
||
if (!sdev->cdl_supported)
|
||
return -EOPNOTSUPP;
|
||
|
||
rcu_read_lock();
|
||
- vpd = rcu_dereference(sdev->vpd_pg89);
|
||
- if (vpd)
|
||
- is_ata = true;
|
||
+ is_ata = rcu_dereference(sdev->vpd_pg89);
|
||
rcu_read_unlock();
|
||
|
||
/*
|
||
* For ATA devices, CDL needs to be enabled with a SET FEATURES command.
|
||
*/
|
||
if (is_ata) {
|
||
+ struct scsi_mode_data data;
|
||
+ struct scsi_sense_hdr sshdr;
|
||
char *buf_data;
|
||
int len;
|
||
|
||
@@ -721,16 +718,30 @@ int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
|
||
if (ret)
|
||
return -EINVAL;
|
||
|
||
- /* Enable CDL using the ATA feature page */
|
||
+ /* Enable or disable CDL using the ATA feature page */
|
||
len = min_t(size_t, sizeof(buf),
|
||
data.length - data.header_length -
|
||
data.block_descriptor_length);
|
||
buf_data = buf + data.header_length +
|
||
data.block_descriptor_length;
|
||
- if (enable)
|
||
- buf_data[4] = 0x02;
|
||
- else
|
||
- buf_data[4] = 0;
|
||
+
|
||
+ /*
|
||
+ * If we want to enable CDL and CDL is already enabled on the
|
||
+ * device, do nothing. This avoids needlessly resetting the CDL
|
||
+ * statistics on the device as that is implied by the CDL enable
|
||
+ * action. Similar to this, there is no need to do anything if
|
||
+ * we want to disable CDL and CDL is already disabled.
|
||
+ */
|
||
+ if (enable) {
|
||
+ if ((buf_data[4] & 0x03) == 0x02)
|
||
+ goto out;
|
||
+ buf_data[4] &= ~0x03;
|
||
+ buf_data[4] |= 0x02;
|
||
+ } else {
|
||
+ if ((buf_data[4] & 0x03) == 0x00)
|
||
+ goto out;
|
||
+ buf_data[4] &= ~0x03;
|
||
+ }
|
||
|
||
ret = scsi_mode_select(sdev, 1, 0, buf_data, len, 5 * HZ, 3,
|
||
&data, &sshdr);
|
||
@@ -742,6 +753,7 @@ int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
|
||
}
|
||
}
|
||
|
||
+out:
|
||
sdev->cdl_enable = enable;
|
||
|
||
return 0;
|
||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
|
||
index e6dc2c556fde9e..bd75e3ebc14da3 100644
|
||
--- a/drivers/scsi/scsi_lib.c
|
||
+++ b/drivers/scsi/scsi_lib.c
|
||
@@ -1152,8 +1152,12 @@ EXPORT_SYMBOL_GPL(scsi_alloc_request);
|
||
*/
|
||
static void scsi_cleanup_rq(struct request *rq)
|
||
{
|
||
+ struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
|
||
+
|
||
+ cmd->flags = 0;
|
||
+
|
||
if (rq->rq_flags & RQF_DONTPREP) {
|
||
- scsi_mq_uninit_cmd(blk_mq_rq_to_pdu(rq));
|
||
+ scsi_mq_uninit_cmd(cmd);
|
||
rq->rq_flags &= ~RQF_DONTPREP;
|
||
}
|
||
}
|
||
diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c
|
||
index fbab7fe5c652b9..d6e205e3812a96 100644
|
||
--- a/drivers/soc/qcom/ice.c
|
||
+++ b/drivers/soc/qcom/ice.c
|
||
@@ -10,6 +10,7 @@
|
||
#include <linux/bitfield.h>
|
||
#include <linux/clk.h>
|
||
#include <linux/delay.h>
|
||
+#include <linux/device.h>
|
||
#include <linux/iopoll.h>
|
||
#include <linux/of.h>
|
||
#include <linux/of_platform.h>
|
||
@@ -328,6 +329,53 @@ struct qcom_ice *of_qcom_ice_get(struct device *dev)
|
||
}
|
||
EXPORT_SYMBOL_GPL(of_qcom_ice_get);
|
||
|
||
+static void qcom_ice_put(const struct qcom_ice *ice)
|
||
+{
|
||
+ struct platform_device *pdev = to_platform_device(ice->dev);
|
||
+
|
||
+ if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "ice"))
|
||
+ platform_device_put(pdev);
|
||
+}
|
||
+
|
||
+static void devm_of_qcom_ice_put(struct device *dev, void *res)
|
||
+{
|
||
+ qcom_ice_put(*(struct qcom_ice **)res);
|
||
+}
|
||
+
|
||
+/**
|
||
+ * devm_of_qcom_ice_get() - Devres managed helper to get an ICE instance from
|
||
+ * a DT node.
|
||
+ * @dev: device pointer for the consumer device.
|
||
+ *
|
||
+ * This function will provide an ICE instance either by creating one for the
|
||
+ * consumer device if its DT node provides the 'ice' reg range and the 'ice'
|
||
+ * clock (for legacy DT style). On the other hand, if consumer provides a
|
||
+ * phandle via 'qcom,ice' property to an ICE DT, the ICE instance will already
|
||
+ * be created and so this function will return that instead.
|
||
+ *
|
||
+ * Return: ICE pointer on success, NULL if there is no ICE data provided by the
|
||
+ * consumer or ERR_PTR() on error.
|
||
+ */
|
||
+struct qcom_ice *devm_of_qcom_ice_get(struct device *dev)
|
||
+{
|
||
+ struct qcom_ice *ice, **dr;
|
||
+
|
||
+ dr = devres_alloc(devm_of_qcom_ice_put, sizeof(*dr), GFP_KERNEL);
|
||
+ if (!dr)
|
||
+ return ERR_PTR(-ENOMEM);
|
||
+
|
||
+ ice = of_qcom_ice_get(dev);
|
||
+ if (!IS_ERR_OR_NULL(ice)) {
|
||
+ *dr = ice;
|
||
+ devres_add(dev, dr);
|
||
+ } else {
|
||
+ devres_free(dr);
|
||
+ }
|
||
+
|
||
+ return ice;
|
||
+}
|
||
+EXPORT_SYMBOL_GPL(devm_of_qcom_ice_get);
|
||
+
|
||
static int qcom_ice_probe(struct platform_device *pdev)
|
||
{
|
||
struct qcom_ice *engine;
|
||
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
|
||
index daa32bde615561..da4442954375b1 100644
|
||
--- a/drivers/spi/spi-imx.c
|
||
+++ b/drivers/spi/spi-imx.c
|
||
@@ -1614,10 +1614,13 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
|
||
struct spi_device *spi,
|
||
struct spi_transfer *transfer)
|
||
{
|
||
+ int ret;
|
||
struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
|
||
unsigned long hz_per_byte, byte_limit;
|
||
|
||
- spi_imx_setupxfer(spi, transfer);
|
||
+ ret = spi_imx_setupxfer(spi, transfer);
|
||
+ if (ret < 0)
|
||
+ return ret;
|
||
transfer->effective_speed_hz = spi_imx->spi_bus_clk;
|
||
|
||
/* flush rxfifo before transfer */
|
||
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
|
||
index d1afa4140e8a26..e3c236025a7b3b 100644
|
||
--- a/drivers/spi/spi-tegra210-quad.c
|
||
+++ b/drivers/spi/spi-tegra210-quad.c
|
||
@@ -1117,9 +1117,9 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
|
||
(&tqspi->xfer_completion,
|
||
QSPI_DMA_TIMEOUT);
|
||
|
||
- if (WARN_ON(ret == 0)) {
|
||
- dev_err(tqspi->dev, "QSPI Transfer failed with timeout: %d\n",
|
||
- ret);
|
||
+ if (WARN_ON_ONCE(ret == 0)) {
|
||
+ dev_err_ratelimited(tqspi->dev,
|
||
+ "QSPI Transfer failed with timeout\n");
|
||
if (tqspi->is_curr_dma_xfer &&
|
||
(tqspi->cur_direction & DATA_DIR_TX))
|
||
dmaengine_terminate_all
|
||
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
|
||
index 7c3310a2b28a41..b92a8a5b2e8c97 100644
|
||
--- a/drivers/thunderbolt/tb.c
|
||
+++ b/drivers/thunderbolt/tb.c
|
||
@@ -1370,11 +1370,15 @@ static void tb_scan_port(struct tb_port *port)
|
||
goto out_rpm_put;
|
||
}
|
||
|
||
- tb_retimer_scan(port, true);
|
||
-
|
||
sw = tb_switch_alloc(port->sw->tb, &port->sw->dev,
|
||
tb_downstream_route(port));
|
||
if (IS_ERR(sw)) {
|
||
+ /*
|
||
+ * Make the downstream retimers available even if there
|
||
+ * is no router connected.
|
||
+ */
|
||
+ tb_retimer_scan(port, true);
|
||
+
|
||
/*
|
||
* If there is an error accessing the connected switch
|
||
* it may be connected to another domain. Also we allow
|
||
@@ -1424,6 +1428,14 @@ static void tb_scan_port(struct tb_port *port)
|
||
upstream_port = tb_upstream_port(sw);
|
||
tb_configure_link(port, upstream_port, sw);
|
||
|
||
+ /*
|
||
+ * Scan for downstream retimers. We only scan them after the
|
||
+ * router has been enumerated to avoid issues with certain
|
||
+ * Pluggable devices that expect the host to enumerate them
|
||
+ * within certain timeout.
|
||
+ */
|
||
+ tb_retimer_scan(port, true);
|
||
+
|
||
/*
|
||
* CL0s and CL1 are enabled and supported together.
|
||
* Silently ignore CLx enabling in case CLx is not supported.
|
||
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
|
||
index 90953e679e386a..76b6429fb9e92e 100644
|
||
--- a/drivers/tty/serial/msm_serial.c
|
||
+++ b/drivers/tty/serial/msm_serial.c
|
||
@@ -1741,6 +1741,12 @@ msm_serial_early_console_setup_dm(struct earlycon_device *device,
|
||
if (!device->port.membase)
|
||
return -ENODEV;
|
||
|
||
+ /* Disable DM / single-character modes */
|
||
+ msm_write(&device->port, 0, UARTDM_DMEN);
|
||
+ msm_write(&device->port, MSM_UART_CR_CMD_RESET_RX, MSM_UART_CR);
|
||
+ msm_write(&device->port, MSM_UART_CR_CMD_RESET_TX, MSM_UART_CR);
|
||
+ msm_write(&device->port, MSM_UART_CR_TX_ENABLE, MSM_UART_CR);
|
||
+
|
||
device->con->write = msm_serial_early_write_dm;
|
||
return 0;
|
||
}
|
||
diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c
|
||
index d195c5de52e78f..e86b00873d0ea6 100644
|
||
--- a/drivers/tty/serial/sifive.c
|
||
+++ b/drivers/tty/serial/sifive.c
|
||
@@ -562,8 +562,11 @@ static void sifive_serial_break_ctl(struct uart_port *port, int break_state)
|
||
static int sifive_serial_startup(struct uart_port *port)
|
||
{
|
||
struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
|
||
+ unsigned long flags;
|
||
|
||
+ uart_port_lock_irqsave(&ssp->port, &flags);
|
||
__ssp_enable_rxwm(ssp);
|
||
+ uart_port_unlock_irqrestore(&ssp->port, flags);
|
||
|
||
return 0;
|
||
}
|
||
@@ -571,9 +574,12 @@ static int sifive_serial_startup(struct uart_port *port)
|
||
static void sifive_serial_shutdown(struct uart_port *port)
|
||
{
|
||
struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
|
||
+ unsigned long flags;
|
||
|
||
+ uart_port_lock_irqsave(&ssp->port, &flags);
|
||
__ssp_disable_rxwm(ssp);
|
||
__ssp_disable_txwm(ssp);
|
||
+ uart_port_unlock_irqrestore(&ssp->port, flags);
|
||
}
|
||
|
||
/**
|
||
diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c
|
||
index da8c1734d33358..411109a5ebbffd 100644
|
||
--- a/drivers/ufs/core/ufs-mcq.c
|
||
+++ b/drivers/ufs/core/ufs-mcq.c
|
||
@@ -632,13 +632,6 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
|
||
unsigned long flags;
|
||
int err;
|
||
|
||
- if (!ufshcd_cmd_inflight(lrbp->cmd)) {
|
||
- dev_err(hba->dev,
|
||
- "%s: skip abort. cmd at tag %d already completed.\n",
|
||
- __func__, tag);
|
||
- return FAILED;
|
||
- }
|
||
-
|
||
/* Skip task abort in case previous aborts failed and report failure */
|
||
if (lrbp->req_abort_skip) {
|
||
dev_err(hba->dev, "%s: skip abort. tag %d failed earlier\n",
|
||
@@ -647,6 +640,11 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
|
||
}
|
||
|
||
hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd));
|
||
+ if (!hwq) {
|
||
+ dev_err(hba->dev, "%s: skip abort. cmd at tag %d already completed.\n",
|
||
+ __func__, tag);
|
||
+ return FAILED;
|
||
+ }
|
||
|
||
if (ufshcd_mcq_sqe_search(hba, hwq, tag)) {
|
||
/*
|
||
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
|
||
index d138b66d5e350b..f61126189876e9 100644
|
||
--- a/drivers/ufs/host/ufs-exynos.c
|
||
+++ b/drivers/ufs/host/ufs-exynos.c
|
||
@@ -990,9 +990,14 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba)
|
||
exynos_ufs_config_intr(ufs, DFES_DEF_L4_ERRS, UNIPRO_L4);
|
||
exynos_ufs_set_unipro_pclk_div(ufs);
|
||
|
||
+ exynos_ufs_setup_clocks(hba, true, PRE_CHANGE);
|
||
+
|
||
/* unipro */
|
||
exynos_ufs_config_unipro(ufs);
|
||
|
||
+ if (ufs->drv_data->pre_link)
|
||
+ ufs->drv_data->pre_link(ufs);
|
||
+
|
||
/* m-phy */
|
||
exynos_ufs_phy_init(ufs);
|
||
if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR)) {
|
||
@@ -1000,11 +1005,6 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba)
|
||
exynos_ufs_config_phy_cap_attr(ufs);
|
||
}
|
||
|
||
- exynos_ufs_setup_clocks(hba, true, PRE_CHANGE);
|
||
-
|
||
- if (ufs->drv_data->pre_link)
|
||
- ufs->drv_data->pre_link(ufs);
|
||
-
|
||
return 0;
|
||
}
|
||
|
||
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
|
||
index 51ed40529f9a7b..c6417ef074a478 100644
|
||
--- a/drivers/ufs/host/ufs-qcom.c
|
||
+++ b/drivers/ufs/host/ufs-qcom.c
|
||
@@ -121,7 +121,7 @@ static int ufs_qcom_ice_init(struct ufs_qcom_host *host)
|
||
struct device *dev = hba->dev;
|
||
struct qcom_ice *ice;
|
||
|
||
- ice = of_qcom_ice_get(dev);
|
||
+ ice = devm_of_qcom_ice_get(dev);
|
||
if (ice == ERR_PTR(-EOPNOTSUPP)) {
|
||
dev_warn(dev, "Disabling inline encryption support\n");
|
||
ice = NULL;
|
||
diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c
|
||
index b1b46c7c63f8b3..05e8414c31df4c 100644
|
||
--- a/drivers/usb/cdns3/cdns3-gadget.c
|
||
+++ b/drivers/usb/cdns3/cdns3-gadget.c
|
||
@@ -1962,6 +1962,7 @@ static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
|
||
unsigned int bit;
|
||
unsigned long reg;
|
||
|
||
+ local_bh_disable();
|
||
spin_lock_irqsave(&priv_dev->lock, flags);
|
||
|
||
reg = readl(&priv_dev->regs->usb_ists);
|
||
@@ -2003,6 +2004,7 @@ static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
|
||
irqend:
|
||
writel(~0, &priv_dev->regs->ep_ien);
|
||
spin_unlock_irqrestore(&priv_dev->lock, flags);
|
||
+ local_bh_enable();
|
||
|
||
return ret;
|
||
}
|
||
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
|
||
index b3cbca361a9696..73d5b9466676c4 100644
|
||
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
|
||
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
|
||
@@ -328,6 +328,13 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
|
||
return ret;
|
||
}
|
||
|
||
+static void ci_hdrc_imx_disable_regulator(void *arg)
|
||
+{
|
||
+ struct ci_hdrc_imx_data *data = arg;
|
||
+
|
||
+ regulator_disable(data->hsic_pad_regulator);
|
||
+}
|
||
+
|
||
static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||
{
|
||
struct ci_hdrc_imx_data *data;
|
||
@@ -386,6 +393,13 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||
"Failed to enable HSIC pad regulator\n");
|
||
goto err_put;
|
||
}
|
||
+ ret = devm_add_action_or_reset(dev,
|
||
+ ci_hdrc_imx_disable_regulator, data);
|
||
+ if (ret) {
|
||
+ dev_err(dev,
|
||
+ "Failed to add regulator devm action\n");
|
||
+ goto err_put;
|
||
+ }
|
||
}
|
||
}
|
||
|
||
@@ -424,11 +438,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||
|
||
ret = imx_get_clks(dev);
|
||
if (ret)
|
||
- goto disable_hsic_regulator;
|
||
+ goto qos_remove_request;
|
||
|
||
ret = imx_prepare_enable_clks(dev);
|
||
if (ret)
|
||
- goto disable_hsic_regulator;
|
||
+ goto qos_remove_request;
|
||
|
||
data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
|
||
if (IS_ERR(data->phy)) {
|
||
@@ -458,7 +472,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||
of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
|
||
pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
|
||
data->override_phy_control = true;
|
||
- usb_phy_init(pdata.usb_phy);
|
||
+ ret = usb_phy_init(pdata.usb_phy);
|
||
+ if (ret) {
|
||
+ dev_err(dev, "Failed to init phy\n");
|
||
+ goto err_clk;
|
||
+ }
|
||
}
|
||
|
||
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
|
||
@@ -467,7 +485,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||
ret = imx_usbmisc_init(data->usbmisc_data);
|
||
if (ret) {
|
||
dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
|
||
- goto err_clk;
|
||
+ goto phy_shutdown;
|
||
}
|
||
|
||
data->ci_pdev = ci_hdrc_add_device(dev,
|
||
@@ -476,7 +494,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||
if (IS_ERR(data->ci_pdev)) {
|
||
ret = PTR_ERR(data->ci_pdev);
|
||
dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
|
||
- goto err_clk;
|
||
+ goto phy_shutdown;
|
||
}
|
||
|
||
if (data->usbmisc_data) {
|
||
@@ -510,17 +528,18 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||
|
||
disable_device:
|
||
ci_hdrc_remove_device(data->ci_pdev);
|
||
+phy_shutdown:
|
||
+ if (data->override_phy_control)
|
||
+ usb_phy_shutdown(data->phy);
|
||
err_clk:
|
||
imx_disable_unprepare_clks(dev);
|
||
-disable_hsic_regulator:
|
||
- if (data->hsic_pad_regulator)
|
||
- /* don't overwrite original ret (cf. EPROBE_DEFER) */
|
||
- regulator_disable(data->hsic_pad_regulator);
|
||
+qos_remove_request:
|
||
if (pdata.flags & CI_HDRC_PMQOS)
|
||
cpu_latency_qos_remove_request(&data->pm_qos_req);
|
||
data->ci_pdev = NULL;
|
||
err_put:
|
||
- put_device(data->usbmisc_data->dev);
|
||
+ if (data->usbmisc_data)
|
||
+ put_device(data->usbmisc_data->dev);
|
||
return ret;
|
||
}
|
||
|
||
@@ -541,10 +560,9 @@ static void ci_hdrc_imx_remove(struct platform_device *pdev)
|
||
imx_disable_unprepare_clks(&pdev->dev);
|
||
if (data->plat_data->flags & CI_HDRC_PMQOS)
|
||
cpu_latency_qos_remove_request(&data->pm_qos_req);
|
||
- if (data->hsic_pad_regulator)
|
||
- regulator_disable(data->hsic_pad_regulator);
|
||
}
|
||
- put_device(data->usbmisc_data->dev);
|
||
+ if (data->usbmisc_data)
|
||
+ put_device(data->usbmisc_data->dev);
|
||
}
|
||
|
||
static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
|
||
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
|
||
index 6830be4419e20a..559c121f092300 100644
|
||
--- a/drivers/usb/class/cdc-wdm.c
|
||
+++ b/drivers/usb/class/cdc-wdm.c
|
||
@@ -726,7 +726,7 @@ static int wdm_open(struct inode *inode, struct file *file)
|
||
rv = -EBUSY;
|
||
goto out;
|
||
}
|
||
-
|
||
+ smp_rmb(); /* ordered against wdm_wwan_port_stop() */
|
||
rv = usb_autopm_get_interface(desc->intf);
|
||
if (rv < 0) {
|
||
dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
|
||
@@ -829,6 +829,7 @@ static struct usb_class_driver wdm_class = {
|
||
static int wdm_wwan_port_start(struct wwan_port *port)
|
||
{
|
||
struct wdm_device *desc = wwan_port_get_drvdata(port);
|
||
+ int rv;
|
||
|
||
/* The interface is both exposed via the WWAN framework and as a
|
||
* legacy usbmisc chardev. If chardev is already open, just fail
|
||
@@ -848,7 +849,15 @@ static int wdm_wwan_port_start(struct wwan_port *port)
|
||
wwan_port_txon(port);
|
||
|
||
/* Start getting events */
|
||
- return usb_submit_urb(desc->validity, GFP_KERNEL);
|
||
+ rv = usb_submit_urb(desc->validity, GFP_KERNEL);
|
||
+ if (rv < 0) {
|
||
+ wwan_port_txoff(port);
|
||
+ desc->manage_power(desc->intf, 0);
|
||
+ /* this must be last lest we race with chardev open */
|
||
+ clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
||
+ }
|
||
+
|
||
+ return rv;
|
||
}
|
||
|
||
static void wdm_wwan_port_stop(struct wwan_port *port)
|
||
@@ -859,8 +868,10 @@ static void wdm_wwan_port_stop(struct wwan_port *port)
|
||
poison_urbs(desc);
|
||
desc->manage_power(desc->intf, 0);
|
||
clear_bit(WDM_READ, &desc->flags);
|
||
- clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
||
unpoison_urbs(desc);
|
||
+ smp_wmb(); /* ordered against wdm_open() */
|
||
+ /* this must be last lest we open a poisoned device */
|
||
+ clear_bit(WDM_WWAN_IN_USE, &desc->flags);
|
||
}
|
||
|
||
static void wdm_wwan_port_tx_complete(struct urb *urb)
|
||
@@ -868,7 +879,7 @@ static void wdm_wwan_port_tx_complete(struct urb *urb)
|
||
struct sk_buff *skb = urb->context;
|
||
struct wdm_device *desc = skb_shinfo(skb)->destructor_arg;
|
||
|
||
- usb_autopm_put_interface(desc->intf);
|
||
+ usb_autopm_put_interface_async(desc->intf);
|
||
wwan_port_txon(desc->wwanp);
|
||
kfree_skb(skb);
|
||
}
|
||
@@ -898,7 +909,7 @@ static int wdm_wwan_port_tx(struct wwan_port *port, struct sk_buff *skb)
|
||
req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
|
||
req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
|
||
req->wValue = 0;
|
||
- req->wIndex = desc->inum;
|
||
+ req->wIndex = desc->inum; /* already converted */
|
||
req->wLength = cpu_to_le16(skb->len);
|
||
|
||
skb_shinfo(skb)->destructor_arg = desc;
|
||
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
|
||
index 6926bd639ec6ff..4903c733d37ae7 100644
|
||
--- a/drivers/usb/core/quirks.c
|
||
+++ b/drivers/usb/core/quirks.c
|
||
@@ -369,6 +369,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||
{ USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
|
||
{ USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
|
||
|
||
+ /* SanDisk Corp. SanDisk 3.2Gen1 */
|
||
+ { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },
|
||
+
|
||
/* Realforce 87U Keyboard */
|
||
{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
|
||
|
||
@@ -383,6 +386,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||
{ USB_DEVICE(0x0904, 0x6103), .driver_info =
|
||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||
|
||
+ /* Silicon Motion Flash Drive */
|
||
+ { USB_DEVICE(0x090c, 0x1000), .driver_info = USB_QUIRK_DELAY_INIT },
|
||
+
|
||
/* Sound Devices USBPre2 */
|
||
{ USB_DEVICE(0x0926, 0x0202), .driver_info =
|
||
USB_QUIRK_ENDPOINT_IGNORE },
|
||
@@ -536,6 +542,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
|
||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||
|
||
+ /* VLI disk */
|
||
+ { USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM },
|
||
+
|
||
/* Raydium Touchscreen */
|
||
{ USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
|
||
|
||
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
|
||
index 052852f8014676..54a4ee2b90b7f4 100644
|
||
--- a/drivers/usb/dwc3/dwc3-pci.c
|
||
+++ b/drivers/usb/dwc3/dwc3-pci.c
|
||
@@ -148,11 +148,21 @@ static const struct property_entry dwc3_pci_intel_byt_properties[] = {
|
||
{}
|
||
};
|
||
|
||
+/*
|
||
+ * Intel Merrifield SoC uses these endpoints for tracing and they cannot
|
||
+ * be re-allocated if being used because the side band flow control signals
|
||
+ * are hard wired to certain endpoints:
|
||
+ * - 1 High BW Bulk IN (IN#1) (RTIT)
|
||
+ * - 1 1KB BW Bulk IN (IN#8) + 1 1KB BW Bulk OUT (Run Control) (OUT#8)
|
||
+ */
|
||
+static const u8 dwc3_pci_mrfld_reserved_endpoints[] = { 3, 16, 17 };
|
||
+
|
||
static const struct property_entry dwc3_pci_mrfld_properties[] = {
|
||
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
|
||
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
|
||
PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
|
||
PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
|
||
+ PROPERTY_ENTRY_U8_ARRAY("snps,reserved-endpoints", dwc3_pci_mrfld_reserved_endpoints),
|
||
PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"),
|
||
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
|
||
{}
|
||
diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
|
||
index d19a5d2d65adb9..ae30aa50a58257 100644
|
||
--- a/drivers/usb/dwc3/dwc3-xilinx.c
|
||
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
|
||
@@ -207,15 +207,13 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
|
||
|
||
skip_usb3_phy:
|
||
/* ulpi reset via gpio-modepin or gpio-framework driver */
|
||
- reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
||
+ reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||
if (IS_ERR(reset_gpio)) {
|
||
return dev_err_probe(dev, PTR_ERR(reset_gpio),
|
||
"Failed to request reset GPIO\n");
|
||
}
|
||
|
||
if (reset_gpio) {
|
||
- /* Toggle ulpi to reset the phy. */
|
||
- gpiod_set_value_cansleep(reset_gpio, 1);
|
||
usleep_range(5000, 10000);
|
||
gpiod_set_value_cansleep(reset_gpio, 0);
|
||
usleep_range(5000, 10000);
|
||
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
|
||
index fdaace1564f96f..f51d743bb3ecc6 100644
|
||
--- a/drivers/usb/dwc3/gadget.c
|
||
+++ b/drivers/usb/dwc3/gadget.c
|
||
@@ -548,6 +548,7 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep)
|
||
int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
|
||
{
|
||
struct dwc3_gadget_ep_cmd_params params;
|
||
+ struct dwc3_ep *dep;
|
||
u32 cmd;
|
||
int i;
|
||
int ret;
|
||
@@ -564,8 +565,13 @@ int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
|
||
return ret;
|
||
|
||
/* Reset resource allocation flags */
|
||
- for (i = resource_index; i < dwc->num_eps && dwc->eps[i]; i++)
|
||
- dwc->eps[i]->flags &= ~DWC3_EP_RESOURCE_ALLOCATED;
|
||
+ for (i = resource_index; i < dwc->num_eps; i++) {
|
||
+ dep = dwc->eps[i];
|
||
+ if (!dep)
|
||
+ continue;
|
||
+
|
||
+ dep->flags &= ~DWC3_EP_RESOURCE_ALLOCATED;
|
||
+ }
|
||
|
||
return 0;
|
||
}
|
||
@@ -752,9 +758,11 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
|
||
|
||
dwc->last_fifo_depth = fifo_depth;
|
||
/* Clear existing TXFIFO for all IN eps except ep0 */
|
||
- for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM);
|
||
- num += 2) {
|
||
+ for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); num += 2) {
|
||
dep = dwc->eps[num];
|
||
+ if (!dep)
|
||
+ continue;
|
||
+
|
||
/* Don't change TXFRAMNUM on usb31 version */
|
||
size = DWC3_IP_IS(DWC3) ? 0 :
|
||
dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) &
|
||
@@ -3670,6 +3678,8 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
|
||
|
||
for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
|
||
dep = dwc->eps[i];
|
||
+ if (!dep)
|
||
+ continue;
|
||
|
||
if (!(dep->flags & DWC3_EP_ENABLED))
|
||
continue;
|
||
@@ -3858,6 +3868,10 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
|
||
u8 epnum = event->endpoint_number;
|
||
|
||
dep = dwc->eps[epnum];
|
||
+ if (!dep) {
|
||
+ dev_warn(dwc->dev, "spurious event, endpoint %u is not allocated\n", epnum);
|
||
+ return;
|
||
+ }
|
||
|
||
if (!(dep->flags & DWC3_EP_ENABLED)) {
|
||
if ((epnum > 1) && !(dep->flags & DWC3_EP_TRANSFER_STARTED))
|
||
@@ -4570,6 +4584,12 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
|
||
if (!count)
|
||
return IRQ_NONE;
|
||
|
||
+ if (count > evt->length) {
|
||
+ dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n",
|
||
+ count, evt->length);
|
||
+ return IRQ_NONE;
|
||
+ }
|
||
+
|
||
evt->count = count;
|
||
evt->flags |= DWC3_EVENT_PENDING;
|
||
|
||
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
|
||
index 573109ca5b7990..a09f72772e6e95 100644
|
||
--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
|
||
+++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
|
||
@@ -548,6 +548,9 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
|
||
d->vhub = vhub;
|
||
d->index = idx;
|
||
d->name = devm_kasprintf(parent, GFP_KERNEL, "port%d", idx+1);
|
||
+ if (!d->name)
|
||
+ return -ENOMEM;
|
||
+
|
||
d->regs = vhub->regs + 0x100 + 0x10 * idx;
|
||
|
||
ast_vhub_init_ep0(vhub, &d->ep0, d);
|
||
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
|
||
index a219260ad3e6c2..cc1f579f02de1c 100644
|
||
--- a/drivers/usb/host/max3421-hcd.c
|
||
+++ b/drivers/usb/host/max3421-hcd.c
|
||
@@ -1946,6 +1946,12 @@ max3421_remove(struct spi_device *spi)
|
||
usb_put_hcd(hcd);
|
||
}
|
||
|
||
+static const struct spi_device_id max3421_spi_ids[] = {
|
||
+ { "max3421" },
|
||
+ { },
|
||
+};
|
||
+MODULE_DEVICE_TABLE(spi, max3421_spi_ids);
|
||
+
|
||
static const struct of_device_id max3421_of_match_table[] = {
|
||
{ .compatible = "maxim,max3421", },
|
||
{},
|
||
@@ -1955,6 +1961,7 @@ MODULE_DEVICE_TABLE(of, max3421_of_match_table);
|
||
static struct spi_driver max3421_driver = {
|
||
.probe = max3421_probe,
|
||
.remove = max3421_remove,
|
||
+ .id_table = max3421_spi_ids,
|
||
.driver = {
|
||
.name = "max3421-hcd",
|
||
.of_match_table = max3421_of_match_table,
|
||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
|
||
index 900ea0d368e034..9f0a6b27e47cb6 100644
|
||
--- a/drivers/usb/host/ohci-pci.c
|
||
+++ b/drivers/usb/host/ohci-pci.c
|
||
@@ -165,6 +165,25 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
|
||
return 0;
|
||
}
|
||
|
||
+static int ohci_quirk_loongson(struct usb_hcd *hcd)
|
||
+{
|
||
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||
+
|
||
+ /*
|
||
+ * Loongson's LS7A OHCI controller (rev 0x02) has a
|
||
+ * flaw. MMIO register with offset 0x60/64 is treated
|
||
+ * as legacy PS2-compatible keyboard/mouse interface.
|
||
+ * Since OHCI only use 4KB BAR resource, LS7A OHCI's
|
||
+ * 32KB BAR is wrapped around (the 2nd 4KB BAR space
|
||
+ * is the same as the 1st 4KB internally). So add 4KB
|
||
+ * offset (0x1000) to the OHCI registers as a quirk.
|
||
+ */
|
||
+ if (pdev->revision == 0x2)
|
||
+ hcd->regs += SZ_4K; /* SZ_4K = 0x1000 */
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
static int ohci_quirk_qemu(struct usb_hcd *hcd)
|
||
{
|
||
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||
@@ -224,6 +243,10 @@ static const struct pci_device_id ohci_pci_quirks[] = {
|
||
PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
|
||
.driver_data = (unsigned long)ohci_quirk_amd700,
|
||
},
|
||
+ {
|
||
+ PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, 0x7a24),
|
||
+ .driver_data = (unsigned long)ohci_quirk_loongson,
|
||
+ },
|
||
{
|
||
.vendor = PCI_VENDOR_ID_APPLE,
|
||
.device = 0x003f,
|
||
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
|
||
index 87f1597a0e5ab7..257e4d79971fda 100644
|
||
--- a/drivers/usb/host/xhci-mvebu.c
|
||
+++ b/drivers/usb/host/xhci-mvebu.c
|
||
@@ -73,13 +73,3 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
|
||
|
||
return 0;
|
||
}
|
||
-
|
||
-int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
|
||
-{
|
||
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||
-
|
||
- /* Without reset on resume, the HC won't work at all */
|
||
- xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||
-
|
||
- return 0;
|
||
-}
|
||
diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h
|
||
index 3be021793cc8b0..9d26e22c48422f 100644
|
||
--- a/drivers/usb/host/xhci-mvebu.h
|
||
+++ b/drivers/usb/host/xhci-mvebu.h
|
||
@@ -12,16 +12,10 @@ struct usb_hcd;
|
||
|
||
#if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
|
||
int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
|
||
-int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd);
|
||
#else
|
||
static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
|
||
{
|
||
return 0;
|
||
}
|
||
-
|
||
-static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
|
||
-{
|
||
- return 0;
|
||
-}
|
||
#endif
|
||
#endif /* __LINUX_XHCI_MVEBU_H */
|
||
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
|
||
index d68e9abcdc69a6..8832e0cedadaff 100644
|
||
--- a/drivers/usb/host/xhci-plat.c
|
||
+++ b/drivers/usb/host/xhci-plat.c
|
||
@@ -106,7 +106,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = {
|
||
};
|
||
|
||
static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
|
||
- .init_quirk = xhci_mvebu_a3700_init_quirk,
|
||
+ .quirks = XHCI_RESET_ON_RESUME,
|
||
};
|
||
|
||
static const struct xhci_plat_priv xhci_plat_brcm = {
|
||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
|
||
index 4a081685a1953e..cb944396294516 100644
|
||
--- a/drivers/usb/host/xhci-ring.c
|
||
+++ b/drivers/usb/host/xhci-ring.c
|
||
@@ -1214,16 +1214,19 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
|
||
* Stopped state, but it will soon change to Running.
|
||
*
|
||
* Assume this bug on unexpected Stop Endpoint failures.
|
||
- * Keep retrying until the EP starts and stops again, on
|
||
- * chips where this is known to help. Wait for 100ms.
|
||
+ * Keep retrying until the EP starts and stops again.
|
||
*/
|
||
- if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
|
||
- break;
|
||
fallthrough;
|
||
case EP_STATE_RUNNING:
|
||
/* Race, HW handled stop ep cmd before ep was running */
|
||
xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n",
|
||
GET_EP_CTX_STATE(ep_ctx));
|
||
+ /*
|
||
+ * Don't retry forever if we guessed wrong or a defective HC never starts
|
||
+ * the EP or says 'Running' but fails the command. We must give back TDs.
|
||
+ */
|
||
+ if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
|
||
+ break;
|
||
|
||
command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
|
||
if (!command) {
|
||
@@ -3876,7 +3879,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
||
* enqueue a No Op TRB, this can prevent the Setup and Data Stage
|
||
* TRB to be breaked by the Link TRB.
|
||
*/
|
||
- if (trb_is_link(ep_ring->enqueue + 1)) {
|
||
+ if (last_trb_on_seg(ep_ring->enq_seg, ep_ring->enqueue + 1)) {
|
||
field = TRB_TYPE(TRB_TR_NOOP) | ep_ring->cycle_state;
|
||
queue_trb(xhci, ep_ring, false, 0, 0,
|
||
TRB_INTR_TARGET(0), field);
|
||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
||
index b8e2bfd4282809..b583b31ea5e72e 100644
|
||
--- a/drivers/usb/serial/ftdi_sio.c
|
||
+++ b/drivers/usb/serial/ftdi_sio.c
|
||
@@ -1093,6 +1093,8 @@ static const struct usb_device_id id_table_combined[] = {
|
||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 1) },
|
||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 2) },
|
||
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) },
|
||
+ /* Abacus Electrics */
|
||
+ { USB_DEVICE(FTDI_VID, ABACUS_OPTICAL_PROBE_PID) },
|
||
{ } /* Terminating entry */
|
||
};
|
||
|
||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
|
||
index 52be47d684ea66..9acb6f83732763 100644
|
||
--- a/drivers/usb/serial/ftdi_sio_ids.h
|
||
+++ b/drivers/usb/serial/ftdi_sio_ids.h
|
||
@@ -442,6 +442,11 @@
|
||
#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */
|
||
#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */
|
||
|
||
+/*
|
||
+ * Abacus Electrics
|
||
+ */
|
||
+#define ABACUS_OPTICAL_PROBE_PID 0xf458 /* ABACUS ELECTRICS Optical Probe */
|
||
+
|
||
/*
|
||
* Oceanic product ids
|
||
*/
|
||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
||
index a9f95bb35bb0f5..5d669511609892 100644
|
||
--- a/drivers/usb/serial/option.c
|
||
+++ b/drivers/usb/serial/option.c
|
||
@@ -611,6 +611,7 @@ static void option_instat_callback(struct urb *urb);
|
||
/* Sierra Wireless products */
|
||
#define SIERRA_VENDOR_ID 0x1199
|
||
#define SIERRA_PRODUCT_EM9191 0x90d3
|
||
+#define SIERRA_PRODUCT_EM9291 0x90e3
|
||
|
||
/* UNISOC (Spreadtrum) products */
|
||
#define UNISOC_VENDOR_ID 0x1782
|
||
@@ -2432,6 +2433,8 @@ static const struct usb_device_id option_ids[] = {
|
||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
|
||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
|
||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
|
||
+ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x30) },
|
||
+ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x40) },
|
||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
||
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
|
||
diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c
|
||
index 24b8772a345e2f..bac5ab6377ae4b 100644
|
||
--- a/drivers/usb/serial/usb-serial-simple.c
|
||
+++ b/drivers/usb/serial/usb-serial-simple.c
|
||
@@ -101,6 +101,11 @@ DEVICE(nokia, NOKIA_IDS);
|
||
{ USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */
|
||
DEVICE_N(novatel_gps, NOVATEL_IDS, 3);
|
||
|
||
+/* OWON electronic test and measurement equipment driver */
|
||
+#define OWON_IDS() \
|
||
+ { USB_DEVICE(0x5345, 0x1234) } /* HDS200 oscilloscopes and others */
|
||
+DEVICE(owon, OWON_IDS);
|
||
+
|
||
/* Siemens USB/MPI adapter */
|
||
#define SIEMENS_IDS() \
|
||
{ USB_DEVICE(0x908, 0x0004) }
|
||
@@ -135,6 +140,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
|
||
&motorola_tetra_device,
|
||
&nokia_device,
|
||
&novatel_gps_device,
|
||
+ &owon_device,
|
||
&siemens_mpi_device,
|
||
&suunto_device,
|
||
&vivopay_device,
|
||
@@ -154,6 +160,7 @@ static const struct usb_device_id id_table[] = {
|
||
MOTOROLA_TETRA_IDS(),
|
||
NOKIA_IDS(),
|
||
NOVATEL_IDS(),
|
||
+ OWON_IDS(),
|
||
SIEMENS_IDS(),
|
||
SUUNTO_IDS(),
|
||
VIVOPAY_IDS(),
|
||
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
|
||
index 1f8c9b16a0fb85..d460d71b425783 100644
|
||
--- a/drivers/usb/storage/unusual_uas.h
|
||
+++ b/drivers/usb/storage/unusual_uas.h
|
||
@@ -83,6 +83,13 @@ UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999,
|
||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||
US_FL_NO_REPORT_LUNS),
|
||
|
||
+/* Reported-by: Oliver Neukum <oneukum@suse.com> */
|
||
+UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160,
|
||
+ "ADATA",
|
||
+ "Portable HDD CH94",
|
||
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||
+ US_FL_NO_ATA_1X),
|
||
+
|
||
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
|
||
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
|
||
"Initio Corporation",
|
||
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
|
||
index d43153fec18ea8..af5c214b220699 100644
|
||
--- a/drivers/xen/Kconfig
|
||
+++ b/drivers/xen/Kconfig
|
||
@@ -278,7 +278,7 @@ config XEN_PRIVCMD_IRQFD
|
||
|
||
config XEN_ACPI_PROCESSOR
|
||
tristate "Xen ACPI processor"
|
||
- depends on XEN && XEN_PV_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ
|
||
+ depends on XEN && XEN_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ
|
||
default m
|
||
help
|
||
This ACPI processor uploads Power Management information to the Xen
|
||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
|
||
index 68092b64e29eac..e794606e7c780b 100644
|
||
--- a/fs/btrfs/file.c
|
||
+++ b/fs/btrfs/file.c
|
||
@@ -2225,15 +2225,20 @@ static void btrfs_punch_hole_lock_range(struct inode *inode,
|
||
* will always return true.
|
||
* So here we need to do extra page alignment for
|
||
* filemap_range_has_page().
|
||
+ *
|
||
+ * And do not decrease page_lockend right now, as it can be 0.
|
||
*/
|
||
const u64 page_lockstart = round_up(lockstart, PAGE_SIZE);
|
||
- const u64 page_lockend = round_down(lockend + 1, PAGE_SIZE) - 1;
|
||
+ const u64 page_lockend = round_down(lockend + 1, PAGE_SIZE);
|
||
|
||
while (1) {
|
||
truncate_pagecache_range(inode, lockstart, lockend);
|
||
|
||
lock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend,
|
||
cached_state);
|
||
+ /* The same page or adjacent pages. */
|
||
+ if (page_lockend <= page_lockstart)
|
||
+ break;
|
||
/*
|
||
* We can't have ordered extents in the range, nor dirty/writeback
|
||
* pages, because we have locked the inode's VFS lock in exclusive
|
||
@@ -2245,7 +2250,7 @@ static void btrfs_punch_hole_lock_range(struct inode *inode,
|
||
* we do, unlock the range and retry.
|
||
*/
|
||
if (!filemap_range_has_page(inode->i_mapping, page_lockstart,
|
||
- page_lockend))
|
||
+ page_lockend - 1))
|
||
break;
|
||
|
||
unlock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend,
|
||
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
|
||
index db6977c15c2828..f0befbeb6cb833 100644
|
||
--- a/fs/ceph/inode.c
|
||
+++ b/fs/ceph/inode.c
|
||
@@ -2319,7 +2319,7 @@ static int fill_fscrypt_truncate(struct inode *inode,
|
||
|
||
/* Try to writeback the dirty pagecaches */
|
||
if (issued & (CEPH_CAP_FILE_BUFFER)) {
|
||
- loff_t lend = orig_pos + CEPH_FSCRYPT_BLOCK_SHIFT - 1;
|
||
+ loff_t lend = orig_pos + CEPH_FSCRYPT_BLOCK_SIZE - 1;
|
||
|
||
ret = filemap_write_and_wait_range(inode->i_mapping,
|
||
orig_pos, lend);
|
||
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
|
||
index 6fe3c941b56514..4d6ba140276b5f 100644
|
||
--- a/fs/ext4/block_validity.c
|
||
+++ b/fs/ext4/block_validity.c
|
||
@@ -351,10 +351,9 @@ int ext4_check_blockref(const char *function, unsigned int line,
|
||
{
|
||
__le32 *bref = p;
|
||
unsigned int blk;
|
||
+ journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
|
||
|
||
- if (ext4_has_feature_journal(inode->i_sb) &&
|
||
- (inode->i_ino ==
|
||
- le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
|
||
+ if (journal && inode == journal->j_inode)
|
||
return 0;
|
||
|
||
while (bref < p+max) {
|
||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
|
||
index ddfeaf19bff1ba..d3d28e65872027 100644
|
||
--- a/fs/ext4/inode.c
|
||
+++ b/fs/ext4/inode.c
|
||
@@ -378,10 +378,11 @@ static int __check_block_validity(struct inode *inode, const char *func,
|
||
unsigned int line,
|
||
struct ext4_map_blocks *map)
|
||
{
|
||
- if (ext4_has_feature_journal(inode->i_sb) &&
|
||
- (inode->i_ino ==
|
||
- le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
|
||
+ journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
|
||
+
|
||
+ if (journal && inode == journal->j_inode)
|
||
return 0;
|
||
+
|
||
if (!ext4_inode_block_valid(inode, map->m_pblk, map->m_len)) {
|
||
ext4_error_inode(inode, func, line, map->m_pblk,
|
||
"lblock %lu mapped to illegal pblock %llu "
|
||
@@ -5478,7 +5479,7 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||
oldsize & (inode->i_sb->s_blocksize - 1)) {
|
||
error = ext4_inode_attach_jinode(inode);
|
||
if (error)
|
||
- goto err_out;
|
||
+ goto out_mmap_sem;
|
||
}
|
||
|
||
handle = ext4_journal_start(inode, EXT4_HT_INODE, 3);
|
||
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
|
||
index e7e6701806ad26..7ffdf0d037fae0 100644
|
||
--- a/fs/iomap/buffered-io.c
|
||
+++ b/fs/iomap/buffered-io.c
|
||
@@ -224,7 +224,7 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio,
|
||
}
|
||
|
||
/* truncate len if we find any trailing uptodate block(s) */
|
||
- for ( ; i <= last; i++) {
|
||
+ while (++i <= last) {
|
||
if (ifs_block_is_uptodate(ifs, i)) {
|
||
plen -= (last - i + 1) * block_size;
|
||
last = i - 1;
|
||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||
index 671e266b8fc5d2..5a885d35efe937 100644
|
||
--- a/fs/namespace.c
|
||
+++ b/fs/namespace.c
|
||
@@ -2439,56 +2439,62 @@ static struct mountpoint *do_lock_mount(struct path *path, bool beneath)
|
||
struct vfsmount *mnt = path->mnt;
|
||
struct dentry *dentry;
|
||
struct mountpoint *mp = ERR_PTR(-ENOENT);
|
||
+ struct path under = {};
|
||
|
||
for (;;) {
|
||
- struct mount *m;
|
||
+ struct mount *m = real_mount(mnt);
|
||
|
||
if (beneath) {
|
||
- m = real_mount(mnt);
|
||
+ path_put(&under);
|
||
read_seqlock_excl(&mount_lock);
|
||
- dentry = dget(m->mnt_mountpoint);
|
||
+ under.mnt = mntget(&m->mnt_parent->mnt);
|
||
+ under.dentry = dget(m->mnt_mountpoint);
|
||
read_sequnlock_excl(&mount_lock);
|
||
+ dentry = under.dentry;
|
||
} else {
|
||
dentry = path->dentry;
|
||
}
|
||
|
||
inode_lock(dentry->d_inode);
|
||
- if (unlikely(cant_mount(dentry))) {
|
||
- inode_unlock(dentry->d_inode);
|
||
- goto out;
|
||
- }
|
||
-
|
||
namespace_lock();
|
||
|
||
- if (beneath && (!is_mounted(mnt) || m->mnt_mountpoint != dentry)) {
|
||
+ if (unlikely(cant_mount(dentry) || !is_mounted(mnt)))
|
||
+ break; // not to be mounted on
|
||
+
|
||
+ if (beneath && unlikely(m->mnt_mountpoint != dentry ||
|
||
+ &m->mnt_parent->mnt != under.mnt)) {
|
||
namespace_unlock();
|
||
inode_unlock(dentry->d_inode);
|
||
- goto out;
|
||
+ continue; // got moved
|
||
}
|
||
|
||
mnt = lookup_mnt(path);
|
||
- if (likely(!mnt))
|
||
+ if (unlikely(mnt)) {
|
||
+ namespace_unlock();
|
||
+ inode_unlock(dentry->d_inode);
|
||
+ path_put(path);
|
||
+ path->mnt = mnt;
|
||
+ path->dentry = dget(mnt->mnt_root);
|
||
+ continue; // got overmounted
|
||
+ }
|
||
+ mp = get_mountpoint(dentry);
|
||
+ if (IS_ERR(mp))
|
||
break;
|
||
-
|
||
- namespace_unlock();
|
||
- inode_unlock(dentry->d_inode);
|
||
- if (beneath)
|
||
- dput(dentry);
|
||
- path_put(path);
|
||
- path->mnt = mnt;
|
||
- path->dentry = dget(mnt->mnt_root);
|
||
- }
|
||
-
|
||
- mp = get_mountpoint(dentry);
|
||
- if (IS_ERR(mp)) {
|
||
- namespace_unlock();
|
||
- inode_unlock(dentry->d_inode);
|
||
+ if (beneath) {
|
||
+ /*
|
||
+ * @under duplicates the references that will stay
|
||
+ * at least until namespace_unlock(), so the path_put()
|
||
+ * below is safe (and OK to do under namespace_lock -
|
||
+ * we are not dropping the final references here).
|
||
+ */
|
||
+ path_put(&under);
|
||
+ }
|
||
+ return mp;
|
||
}
|
||
-
|
||
-out:
|
||
+ namespace_unlock();
|
||
+ inode_unlock(dentry->d_inode);
|
||
if (beneath)
|
||
- dput(dentry);
|
||
-
|
||
+ path_put(&under);
|
||
return mp;
|
||
}
|
||
|
||
@@ -2499,14 +2505,11 @@ static inline struct mountpoint *lock_mount(struct path *path)
|
||
|
||
static void unlock_mount(struct mountpoint *where)
|
||
{
|
||
- struct dentry *dentry = where->m_dentry;
|
||
-
|
||
+ inode_unlock(where->m_dentry->d_inode);
|
||
read_seqlock_excl(&mount_lock);
|
||
put_mountpoint(where);
|
||
read_sequnlock_excl(&mount_lock);
|
||
-
|
||
namespace_unlock();
|
||
- inode_unlock(dentry->d_inode);
|
||
}
|
||
|
||
static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
|
||
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
|
||
index 2ecd0303f9421b..4aea458216117f 100644
|
||
--- a/fs/ntfs3/file.c
|
||
+++ b/fs/ntfs3/file.c
|
||
@@ -335,6 +335,7 @@ static int ntfs_extend(struct inode *inode, loff_t pos, size_t count,
|
||
}
|
||
|
||
if (extend_init && !is_compressed(ni)) {
|
||
+ WARN_ON(ni->i_valid >= pos);
|
||
err = ntfs_extend_initialized_size(file, ni, ni->i_valid, pos);
|
||
if (err)
|
||
goto out;
|
||
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
|
||
index c2a98b2736645d..f04922eb45d4c9 100644
|
||
--- a/fs/smb/client/sess.c
|
||
+++ b/fs/smb/client/sess.c
|
||
@@ -732,6 +732,22 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
|
||
*pbcc_area = bcc_ptr;
|
||
}
|
||
|
||
+static void
|
||
+ascii_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
|
||
+{
|
||
+ char *bcc_ptr = *pbcc_area;
|
||
+
|
||
+ strcpy(bcc_ptr, "Linux version ");
|
||
+ bcc_ptr += strlen("Linux version ");
|
||
+ strcpy(bcc_ptr, init_utsname()->release);
|
||
+ bcc_ptr += strlen(init_utsname()->release) + 1;
|
||
+
|
||
+ strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
|
||
+ bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
|
||
+
|
||
+ *pbcc_area = bcc_ptr;
|
||
+}
|
||
+
|
||
static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
|
||
const struct nls_table *nls_cp)
|
||
{
|
||
@@ -756,6 +772,25 @@ static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
|
||
*pbcc_area = bcc_ptr;
|
||
}
|
||
|
||
+static void ascii_domain_string(char **pbcc_area, struct cifs_ses *ses,
|
||
+ const struct nls_table *nls_cp)
|
||
+{
|
||
+ char *bcc_ptr = *pbcc_area;
|
||
+ int len;
|
||
+
|
||
+ /* copy domain */
|
||
+ if (ses->domainName != NULL) {
|
||
+ len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
|
||
+ if (WARN_ON_ONCE(len < 0))
|
||
+ len = CIFS_MAX_DOMAINNAME_LEN - 1;
|
||
+ bcc_ptr += len;
|
||
+ } /* else we send a null domain name so server will default to its own domain */
|
||
+ *bcc_ptr = 0;
|
||
+ bcc_ptr++;
|
||
+
|
||
+ *pbcc_area = bcc_ptr;
|
||
+}
|
||
+
|
||
static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
|
||
const struct nls_table *nls_cp)
|
||
{
|
||
@@ -801,25 +836,10 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
|
||
*bcc_ptr = 0;
|
||
bcc_ptr++; /* account for null termination */
|
||
|
||
- /* copy domain */
|
||
- if (ses->domainName != NULL) {
|
||
- len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
|
||
- if (WARN_ON_ONCE(len < 0))
|
||
- len = CIFS_MAX_DOMAINNAME_LEN - 1;
|
||
- bcc_ptr += len;
|
||
- } /* else we send a null domain name so server will default to its own domain */
|
||
- *bcc_ptr = 0;
|
||
- bcc_ptr++;
|
||
-
|
||
/* BB check for overflow here */
|
||
|
||
- strcpy(bcc_ptr, "Linux version ");
|
||
- bcc_ptr += strlen("Linux version ");
|
||
- strcpy(bcc_ptr, init_utsname()->release);
|
||
- bcc_ptr += strlen(init_utsname()->release) + 1;
|
||
-
|
||
- strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
|
||
- bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
|
||
+ ascii_domain_string(&bcc_ptr, ses, nls_cp);
|
||
+ ascii_oslm_strings(&bcc_ptr, nls_cp);
|
||
|
||
*pbcc_area = bcc_ptr;
|
||
}
|
||
@@ -1622,7 +1642,7 @@ sess_auth_kerberos(struct sess_data *sess_data)
|
||
sess_data->iov[1].iov_len = msg->secblob_len;
|
||
pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
|
||
|
||
- if (ses->capabilities & CAP_UNICODE) {
|
||
+ if (pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) {
|
||
/* unicode strings must be word aligned */
|
||
if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
|
||
*bcc_ptr = 0;
|
||
@@ -1631,8 +1651,8 @@ sess_auth_kerberos(struct sess_data *sess_data)
|
||
unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
|
||
unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
|
||
} else {
|
||
- /* BB: is this right? */
|
||
- ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
|
||
+ ascii_oslm_strings(&bcc_ptr, sess_data->nls_cp);
|
||
+ ascii_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
|
||
}
|
||
|
||
sess_data->iov[2].iov_len = (long) bcc_ptr -
|
||
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
|
||
index bc1bac36c1b291..caa1d852ece49c 100644
|
||
--- a/fs/smb/client/smb1ops.c
|
||
+++ b/fs/smb/client/smb1ops.c
|
||
@@ -597,6 +597,42 @@ static int cifs_query_path_info(const unsigned int xid,
|
||
CIFSSMBClose(xid, tcon, fid.netfid);
|
||
}
|
||
|
||
+#ifdef CONFIG_CIFS_XATTR
|
||
+ /*
|
||
+ * For WSL CHR and BLK reparse points it is required to fetch
|
||
+ * EA $LXDEV which contains major and minor device numbers.
|
||
+ */
|
||
+ if (!rc && data->reparse_point) {
|
||
+ struct smb2_file_full_ea_info *ea;
|
||
+
|
||
+ ea = (struct smb2_file_full_ea_info *)data->wsl.eas;
|
||
+ rc = CIFSSMBQAllEAs(xid, tcon, full_path, SMB2_WSL_XATTR_DEV,
|
||
+ &ea->ea_data[SMB2_WSL_XATTR_NAME_LEN + 1],
|
||
+ SMB2_WSL_XATTR_DEV_SIZE, cifs_sb);
|
||
+ if (rc == SMB2_WSL_XATTR_DEV_SIZE) {
|
||
+ ea->next_entry_offset = cpu_to_le32(0);
|
||
+ ea->flags = 0;
|
||
+ ea->ea_name_length = SMB2_WSL_XATTR_NAME_LEN;
|
||
+ ea->ea_value_length = cpu_to_le16(SMB2_WSL_XATTR_DEV_SIZE);
|
||
+ memcpy(&ea->ea_data[0], SMB2_WSL_XATTR_DEV, SMB2_WSL_XATTR_NAME_LEN + 1);
|
||
+ data->wsl.eas_len = sizeof(*ea) + SMB2_WSL_XATTR_NAME_LEN + 1 +
|
||
+ SMB2_WSL_XATTR_DEV_SIZE;
|
||
+ rc = 0;
|
||
+ } else if (rc >= 0) {
|
||
+ /* It is an error if EA $LXDEV has wrong size. */
|
||
+ rc = -EINVAL;
|
||
+ } else {
|
||
+ /*
|
||
+ * In all other cases ignore error if fetching
|
||
+ * of EA $LXDEV failed. It is needed only for
|
||
+ * WSL CHR and BLK reparse points and wsl_to_fattr()
|
||
+ * handle the case when EA is missing.
|
||
+ */
|
||
+ rc = 0;
|
||
+ }
|
||
+ }
|
||
+#endif
|
||
+
|
||
return rc;
|
||
}
|
||
|
||
diff --git a/fs/splice.c b/fs/splice.c
|
||
index d983d375ff1130..6f9b06bbb860ac 100644
|
||
--- a/fs/splice.c
|
||
+++ b/fs/splice.c
|
||
@@ -45,7 +45,7 @@
|
||
* here if set to avoid blocking other users of this pipe if splice is
|
||
* being done on it.
|
||
*/
|
||
-static noinline void noinline pipe_clear_nowait(struct file *file)
|
||
+static noinline void pipe_clear_nowait(struct file *file)
|
||
{
|
||
fmode_t fmode = READ_ONCE(file->f_mode);
|
||
|
||
diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
|
||
index b9caa01dfac485..adec808b371a11 100644
|
||
--- a/include/linux/energy_model.h
|
||
+++ b/include/linux/energy_model.h
|
||
@@ -243,7 +243,6 @@ static inline unsigned long em_cpu_energy(struct em_perf_domain *pd,
|
||
scale_cpu = arch_scale_cpu_capacity(cpu);
|
||
ps = &pd->table[pd->nr_perf_states - 1];
|
||
|
||
- max_util = map_util_perf(max_util);
|
||
max_util = min(max_util, allowed_cpu_cap);
|
||
freq = map_util_freq(max_util, ps->frequency, scale_cpu);
|
||
|
||
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
|
||
index ab2a7ef61d420f..b4fcd0164048ed 100644
|
||
--- a/include/media/v4l2-subdev.h
|
||
+++ b/include/media/v4l2-subdev.h
|
||
@@ -1038,10 +1038,11 @@ struct v4l2_subdev_platform_data {
|
||
* @active_state: Active state for the subdev (NULL for subdevs tracking the
|
||
* state internally). Initialized by calling
|
||
* v4l2_subdev_init_finalize().
|
||
- * @enabled_streams: Bitmask of enabled streams used by
|
||
- * v4l2_subdev_enable_streams() and
|
||
- * v4l2_subdev_disable_streams() helper functions for fallback
|
||
- * cases.
|
||
+ * @enabled_pads: Bitmask of enabled pads used by v4l2_subdev_enable_streams()
|
||
+ * and v4l2_subdev_disable_streams() helper functions for
|
||
+ * fallback cases.
|
||
+ * @s_stream_enabled: Tracks whether streaming has been enabled with s_stream.
|
||
+ * This is only for call_s_stream() internal use.
|
||
*
|
||
* Each instance of a subdev driver should create this struct, either
|
||
* stand-alone or embedded in a larger struct.
|
||
@@ -1089,7 +1090,8 @@ struct v4l2_subdev {
|
||
* doesn't support it.
|
||
*/
|
||
struct v4l2_subdev_state *active_state;
|
||
- u64 enabled_streams;
|
||
+ u64 enabled_pads;
|
||
+ bool s_stream_enabled;
|
||
};
|
||
|
||
|
||
@@ -1916,4 +1918,17 @@ extern const struct v4l2_subdev_ops v4l2_subdev_call_wrappers;
|
||
void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
|
||
const struct v4l2_event *ev);
|
||
|
||
+/**
|
||
+ * v4l2_subdev_is_streaming() - Returns if the subdevice is streaming
|
||
+ * @sd: The subdevice
|
||
+ *
|
||
+ * v4l2_subdev_is_streaming() tells if the subdevice is currently streaming.
|
||
+ * "Streaming" here means whether .s_stream() or .enable_streams() has been
|
||
+ * successfully called, and the streaming has not yet been disabled.
|
||
+ *
|
||
+ * If the subdevice implements .enable_streams() this function must be called
|
||
+ * while holding the active state lock.
|
||
+ */
|
||
+bool v4l2_subdev_is_streaming(struct v4l2_subdev *sd);
|
||
+
|
||
#endif /* _V4L2_SUBDEV_H */
|
||
diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h
|
||
index 5870a94599a258..d5f6a228df6594 100644
|
||
--- a/include/soc/qcom/ice.h
|
||
+++ b/include/soc/qcom/ice.h
|
||
@@ -34,4 +34,6 @@ int qcom_ice_program_key(struct qcom_ice *ice,
|
||
int slot);
|
||
int qcom_ice_evict_key(struct qcom_ice *ice, int slot);
|
||
struct qcom_ice *of_qcom_ice_get(struct device *dev);
|
||
+struct qcom_ice *devm_of_qcom_ice_get(struct device *dev);
|
||
+
|
||
#endif /* __QCOM_ICE_H__ */
|
||
diff --git a/include/trace/stages/stage3_trace_output.h b/include/trace/stages/stage3_trace_output.h
|
||
index c1fb1355d3094b..1e7b0bef95f525 100644
|
||
--- a/include/trace/stages/stage3_trace_output.h
|
||
+++ b/include/trace/stages/stage3_trace_output.h
|
||
@@ -119,6 +119,14 @@
|
||
trace_print_array_seq(p, array, count, el_size); \
|
||
})
|
||
|
||
+#undef __print_dynamic_array
|
||
+#define __print_dynamic_array(array, el_size) \
|
||
+ ({ \
|
||
+ __print_array(__get_dynamic_array(array), \
|
||
+ __get_dynamic_array_len(array) / (el_size), \
|
||
+ (el_size)); \
|
||
+ })
|
||
+
|
||
#undef __print_hex_dump
|
||
#define __print_hex_dump(prefix_str, prefix_type, \
|
||
rowsize, groupsize, buf, len, ascii) \
|
||
diff --git a/include/trace/stages/stage7_class_define.h b/include/trace/stages/stage7_class_define.h
|
||
index bcb960d16fc0ed..fcd564a590f434 100644
|
||
--- a/include/trace/stages/stage7_class_define.h
|
||
+++ b/include/trace/stages/stage7_class_define.h
|
||
@@ -22,6 +22,7 @@
|
||
#undef __get_rel_cpumask
|
||
#undef __get_rel_sockaddr
|
||
#undef __print_array
|
||
+#undef __print_dynamic_array
|
||
#undef __print_hex_dump
|
||
#undef __get_buf
|
||
|
||
diff --git a/init/Kconfig b/init/Kconfig
|
||
index 1105cb53f391ab..8b630143c720f6 100644
|
||
--- a/init/Kconfig
|
||
+++ b/init/Kconfig
|
||
@@ -689,7 +689,7 @@ endmenu # "CPU/Task time and stats accounting"
|
||
|
||
config CPU_ISOLATION
|
||
bool "CPU isolation"
|
||
- depends on SMP || COMPILE_TEST
|
||
+ depends on SMP
|
||
default y
|
||
help
|
||
Make sure that CPUs running critical tasks are not disturbed by
|
||
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
|
||
index efa7849b82c184..3ce93418e0151d 100644
|
||
--- a/io_uring/io_uring.c
|
||
+++ b/io_uring/io_uring.c
|
||
@@ -1247,21 +1247,22 @@ static __cold void io_fallback_tw(struct io_uring_task *tctx, bool sync)
|
||
while (node) {
|
||
req = container_of(node, struct io_kiocb, io_task_work.node);
|
||
node = node->next;
|
||
- if (sync && last_ctx != req->ctx) {
|
||
+ if (last_ctx != req->ctx) {
|
||
if (last_ctx) {
|
||
- flush_delayed_work(&last_ctx->fallback_work);
|
||
+ if (sync)
|
||
+ flush_delayed_work(&last_ctx->fallback_work);
|
||
percpu_ref_put(&last_ctx->refs);
|
||
}
|
||
last_ctx = req->ctx;
|
||
percpu_ref_get(&last_ctx->refs);
|
||
}
|
||
- if (llist_add(&req->io_task_work.node,
|
||
- &req->ctx->fallback_llist))
|
||
- schedule_delayed_work(&req->ctx->fallback_work, 1);
|
||
+ if (llist_add(&req->io_task_work.node, &last_ctx->fallback_llist))
|
||
+ schedule_delayed_work(&last_ctx->fallback_work, 1);
|
||
}
|
||
|
||
if (last_ctx) {
|
||
- flush_delayed_work(&last_ctx->fallback_work);
|
||
+ if (sync)
|
||
+ flush_delayed_work(&last_ctx->fallback_work);
|
||
percpu_ref_put(&last_ctx->refs);
|
||
}
|
||
}
|
||
@@ -1916,7 +1917,7 @@ struct io_wq_work *io_wq_free_work(struct io_wq_work *work)
|
||
struct io_kiocb *req = container_of(work, struct io_kiocb, work);
|
||
struct io_kiocb *nxt = NULL;
|
||
|
||
- if (req_ref_put_and_test(req)) {
|
||
+ if (req_ref_put_and_test_atomic(req)) {
|
||
if (req->flags & IO_REQ_LINK_FLAGS)
|
||
nxt = io_req_find_next(req);
|
||
io_free_req(req);
|
||
diff --git a/io_uring/refs.h b/io_uring/refs.h
|
||
index 1336de3f2a30aa..21a379b0f22d61 100644
|
||
--- a/io_uring/refs.h
|
||
+++ b/io_uring/refs.h
|
||
@@ -17,6 +17,13 @@ static inline bool req_ref_inc_not_zero(struct io_kiocb *req)
|
||
return atomic_inc_not_zero(&req->refs);
|
||
}
|
||
|
||
+static inline bool req_ref_put_and_test_atomic(struct io_kiocb *req)
|
||
+{
|
||
+ WARN_ON_ONCE(!(data_race(req->flags) & REQ_F_REFCOUNT));
|
||
+ WARN_ON_ONCE(req_ref_zero_or_close_to_overflow(req));
|
||
+ return atomic_dec_and_test(&req->refs);
|
||
+}
|
||
+
|
||
static inline bool req_ref_put_and_test(struct io_kiocb *req)
|
||
{
|
||
if (likely(!(req->flags & REQ_F_REFCOUNT)))
|
||
diff --git a/kernel/bpf/bpf_cgrp_storage.c b/kernel/bpf/bpf_cgrp_storage.c
|
||
index ee1c7b77096e7b..fbbf3b6b9f8353 100644
|
||
--- a/kernel/bpf/bpf_cgrp_storage.c
|
||
+++ b/kernel/bpf/bpf_cgrp_storage.c
|
||
@@ -162,6 +162,7 @@ BPF_CALL_5(bpf_cgrp_storage_get, struct bpf_map *, map, struct cgroup *, cgroup,
|
||
void *, value, u64, flags, gfp_t, gfp_flags)
|
||
{
|
||
struct bpf_local_storage_data *sdata;
|
||
+ bool nobusy;
|
||
|
||
WARN_ON_ONCE(!bpf_rcu_lock_held());
|
||
if (flags & ~(BPF_LOCAL_STORAGE_GET_F_CREATE))
|
||
@@ -170,21 +171,21 @@ BPF_CALL_5(bpf_cgrp_storage_get, struct bpf_map *, map, struct cgroup *, cgroup,
|
||
if (!cgroup)
|
||
return (unsigned long)NULL;
|
||
|
||
- if (!bpf_cgrp_storage_trylock())
|
||
- return (unsigned long)NULL;
|
||
+ nobusy = bpf_cgrp_storage_trylock();
|
||
|
||
- sdata = cgroup_storage_lookup(cgroup, map, true);
|
||
+ sdata = cgroup_storage_lookup(cgroup, map, nobusy);
|
||
if (sdata)
|
||
goto unlock;
|
||
|
||
/* only allocate new storage, when the cgroup is refcounted */
|
||
if (!percpu_ref_is_dying(&cgroup->self.refcnt) &&
|
||
- (flags & BPF_LOCAL_STORAGE_GET_F_CREATE))
|
||
+ (flags & BPF_LOCAL_STORAGE_GET_F_CREATE) && nobusy)
|
||
sdata = bpf_local_storage_update(cgroup, (struct bpf_local_storage_map *)map,
|
||
value, BPF_NOEXIST, gfp_flags);
|
||
|
||
unlock:
|
||
- bpf_cgrp_storage_unlock();
|
||
+ if (nobusy)
|
||
+ bpf_cgrp_storage_unlock();
|
||
return IS_ERR_OR_NULL(sdata) ? (unsigned long)NULL : (unsigned long)sdata->data;
|
||
}
|
||
|
||
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
|
||
index d6a4102312fadd..e443506b0a65a1 100644
|
||
--- a/kernel/bpf/verifier.c
|
||
+++ b/kernel/bpf/verifier.c
|
||
@@ -20106,6 +20106,33 @@ BTF_ID(func, __rcu_read_unlock)
|
||
#endif
|
||
BTF_SET_END(btf_id_deny)
|
||
|
||
+/* fexit and fmod_ret can't be used to attach to __noreturn functions.
|
||
+ * Currently, we must manually list all __noreturn functions here. Once a more
|
||
+ * robust solution is implemented, this workaround can be removed.
|
||
+ */
|
||
+BTF_SET_START(noreturn_deny)
|
||
+#ifdef CONFIG_IA32_EMULATION
|
||
+BTF_ID(func, __ia32_sys_exit)
|
||
+BTF_ID(func, __ia32_sys_exit_group)
|
||
+#endif
|
||
+#ifdef CONFIG_KUNIT
|
||
+BTF_ID(func, __kunit_abort)
|
||
+BTF_ID(func, kunit_try_catch_throw)
|
||
+#endif
|
||
+#ifdef CONFIG_MODULES
|
||
+BTF_ID(func, __module_put_and_kthread_exit)
|
||
+#endif
|
||
+#ifdef CONFIG_X86_64
|
||
+BTF_ID(func, __x64_sys_exit)
|
||
+BTF_ID(func, __x64_sys_exit_group)
|
||
+#endif
|
||
+BTF_ID(func, do_exit)
|
||
+BTF_ID(func, do_group_exit)
|
||
+BTF_ID(func, kthread_complete_and_exit)
|
||
+BTF_ID(func, kthread_exit)
|
||
+BTF_ID(func, make_task_dead)
|
||
+BTF_SET_END(noreturn_deny)
|
||
+
|
||
static bool can_be_sleepable(struct bpf_prog *prog)
|
||
{
|
||
if (prog->type == BPF_PROG_TYPE_TRACING) {
|
||
@@ -20194,6 +20221,11 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
|
||
} else if (prog->type == BPF_PROG_TYPE_TRACING &&
|
||
btf_id_set_contains(&btf_id_deny, btf_id)) {
|
||
return -EINVAL;
|
||
+ } else if ((prog->expected_attach_type == BPF_TRACE_FEXIT ||
|
||
+ prog->expected_attach_type == BPF_MODIFY_RETURN) &&
|
||
+ btf_id_set_contains(&noreturn_deny, btf_id)) {
|
||
+ verbose(env, "Attaching fexit/fmod_ret to __noreturn functions is rejected.\n");
|
||
+ return -EINVAL;
|
||
}
|
||
|
||
key = bpf_trampoline_compute_key(tgt_prog, prog->aux->attach_btf, btf_id);
|
||
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
|
||
index f005c66f378c32..a600819799637b 100644
|
||
--- a/kernel/dma/contiguous.c
|
||
+++ b/kernel/dma/contiguous.c
|
||
@@ -70,8 +70,7 @@ struct cma *dma_contiguous_default_area;
|
||
* Users, who want to set the size of global CMA area for their system
|
||
* should use cma= kernel parameter.
|
||
*/
|
||
-static const phys_addr_t size_bytes __initconst =
|
||
- (phys_addr_t)CMA_SIZE_MBYTES * SZ_1M;
|
||
+#define size_bytes ((phys_addr_t)CMA_SIZE_MBYTES * SZ_1M)
|
||
static phys_addr_t size_cmdline __initdata = -1;
|
||
static phys_addr_t base_cmdline __initdata;
|
||
static phys_addr_t limit_cmdline __initdata;
|
||
diff --git a/kernel/events/core.c b/kernel/events/core.c
|
||
index b710976fb01b17..987807b1040ae0 100644
|
||
--- a/kernel/events/core.c
|
||
+++ b/kernel/events/core.c
|
||
@@ -13419,6 +13419,9 @@ inherit_event(struct perf_event *parent_event,
|
||
if (IS_ERR(child_event))
|
||
return child_event;
|
||
|
||
+ get_ctx(child_ctx);
|
||
+ child_event->ctx = child_ctx;
|
||
+
|
||
pmu_ctx = find_get_pmu_context(child_event->pmu, child_ctx, child_event);
|
||
if (IS_ERR(pmu_ctx)) {
|
||
free_event(child_event);
|
||
@@ -13441,8 +13444,6 @@ inherit_event(struct perf_event *parent_event,
|
||
return NULL;
|
||
}
|
||
|
||
- get_ctx(child_ctx);
|
||
-
|
||
/*
|
||
* Make the child state follow the state of the parent event,
|
||
* not its attr.disabled bit. We hold the parent's mutex,
|
||
@@ -13463,7 +13464,6 @@ inherit_event(struct perf_event *parent_event,
|
||
local64_set(&hwc->period_left, sample_period);
|
||
}
|
||
|
||
- child_event->ctx = child_ctx;
|
||
child_event->overflow_handler = parent_event->overflow_handler;
|
||
child_event->overflow_handler_context
|
||
= parent_event->overflow_handler_context;
|
||
diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig
|
||
index 33a2e991f60814..b411315ecd3c4b 100644
|
||
--- a/kernel/module/Kconfig
|
||
+++ b/kernel/module/Kconfig
|
||
@@ -229,6 +229,7 @@ comment "Do not forget to sign required modules with scripts/sign-file"
|
||
choice
|
||
prompt "Which hash algorithm should modules be signed with?"
|
||
depends on MODULE_SIG || IMA_APPRAISE_MODSIG
|
||
+ default MODULE_SIG_SHA512
|
||
help
|
||
This determines which sort of hashing algorithm will be used during
|
||
signature generation. This algorithm _must_ be built into the kernel
|
||
diff --git a/kernel/panic.c b/kernel/panic.c
|
||
index ef9f9a4e928de6..d7973e97547482 100644
|
||
--- a/kernel/panic.c
|
||
+++ b/kernel/panic.c
|
||
@@ -763,9 +763,15 @@ device_initcall(register_warn_debugfs);
|
||
*/
|
||
__visible noinstr void __stack_chk_fail(void)
|
||
{
|
||
+ unsigned long flags;
|
||
+
|
||
instrumentation_begin();
|
||
+ flags = user_access_save();
|
||
+
|
||
panic("stack-protector: Kernel stack is corrupted in: %pB",
|
||
__builtin_return_address(0));
|
||
+
|
||
+ user_access_restore(flags);
|
||
instrumentation_end();
|
||
}
|
||
EXPORT_SYMBOL(__stack_chk_fail);
|
||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
|
||
index 8c5f75af07db0e..760a6c3781cbfc 100644
|
||
--- a/kernel/sched/core.c
|
||
+++ b/kernel/sched/core.c
|
||
@@ -7406,18 +7406,13 @@ int sched_core_idle_cpu(int cpu)
|
||
* required to meet deadlines.
|
||
*/
|
||
unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
|
||
- enum cpu_util_type type,
|
||
- struct task_struct *p)
|
||
+ unsigned long *min,
|
||
+ unsigned long *max)
|
||
{
|
||
- unsigned long dl_util, util, irq, max;
|
||
+ unsigned long util, irq, scale;
|
||
struct rq *rq = cpu_rq(cpu);
|
||
|
||
- max = arch_scale_cpu_capacity(cpu);
|
||
-
|
||
- if (!uclamp_is_used() &&
|
||
- type == FREQUENCY_UTIL && rt_rq_is_runnable(&rq->rt)) {
|
||
- return max;
|
||
- }
|
||
+ scale = arch_scale_cpu_capacity(cpu);
|
||
|
||
/*
|
||
* Early check to see if IRQ/steal time saturates the CPU, can be
|
||
@@ -7425,45 +7420,49 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
|
||
* update_irq_load_avg().
|
||
*/
|
||
irq = cpu_util_irq(rq);
|
||
- if (unlikely(irq >= max))
|
||
- return max;
|
||
+ if (unlikely(irq >= scale)) {
|
||
+ if (min)
|
||
+ *min = scale;
|
||
+ if (max)
|
||
+ *max = scale;
|
||
+ return scale;
|
||
+ }
|
||
+
|
||
+ if (min) {
|
||
+ /*
|
||
+ * The minimum utilization returns the highest level between:
|
||
+ * - the computed DL bandwidth needed with the IRQ pressure which
|
||
+ * steals time to the deadline task.
|
||
+ * - The minimum performance requirement for CFS and/or RT.
|
||
+ */
|
||
+ *min = max(irq + cpu_bw_dl(rq), uclamp_rq_get(rq, UCLAMP_MIN));
|
||
+
|
||
+ /*
|
||
+ * When an RT task is runnable and uclamp is not used, we must
|
||
+ * ensure that the task will run at maximum compute capacity.
|
||
+ */
|
||
+ if (!uclamp_is_used() && rt_rq_is_runnable(&rq->rt))
|
||
+ *min = max(*min, scale);
|
||
+ }
|
||
|
||
/*
|
||
* Because the time spend on RT/DL tasks is visible as 'lost' time to
|
||
* CFS tasks and we use the same metric to track the effective
|
||
* utilization (PELT windows are synchronized) we can directly add them
|
||
* to obtain the CPU's actual utilization.
|
||
- *
|
||
- * CFS and RT utilization can be boosted or capped, depending on
|
||
- * utilization clamp constraints requested by currently RUNNABLE
|
||
- * tasks.
|
||
- * When there are no CFS RUNNABLE tasks, clamps are released and
|
||
- * frequency will be gracefully reduced with the utilization decay.
|
||
*/
|
||
util = util_cfs + cpu_util_rt(rq);
|
||
- if (type == FREQUENCY_UTIL)
|
||
- util = uclamp_rq_util_with(rq, util, p);
|
||
-
|
||
- dl_util = cpu_util_dl(rq);
|
||
+ util += cpu_util_dl(rq);
|
||
|
||
/*
|
||
- * For frequency selection we do not make cpu_util_dl() a permanent part
|
||
- * of this sum because we want to use cpu_bw_dl() later on, but we need
|
||
- * to check if the CFS+RT+DL sum is saturated (ie. no idle time) such
|
||
- * that we select f_max when there is no idle time.
|
||
- *
|
||
- * NOTE: numerical errors or stop class might cause us to not quite hit
|
||
- * saturation when we should -- something for later.
|
||
+ * The maximum hint is a soft bandwidth requirement, which can be lower
|
||
+ * than the actual utilization because of uclamp_max requirements.
|
||
*/
|
||
- if (util + dl_util >= max)
|
||
- return max;
|
||
+ if (max)
|
||
+ *max = min(scale, uclamp_rq_get(rq, UCLAMP_MAX));
|
||
|
||
- /*
|
||
- * OTOH, for energy computation we need the estimated running time, so
|
||
- * include util_dl and ignore dl_bw.
|
||
- */
|
||
- if (type == ENERGY_UTIL)
|
||
- util += dl_util;
|
||
+ if (util >= scale)
|
||
+ return scale;
|
||
|
||
/*
|
||
* There is still idle time; further improve the number by using the
|
||
@@ -7474,28 +7473,15 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
|
||
* U' = irq + --------- * U
|
||
* max
|
||
*/
|
||
- util = scale_irq_capacity(util, irq, max);
|
||
+ util = scale_irq_capacity(util, irq, scale);
|
||
util += irq;
|
||
|
||
- /*
|
||
- * Bandwidth required by DEADLINE must always be granted while, for
|
||
- * FAIR and RT, we use blocked utilization of IDLE CPUs as a mechanism
|
||
- * to gracefully reduce the frequency when no tasks show up for longer
|
||
- * periods of time.
|
||
- *
|
||
- * Ideally we would like to set bw_dl as min/guaranteed freq and util +
|
||
- * bw_dl as requested freq. However, cpufreq is not yet ready for such
|
||
- * an interface. So, we only do the latter for now.
|
||
- */
|
||
- if (type == FREQUENCY_UTIL)
|
||
- util += cpu_bw_dl(rq);
|
||
-
|
||
- return min(max, util);
|
||
+ return min(scale, util);
|
||
}
|
||
|
||
unsigned long sched_cpu_util(int cpu)
|
||
{
|
||
- return effective_cpu_util(cpu, cpu_util_cfs(cpu), ENERGY_UTIL, NULL);
|
||
+ return effective_cpu_util(cpu, cpu_util_cfs(cpu), NULL, NULL);
|
||
}
|
||
#endif /* CONFIG_SMP */
|
||
|
||
@@ -10048,7 +10034,7 @@ void __init sched_init(void)
|
||
#ifdef CONFIG_SMP
|
||
rq->sd = NULL;
|
||
rq->rd = NULL;
|
||
- rq->cpu_capacity = rq->cpu_capacity_orig = SCHED_CAPACITY_SCALE;
|
||
+ rq->cpu_capacity = SCHED_CAPACITY_SCALE;
|
||
rq->balance_callback = &balance_push_callback;
|
||
rq->active_balance = 0;
|
||
rq->next_balance = jiffies;
|
||
diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c
|
||
index 57c92d751bcd73..95baa12a10293e 100644
|
||
--- a/kernel/sched/cpudeadline.c
|
||
+++ b/kernel/sched/cpudeadline.c
|
||
@@ -131,7 +131,7 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p,
|
||
if (!dl_task_fits_capacity(p, cpu)) {
|
||
cpumask_clear_cpu(cpu, later_mask);
|
||
|
||
- cap = capacity_orig_of(cpu);
|
||
+ cap = arch_scale_cpu_capacity(cpu);
|
||
|
||
if (cap > max_cap ||
|
||
(cpu == task_cpu(p) && cap == max_cap)) {
|
||
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
|
||
index 259521b179aa11..776be0549162c9 100644
|
||
--- a/kernel/sched/cpufreq_schedutil.c
|
||
+++ b/kernel/sched/cpufreq_schedutil.c
|
||
@@ -47,7 +47,7 @@ struct sugov_cpu {
|
||
u64 last_update;
|
||
|
||
unsigned long util;
|
||
- unsigned long bw_dl;
|
||
+ unsigned long bw_min;
|
||
|
||
/* The field below is for single-CPU policies only: */
|
||
#ifdef CONFIG_NO_HZ_COMMON
|
||
@@ -81,9 +81,20 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
|
||
if (!cpufreq_this_cpu_can_update(sg_policy->policy))
|
||
return false;
|
||
|
||
- if (unlikely(sg_policy->limits_changed)) {
|
||
- sg_policy->limits_changed = false;
|
||
+ if (unlikely(READ_ONCE(sg_policy->limits_changed))) {
|
||
+ WRITE_ONCE(sg_policy->limits_changed, false);
|
||
sg_policy->need_freq_update = true;
|
||
+
|
||
+ /*
|
||
+ * The above limits_changed update must occur before the reads
|
||
+ * of policy limits in cpufreq_driver_resolve_freq() or a policy
|
||
+ * limits update might be missed, so use a memory barrier to
|
||
+ * ensure it.
|
||
+ *
|
||
+ * This pairs with the write memory barrier in sugov_limits().
|
||
+ */
|
||
+ smp_mb();
|
||
+
|
||
return true;
|
||
}
|
||
|
||
@@ -155,7 +166,6 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy,
|
||
unsigned int freq = arch_scale_freq_invariant() ?
|
||
policy->cpuinfo.max_freq : policy->cur;
|
||
|
||
- util = map_util_perf(util);
|
||
freq = map_util_freq(util, freq, max);
|
||
|
||
if (freq == sg_policy->cached_raw_freq && !sg_policy->need_freq_update)
|
||
@@ -165,14 +175,30 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy,
|
||
return cpufreq_driver_resolve_freq(policy, freq);
|
||
}
|
||
|
||
+unsigned long sugov_effective_cpu_perf(int cpu, unsigned long actual,
|
||
+ unsigned long min,
|
||
+ unsigned long max)
|
||
+{
|
||
+ /* Add dvfs headroom to actual utilization */
|
||
+ actual = map_util_perf(actual);
|
||
+ /* Actually we don't need to target the max performance */
|
||
+ if (actual < max)
|
||
+ max = actual;
|
||
+
|
||
+ /*
|
||
+ * Ensure at least minimum performance while providing more compute
|
||
+ * capacity when possible.
|
||
+ */
|
||
+ return max(min, max);
|
||
+}
|
||
+
|
||
static void sugov_get_util(struct sugov_cpu *sg_cpu)
|
||
{
|
||
- unsigned long util = cpu_util_cfs_boost(sg_cpu->cpu);
|
||
- struct rq *rq = cpu_rq(sg_cpu->cpu);
|
||
+ unsigned long min, max, util = cpu_util_cfs_boost(sg_cpu->cpu);
|
||
|
||
- sg_cpu->bw_dl = cpu_bw_dl(rq);
|
||
- sg_cpu->util = effective_cpu_util(sg_cpu->cpu, util,
|
||
- FREQUENCY_UTIL, NULL);
|
||
+ util = effective_cpu_util(sg_cpu->cpu, util, &min, &max);
|
||
+ sg_cpu->bw_min = min;
|
||
+ sg_cpu->util = sugov_effective_cpu_perf(sg_cpu->cpu, util, min, max);
|
||
}
|
||
|
||
/**
|
||
@@ -318,8 +344,8 @@ static inline bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) { return false; }
|
||
*/
|
||
static inline void ignore_dl_rate_limit(struct sugov_cpu *sg_cpu)
|
||
{
|
||
- if (cpu_bw_dl(cpu_rq(sg_cpu->cpu)) > sg_cpu->bw_dl)
|
||
- sg_cpu->sg_policy->limits_changed = true;
|
||
+ if (cpu_bw_dl(cpu_rq(sg_cpu->cpu)) > sg_cpu->bw_min)
|
||
+ WRITE_ONCE(sg_cpu->sg_policy->limits_changed, true);
|
||
}
|
||
|
||
static inline bool sugov_update_single_common(struct sugov_cpu *sg_cpu,
|
||
@@ -419,8 +445,8 @@ static void sugov_update_single_perf(struct update_util_data *hook, u64 time,
|
||
sugov_cpu_is_busy(sg_cpu) && sg_cpu->util < prev_util)
|
||
sg_cpu->util = prev_util;
|
||
|
||
- cpufreq_driver_adjust_perf(sg_cpu->cpu, map_util_perf(sg_cpu->bw_dl),
|
||
- map_util_perf(sg_cpu->util), max_cap);
|
||
+ cpufreq_driver_adjust_perf(sg_cpu->cpu, sg_cpu->bw_min,
|
||
+ sg_cpu->util, max_cap);
|
||
|
||
sg_cpu->sg_policy->last_freq_update_time = time;
|
||
}
|
||
@@ -829,7 +855,16 @@ static void sugov_limits(struct cpufreq_policy *policy)
|
||
mutex_unlock(&sg_policy->work_lock);
|
||
}
|
||
|
||
- sg_policy->limits_changed = true;
|
||
+ /*
|
||
+ * The limits_changed update below must take place before the updates
|
||
+ * of policy limits in cpufreq_set_policy() or a policy limits update
|
||
+ * might be missed, so use a memory barrier to ensure it.
|
||
+ *
|
||
+ * This pairs with the memory barrier in sugov_should_update_freq().
|
||
+ */
|
||
+ smp_wmb();
|
||
+
|
||
+ WRITE_ONCE(sg_policy->limits_changed, true);
|
||
}
|
||
|
||
struct cpufreq_governor schedutil_gov = {
|
||
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
|
||
index 6c639e48e49a97..a15cf7969953a5 100644
|
||
--- a/kernel/sched/deadline.c
|
||
+++ b/kernel/sched/deadline.c
|
||
@@ -132,7 +132,7 @@ static inline unsigned long __dl_bw_capacity(const struct cpumask *mask)
|
||
int i;
|
||
|
||
for_each_cpu_and(i, mask, cpu_active_mask)
|
||
- cap += capacity_orig_of(i);
|
||
+ cap += arch_scale_cpu_capacity(i);
|
||
|
||
return cap;
|
||
}
|
||
@@ -144,7 +144,7 @@ static inline unsigned long __dl_bw_capacity(const struct cpumask *mask)
|
||
static inline unsigned long dl_bw_capacity(int i)
|
||
{
|
||
if (!sched_asym_cpucap_active() &&
|
||
- capacity_orig_of(i) == SCHED_CAPACITY_SCALE) {
|
||
+ arch_scale_cpu_capacity(i) == SCHED_CAPACITY_SCALE) {
|
||
return dl_bw_cpus(i) << SCHED_CAPACITY_SHIFT;
|
||
} else {
|
||
RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held(),
|
||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
|
||
index 2808dbdd03847e..268e2a49b964e0 100644
|
||
--- a/kernel/sched/fair.c
|
||
+++ b/kernel/sched/fair.c
|
||
@@ -4951,7 +4951,7 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
|
||
* To avoid overestimation of actual task utilization, skip updates if
|
||
* we cannot grant there is idle time in this CPU.
|
||
*/
|
||
- if (task_util(p) > capacity_orig_of(cpu_of(rq_of(cfs_rq))))
|
||
+ if (task_util(p) > arch_scale_cpu_capacity(cpu_of(rq_of(cfs_rq))))
|
||
return;
|
||
|
||
/*
|
||
@@ -4999,14 +4999,14 @@ static inline int util_fits_cpu(unsigned long util,
|
||
return fits;
|
||
|
||
/*
|
||
- * We must use capacity_orig_of() for comparing against uclamp_min and
|
||
+ * We must use arch_scale_cpu_capacity() for comparing against uclamp_min and
|
||
* uclamp_max. We only care about capacity pressure (by using
|
||
* capacity_of()) for comparing against the real util.
|
||
*
|
||
* If a task is boosted to 1024 for example, we don't want a tiny
|
||
* pressure to skew the check whether it fits a CPU or not.
|
||
*
|
||
- * Similarly if a task is capped to capacity_orig_of(little_cpu), it
|
||
+ * Similarly if a task is capped to arch_scale_cpu_capacity(little_cpu), it
|
||
* should fit a little cpu even if there's some pressure.
|
||
*
|
||
* Only exception is for thermal pressure since it has a direct impact
|
||
@@ -5018,7 +5018,7 @@ static inline int util_fits_cpu(unsigned long util,
|
||
* For uclamp_max, we can tolerate a drop in performance level as the
|
||
* goal is to cap the task. So it's okay if it's getting less.
|
||
*/
|
||
- capacity_orig = capacity_orig_of(cpu);
|
||
+ capacity_orig = arch_scale_cpu_capacity(cpu);
|
||
capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu);
|
||
|
||
/*
|
||
@@ -7515,7 +7515,7 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
|
||
* Look for the CPU with best capacity.
|
||
*/
|
||
else if (fits < 0)
|
||
- cpu_cap = capacity_orig_of(cpu) - thermal_load_avg(cpu_rq(cpu));
|
||
+ cpu_cap = arch_scale_cpu_capacity(cpu) - thermal_load_avg(cpu_rq(cpu));
|
||
|
||
/*
|
||
* First, select CPU which fits better (-1 being better than 0).
|
||
@@ -7757,7 +7757,7 @@ cpu_util(int cpu, struct task_struct *p, int dst_cpu, int boost)
|
||
util = max(util, util_est);
|
||
}
|
||
|
||
- return min(util, capacity_orig_of(cpu));
|
||
+ return min(util, arch_scale_cpu_capacity(cpu));
|
||
}
|
||
|
||
unsigned long cpu_util_cfs(int cpu)
|
||
@@ -7859,7 +7859,7 @@ static inline void eenv_pd_busy_time(struct energy_env *eenv,
|
||
for_each_cpu(cpu, pd_cpus) {
|
||
unsigned long util = cpu_util(cpu, p, -1, 0);
|
||
|
||
- busy_time += effective_cpu_util(cpu, util, ENERGY_UTIL, NULL);
|
||
+ busy_time += effective_cpu_util(cpu, util, NULL, NULL);
|
||
}
|
||
|
||
eenv->pd_busy_time = min(eenv->pd_cap, busy_time);
|
||
@@ -7882,7 +7882,7 @@ eenv_pd_max_util(struct energy_env *eenv, struct cpumask *pd_cpus,
|
||
for_each_cpu(cpu, pd_cpus) {
|
||
struct task_struct *tsk = (cpu == dst_cpu) ? p : NULL;
|
||
unsigned long util = cpu_util(cpu, p, dst_cpu, 1);
|
||
- unsigned long eff_util;
|
||
+ unsigned long eff_util, min, max;
|
||
|
||
/*
|
||
* Performance domain frequency: utilization clamping
|
||
@@ -7891,7 +7891,23 @@ eenv_pd_max_util(struct energy_env *eenv, struct cpumask *pd_cpus,
|
||
* NOTE: in case RT tasks are running, by default the
|
||
* FREQUENCY_UTIL's utilization can be max OPP.
|
||
*/
|
||
- eff_util = effective_cpu_util(cpu, util, FREQUENCY_UTIL, tsk);
|
||
+ eff_util = effective_cpu_util(cpu, util, &min, &max);
|
||
+
|
||
+ /* Task's uclamp can modify min and max value */
|
||
+ if (tsk && uclamp_is_used()) {
|
||
+ min = max(min, uclamp_eff_value(p, UCLAMP_MIN));
|
||
+
|
||
+ /*
|
||
+ * If there is no active max uclamp constraint,
|
||
+ * directly use task's one, otherwise keep max.
|
||
+ */
|
||
+ if (uclamp_rq_is_idle(cpu_rq(cpu)))
|
||
+ max = uclamp_eff_value(p, UCLAMP_MAX);
|
||
+ else
|
||
+ max = max(max, uclamp_eff_value(p, UCLAMP_MAX));
|
||
+ }
|
||
+
|
||
+ eff_util = sugov_effective_cpu_perf(cpu, eff_util, min, max);
|
||
max_util = max(max_util, eff_util);
|
||
}
|
||
|
||
@@ -9544,8 +9560,6 @@ static void update_cpu_capacity(struct sched_domain *sd, int cpu)
|
||
unsigned long capacity = scale_rt_capacity(cpu);
|
||
struct sched_group *sdg = sd->groups;
|
||
|
||
- cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(cpu);
|
||
-
|
||
if (!capacity)
|
||
capacity = 1;
|
||
|
||
@@ -9621,7 +9635,7 @@ static inline int
|
||
check_cpu_capacity(struct rq *rq, struct sched_domain *sd)
|
||
{
|
||
return ((rq->cpu_capacity * sd->imbalance_pct) <
|
||
- (rq->cpu_capacity_orig * 100));
|
||
+ (arch_scale_cpu_capacity(cpu_of(rq)) * 100));
|
||
}
|
||
|
||
/*
|
||
@@ -9632,7 +9646,7 @@ check_cpu_capacity(struct rq *rq, struct sched_domain *sd)
|
||
static inline int check_misfit_status(struct rq *rq, struct sched_domain *sd)
|
||
{
|
||
return rq->misfit_task_load &&
|
||
- (rq->cpu_capacity_orig < rq->rd->max_cpu_capacity ||
|
||
+ (arch_scale_cpu_capacity(rq->cpu) < rq->rd->max_cpu_capacity ||
|
||
check_cpu_capacity(rq, sd));
|
||
}
|
||
|
||
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
|
||
index b89223a973168f..91b1ee0d81fce4 100644
|
||
--- a/kernel/sched/rt.c
|
||
+++ b/kernel/sched/rt.c
|
||
@@ -519,7 +519,7 @@ static inline bool rt_task_fits_capacity(struct task_struct *p, int cpu)
|
||
min_cap = uclamp_eff_value(p, UCLAMP_MIN);
|
||
max_cap = uclamp_eff_value(p, UCLAMP_MAX);
|
||
|
||
- cpu_cap = capacity_orig_of(cpu);
|
||
+ cpu_cap = arch_scale_cpu_capacity(cpu);
|
||
|
||
return cpu_cap >= min(min_cap, max_cap);
|
||
}
|
||
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
|
||
index d48c6a292a83db..60dc51f43dd91f 100644
|
||
--- a/kernel/sched/sched.h
|
||
+++ b/kernel/sched/sched.h
|
||
@@ -1048,7 +1048,6 @@ struct rq {
|
||
struct sched_domain __rcu *sd;
|
||
|
||
unsigned long cpu_capacity;
|
||
- unsigned long cpu_capacity_orig;
|
||
|
||
struct balance_callback *balance_callback;
|
||
|
||
@@ -2985,29 +2984,14 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {}
|
||
#endif
|
||
|
||
#ifdef CONFIG_SMP
|
||
-static inline unsigned long capacity_orig_of(int cpu)
|
||
-{
|
||
- return cpu_rq(cpu)->cpu_capacity_orig;
|
||
-}
|
||
+unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
|
||
+ unsigned long *min,
|
||
+ unsigned long *max);
|
||
|
||
-/**
|
||
- * enum cpu_util_type - CPU utilization type
|
||
- * @FREQUENCY_UTIL: Utilization used to select frequency
|
||
- * @ENERGY_UTIL: Utilization used during energy calculation
|
||
- *
|
||
- * The utilization signals of all scheduling classes (CFS/RT/DL) and IRQ time
|
||
- * need to be aggregated differently depending on the usage made of them. This
|
||
- * enum is used within effective_cpu_util() to differentiate the types of
|
||
- * utilization expected by the callers, and adjust the aggregation accordingly.
|
||
- */
|
||
-enum cpu_util_type {
|
||
- FREQUENCY_UTIL,
|
||
- ENERGY_UTIL,
|
||
-};
|
||
+unsigned long sugov_effective_cpu_perf(int cpu, unsigned long actual,
|
||
+ unsigned long min,
|
||
+ unsigned long max);
|
||
|
||
-unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
|
||
- enum cpu_util_type type,
|
||
- struct task_struct *p);
|
||
|
||
/*
|
||
* Verify the fitness of task @p to run on @cpu taking into account the
|
||
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
|
||
index 2ed884bb362137..c61698cff0f3a8 100644
|
||
--- a/kernel/sched/topology.c
|
||
+++ b/kernel/sched/topology.c
|
||
@@ -2486,12 +2486,15 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att
|
||
/* Attach the domains */
|
||
rcu_read_lock();
|
||
for_each_cpu(i, cpu_map) {
|
||
+ unsigned long capacity;
|
||
+
|
||
rq = cpu_rq(i);
|
||
sd = *per_cpu_ptr(d.sd, i);
|
||
|
||
+ capacity = arch_scale_cpu_capacity(i);
|
||
/* Use READ_ONCE()/WRITE_ONCE() to avoid load/store tearing: */
|
||
- if (rq->cpu_capacity_orig > READ_ONCE(d.rd->max_cpu_capacity))
|
||
- WRITE_ONCE(d.rd->max_cpu_capacity, rq->cpu_capacity_orig);
|
||
+ if (capacity > READ_ONCE(d.rd->max_cpu_capacity))
|
||
+ WRITE_ONCE(d.rd->max_cpu_capacity, capacity);
|
||
|
||
cpu_attach_domain(sd, d.rd, i);
|
||
}
|
||
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
|
||
index 7f2b17fc8ce403..ecdb8c2b2cab21 100644
|
||
--- a/kernel/time/tick-common.c
|
||
+++ b/kernel/time/tick-common.c
|
||
@@ -495,6 +495,7 @@ void tick_resume(void)
|
||
|
||
#ifdef CONFIG_SUSPEND
|
||
static DEFINE_RAW_SPINLOCK(tick_freeze_lock);
|
||
+static DEFINE_WAIT_OVERRIDE_MAP(tick_freeze_map, LD_WAIT_SLEEP);
|
||
static unsigned int tick_freeze_depth;
|
||
|
||
/**
|
||
@@ -514,9 +515,22 @@ void tick_freeze(void)
|
||
if (tick_freeze_depth == num_online_cpus()) {
|
||
trace_suspend_resume(TPS("timekeeping_freeze"),
|
||
smp_processor_id(), true);
|
||
+ /*
|
||
+ * All other CPUs have their interrupts disabled and are
|
||
+ * suspended to idle. Other tasks have been frozen so there
|
||
+ * is no scheduling happening. This means that there is no
|
||
+ * concurrency in the system at this point. Therefore it is
|
||
+ * okay to acquire a sleeping lock on PREEMPT_RT, such as a
|
||
+ * spinlock, because the lock cannot be held by other CPUs
|
||
+ * or threads and acquiring it cannot block.
|
||
+ *
|
||
+ * Inform lockdep about the situation.
|
||
+ */
|
||
+ lock_map_acquire_try(&tick_freeze_map);
|
||
system_state = SYSTEM_SUSPEND;
|
||
sched_clock_suspend();
|
||
timekeeping_suspend();
|
||
+ lock_map_release(&tick_freeze_map);
|
||
} else {
|
||
tick_suspend_local();
|
||
}
|
||
@@ -538,8 +552,16 @@ void tick_unfreeze(void)
|
||
raw_spin_lock(&tick_freeze_lock);
|
||
|
||
if (tick_freeze_depth == num_online_cpus()) {
|
||
+ /*
|
||
+ * Similar to tick_freeze(). On resumption the first CPU may
|
||
+ * acquire uncontended sleeping locks while other CPUs block on
|
||
+ * tick_freeze_lock.
|
||
+ */
|
||
+ lock_map_acquire_try(&tick_freeze_map);
|
||
timekeeping_resume();
|
||
sched_clock_resume();
|
||
+ lock_map_release(&tick_freeze_map);
|
||
+
|
||
system_state = SYSTEM_RUNNING;
|
||
trace_suspend_resume(TPS("timekeeping_freeze"),
|
||
smp_processor_id(), false);
|
||
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
|
||
index 545393601be8ce..97f660a8ddc73d 100644
|
||
--- a/kernel/trace/bpf_trace.c
|
||
+++ b/kernel/trace/bpf_trace.c
|
||
@@ -400,7 +400,7 @@ static const struct bpf_func_proto bpf_trace_printk_proto = {
|
||
.arg2_type = ARG_CONST_SIZE,
|
||
};
|
||
|
||
-static void __set_printk_clr_event(void)
|
||
+static void __set_printk_clr_event(struct work_struct *work)
|
||
{
|
||
/*
|
||
* This program might be calling bpf_trace_printk,
|
||
@@ -413,10 +413,11 @@ static void __set_printk_clr_event(void)
|
||
if (trace_set_clr_event("bpf_trace", "bpf_trace_printk", 1))
|
||
pr_warn_ratelimited("could not enable bpf_trace_printk events");
|
||
}
|
||
+static DECLARE_WORK(set_printk_work, __set_printk_clr_event);
|
||
|
||
const struct bpf_func_proto *bpf_get_trace_printk_proto(void)
|
||
{
|
||
- __set_printk_clr_event();
|
||
+ schedule_work(&set_printk_work);
|
||
return &bpf_trace_printk_proto;
|
||
}
|
||
|
||
@@ -459,7 +460,7 @@ static const struct bpf_func_proto bpf_trace_vprintk_proto = {
|
||
|
||
const struct bpf_func_proto *bpf_get_trace_vprintk_proto(void)
|
||
{
|
||
- __set_printk_clr_event();
|
||
+ schedule_work(&set_printk_work);
|
||
return &bpf_trace_vprintk_proto;
|
||
}
|
||
|
||
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
|
||
index 1a936978c2b1a6..5f74e9f9c8a734 100644
|
||
--- a/kernel/trace/trace_events.c
|
||
+++ b/kernel/trace/trace_events.c
|
||
@@ -470,6 +470,7 @@ static void test_event_printk(struct trace_event_call *call)
|
||
case '%':
|
||
continue;
|
||
case 'p':
|
||
+ do_pointer:
|
||
/* Find dereferencing fields */
|
||
switch (fmt[i + 1]) {
|
||
case 'B': case 'R': case 'r':
|
||
@@ -498,6 +499,12 @@ static void test_event_printk(struct trace_event_call *call)
|
||
continue;
|
||
if (fmt[i + j] == '*') {
|
||
star = true;
|
||
+ /* Handle %*pbl case */
|
||
+ if (!j && fmt[i + 1] == 'p') {
|
||
+ arg++;
|
||
+ i++;
|
||
+ goto do_pointer;
|
||
+ }
|
||
continue;
|
||
}
|
||
if ((fmt[i + j] == 's')) {
|
||
diff --git a/lib/test_ubsan.c b/lib/test_ubsan.c
|
||
index 2062be1f2e80f6..f90f2b9842ec4f 100644
|
||
--- a/lib/test_ubsan.c
|
||
+++ b/lib/test_ubsan.c
|
||
@@ -35,18 +35,22 @@ static void test_ubsan_shift_out_of_bounds(void)
|
||
|
||
static void test_ubsan_out_of_bounds(void)
|
||
{
|
||
- volatile int i = 4, j = 5, k = -1;
|
||
- volatile char above[4] = { }; /* Protect surrounding memory. */
|
||
- volatile int arr[4];
|
||
- volatile char below[4] = { }; /* Protect surrounding memory. */
|
||
+ int i = 4, j = 4, k = -1;
|
||
+ volatile struct {
|
||
+ char above[4]; /* Protect surrounding memory. */
|
||
+ int arr[4];
|
||
+ char below[4]; /* Protect surrounding memory. */
|
||
+ } data;
|
||
|
||
- above[0] = below[0];
|
||
+ OPTIMIZER_HIDE_VAR(i);
|
||
+ OPTIMIZER_HIDE_VAR(j);
|
||
+ OPTIMIZER_HIDE_VAR(k);
|
||
|
||
UBSAN_TEST(CONFIG_UBSAN_BOUNDS, "above");
|
||
- arr[j] = i;
|
||
+ data.arr[j] = i;
|
||
|
||
UBSAN_TEST(CONFIG_UBSAN_BOUNDS, "below");
|
||
- arr[k] = i;
|
||
+ data.arr[k] = i;
|
||
}
|
||
|
||
enum ubsan_test_enum {
|
||
diff --git a/net/9p/client.c b/net/9p/client.c
|
||
index d841d82e908fe3..cf73fe306219a9 100644
|
||
--- a/net/9p/client.c
|
||
+++ b/net/9p/client.c
|
||
@@ -1547,7 +1547,8 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
|
||
struct p9_client *clnt = fid->clnt;
|
||
struct p9_req_t *req;
|
||
int count = iov_iter_count(to);
|
||
- int rsize, received, non_zc = 0;
|
||
+ u32 rsize, received;
|
||
+ bool non_zc = false;
|
||
char *dataptr;
|
||
|
||
*err = 0;
|
||
@@ -1570,7 +1571,7 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
|
||
0, 11, "dqd", fid->fid,
|
||
offset, rsize);
|
||
} else {
|
||
- non_zc = 1;
|
||
+ non_zc = true;
|
||
req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
|
||
rsize);
|
||
}
|
||
@@ -1591,11 +1592,11 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
|
||
return 0;
|
||
}
|
||
if (rsize < received) {
|
||
- pr_err("bogus RREAD count (%d > %d)\n", received, rsize);
|
||
+ pr_err("bogus RREAD count (%u > %u)\n", received, rsize);
|
||
received = rsize;
|
||
}
|
||
|
||
- p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", received);
|
||
+ p9_debug(P9_DEBUG_9P, "<<< RREAD count %u\n", received);
|
||
|
||
if (non_zc) {
|
||
int n = copy_to_iter(dataptr, received, to);
|
||
@@ -1622,9 +1623,9 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
|
||
*err = 0;
|
||
|
||
while (iov_iter_count(from)) {
|
||
- int count = iov_iter_count(from);
|
||
- int rsize = fid->iounit;
|
||
- int written;
|
||
+ size_t count = iov_iter_count(from);
|
||
+ u32 rsize = fid->iounit;
|
||
+ u32 written;
|
||
|
||
if (!rsize || rsize > clnt->msize - P9_IOHDRSZ)
|
||
rsize = clnt->msize - P9_IOHDRSZ;
|
||
@@ -1632,7 +1633,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
|
||
if (count < rsize)
|
||
rsize = count;
|
||
|
||
- p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d (/%d)\n",
|
||
+ p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %u (/%zu)\n",
|
||
fid->fid, offset, rsize, count);
|
||
|
||
/* Don't bother zerocopy for small IO (< 1024) */
|
||
@@ -1658,11 +1659,11 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
|
||
break;
|
||
}
|
||
if (rsize < written) {
|
||
- pr_err("bogus RWRITE count (%d > %d)\n", written, rsize);
|
||
+ pr_err("bogus RWRITE count (%u > %u)\n", written, rsize);
|
||
written = rsize;
|
||
}
|
||
|
||
- p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", written);
|
||
+ p9_debug(P9_DEBUG_9P, "<<< RWRITE count %u\n", written);
|
||
|
||
p9_req_put(clnt, req);
|
||
iov_iter_revert(from, count - written - iov_iter_count(from));
|
||
@@ -2049,7 +2050,8 @@ EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
|
||
|
||
int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
|
||
{
|
||
- int err, rsize, non_zc = 0;
|
||
+ int err, non_zc = 0;
|
||
+ u32 rsize;
|
||
struct p9_client *clnt;
|
||
struct p9_req_t *req;
|
||
char *dataptr;
|
||
@@ -2058,7 +2060,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
|
||
|
||
iov_iter_kvec(&to, ITER_DEST, &kv, 1, count);
|
||
|
||
- p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
|
||
+ p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %u\n",
|
||
fid->fid, offset, count);
|
||
|
||
clnt = fid->clnt;
|
||
@@ -2093,11 +2095,11 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
|
||
goto free_and_error;
|
||
}
|
||
if (rsize < count) {
|
||
- pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize);
|
||
+ pr_err("bogus RREADDIR count (%u > %u)\n", count, rsize);
|
||
count = rsize;
|
||
}
|
||
|
||
- p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
|
||
+ p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %u\n", count);
|
||
|
||
if (non_zc)
|
||
memmove(data, dataptr, count);
|
||
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
|
||
index 4417a18b3e951a..f63586c9ce0216 100644
|
||
--- a/net/core/lwtunnel.c
|
||
+++ b/net/core/lwtunnel.c
|
||
@@ -332,6 +332,8 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||
struct dst_entry *dst;
|
||
int ret;
|
||
|
||
+ local_bh_disable();
|
||
+
|
||
if (dev_xmit_recursion()) {
|
||
net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
|
||
__func__);
|
||
@@ -347,8 +349,10 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||
lwtstate = dst->lwtstate;
|
||
|
||
if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
|
||
- lwtstate->type > LWTUNNEL_ENCAP_MAX)
|
||
- return 0;
|
||
+ lwtstate->type > LWTUNNEL_ENCAP_MAX) {
|
||
+ ret = 0;
|
||
+ goto out;
|
||
+ }
|
||
|
||
ret = -EOPNOTSUPP;
|
||
rcu_read_lock();
|
||
@@ -363,11 +367,13 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||
if (ret == -EOPNOTSUPP)
|
||
goto drop;
|
||
|
||
- return ret;
|
||
+ goto out;
|
||
|
||
drop:
|
||
kfree_skb(skb);
|
||
|
||
+out:
|
||
+ local_bh_enable();
|
||
return ret;
|
||
}
|
||
EXPORT_SYMBOL_GPL(lwtunnel_output);
|
||
@@ -379,6 +385,8 @@ int lwtunnel_xmit(struct sk_buff *skb)
|
||
struct dst_entry *dst;
|
||
int ret;
|
||
|
||
+ local_bh_disable();
|
||
+
|
||
if (dev_xmit_recursion()) {
|
||
net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
|
||
__func__);
|
||
@@ -395,8 +403,10 @@ int lwtunnel_xmit(struct sk_buff *skb)
|
||
lwtstate = dst->lwtstate;
|
||
|
||
if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
|
||
- lwtstate->type > LWTUNNEL_ENCAP_MAX)
|
||
- return 0;
|
||
+ lwtstate->type > LWTUNNEL_ENCAP_MAX) {
|
||
+ ret = 0;
|
||
+ goto out;
|
||
+ }
|
||
|
||
ret = -EOPNOTSUPP;
|
||
rcu_read_lock();
|
||
@@ -411,11 +421,13 @@ int lwtunnel_xmit(struct sk_buff *skb)
|
||
if (ret == -EOPNOTSUPP)
|
||
goto drop;
|
||
|
||
- return ret;
|
||
+ goto out;
|
||
|
||
drop:
|
||
kfree_skb(skb);
|
||
|
||
+out:
|
||
+ local_bh_enable();
|
||
return ret;
|
||
}
|
||
EXPORT_SYMBOL_GPL(lwtunnel_xmit);
|
||
@@ -427,6 +439,8 @@ int lwtunnel_input(struct sk_buff *skb)
|
||
struct dst_entry *dst;
|
||
int ret;
|
||
|
||
+ DEBUG_NET_WARN_ON_ONCE(!in_softirq());
|
||
+
|
||
if (dev_xmit_recursion()) {
|
||
net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
|
||
__func__);
|
||
diff --git a/net/core/selftests.c b/net/core/selftests.c
|
||
index acb1ee97bbd324..7af99d07762ea0 100644
|
||
--- a/net/core/selftests.c
|
||
+++ b/net/core/selftests.c
|
||
@@ -100,10 +100,10 @@ static struct sk_buff *net_test_get_skb(struct net_device *ndev,
|
||
ehdr->h_proto = htons(ETH_P_IP);
|
||
|
||
if (attr->tcp) {
|
||
+ memset(thdr, 0, sizeof(*thdr));
|
||
thdr->source = htons(attr->sport);
|
||
thdr->dest = htons(attr->dport);
|
||
thdr->doff = sizeof(struct tcphdr) / 4;
|
||
- thdr->check = 0;
|
||
} else {
|
||
uhdr->source = htons(attr->sport);
|
||
uhdr->dest = htons(attr->dport);
|
||
@@ -144,10 +144,18 @@ static struct sk_buff *net_test_get_skb(struct net_device *ndev,
|
||
attr->id = net_test_next_id;
|
||
shdr->id = net_test_next_id++;
|
||
|
||
- if (attr->size)
|
||
- skb_put(skb, attr->size);
|
||
- if (attr->max_size && attr->max_size > skb->len)
|
||
- skb_put(skb, attr->max_size - skb->len);
|
||
+ if (attr->size) {
|
||
+ void *payload = skb_put(skb, attr->size);
|
||
+
|
||
+ memset(payload, 0, attr->size);
|
||
+ }
|
||
+
|
||
+ if (attr->max_size && attr->max_size > skb->len) {
|
||
+ size_t pad_len = attr->max_size - skb->len;
|
||
+ void *pad = skb_put(skb, pad_len);
|
||
+
|
||
+ memset(pad, 0, pad_len);
|
||
+ }
|
||
|
||
skb->csum = 0;
|
||
skb->ip_summed = CHECKSUM_PARTIAL;
|
||
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
|
||
index 880c5f16b29ccf..371255e624332f 100644
|
||
--- a/net/sched/sch_hfsc.c
|
||
+++ b/net/sched/sch_hfsc.c
|
||
@@ -958,6 +958,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||
|
||
if (cl != NULL) {
|
||
int old_flags;
|
||
+ int len = 0;
|
||
|
||
if (parentid) {
|
||
if (cl->cl_parent &&
|
||
@@ -988,9 +989,13 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||
if (usc != NULL)
|
||
hfsc_change_usc(cl, usc, cur_time);
|
||
|
||
+ if (cl->qdisc->q.qlen != 0)
|
||
+ len = qdisc_peek_len(cl->qdisc);
|
||
+ /* Check queue length again since some qdisc implementations
|
||
+ * (e.g., netem/codel) might empty the queue during the peek
|
||
+ * operation.
|
||
+ */
|
||
if (cl->qdisc->q.qlen != 0) {
|
||
- int len = qdisc_peek_len(cl->qdisc);
|
||
-
|
||
if (cl->cl_flags & HFSC_RSC) {
|
||
if (old_flags & HFSC_RSC)
|
||
update_ed(cl, len);
|
||
@@ -1633,10 +1638,16 @@ hfsc_dequeue(struct Qdisc *sch)
|
||
if (cl->qdisc->q.qlen != 0) {
|
||
/* update ed */
|
||
next_len = qdisc_peek_len(cl->qdisc);
|
||
- if (realtime)
|
||
- update_ed(cl, next_len);
|
||
- else
|
||
- update_d(cl, next_len);
|
||
+ /* Check queue length again since some qdisc implementations
|
||
+ * (e.g., netem/codel) might empty the queue during the peek
|
||
+ * operation.
|
||
+ */
|
||
+ if (cl->qdisc->q.qlen != 0) {
|
||
+ if (realtime)
|
||
+ update_ed(cl, next_len);
|
||
+ else
|
||
+ update_d(cl, next_len);
|
||
+ }
|
||
} else {
|
||
/* the class becomes passive */
|
||
eltree_remove(cl);
|
||
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
|
||
index 77a3d016cadec1..ddc3e4e5e18d78 100644
|
||
--- a/net/tipc/monitor.c
|
||
+++ b/net/tipc/monitor.c
|
||
@@ -716,7 +716,8 @@ void tipc_mon_reinit_self(struct net *net)
|
||
if (!mon)
|
||
continue;
|
||
write_lock_bh(&mon->lock);
|
||
- mon->self->addr = tipc_own_addr(net);
|
||
+ if (mon->self)
|
||
+ mon->self->addr = tipc_own_addr(net);
|
||
write_unlock_bh(&mon->lock);
|
||
}
|
||
}
|
||
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h
|
||
index 1c6b843b8c4eeb..06be777b3b14b7 100644
|
||
--- a/samples/trace_events/trace-events-sample.h
|
||
+++ b/samples/trace_events/trace-events-sample.h
|
||
@@ -302,6 +302,7 @@ TRACE_EVENT(foo_bar,
|
||
__bitmask( cpus, num_possible_cpus() )
|
||
__cpumask( cpum )
|
||
__vstring( vstr, fmt, va )
|
||
+ __string_len( lstr, foo, bar / 2 < strlen(foo) ? bar / 2 : strlen(foo) )
|
||
),
|
||
|
||
TP_fast_assign(
|
||
@@ -310,12 +311,14 @@ TRACE_EVENT(foo_bar,
|
||
memcpy(__get_dynamic_array(list), lst,
|
||
__length_of(lst) * sizeof(int));
|
||
__assign_str(str, string);
|
||
+ __assign_str(lstr, foo);
|
||
__assign_vstr(vstr, fmt, va);
|
||
__assign_bitmask(cpus, cpumask_bits(mask), num_possible_cpus());
|
||
__assign_cpumask(cpum, cpumask_bits(mask));
|
||
),
|
||
|
||
- TP_printk("foo %s %d %s %s %s %s (%s) (%s) %s", __entry->foo, __entry->bar,
|
||
+ TP_printk("foo %s %d %s %s %s %s %s %s (%s) (%s) %s [%d] %*pbl",
|
||
+ __entry->foo, __entry->bar,
|
||
|
||
/*
|
||
* Notice here the use of some helper functions. This includes:
|
||
@@ -359,8 +362,17 @@ TRACE_EVENT(foo_bar,
|
||
__print_array(__get_dynamic_array(list),
|
||
__get_dynamic_array_len(list) / sizeof(int),
|
||
sizeof(int)),
|
||
- __get_str(str), __get_bitmask(cpus), __get_cpumask(cpum),
|
||
- __get_str(vstr))
|
||
+
|
||
+/* A shortcut is to use __print_dynamic_array for dynamic arrays */
|
||
+
|
||
+ __print_dynamic_array(list, sizeof(int)),
|
||
+
|
||
+ __get_str(str), __get_str(lstr),
|
||
+ __get_bitmask(cpus), __get_cpumask(cpum),
|
||
+ __get_str(vstr),
|
||
+ __get_dynamic_array_len(cpus),
|
||
+ __get_dynamic_array_len(cpus),
|
||
+ __get_dynamic_array(cpus))
|
||
);
|
||
|
||
/*
|
||
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
|
||
index 44f20b1b853a50..4aecfb0a0ef6ae 100644
|
||
--- a/scripts/Makefile.lib
|
||
+++ b/scripts/Makefile.lib
|
||
@@ -268,7 +268,7 @@ objtool-args-$(CONFIG_SLS) += --sls
|
||
objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval
|
||
objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call
|
||
objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess
|
||
-objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable
|
||
+objtool-args-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV)) += --no-unreachable
|
||
objtool-args-$(CONFIG_PREFIX_SYMBOLS) += --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
|
||
|
||
objtool-args = $(objtool-args-y) \
|
||
diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
|
||
index 1b6e376f3833cb..fe222c4b74c006 100644
|
||
--- a/sound/soc/codecs/wcd934x.c
|
||
+++ b/sound/soc/codecs/wcd934x.c
|
||
@@ -2281,7 +2281,7 @@ static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data)
|
||
{
|
||
struct wcd934x_codec *wcd = data;
|
||
unsigned long status = 0;
|
||
- int i, j, port_id;
|
||
+ unsigned int i, j, port_id;
|
||
unsigned int val, int_val = 0;
|
||
irqreturn_t ret = IRQ_NONE;
|
||
bool tx;
|
||
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c
|
||
index ff9f6a1c95df19..40b6a837f66bbc 100644
|
||
--- a/sound/soc/qcom/apq8016_sbc.c
|
||
+++ b/sound/soc/qcom/apq8016_sbc.c
|
||
@@ -343,4 +343,4 @@ module_platform_driver(apq8016_sbc_platform_driver);
|
||
|
||
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
|
||
MODULE_DESCRIPTION("APQ8016 ASoC Machine Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c
|
||
index cddeb47dbcf213..8f1475685cb207 100644
|
||
--- a/sound/soc/qcom/apq8096.c
|
||
+++ b/sound/soc/qcom/apq8096.c
|
||
@@ -142,4 +142,4 @@ static struct platform_driver msm_snd_apq8096_driver = {
|
||
module_platform_driver(msm_snd_apq8096_driver);
|
||
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
|
||
MODULE_DESCRIPTION("APQ8096 ASoC Machine Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
|
||
index f2d1e3009cd23c..23beafbcc26c27 100644
|
||
--- a/sound/soc/qcom/common.c
|
||
+++ b/sound/soc/qcom/common.c
|
||
@@ -239,4 +239,4 @@ int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
|
||
return 0;
|
||
}
|
||
EXPORT_SYMBOL_GPL(qcom_snd_wcd_jack_setup);
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/lpass-apq8016.c b/sound/soc/qcom/lpass-apq8016.c
|
||
index f919d46e18caa8..63db0f152e9dbe 100644
|
||
--- a/sound/soc/qcom/lpass-apq8016.c
|
||
+++ b/sound/soc/qcom/lpass-apq8016.c
|
||
@@ -300,10 +300,10 @@ static struct platform_driver apq8016_lpass_cpu_platform_driver = {
|
||
.of_match_table = of_match_ptr(apq8016_lpass_cpu_device_id),
|
||
},
|
||
.probe = asoc_qcom_lpass_cpu_platform_probe,
|
||
- .remove = asoc_qcom_lpass_cpu_platform_remove,
|
||
+ .remove_new = asoc_qcom_lpass_cpu_platform_remove,
|
||
};
|
||
module_platform_driver(apq8016_lpass_cpu_platform_driver);
|
||
|
||
MODULE_DESCRIPTION("APQ8016 LPASS CPU Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
|
||
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
|
||
index e587455dc40a0e..bdb5e0c740a906 100644
|
||
--- a/sound/soc/qcom/lpass-cpu.c
|
||
+++ b/sound/soc/qcom/lpass-cpu.c
|
||
@@ -1284,15 +1284,12 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
|
||
}
|
||
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_probe);
|
||
|
||
-int asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev)
|
||
+void asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev)
|
||
{
|
||
struct lpass_data *drvdata = platform_get_drvdata(pdev);
|
||
|
||
if (drvdata->variant->exit)
|
||
drvdata->variant->exit(pdev);
|
||
-
|
||
-
|
||
- return 0;
|
||
}
|
||
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_remove);
|
||
|
||
@@ -1307,4 +1304,4 @@ void asoc_qcom_lpass_cpu_platform_shutdown(struct platform_device *pdev)
|
||
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_shutdown);
|
||
|
||
MODULE_DESCRIPTION("QTi LPASS CPU Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/lpass-hdmi.c b/sound/soc/qcom/lpass-hdmi.c
|
||
index 24b1a7523adb90..ce753ebc08945a 100644
|
||
--- a/sound/soc/qcom/lpass-hdmi.c
|
||
+++ b/sound/soc/qcom/lpass-hdmi.c
|
||
@@ -251,4 +251,4 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_hdmi_dai_ops = {
|
||
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_hdmi_dai_ops);
|
||
|
||
MODULE_DESCRIPTION("QTi LPASS HDMI Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/lpass-ipq806x.c b/sound/soc/qcom/lpass-ipq806x.c
|
||
index 2c97f295e39400..2a82684c04de45 100644
|
||
--- a/sound/soc/qcom/lpass-ipq806x.c
|
||
+++ b/sound/soc/qcom/lpass-ipq806x.c
|
||
@@ -172,9 +172,9 @@ static struct platform_driver ipq806x_lpass_cpu_platform_driver = {
|
||
.of_match_table = of_match_ptr(ipq806x_lpass_cpu_device_id),
|
||
},
|
||
.probe = asoc_qcom_lpass_cpu_platform_probe,
|
||
- .remove = asoc_qcom_lpass_cpu_platform_remove,
|
||
+ .remove_new = asoc_qcom_lpass_cpu_platform_remove,
|
||
};
|
||
module_platform_driver(ipq806x_lpass_cpu_platform_driver);
|
||
|
||
MODULE_DESCRIPTION("QTi LPASS CPU Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
|
||
index 73e3d39bd24c30..f918d9e16dc041 100644
|
||
--- a/sound/soc/qcom/lpass-platform.c
|
||
+++ b/sound/soc/qcom/lpass-platform.c
|
||
@@ -1383,4 +1383,4 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
|
||
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register);
|
||
|
||
MODULE_DESCRIPTION("QTi LPASS Platform Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c
|
||
index d16c0d83aaad92..98faf82c22568e 100644
|
||
--- a/sound/soc/qcom/lpass-sc7180.c
|
||
+++ b/sound/soc/qcom/lpass-sc7180.c
|
||
@@ -315,11 +315,11 @@ static struct platform_driver sc7180_lpass_cpu_platform_driver = {
|
||
.pm = &sc7180_lpass_pm_ops,
|
||
},
|
||
.probe = asoc_qcom_lpass_cpu_platform_probe,
|
||
- .remove = asoc_qcom_lpass_cpu_platform_remove,
|
||
+ .remove_new = asoc_qcom_lpass_cpu_platform_remove,
|
||
.shutdown = asoc_qcom_lpass_cpu_platform_shutdown,
|
||
};
|
||
|
||
module_platform_driver(sc7180_lpass_cpu_platform_driver);
|
||
|
||
MODULE_DESCRIPTION("SC7180 LPASS CPU DRIVER");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/lpass-sc7280.c b/sound/soc/qcom/lpass-sc7280.c
|
||
index 6b2eb25ed9390c..97b9053ed3b027 100644
|
||
--- a/sound/soc/qcom/lpass-sc7280.c
|
||
+++ b/sound/soc/qcom/lpass-sc7280.c
|
||
@@ -445,7 +445,7 @@ static struct platform_driver sc7280_lpass_cpu_platform_driver = {
|
||
.pm = &sc7280_lpass_pm_ops,
|
||
},
|
||
.probe = asoc_qcom_lpass_cpu_platform_probe,
|
||
- .remove = asoc_qcom_lpass_cpu_platform_remove,
|
||
+ .remove_new = asoc_qcom_lpass_cpu_platform_remove,
|
||
.shutdown = asoc_qcom_lpass_cpu_platform_shutdown,
|
||
};
|
||
|
||
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
|
||
index ea12f02eca55f6..5caec24555ea2e 100644
|
||
--- a/sound/soc/qcom/lpass.h
|
||
+++ b/sound/soc/qcom/lpass.h
|
||
@@ -399,8 +399,8 @@ struct lpass_pcm_data {
|
||
};
|
||
|
||
/* register the platform driver from the CPU DAI driver */
|
||
-int asoc_qcom_lpass_platform_register(struct platform_device *);
|
||
-int asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev);
|
||
+int asoc_qcom_lpass_platform_register(struct platform_device *pdev);
|
||
+void asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev);
|
||
void asoc_qcom_lpass_cpu_platform_shutdown(struct platform_device *pdev);
|
||
int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev);
|
||
extern const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops;
|
||
diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
|
||
index 919e326b9462b3..fcef53b97ff98a 100644
|
||
--- a/sound/soc/qcom/qdsp6/q6afe.c
|
||
+++ b/sound/soc/qcom/qdsp6/q6afe.c
|
||
@@ -552,13 +552,13 @@ struct q6afe_port {
|
||
};
|
||
|
||
struct afe_cmd_remote_lpass_core_hw_vote_request {
|
||
- uint32_t hw_block_id;
|
||
- char client_name[8];
|
||
+ uint32_t hw_block_id;
|
||
+ char client_name[8];
|
||
} __packed;
|
||
|
||
struct afe_cmd_remote_lpass_core_hw_devote_request {
|
||
- uint32_t hw_block_id;
|
||
- uint32_t client_handle;
|
||
+ uint32_t hw_block_id;
|
||
+ uint32_t client_handle;
|
||
} __packed;
|
||
|
||
|
||
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
|
||
index def05ce58d176e..179f4f7386dd00 100644
|
||
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
|
||
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
|
||
@@ -64,20 +64,16 @@ struct q6apm_dai_rtd {
|
||
phys_addr_t phys;
|
||
unsigned int pcm_size;
|
||
unsigned int pcm_count;
|
||
- unsigned int pos; /* Buffer position */
|
||
unsigned int periods;
|
||
unsigned int bytes_sent;
|
||
unsigned int bytes_received;
|
||
unsigned int copied_total;
|
||
uint16_t bits_per_sample;
|
||
- uint16_t source; /* Encoding source bit mask */
|
||
- uint16_t session_id;
|
||
+ snd_pcm_uframes_t queue_ptr;
|
||
bool next_track;
|
||
enum stream_state state;
|
||
struct q6apm_graph *graph;
|
||
spinlock_t lock;
|
||
- uint32_t initial_samples_drop;
|
||
- uint32_t trailing_samples_drop;
|
||
bool notify_on_drain;
|
||
};
|
||
|
||
@@ -127,25 +123,16 @@ static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, vo
|
||
{
|
||
struct q6apm_dai_rtd *prtd = priv;
|
||
struct snd_pcm_substream *substream = prtd->substream;
|
||
- unsigned long flags;
|
||
|
||
switch (opcode) {
|
||
case APM_CLIENT_EVENT_CMD_EOS_DONE:
|
||
prtd->state = Q6APM_STREAM_STOPPED;
|
||
break;
|
||
case APM_CLIENT_EVENT_DATA_WRITE_DONE:
|
||
- spin_lock_irqsave(&prtd->lock, flags);
|
||
- prtd->pos += prtd->pcm_count;
|
||
- spin_unlock_irqrestore(&prtd->lock, flags);
|
||
snd_pcm_period_elapsed(substream);
|
||
- if (prtd->state == Q6APM_STREAM_RUNNING)
|
||
- q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, 0);
|
||
|
||
break;
|
||
case APM_CLIENT_EVENT_DATA_READ_DONE:
|
||
- spin_lock_irqsave(&prtd->lock, flags);
|
||
- prtd->pos += prtd->pcm_count;
|
||
- spin_unlock_irqrestore(&prtd->lock, flags);
|
||
snd_pcm_period_elapsed(substream);
|
||
if (prtd->state == Q6APM_STREAM_RUNNING)
|
||
q6apm_read(prtd->graph);
|
||
@@ -251,7 +238,6 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
|
||
}
|
||
|
||
prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
|
||
- prtd->pos = 0;
|
||
/* rate and channels are sent to audio driver */
|
||
ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
|
||
if (ret < 0) {
|
||
@@ -297,6 +283,27 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
|
||
return 0;
|
||
}
|
||
|
||
+static int q6apm_dai_ack(struct snd_soc_component *component, struct snd_pcm_substream *substream)
|
||
+{
|
||
+ struct snd_pcm_runtime *runtime = substream->runtime;
|
||
+ struct q6apm_dai_rtd *prtd = runtime->private_data;
|
||
+ int i, ret = 0, avail_periods;
|
||
+
|
||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||
+ avail_periods = (runtime->control->appl_ptr - prtd->queue_ptr)/runtime->period_size;
|
||
+ for (i = 0; i < avail_periods; i++) {
|
||
+ ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP);
|
||
+ if (ret < 0) {
|
||
+ dev_err(component->dev, "Error queuing playback buffer %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
+ prtd->queue_ptr += runtime->period_size;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
static int q6apm_dai_trigger(struct snd_soc_component *component,
|
||
struct snd_pcm_substream *substream, int cmd)
|
||
{
|
||
@@ -308,9 +315,6 @@ static int q6apm_dai_trigger(struct snd_soc_component *component,
|
||
case SNDRV_PCM_TRIGGER_START:
|
||
case SNDRV_PCM_TRIGGER_RESUME:
|
||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||
- /* start writing buffers for playback only as we already queued capture buffers */
|
||
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||
- ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, 0);
|
||
break;
|
||
case SNDRV_PCM_TRIGGER_STOP:
|
||
/* TODO support be handled via SoftPause Module */
|
||
@@ -432,16 +436,12 @@ static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component,
|
||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||
struct q6apm_dai_rtd *prtd = runtime->private_data;
|
||
snd_pcm_uframes_t ptr;
|
||
- unsigned long flags;
|
||
|
||
- spin_lock_irqsave(&prtd->lock, flags);
|
||
- if (prtd->pos == prtd->pcm_size)
|
||
- prtd->pos = 0;
|
||
-
|
||
- ptr = bytes_to_frames(runtime, prtd->pos);
|
||
- spin_unlock_irqrestore(&prtd->lock, flags);
|
||
+ ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) * runtime->period_size;
|
||
+ if (ptr)
|
||
+ return ptr - 1;
|
||
|
||
- return ptr;
|
||
+ return 0;
|
||
}
|
||
|
||
static int q6apm_dai_hw_params(struct snd_soc_component *component,
|
||
@@ -656,8 +656,6 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
|
||
prtd->pcm_size = runtime->fragments * runtime->fragment_size;
|
||
prtd->bits_per_sample = 16;
|
||
|
||
- prtd->pos = 0;
|
||
-
|
||
if (prtd->next_track != true) {
|
||
memcpy(&prtd->codec, codec, sizeof(*codec));
|
||
|
||
@@ -721,14 +719,12 @@ static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component,
|
||
|
||
switch (metadata->key) {
|
||
case SNDRV_COMPRESS_ENCODER_PADDING:
|
||
- prtd->trailing_samples_drop = metadata->value[0];
|
||
q6apm_remove_trailing_silence(component->dev, prtd->graph,
|
||
- prtd->trailing_samples_drop);
|
||
+ metadata->value[0]);
|
||
break;
|
||
case SNDRV_COMPRESS_ENCODER_DELAY:
|
||
- prtd->initial_samples_drop = metadata->value[0];
|
||
q6apm_remove_initial_silence(component->dev, prtd->graph,
|
||
- prtd->initial_samples_drop);
|
||
+ metadata->value[0]);
|
||
break;
|
||
default:
|
||
ret = -EINVAL;
|
||
@@ -840,6 +836,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = {
|
||
.hw_params = q6apm_dai_hw_params,
|
||
.pointer = q6apm_dai_pointer,
|
||
.trigger = q6apm_dai_trigger,
|
||
+ .ack = q6apm_dai_ack,
|
||
.compress_ops = &q6apm_dai_compress_ops,
|
||
.use_dai_pcm_id = true,
|
||
};
|
||
diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h
|
||
index 394604c349432f..a33d92c7bd6bff 100644
|
||
--- a/sound/soc/qcom/qdsp6/q6asm.h
|
||
+++ b/sound/soc/qcom/qdsp6/q6asm.h
|
||
@@ -36,16 +36,16 @@ enum {
|
||
#define ASM_LAST_BUFFER_FLAG BIT(30)
|
||
|
||
struct q6asm_flac_cfg {
|
||
- u32 sample_rate;
|
||
- u32 ext_sample_rate;
|
||
- u32 min_frame_size;
|
||
- u32 max_frame_size;
|
||
- u16 stream_info_present;
|
||
- u16 min_blk_size;
|
||
- u16 max_blk_size;
|
||
- u16 ch_cfg;
|
||
- u16 sample_size;
|
||
- u16 md5_sum;
|
||
+ u32 sample_rate;
|
||
+ u32 ext_sample_rate;
|
||
+ u32 min_frame_size;
|
||
+ u32 max_frame_size;
|
||
+ u16 stream_info_present;
|
||
+ u16 min_blk_size;
|
||
+ u16 max_blk_size;
|
||
+ u16 ch_cfg;
|
||
+ u16 sample_size;
|
||
+ u16 md5_sum;
|
||
};
|
||
|
||
struct q6asm_wma_cfg {
|
||
diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c
|
||
index 130b22a34fb3b5..70572c83e1017d 100644
|
||
--- a/sound/soc/qcom/qdsp6/topology.c
|
||
+++ b/sound/soc/qcom/qdsp6/topology.c
|
||
@@ -545,6 +545,7 @@ static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *ap
|
||
|
||
if (mod) {
|
||
int pn, id = 0;
|
||
+
|
||
mod->module_id = module_id;
|
||
mod->max_ip_port = max_ip_port;
|
||
mod->max_op_port = max_op_port;
|
||
@@ -1271,7 +1272,7 @@ int audioreach_tplg_init(struct snd_soc_component *component)
|
||
|
||
ret = request_firmware(&fw, tplg_fw_name, dev);
|
||
if (ret < 0) {
|
||
- dev_err(dev, "tplg firmware loading %s failed %d \n", tplg_fw_name, ret);
|
||
+ dev_err(dev, "tplg firmware loading %s failed %d\n", tplg_fw_name, ret);
|
||
goto err;
|
||
}
|
||
|
||
diff --git a/sound/soc/qcom/sc7180.c b/sound/soc/qcom/sc7180.c
|
||
index d1fd40e3f7a9d8..1367752f2b63a6 100644
|
||
--- a/sound/soc/qcom/sc7180.c
|
||
+++ b/sound/soc/qcom/sc7180.c
|
||
@@ -428,4 +428,4 @@ static struct platform_driver sc7180_snd_driver = {
|
||
module_platform_driver(sc7180_snd_driver);
|
||
|
||
MODULE_DESCRIPTION("sc7180 ASoC Machine Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
|
||
index 6e5f194bc34b06..d5cc967992d161 100644
|
||
--- a/sound/soc/qcom/sc8280xp.c
|
||
+++ b/sound/soc/qcom/sc8280xp.c
|
||
@@ -174,4 +174,4 @@ static struct platform_driver snd_sc8280xp_driver = {
|
||
module_platform_driver(snd_sc8280xp_driver);
|
||
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
|
||
MODULE_DESCRIPTION("SC8280XP ASoC Machine Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
|
||
index 25b964dea6c56c..3eb29645a6377c 100644
|
||
--- a/sound/soc/qcom/sdm845.c
|
||
+++ b/sound/soc/qcom/sdm845.c
|
||
@@ -625,4 +625,4 @@ static struct platform_driver sdm845_snd_driver = {
|
||
module_platform_driver(sdm845_snd_driver);
|
||
|
||
MODULE_DESCRIPTION("sdm845 ASoC Machine Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/sdw.c b/sound/soc/qcom/sdw.c
|
||
index ce89c0a33ef058..e7413b1fd867e5 100644
|
||
--- a/sound/soc/qcom/sdw.c
|
||
+++ b/sound/soc/qcom/sdw.c
|
||
@@ -117,4 +117,4 @@ int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream,
|
||
return 0;
|
||
}
|
||
EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_free);
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c
|
||
index 9eb8ae0196d91f..88a7169336d61f 100644
|
||
--- a/sound/soc/qcom/sm8250.c
|
||
+++ b/sound/soc/qcom/sm8250.c
|
||
@@ -170,4 +170,4 @@ static struct platform_driver snd_sm8250_driver = {
|
||
module_platform_driver(snd_sm8250_driver);
|
||
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
|
||
MODULE_DESCRIPTION("SM8250 ASoC Machine Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c
|
||
index 553165f11d3069..c8d5ac43a17668 100644
|
||
--- a/sound/soc/qcom/storm.c
|
||
+++ b/sound/soc/qcom/storm.c
|
||
@@ -140,4 +140,4 @@ static struct platform_driver storm_platform_driver = {
|
||
module_platform_driver(storm_platform_driver);
|
||
|
||
MODULE_DESCRIPTION("QTi IPQ806x-based Storm Machine Driver");
|
||
-MODULE_LICENSE("GPL v2");
|
||
+MODULE_LICENSE("GPL");
|
||
diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c
|
||
index c10d91fff2fb0b..1ddec1f4f05d53 100644
|
||
--- a/sound/virtio/virtio_pcm.c
|
||
+++ b/sound/virtio/virtio_pcm.c
|
||
@@ -337,6 +337,21 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
|
||
if (!snd->substreams)
|
||
return -ENOMEM;
|
||
|
||
+ /*
|
||
+ * Initialize critical substream fields early in case we hit an
|
||
+ * error path and end up trying to clean up uninitialized structures
|
||
+ * elsewhere.
|
||
+ */
|
||
+ for (i = 0; i < snd->nsubstreams; ++i) {
|
||
+ struct virtio_pcm_substream *vss = &snd->substreams[i];
|
||
+
|
||
+ vss->snd = snd;
|
||
+ vss->sid = i;
|
||
+ INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
|
||
+ init_waitqueue_head(&vss->msg_empty);
|
||
+ spin_lock_init(&vss->lock);
|
||
+ }
|
||
+
|
||
info = kcalloc(snd->nsubstreams, sizeof(*info), GFP_KERNEL);
|
||
if (!info)
|
||
return -ENOMEM;
|
||
@@ -350,12 +365,6 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
|
||
struct virtio_pcm_substream *vss = &snd->substreams[i];
|
||
struct virtio_pcm *vpcm;
|
||
|
||
- vss->snd = snd;
|
||
- vss->sid = i;
|
||
- INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
|
||
- init_waitqueue_head(&vss->msg_empty);
|
||
- spin_lock_init(&vss->lock);
|
||
-
|
||
rc = virtsnd_pcm_build_hw(vss, &info[i]);
|
||
if (rc)
|
||
goto on_exit;
|
||
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
|
||
index 90ae2ea61324cc..174e076e56af2a 100644
|
||
--- a/tools/bpf/bpftool/prog.c
|
||
+++ b/tools/bpf/bpftool/prog.c
|
||
@@ -1924,6 +1924,7 @@ static int do_loader(int argc, char **argv)
|
||
|
||
obj = bpf_object__open_file(file, &open_opts);
|
||
if (!obj) {
|
||
+ err = -1;
|
||
p_err("failed to open object file");
|
||
goto err_close_obj;
|
||
}
|
||
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
|
||
index 8ba5bcfd5cd572..a1b14378bab045 100644
|
||
--- a/tools/objtool/check.c
|
||
+++ b/tools/objtool/check.c
|
||
@@ -1225,12 +1225,15 @@ static const char *uaccess_safe_builtin[] = {
|
||
"__ubsan_handle_load_invalid_value",
|
||
/* STACKLEAK */
|
||
"stackleak_track_stack",
|
||
+ /* TRACE_BRANCH_PROFILING */
|
||
+ "ftrace_likely_update",
|
||
+ /* STACKPROTECTOR */
|
||
+ "__stack_chk_fail",
|
||
/* misc */
|
||
"csum_partial_copy_generic",
|
||
"copy_mc_fragile",
|
||
"copy_mc_fragile_handle_tail",
|
||
"copy_mc_enhanced_fast_string",
|
||
- "ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */
|
||
"rep_stos_alternative",
|
||
"rep_movs_alternative",
|
||
"__copy_user_nocache",
|
||
@@ -1549,6 +1552,8 @@ static int add_jump_destinations(struct objtool_file *file)
|
||
unsigned long dest_off;
|
||
|
||
for_each_insn(file, insn) {
|
||
+ struct symbol *func = insn_func(insn);
|
||
+
|
||
if (insn->jump_dest) {
|
||
/*
|
||
* handle_group_alt() may have previously set
|
||
@@ -1572,7 +1577,7 @@ static int add_jump_destinations(struct objtool_file *file)
|
||
} else if (reloc->sym->return_thunk) {
|
||
add_return_call(file, insn, true);
|
||
continue;
|
||
- } else if (insn_func(insn)) {
|
||
+ } else if (func) {
|
||
/*
|
||
* External sibling call or internal sibling call with
|
||
* STT_FUNC reloc.
|
||
@@ -1605,6 +1610,15 @@ static int add_jump_destinations(struct objtool_file *file)
|
||
continue;
|
||
}
|
||
|
||
+ /*
|
||
+ * GCOV/KCOV dead code can jump to the end of the
|
||
+ * function/section.
|
||
+ */
|
||
+ if (file->ignore_unreachables && func &&
|
||
+ dest_sec == insn->sec &&
|
||
+ dest_off == func->offset + func->len)
|
||
+ continue;
|
||
+
|
||
WARN_INSN(insn, "can't find jump dest instruction at %s+0x%lx",
|
||
dest_sec->name, dest_off);
|
||
return -1;
|
||
@@ -1613,8 +1627,7 @@ static int add_jump_destinations(struct objtool_file *file)
|
||
/*
|
||
* Cross-function jump.
|
||
*/
|
||
- if (insn_func(insn) && insn_func(jump_dest) &&
|
||
- insn_func(insn) != insn_func(jump_dest)) {
|
||
+ if (func && insn_func(jump_dest) && func != insn_func(jump_dest)) {
|
||
|
||
/*
|
||
* For GCC 8+, create parent/child links for any cold
|
||
@@ -1631,10 +1644,10 @@ static int add_jump_destinations(struct objtool_file *file)
|
||
* case where the parent function's only reference to a
|
||
* subfunction is through a jump table.
|
||
*/
|
||
- if (!strstr(insn_func(insn)->name, ".cold") &&
|
||
+ if (!strstr(func->name, ".cold") &&
|
||
strstr(insn_func(jump_dest)->name, ".cold")) {
|
||
- insn_func(insn)->cfunc = insn_func(jump_dest);
|
||
- insn_func(jump_dest)->pfunc = insn_func(insn);
|
||
+ func->cfunc = insn_func(jump_dest);
|
||
+ insn_func(jump_dest)->pfunc = func;
|
||
}
|
||
}
|
||
|
||
@@ -3569,6 +3582,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
|
||
!strncmp(func->name, "__pfx_", 6))
|
||
return 0;
|
||
|
||
+ if (file->ignore_unreachables)
|
||
+ return 0;
|
||
+
|
||
WARN("%s() falls through to next function %s()",
|
||
func->name, insn_func(insn)->name);
|
||
return 1;
|
||
@@ -3788,6 +3804,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
|
||
if (!next_insn) {
|
||
if (state.cfi.cfa.base == CFI_UNDEFINED)
|
||
return 0;
|
||
+ if (file->ignore_unreachables)
|
||
+ return 0;
|
||
+
|
||
WARN("%s: unexpected end of section", sec->name);
|
||
return 1;
|
||
}
|
||
@@ -3940,6 +3959,9 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
|
||
break;
|
||
}
|
||
|
||
+ if (insn->dead_end)
|
||
+ return 0;
|
||
+
|
||
if (!next) {
|
||
WARN_INSN(insn, "teh end!");
|
||
return -1;
|
||
diff --git a/tools/testing/selftests/mincore/mincore_selftest.c b/tools/testing/selftests/mincore/mincore_selftest.c
|
||
index e949a43a614508..efabfcbe0b498c 100644
|
||
--- a/tools/testing/selftests/mincore/mincore_selftest.c
|
||
+++ b/tools/testing/selftests/mincore/mincore_selftest.c
|
||
@@ -261,9 +261,6 @@ TEST(check_file_mmap)
|
||
TH_LOG("No read-ahead pages found in memory");
|
||
}
|
||
|
||
- EXPECT_LT(i, vec_size) {
|
||
- TH_LOG("Read-ahead pages reached the end of the file");
|
||
- }
|
||
/*
|
||
* End of the readahead window. The rest of the pages shouldn't
|
||
* be in memory.
|
||
diff --git a/tools/testing/selftests/ublk/test_stripe_04.sh b/tools/testing/selftests/ublk/test_stripe_04.sh
|
||
new file mode 100755
|
||
index 00000000000000..1f2b642381d179
|
||
--- /dev/null
|
||
+++ b/tools/testing/selftests/ublk/test_stripe_04.sh
|
||
@@ -0,0 +1,24 @@
|
||
+#!/bin/bash
|
||
+# SPDX-License-Identifier: GPL-2.0
|
||
+
|
||
+. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh
|
||
+
|
||
+TID="stripe_04"
|
||
+ERR_CODE=0
|
||
+
|
||
+_prep_test "stripe" "mkfs & mount & umount on zero copy"
|
||
+
|
||
+backfile_0=$(_create_backfile 256M)
|
||
+backfile_1=$(_create_backfile 256M)
|
||
+dev_id=$(_add_ublk_dev -t stripe -z -q 2 "$backfile_0" "$backfile_1")
|
||
+_check_add_dev $TID $? "$backfile_0" "$backfile_1"
|
||
+
|
||
+_mkfs_mount_test /dev/ublkb"${dev_id}"
|
||
+ERR_CODE=$?
|
||
+
|
||
+_cleanup_test "stripe"
|
||
+
|
||
+_remove_backfile "$backfile_0"
|
||
+_remove_backfile "$backfile_1"
|
||
+
|
||
+_show_result $TID $ERR_CODE
|