commit 3e35142ef99fe6b4fe5d834ad43ee13cca10a2dc upstream.
Since commit d1bcae833b32f1 ("ELF: Don't generate unused section
symbols") [1], binutils (v2.36+) started dropping section symbols that
it thought were unused. This isn't an issue in general, but with
kexec_file.c, gcc is placing kexec_arch_apply_relocations[_add] into a
separate .text.unlikely section and the section symbol ".text.unlikely"
is being dropped. Due to this, recordmcount is unable to find a non-weak
symbol in .text.unlikely to generate a relocation record against.
Address this by dropping the weak attribute from these functions.
Instead, follow the existing pattern of having architectures #define the
name of the function they want to override in their headers.
[1] https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d1bcae833b32f1
[akpm(a)linux-foundation.org: arch/s390/include/asm/kexec.h needs linux/module.h]
Link: https://lkml.kernel.org/r/20220519091237.676736-1-naveen.n.rao@linux.vnet.i…
Signed-off-by: Michael Ellerman <mpe(a)ellerman.id.au>
Signed-off-by: Naveen N. Rao <naveen.n.rao(a)linux.vnet.ibm.com>
Cc: "Eric W. Biederman" <ebiederm(a)xmission.com>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
arch/x86/include/asm/kexec.h | 6 ++++++
include/linux/kexec.h | 26 ++++++++++++++++++++++----
kernel/kexec_file.c | 18 ------------------
3 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index 5125fca472bb0b..e699819bf7b349 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -21,6 +21,7 @@
#ifndef __ASSEMBLY__
#include <linux/string.h>
+#include <linux/module.h>
#include <asm/page.h>
#include <asm/ptrace.h>
@@ -217,6 +218,11 @@ extern int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages,
extern void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages);
#define arch_kexec_pre_free_pages arch_kexec_pre_free_pages
+#ifdef CONFIG_KEXEC_FILE
+int arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr,
+ Elf_Shdr *sechdrs, unsigned int relsec);
+#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add
+#endif
#endif
typedef void crash_vmclear_fn(void);
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 1ce6ba5f04077d..07578da0e2f5b1 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -163,6 +163,28 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
int (*func)(u64, u64, void *));
extern int kexec_add_buffer(struct kexec_buf *kbuf);
int kexec_locate_mem_hole(struct kexec_buf *kbuf);
+
+#ifndef arch_kexec_apply_relocations_add
+/* Apply relocations of type RELA */
+static inline int
+arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr,
+ Elf_Shdr *sechdrs, unsigned int relsec)
+{
+ pr_err("RELA relocation unsupported.\n");
+ return -ENOEXEC;
+}
+#endif
+
+#ifndef arch_kexec_apply_relocations
+/* Apply relocations of type REL */
+static inline int
+arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
+ unsigned int relsec)
+{
+ pr_err("REL relocation unsupported.\n");
+ return -ENOEXEC;
+}
+#endif
#endif /* CONFIG_KEXEC_FILE */
struct kimage {
@@ -288,10 +310,6 @@ void * __weak arch_kexec_kernel_image_load(struct kimage *image);
int __weak arch_kimage_file_post_load_cleanup(struct kimage *image);
int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf,
unsigned long buf_len);
-int __weak arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr,
- Elf_Shdr *sechdrs, unsigned int relsec);
-int __weak arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
- unsigned int relsec);
void arch_kexec_protect_crashkres(void);
void arch_kexec_unprotect_crashkres(void);
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 9d979b2954ef7f..4e95641e8dd6ec 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -53,24 +53,6 @@ int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf,
}
#endif
-/* Apply relocations of type RELA */
-int __weak
-arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
- unsigned int relsec)
-{
- pr_err("RELA relocation unsupported.\n");
- return -ENOEXEC;
-}
-
-/* Apply relocations of type REL */
-int __weak
-arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
- unsigned int relsec)
-{
- pr_err("REL relocation unsupported.\n");
- return -ENOEXEC;
-}
-
/*
* Free up memory used by kernel, initrd, and command line. This is temporary
* memory allocation which is not needed any more after these buffers have
base-commit: f051383ef03bde49ca992f297ec80757a702e774
--
2.36.1
There's currently an almost deadlock when ath9k shuts down if no random
bytes are available:
Thread A Thread B
-------------------------------------------------------------------------
rng_dev_read
get_current_rng
kref_get(¤t_rng->ref)
rng_get_data
ath9k_rng_read
msleep_interruptible(...)
ath9k_rng_stop
devm_hwrng_unregister
devm_hwrng_release
hwrng_unregister
drop_current_rng
kref_put(¤t_rng->ref, cleanup_rng)
// Does NOT call cleanup_rng here,
// because of thread A's kref_get.
wait_for_completion(&rng->cleanup_done);
// Waits for a really long time...
// Eventually sleep is over...
put_rng
kref_put(&rng->ref, cleanup_rng);
cleanup_rng
complete(&rng->cleanup_done);
return
When thread B doesn't return right away, sleep and other functions that
are waiting for ath9k_rng_stop to complete time out, and problems ensue.
This commit fixes the problem by using another completion inside of
ath9k_rng_read so that hwrng_unregister can interrupt it as needed.
Reported-by: Gregory Erwin <gregerwin256(a)gmail.com>
Cc: Toke Høiland-Jørgensen <toke(a)redhat.com>
Cc: Kalle Valo <kvalo(a)kernel.org>
Cc: Rui Salvaterra <rsalvaterra(a)gmail.com>
Cc: stable(a)vger.kernel.org
Fixes: fcd09c90c3c5 ("ath9k: use hw_random API instead of directly dumping into random.c")
Link: https://lore.kernel.org/all/CAO+Okf6ZJC5-nTE_EJUGQtd8JiCkiEHytGgDsFGTEjs0c0…
Link: https://bugs.archlinux.org/task/75138
Signed-off-by: Jason A. Donenfeld <Jason(a)zx2c4.com>
---
I do not have an ath9k and therefore I can't test this myself. The
analysis above was done completely statically, with no dynamic tracing
and just a bug report of symptoms from Gregory. So it might be totally
wrong. Thus, this patch very much requires Gregory's testing. Please
don't apply it until we have his `Tested-by` line.
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/rng.c | 26 ++++++++++++++++----------
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 3ccf8cfc6b63..731db7f70e5d 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -1072,6 +1072,7 @@ struct ath_softc {
#ifdef CONFIG_ATH9K_HWRNG
struct hwrng rng_ops;
+ struct completion rng_shutdown;
u32 rng_last;
char rng_name[sizeof("ath9k_65535")];
#endif
diff --git a/drivers/net/wireless/ath/ath9k/rng.c b/drivers/net/wireless/ath/ath9k/rng.c
index cb5414265a9b..67c6b03a22ac 100644
--- a/drivers/net/wireless/ath/ath9k/rng.c
+++ b/drivers/net/wireless/ath/ath9k/rng.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015 Qualcomm Atheros, Inc.
+ * Copyright (C) 2022 Jason A. Donenfeld <Jason(a)zx2c4.com>. All Rights Reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -52,18 +53,13 @@ static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size)
return j << 2;
}
-static u32 ath9k_rng_delay_get(u32 fail_stats)
+static unsigned long ath9k_rng_delay_get(u32 fail_stats)
{
- u32 delay;
-
if (fail_stats < 100)
- delay = 10;
+ return msecs_to_jiffies(10);
else if (fail_stats < 105)
- delay = 1000;
- else
- delay = 10000;
-
- return delay;
+ return msecs_to_jiffies(1000);
+ return msecs_to_jiffies(10000);
}
static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
@@ -83,7 +79,10 @@ static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
if (!wait || !max || likely(bytes_read) || fail_stats > 110)
break;
- msleep_interruptible(ath9k_rng_delay_get(++fail_stats));
+ if (wait_for_completion_interruptible_timeout(
+ &sc->rng_shutdown,
+ ath9k_rng_delay_get(++fail_stats)))
+ break;
}
if (wait && !bytes_read && max)
@@ -91,6 +90,11 @@ static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
return bytes_read;
}
+static void ath9k_rng_cleanup(struct hwrng *rng)
+{
+ complete(&container_of(rng, struct ath_softc, rng_ops)->rng_shutdown);
+}
+
void ath9k_rng_start(struct ath_softc *sc)
{
static atomic_t serial = ATOMIC_INIT(0);
@@ -104,8 +108,10 @@ void ath9k_rng_start(struct ath_softc *sc)
snprintf(sc->rng_name, sizeof(sc->rng_name), "ath9k_%u",
(atomic_inc_return(&serial) - 1) & U16_MAX);
+ init_completion(&sc->rng_shutdown);
sc->rng_ops.name = sc->rng_name;
sc->rng_ops.read = ath9k_rng_read;
+ sc->rng_ops.cleanup = ath9k_rng_cleanup;
sc->rng_ops.quality = 320;
if (devm_hwrng_register(sc->dev, &sc->rng_ops))
--
2.35.1
From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri(a)xilinx.com>
[ Upstream commit 21b511ddee09a78909035ec47a6a594349fe3296 ]
As part of unprepare_transfer_hardware, SPI controller will be disabled
which will indirectly deassert the CS line. This will create a problem
in some of the devices where message will be transferred with
cs_change flag set(CS should not be deasserted).
As per SPI controller implementation, if SPI controller is disabled then
all output enables are inactive and all pins are set to input mode which
means CS will go to default state high(deassert). This leads to an issue
when core explicitly ask not to deassert the CS (cs_change = 1). This
patch fix the above issue by checking the Slave select status bits from
configuration register before disabling the SPI.
Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri(a)xilinx.com>
Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra(a)xilinx.com>
Link: https://lore.kernel.org/r/20220606062525.18447-1-amit.kumar-mahapatra@xilin…
Signed-off-by: Mark Brown <broonie(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
drivers/spi/spi-cadence.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index ceb16e70d235..90b18c32f859 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -69,6 +69,7 @@
#define CDNS_SPI_BAUD_DIV_SHIFT 3 /* Baud rate divisor shift in CR */
#define CDNS_SPI_SS_SHIFT 10 /* Slave Select field shift in CR */
#define CDNS_SPI_SS0 0x1 /* Slave Select zero */
+#define CDNS_SPI_NOSS 0x3C /* No Slave select */
/*
* SPI Interrupt Registers bit Masks
@@ -449,15 +450,20 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
* @master: Pointer to the spi_master structure which provides
* information about the controller.
*
- * This function disables the SPI master controller.
+ * This function disables the SPI master controller when no slave selected.
*
* Return: 0 always
*/
static int cdns_unprepare_transfer_hardware(struct spi_master *master)
{
struct cdns_spi *xspi = spi_master_get_devdata(master);
+ u32 ctrl_reg;
- cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
+ /* Disable the SPI if slave is deselected */
+ ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
+ ctrl_reg = (ctrl_reg & CDNS_SPI_CR_SSCTRL) >> CDNS_SPI_SS_SHIFT;
+ if (ctrl_reg == CDNS_SPI_NOSS)
+ cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
return 0;
}
--
2.35.1
Hello,
My name is Steve Dibenedetto.
I apologize to have contacted you this way without a direct relationship. There is an opportunity to collaborate with me in the sourcing of some materials needed by our company for production of the different medicines we are researching.
I'm aware that this might be totally outside your professional specialization, but it will be a great source for generating extra revenue. I discovered a manufacturer who can supply us at a lower rate than our company's previous purchases.
I will give you more specific details when/if I receive feedback from you showing interest.
Warm Regards
Steve Dibenedetto
Production & Control Manager,
Green Field Laboratories
Gothic House, Barker Gate,
Nottingham, NG1 1JU,
United Kingdom.