summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/arm-smccc-rsi.h2
-rw-r--r--include/linux/bio.h27
-rw-r--r--include/linux/blk-mq.h7
-rw-r--r--include/linux/blk_types.h14
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/bootconfig.h14
-rw-r--r--include/linux/bpf-cgroup.h36
-rw-r--r--include/linux/bpf_verifier.h189
-rw-r--r--include/linux/bsg-lib.h3
-rw-r--r--include/linux/btf.h42
-rw-r--r--include/linux/bvec.h3
-rw-r--r--include/linux/clk/ti.h8
-rw-r--r--include/linux/cnum.h3
-rw-r--r--include/linux/compiler_attributes.h12
-rw-r--r--include/linux/coredump.h4
-rw-r--r--include/linux/dcache.h3
-rw-r--r--include/linux/dma-buf-io.h125
-rw-r--r--include/linux/firewire.h105
-rw-r--r--include/linux/firmware/intel/stratix10-smc.h44
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/fs_context.h8
-rw-r--r--include/linux/fsnotify_backend.h1
-rw-r--r--include/linux/ftrace.h1
-rw-r--r--include/linux/futex.h19
-rw-r--r--include/linux/futex_types.h2
-rw-r--r--include/linux/gpio/legacy.h10
-rw-r--r--include/linux/greybus/bundle.h12
-rw-r--r--include/linux/hardirq.h2
-rw-r--r--include/linux/hazptr.h325
-rw-r--r--include/linux/huge_mm.h9
-rw-r--r--include/linux/interrupt_rc.h13
-rw-r--r--include/linux/io_uring_types.h5
-rw-r--r--include/linux/iov_iter.h2
-rw-r--r--include/linux/irq-entry-common.h23
-rw-r--r--include/linux/key.h2
-rw-r--r--include/linux/kvm_host.h24
-rw-r--r--include/linux/landlock.h29
-rw-r--r--include/linux/memblock.h3
-rw-r--r--include/linux/mhi_ep.h16
-rw-r--r--include/linux/mlx5/mlx5_ifc.h16
-rw-r--r--include/linux/mm.h155
-rw-r--r--include/linux/mm_types.h6
-rw-r--r--include/linux/module.h4
-rw-r--r--include/linux/mtd/nand-qpic-common.h17
-rw-r--r--include/linux/netdevice.h18
-rw-r--r--include/linux/nfs_common.h4
-rw-r--r--include/linux/overflow.h2
-rw-r--r--include/linux/pci.h15
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/pid.h64
-rw-r--r--include/linux/pid_types.h8
-rw-r--r--include/linux/pidfs.h5
-rw-r--r--include/linux/platform_data/dmtimer-omap.h2
-rw-r--r--include/linux/rbtree_augmented.h201
-rw-r--r--include/linux/rcutree.h2
-rw-r--r--include/linux/remoteproc.h4
-rw-r--r--include/linux/sched/signal.h22
-rw-r--r--include/linux/seq_buf.h141
-rw-r--r--include/linux/seq_file.h13
-rw-r--r--include/linux/serial_8250.h8
-rw-r--r--include/linux/socket.h9
-rw-r--r--include/linux/spinlock_types_raw.h4
-rw-r--r--include/linux/spmi.h17
-rw-r--r--include/linux/sunrpc/svc.h2
-rw-r--r--include/linux/sunrpc/xdrgen/nfs2.h298
-rw-r--r--include/linux/sunrpc/xprt.h1
-rw-r--r--include/linux/tcp.h7
-rw-r--r--include/linux/tnum.h2
-rw-r--r--include/linux/torture.h6
-rw-r--r--include/linux/trace_seq.h5
-rw-r--r--include/linux/uio.h11
-rw-r--r--include/linux/unicode.h1
-rw-r--r--include/linux/usb/serial.h8
-rw-r--r--include/linux/vfio_pci_core.h41
74 files changed, 1633 insertions, 638 deletions
diff --git a/include/linux/arm-smccc-rsi.h b/include/linux/arm-smccc-rsi.h
index fddb77986f70..cca881ddfdba 100644
--- a/include/linux/arm-smccc-rsi.h
+++ b/include/linux/arm-smccc-rsi.h
@@ -128,7 +128,7 @@ struct realm_config {
union {
struct {
unsigned long ipa_bits; /* Width of IPA in bits */
- unsigned long hash_algo; /* Hash algorithm */
+ u8 hash_algo; /* Hash algorithm */
};
u8 pad[0x200];
};
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 75f8086351c0..7a794ce723b8 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -80,7 +80,8 @@ static inline bool bio_no_advance_iter(const struct bio *bio)
{
return bio_op(bio) == REQ_OP_DISCARD ||
bio_op(bio) == REQ_OP_SECURE_ERASE ||
- bio_op(bio) == REQ_OP_WRITE_ZEROES;
+ bio_op(bio) == REQ_OP_WRITE_ZEROES ||
+ op_is_dmabuf(bio->bi_opf);
}
static inline void *bio_data(struct bio *bio)
@@ -113,11 +114,13 @@ static inline void bio_advance_iter(const struct bio *bio,
{
iter->bi_sector += bytes >> 9;
- if (bio_no_advance_iter(bio))
+ if (bio_no_advance_iter(bio)) {
iter->bi_size -= bytes;
- else
+ iter->bi_offset += bytes;
+ } else {
bvec_iter_advance(bio->bi_io_vec, iter, bytes);
/* TODO: It is reasonable to complete bio with error here. */
+ }
}
/* @bytes should be less or equal to bvec[i->bi_idx].bv_len */
@@ -127,10 +130,12 @@ static inline void bio_advance_iter_single(const struct bio *bio,
{
iter->bi_sector += bytes >> 9;
- if (bio_no_advance_iter(bio))
+ if (bio_no_advance_iter(bio)) {
iter->bi_size -= bytes;
- else
+ iter->bi_offset += bytes;
+ } else {
bvec_iter_advance_single(bio->bi_io_vec, iter, bytes);
+ }
}
void __bio_advance(struct bio *, unsigned bytes);
@@ -256,12 +261,6 @@ static inline struct folio *bio_first_folio_all(struct bio *bio)
return page_folio(bio_first_page_all(bio));
}
-static inline struct bio_vec *bio_last_bvec_all(struct bio *bio)
-{
- WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
- return &bio->bi_io_vec[bio->bi_vcnt - 1];
-}
-
/**
* struct folio_iter - State for iterating all folios in a bio.
* @folio: The current folio we're iterating. NULL after the last folio.
@@ -440,12 +439,12 @@ static inline void bio_wouldblock_error(struct bio *bio)
/*
* Calculate number of bvec segments that should be allocated to fit data
- * pointed by @iter. If @iter is backed by bvec it's going to be reused
- * instead of allocating a new one.
+ * pointed by @iter. If @iter is backed by a bvec or a dmabuf, the bvec array /
+ * the dma map are going to be reused, and so no extra allocation is required.
*/
static inline int bio_iov_vecs_to_alloc(struct iov_iter *iter, int max_segs)
{
- if (iov_iter_is_bvec(iter))
+ if (iov_iter_is_bvec(iter) || iov_iter_is_dmabuf_map(iter))
return 0;
return iov_iter_npages(iter, max_segs);
}
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index af878597afb8..7c7504c84e09 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -1017,6 +1017,13 @@ static inline void *blk_mq_rq_to_pdu(struct request *rq)
return rq + 1;
}
+static inline bool blk_mq_rq_is_dmabuf(struct request *rq)
+{
+ if (!IS_ENABLED(CONFIG_DMA_SHARED_BUFFER))
+ return false;
+ return rq->bio && op_is_dmabuf(rq->bio->bi_opf);
+}
+
static inline struct blk_mq_hw_ctx *queue_hctx(struct request_queue *q, int id)
{
struct blk_mq_hw_ctx *hctx;
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 98e21b4cbf32..0cc09b975d8f 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -233,7 +233,12 @@ struct bio {
atomic_t __bi_remaining;
/* The actual vec list, preserved by bio_reset() */
- struct bio_vec *bi_io_vec;
+ union {
+ struct bio_vec *bi_io_vec;
+ /* Driver specific dma map, valid IFF REQ_DMABUF is set */
+ struct dma_buf_io_map *bi_dmabuf_map;
+ };
+
struct bvec_iter bi_iter;
union {
@@ -402,6 +407,7 @@ enum req_flag_bits {
__REQ_DRV, /* for driver use */
__REQ_FS_PRIVATE, /* for file system (submitter) use */
__REQ_ATOMIC, /* for atomic write operations */
+ __REQ_DMABUF, /* Using premmaped dma buffers */
/*
* Command specific flags, keep last:
*/
@@ -434,6 +440,7 @@ enum req_flag_bits {
#define REQ_DRV (__force blk_opf_t)(1ULL << __REQ_DRV)
#define REQ_FS_PRIVATE (__force blk_opf_t)(1ULL << __REQ_FS_PRIVATE)
#define REQ_ATOMIC (__force blk_opf_t)(1ULL << __REQ_ATOMIC)
+#define REQ_DMABUF (__force blk_opf_t)(1ULL << __REQ_DMABUF)
#define REQ_NOUNMAP (__force blk_opf_t)(1ULL << __REQ_NOUNMAP)
@@ -487,6 +494,11 @@ static inline bool op_is_discard(blk_opf_t op)
return (op & REQ_OP_MASK) == REQ_OP_DISCARD;
}
+static inline bool op_is_dmabuf(blk_opf_t op)
+{
+ return op & REQ_DMABUF;
+}
+
/*
* Check if a bio or request operation is a zone management operation.
*/
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index d003a9d2d1f6..2d5c30823aab 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1599,6 +1599,8 @@ struct block_device_operations {
/* returns the length of the identifier or a negative errno: */
int (*get_unique_id)(struct gendisk *disk, u8 id[16],
enum blk_unique_id id_type);
+ int (*init_dma_buf_io_ctx)(struct block_device *,
+ struct dma_buf_io_ctx *);
struct module *owner;
const struct pr_ops *pr_ops;
diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
index fdc15b6f4d1b..260a6f46042e 100644
--- a/include/linux/bootconfig.h
+++ b/include/linux/bootconfig.h
@@ -27,6 +27,10 @@ bool __init cmdline_has_extra_options(void);
#define BOOTCONFIG_ALIGN (1 << BOOTCONFIG_ALIGN_SHIFT)
#define BOOTCONFIG_ALIGN_MASK (BOOTCONFIG_ALIGN - 1)
+/* Bootconfig footer is [size][csum][BOOTCONFIG_MAGIC]. */
+#define BOOTCONFIG_FOOTER_SIZE \
+ (sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN)
+
/**
* xbc_calc_checksum() - Calculate checksum of bootconfig
* @data: Bootconfig data.
@@ -266,7 +270,15 @@ int __init xbc_node_compose_key_after(struct xbc_node *root,
struct xbc_node *node, char *buf, size_t size);
/* Render key/value pairs under @root as a flat cmdline string */
-int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *root);
+typedef bool (*xbc_cmdline_filter_fn)(struct xbc_node *node, const char *key, void *data);
+
+int __init xbc_snprint_cmdline_filter(char *buf, size_t size, struct xbc_node *root,
+ xbc_cmdline_filter_fn filter, void *data);
+
+static inline int __init xbc_snprint_cmdline(char *buf, size_t size, struct xbc_node *root)
+{
+ return xbc_snprint_cmdline_filter(buf, size, root, NULL, NULL);
+}
/**
* xbc_node_compose_key() - Compose full key string of the XBC node
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 8a75a6cd7309..02ef7f899b3d 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -345,27 +345,19 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
* calling bpf_setsockopt on listener-sk will not make sense anyway,
* so passing 'sock_ops->sk == req_sk' to the bpf prog is appropriate here.
*/
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(sock_ops, sk) \
-({ \
- int __ret = 0; \
- if (cgroup_bpf_enabled(CGROUP_SOCK_OPS)) \
- __ret = __cgroup_bpf_run_filter_sock_ops(sk, \
- sock_ops, \
- CGROUP_SOCK_OPS); \
- __ret; \
-})
-
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \
-({ \
- int __ret = 0; \
- if (cgroup_bpf_enabled(CGROUP_SOCK_OPS) && (sock_ops)->sk) { \
- typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \
- if (__sk && sk_fullsock(__sk)) \
- __ret = __cgroup_bpf_run_filter_sock_ops(__sk, \
- sock_ops, \
- CGROUP_SOCK_OPS); \
- } \
- __ret; \
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(sock_ops, sk) \
+ __cgroup_bpf_run_filter_sock_ops(sk, sock_ops, \
+ CGROUP_SOCK_OPS)
+
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \
+({ \
+ int __ret = 0; \
+ typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \
+ if (__sk && sk_fullsock(__sk)) \
+ __ret = __cgroup_bpf_run_filter_sock_ops(__sk, \
+ sock_ops, \
+ CGROUP_SOCK_OPS); \
+ __ret; \
})
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) \
@@ -529,7 +521,7 @@ static inline int cgroup_bpf_struct_ops_attach(struct bpf_map *map,
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
#define BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) ({ 0; })
#define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos) ({ 0; })
#define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, \
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index c51083c761cf..791398e14962 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -9,6 +9,20 @@
#include <linux/filter.h> /* for MAX_BPF_STACK */
#include <linux/tnum.h>
#include <linux/cnum.h>
+#include <linux/math64.h> /* for div_s64_rem() */
+
+/*
+ * Mathematical modulo, the residue of 'v' modulo 'step', normalized to [0, step).
+ * This differs from C's '%' operator, which truncates the quotient toward zero
+ * and so returns a remainder with the sign of the dividend (e.g. -1 % 3 == -1, not 2).
+ */
+static inline u16 imod(s64 v, u16 step)
+{
+ s32 rem;
+
+ div_s64_rem(v, step, &rem);
+ return rem < 0 ? rem + step : rem;
+}
/* Maximum variable offset umax_value permitted when resolving memory accesses.
* In practice this is far bigger than any realistic pointer offset; this limit
@@ -125,6 +139,13 @@ struct bpf_reg_state {
*/
struct cnum64 r64; /* 64-bit range as circular number */
struct cnum32 r32; /* 32-bit range as circular number */
+ /*
+ * The value described by this register, interpreted as s64, lies on
+ * a line described by a linear equation base + step * k.
+ * Invariant: base < step.
+ */
+ u16 base;
+ u16 step;
/* For PTR_TO_PACKET, used to find other pointers with the same variable
* offset, so they can share range knowledge.
* For PTR_TO_MAP_VALUE_OR_NULL this is used to share which map value we
@@ -163,9 +184,9 @@ struct bpf_reg_state {
* other registers. Kept outside the metadata union for ID remapping
* during state comparisons.
*/
- u32 map_uid;
+ u32 map_uid:31;
/* if (!precise && SCALAR_VALUE) min/max/tnum don't affect safety */
- bool precise;
+ u32 precise:1;
};
static inline s64 reg_smin(const struct bpf_reg_state *reg)
@@ -307,6 +328,25 @@ struct bpf_retval_range {
bool return_32bit;
};
+/* SCEV/widening register space: r0..r10 plus every stack slot of a frame. */
+#define BPF_SCEV_REGS_NUM (MAX_BPF_REG + MAX_BPF_STACK_SLOTS)
+
+struct bpf_loop_iters {
+ u32 min_header_count; /* min number of times header is executed */
+ u32 max_header_count; /* max number of times header is executed */
+ unsigned long precise_regs[BITS_TO_LONGS(BPF_SCEV_REGS_NUM)];
+};
+
+struct loop_stack_entry {
+ struct bpf_verifier_state *entry_state;
+ u32 min_header_count;
+ u32 max_header_count;
+ u32 loop_id:31;
+ u32 terminates:1;
+};
+
+#define LOOP_STACK_SIZE 16
+
/* state of the program:
* type of all registers and stack info
*/
@@ -352,6 +392,11 @@ struct bpf_func_state {
u32 callback_depth;
/* Instructions processed in this frame and callees on the current path. */
u32 insns_subtotal;
+ /*
+ * Control-flow loop nesting at the current insn within this frame's
+ * subprogram (loops never cross subprogram boundaries).
+ */
+ u32 loop_stack_cnt;
/* The following fields should be last. See copy_func_state() */
/* The state of the stack. Each element of the array describes BPF_REG_SIZE
@@ -369,6 +414,7 @@ struct bpf_func_state {
u16 out_stack_arg_cnt; /* Number of outgoing on-stack argument slots */
struct bpf_reg_state *stack_arg_regs; /* Outgoing on-stack arguments */
+ struct loop_stack_entry *loop_stack;
};
#define MAX_CALL_FRAMES 16
@@ -415,6 +461,7 @@ static_assert(MAX_BPF_STACK_SLOTS <= (1 << 12));
#define MAX_STACK_ARG_SLOTS (MAX_BPF_FUNC_ARGS - MAX_BPF_FUNC_REG_ARGS)
#define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK_SLOTS + MAX_STACK_ARG_SLOTS) * \
MAX_CALL_FRAMES)
+
struct bpf_verifier_state {
/* call stack tracking */
struct bpf_func_state *frame[MAX_CALL_FRAMES];
@@ -481,7 +528,10 @@ struct bpf_verifier_state {
bool speculative;
bool in_sleepable;
- /* first and last insn idx of this verifier state */
+ /*
+ * First and last insn idx of this verifier state.
+ * last_insn_idx is -1 if no instructions have been executed yet.
+ */
u32 first_insn_idx;
u32 last_insn_idx;
/* if this state is a backedge state then equal_state
@@ -508,7 +558,7 @@ static inline u32 bpf_stack_nr_slots(const struct bpf_func_state *frame)
/*
* Stack slot @spi of @frame, covering bytes [fp - (spi + 1) * 8, fp - spi * 8).
- * The caller must ensure spi < bpf_stack_nr_slots(frame), see grow_stack_state().
+ * The caller must ensure spi < bpf_stack_nr_slots(frame), see bpf_grow_stack_state().
*/
static inline struct bpf_stack_state *bpf_stack_slot(const struct bpf_func_state *frame, u32 spi)
{
@@ -629,6 +679,52 @@ struct bpf_iarray {
u32 items[];
};
+#define iarray_for_each(item, arr) \
+ for (int ___idx = 0; \
+ ___idx < (arr)->cnt && ({ item = (arr)->items[___idx]; 1; }); \
+ ___idx++)
+
+#define MAX_BACKEDGES 16
+#define MAX_LOOP_EXITS 256
+
+/* Number of exit conditions dominating a backedge. */
+#define MAX_LATCHES 4
+
+struct bpf_backedge {
+ int from;
+ /*
+ * Conditional jumps within the loop that dominate 'from' and have
+ * a successor outside the loop, nearest first. latches[0] is the
+ * latch; the remaining entries are additional exit conditions.
+ * Each usable condition gives an upper bound on the iteration count,
+ * so keeping only a subset is sound.
+ */
+ int latches[MAX_LATCHES];
+ u8 latches_cnt;
+};
+
+struct bpf_loop_exit {
+ int from; /* instruction inside the loop */
+ int to; /* instruction outside the loop */
+};
+
+struct bpf_loop {
+ struct bpf_backedge backedges[MAX_BACKEDGES];
+ /* edges exiting from this loop, includes edges from nested loops */
+ struct bpf_loop_exit *exits;
+ int backedges_cnt;
+ int exits_cnt;
+ bool irreducible;
+ bool backedges_overflow;
+ bool exits_overflow;
+ /*
+ * Loop-entry registers used to compute stack addresses for loads,
+ * stores and calls requiring fixed stack offsets, in this and nested
+ * loops.
+ */
+ unsigned long store_base_regs[BITS_TO_LONGS(BPF_SCEV_REGS_NUM)];
+};
+
struct bpf_insn_aux_data {
union {
enum bpf_reg_type ptr_type; /* pointer type for load/store insns */
@@ -662,6 +758,13 @@ struct bpf_insn_aux_data {
};
struct btf_struct_meta *kptr_struct_meta;
u64 map_key_state; /* constant (32 bit) key tracking for maps */
+ /*
+ * Per-instruction summary of stack slots in the current frame
+ * that this instruction may write to.
+ */
+ DECLARE_BITMAP(may_write_mask, MAX_BPF_STACK_SLOTS);
+ DECLARE_BITMAP(live_stack_before, MAX_BPF_STACK_SLOTS);
+ u16 stack_ptrs; /* bitmask of regs that may hold a frame pointer here (arg_track) */
int ctx_field_size; /* the ctx field size for load insn, maybe 0 */
u32 seen; /* this insn was processed by the verifier at env->pass_cnt */
bool nospec; /* do not execute this instruction speculatively */
@@ -673,6 +776,8 @@ struct bpf_insn_aux_data {
bool is_iter_next; /* bpf_iter_<type>_next() kfunc call */
bool call_with_percpu_alloc_ptr; /* {this,per}_cpu_ptr() with prog percpu alloc */
bool arena_scalar; /* ldx/stx/st/atomic through a number, it's an address in arena */
+ bool bb_end; /* last instruction of a basic block */
+ bool need_scev;
u8 alu_state; /* used in combination with alu_limit */
/* true if STX or LDX instruction is a part of a spill/fill
* pattern for a bpf_fastcall call.
@@ -719,6 +824,13 @@ struct bpf_insn_aux_data {
u16 const_reg_map_mask;
u16 const_reg_subprog_mask;
u32 const_reg_vals[10];
+ /*
+ * Header index of the innermost loop containing this instruction, -1 if none.
+ * For a loop header, identifies the parent loop instead.
+ */
+ s32 loop_header;
+ /* additional information about the loop if this instruction is a loop header */
+ struct bpf_loop *loop;
};
#define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */
@@ -921,6 +1033,7 @@ struct bpf_scc_info {
};
struct bpf_liveness;
+struct scev;
struct bpf_fd_array {
union {
@@ -1008,6 +1121,7 @@ struct bpf_verifier_env {
* see bpf_subprog_info->postorder_start.
*/
int *insn_postorder;
+ int *postorder_nums;
int cur_stack;
/* current position in the insn_postorder vector */
int cur_postorder;
@@ -1083,6 +1197,8 @@ struct bpf_verifier_env {
u32 scc_cnt;
struct bpf_iarray *succ;
struct bpf_iarray *gotox_tmp_buf;
+ int *idoms;
+ struct scev *scev;
};
static inline struct bpf_func_info_aux *subprog_aux(struct bpf_verifier_env *env, int subprog)
@@ -1144,6 +1260,7 @@ int bpf_vlog_finalize(struct bpf_verifier_log *log, u32 *log_size_actual);
__printf(3, 4) void verbose_linfo(struct bpf_verifier_env *env,
u32 insn_off,
const char *prefix_fmt, ...);
+void bpf_verbose_snum(struct bpf_verifier_env *env, s64 num);
#define verifier_bug_if(cond, env, fmt, args...) \
({ \
@@ -1261,6 +1378,7 @@ void bpf_free_kfunc_btf_tab(struct bpf_kfunc_btf_tab *tab);
int mark_chain_precision(struct bpf_verifier_env *env, int regno);
int bpf_is_state_visited(struct bpf_verifier_env *env, int insn_idx);
+int bpf_split_cur_state(struct bpf_verifier_env *env);
int bpf_update_branch_counts(struct bpf_verifier_env *env, struct bpf_verifier_state *st);
void bpf_clear_jmp_history(struct bpf_verifier_state *state);
@@ -1275,7 +1393,9 @@ int bpf_push_jmp_history(struct bpf_verifier_env *env, struct bpf_verifier_state
void bpf_bt_sync_linked_regs(struct backtrack_state *bt, struct bpf_jmp_history_entry *hist);
void bpf_mark_reg_not_init(const struct bpf_verifier_env *env,
struct bpf_reg_state *reg);
+void bpf_mark_reg_known_scalar(struct bpf_reg_state *reg, u64 imm);
void bpf_mark_reg_unknown_imprecise(struct bpf_reg_state *reg);
+int bpf_grow_stack_state(struct bpf_verifier_env *env, struct bpf_func_state *state, int size);
void bpf_mark_all_scalars_precise(struct bpf_verifier_env *env,
struct bpf_verifier_state *st);
void bpf_clear_singular_ids(struct bpf_verifier_env *env, struct bpf_verifier_state *st);
@@ -1339,6 +1459,15 @@ static inline bool bpf_is_spilled_reg(const struct bpf_stack_state *stack)
return stack->slot_type[BPF_REG_SIZE - 1] == STACK_SPILL;
}
+static inline int bpf_spill_size(const struct bpf_stack_state *stack)
+{
+ int i, spill_size = 0;
+
+ for (i = BPF_REG_SIZE - 1; i >= 0 && stack->slot_type[i] == STACK_SPILL; i--)
+ spill_size++;
+ return spill_size;
+}
+
static inline bool bpf_is_spilled_scalar_reg(const struct bpf_stack_state *stack)
{
return bpf_is_spilled_reg(stack) && stack->spilled_ptr.type == SCALAR_VALUE;
@@ -1723,17 +1852,37 @@ bool bpf_is_may_goto_insn(struct bpf_insn *insn);
void bpf_verbose_insn(struct bpf_verifier_env *env, struct bpf_insn *insn);
bool bpf_get_call_summary(struct bpf_verifier_env *env, struct bpf_insn *call,
struct bpf_call_summary *cs);
-s64 bpf_helper_stack_access_bytes(struct bpf_verifier_env *env,
- struct bpf_insn *insn, int arg,
- int insn_idx);
-s64 bpf_kfunc_stack_access_bytes(struct bpf_verifier_env *env,
- struct bpf_insn *insn, int arg,
- int insn_idx);
+/* Stack effects used for state pruning; must_write implies may_write. */
+struct arg_access_info {
+ u32 size; /* Maximum extent; U32_MAX if unknown. */
+ u8 may_read:1; /* Incoming contents or initialization may be needed. */
+ u8 may_write:1;
+ u8 must_write:1; /* Prior verifier state is destroyed throughout size. */
+};
+
+struct arg_access_info
+bpf_helper_stack_access_bytes(struct bpf_verifier_env *env,
+ struct bpf_insn *insn, int arg, int insn_idx);
+struct arg_access_info
+bpf_kfunc_stack_access_bytes(struct bpf_verifier_env *env,
+ struct bpf_insn *insn, int arg, int insn_idx);
+struct arg_access_info
+bpf_global_subprog_stack_access_bytes(struct bpf_verifier_env *env,
+ struct bpf_insn *insn, int arg, int insn_idx);
int bpf_compute_subprog_arg_access(struct bpf_verifier_env *env);
+bool bpf_same_memory_origin(const struct bpf_reg_state *reg_a,
+ const struct bpf_reg_state *reg_b);
+int bpf_set_reg_range(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
+ struct cnum64 range, u16 base, u16 step);
+bool bpf_reg_union_compatible(const struct bpf_reg_state *a, const struct bpf_reg_state *b);
+int bpf_reg_union(struct bpf_verifier_env *env, struct bpf_reg_state *acc,
+ const struct bpf_reg_state *src);
int bpf_stack_liveness_init(struct bpf_verifier_env *env);
void bpf_stack_liveness_free(struct bpf_verifier_env *env);
int bpf_live_stack_query_init(struct bpf_verifier_env *env, struct bpf_verifier_state *st);
+const unsigned long *bpf_may_write_mask(struct bpf_verifier_env *env, u32 insn_idx);
+bool bpf_needs_fixed_stack_off(struct bpf_verifier_env *env, int insn_idx);
bool bpf_stack_slot_alive(struct bpf_verifier_env *env, u32 frameno, u32 spi);
int bpf_compute_live_registers(struct bpf_verifier_env *env);
@@ -1830,6 +1979,7 @@ int bpf_check_attach_btf_id_multi(struct btf *btf, struct bpf_prog *prog, u32 bt
struct bpf_attach_target_info *tgt_info);
/* Functions in fixups.c, called from bpf_check() */
+void bpf_clear_insn_aux_data(struct bpf_verifier_env *env, int start, int len);
int bpf_remove_fastcall_spills_fills(struct bpf_verifier_env *env);
int bpf_optimize_bpf_loop(struct bpf_verifier_env *env);
void bpf_opt_hard_wire_dead_code_branches(struct bpf_verifier_env *env);
@@ -1842,4 +1992,23 @@ int bpf_fixup_call_args(struct bpf_verifier_env *env);
int bpf_do_misc_fixups(struct bpf_verifier_env *env);
int bpf_insn_def32(struct bpf_prog *prog, struct bpf_insn *insn);
+int bpf_flip_opcode(u32 opcode);
+u8 bpf_rev_opcode(u8 opcode);
+
+int bpf_compute_idoms(struct bpf_verifier_env *env);
+int bpf_compute_loops(struct bpf_verifier_env *env);
+int bpf_loop_at_index(struct bpf_verifier_env *env, u32 idx);
+bool bpf_is_nested_loop(struct bpf_verifier_env *env, int inner_header, int outer_header);
+
+int bpf_init_scev(struct bpf_verifier_env *env);
+void bpf_free_scev(struct bpf_verifier_env *env);
+int bpf_compute_scev(struct bpf_verifier_env *env);
+
+int bpf_compute_loop_iters(struct bpf_verifier_env *env, struct bpf_verifier_state *st,
+ struct bpf_loop_iters *iters);
+int bpf_widen_scev_regs(struct bpf_verifier_env *env, struct bpf_verifier_state *st,
+ struct bpf_verifier_state *loop_entry, struct bpf_loop_iters *iters);
+int bpf_clamp_scev_regs(struct bpf_verifier_env *env, struct bpf_func_state *st, u32 insn_idx,
+ struct bpf_verifier_state *entry_state, u32 max_header_count);
+
#endif /* _LINUX_BPF_VERIFIER_H */
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index 14fa93268630..a697246feeac 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -66,7 +66,8 @@ void bsg_job_done(struct bsg_job *job, int result,
unsigned int reply_payload_rcv_len);
struct request_queue *bsg_setup_queue(struct device *dev, const char *name,
struct queue_limits *lim, bsg_job_fn *job_fn,
- bsg_timeout_fn *timeout, int dd_job_size);
+ bsg_timeout_fn *timeout, int dd_job_size,
+ unsigned int reply_len);
void bsg_remove_queue(struct request_queue *q);
void bsg_job_put(struct bsg_job *job);
int __must_check bsg_job_get(struct bsg_job *job);
diff --git a/include/linux/btf.h b/include/linux/btf.h
index 4b63bb91550a..b66e20a18c54 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -5,6 +5,7 @@
#define _LINUX_BTF_H 1
#include <linux/types.h>
+#include <linux/module.h>
#include <linux/bpfptr.h>
#include <linux/bsearch.h>
#include <linux/btf_ids.h>
@@ -118,6 +119,19 @@ struct btf_show;
struct btf_id_set;
struct bpf_prog;
+#define BTF_LINK_SHA256_LEN 32
+
+/*
+ * A .BTF.link or .BTF.inline.link section identifies the module which
+ * carries a vmlinux BTF section. The module name is NUL terminated and the
+ * field is padded to __MODULE_NAME_LEN.
+ */
+struct btf_link {
+ char module_name[__MODULE_NAME_LEN];
+ u8 sha256[BTF_LINK_SHA256_LEN];
+ u32 btf_size;
+} __packed;
+
typedef int (*btf_kfunc_filter_t)(const struct bpf_prog *prog, u32 kfunc_id);
struct btf_kfunc_id_set {
@@ -594,7 +608,8 @@ struct btf_field_iter {
#ifdef CONFIG_BPF_SYSCALL
const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id);
void btf_set_base_btf(struct btf *btf, const struct btf *base_btf);
-int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32 **map_ids);
+int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32 **map_ids,
+ __u32 **map_strs);
int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
enum btf_field_iter_kind iter_kind);
__u32 *btf_field_iter_next(struct btf_field_iter *it);
@@ -624,6 +639,29 @@ bool btf_types_are_same(const struct btf *btf1, u32 id1,
const struct btf *btf2, u32 id2);
int btf_check_iter_arg(struct btf *btf, const struct btf_type *func, int arg_idx);
+#if IS_ENABLED(CONFIG_SYSFS)
+struct bin_attribute *sysfs_btf_add(const char *name, void *data, size_t data_size,
+ bool mmap, const char *lazy_module_name);
+bool sysfs_btf_update(struct bin_attribute *attr, void *data);
+void sysfs_btf_remove(struct bin_attribute *attr);
+#else
+static inline struct bin_attribute *
+sysfs_btf_add(const char *name, void *data, size_t data_size, bool mmap,
+ const char *lazy_module_name)
+{
+ return NULL;
+}
+
+static inline bool sysfs_btf_update(struct bin_attribute *attr, void *data)
+{
+ return false;
+}
+
+static inline void sysfs_btf_remove(struct bin_attribute *attr)
+{
+}
+#endif
+
static inline bool btf_type_is_struct_ptr(struct btf *btf, const struct btf_type *t)
{
if (!btf_type_is_ptr(t))
@@ -645,7 +683,7 @@ static inline void btf_set_base_btf(struct btf *btf, const struct btf *base_btf)
}
static inline int btf_relocate(void *log, struct btf *btf, const struct btf *base_btf,
- __u32 **map_ids)
+ __u32 **map_ids, __u32 **map_strs)
{
return -EOPNOTSUPP;
}
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index df9ce860e787..8decff9484c4 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -108,7 +108,8 @@ struct bvec_iter {
unsigned int bi_idx;
/*
- * Current offset in the bvec entry pointed to by `bi_idx`.
+ * Current offset in the bvec entry pointed to by `bi_idx` or into
+ * a dma-buf map.
*/
unsigned int bi_offset;
} __packed __aligned(4);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index b179b1813278..61c4abf19995 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -265,6 +265,12 @@ int omap2_clk_disable_autoidle_all(void);
int omap2_clk_enable_autoidle_all(void);
int omap2_clk_allow_idle(struct clk *clk);
int omap2_clk_deny_idle(struct clk *clk);
+unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
+ unsigned long parent_rate);
+int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
+ unsigned long parent_rate);
+void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
+void omap2xxx_clkt_vps_init(void);
unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
void ti_dt_clk_init_retry_clks(void);
@@ -316,6 +322,8 @@ void omap3_noncore_dpll_restore_context(struct clk_hw *hw);
int omap3_core_dpll_save_context(struct clk_hw *hw);
void omap3_core_dpll_restore_context(struct clk_hw *hw);
+extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
+
#ifdef CONFIG_ATAGS
int omap3430_clk_legacy_init(void);
int omap3430es1_clk_legacy_init(void);
diff --git a/include/linux/cnum.h b/include/linux/cnum.h
index 49b7d0c7645d..49160318adf9 100644
--- a/include/linux/cnum.h
+++ b/include/linux/cnum.h
@@ -39,6 +39,7 @@ u32 cnum32_umin(struct cnum32 cnum);
u32 cnum32_umax(struct cnum32 cnum);
s32 cnum32_smin(struct cnum32 cnum);
s32 cnum32_smax(struct cnum32 cnum);
+struct cnum32 cnum32_union(struct cnum32 a, struct cnum32 b);
struct cnum32 cnum32_intersect(struct cnum32 a, struct cnum32 b);
void cnum32_intersect_with(struct cnum32 *dst, struct cnum32 src);
void cnum32_intersect_with_urange(struct cnum32 *dst, u32 min, u32 max);
@@ -65,6 +66,7 @@ u64 cnum64_umin(struct cnum64 cnum);
u64 cnum64_umax(struct cnum64 cnum);
s64 cnum64_smin(struct cnum64 cnum);
s64 cnum64_smax(struct cnum64 cnum);
+struct cnum64 cnum64_union(struct cnum64 a, struct cnum64 b);
struct cnum64 cnum64_intersect(struct cnum64 a, struct cnum64 b);
void cnum64_intersect_with(struct cnum64 *dst, struct cnum64 src);
void cnum64_intersect_with_urange(struct cnum64 *dst, u64 min, u64 max);
@@ -78,5 +80,6 @@ bool cnum64_is_subset(struct cnum64 outer, struct cnum64 inner);
struct cnum32 cnum32_from_cnum64(struct cnum64 cnum);
struct cnum64 cnum64_cnum32_intersect(struct cnum64 a, struct cnum32 b);
+struct cnum64 cnum64_intersect_linear(struct cnum64 in, u16 base, u16 step);
#endif /* _LINUX_CNUM_H */
diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h
index 476c4c560d17..625e95e684c7 100644
--- a/include/linux/compiler_attributes.h
+++ b/include/linux/compiler_attributes.h
@@ -323,6 +323,18 @@
#define __pure __attribute__((__pure__))
/*
+ * Optional: not supported by gcc
+ * Optional: only supported since clang >= 20.0
+ *
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#require-explicit-initialization
+ */
+#if __has_attribute(__require_explicit_initialization__)
+# define __require_explicit_initialization __attribute__((__require_explicit_initialization__))
+#else
+# define __require_explicit_initialization
+#endif
+
+/*
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-section-function-attribute
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute
* clang: https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate
diff --git a/include/linux/coredump.h b/include/linux/coredump.h
index 74af57b9406b..8e857770dd21 100644
--- a/include/linux/coredump.h
+++ b/include/linux/coredump.h
@@ -5,6 +5,7 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/fs.h>
+#include <linux/pid_types.h>
#include <linux/sched/coredump.h>
#include <uapi/linux/coredump.h>
#include <asm/siginfo.h>
@@ -51,7 +52,8 @@ struct coredump_params {
int vma_count;
size_t vma_data_size;
struct core_vma_metadata *vma_meta;
- struct pid *pid;
+ /* Dumping thread and its thread-group leader by pid type. */
+ DECLARE_PIDS(pid, PIDTYPE_TGID);
};
extern unsigned int core_file_note_size_limit;
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index adf239f8205f..d5ce9ecb28f3 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -239,7 +239,8 @@ enum dentry_flags {
DCACHE_DENTRY_CURSOR = BIT(25),
DCACHE_NORCU = BIT(26), /* No RCU delay for freeing */
DCACHE_PERSISTENT = BIT(27),
-/* 28, 29, 30 free */
+ DCACHE_UNCOVERED = BIT(28), /* lost its mounts on its way out */
+/* 29, 30 free */
DCACHE_PRIVATE = BIT(31) /* fs-specific flag */
};
diff --git a/include/linux/dma-buf-io.h b/include/linux/dma-buf-io.h
new file mode 100644
index 000000000000..b9bbeca1744f
--- /dev/null
+++ b/include/linux/dma-buf-io.h
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DMA_BUF_IO_H__
+#define __DMA_BUF_IO_H__
+
+#include <linux/dma-buf.h>
+
+struct dma_buf_io_ctx;
+struct dma_buf_io_map;
+
+struct dma_buf_io_ops {
+ /*
+ * Create a new map for the given ctx. Called with the reservation
+ * lock held.
+ */
+ struct dma_buf_io_map *(*map)(struct dma_buf_io_ctx *ctx);
+
+ /*
+ * Clean up device specific parts of the @map. Called with the
+ * reservation lock held.
+ */
+ void (*unmap)(struct dma_buf_io_ctx *ctx, struct dma_buf_io_map *map);
+
+ /*
+ * The user tries to destroy the ctx. Release all device specific
+ * parts of the token.
+ */
+ void (*release)(struct dma_buf_io_ctx *);
+};
+
+struct dma_buf_io_map {
+ /*
+ * Counts attached requests and other users. Device specific unmapping
+ * is deferred until all refs are dropped.
+ */
+ struct percpu_ref refs;
+ /*
+ * Shift for the minimum segment size of the mapping.
+ */
+ unsigned min_seg_shift;
+
+ struct dma_buf_io_ctx *ctx;
+ struct completion drained;
+};
+
+struct dma_buf_io_ctx {
+ struct dma_buf_io_map __rcu *map;
+ struct dma_buf *dmabuf;
+ enum dma_data_direction dir;
+ bool is_dead;
+
+ void *dev_priv;
+ const struct dma_buf_io_ops *dev_ops;
+};
+
+int dma_buf_io_ctx_create(struct file *file,
+ struct dma_buf *dmabuf,
+ enum dma_data_direction dir,
+ struct dma_buf_io_ctx **ctx);
+void dma_buf_io_ctx_release(struct dma_buf_io_ctx *ctx);
+
+struct dma_buf_io_map *dma_buf_io_create_map(struct dma_buf_io_ctx *ctx);
+
+static inline struct dma_buf_io_map *
+__dma_buf_io_get_map(struct dma_buf_io_ctx *ctx)
+{
+ struct dma_buf_io_map *map;
+
+ guard(rcu)();
+
+ map = rcu_dereference(ctx->map);
+ if (unlikely(!map || !percpu_ref_tryget_live_rcu(&map->refs)))
+ return NULL;
+
+ return map;
+}
+
+/**
+ * dma_buf_io_get_map - Create a new or reference an existing map.
+ * @ctx: [in] dma-buf I/O context
+ * @nowait: [in] specifies whether it's allowed to block
+ *
+ * Create a new or acquire an existing map. When succeeds, it returns
+ * a referenced map, which should eventually be put down with
+ * dma_buf_io_map_drop(). If @nowait is set and the function would block,
+ * it return -EAGAIN, and the caller is expected to retry from a context
+ * where blocking is allowed.
+ *
+ * Returns a map on success, or ERR_PTR encoded errno otherwise.
+ */
+static inline struct dma_buf_io_map *
+dma_buf_io_get_map(struct dma_buf_io_ctx *ctx, bool nowait)
+{
+ struct dma_buf_io_map *map;
+
+ map = __dma_buf_io_get_map(ctx);
+ if (likely(map))
+ return map;
+
+ if (nowait)
+ return ERR_PTR(-EAGAIN);
+ return dma_buf_io_create_map(ctx);
+}
+
+/**
+ * dma_buf_io_map_drop - Drop the map.
+ * @map: [in] dma-buf I/O map
+ *
+ * Put down a reference for the @map acquired via dma_buf_io_get_map().
+ * Should be called as soon as I/O is completed.
+ */
+static inline void dma_buf_io_map_drop(struct dma_buf_io_map *map)
+{
+ percpu_ref_put(&map->refs);
+}
+
+/*
+ * Device API
+ */
+
+void dma_buf_io_invalidate_mappings(struct dma_buf_io_ctx *ctx);
+int dma_buf_io_init_map(struct dma_buf_io_ctx *ctx, struct dma_buf_io_map *map,
+ struct sg_table *sgt);
+void dma_buf_io_detach(struct dma_buf_io_ctx *ctx);
+
+#endif
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index dbb5c825a1cc..9c563fbdbbf0 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -92,17 +92,17 @@ struct fw_card {
u64 reset_jiffies;
struct {
- int current_tlabel;
- u64 tlabel_mask;
- struct list_head list;
+ int current_tlabel __guarded_by(&lock);
+ u64 tlabel_mask __guarded_by(&lock);
+ struct list_head list __guarded_by(&lock);
spinlock_t lock;
} transactions;
struct {
- u32 hi;
- u32 lo;
- unsigned int cycles;
- unsigned int jiffies;
+ u32 hi __guarded_by(&lock);
+ u32 lo __guarded_by(&lock);
+ unsigned int cycles __guarded_by(&lock);
+ unsigned int jiffies __guarded_by(&lock);
spinlock_t lock;
} split_timeout;
@@ -139,7 +139,7 @@ struct fw_card {
u32 broadcast_channel;
struct {
- __be32 buffer[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4];
+ __be32 buffer[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4] __guarded_by(&lock);
spinlock_t lock;
} topology_map;
@@ -286,20 +286,69 @@ struct fw_request;
typedef void (*fw_packet_callback_t)(struct fw_packet *packet,
struct fw_card *card, int status);
+
+/**
+ * typedef fw_transaction_callback_t - Function to handle the result of outgoing transaction.
+ * @card: the interface to send the request at
+ * @rcode: the response code
+ * @data: the data for the response subaction
+ * @length: the length of data
+ * @callback_data: the data registered with this callback
+ *
+ * This callback is called from a workqueue in process context after the outgoing transaction is
+ * completed successfully or unsuccessfully.
+ *
+ * Among its parameters is the response code which is either one of the rcodes per IEEE 1394 or, in
+ * case of internal errors, the firewire-core specific %RCODE_SEND_ERROR. The other firewire-core
+ * specific rcodes (%RCODE_CANCELLED, %RCODE_BUSY, %RCODE_GENERATION, %RCODE_NO_ACK) denote
+ * transaction timeout, busy responder, stale request generation, or missing ACK respectively.
+ *
+ * Context: Process context.
+ */
typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
void *data, size_t length,
void *callback_data);
+
+/**
+ * typedef fw_transaction_callback_with_tstamp_t - Function to handle the result of outgoing
+ * transaction with hardware time stamps.
+ * @card: the interface to send the request at
+ * @rcode: the response code
+ * @request_tstamp: the time stamp at which the request subaction finished
+ * @response_tstamp: the time stamp at which the response subaction finished
+ * @data: the data for the response subaction
+ * @length: the length of data
+ * @callback_data: the data registered with this callback
+ *
+ * This callback is called from a workqueue in process context after the outgoing transaction is
+ * completed successfully or unsuccessfully.
+ *
+ * Among its parameters is the response code which is either one of the rcodes per IEEE 1394 or, in
+ * case of internal errors, the firewire-core specific %RCODE_SEND_ERROR. The other firewire-core
+ * specific rcodes (%RCODE_CANCELLED, %RCODE_BUSY, %RCODE_GENERATION, %RCODE_NO_ACK) denote
+ * transaction timeout, busy responder, stale request generation, or missing ACK respectively.
+ *
+ * The timestamp consists of the low order 3 bits of second field and the full 13 bits of count
+ * field of isochronous cycle time register.
+ *
+ * Context: Process context.
+ */
typedef void (*fw_transaction_callback_with_tstamp_t)(struct fw_card *card, int rcode,
u32 request_tstamp, u32 response_tstamp, void *data,
size_t length, void *callback_data);
+/**
+ * union fw_transaction_callback - A union to store the outgoing transaction callback.
+ * @without_tstamp: Callback without hardware timestamps.
+ * @with_tstamp: Callback with hardware timestamps.
+ */
union fw_transaction_callback {
fw_transaction_callback_t without_tstamp;
fw_transaction_callback_with_tstamp_t with_tstamp;
};
/**
- * typedef fw_address_callback_t - Function to handle the request of the asynchronous transaction.
+ * typedef fw_address_callback_t - Function to handle the request of the incoming transaction.
* @card: the card instance which receives the request
* @request: the request instance.
* @tcode: the transaction code
@@ -313,8 +362,9 @@ union fw_transaction_callback {
*
* This callback handles an inbound request subaction.
*
- * The callback is responsible that fw_send_response() is called on the @request, except for FCP
- * registers for which the core takes care of that.
+ * The contents of @request are opaque to the callback. The callback is responsible for calling
+ * fw_send_response() for @request, except for FCP registers, for which the core handles the
+ * response.
*
* Context: Process context.
*/
@@ -352,7 +402,15 @@ struct fw_packet {
void *driver_data;
};
+/**
+ * struct fw_transaction - A structure to hold outgoing transaction state.
+ *
+ * All structure members are for internal use only. Once passed to __fw_send_request(), this
+ * structure holds the state of an outgoing transaction. It must not be freed until the callback
+ * reports the transaction result.
+ */
struct fw_transaction {
+ /* private: */
int node_id; /* The generation is implied; it is always the current. */
int tlabel;
struct list_head link;
@@ -377,18 +435,37 @@ struct fw_transaction {
u32 response_timestamp;
};
+/**
+ * struct fw_address_handler - A handler for incoming transaction requests to a registered address
+ * region.
+ * @offset: The registered offset, available after successful registration.
+ * @length: The length of the address region in bytes, a multiple of a quadlet.
+ * @address_callback: Callback invoked when a transaction request is received for the registered
+ * address region.
+ * @callback_data: Data passed to @address_callback.
+ *
+ * This structure represents a handler registered to receive incoming asynchronous requests to a
+ * specific region of the address space on the local node.
+ */
struct fw_address_handler {
u64 offset;
u64 length;
fw_address_callback_t address_callback;
void *callback_data;
- // Only for core functions.
+ /* private: */
struct list_head link;
struct kref kref;
struct completion done;
};
+/**
+ * struct fw_address_region - An address range.
+ * @start: The starting offset in bytes, a multiple of a quadlet.
+ * @end: The ending offset in bytes, a multiple of a quadlet.
+ *
+ * Represents a range of addresses in the local node's address space.
+ */
struct fw_address_region {
u64 start;
u64 end;
@@ -429,6 +506,8 @@ void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode
*
* After the transaction is completed successfully or unsuccessfully, the @callback will be called
* in process context.
+ *
+ * Context: Any context.
*/
static inline void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
int destination_id, int generation, int speed,
@@ -461,6 +540,8 @@ static inline void fw_send_request(struct fw_card *card, struct fw_transaction *
*
* After the transaction is completed successfully or unsuccessfully, the @callback will be called
* in process context.
+ *
+ * Context: Any context.
*/
static inline void fw_send_request_with_tstamp(struct fw_card *card, struct fw_transaction *t,
int tcode, int destination_id, int generation, int speed, unsigned long long offset,
diff --git a/include/linux/firmware/intel/stratix10-smc.h b/include/linux/firmware/intel/stratix10-smc.h
index 366309260121..6a6fa51ad39e 100644
--- a/include/linux/firmware/intel/stratix10-smc.h
+++ b/include/linux/firmware/intel/stratix10-smc.h
@@ -725,6 +725,27 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_POLL)
/**
+ * Request INTEL_SIP_SMC_ASYNC_POLL_ON_IRQ
+ * Async call used by service driver at EL1 to retrieve the transaction IDs
+ * of available responses from the SDM mailbox (typically after an IRQ).
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_ASYNC_POLL_ON_IRQ
+ * a1-a17 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ * a1-a4 contain a bitmap of pending transaction IDs (set bit positions)
+ * a5-a17 not used
+ * Or
+ * a0 INTEL_SIP_SMC_STATUS_NO_RESPONSE
+ * a1-a17 not used
+ */
+#define INTEL_SIP_SMC_ASYNC_FUNC_ID_IRQ_POLL (0xC9)
+#define INTEL_SIP_SMC_ASYNC_POLL_ON_IRQ \
+ INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_IRQ_POLL)
+
+/**
* Request INTEL_SIP_SMC_ASYNC_HWMON_READTEMP
* Async call to request temperature
*
@@ -813,4 +834,27 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
#define INTEL_SIP_SMC_ASYNC_FUNC_ID_RSU_NOTIFY (0xEC)
#define INTEL_SIP_SMC_ASYNC_RSU_NOTIFY \
INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_RSU_NOTIFY)
+
+/**
+ * Request INTEL_SIP_SMC_SDM_REMAPPER_CONFIG
+ *
+ * Sync call to configure the SDM address remapper. On Agilex5, the remapper
+ * must be bypassed when the SMMU is active to avoid conflicts with IOMMU
+ * address translation.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_SDM_REMAPPER_CONFIG
+ * a1: INTEL_SIP_SMC_SDM_REMAPPER_ENABLE or INTEL_SIP_SMC_SDM_REMAPPER_BYPASS
+ * a2-7: not used
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK
+ * a1-3: not used
+ */
+#define INTEL_SIP_SMC_FUNCID_SDM_REMAPPER_CONFIG 513
+#define INTEL_SIP_SMC_SDM_REMAPPER_CONFIG \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_SDM_REMAPPER_CONFIG)
+#define INTEL_SIP_SMC_SDM_REMAPPER_ENABLE 0
+#define INTEL_SIP_SMC_SDM_REMAPPER_BYPASS 1
+
#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 83d41d9f1130..f387c961e0a0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1914,6 +1914,7 @@ struct dir_context {
#define COPY_FILE_SPLICE (1 << 0)
struct io_uring_cmd;
+struct dma_buf_io_ctx;
struct offset_ctx;
struct file_operations {
@@ -1960,6 +1961,7 @@ struct file_operations {
int (*uring_cmd_iopoll)(struct io_uring_cmd *, struct io_comp_batch *,
unsigned int poll_flags);
int (*mmap_prepare)(struct vm_area_desc *);
+ int (*init_dma_buf_io_ctx)(struct file *, struct dma_buf_io_ctx *);
} __randomize_layout;
/* Supports async buffered reads */
diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h
index c920aba5177c..d1727dffecc5 100644
--- a/include/linux/fs_context.h
+++ b/include/linux/fs_context.h
@@ -150,10 +150,10 @@ extern int vfs_parse_fs_param_source(struct fs_context *fc,
struct fs_parameter *param);
extern void fc_drop_locked(struct fs_context *fc);
-extern int get_tree_super(struct fs_context *fc,
- int (*test)(struct super_block *, struct fs_context *),
- int (*fill_super)(struct super_block *sb,
- struct fs_context *fc));
+int get_tree_super(struct fs_context *fc,
+ int (*test)(struct super_block *, struct fs_context *),
+ int (*fill_super)(struct super_block *sb,
+ struct fs_context *fc));
extern int get_tree_nodev(struct fs_context *fc,
int (*fill_super)(struct super_block *sb,
struct fs_context *fc));
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 618eed4d6d72..a6d5c1a89cff 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -566,6 +566,7 @@ struct fsnotify_mark_connector {
unsigned char prio; /* Highest priority group */
#define FSNOTIFY_CONN_FLAG_IS_WATCHED 0x01
#define FSNOTIFY_CONN_FLAG_HAS_IREF 0x02
+#define FSNOTIFY_CONN_FLAG_DESTROYING 0x04
unsigned short flags; /* flags [lock] */
union {
/* Object pointer [lock] */
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index bd76a16a63af..b041d9142d2b 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -416,6 +416,7 @@ void free_ftrace_hash(struct ftrace_hash *hash);
struct ftrace_func_entry *add_ftrace_hash_entry_direct(struct ftrace_hash *hash,
unsigned long ip, unsigned long direct);
void add_ftrace_hash_entry(struct ftrace_hash *hash, struct ftrace_func_entry *entry);
+struct ftrace_func_entry *ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip);
void ftrace_hash_remove(struct ftrace_hash *hash);
/* The hash used to know what functions callbacks trace */
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 18ed18d5cbc1..a895d8c69d66 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -23,28 +23,32 @@ struct task_struct;
* 01 : Shared futex (PTHREAD_PROCESS_SHARED)
* mapped on a file (reference on the underlying inode)
* 10 : Shared futex (PTHREAD_PROCESS_SHARED)
- * (but private mapping on an mm, and reference taken on it)
+ * (but private mapping on an mm)
*/
-#define FUT_OFF_INODE 1 /* We set bit 0 if key has a reference on inode */
-#define FUT_OFF_MMSHARED 2 /* We set bit 1 if key has a reference on mm */
+#define FUT_OFF_INODE 1 /* We set bit 0 if shared key identifies an inode */
+#define FUT_OFF_MMSHARED 2 /* We set bit 1 if shared key identifies an mm */
union futex_key {
+ /* For FUT_OFF_INODE */
struct {
u64 i_seq;
unsigned long pgoff;
unsigned int offset;
/* unsigned int node; */
} shared;
+
+ /* For FUT_OFF_MMSHARED or private */
struct {
union {
- struct mm_struct *mm;
- u64 __tmp;
+ struct mm_struct *mm; /* for private */
+ u64 mm_seq; /* for FUT_OFF_MMSHARED */
};
unsigned long address;
unsigned int offset;
/* unsigned int node; */
} private;
+
struct {
u64 ptr;
unsigned long word;
@@ -152,11 +156,10 @@ static inline void futex_set_vdso_cs_range(struct futex_mm_data *fd, unsigned in
static inline void futex_fixup_robust_unlock(struct pt_regs *regs) { }
#endif /* !CONFIG_FUTEX_ROBUST_UNLOCK */
-
-#if defined(CONFIG_FUTEX_PRIVATE_HASH) || defined(CONFIG_FUTEX_ROBUST_UNLOCK)
+#ifdef CONFIG_FUTEX
void futex_mm_init(struct mm_struct *mm);
#else
static inline void futex_mm_init(struct mm_struct *mm) { }
-#endif
+#endif /* !CONFIG_FUTEX */
#endif /* _LINUX_FUTEX_H */
diff --git a/include/linux/futex_types.h b/include/linux/futex_types.h
index d320c0571f0c..34b16f2828e7 100644
--- a/include/linux/futex_types.h
+++ b/include/linux/futex_types.h
@@ -85,10 +85,12 @@ struct futex_unlock_cs_ranges { };
* struct futex_mm_data - Futex related per MM data
* @phash: Futex private hash related data
* @unlock: Futex unlock VDSO critical sections
+ * @unique_id: Unique ID of the MM, for FUT_OFF_MMSHARED futexes
*/
struct futex_mm_data {
struct futex_mm_phash phash;
struct futex_unlock_cs_ranges unlock;
+ atomic64_t unique_id;
};
#else /* CONFIG_FUTEX */
struct futex_sched_data { };
diff --git a/include/linux/gpio/legacy.h b/include/linux/gpio/legacy.h
index 557ef635935e..4001208d5d63 100644
--- a/include/linux/gpio/legacy.h
+++ b/include/linux/gpio/legacy.h
@@ -63,10 +63,6 @@ static inline int gpio_get_value_cansleep(unsigned gpio)
{
return gpiod_get_raw_value_cansleep(gpio_to_desc(gpio));
}
-static inline void gpio_set_value_cansleep(unsigned gpio, int value)
-{
- gpiod_set_raw_value_cansleep(gpio_to_desc(gpio), value);
-}
static inline int gpio_get_value(unsigned gpio)
{
@@ -148,12 +144,6 @@ static inline int gpio_get_value_cansleep(unsigned gpio)
return 0;
}
-static inline void gpio_set_value_cansleep(unsigned gpio, int value)
-{
- /* GPIO can never have been requested or set as output */
- WARN_ON(1);
-}
-
static inline int gpio_to_irq(unsigned gpio)
{
/* GPIO can never have been requested or set as input */
diff --git a/include/linux/greybus/bundle.h b/include/linux/greybus/bundle.h
index df8d88424cb7..361a94d3499b 100644
--- a/include/linux/greybus/bundle.h
+++ b/include/linux/greybus/bundle.h
@@ -59,14 +59,9 @@ static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle)
return 0;
}
-static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle)
+static inline void gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle)
{
- int retval;
-
- pm_runtime_mark_last_busy(&bundle->dev);
- retval = pm_runtime_put_autosuspend(&bundle->dev);
-
- return retval;
+ pm_runtime_put_autosuspend(&bundle->dev);
}
static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle)
@@ -82,8 +77,7 @@ static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle)
#else
static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle)
{ return 0; }
-static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle)
-{ return 0; }
+static inline void gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) {}
static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) {}
static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) {}
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 73b48dd9f135..2648c49cd8f6 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -108,7 +108,7 @@ DECLARE_PER_CPU(unsigned int, nmi_nesting);
#define __preempt_count_nmi_enter() \
do { \
__preempt_count_add(HARDIRQ_OFFSET); \
- /* Maximum NMI nesting is 15. */ \
+ /* NMI nesting is represented in 4 bits. */ \
BUG_ON(__this_cpu_read(nmi_nesting) >= 15); \
__this_cpu_inc(nmi_nesting); \
preempt_count_set(preempt_count() | NMI_MASK); \
diff --git a/include/linux/hazptr.h b/include/linux/hazptr.h
deleted file mode 100644
index d1670121947a..000000000000
--- a/include/linux/hazptr.h
+++ /dev/null
@@ -1,325 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1-or-later
-//
-// SPDX-FileCopyrightText: 2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-
-#ifndef _LINUX_HAZPTR_H
-#define _LINUX_HAZPTR_H
-
-/*
- * hazptr: Hazard Pointers
- *
- * This API provides existence guarantees of objects through hazard
- * pointers.
- *
- * Its main benefit over RCU is that it allows fast reclaim of
- * HP-protected pointers without needing to wait for a grace period.
- *
- * References:
- *
- * [1]: M. M. Michael, "Hazard pointers: safe memory reclamation for
- * lock-free objects," in IEEE Transactions on Parallel and
- * Distributed Systems, vol. 15, no. 6, pp. 491-504, June 2004
- */
-
-#include <linux/percpu.h>
-#include <linux/types.h>
-#include <linux/cleanup.h>
-#include <linux/sched.h>
-
-/* 4 slots (each sizeof(hazptr_slot_item)) fit in a single 64-byte cache line. */
-#define NR_HAZPTR_PERCPU_SLOTS 4
-
-/* The current hazard pointer wildcard. */
-extern void *hazptr_wildcard;
-
-/*
- * Hazard pointer slot.
- */
-struct hazptr_slot {
- void *addr;
-};
-
-struct hazptr_overflow_list;
-
-struct hazptr_backup_slot {
- struct hlist_node overflow_node;
- struct hazptr_slot slot;
- /* Overflow list where the backup slot is added. */
- struct hazptr_overflow_list *overflow_list;
-};
-
-struct hazptr_ctx {
- struct hazptr_slot *slot;
- /* Backup slot in case all per-CPU slots are used. */
- struct hazptr_backup_slot backup_slot;
- struct hlist_node preempt_node;
-#ifdef CONFIG_HAZPTR_DEBUG
- bool detach_task, detach_cpu; /* Whether the ctx has been detached from task/cpu. */
- int acquire_pid, acquire_cpu; /* Note the task and cpu number at acquire. */
- unsigned long acquire_caller; /* Acquire instruction pointer. */
-#endif
-};
-
-struct hazptr_slot_ctx {
- struct hazptr_ctx *ctx;
-};
-
-struct hazptr_slot_item {
- struct hazptr_slot slot;
- struct hazptr_slot_ctx ctx;
-};
-
-struct hazptr_percpu_slots {
- struct hazptr_slot_item items[NR_HAZPTR_PERCPU_SLOTS];
-} ____cacheline_aligned;
-
-DECLARE_PER_CPU(struct hazptr_percpu_slots, hazptr_percpu_slots);
-
-void *__hazptr_acquire(struct hazptr_ctx *ctx, void * const *addr_p);
-
-/**
- * hazptr_synchronize: Wait for release from hazard-pointer protection
- *
- * @addr: The address to be released from hazard-pointer protection
- *
- * Wait for the specified @addr to be released from protection from all
- * hazard pointers. The caller should make @addr inaccessible to all
- * hazard-pointer readers before invoking this function.
- *
- * Must be called from preemptible context.
- */
-void hazptr_synchronize(void *addr);
-
-/*
- * hazptr_chain_backup_slot: Chain backup slot into overflow list.
- *
- * Set backup slot address to @addr, and chain it into the overflow
- * list.
- */
-struct hazptr_slot *hazptr_chain_backup_slot(struct hazptr_ctx *ctx);
-
-/*
- * hazptr_unchain_backup_slot: Unchain backup slot from overflow list.
- */
-void hazptr_unchain_backup_slot(struct hazptr_ctx *ctx);
-
-static inline
-bool hazptr_slot_is_backup(struct hazptr_ctx *ctx, struct hazptr_slot *slot)
-{
- return slot == &ctx->backup_slot.slot;
-}
-
-/* Internal helper. */
-static inline
-void hazptr_promote_to_backup_slot(struct hazptr_ctx *ctx, struct hazptr_slot *slot)
-{
- struct hazptr_slot *backup_slot;
-
- backup_slot = hazptr_chain_backup_slot(ctx);
- /*
- * Move hazard pointer from the per-CPU slot to the
- * backup slot. This requires hazard pointer
- * synchronize to iterate on per-CPU slots with
- * load-acquire before iterating on the overflow list.
- */
- WRITE_ONCE(backup_slot->addr, slot->addr);
- /*
- * store-release orders store to backup slot addr before
- * store to per-CPU slot addr.
- */
- smp_store_release(&slot->addr, NULL);
- /* Use the backup slot for context. */
- ctx->slot = backup_slot;
-}
-
-/**
- * hazptr_detach - Allow a hazard pointer to be released in some other context
- *
- * @ctx: The hazard-pointer context to be detached.
- *
- * By default, a given hazptr_acquire() and the corresponding
- * hazptr_release() must run in a single execution context, for example,
- * the context of a single task or a single interrupt handler. When you
- * have acquired a hazard pointer in one context and need to release it
- * in another, you must invoke hazptr_detach() on that hazard pointer's
- * context. It is permissible to invoke hazptr_detach() multiple times
- * on the same @ctx while it is protecting the same pointer, however,
- * the first invocation absolutely must be in the same context that did
- * the hazptr_acquire(), and must take place after the return from that
- * hazptr_acquire().
- *
- * For example, if a hazard pointer is acquired by a task and released
- * by a timer handler, that task would need to pass the hazard pointer's
- * context to hazptr_detach() after return from the hazptr_acquire() and
- * before arming the timer (or at least before the handler had a chance
- * to access that hazard-pointer context).
- */
-static inline
-void hazptr_detach(struct hazptr_ctx *ctx)
-{
- struct hazptr_slot *slot;
-
- guard(preempt)();
- slot = ctx->slot;
- if (!slot->addr)
- return;
-#ifdef CONFIG_HAZPTR_DEBUG
- ctx->detach_task = ctx->detach_cpu = true;
-#endif
- if (unlikely(hazptr_slot_is_backup(ctx, slot)))
- return;
- hazptr_promote_to_backup_slot(ctx, slot);
-}
-
-static inline
-void hazptr_note_context_switch(void)
-{
- struct hazptr_percpu_slots *percpu_slots = this_cpu_ptr(&hazptr_percpu_slots);
- unsigned int idx;
-
- for (idx = 0; idx < NR_HAZPTR_PERCPU_SLOTS; idx++) {
- struct hazptr_slot_item *item = &percpu_slots->items[idx];
- struct hazptr_slot *slot = &item->slot;
-
- if (!slot->addr)
- continue;
-#ifdef CONFIG_HAZPTR_DEBUG
- item->ctx.ctx->detach_cpu = true;
-#endif
- hazptr_promote_to_backup_slot(item->ctx.ctx, slot);
- }
-}
-
-/**
- * hazptr_acquire - Load pointer at address and protect with hazard pointer.
- *
- * @ctx: The hazard-pointer context to be passed to hazptr_release().
- * @addr_p: Pointer to the pointer that is to be hazard-pointer protected.
- *
- * Load @addr_p, and protect the loaded pointer with hazard pointer.
- * This protection is roughly similar to (but way faster than) that of a
- * reference counter, and ends with a later call to hazptr_release().
- *
- * This protection is unconditional, and has limitations similar to
- * that of unconditional reference-counter acquisition. In particular,
- * although holding a hazard pointer prevents a hazard-pointer-protected
- * object from being freed, it does not prevent that object from being
- * removed from a linked data structure, and does not prevent other
- * hazard-pointer-protected objects referenced by this object from being
- * both removed and freed. At which point, invoking hazptr_acquire()
- * on these dangling pointers would be a bug. On the other hand, use of
- * hazptr_acquire() is safe for immortal pointers to objects that do not
- * themselves contain pointers to hazard-pointer-protected objects.
- * Other (more complex) use cases are also possible.
- *
- * By default, the call to hazptr_release() must be running in the same
- * execution context as the corresponding hazptr_acquire(), for example,
- * within the same task or interrupt handler. When it is necessary to
- * instead call hazptr_release() from some other context, pass @ctx to
- * hazptr_detach() in the original context after invoking hazptr_acquire()
- * but before making the hazard pointer available to that other context.
- *
- * It is not permissible to invoke hazptr_acquire() twice on the same @ctx
- * without an intervening hazptr_release().
- *
- * Returns a non-NULL protected address if the loaded pointer is non-NULL.
- * Returns NULL if the loaded pointer is NULL.
- *
- * On success the protected hazptr slot is stored in @ctx->slot.
- */
-static inline
-void *hazptr_acquire(struct hazptr_ctx *ctx, void * const *addr_p)
-{
- struct hazptr_percpu_slots *percpu_slots;
- struct hazptr_slot_item *slot_item;
- struct hazptr_slot *slot;
- void *addr;
-
- guard(preempt)();
- percpu_slots = this_cpu_ptr(&hazptr_percpu_slots);
- slot_item = &percpu_slots->items[0];
- slot = &slot_item->slot;
-#ifdef CONFIG_HAZPTR_DEBUG
- ctx->detach_cpu = ctx->detach_task = false;
- ctx->acquire_pid = current->pid;
- ctx->acquire_cpu = smp_processor_id();
- ctx->acquire_caller = _THIS_IP_;
-#endif
- if (unlikely(slot->addr))
- return __hazptr_acquire(ctx, addr_p);
- WRITE_ONCE(slot->addr, READ_ONCE(hazptr_wildcard)); /* Store B */
-
- /* Memory ordering: Store B before Load A. */
- smp_mb();
-
- /*
- * Load @addr_p after storing wildcard to the hazard pointer slot.
- */
- addr = READ_ONCE(*addr_p); /* Load A */
-
- /*
- * We don't care about ordering of Store C. It will simply
- * replace the wildcard by a more specific address. If addr is
- * NULL, we simply store NULL into the slot.
- */
- WRITE_ONCE(slot->addr, addr); /* Store C */
- slot_item->ctx.ctx = ctx;
- ctx->slot = slot;
- return addr;
-}
-
-#ifdef CONFIG_HAZPTR_DEBUG
-/* Called with preemption disabled. */
-static inline
-void hazptr_release_debug(struct hazptr_ctx *ctx, void *addr)
-{
- int pid = current->pid, cpu = smp_processor_id();
- bool warn_remote_cpu = !ctx->detach_cpu && ctx->acquire_cpu != cpu,
- warn_remote_task = !ctx->detach_task && ctx->acquire_pid != pid;
-
- WARN_ONCE(warn_remote_cpu || warn_remote_task,
- "Hazard Pointer (addr=%p) released on remote %s without %s. Acquire: caller=%pS, pid=%d, cpu=%d. Release: pid=%d, cpu=%d.",
- addr,
- warn_remote_task ? "task" : "cpu",
- warn_remote_task ? "being detached from task" : "context switch",
- (void *) ctx->acquire_caller, ctx->acquire_pid, ctx->acquire_cpu, pid, cpu);
-}
-#else
-static inline void hazptr_release_debug(struct hazptr_ctx *ctx, void *addr) { }
-#endif
-
-/**
- * hazptr_release - Release the specified hazard pointer
- *
- * @ctx: The hazard-pointer context that was passed to hazptr_acquire().
- * @addr_p: The pointer that is to be hazard-pointer unprotected.
- *
- * Release the protected hazard pointer recorded in @ctx.
- *
- * By default, hazptr_release() must execute in the same execution context
- * that invoked the corresponding hazptr_acquire(), for example, within the
- * same task or the same interrupt handler. However, if this restriction
- * is problematic for your use case, please see hazptr_detach().
- *
- * It is permissible (though unwise from a maintainability viewpoint)
- * to invoke hazptr_release() twice on the same @ctx without an intervening
- * hazptr_acquire().
- */
-static inline
-void hazptr_release(struct hazptr_ctx *ctx, void *addr)
-{
- struct hazptr_slot *slot;
-
- if (!addr)
- return;
- guard(preempt)();
- hazptr_release_debug(ctx, addr);
- slot = ctx->slot;
- smp_store_release(&slot->addr, NULL);
- if (unlikely(hazptr_slot_is_backup(ctx, slot)))
- hazptr_unchain_backup_slot(ctx);
-}
-
-void hazptr_init(void);
-
-#endif /* _LINUX_HAZPTR_H */
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 8ca0fa3be2ac..c745f7ad2298 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -510,6 +510,8 @@ change_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma,
int hugepage_madvise(struct vm_area_struct *vma, vm_flags_t *vm_flags,
int advice);
+int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end, bool *lock_dropped);
void vma_adjust_trans_huge(struct vm_area_struct *vma, unsigned long start,
unsigned long end, struct vm_area_struct *next);
spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma);
@@ -713,6 +715,13 @@ static inline int hugepage_madvise(struct vm_area_struct *vma,
return -EINVAL;
}
+static inline int madvise_collapse(struct vm_area_struct *vma,
+ unsigned long start,
+ unsigned long end, bool *lock_dropped)
+{
+ return -EINVAL;
+}
+
static inline void vma_adjust_trans_huge(struct vm_area_struct *vma,
unsigned long start,
unsigned long end,
diff --git a/include/linux/interrupt_rc.h b/include/linux/interrupt_rc.h
index a9ed937a80e7..d385ab05a2b6 100644
--- a/include/linux/interrupt_rc.h
+++ b/include/linux/interrupt_rc.h
@@ -11,6 +11,7 @@
* make it easier to include without hitting circular header dependencies.
*/
+#include <linux/debug_locks.h>
#include <linux/irqflags.h>
#include <linux/preempt.h>
#include <linux/processor.h>
@@ -65,6 +66,13 @@ static inline void local_interrupt_disable(void)
local_irq_save(flags);
new_count = hardirq_disable_enter();
+ /* Is hardirq disable count overflow soon? */
+ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT) &&
+ DEBUG_LOCKS_WARN_ON(((new_count & HARDIRQ_DISABLE_MASK) +
+ (10 << HARDIRQ_DISABLE_SHIFT)) >=
+ HARDIRQ_DISABLE_MASK))
+ return;
+
if ((new_count & HARDIRQ_DISABLE_MASK) == HARDIRQ_DISABLE_OFFSET)
_local_interrupt_save_state(flags);
}
@@ -73,6 +81,11 @@ static inline void local_interrupt_enable(void)
{
int new_count;
+ /* Unpaired local_interrupt_enable()? Warn and abort. */
+ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT) &&
+ DEBUG_LOCKS_WARN_ON((preempt_count() & HARDIRQ_DISABLE_MASK) == 0))
+ return;
+
new_count = hardirq_disable_exit();
if ((new_count & HARDIRQ_DISABLE_MASK) == 0)
diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h
index 53941c6a6875..50970b382a9a 100644
--- a/include/linux/io_uring_types.h
+++ b/include/linux/io_uring_types.h
@@ -11,6 +11,7 @@
struct iou_loop_params;
struct io_uring_bpf_ops;
+struct dma_buf_io_map;
enum {
/*
@@ -612,6 +613,7 @@ enum {
REQ_F_IMPORT_BUFFER_BIT,
REQ_F_SQE_COPIED_BIT,
REQ_F_IOPOLL_BIT,
+ REQ_F_DMABUF_BIT,
/* not a real bit, just to check we're not overflowing the space */
__REQ_F_LAST_BIT,
@@ -707,6 +709,8 @@ enum {
REQ_F_SQE_COPIED = IO_REQ_FLAG(REQ_F_SQE_COPIED_BIT),
/* request must be iopolled to completion (set in ->issue()) */
REQ_F_IOPOLL = IO_REQ_FLAG(REQ_F_IOPOLL_BIT),
+ /* there is a dma map attached to request that needs to be dropped */
+ REQ_F_DMABUF = IO_REQ_FLAG(REQ_F_DMABUF_BIT),
};
struct io_tw_req {
@@ -829,6 +833,7 @@ struct io_kiocb {
/* custom credentials, valid IFF REQ_F_CREDS is set */
const struct cred *creds;
struct io_wq_work work;
+ struct dma_buf_io_map *dmabuf_map;
struct io_big_cqe {
u64 extra1;
diff --git a/include/linux/iov_iter.h b/include/linux/iov_iter.h
index 39ffd5878f50..e88930af7f36 100644
--- a/include/linux/iov_iter.h
+++ b/include/linux/iov_iter.h
@@ -319,6 +319,8 @@ size_t iterate_and_advance2(struct iov_iter *iter, size_t len, void *priv,
return iterate_bvecq(iter, len, priv, priv2, step);
if (iov_iter_is_xarray(iter))
return iterate_xarray(iter, len, priv, priv2, step);
+ if (WARN_ON_ONCE(iov_iter_is_dmabuf_map(iter)))
+ return 0;
return iterate_discard(iter, len, priv, priv2, step);
}
diff --git a/include/linux/irq-entry-common.h b/include/linux/irq-entry-common.h
index 2be273bb68f0..d5a66f54d70b 100644
--- a/include/linux/irq-entry-common.h
+++ b/include/linux/irq-entry-common.h
@@ -453,6 +453,25 @@ static inline void irqentry_exit_to_kernel_mode_preempt(struct pt_regs *regs,
irqentry_exit_cond_resched();
}
+/*
+ * The deferred hrtimer rearm is the tail of the timer interrupt, moved to the
+ * interrupt return path so that it runs after a possible reschedule. By now
+ * irq_exit_rcu() has left lockdep's hardirq context. Re-enter it for the
+ * rearm, so that the hrtimer base lock and the timekeeping sequence count are
+ * not chained onto the locks held by the interrupted context, which would add
+ * new lock chains for every lock stack an interrupt hits.
+ *
+ * The rearm on return to user mode needs no such annotation: no locks are
+ * held there, so it uses the same lock chains as the rearm in hardirq
+ * context.
+ */
+static __always_inline void irqentry_hrtimer_rearm_deferred(void)
+{
+ lockdep_hardirq_enter();
+ hrtimer_rearm_deferred();
+ lockdep_hardirq_exit();
+}
+
/**
* irqentry_exit_to_kernel_mode_after_preempt - Establish trace, lockdep and RCU state
* @regs: Pointer to current's pt_regs
@@ -476,7 +495,7 @@ irqentry_exit_to_kernel_mode_after_preempt(struct pt_regs *regs, irqentry_state_
*/
if (state.exit_rcu) {
instrumentation_begin();
- hrtimer_rearm_deferred();
+ irqentry_hrtimer_rearm_deferred();
/* Tell the tracer that IRET will enable interrupts */
trace_hardirqs_on_prepare();
lockdep_hardirqs_on_prepare();
@@ -487,7 +506,7 @@ irqentry_exit_to_kernel_mode_after_preempt(struct pt_regs *regs, irqentry_state_
}
instrumentation_begin();
- hrtimer_rearm_deferred();
+ irqentry_hrtimer_rearm_deferred();
/* Covers both tracing and lockdep */
trace_hardirqs_on();
instrumentation_end();
diff --git a/include/linux/key.h b/include/linux/key.h
index bd10fe45819d..dd386c56278c 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -441,6 +441,8 @@ extern int keyring_restrict(key_ref_t keyring, const char *type,
const char *restriction);
extern void key_register_bpf_keyring(struct key *keyring);
+extern void key_register_dm_verity_keyring(struct key *keyring);
+extern void key_register_fs_verity_keyring(struct key *keyring);
extern struct key *key_lookup(key_serial_t id);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index f6e6a6c7b18c..4d4e76a50d77 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -45,6 +45,10 @@
#include <asm/kvm_host.h>
#include <linux/kvm_dirty_ring.h>
+#define __KVM_DEV_STRING(name, x) __stringify(name ## _ ## x)
+#define _KVM_DEV_STRING(name, x) __KVM_DEV_STRING(name, x)
+#define KVM_DEV_STRING(x) _KVM_DEV_STRING(KVM_DEV_NAME, x)
+
#ifndef KVM_MAX_VCPU_IDS
#define KVM_MAX_VCPU_IDS KVM_MAX_VCPUS
#endif
@@ -725,7 +729,11 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm_vcpu *vcpu)
#ifndef kvm_arch_has_readonly_mem
static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm)
{
- return IS_ENABLED(CONFIG_HAVE_KVM_READONLY_MEM);
+#ifdef __KVM_HAVE_READONLY_MEM
+ return true;
+#else
+ return false;
+#endif
}
#endif
@@ -817,7 +825,7 @@ struct kvm {
struct kvm_vm_stat stat;
struct kvm_arch arch;
refcount_t users_count;
-#ifdef CONFIG_KVM_MMIO
+#ifndef __KVM_NO_MMIO
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
spinlock_t ring_lock;
struct list_head coalesced_zones;
@@ -2462,7 +2470,7 @@ void kvm_arch_update_irqfd_routing(struct kvm_kernel_irqfd *irqfd,
struct kvm_kernel_irq_routing_entry *new);
#endif /* CONFIG_HAVE_KVM_IRQ_BYPASS */
-#ifdef CONFIG_HAVE_KVM_INVALID_WAKEUPS
+#ifdef __KVM_HAVE_INVALID_WAKEUPS
/* If we wakeup during the poll time, was it a sucessful poll? */
static inline bool vcpu_valid_wakeup(struct kvm_vcpu *vcpu)
{
@@ -2474,9 +2482,9 @@ static inline bool vcpu_valid_wakeup(struct kvm_vcpu *vcpu)
{
return true;
}
-#endif /* CONFIG_HAVE_KVM_INVALID_WAKEUPS */
+#endif /* __KVM_HAVE_INVALID_WAKEUPS */
-#ifdef CONFIG_HAVE_KVM_NO_POLL
+#ifdef __KVM_HAVE_NO_POLL
/* Callback that tells if we must not poll */
bool kvm_arch_no_poll(struct kvm_vcpu *vcpu);
#else
@@ -2484,18 +2492,18 @@ static inline bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
{
return false;
}
-#endif /* CONFIG_HAVE_KVM_NO_POLL */
+#endif /* __KVM_HAVE_NO_POLL */
void kvm_arch_guest_memory_reclaimed(struct kvm *kvm);
-#ifdef CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE
+#ifdef __KVM_HAVE_VCPU_RUN_PID_CHANGE
int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu);
#else
static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
{
return 0;
}
-#endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */
+#endif /* __KVM_HAVE_VCPU_RUN_PID_CHANGE */
#ifdef CONFIG_VIRT_XFER_TO_GUEST_WORK
static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu)
diff --git a/include/linux/landlock.h b/include/linux/landlock.h
index 004cbd0b9298..0ee4880988ba 100644
--- a/include/linux/landlock.h
+++ b/include/linux/landlock.h
@@ -13,14 +13,16 @@
#include <uapi/linux/landlock.h>
/*
- * Access-right and scope names, shared between the audit records (get_blocker()
- * in security/landlock/audit.c) and the trace events
+ * Access-right, scope, and permission names, shared between the audit records
+ * (get_blocker() in security/landlock/audit.c) and the trace events
* (include/trace/events/landlock.h). A consumer defines
* _LANDLOCK_NAME_ENTRY(mask, name) before expanding a list and undefines it
* afterwards: audit maps each entry to a "[bit] = name" slot for O(1) lookup,
* the trace events map it to a __print_flags() { mask, name } pair. The bit
* value lives only in the LANDLOCK_* UAPI constant each entry references.
- * Names are unprefixed; audit prepends the "fs."/"net."/"scope." category.
+ * Access-right and scope names are unprefixed; audit prepends the
+ * "fs."/"net."/"scope." category. Permission entries carry an action and a
+ * domain for the qualified and bare views below.
*/
#define _LANDLOCK_ACCESS_FS_NAMES \
_LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_EXECUTE, "execute"), \
@@ -53,4 +55,25 @@
"abstract_unix_socket"), \
_LANDLOCK_NAME_ENTRY(LANDLOCK_SCOPE_SIGNAL, "signal")
+#define _LANDLOCK_PERMISSION_NAMESPACE_NAME "namespace"
+#define _LANDLOCK_PERMISSION_CAPABILITY_NAME "capability"
+
+#define _LANDLOCK_PERMISSION_LIST(entry) \
+ entry(LANDLOCK_PERMISSION_NAMESPACE_USE, "use", \
+ _LANDLOCK_PERMISSION_NAMESPACE_NAME), \
+ entry(LANDLOCK_PERMISSION_CAPABILITY_USE, "use", \
+ _LANDLOCK_PERMISSION_CAPABILITY_NAME)
+
+#define _LANDLOCK_PERMISSION_QUALIFIED_ENTRY(mask, action, domain) \
+ _LANDLOCK_NAME_ENTRY(mask, domain "." action)
+
+#define _LANDLOCK_PERMISSION_BARE_ENTRY(mask, action, ...) \
+ _LANDLOCK_NAME_ENTRY(mask, action)
+
+#define _LANDLOCK_PERMISSION_NAMES \
+ _LANDLOCK_PERMISSION_LIST(_LANDLOCK_PERMISSION_QUALIFIED_ENTRY)
+
+#define _LANDLOCK_PERMISSION_BLOCKER_NAMES \
+ _LANDLOCK_PERMISSION_LIST(_LANDLOCK_PERMISSION_BARE_ENTRY)
+
#endif /* _LINUX_LANDLOCK_H */
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index ea288cf21400..40e6e0aa2f8d 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -412,9 +412,6 @@ static __always_inline phys_addr_t memblock_phys_alloc(phys_addr_t size,
MEMBLOCK_ALLOC_ACCESSIBLE);
}
-void *memblock_alloc_exact_nid_raw(phys_addr_t size, phys_addr_t align,
- phys_addr_t min_addr, phys_addr_t max_addr,
- int nid);
void *memblock_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align,
phys_addr_t min_addr, phys_addr_t max_addr,
int nid);
diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h
index f6383a57a872..852f331f03fd 100644
--- a/include/linux/mhi_ep.h
+++ b/include/linux/mhi_ep.h
@@ -304,4 +304,20 @@ bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_directio
*/
int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb);
+/**
+ * mhi_ep_queue_buf - Transfer buffer contents to host over MHI Endpoint
+ * @mhi_dev: Device associated with the DL channel
+ * @buf: Buffer to be queued. On success, ownership passes to the MHI stack;
+ * the caller must not free @buf until the DL transfer callback fires
+ * with result->buf_addr equal to @buf. On failure, the caller retains
+ * ownership and must free @buf.
+ * Note: if @len spans multiple host DL TREs, the DL transfer callback
+ * fires once per TRE, each time with result->buf_addr equal to @buf.
+ * @len: Size of the buffer
+ *
+ * Return: 0 if the buffer contents have been transferred successfully, a
+ * negative error code otherwise.
+ */
+int mhi_ep_queue_buf(struct mhi_ep_device *mhi_dev, void *buf, size_t len);
+
#endif
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 8247cb0f8dfd..697fc9387b73 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -929,7 +929,7 @@ struct mlx5_ifc_flow_table_nic_cap_bits {
struct mlx5_ifc_port_selection_cap_bits {
u8 reserved_at_0[0x10];
u8 port_select_flow_table[0x1];
- u8 reserved_at_11[0x1];
+ u8 port_select_eswitch[0x1];
u8 port_select_flow_table_bypass[0x1];
u8 reserved_at_13[0xd];
@@ -1070,7 +1070,9 @@ struct mlx5_ifc_e_switch_cap_bits {
u8 root_ft_on_other_esw[0x1];
u8 reserved_at_a[0x1];
u8 esw_vport_state_max_tx_speed[0x1];
- u8 reserved_at_c[0xd];
+ u8 esw_vport_state_cap_tx_speed[0x1];
+ u8 esw_vport_state_effective_tx_speed[0x1];
+ u8 reserved_at_e[0xb];
u8 esw_functions_changed[0x1];
u8 reserved_at_1a[0x1];
u8 ecpf_vport_exists[0x1];
@@ -2008,7 +2010,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 reserved_at_3b0[0x2];
u8 qp_latency_sensitive_disable[0x1];
u8 log_max_stride_sz_sq[0x5];
- u8 reserved_at_3b8[0x3];
+ u8 reserved_at_3b8[0x1];
+ u8 multi_uplink_eswitch[0x1];
+ u8 reserved_at_3ba[0x1];
u8 log_min_stride_sz_sq[0x5];
u8 hairpin[0x1];
@@ -5492,6 +5496,9 @@ struct mlx5_ifc_query_vport_state_out_bits {
u8 reserved_at_70[0x8];
u8 admin_state[0x4];
u8 state[0x4];
+
+ u8 cap_tx_speed[0x10];
+ u8 effective_tx_speed[0x10];
};
struct mlx5_ifc_array1024_auto_bits {
@@ -7948,6 +7955,9 @@ struct mlx5_ifc_modify_vport_state_in_bits {
u8 reserved_at_74[0x4];
u8 admin_state[0x4];
u8 reserved_at_7c[0x4];
+
+ u8 cap_tx_speed[0x10];
+ u8 effective_tx_speed[0x10];
};
struct mlx5_ifc_modify_tis_out_bits {
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 26979c5f8f2e..ba755a438fa0 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1695,57 +1695,22 @@ static inline bool vma_is_fixed_mapping(const struct vm_area_struct *vma)
}
/**
- * vma_flags_can_merge() - Do the specified VMA flags permit the VMA to be
- * merged with another?
- * @flags: The VMA flags to test.
- * Returns: true if the flags permit merging, false otherwise.
- */
-static inline bool vma_flags_can_merge(const vma_flags_t *flags)
-{
- /*
- * VMA merging assumes that a VMA's flags and fields completely describe
- * its state.
- *
- * However, mappings which are not mm-managed may have established state
- * upon mapping not embodied in any attribute of the VMA.
- *
- * Additionally, private (CoW) PFN maps encode the source PFN of the
- * range in vma->vm_pgoff, which may otherwise cause spurious merges.
- */
- if (!vma_flags_is_mm_managed(flags))
- return false;
- /* VMA explicitly marked as being unmergeable. */
- if (vma_flags_is_fixed_mapping(flags))
- return false;
-
- return true;
-}
-
-/**
- * vma_can_merge() - Do @vma's flags permit it to be merged with another VMA?
- * @vma: The VMA to test.
- * Returns: true if the flags permit merging, otherwise false.
- */
-static inline bool vma_can_merge(const struct vm_area_struct *vma)
-{
- return vma_flags_can_merge(&vma->flags);
-}
-
-/**
* vma_flags_is_mm_backed() - Do the specified VMA flags imply the mapping is
* backed by core mm?
* @flags: The VMA flags to test.
*
* An mm-backed mapping is one managed by core mm (see
- * vma_flags_is_mm_managed()) for which two further things are true:
+ * vma_flags_is_mm_managed()) whose contents are established by core mm's own
+ * fault path rather than a custom ->fault handler.
*
- * 1. Everything mapped was placed there by core mm's fault path (no custom
- * ->fault).
- * 2. What is mapped stays there until it is zapped or unmapped by the user.
+ * Mappings not managed by core mm are populated by their owner, and fixed
+ * mappings may be mm-managed but have their contents established by a custom
+ * ->fault handler, so neither are mm-backed. hugetlb mappings are fixed, but
+ * core mm owns them entirely, so they are.
*
- * These mappings are the only ones which can be sensibly locked, merged, dumped
- * or be subject to uffd faulting, as all of these assume core mm and core mm
- * alone manages these, and that the mappings will remain there.
+ * These are the only mappings which can sensibly be merged, locked, dumped or
+ * be subject to uffd faulting, as all of these assume core mm and core mm
+ * alone manages their contents.
*
* Returns: true if the flags imply an mm-backed mapping, otherwise false.
*/
@@ -1761,11 +1726,7 @@ static inline bool vma_flags_is_mm_backed(const vma_flags_t *flags)
* by a custom ->fault handler, so core mm cannot assume ordinary fault
* semantics over them.
*/
- if (!vma_flags_is_mm_managed(flags) ||
- vma_flags_is_fixed_mapping(flags))
- return false;
- /* Core mm may discard droppable memory at any time. */
- return !vma_flags_test_single_mask(flags, VMA_DROPPABLE);
+ return vma_flags_is_mm_managed(flags) && !vma_flags_is_fixed_mapping(flags);
}
/**
@@ -1782,6 +1743,43 @@ static inline bool vma_is_mm_backed(const struct vm_area_struct *vma)
}
/**
+ * vma_flags_can_merge() - Do the specified VMA flags permit the VMA to be
+ * merged with another?
+ * @flags: The VMA flags to test.
+ * Returns: true if the flags permit merging, false otherwise.
+ */
+static inline bool vma_flags_can_merge(const vma_flags_t *flags)
+{
+ /*
+ * VMA merging assumes that a VMA's flags and fields completely describe
+ * its state, which is only the case for mm-backed mappings.
+ *
+ * Mappings which are not mm-managed may have established state upon
+ * mapping not embodied in any attribute of the VMA.
+ *
+ * Additionally, private (CoW) PFN maps encode the source PFN of the
+ * range in vma->vm_pgoff, which may otherwise cause spurious merges.
+ */
+ if (!vma_flags_is_mm_backed(flags))
+ return false;
+ /*
+ * hugetlb mappings contain per-VMA state, so their flags and fields do
+ * not completely describe them.
+ */
+ return !vma_flags_is_hugetlb(flags);
+}
+
+/**
+ * vma_can_merge() - Do @vma's flags permit it to be merged with another VMA?
+ * @vma: The VMA to test.
+ * Returns: true if the flags permit merging, otherwise false.
+ */
+static inline bool vma_can_merge(const struct vm_area_struct *vma)
+{
+ return vma_flags_can_merge(&vma->flags);
+}
+
+/**
* vma_kernel_pagesize - Default page size granularity for this VMA.
* @vma: The user mapping.
*
@@ -3969,23 +3967,6 @@ static inline void pagetable_free_kernel(struct ptdesc *pt)
__pagetable_free(pt);
}
#endif
-/**
- * pagetable_free - Free pagetables
- * @pt: The page table descriptor
- *
- * pagetable_free frees the memory of all page tables described by a page
- * table descriptor and the memory for the descriptor itself.
- */
-static inline void pagetable_free(struct ptdesc *pt)
-{
- if (ptdesc_test_kernel(pt)) {
- ptdesc_clear_kernel(pt);
- pagetable_free_kernel(pt);
- } else {
- __pagetable_free(pt);
- }
-}
-
#if defined(CONFIG_SPLIT_PTE_PTLOCKS)
#if ALLOC_SPLIT_PTLOCKS
void __init ptlock_cache_init(void);
@@ -4078,6 +4059,26 @@ static inline void pagetable_dtor(struct ptdesc *ptdesc)
lruvec_stat_sub_folio(folio, NR_PAGETABLE);
}
+/**
+ * pagetable_free - Free pagetables
+ * @pt: The page table descriptor
+ *
+ * pagetable_free frees the memory of all page tables described by a page
+ * table descriptor and the memory for the descriptor itself.
+ */
+static inline void pagetable_free(struct ptdesc *pt)
+{
+ if (PageTable(ptdesc_page(pt)))
+ pagetable_dtor(pt);
+
+ if (ptdesc_test_kernel(pt)) {
+ ptdesc_clear_kernel(pt);
+ pagetable_free_kernel(pt);
+ } else {
+ __pagetable_free(pt);
+ }
+}
+
static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
{
pagetable_dtor(ptdesc);
@@ -4834,28 +4835,26 @@ discontig_kernel_map_abort(struct discontig_kernel_page_state *state)
static inline void
discontig_kernel_map_page(struct discontig_kernel_page_state *state,
- struct page *page)
+ struct page *page)
{
struct folio *folio = page_folio(page);
+ unsigned long nr_pages = 1;
if (folio_test_large(folio)) {
VM_WARN_ON_ONCE(page != folio_page(folio, 0));
- state->action = DISCONTIG_KERNEL_PAGE_MAP_COMPOUND_PAGE;
- state->__folio = folio;
- state->__nr_pages = min(state->nr_pages_remain,
- folio_nr_pages(folio));
- } else {
- state->action = DISCONTIG_KERNEL_PAGE_MAP_PAGE;
- state->__page = page;
- state->__nr_pages = 1;
+ nr_pages = folio_nr_pages(folio);
}
+
+ state->action = DISCONTIG_KERNEL_PAGE_MAP_CONTIG_PAGES;
+ state->__page = page;
+ state->__nr_pages = min(nr_pages, state->nr_pages_remain);
}
static inline void
-discontig_kernel_map_page_range(struct discontig_kernel_page_state *state,
- struct page **page_arr, unsigned long nr_pages)
+discontig_kernel_map_pages(struct discontig_kernel_page_state *state,
+ struct page **page_arr, unsigned long nr_pages)
{
- state->action = DISCONTIG_KERNEL_PAGE_MAP_PAGE_RANGE;
+ state->action = DISCONTIG_KERNEL_PAGE_MAP_PAGES;
state->__page_arr = page_arr;
state->__nr_pages = min(nr_pages, state->nr_pages_remain);
}
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 6141160ec652..0dead656d3e3 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -825,9 +825,8 @@ enum mmap_action_type {
enum discontig_kernel_page_action {
DISCONTIG_KERNEL_PAGE_ABORT,
- DISCONTIG_KERNEL_PAGE_MAP_PAGE,
- DISCONTIG_KERNEL_PAGE_MAP_COMPOUND_PAGE,
- DISCONTIG_KERNEL_PAGE_MAP_PAGE_RANGE,
+ DISCONTIG_KERNEL_PAGE_MAP_PAGES, /* Array of individual pages. */
+ DISCONTIG_KERNEL_PAGE_MAP_CONTIG_PAGES, /* 1..N contiguous pages. */
};
struct discontig_kernel_page_state {
@@ -847,7 +846,6 @@ struct discontig_kernel_page_state {
enum discontig_kernel_page_action action;
union {
struct page *__page;
- struct folio *__folio;
struct page **__page_arr;
};
unsigned long __nr_pages;
diff --git a/include/linux/module.h b/include/linux/module.h
index 2c5a02621c19..76f4f3596477 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -503,6 +503,10 @@ struct module {
void *btf_data;
void *btf_base_data;
#endif
+#if IS_ENABLED(CONFIG_DEBUG_INFO_BTF_INLINE)
+ unsigned int btf_inline_data_size;
+ void *btf_inline_data;
+#endif
#ifdef CONFIG_JUMP_LABEL
struct jump_entry *jump_entries;
unsigned int num_jump_entries;
diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h
index 0f40964eefe7..f31fd18d837f 100644
--- a/include/linux/mtd/nand-qpic-common.h
+++ b/include/linux/mtd/nand-qpic-common.h
@@ -457,6 +457,12 @@ struct qcom_nandc_props {
bool use_codeword_fixup;
};
+struct qcom_nandc_read_stats {
+ __le32 flash;
+ __le32 buffer;
+ __le32 erased_cw;
+};
+
void qcom_free_bam_transaction(struct qcom_nand_controller *nandc);
struct bam_transaction *qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc);
void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc);
@@ -482,5 +488,16 @@ int qcom_submit_descs(struct qcom_nand_controller *nandc);
void qcom_clear_read_regs(struct qcom_nand_controller *nandc);
void qcom_nandc_unalloc(struct qcom_nand_controller *nandc);
int qcom_nandc_alloc(struct qcom_nand_controller *nandc);
+int qcom_nandc_check_flash_errors(struct qcom_nand_controller *nandc,
+ int cw_cnt);
+void qcom_nandc_config_page_read(struct qcom_nand_controller *nandc);
+void qcom_nandc_config_page_write(struct qcom_nand_controller *nandc);
+void qcom_nandc_config_cw_write(struct qcom_nand_controller *nandc);
+void qcom_nandc_set_read_loc_first(struct qcom_nand_controller *nandc,
+ int reg_base, u32 cw_offset,
+ u32 read_size, u32 is_last_read_loc);
+void qcom_nandc_set_read_loc_last(struct qcom_nand_controller *nandc,
+ int reg_base, u32 cw_offset,
+ u32 read_size, u32 is_last_read_loc);
#endif
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5b4b92e76b67..8fbe3a5d8169 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -5500,7 +5500,14 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
netdev_features_t passthru_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features);
-netdev_features_t netif_skb_features(struct sk_buff *skb);
+netdev_features_t __netif_skb_features(struct sk_buff *skb,
+ bool check_gso_limits);
+
+static inline netdev_features_t netif_skb_features(struct sk_buff *skb)
+{
+ return __netif_skb_features(skb, true);
+}
+
void skb_warn_bad_offload(const struct sk_buff *skb);
static inline bool net_gso_ok(netdev_features_t features, int gso_type)
@@ -5566,15 +5573,6 @@ netif_get_gro_max_size(const struct net_device *dev, const struct sk_buff *skb)
READ_ONCE(dev->gro_ipv4_max_size);
}
-static inline unsigned int
-netif_get_gso_max_size(const struct net_device *dev, const struct sk_buff *skb)
-{
- /* pairs with WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
- return skb->protocol == htons(ETH_P_IPV6) ?
- READ_ONCE(dev->gso_max_size) :
- READ_ONCE(dev->gso_ipv4_max_size);
-}
-
static inline bool netif_is_macsec(const struct net_device *dev)
{
return dev->priv_flags & IFF_MACSEC;
diff --git a/include/linux/nfs_common.h b/include/linux/nfs_common.h
index a541c3a02887..88dccd8564cf 100644
--- a/include/linux/nfs_common.h
+++ b/include/linux/nfs_common.h
@@ -6,11 +6,11 @@
#define _LINUX_NFS_COMMON_H
#include <linux/errno.h>
-#include <uapi/linux/nfs.h>
+#include <linux/types.h>
/* Mapping from NFS error code to "errno" error code. */
-int nfs_stat_to_errno(enum nfs_stat status);
+int nfs_stat_to_errno(int status);
int nfs4_stat_to_errno(int stat);
__u32 nfs_localio_errno_to_nfs4_stat(int errno);
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index a8cb6319b4fb..d0f04436343e 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -418,7 +418,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
#define flex_array_size(p, member, count) \
__builtin_choose_expr(__is_constexpr(count), \
(count) * sizeof(*(p)->member) + __must_be_array((p)->member), \
- size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member)))
+ size_mul(count, sizeof(*(p)->member)) + __must_be_array((p)->member))
/**
* struct_size() - Calculate size of structure with trailing flexible array.
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d1dad3a3b1d0..6482549a8417 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -468,6 +468,7 @@ struct pci_dev {
unsigned int is_busmaster:1; /* Is busmaster */
unsigned int no_msi:1; /* May not use MSI */
+ unsigned int no_aer_anfe:1; /* Do not unmask ANFE */
unsigned int block_cfg_access:1; /* Config space access blocked */
unsigned int broken_parity_status:1; /* Generates false positive parity */
unsigned int irq_reroute_variant:2; /* Needs IRQ rerouting variant */
@@ -615,7 +616,10 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
struct pci_dev *pci_alloc_dev(struct pci_bus *bus);
-#define to_pci_dev(n) container_of(n, struct pci_dev, dev)
+static inline struct pci_dev *to_pci_dev(const struct device *dev)
+{
+ return container_of(dev, struct pci_dev, dev);
+}
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
#define for_each_pci_dev_reverse(d) \
while ((d = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
@@ -1484,7 +1488,7 @@ int pcie_set_mps(struct pci_dev *dev, int mps);
u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
enum pci_bus_speed *speed,
enum pcie_link_width *width);
-int pcie_link_speed_mbps(struct pci_dev *pdev);
+int pcie_link_bandwidth_mbps(struct pci_dev *pdev);
void pcie_print_link_status(struct pci_dev *dev);
int pcie_reset_flr(struct pci_dev *dev, bool probe);
int pcie_flr(struct pci_dev *dev);
@@ -1960,10 +1964,9 @@ int pci_disable_link_state(struct pci_dev *pdev, int state);
int pci_disable_link_state_locked(struct pci_dev *pdev, int state);
int pci_enable_link_state(struct pci_dev *pdev, int state);
int pci_enable_link_state_locked(struct pci_dev *pdev, int state);
-int pci_force_enable_link_state(struct pci_dev *pdev, int state);
void pcie_no_aspm(void);
bool pcie_aspm_support_enabled(void);
-u32 pcie_aspm_enabled(struct pci_dev *pdev);
+bool pcie_aspm_enabled(struct pci_dev *pdev);
#else
static inline int pci_disable_link_state(struct pci_dev *pdev, int state)
{ return 0; }
@@ -1973,11 +1976,9 @@ static inline int pci_enable_link_state(struct pci_dev *pdev, int state)
{ return 0; }
static inline int pci_enable_link_state_locked(struct pci_dev *pdev, int state)
{ return 0; }
-static inline int pci_force_enable_link_state(struct pci_dev *pdev, int state)
-{ return 0; }
static inline void pcie_no_aspm(void) { }
static inline bool pcie_aspm_support_enabled(void) { return false; }
-static inline u32 pcie_aspm_enabled(struct pci_dev *pdev) { return 0; }
+static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; }
#endif
#ifdef CONFIG_HOTPLUG_PCI
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 0693e4532a68..030c86dd6d67 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -889,6 +889,7 @@
#define PCI_DEVICE_ID_TI_XX12 0x8039
#define PCI_DEVICE_ID_TI_XX12_FM 0x803b
#define PCI_DEVICE_ID_TI_XIO2000A 0x8231
+#define PCI_DEVICE_ID_TI_TUSB73X0 0x8241
#define PCI_DEVICE_ID_TI_1130 0xac12
#define PCI_DEVICE_ID_TI_1031 0xac13
#define PCI_DEVICE_ID_TI_1131 0xac15
diff --git a/include/linux/pid.h b/include/linux/pid.h
index ddaef0bbc8ba..185bf0cde2d1 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -2,6 +2,9 @@
#ifndef _LINUX_PID_H
#define _LINUX_PID_H
+#include <linux/array_size.h>
+#include <linux/build_bug.h>
+#include <linux/minmax.h>
#include <linux/pid_types.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
@@ -92,6 +95,56 @@ static inline struct pid *get_pid(struct pid *pid)
}
extern void put_pid(struct pid *pid);
+
+/*
+ * Helpers for arrays of struct pid indexed by pid type declared with
+ * DECLARE_PIDS(). The array covers PIDTYPE_PID up to the pid type it
+ * was declared with and the helpers take that bound from the array.
+ */
+static inline void __get_pids(struct pid **dst, struct pid *const *src,
+ enum pid_type last)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ dst[type] = get_pid(src[type]);
+}
+
+static inline void __put_pids(struct pid **pids, enum pid_type last)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++) {
+ put_pid(pids[type]);
+ pids[type] = NULL;
+ }
+}
+
+static inline void __swap_pids(struct pid **a, struct pid **b,
+ enum pid_type last)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ swap(a[type], b[type]);
+}
+
+static inline bool __pids_equal(struct pid *const *a, struct pid *const *b,
+ enum pid_type last)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ if (a[type] != b[type])
+ return false;
+ return true;
+}
+
+/* The last pid type an array declared with DECLARE_PIDS() covers. */
+#define pids_last(pids) \
+ ((enum pid_type)(ARRAY_SIZE(pids) - 1 + \
+ BUILD_BUG_ON_ZERO(ARRAY_SIZE(pids) > PIDTYPE_MAX)))
+
+#define __pids_last2(a, b) \
+ (pids_last(a) + BUILD_BUG_ON_ZERO(ARRAY_SIZE(a) != ARRAY_SIZE(b)))
+
+#define get_pids(dst, src) __get_pids(dst, src, __pids_last2(dst, src))
+#define put_pids(pids) __put_pids(pids, pids_last(pids))
+#define swap_pids(a, b) __swap_pids(a, b, __pids_last2(a, b))
+#define pids_equal(a, b) __pids_equal(a, b, __pids_last2(a, b))
+
extern struct task_struct *pid_task(struct pid *pid, enum pid_type);
static inline bool pid_has_task(struct pid *pid, enum pid_type type)
{
@@ -187,6 +240,15 @@ static inline pid_t pid_nr(struct pid *pid)
pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
pid_t pid_vnr(struct pid *pid);
+/*
+ * Needs tasklist_lock if type > PIDTYPE_TGID. A lockless reader can:
+ *
+ * - race with a change_pid() that moves the task to another hlist,
+ * and continue to scan the wrong list.
+ *
+ * - race with a copy_process() that adds a new task to the start of hlist,
+ * and miss the new child.
+ */
#define do_each_pid_task(pid, type, task) \
do { \
if ((pid) != NULL) \
@@ -264,7 +326,7 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk)
*/
static inline int pid_alive(const struct task_struct *p)
{
- return p->thread_pid != NULL;
+ return READ_ONCE(p->thread_pid) != NULL;
}
static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
diff --git a/include/linux/pid_types.h b/include/linux/pid_types.h
index c2aee1d91dcf..3302690a2a28 100644
--- a/include/linux/pid_types.h
+++ b/include/linux/pid_types.h
@@ -2,6 +2,8 @@
#ifndef _LINUX_PID_TYPES_H
#define _LINUX_PID_TYPES_H
+#include <linux/build_bug.h>
+
enum pid_type {
PIDTYPE_PID,
PIDTYPE_TGID,
@@ -10,6 +12,12 @@ enum pid_type {
PIDTYPE_MAX,
};
+struct pid;
+
+/* An array of struct pid indexed by pid type, PIDTYPE_PID up to @last. */
+#define DECLARE_PIDS(name, last) \
+ struct pid *name[(last) + 1 + BUILD_BUG_ON_ZERO((last) >= PIDTYPE_MAX)]
+
struct pid_namespace;
extern struct pid_namespace init_pid_ns;
diff --git a/include/linux/pidfs.h b/include/linux/pidfs.h
index 0abf7da9ab23..3c1e82f1a369 100644
--- a/include/linux/pidfs.h
+++ b/include/linux/pidfs.h
@@ -3,6 +3,7 @@
#define _LINUX_PID_FS_H
#include <linux/gfp_types.h>
+#include <linux/pid.h>
struct coredump_params;
@@ -32,5 +33,9 @@ static inline int pidfs_register_pid(struct pid *pid)
}
void pidfs_free_pid(struct pid *pid);
+int __pidfs_register_pids(struct pid *const *pids, enum pid_type last);
+
+/* Register the pids of an array declared with DECLARE_PIDS(). */
+#define pidfs_register_pids(pids) __pidfs_register_pids(pids, pids_last(pids))
#endif /* _LINUX_PID_FS_H */
diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h
index 726d89143842..b78ee4676b98 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -57,6 +57,8 @@ struct dmtimer_platform_data {
u32 timer_errata;
int (*get_context_loss_count)(struct device *);
const struct omap_dm_timer_ops *timer_ops;
+ /* always-on timers can be used for clocksource/clockevent */
+ bool system_timer_capable;
};
#endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
index d2fa1c41bfd2..b9fc1be86ae3 100644
--- a/include/linux/rbtree_augmented.h
+++ b/include/linux/rbtree_augmented.h
@@ -15,6 +15,8 @@
#include <linux/compiler.h>
#include <linux/rbtree.h>
#include <linux/rcupdate.h>
+#include <linux/args.h>
+#include <linux/minmax.h>
/*
* Please note - only struct rb_augment_callbacks and the prototypes for
@@ -28,6 +30,7 @@ struct rb_augment_callbacks {
void (*propagate)(struct rb_node *node, struct rb_node *stop);
void (*copy)(struct rb_node *old, struct rb_node *new);
void (*rotate)(struct rb_node *old, struct rb_node *new);
+ void (*merge)(struct rb_node *node, struct rb_node *new);
};
extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
@@ -60,6 +63,12 @@ rb_insert_augmented_cached(struct rb_node *node,
rb_insert_augmented(node, &root->rb_root, augment);
}
+/*
+ * Insert @node into the leftmost cached augmented tree @tree.
+ *
+ * The augmented data of @node must already describe @node alone; it is
+ * merged into every ancestor on the way down through augment->merge().
+ */
static __always_inline struct rb_node *
rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
bool (*less)(struct rb_node *, const struct rb_node *),
@@ -71,6 +80,7 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
while (*link) {
parent = *link;
+ augment->merge(parent, node);
if (less(node, parent)) {
link = &parent->rb_left;
} else {
@@ -80,12 +90,108 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
}
rb_link_node(node, parent, link);
- augment->propagate(parent, NULL); /* suboptimal */
rb_insert_augmented_cached(node, tree, leftmost, augment);
return leftmost ? node : NULL;
}
+#define RB_FOR_EACH_1(what, RBNAME, RBSTRUCT, RBFIELD, x) \
+ what(1, RBNAME, RBSTRUCT, RBFIELD, x)
+
+#define RB_FOR_EACH_2(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(2, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_1(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_3(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(3, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_2(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_4(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(4, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_3(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_5(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(5, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_4(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_6(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(6, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_5(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_7(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(7, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_6(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_8(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(8, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_7(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH(action, RBNAME, RBSTRUCT, RBFIELD, ...) \
+ CONCATENATE(RB_FOR_EACH_, COUNT_ARGS(__VA_ARGS__)) \
+ (action, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+/*
+ * One augmented field: @val is the node's own contribution (a member for
+ * RB_AUG(), a function of the node for RB_AUG_FUNC()), @aug the member
+ * holding the aggregate over the subtree, and @fold(a, b) combines two
+ * aggregates: min, max, a sum, ... It must be commutative and associative.
+ */
+#define RB_AUG_FUNC(val, aug, fold) (val(s), aug, fold)
+#define RB_AUG(val, aug, fold) (s->val, aug, fold)
+#define RB_UNPACK(...) __VA_ARGS__
+
+#define __RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \
+static inline void \
+RBNAME ## _copy_ ## n(RBSTRUCT *old, RBSTRUCT *new) \
+{ \
+ new->aug = old->aug; \
+} \
+static inline bool \
+RBNAME ## _compute_ ## n(RBSTRUCT *s, bool exit) \
+{ \
+ TYPEOF_UNQUAL(s->aug) _old_aug = s->aug; \
+ TYPEOF_UNQUAL(s->aug) _val = val; \
+ struct rb_node *_node = &s->RBFIELD; \
+ if (_node->rb_right) { \
+ RBSTRUCT *_c = container_of(_node->rb_right, typeof(*s), RBFIELD); \
+ _val = fold(_val, _c->aug); \
+ } \
+ if (_node->rb_left) { \
+ RBSTRUCT *_c = container_of(_node->rb_left, typeof(*s), RBFIELD); \
+ _val = fold(_val, _c->aug); \
+ } \
+ if (exit && _old_aug == _val) \
+ return true; \
+ s->aug = _val; \
+ return false; \
+}
+#define _RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, args) \
+ __RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, args)
+#define RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, x) \
+ _RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x)
+
+#define __RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \
+ RBNAME ## _copy_ ## n(old, new);
+#define _RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, args) \
+ __RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, args)
+#define RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, x) \
+ _RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x)
+
+#define __RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \
+ ret &= RBNAME ## _compute_ ## n(node, exit);
+#define _RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, args) \
+ __RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, args)
+#define RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, x) \
+ _RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x)
+
+/* fold @new, about to become a descendant of @node, into @node */
+#define __RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \
+ node->aug = fold(node->aug, new->aug);
+#define _RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, args) \
+ __RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, args)
+#define RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, x) \
+ _RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x)
+
/*
* Template for declaring augmented rbtree callbacks (generic multi fields)
*
@@ -93,18 +199,29 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
* RBNAME: name of the rb_augment_callbacks structure
* RBSTRUCT: struct type of the tree nodes
* RBFIELD: name of struct rb_node field within RBSTRUCT
- * RBCOPY: name of function that copies the RBAUGMENTED datas
- * RBCOMPUTE: name of function that recomputes the RBAUGMENTED datas
+ * RBAUG...: list of RB_AUG() describing the augmented data
*/
-
-#define RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \
- RBSTRUCT, RBFIELD, RBCOPY, RBCOMPUTE) \
+#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
+ RBSTRUCT, RBFIELD, RBAUG...) \
+RB_FOR_EACH(RB_INST, RBNAME, RBSTRUCT, RBFIELD, RBAUG) \
+static inline void \
+RBNAME ## __copy(RBSTRUCT *old, RBSTRUCT *new) \
+{ \
+ RB_FOR_EACH(RB_COPY, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \
+} \
+static inline bool \
+RBNAME ## __compute(RBSTRUCT *node, bool exit) \
+{ \
+ bool ret = true; \
+ RB_FOR_EACH(RB_COMPUTE, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \
+ return ret; \
+} \
static inline void \
RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
{ \
while (rb != stop) { \
RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
- if (RBCOMPUTE(node, true)) \
+ if (RBNAME ## __compute(node, true)) \
break; \
rb = rb_parent(&node->RBFIELD); \
} \
@@ -114,44 +231,31 @@ RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \
{ \
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
- RBCOPY(new, old); \
+ RBNAME ## __copy(old, new); \
} \
static void \
RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \
{ \
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
- RBCOPY(new, old); \
- RBCOMPUTE(old, false); \
+ RBNAME ## __copy(old, new); \
+ RBNAME ## __compute(old, false); \
+} \
+static inline void \
+RBNAME ## _merge(struct rb_node *rb, struct rb_node *rb_new) \
+{ \
+ RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
+ RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
+ RB_FOR_EACH(RB_MERGE, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \
} \
RBSTATIC const struct rb_augment_callbacks RBNAME = { \
.propagate = RBNAME ## _propagate, \
.copy = RBNAME ## _copy, \
- .rotate = RBNAME ## _rotate \
+ .rotate = RBNAME ## _rotate, \
+ .merge = RBNAME ## _merge \
};
/*
- * Template for declaring augmented rbtree callbacks (generic single field)
- *
- * RBSTATIC: 'static' or empty
- * RBNAME: name of the rb_augment_callbacks structure
- * RBSTRUCT: struct type of the tree nodes
- * RBFIELD: name of struct rb_node field within RBSTRUCT
- * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
- * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
- */
-
-#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
- RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
-static inline void \
-RBNAME ## _copy_single(RBSTRUCT *new, RBSTRUCT *old) \
-{ \
- new->RBAUGMENTED = old->RBAUGMENTED; \
-} \
-RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \
- RBSTRUCT, RBFIELD, RBNAME ## _copy_single, RBCOMPUTE)
-
-/*
* Template for declaring augmented rbtree callbacks,
* computing RBAUGMENTED scalar as max(RBCOMPUTE(node)) for all subtree nodes.
*
@@ -159,34 +263,15 @@ RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \
* RBNAME: name of the rb_augment_callbacks structure
* RBSTRUCT: struct type of the tree nodes
* RBFIELD: name of struct rb_node field within RBSTRUCT
- * RBTYPE: type of the RBAUGMENTED field
- * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree
- * RBCOMPUTE: name of function that returns the per-node RBTYPE scalar
+ * RBTYPE: type of the RBAUGMENTED field -- unused, assumed typeof(RBAUGMENTED)
+ * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
+ * RBVALUE: name of function that returns the per-node RBTYPE scalar
*/
-#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
- RBTYPE, RBAUGMENTED, RBCOMPUTE) \
-static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \
-{ \
- RBSTRUCT *child; \
- RBTYPE max = RBCOMPUTE(node); \
- if (node->RBFIELD.rb_left) { \
- child = rb_entry(node->RBFIELD.rb_left, RBSTRUCT, RBFIELD); \
- if (child->RBAUGMENTED > max) \
- max = child->RBAUGMENTED; \
- } \
- if (node->RBFIELD.rb_right) { \
- child = rb_entry(node->RBFIELD.rb_right, RBSTRUCT, RBFIELD); \
- if (child->RBAUGMENTED > max) \
- max = child->RBAUGMENTED; \
- } \
- if (exit && node->RBAUGMENTED == max) \
- return true; \
- node->RBAUGMENTED = max; \
- return false; \
-} \
-RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
- RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max)
+#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
+ RBTYPE, RBAUGMENTED, RBVALUE) \
+RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
+ RB_AUG_FUNC(RBVALUE, RBAUGMENTED, max))
#define RB_RED 0
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index 16a04202888b..e6ad4f2a475c 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -116,7 +116,7 @@ int rcutree_offline_cpu(unsigned int cpu);
void rcutree_migrate_callbacks(int cpu);
-/* Called from hotplug and also arm64 early secondary boot failure */
+/* Called from hotplug */
void rcutree_report_cpu_dead(void);
#endif /* __LINUX_RCUTREE_H */
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index ff0ad1e12c01..00019b1895e6 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -233,7 +233,7 @@ enum rproc_features {
* @subdevs: list of subdevices, to following the running state
* @notifyids: idr for dynamically assigning rproc-wide unique notify ids
* @index: index of this rproc device
- * @attach_work: workqueue for attaching rproc
+ * @boot_work: workqueue for booting rproc
* @crash_handler: workqueue for handling a crash
* @crash_handler_lock: serializes crash handler queueing and deletion
* @deleting: remoteproc deletion has begun
@@ -280,7 +280,7 @@ struct rproc {
struct list_head subdevs;
struct idr notifyids;
int index;
- struct work_struct attach_work;
+ struct work_struct boot_work;
struct work_struct crash_handler;
spinlock_t crash_handler_lock;
bool deleting;
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index d9419dc902f6..0adb51ab1542 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -131,8 +131,8 @@ struct signal_struct {
* process will inherit a flag if they should look for a
* child_subreaper process at exit.
*/
- unsigned int is_child_subreaper:1;
- unsigned int has_child_subreaper:1;
+ bool is_child_subreaper;
+ bool has_child_subreaper;
unsigned int autoreap:1;
#ifdef CONFIG_POSIX_TIMERS
@@ -697,6 +697,24 @@ struct pid *task_pid_type(struct task_struct *task, enum pid_type type)
return pid;
}
+/* Fill @pids with the pid types of @task up to @last, without references. */
+static inline void __task_pids(struct pid **pids, enum pid_type last,
+ struct task_struct *task)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ pids[type] = task_pid_type(task, type);
+}
+
+static inline void __get_task_pids(struct pid **pids, enum pid_type last,
+ struct task_struct *task)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ pids[type] = get_pid(task_pid_type(task, type));
+}
+
+#define task_pids(pids, task) __task_pids(pids, pids_last(pids), task)
+#define get_task_pids(pids, task) __get_task_pids(pids, pids_last(pids), task)
+
static inline struct pid *task_tgid(struct task_struct *task)
{
return task->signal->pids[PIDTYPE_TGID];
diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h
index 9f2839e73f8a..f006f2654e4c 100644
--- a/include/linux/seq_buf.h
+++ b/include/linux/seq_buf.h
@@ -5,6 +5,7 @@
#include <linux/bug.h>
#include <linux/minmax.h>
#include <linux/seq_file.h>
+#include <linux/string.h>
#include <linux/types.h>
/*
@@ -30,6 +31,10 @@ struct seq_buf {
.size = SIZE, \
}
+/**
+ * seq_buf_clear - reset the seq_buf to be read / appended from the beginning
+ * @s: the seq_buf handle
+ */
static inline void seq_buf_clear(struct seq_buf *s)
{
s->len = 0;
@@ -37,6 +42,14 @@ static inline void seq_buf_clear(struct seq_buf *s)
s->buffer[0] = '\0';
}
+/**
+ * seq_buf_init - initialize a seq_buf
+ * @s: the seq_buf handle
+ * @buf: pointer to the buffer
+ * @size: total size of @buf
+ *
+ * The contents of the buffer are ignored.
+ */
static inline void
seq_buf_init(struct seq_buf *s, char *buf, unsigned int size)
{
@@ -55,12 +68,46 @@ seq_buf_has_overflowed(struct seq_buf *s)
return s->len > s->size;
}
+/*
+ * Mark @s as overflowed, which discards the length of what it holds. The
+ * bytes up to its last one are the string from then on, as that is where
+ * seq_buf_str() terminates it, so clear whatever was not written: a writer
+ * sets len to how much it filled, and anything past that was never adopted.
+ */
static inline void
seq_buf_set_overflow(struct seq_buf *s)
{
+ if (s->len < s->size)
+ memset(s->buffer + s->len, 0, s->size - s->len);
+
s->len = s->size + 1;
}
+/**
+ * seq_buf_init_append - initialize a seq_buf over a buffer that may
+ * already hold NUL-terminated content
+ * @s: the seq_buf handle
+ * @buf: pointer to the (possibly non-empty) buffer
+ * @size: total size of @buf
+ *
+ * Unlike seq_buf_init(), which always starts @buf at len=0, this
+ * preserves whatever NUL-terminated content @buf already holds and
+ * positions @s to append after it. Useful for converting code that used
+ * to append to an existing buffer with strlcat()/scnprintf() and friends.
+ *
+ * If @buf holds no NUL within @size, @s starts out overflowed, as
+ * strlcat() treats such a buffer as already truncated.
+ */
+static inline void
+seq_buf_init_append(struct seq_buf *s, char *buf, unsigned int size)
+{
+ s->buffer = buf;
+ s->size = size;
+ s->len = strnlen(buf, size);
+ if (s->len == size)
+ seq_buf_set_overflow(s);
+}
+
/*
* How much buffer is left on the seq_buf?
*/
@@ -79,6 +126,27 @@ static inline unsigned int seq_buf_used(struct seq_buf *s)
return min(s->len, s->size);
}
+/*
+ * NUL-terminate the buffer in @s: directly after the data when there is
+ * room for it, otherwise in the last byte of the buffer. @s->size must not
+ * be zero.
+ *
+ * Returns: the offset of the NUL.
+ */
+static inline size_t __seq_buf_terminate(struct seq_buf *s)
+{
+ size_t end;
+
+ if (seq_buf_buffer_left(s))
+ end = s->len;
+ else
+ end = s->size - 1;
+
+ s->buffer[end] = 0;
+
+ return end;
+}
+
/**
* seq_buf_str - get NUL-terminated C string from seq_buf
* @s: the seq_buf handle
@@ -88,7 +156,14 @@ static inline unsigned int seq_buf_used(struct seq_buf *s)
*
* Note, if this is called when the buffer has overflowed, then
* the last byte of the buffer is zeroed, and the len will still
- * point passed it.
+ * point passed it. The same happens when the buffer is exactly
+ * full: the NUL takes the place of the last byte written, which is
+ * lost, though seq_buf_used() still counts it.
+ *
+ * A zero-sized seq_buf has nowhere to put a NUL, so the empty string
+ * is returned instead of writing to @s->buffer. Any other seq_buf
+ * returns @s->buffer, even when it holds an empty string, so callers
+ * always get their own buffer back.
*
* After this function is called, s->buffer is safe to use
* in string operations.
@@ -97,18 +172,68 @@ static inline unsigned int seq_buf_used(struct seq_buf *s)
*/
static inline const char *seq_buf_str(struct seq_buf *s)
{
- if (WARN_ON(s->size == 0))
+ if (s->size == 0)
return "";
- if (seq_buf_buffer_left(s))
- s->buffer[s->len] = 0;
- else
- s->buffer[s->size - 1] = 0;
+ __seq_buf_terminate(s);
return s->buffer;
}
/**
+ * seq_buf_strlen - get the length of the NUL-terminated C string in seq_buf
+ * @s: the seq_buf handle
+ *
+ * This makes sure that the buffer in @s is NUL-terminated, exactly as
+ * seq_buf_str() does, and returns the length of the resulting string
+ * without walking it. Unlike seq_buf_used(), this does not count the byte
+ * given up to the NUL when the buffer is full or has overflowed. When the
+ * buffer is exactly full, that byte is the last one written, and calling
+ * either function loses it.
+ *
+ * A zero-sized seq_buf holds no string, so 0 is returned without writing
+ * to @s->buffer, matching what seq_buf_str() returns for one.
+ *
+ * After this function is called, s->buffer is safe to use
+ * in string operations.
+ *
+ * Returns: the offset of the NUL that terminates @s->buffer. That is the
+ * length of the string unless an earlier NUL is in the way, either one the
+ * data written to @s carried itself, or one seq_buf_set_overflow() left
+ * behind when it cleared what no writer had claimed.
+ */
+static inline size_t seq_buf_strlen(struct seq_buf *s)
+{
+ if (s->size == 0)
+ return 0;
+
+ return __seq_buf_terminate(s);
+}
+
+/**
+ * seq_buf_terminate - NUL-terminate the string in a seq_buf
+ * @s: the seq_buf handle
+ *
+ * Terminate @s->buffer exactly as seq_buf_str() and seq_buf_strlen() do,
+ * for callers that want neither the pointer nor the length and only need
+ * the buffer to be safe to read as a C string. A zero-sized seq_buf has
+ * nowhere to put a NUL and is left untouched.
+ *
+ * Nothing is returned on purpose: a caller that wants the length should
+ * use seq_buf_strlen(), which says so.
+ *
+ * After this function is called, s->buffer is safe to use
+ * in string operations.
+ */
+static inline void seq_buf_terminate(struct seq_buf *s)
+{
+ if (s->size == 0)
+ return;
+
+ __seq_buf_terminate(s);
+}
+
+/**
* seq_buf_get_buf - get buffer to write arbitrary data to
* @s: the seq_buf handle
* @bufp: the beginning of the buffer is stored here
@@ -155,11 +280,11 @@ static inline void seq_buf_commit(struct seq_buf *s, int num)
*
* Removes the last written character to the seq_buf @s.
*
- * Returns the last character or -1 if it is empty.
+ * Returns the last character, or -1 if @s is empty or has overflowed.
*/
static inline int seq_buf_pop(struct seq_buf *s)
{
- if (!s->len)
+ if (!s->len || seq_buf_has_overflowed(s))
return -1;
s->len--;
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index dc0e8c62d9e0..f0e7e52a0905 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -28,11 +28,16 @@ struct seq_file {
void *private;
};
+/* All four are called without checking for NULL. */
struct seq_operations {
- void * (*start) (struct seq_file *m, loff_t *pos);
- void (*stop) (struct seq_file *m, void *v);
- void * (*next) (struct seq_file *m, void *v, loff_t *pos);
- int (*show) (struct seq_file *m, void *v);
+ void *(*start)(struct seq_file *m, loff_t *pos)
+ __require_explicit_initialization;
+ void (*stop)(struct seq_file *m, void *v)
+ __require_explicit_initialization;
+ void *(*next)(struct seq_file *m, void *v, loff_t *pos)
+ __require_explicit_initialization;
+ int (*show)(struct seq_file *m, void *v)
+ __require_explicit_initialization;
};
#define SEQ_SKIP 1
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index eeb868e93e15..d91c0477be9d 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -186,10 +186,10 @@ static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up)
return container_of(up, struct uart_8250_port, port);
}
-int serial8250_register_8250_port(const struct uart_8250_port *);
-void serial8250_unregister_port(int line);
-void serial8250_suspend_port(int line);
-void serial8250_resume_port(int line);
+struct uart_8250_port *serial8250_register_8250_port(const struct uart_8250_port *);
+void serial8250_unregister_port(struct uart_8250_port *);
+void serial8250_suspend_port(struct uart_8250_port *);
+void serial8250_resume_port(struct uart_8250_port *);
int early_serial_setup(struct uart_port *port);
int early_serial8250_setup(struct earlycon_device *device, const char *options);
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 5a5eb1250103..b17fdb7d38a7 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -189,10 +189,11 @@ static inline size_t msg_data_left(const struct msghdr *msg)
/* "Socket"-level control message types: */
-#define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */
-#define SCM_CREDENTIALS 0x02 /* rw: struct ucred */
-#define SCM_SECURITY 0x03 /* rw: security label */
-#define SCM_PIDFD 0x04 /* ro: pidfd (int) */
+#define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */
+#define SCM_CREDENTIALS 0x02 /* rw: struct ucred */
+#define SCM_SECURITY 0x03 /* rw: security label */
+#define SCM_PIDFD 0x04 /* ro: pidfd (int) */
+#define SCM_PIDFD_THREAD 0x05 /* ro: thread pidfd (int) */
struct ucred {
__u32 pid;
diff --git a/include/linux/spinlock_types_raw.h b/include/linux/spinlock_types_raw.h
index e5644ab2161f..942c229c90bb 100644
--- a/include/linux/spinlock_types_raw.h
+++ b/include/linux/spinlock_types_raw.h
@@ -11,6 +11,10 @@
#include <linux/lockdep_types.h>
+/*
+ * Keep in sync with rust/kernel/sync/lock/spinlock.rs
+ */
+
context_lock_struct(raw_spinlock) {
arch_spinlock_t raw_lock;
#ifdef CONFIG_DEBUG_SPINLOCK
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index 4eb9564a7fb3..4daebc980501 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -70,6 +70,22 @@ int spmi_device_add(struct spmi_device *sdev);
void spmi_device_remove(struct spmi_device *sdev);
/**
+ * struct spmi_subdevice - Basic representation of an SPMI sub-device
+ * @sdev: Sub-device representation of an SPMI device
+ * @devid: Platform Device ID of an SPMI sub-device
+ */
+struct spmi_subdevice {
+ struct spmi_device sdev;
+ unsigned int devid;
+};
+
+struct spmi_subdevice *spmi_subdevice_alloc_and_add(struct spmi_device *sparent);
+void spmi_subdevice_remove(struct spmi_subdevice *sdev);
+
+struct spmi_subdevice *devm_spmi_subdevice_alloc_and_add(struct device *dev,
+ struct spmi_device *sparent);
+
+/**
* struct spmi_controller - interface to the SPMI master controller
* @dev: Driver model representation of the device.
* @nr: board-specific number identifier for this controller/bus
@@ -173,6 +189,7 @@ static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
struct device_node;
struct spmi_device *spmi_find_device_by_of_node(struct device_node *np);
+struct spmi_device *spmi_get_parent_spmi_device(struct device *dev);
int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
size_t len);
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 24698856eb40..cfb5ab17dabd 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -87,6 +87,8 @@ struct svc_serv {
char * sv_name; /* service name */
bool sv_is_pooled; /* is this a pooled service? */
+ /* Caller registers with rpcbind itself. Set before svc_bind(). */
+ bool sv_no_rpcbind;
struct svc_pool * sv_pools; /* array of thread pools */
int (*sv_threadfn)(void *data);
diff --git a/include/linux/sunrpc/xdrgen/nfs2.h b/include/linux/sunrpc/xdrgen/nfs2.h
new file mode 100644
index 000000000000..1d26de39ac69
--- /dev/null
+++ b/include/linux/sunrpc/xdrgen/nfs2.h
@@ -0,0 +1,298 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Generated by xdrgen. Manual edits will be lost. */
+/* XDR specification file: ../../Documentation/sunrpc/xdr/nfs2.x */
+/* XDR specification modification time: Tue Sep 8 11:26:28 2026 */
+
+#ifndef _LINUX_XDRGEN_NFS2_DEF_H
+#define _LINUX_XDRGEN_NFS2_DEF_H
+
+#include <linux/types.h>
+#include <linux/sunrpc/xdrgen/_defs.h>
+
+enum { NFS_MAXDATA = 8192 };
+
+enum { NFS_MAXPATHLEN = 1024 };
+
+enum { NFS_MAXNAMLEN = 255 };
+
+enum { NFS_COOKIESIZE = 4 };
+
+enum { NFS_FHSIZE = 32 };
+
+enum nfsstat {
+ NFS_OK = 0,
+ NFSERR_PERM = 1,
+ NFSERR_NOENT = 2,
+ NFSERR_IO = 5,
+ NFSERR_NXIO = 6,
+ NFSERR_ACCES = 13,
+ NFSERR_EXIST = 17,
+ NFSERR_NODEV = 19,
+ NFSERR_NOTDIR = 20,
+ NFSERR_ISDIR = 21,
+ NFSERR_FBIG = 27,
+ NFSERR_NOSPC = 28,
+ NFSERR_ROFS = 30,
+ NFSERR_NAMETOOLONG = 63,
+ NFSERR_NOTEMPTY = 66,
+ NFSERR_DQUOT = 69,
+ NFSERR_STALE = 70,
+ NFSERR_WFLUSH = 99,
+};
+
+typedef __be32 nfsstat;
+
+enum ftype {
+ NFNON = 0,
+ NFREG = 1,
+ NFDIR = 2,
+ NFBLK = 3,
+ NFCHR = 4,
+ NFLNK = 5,
+};
+
+typedef enum ftype ftype;
+
+typedef u8 fhandle[NFS_FHSIZE];
+
+typedef u8 nfscookie[NFS_COOKIESIZE];
+
+struct timeval {
+ u32 seconds;
+ u32 useconds;
+};
+
+struct fattr {
+ ftype type;
+ u32 mode;
+ u32 nlink;
+ u32 uid;
+ u32 gid;
+ u32 size;
+ u32 blocksize;
+ u32 rdev;
+ u32 blocks;
+ u32 fsid;
+ u32 fileid;
+ struct timeval atime;
+ struct timeval mtime;
+ struct timeval ctime;
+};
+
+struct sattr {
+ u32 mode;
+ u32 uid;
+ u32 gid;
+ u32 size;
+ struct timeval atime;
+ struct timeval mtime;
+};
+
+typedef string filename;
+
+typedef string path;
+
+struct attrstat {
+ nfsstat status;
+ union {
+ struct fattr attributes;
+ } u;
+};
+
+struct diropargs {
+ fhandle dir;
+ filename name;
+};
+
+struct diropok {
+ fhandle file;
+ struct fattr attributes;
+};
+
+struct diropres {
+ nfsstat status;
+ union {
+ struct diropok diropok;
+ } u;
+};
+
+struct sattrargs {
+ fhandle file;
+ struct sattr attributes;
+};
+
+struct readlinkres {
+ nfsstat status;
+ union {
+ path data;
+ } u;
+};
+
+struct readargs {
+ fhandle file;
+ u32 offset;
+ u32 count;
+ u32 totalcount;
+};
+
+struct readresok {
+ struct fattr attributes;
+ opaque data;
+};
+
+struct readres {
+ nfsstat status;
+ union {
+ struct readresok readresok;
+ } u;
+};
+
+struct writeargs {
+ fhandle file;
+ u32 beginoffset;
+ u32 offset;
+ u32 totalcount;
+ struct xdr_buf data;
+};
+
+struct createargs {
+ struct diropargs where;
+ struct sattr attributes;
+};
+
+struct renameargs {
+ struct diropargs from;
+ struct diropargs to;
+};
+
+struct linkargs {
+ fhandle from;
+ struct diropargs to;
+};
+
+struct symlinkargs {
+ struct diropargs from;
+ struct xdr_buf to;
+ struct sattr attributes;
+};
+
+struct readdirargs {
+ fhandle dir;
+ nfscookie cookie;
+ u32 count;
+};
+
+struct entry {
+ u32 fileid;
+ filename name;
+ nfscookie cookie;
+};
+
+struct readdirok {
+ struct entry *entries;
+ bool eof;
+};
+
+struct readdirres {
+ nfsstat status;
+ union {
+ struct readdirok readdirok;
+ } u;
+};
+
+struct info {
+ u32 tsize;
+ u32 bsize;
+ u32 blocks;
+ u32 bfree;
+ u32 bavail;
+};
+
+struct statfsres {
+ nfsstat status;
+ union {
+ struct info info;
+ } u;
+};
+
+enum {
+ NFSPROC_NULL = 0,
+ NFSPROC_GETATTR = 1,
+ NFSPROC_SETATTR = 2,
+ NFSPROC_ROOT = 3,
+ NFSPROC_LOOKUP = 4,
+ NFSPROC_READLINK = 5,
+ NFSPROC_READ = 6,
+ NFSPROC_WRITECACHE = 7,
+ NFSPROC_WRITE = 8,
+ NFSPROC_CREATE = 9,
+ NFSPROC_REMOVE = 10,
+ NFSPROC_RENAME = 11,
+ NFSPROC_LINK = 12,
+ NFSPROC_SYMLINK = 13,
+ NFSPROC_MKDIR = 14,
+ NFSPROC_RMDIR = 15,
+ NFSPROC_READDIR = 16,
+ NFSPROC_STATFS = 17,
+};
+
+#ifndef NFS_PROGRAM
+#define NFS_PROGRAM (100003)
+#endif
+
+#define NFS2_nfsstat_sz (XDR_int)
+#define NFS2_ftype_sz (XDR_int)
+#define NFS2_fhandle_sz (XDR_QUADLEN(NFS_FHSIZE))
+#define NFS2_nfscookie_sz (XDR_QUADLEN(NFS_COOKIESIZE))
+#define NFS2_timeval_sz \
+ (XDR_unsigned_int + XDR_unsigned_int)
+#define NFS2_fattr_sz \
+ (NFS2_ftype_sz + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + NFS2_timeval_sz + NFS2_timeval_sz + NFS2_timeval_sz)
+#define NFS2_sattr_sz \
+ (XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + NFS2_timeval_sz + NFS2_timeval_sz)
+#define NFS2_filename_sz (XDR_unsigned_int + XDR_QUADLEN(NFS_MAXNAMLEN))
+#define NFS2_path_sz (XDR_unsigned_int + XDR_QUADLEN(NFS_MAXPATHLEN))
+#define NFS2_attrstat_sz \
+ (NFS2_nfsstat_sz + NFS2_fattr_sz)
+#define NFS2_diropargs_sz \
+ (NFS2_fhandle_sz + NFS2_filename_sz)
+#define NFS2_diropok_sz \
+ (NFS2_fhandle_sz + NFS2_fattr_sz)
+#define NFS2_diropres_sz \
+ (NFS2_nfsstat_sz + NFS2_diropok_sz)
+#define NFS2_sattrargs_sz \
+ (NFS2_fhandle_sz + NFS2_sattr_sz)
+#define NFS2_readlinkres_sz \
+ (NFS2_nfsstat_sz + NFS2_path_sz)
+#define NFS2_readargs_sz \
+ (NFS2_fhandle_sz + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int)
+#define NFS2_readresok_sz \
+ (NFS2_fattr_sz + XDR_unsigned_int + XDR_QUADLEN(NFS_MAXDATA))
+#define NFS2_readres_sz \
+ (NFS2_nfsstat_sz + NFS2_readresok_sz)
+#define NFS2_writeargs_sz \
+ (NFS2_fhandle_sz + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_QUADLEN(NFS_MAXDATA))
+#define NFS2_createargs_sz \
+ (NFS2_diropargs_sz + NFS2_sattr_sz)
+#define NFS2_renameargs_sz \
+ (NFS2_diropargs_sz + NFS2_diropargs_sz)
+#define NFS2_linkargs_sz \
+ (NFS2_fhandle_sz + NFS2_diropargs_sz)
+#define NFS2_symlinkargs_sz \
+ (NFS2_diropargs_sz + NFS2_path_sz + NFS2_sattr_sz)
+#define NFS2_readdirargs_sz \
+ (NFS2_fhandle_sz + NFS2_nfscookie_sz + XDR_unsigned_int)
+#define NFS2_entry_sz \
+ (XDR_bool + XDR_unsigned_int + NFS2_filename_sz + NFS2_nfscookie_sz)
+#define NFS2_readdirok_sz \
+ (XDR_bool + XDR_bool)
+#define NFS2_readdirres_sz \
+ (NFS2_nfsstat_sz + NFS2_readdirok_sz)
+#define NFS2_info_sz \
+ (XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int + XDR_unsigned_int)
+#define NFS2_statfsres_sz \
+ (NFS2_nfsstat_sz + NFS2_info_sz)
+#define NFS2_MAX_ARGS_SZ \
+ (NFS2_writeargs_sz)
+
+#endif /* _LINUX_XDRGEN_NFS2_DEF_H */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index a82045804d34..005730623f3b 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -145,6 +145,7 @@ struct xprtsec_parms {
enum xprtsec_policies policy;
/* authentication material */
+ key_serial_t keyring_serial;
key_serial_t cert_serial;
key_serial_t privkey_serial;
};
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index e4d1720f49f0..d18f7bc1e5d0 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -233,6 +233,13 @@ struct tcp_sock {
is_sack_reneg:1, /* in recovery from loss with SACK reneg? */
is_cwnd_limited:1,/* forward progress limited by snd_cwnd? */
recvmsg_inq : 1;/* Indicate # of bytes in queue upon recvmsg */
+#ifdef CONFIG_BPF
+ u32 bpf_tcp_ops_flags;
+#define BPF_TCP_OPS_TEST_FLAG(TP, ARG) \
+ (READ_ONCE((TP)->bpf_tcp_ops_flags) & BPF_TCP_OPS_FLAG_ ## ARG)
+#else
+#define BPF_TCP_OPS_TEST_FLAG(TP, ARG) (0)
+#endif
__cacheline_group_end(tcp_sock_read_txrx);
/* RX read-mostly hotpath cache lines */
diff --git a/include/linux/tnum.h b/include/linux/tnum.h
index ca2cfec8de08..16682248f963 100644
--- a/include/linux/tnum.h
+++ b/include/linux/tnum.h
@@ -134,4 +134,6 @@ static inline bool tnum_subreg_is_const(struct tnum a)
/* Returns the smallest member of t larger than z */
u64 tnum_step(struct tnum t, u64 z);
+u32 tnum_alignment(struct tnum a);
+
#endif /* _LINUX_TNUM_H */
diff --git a/include/linux/torture.h b/include/linux/torture.h
index 1b6d5be641f8..c9b47d138302 100644
--- a/include/linux/torture.h
+++ b/include/linux/torture.h
@@ -98,7 +98,6 @@ void torture_shutdown_absorb(const char *title);
int torture_shutdown_init(int ssecs, void (*cleanup)(void));
/* Task stuttering, which forces load/no-load transitions. */
-bool stutter_will_wait(void);
bool stutter_wait(const char *title);
int torture_stutter_init(int s, int sgap);
@@ -132,11 +131,8 @@ void _torture_stop_kthread(char *m, struct task_struct **tp);
#endif
void torture_sched_set_normal(struct task_struct *t, int nice);
-#if IS_ENABLED(CONFIG_RCU_TORTURE_TEST) || IS_ENABLED(CONFIG_LOCK_TORTURE_TEST) || IS_ENABLED(CONFIG_HAZPTR_TORTURE_TEST)
+#if IS_ENABLED(CONFIG_RCU_TORTURE_TEST) || IS_MODULE(CONFIG_RCU_TORTURE_TEST) || IS_ENABLED(CONFIG_LOCK_TORTURE_TEST) || IS_MODULE(CONFIG_LOCK_TORTURE_TEST)
long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn);
#endif
-/* Atomic per-CPU counters. */
-s64 torture_sum_pcpu_atomic_long(atomic_long_t __percpu *pcp);
-
#endif /* __LINUX_TORTURE_H */
diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h
index 697d619aafdc..7174ebf3f015 100644
--- a/include/linux/trace_seq.h
+++ b/include/linux/trace_seq.h
@@ -86,7 +86,10 @@ static inline bool trace_seq_has_overflowed(struct trace_seq *s)
*
* Removes the last written character to the trace_seq @s.
*
- * Returns the last character or -1 if it is empty.
+ * Returns the last character, or -1 if the underlying seq_buf is empty or
+ * has overflowed. Note that only that buffer is consulted: a @s marked
+ * full by a write that did not fit, which trace_seq_has_overflowed()
+ * reports as overflowed, still pops the last character written.
*/
static inline int trace_seq_pop(struct trace_seq *s)
{
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 8d82a8258ef1..3fc98542922e 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -11,6 +11,7 @@
#include <uapi/linux/uio.h>
struct page;
+struct dma_buf_io_map;
typedef unsigned int __bitwise iov_iter_extraction_t;
@@ -28,6 +29,7 @@ enum iter_type {
ITER_BVECQ,
ITER_XARRAY,
ITER_DISCARD,
+ ITER_DMABUF_MAP,
};
#define ITER_SOURCE 1 // == WRITE
@@ -70,6 +72,7 @@ struct iov_iter {
const struct bvecq *bvecq;
struct xarray *xarray;
void __user *ubuf;
+ struct dma_buf_io_map *dmabuf_map;
};
size_t count;
};
@@ -154,6 +157,11 @@ static inline bool iov_iter_is_xarray(const struct iov_iter *i)
return iov_iter_type(i) == ITER_XARRAY;
}
+static inline bool iov_iter_is_dmabuf_map(const struct iov_iter *i)
+{
+ return iov_iter_type(i) == ITER_DMABUF_MAP;
+}
+
static inline unsigned char iov_iter_rw(const struct iov_iter *i)
{
return i->data_source ? WRITE : READ;
@@ -299,6 +307,9 @@ void iov_iter_bvec_queue(struct iov_iter *i, unsigned int direction,
unsigned int first_slot, unsigned int offset, size_t count);
void iov_iter_xarray(struct iov_iter *i, unsigned int direction, struct xarray *xarray,
loff_t start, size_t count);
+void iov_iter_dmabuf_map(struct iov_iter *i, unsigned int direction,
+ struct dma_buf_io_map *map,
+ loff_t off, size_t count);
ssize_t iov_iter_get_pages2(struct iov_iter *i, struct page **pages,
size_t maxsize, unsigned maxpages, size_t *start);
ssize_t iov_iter_get_pages_alloc2(struct iov_iter *i, struct page ***pages,
diff --git a/include/linux/unicode.h b/include/linux/unicode.h
index 64fa44fe180c..3a8cb603eb93 100644
--- a/include/linux/unicode.h
+++ b/include/linux/unicode.h
@@ -53,6 +53,7 @@ struct unicode_map {
unsigned int version;
const struct utf8data *ntab[UTF8_NMAX];
const struct utf8data_table *tables;
+ struct rcu_head rcu;
};
int utf8_validate(const struct unicode_map *um, const struct qstr *str);
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index ab0a32a90629..5866f19d3c7b 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -305,9 +305,17 @@ struct usb_serial_driver {
void (*write_bulk_callback)(struct urb *urb);
/* Called by the generic read bulk callback */
void (*process_read_urb)(struct urb *urb);
+ /*
+ * Called with port->lock held before preparing another write URB.
+ * Drivers returning false must restart the generic write path when
+ * writes may proceed again.
+ */
+ bool (*write_ready)(struct usb_serial_port *port);
/* Called by the generic write implementation */
int (*prepare_write_buffer)(struct usb_serial_port *port,
void *dest, size_t size);
+ /* Called with port->lock held to roll back a failed write submission */
+ void (*write_rollback)(struct usb_serial_port *port, int count);
};
#define to_usb_serial_driver(d) \
container_of(d, struct usb_serial_driver, driver)
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index 9a1674c152aa..2f3fa2787737 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -8,6 +8,7 @@
* Author: Tom Lyon, pugs@cisco.com
*/
+#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/vfio.h>
@@ -16,6 +17,7 @@
#include <linux/types.h>
#include <linux/uuid.h>
#include <linux/notifier.h>
+#include <linux/pm.h>
#ifndef VFIO_PCI_CORE_H
#define VFIO_PCI_CORE_H
@@ -168,7 +170,6 @@ int vfio_pci_core_init_dev(struct vfio_device *core_vdev);
void vfio_pci_core_release_dev(struct vfio_device *core_vdev);
int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev);
void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev);
-extern const struct pci_error_handlers vfio_pci_core_err_handlers;
int vfio_pci_core_sriov_configure(struct vfio_pci_core_device *vdev,
int nr_virtfn);
long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
@@ -193,8 +194,6 @@ int vfio_pci_core_match_token_uuid(struct vfio_device *core_vdev,
int vfio_pci_core_enable(struct vfio_pci_core_device *vdev);
void vfio_pci_core_disable(struct vfio_pci_core_device *vdev);
void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev);
-pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
- pci_channel_state_t state);
ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
void __iomem *io, char __user *buf,
loff_t off, size_t count, size_t x_start,
@@ -260,4 +259,40 @@ vfio_pci_core_get_iomap(struct vfio_pci_core_device *vdev, unsigned int bar)
int vfio_pci_dma_buf_iommufd_map(struct dma_buf_attachment *attachment,
struct phys_vec *phys);
+int vfio_pci_core_runtime_suspend(struct vfio_pci_core_device *vdev);
+int vfio_pci_core_runtime_resume(struct vfio_pci_core_device *vdev);
+pci_ers_result_t vfio_pci_core_aer_err_detected(struct vfio_pci_core_device *vdev);
+
+/*
+ * Per-driver PM/AER trampolines. driver_data points to the driver's private
+ * structure, which embeds a struct vfio_pci_core_device.
+ *
+ * @name: prefix for <name>_pm_ops and <name>_aer_err_detected
+ * @drv_type: type of the driver's private structure, including struct
+ * @member: member containing the struct vfio_pci_core_device
+ */
+#define VFIO_PCI_CORE_DEFINE_CALLBACKS(name, drv_type, member) \
+static int __maybe_unused name##_pm_suspend(struct device *dev) \
+{ \
+ drv_type *drvdata = dev_get_drvdata(dev); \
+ \
+ return vfio_pci_core_runtime_suspend(&drvdata->member); \
+} \
+static int __maybe_unused name##_pm_resume(struct device *dev) \
+{ \
+ drv_type *drvdata = dev_get_drvdata(dev); \
+ \
+ return vfio_pci_core_runtime_resume(&drvdata->member); \
+} \
+static const struct dev_pm_ops name##_pm_ops = { \
+ SET_RUNTIME_PM_OPS(name##_pm_suspend, name##_pm_resume, NULL) \
+}; \
+static pci_ers_result_t name##_aer_err_detected(struct pci_dev *pdev, \
+ pci_channel_state_t state) \
+{ \
+ drv_type *drvdata = pci_get_drvdata(pdev); \
+ \
+ return vfio_pci_core_aer_err_detected(&drvdata->member); \
+}
+
#endif /* VFIO_PCI_CORE_H */