mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
Merge 732413d5ae ("USB: misc: yurex: fix race between read and write") into android14-6.1-lts
Steps on the way to 6.1.113 Change-Id: Ie7950304b1c062afe32c9e4f87aaa2e77ede3ceb Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
source "arch/powerpc/platforms/Kconfig.cputype"
|
||||
|
||||
config CC_HAS_ELFV2
|
||||
def_bool PPC64 && $(cc-option, -mabi=elfv2)
|
||||
|
||||
config CC_HAS_PREFIXED
|
||||
def_bool PPC64 && $(cc-option, -mcpu=power10 -mprefixed)
|
||||
|
||||
config 32BIT
|
||||
bool
|
||||
default y if PPC32
|
||||
@@ -583,6 +589,24 @@ config KEXEC_FILE
|
||||
config ARCH_HAS_KEXEC_PURGATORY
|
||||
def_bool KEXEC_FILE
|
||||
|
||||
config PPC64_BIG_ENDIAN_ELF_ABI_V2
|
||||
bool "Build big-endian kernel using ELF ABI V2 (EXPERIMENTAL)"
|
||||
depends on PPC64 && CPU_BIG_ENDIAN
|
||||
depends on CC_HAS_ELFV2
|
||||
depends on LD_IS_BFD && LD_VERSION >= 22400
|
||||
default n
|
||||
help
|
||||
This builds the kernel image using the "Power Architecture 64-Bit ELF
|
||||
V2 ABI Specification", which has a reduced stack overhead and faster
|
||||
function calls. This internal kernel ABI option does not affect
|
||||
userspace compatibility.
|
||||
|
||||
The V2 ABI is standard for 64-bit little-endian, but for big-endian
|
||||
it is less well tested by kernel and toolchain. However some distros
|
||||
build userspace this way, and it can produce a functioning kernel.
|
||||
|
||||
This requires GCC and binutils 2.24 or newer.
|
||||
|
||||
config RELOCATABLE
|
||||
bool "Build a relocatable kernel"
|
||||
depends on PPC64 || (FLATMEM && (44x || PPC_85xx))
|
||||
|
||||
@@ -176,7 +176,11 @@ ifdef CONFIG_476FPE_ERR46
|
||||
endif
|
||||
|
||||
# No prefix or pcrel
|
||||
ifdef CONFIG_PPC_KERNEL_PREFIXED
|
||||
KBUILD_CFLAGS += $(call cc-option,-mprefixed)
|
||||
else
|
||||
KBUILD_CFLAGS += $(call cc-option,-mno-prefixed)
|
||||
endif
|
||||
KBUILD_CFLAGS += $(call cc-option,-mno-pcrel)
|
||||
|
||||
# No AltiVec or VSX or MMA instructions when building kernel
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
#define STDX_BE stringify_in_c(stdbrx)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CC_IS_CLANG
|
||||
#define DS_FORM_CONSTRAINT "Z<>"
|
||||
#else
|
||||
#define DS_FORM_CONSTRAINT "YZ<>"
|
||||
#endif
|
||||
|
||||
#else /* 32-bit */
|
||||
|
||||
/* operations for longs and pointers */
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/asm-const.h>
|
||||
#include <asm/asm-compat.h>
|
||||
|
||||
/*
|
||||
* Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
|
||||
@@ -27,14 +28,22 @@ static __inline__ int arch_atomic_read(const atomic_t *v)
|
||||
{
|
||||
int t;
|
||||
|
||||
__asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter));
|
||||
/* -mprefixed can generate offsets beyond range, fall back hack */
|
||||
if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
|
||||
__asm__ __volatile__("lwz %0,0(%1)" : "=r"(t) : "b"(&v->counter));
|
||||
else
|
||||
__asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter));
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static __inline__ void arch_atomic_set(atomic_t *v, int i)
|
||||
{
|
||||
__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i));
|
||||
/* -mprefixed can generate offsets beyond range, fall back hack */
|
||||
if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
|
||||
__asm__ __volatile__("stw %1,0(%2)" : "=m"(v->counter) : "r"(i), "b"(&v->counter));
|
||||
else
|
||||
__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i));
|
||||
}
|
||||
|
||||
#define ATOMIC_OP(op, asm_op, suffix, sign, ...) \
|
||||
@@ -226,14 +235,22 @@ static __inline__ s64 arch_atomic64_read(const atomic64_t *v)
|
||||
{
|
||||
s64 t;
|
||||
|
||||
__asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter));
|
||||
/* -mprefixed can generate offsets beyond range, fall back hack */
|
||||
if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
|
||||
__asm__ __volatile__("ld %0,0(%1)" : "=r"(t) : "b"(&v->counter));
|
||||
else
|
||||
__asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : DS_FORM_CONSTRAINT (v->counter));
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static __inline__ void arch_atomic64_set(atomic64_t *v, s64 i)
|
||||
{
|
||||
__asm__ __volatile__("std%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i));
|
||||
/* -mprefixed can generate offsets beyond range, fall back hack */
|
||||
if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
|
||||
__asm__ __volatile__("std %1,0(%2)" : "=m"(v->counter) : "r"(i), "b"(&v->counter));
|
||||
else
|
||||
__asm__ __volatile__("std%U0%X0 %1,%0" : "=" DS_FORM_CONSTRAINT (v->counter) : "r"(i));
|
||||
}
|
||||
|
||||
#define ATOMIC64_OP(op, asm_op) \
|
||||
|
||||
@@ -97,6 +97,42 @@ extern bool isa_io_special;
|
||||
*
|
||||
*/
|
||||
|
||||
/* -mprefixed can generate offsets beyond range, fall back hack */
|
||||
#ifdef CONFIG_PPC_KERNEL_PREFIXED
|
||||
#define DEF_MMIO_IN_X(name, size, insn) \
|
||||
static inline u##size name(const volatile u##size __iomem *addr) \
|
||||
{ \
|
||||
u##size ret; \
|
||||
__asm__ __volatile__("sync;"#insn" %0,0,%1;twi 0,%0,0;isync" \
|
||||
: "=r" (ret) : "r" (addr) : "memory"); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define DEF_MMIO_OUT_X(name, size, insn) \
|
||||
static inline void name(volatile u##size __iomem *addr, u##size val) \
|
||||
{ \
|
||||
__asm__ __volatile__("sync;"#insn" %1,0,%0" \
|
||||
: : "r" (addr), "r" (val) : "memory"); \
|
||||
mmiowb_set_pending(); \
|
||||
}
|
||||
|
||||
#define DEF_MMIO_IN_D(name, size, insn) \
|
||||
static inline u##size name(const volatile u##size __iomem *addr) \
|
||||
{ \
|
||||
u##size ret; \
|
||||
__asm__ __volatile__("sync;"#insn" %0,0(%1);twi 0,%0,0;isync"\
|
||||
: "=r" (ret) : "b" (addr) : "memory"); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define DEF_MMIO_OUT_D(name, size, insn) \
|
||||
static inline void name(volatile u##size __iomem *addr, u##size val) \
|
||||
{ \
|
||||
__asm__ __volatile__("sync;"#insn" %1,0(%0)" \
|
||||
: : "b" (addr), "r" (val) : "memory"); \
|
||||
mmiowb_set_pending(); \
|
||||
}
|
||||
#else
|
||||
#define DEF_MMIO_IN_X(name, size, insn) \
|
||||
static inline u##size name(const volatile u##size __iomem *addr) \
|
||||
{ \
|
||||
@@ -130,6 +166,7 @@ static inline void name(volatile u##size __iomem *addr, u##size val) \
|
||||
: "=m<>" (*addr) : "r" (val) : "memory"); \
|
||||
mmiowb_set_pending(); \
|
||||
}
|
||||
#endif
|
||||
|
||||
DEF_MMIO_IN_D(in_8, 8, lbz);
|
||||
DEF_MMIO_OUT_D(out_8, 8, stb);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/extable.h>
|
||||
#include <asm/kup.h>
|
||||
#include <asm/asm-compat.h>
|
||||
|
||||
#ifdef __powerpc64__
|
||||
/* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
|
||||
@@ -71,19 +72,25 @@ __pu_failed: \
|
||||
* because we do not write to any memory gcc knows about, so there
|
||||
* are no aliasing issues.
|
||||
*/
|
||||
/* -mprefixed can generate offsets beyond range, fall back hack */
|
||||
#ifdef CONFIG_PPC_KERNEL_PREFIXED
|
||||
#define __put_user_asm_goto(x, addr, label, op) \
|
||||
asm_volatile_goto( \
|
||||
"1: " op " %0,0(%1) # put_user\n" \
|
||||
EX_TABLE(1b, %l2) \
|
||||
: \
|
||||
: "r" (x), "b" (addr) \
|
||||
: \
|
||||
: label)
|
||||
#else
|
||||
#define __put_user_asm_goto(x, addr, label, op) \
|
||||
asm goto( \
|
||||
"1: " op "%U1%X1 %0,%1 # put_user\n" \
|
||||
EX_TABLE(1b, %l2) \
|
||||
: \
|
||||
: "r" (x), "m<>" (*addr) \
|
||||
: "r" (x), "m<>" (*addr) \
|
||||
: \
|
||||
: label)
|
||||
|
||||
#ifdef CONFIG_CC_IS_CLANG
|
||||
#define DS_FORM_CONSTRAINT "Z<>"
|
||||
#else
|
||||
#define DS_FORM_CONSTRAINT "YZ<>"
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
@@ -142,14 +149,26 @@ do { \
|
||||
|
||||
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
|
||||
|
||||
/* -mprefixed can generate offsets beyond range, fall back hack */
|
||||
#ifdef CONFIG_PPC_KERNEL_PREFIXED
|
||||
#define __get_user_asm_goto(x, addr, label, op) \
|
||||
asm_volatile_goto( \
|
||||
"1: "op" %0,0(%1) # get_user\n" \
|
||||
EX_TABLE(1b, %l2) \
|
||||
: "=r" (x) \
|
||||
: "b" (addr) \
|
||||
: \
|
||||
: label)
|
||||
#else
|
||||
#define __get_user_asm_goto(x, addr, label, op) \
|
||||
asm_goto_output( \
|
||||
"1: "op"%U1%X1 %0, %1 # get_user\n" \
|
||||
EX_TABLE(1b, %l2) \
|
||||
: "=r" (x) \
|
||||
: "m<>" (*addr) \
|
||||
: "m<>" (*addr) \
|
||||
: \
|
||||
: label)
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
#define __get_user_asm2_goto(x, addr, label) \
|
||||
|
||||
@@ -194,6 +194,8 @@ __ftrace_make_nop(struct module *mod,
|
||||
* get corrupted.
|
||||
*
|
||||
* Use a b +8 to jump over the load.
|
||||
* XXX: could make PCREL depend on MPROFILE_KERNEL
|
||||
* XXX: check PCREL && MPROFILE_KERNEL calling sequence
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_MPROFILE_KERNEL) || IS_ENABLED(CONFIG_PPC32))
|
||||
pop = ppc_inst(PPC_RAW_NOP());
|
||||
|
||||
@@ -176,6 +176,7 @@ config POWER10_CPU
|
||||
bool "POWER10"
|
||||
depends on PPC_BOOK3S_64
|
||||
select ARCH_HAS_FAST_MULTIPLIER
|
||||
select PPC_HAVE_PREFIXED_SUPPORT
|
||||
|
||||
config E5500_CPU
|
||||
bool "Freescale e5500"
|
||||
@@ -449,6 +450,22 @@ config PPC_RADIX_MMU_DEFAULT
|
||||
|
||||
If you're unsure, say Y.
|
||||
|
||||
config PPC_KERNEL_PREFIXED
|
||||
depends on PPC_HAVE_PREFIXED_SUPPORT
|
||||
depends on CC_HAS_PREFIXED
|
||||
default n
|
||||
bool "Build Kernel with Prefixed Instructions"
|
||||
help
|
||||
POWER10 and later CPUs support prefixed instructions, 8 byte
|
||||
instructions that include large immediate, pc relative addressing,
|
||||
and various floating point, vector, MMA.
|
||||
|
||||
This option builds the kernel with prefixed instructions, and
|
||||
allows a pc relative addressing option to be selected.
|
||||
|
||||
Kernel support for prefixed instructions in applications and guests
|
||||
is not affected by this option.
|
||||
|
||||
config PPC_KUEP
|
||||
bool "Kernel Userspace Execution Prevention" if !40x
|
||||
default y if !40x
|
||||
@@ -485,6 +502,9 @@ config PPC_MMU_NOHASH
|
||||
config PPC_HAVE_PMU_SUPPORT
|
||||
bool
|
||||
|
||||
config PPC_HAVE_PREFIXED_SUPPORT
|
||||
bool
|
||||
|
||||
config PMU_SYSFS
|
||||
bool "Create PMU SPRs sysfs file"
|
||||
default n
|
||||
@@ -585,10 +605,10 @@ config CPU_LITTLE_ENDIAN
|
||||
endchoice
|
||||
|
||||
config PPC64_ELF_ABI_V1
|
||||
def_bool PPC64 && CPU_BIG_ENDIAN
|
||||
def_bool PPC64 && (CPU_BIG_ENDIAN && !PPC64_BIG_ENDIAN_ELF_ABI_V2)
|
||||
|
||||
config PPC64_ELF_ABI_V2
|
||||
def_bool PPC64 && CPU_LITTLE_ENDIAN
|
||||
def_bool PPC64 && !PPC64_ELF_ABI_V1
|
||||
|
||||
config PPC64_BOOT_WRAPPER
|
||||
def_bool n
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#define YUREX_BUF_SIZE 8
|
||||
#define YUREX_WRITE_TIMEOUT (HZ*2)
|
||||
|
||||
#define MAX_S64_STRLEN 20 /* {-}922337203685477580{7,8} */
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
static struct usb_device_id yurex_table[] = {
|
||||
{ USB_DEVICE(YUREX_VENDOR_ID, YUREX_PRODUCT_ID) },
|
||||
@@ -401,8 +403,7 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,
|
||||
{
|
||||
struct usb_yurex *dev;
|
||||
int len = 0;
|
||||
char in_buffer[20];
|
||||
unsigned long flags;
|
||||
char in_buffer[MAX_S64_STRLEN];
|
||||
|
||||
dev = file->private_data;
|
||||
|
||||
@@ -412,14 +413,14 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
len = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
mutex_unlock(&dev->io_mutex);
|
||||
|
||||
if (WARN_ON_ONCE(len >= sizeof(in_buffer)))
|
||||
if (WARN_ON_ONCE(dev->bbu > S64_MAX || dev->bbu < S64_MIN))
|
||||
return -EIO;
|
||||
|
||||
spin_lock_irq(&dev->lock);
|
||||
scnprintf(in_buffer, MAX_S64_STRLEN, "%lld\n", dev->bbu);
|
||||
spin_unlock_irq(&dev->lock);
|
||||
mutex_unlock(&dev->io_mutex);
|
||||
|
||||
return simple_read_from_buffer(buffer, count, ppos, in_buffer, len);
|
||||
}
|
||||
|
||||
@@ -507,8 +508,11 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
|
||||
__func__, retval);
|
||||
goto error;
|
||||
}
|
||||
if (set && timeout)
|
||||
if (set && timeout) {
|
||||
spin_lock_irq(&dev->lock);
|
||||
dev->bbu = c2;
|
||||
spin_unlock_irq(&dev->lock);
|
||||
}
|
||||
return timeout ? count : -EIO;
|
||||
|
||||
error:
|
||||
|
||||
Reference in New Issue
Block a user