diff options
Diffstat (limited to 'include/linux')
175 files changed, 4739 insertions, 2297 deletions
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index e7195750d21b..4de81848fe2e 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -90,6 +90,11 @@ ARM_SMCCC_SMC_32, \ 0, 2) +#define ARM_SMCCC_ARCH_SOC_ID64 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + 0, 2) + #define ARM_SMCCC_ARCH_WORKAROUND_1 \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_32, \ diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h index 81e603839c4a..17eca3dfc59e 100644 --- a/include/linux/arm_ffa.h +++ b/include/linux/arm_ffa.h @@ -173,7 +173,7 @@ struct ffa_partition_info; #if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT) struct ffa_device * ffa_device_register(const struct ffa_partition_info *part_info, - const struct ffa_ops *ops); + const struct ffa_ops *ops, struct device *parent); void ffa_device_unregister(struct ffa_device *ffa_dev); int ffa_driver_register(struct ffa_driver *driver, struct module *owner, const char *mod_name); @@ -184,7 +184,7 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev); #else static inline struct ffa_device * ffa_device_register(const struct ffa_partition_info *part_info, - const struct ffa_ops *ops) + const struct ffa_ops *ops, struct device *parent) { return NULL; } diff --git a/include/linux/atalk.h b/include/linux/atalk.h deleted file mode 100644 index a55bfc6567d0..000000000000 --- a/include/linux/atalk.h +++ /dev/null @@ -1,186 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __LINUX_ATALK_H__ -#define __LINUX_ATALK_H__ - - -#include <net/sock.h> -#include <uapi/linux/atalk.h> - -struct atalk_route { - struct net_device *dev; - struct atalk_addr target; - struct atalk_addr gateway; - int flags; - struct atalk_route *next; -}; - -/** - * struct atalk_iface - AppleTalk Interface - * @dev - Network device associated with this interface - * @address - Our address - * @status - What are we doing? - * @nets - Associated direct netrange - * @next - next element in the list of interfaces - */ -struct atalk_iface { - struct net_device *dev; - struct atalk_addr address; - int status; -#define ATIF_PROBE 1 /* Probing for an address */ -#define ATIF_PROBE_FAIL 2 /* Probe collided */ - struct atalk_netrange nets; - struct atalk_iface *next; -}; - -struct atalk_sock { - /* struct sock has to be the first member of atalk_sock */ - struct sock sk; - __be16 dest_net; - __be16 src_net; - unsigned char dest_node; - unsigned char src_node; - unsigned char dest_port; - unsigned char src_port; -}; - -static inline struct atalk_sock *at_sk(struct sock *sk) -{ - return (struct atalk_sock *)sk; -} - -struct ddpehdr { - __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */ - __be16 deh_sum; - __be16 deh_dnet; - __be16 deh_snet; - __u8 deh_dnode; - __u8 deh_snode; - __u8 deh_dport; - __u8 deh_sport; - /* And netatalk apps expect to stick the type in themselves */ -}; - -static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) -{ - return (struct ddpehdr *)skb_transport_header(skb); -} - -/* AppleTalk AARP headers */ -struct elapaarp { - __be16 hw_type; -#define AARP_HW_TYPE_ETHERNET 1 -#define AARP_HW_TYPE_TOKENRING 2 - __be16 pa_type; - __u8 hw_len; - __u8 pa_len; -#define AARP_PA_ALEN 4 - __be16 function; -#define AARP_REQUEST 1 -#define AARP_REPLY 2 -#define AARP_PROBE 3 - __u8 hw_src[ETH_ALEN]; - __u8 pa_src_zero; - __be16 pa_src_net; - __u8 pa_src_node; - __u8 hw_dst[ETH_ALEN]; - __u8 pa_dst_zero; - __be16 pa_dst_net; - __u8 pa_dst_node; -} __attribute__ ((packed)); - -static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb) -{ - return (struct elapaarp *)skb_transport_header(skb); -} - -/* Not specified - how long till we drop a resolved entry */ -#define AARP_EXPIRY_TIME (5 * 60 * HZ) -/* Size of hash table */ -#define AARP_HASH_SIZE 16 -/* Fast retransmission timer when resolving */ -#define AARP_TICK_TIME (HZ / 5) -/* Send 10 requests then give up (2 seconds) */ -#define AARP_RETRANSMIT_LIMIT 10 -/* - * Some value bigger than total retransmit time + a bit for last reply to - * appear and to stop continual requests - */ -#define AARP_RESOLVE_TIME (10 * HZ) - -extern struct datalink_proto *ddp_dl, *aarp_dl; -extern int aarp_proto_init(void); - -/* Inter module exports */ - -/* Give a device find its atif control structure */ -#if IS_ENABLED(CONFIG_ATALK) -static inline struct atalk_iface *atalk_find_dev(struct net_device *dev) -{ - return dev->atalk_ptr; -} -#endif - -extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev); -extern struct net_device *atrtr_get_dev(struct atalk_addr *sa); -extern int aarp_send_ddp(struct net_device *dev, - struct sk_buff *skb, - struct atalk_addr *sa, void *hwaddr); -extern void aarp_device_down(struct net_device *dev); -extern void aarp_probe_network(struct atalk_iface *atif); -extern int aarp_proxy_probe_network(struct atalk_iface *atif, - struct atalk_addr *sa); -extern void aarp_proxy_remove(struct net_device *dev, - struct atalk_addr *sa); - -extern void aarp_cleanup_module(void); - -extern struct hlist_head atalk_sockets; -extern rwlock_t atalk_sockets_lock; - -extern struct atalk_route *atalk_routes; -extern rwlock_t atalk_routes_lock; - -extern struct atalk_iface *atalk_interfaces; -extern rwlock_t atalk_interfaces_lock; - -extern struct atalk_route atrtr_default; - -struct aarp_iter_state { - int bucket; - struct aarp_entry **table; -}; - -extern const struct seq_operations aarp_seq_ops; - -extern int sysctl_aarp_expiry_time; -extern int sysctl_aarp_tick_time; -extern int sysctl_aarp_retransmit_limit; -extern int sysctl_aarp_resolve_time; - -#ifdef CONFIG_SYSCTL -extern int atalk_register_sysctl(void); -extern void atalk_unregister_sysctl(void); -#else -static inline int atalk_register_sysctl(void) -{ - return 0; -} -static inline void atalk_unregister_sysctl(void) -{ -} -#endif - -#ifdef CONFIG_PROC_FS -extern int atalk_proc_init(void); -extern void atalk_proc_exit(void); -#else -static inline int atalk_proc_init(void) -{ - return 0; -} -static inline void atalk_proc_exit(void) -{ -} -#endif /* CONFIG_PROC_FS */ - -#endif /* __LINUX_ATALK_H__ */ diff --git a/include/linux/atm_tcp.h b/include/linux/atm_tcp.h deleted file mode 100644 index 2558439d849b..000000000000 --- a/include/linux/atm_tcp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* atm_tcp.h - Driver-specific declarations of the ATMTCP driver (for use by - driver-specific utilities) */ - -/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */ - -#ifndef LINUX_ATM_TCP_H -#define LINUX_ATM_TCP_H - -#include <uapi/linux/atm_tcp.h> - -struct atm_vcc; -struct module; - -struct atm_tcp_ops { - int (*attach)(struct atm_vcc *vcc,int itf); - int (*create_persistent)(int itf); - int (*remove_persistent)(int itf); - struct module *owner; -}; - -extern struct atm_tcp_ops atm_tcp_ops; - -#endif diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 82a32526df64..fe21d2f547b5 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -51,33 +51,11 @@ enum { driver, cleared by anybody. */ ATM_VF_PARTIAL, /* resources are bound to PVC (partial PVC setup), controlled by socket layer */ - ATM_VF_REGIS, /* registered with demon, controlled by SVC - socket layer */ - ATM_VF_BOUND, /* local SAP is set, controlled by SVC socket - layer */ - ATM_VF_RELEASED, /* demon has indicated/requested release, - controlled by SVC socket layer */ ATM_VF_HASQOS, /* QOS parameters have been set */ - ATM_VF_LISTEN, /* socket is used for listening */ - ATM_VF_META, /* SVC socket isn't used for normal data - traffic and doesn't depend on signaling - to be available */ - ATM_VF_SESSION, /* VCC is p2mp session control descriptor */ - ATM_VF_HASSAP, /* SAP has been set */ - ATM_VF_CLOSE, /* asynchronous close - treat like VF_RELEASED*/ - ATM_VF_WAITING, /* waiting for reply from sigd */ - ATM_VF_IS_CLIP, /* in use by CLIP protocol */ + ATM_VF_CLOSE, /* asynchronous close - VC is being torn down */ }; -#define ATM_VF2VS(flags) \ - (test_bit(ATM_VF_READY,&(flags)) ? ATM_VS_CONNECTED : \ - test_bit(ATM_VF_RELEASED,&(flags)) ? ATM_VS_CLOSING : \ - test_bit(ATM_VF_LISTEN,&(flags)) ? ATM_VS_LISTEN : \ - test_bit(ATM_VF_REGIS,&(flags)) ? ATM_VS_INUSE : \ - test_bit(ATM_VF_BOUND,&(flags)) ? ATM_VS_BOUND : ATM_VS_IDLE) - - enum { ATM_DF_REMOVED, /* device was removed from atm_devs list */ }; @@ -100,26 +78,16 @@ struct atm_vcc { unsigned long atm_options; /* ATM layer options */ struct atm_dev *dev; /* device back pointer */ struct atm_qos qos; /* QOS */ - struct atm_sap sap; /* SAP */ void (*release_cb)(struct atm_vcc *vcc); /* release_sock callback */ void (*push)(struct atm_vcc *vcc,struct sk_buff *skb); void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */ - int (*push_oam)(struct atm_vcc *vcc,void *cell); int (*send)(struct atm_vcc *vcc,struct sk_buff *skb); void *dev_data; /* per-device data */ void *proto_data; /* per-protocol data */ struct k_atm_aal_stats *stats; /* pointer to AAL stats group */ struct module *owner; /* owner of ->push function */ - /* SVC part --- may move later ------------------------------------- */ - short itf; /* interface number */ - struct sockaddr_atmsvc local; - struct sockaddr_atmsvc remote; - /* Multipoint part ------------------------------------------------- */ - struct atm_vcc *session; /* session VCC descriptor */ - /* Other stuff ----------------------------------------------------- */ - void *user_back; /* user backlink - not touched by */ - /* native ATM stack. Currently used */ - /* by CLIP and sch_atm. */ + void *user_back; /* user backlink - not touched by the */ + /* native ATM stack, used by sch_atm */ }; static inline struct atm_vcc *atm_sk(struct sock *sk) @@ -137,31 +105,19 @@ static inline struct sock *sk_atm(struct atm_vcc *vcc) return (struct sock *)vcc; } -struct atm_dev_addr { - struct sockaddr_atmsvc addr; /* ATM address */ - struct list_head entry; /* next address */ -}; - -enum atm_addr_type_t { ATM_ADDR_LOCAL, ATM_ADDR_LECS }; - struct atm_dev { const struct atmdev_ops *ops; /* device operations; NULL if unused */ - const struct atmphy_ops *phy; /* PHY operations, may be undefined */ - /* (NULL) */ const char *type; /* device type name */ int number; /* device index */ void *dev_data; /* per-device data */ void *phy_data; /* private PHY data */ unsigned long flags; /* device flags (ATM_DF_*) */ - struct list_head local; /* local ATM addresses */ - struct list_head lecs; /* LECS ATM addresses learned via ILMI */ unsigned char esi[ESI_LEN]; /* ESI ("MAC" addr) */ struct atm_cirange ci_range; /* VPI/VCI range */ struct k_atm_dev_stats stats; /* statistics */ char signal; /* signal status (ATM_PHY_SIG_*) */ int link_rate; /* link rate (default: OC3) */ refcount_t refcnt; /* reference count */ - spinlock_t lock; /* protect internal members */ #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry; /* proc entry */ char *proc_name; /* proc entry name */ @@ -170,12 +126,6 @@ struct atm_dev { struct list_head dev_list; /* linkage */ }; - -/* OF: send_Oam Flags */ - -#define ATM_OF_IMMED 1 /* Attempt immediate delivery */ -#define ATM_OF_INRATE 2 /* Attempt in-rate delivery */ - struct atmdev_ops { /* only send is required */ void (*dev_close)(struct atm_dev *dev); int (*open)(struct atm_vcc *vcc); @@ -185,25 +135,11 @@ struct atmdev_ops { /* only send is required */ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd, void __user *arg); #endif - int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb); int (*send)(struct atm_vcc *vcc,struct sk_buff *skb); - int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb); - int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags); - void (*phy_put)(struct atm_dev *dev,unsigned char value, - unsigned long addr); - unsigned char (*phy_get)(struct atm_dev *dev,unsigned long addr); - int (*change_qos)(struct atm_vcc *vcc,struct atm_qos *qos,int flags); int (*proc_read)(struct atm_dev *dev,loff_t *pos,char *page); struct module *owner; }; -struct atmphy_ops { - int (*start)(struct atm_dev *dev); - int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void __user *arg); - void (*interrupt)(struct atm_dev *dev); - int (*stop)(struct atm_dev *dev); -}; - struct atm_skb_data { struct atm_vcc *vcc; /* ATM VCC */ unsigned long atm_options; /* ATM layer options */ diff --git a/include/linux/audit.h b/include/linux/audit.h index 803b0183d98d..45abb3722d30 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -133,8 +133,8 @@ enum audit_nfcfgop { AUDIT_NFT_OP_INVALID, }; -extern int __init audit_register_class(int class, unsigned *list); -extern int audit_classify_syscall(int abi, unsigned syscall); +extern int __init audit_register_class(int class, unsigned int *list); +extern int audit_classify_syscall(int abi, unsigned int syscall); extern int audit_classify_arch(int arch); /* audit_names->type values */ diff --git a/include/linux/audit_arch.h b/include/linux/audit_arch.h index 2b8153791e6a..a35069a6c15d 100644 --- a/include/linux/audit_arch.h +++ b/include/linux/audit_arch.h @@ -21,13 +21,13 @@ enum auditsc_class_t { AUDITSC_NVALS /* count */ }; -extern int audit_classify_compat_syscall(int abi, unsigned syscall); +extern int audit_classify_compat_syscall(int abi, unsigned int syscall); /* only for compat system calls */ -extern unsigned compat_write_class[]; -extern unsigned compat_read_class[]; -extern unsigned compat_dir_class[]; -extern unsigned compat_chattr_class[]; -extern unsigned compat_signal_class[]; +extern unsigned int compat_write_class[]; +extern unsigned int compat_read_class[]; +extern unsigned int compat_dir_class[]; +extern unsigned int compat_chattr_class[]; +extern unsigned int compat_signal_class[]; #endif diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 54aeeef1f0ec..14f86e455a67 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h @@ -44,7 +44,7 @@ * FIELD_MODIFY(REG_FIELD_C, ®, c); */ -#define __bf_shf(x) (__builtin_ffsll(x) - 1) +#define __bf_shf __builtin_ctzll #define __scalar_type_to_unsigned_cases(type) \ unsigned type: (unsigned type)0, \ @@ -179,6 +179,22 @@ }) /** + * FIELD_GET_SIGNED() - extract a signed bitfield element + * @mask: shifted mask defining the field's length and position + * @reg: value of entire bitfield + * + * Returns the sign-extended field specified by @_mask from the + * bitfield passed in as @reg by masking and shifting it down. + */ +#define FIELD_GET_SIGNED(mask, reg) \ + ({ \ + __BF_FIELD_CHECK(mask, reg, 0U, "FIELD_GET_SIGNED: "); \ + ((__signed_scalar_typeof(mask)) \ + (((long long)(reg) << __builtin_clzll(mask)) >> \ + (__builtin_clzll(mask) + __builtin_ctzll(mask)))); \ + }) + +/** * FIELD_MODIFY() - modify a bitfield element * @_mask: shifted mask defining the field's length and position * @_reg_p: pointer to the memory that should be updated diff --git a/include/linux/bitmap-str.h b/include/linux/bitmap-str.h index 53d3e1b32d3d..abe7a69a846f 100644 --- a/include/linux/bitmap-str.h +++ b/include/linux/bitmap-str.h @@ -5,7 +5,6 @@ #include <linux/types.h> int bitmap_parse_user(const char __user *ubuf, unsigned int ulen, unsigned long *dst, int nbits); -int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, int nmaskbits); int bitmap_print_bitmask_to_buf(char *buf, const unsigned long *maskp, int nmaskbits, loff_t off, size_t count); int bitmap_print_list_to_buf(char *buf, const unsigned long *maskp, int nmaskbits, diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h index d35b8ec1c485..11620a70e776 100644 --- a/include/linux/bitrev.h +++ b/include/linux/bitrev.h @@ -12,22 +12,10 @@ #define __bitrev8 __arch_bitrev8 #else -extern u8 const byte_rev_table[256]; -static inline u8 __bitrev8(u8 byte) -{ - return byte_rev_table[byte]; -} - -static inline u16 __bitrev16(u16 x) -{ - return (__bitrev8(x & 0xff) << 8) | __bitrev8(x >> 8); -} - -static inline u32 __bitrev32(u32 x) -{ - return (__bitrev16(x & 0xffff) << 16) | __bitrev16(x >> 16); -} - +#include <asm-generic/bitops/__bitrev.h> +#define __bitrev32 generic___bitrev32 +#define __bitrev16 generic___bitrev16 +#define __bitrev8 generic___bitrev8 #endif /* CONFIG_HAVE_ARCH_BITREVERSE */ #define __bitrev8x4(x) (__bitrev32(swab32(x))) diff --git a/include/linux/bootmem_info.h b/include/linux/bootmem_info.h index 492ceeb1cdf8..f724340755e5 100644 --- a/include/linux/bootmem_info.h +++ b/include/linux/bootmem_info.h @@ -82,7 +82,6 @@ static inline void get_page_bootmem(unsigned long info, struct page *page, static inline void free_bootmem_page(struct page *page) { - kmemleak_free_part_phys(PFN_PHYS(page_to_pfn(page)), PAGE_SIZE); free_reserved_page(page); } #endif diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h index b2e79c2b41d5..4d0cc65976a1 100644 --- a/include/linux/bpf-cgroup.h +++ b/include/linux/bpf-cgroup.h @@ -421,7 +421,7 @@ int cgroup_bpf_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype); int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); int cgroup_bpf_prog_query(const union bpf_attr *attr, - union bpf_attr __user *uattr); + union bpf_attr __user *uattr, u32 uattr_size); const struct bpf_func_proto * cgroup_common_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog); @@ -452,7 +452,8 @@ static inline int cgroup_bpf_link_attach(const union bpf_attr *attr, } static inline int cgroup_bpf_prog_query(const union bpf_attr *attr, - union bpf_attr __user *uattr) + union bpf_attr __user *uattr, + u32 uattr_size) { return -EINVAL; } diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 64efc3fdb716..7719f6528445 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -6,6 +6,7 @@ #include <uapi/linux/bpf.h> #include <uapi/linux/filter.h> +#include <linux/bpf_defs.h> #include <crypto/sha2.h> #include <linux/workqueue.h> @@ -32,6 +33,8 @@ #include <linux/memcontrol.h> #include <linux/cfi.h> #include <linux/xattr.h> +#include <linux/key.h> +#include <linux/ftrace.h> #include <asm/rqspinlock.h> struct bpf_verifier_env; @@ -111,7 +114,7 @@ struct bpf_map_ops { long (*map_pop_elem)(struct bpf_map *map, void *value); long (*map_peek_elem)(struct bpf_map *map, void *value); void *(*map_lookup_percpu_elem)(struct bpf_map *map, void *key, u32 cpu); - int (*map_get_hash)(struct bpf_map *map, u32 hash_buf_size, void *hash_buf); + int (*map_get_hash)(struct bpf_map *map); /* funcs called by prog_array and perf_event_array map */ void *(*map_fd_get_ptr)(struct bpf_map *map, struct file *map_file, @@ -296,6 +299,7 @@ struct bpf_map_owner { struct bpf_map { u8 sha[SHA256_DIGEST_SIZE]; + u32 excl; const struct bpf_map_ops *ops; struct bpf_map *inner_map_meta; #ifdef CONFIG_SECURITY @@ -489,6 +493,35 @@ static inline bool btf_record_has_field(const struct btf_record *rec, enum btf_f return rec->field_mask & type; } +static inline bool btf_field_is_nmi_safe(enum btf_field_type type) +{ + switch (type) { + case BPF_SPIN_LOCK: + case BPF_RES_SPIN_LOCK: + case BPF_TIMER: + case BPF_WORKQUEUE: + case BPF_TASK_WORK: + case BPF_KPTR_UNREF: + case BPF_REFCOUNT: + return true; + default: + return false; + } +} + +static inline bool btf_record_has_nmi_unsafe_fields(const struct btf_record *rec) +{ + int i; + + if (IS_ERR_OR_NULL(rec)) + return false; + for (i = 0; i < rec->cnt; i++) { + if (!btf_field_is_nmi_safe(rec->fields[i].type)) + return true; + } + return false; +} + static inline void bpf_obj_init(const struct btf_record *rec, void *obj) { int i; @@ -618,6 +651,8 @@ void bpf_rb_root_free(const struct btf_field *field, void *rb_root, struct bpf_spin_lock *spin_lock); u64 bpf_arena_get_kern_vm_start(struct bpf_arena *arena); u64 bpf_arena_get_user_vm_start(struct bpf_arena *arena); +u64 bpf_arena_map_kern_vm_start(struct bpf_map *map); +struct bpf_map *bpf_prog_arena(struct bpf_prog *prog); int bpf_obj_name_cpy(char *dst, const char *src, unsigned int size); struct bpf_offload_dev; @@ -679,6 +714,8 @@ int bpf_dynptr_from_file_sleepable(struct file *file, u32 flags, void *bpf_arena_alloc_pages_non_sleepable(void *p__map, void *addr__ign, u32 page_cnt, int node_id, u64 flags); void bpf_arena_free_pages_non_sleepable(void *p__map, void *ptr__ign, u32 page_cnt); +void *bpf_arena_alloc_pages_sleepable(void *p__map, void *addr__ign, u32 page_cnt, int node_id, + u64 flags); #else static inline void *bpf_arena_alloc_pages_non_sleepable(void *p__map, void *addr__ign, u32 page_cnt, int node_id, u64 flags) @@ -689,6 +726,12 @@ static inline void *bpf_arena_alloc_pages_non_sleepable(void *p__map, void *addr static inline void bpf_arena_free_pages_non_sleepable(void *p__map, void *ptr__ign, u32 page_cnt) { } + +static inline void *bpf_arena_alloc_pages_sleepable(void *p__map, void *addr__ign, u32 page_cnt, + int node_id, u64 flags) +{ + return NULL; +} #endif extern const struct bpf_map_ops bpf_map_offload_ops; @@ -1052,7 +1095,7 @@ struct bpf_insn_access_aux { struct { struct btf *btf; u32 btf_id; - u32 ref_obj_id; + u32 ref_id; }; }; struct bpf_verifier_log *log; /* for verbose logs */ @@ -1152,6 +1195,11 @@ struct bpf_prog_offload { /* The longest tracepoint has 12 args. * See include/trace/bpf_probe.h + * + * Also reuse this macro for maximum number of arguments a BPF function + * or a kfunc can have. Args 1-5 are passed in registers, args 6-12 via + * stack arg slots. The JIT may map some stack arg slots to registers based + * on the native calling convention (e.g., arg 6 to R9 on x86-64). */ #define MAX_BPF_FUNC_ARGS 12 @@ -1234,9 +1282,9 @@ enum { #define BPF_TRAMP_COOKIE_INDEX_SHIFT 8 #define BPF_TRAMP_IS_RETURN_SHIFT 63 -struct bpf_tramp_links { - struct bpf_tramp_link *links[BPF_MAX_TRAMP_LINKS]; - int nr_links; +struct bpf_tramp_nodes { + struct bpf_tramp_node *nodes[BPF_MAX_TRAMP_LINKS]; + int nr_nodes; }; struct bpf_tramp_run_ctx; @@ -1264,13 +1312,13 @@ struct bpf_tramp_run_ctx; struct bpf_tramp_image; int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image_end, const struct btf_func_model *m, u32 flags, - struct bpf_tramp_links *tlinks, + struct bpf_tramp_nodes *tnodes, void *func_addr); void *arch_alloc_bpf_trampoline(unsigned int size); void arch_free_bpf_trampoline(void *image, unsigned int size); int __must_check arch_protect_bpf_trampoline(void *image, unsigned int size); int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags, - struct bpf_tramp_links *tlinks, void *func_addr); + struct bpf_tramp_nodes *tnodes, void *func_addr); u64 notrace __bpf_prog_enter_sleepable_recur(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx); @@ -1336,8 +1384,6 @@ struct bpf_trampoline { /* hlist for trampoline_ip_table */ struct hlist_node hlist_ip; struct ftrace_ops *fops; - /* serializes access to fields of this trampoline */ - struct mutex mutex; refcount_t refcnt; u32 flags; u64 key; @@ -1358,6 +1404,11 @@ struct bpf_trampoline { int progs_cnt[BPF_TRAMP_MAX]; /* Executable image of trampoline */ struct bpf_tramp_image *cur_image; + /* Used as temporary old image storage for multi_attach */ + struct { + struct bpf_tramp_image *old_image; + u32 old_flags; + } multi_attach; }; struct bpf_attach_target_info { @@ -1455,11 +1506,13 @@ static inline int bpf_dynptr_check_off_len(const struct bpf_dynptr_kern *ptr, u6 return 0; } +struct bpf_tracing_multi_link; + #ifdef CONFIG_BPF_JIT -int bpf_trampoline_link_prog(struct bpf_tramp_link *link, +int bpf_trampoline_link_prog(struct bpf_tramp_node *node, struct bpf_trampoline *tr, struct bpf_prog *tgt_prog); -int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, +int bpf_trampoline_unlink_prog(struct bpf_tramp_node *node, struct bpf_trampoline *tr, struct bpf_prog *tgt_prog); struct bpf_trampoline *bpf_trampoline_get(u64 key, @@ -1467,6 +1520,11 @@ struct bpf_trampoline *bpf_trampoline_get(u64 key, void bpf_trampoline_put(struct bpf_trampoline *tr); int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs); +int bpf_trampoline_multi_attach(struct bpf_prog *prog, u32 *ids, + struct bpf_tracing_multi_link *link); +int bpf_trampoline_multi_detach(struct bpf_prog *prog, + struct bpf_tracing_multi_link *link); + /* * When the architecture supports STATIC_CALL replace the bpf_dispatcher_fn * indirection with a direct call to the bpf program. If the architecture does @@ -1544,14 +1602,15 @@ void bpf_jit_uncharge_modmem(u32 size); bool bpf_prog_has_trampoline(const struct bpf_prog *prog); bool bpf_insn_is_indirect_target(const struct bpf_verifier_env *env, const struct bpf_prog *prog, int insn_idx); +u16 bpf_out_stack_arg_cnt(const struct bpf_verifier_env *env, const struct bpf_prog *prog); #else -static inline int bpf_trampoline_link_prog(struct bpf_tramp_link *link, +static inline int bpf_trampoline_link_prog(struct bpf_tramp_node *node, struct bpf_trampoline *tr, struct bpf_prog *tgt_prog) { return -ENOTSUPP; } -static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, +static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_node *node, struct bpf_trampoline *tr, struct bpf_prog *tgt_prog) { @@ -1578,6 +1637,16 @@ static inline bool bpf_prog_has_trampoline(const struct bpf_prog *prog) { return false; } +static inline int bpf_trampoline_multi_attach(struct bpf_prog *prog, u32 *ids, + struct bpf_tracing_multi_link *link) +{ + return -ENOTSUPP; +} +static inline int bpf_trampoline_multi_detach(struct bpf_prog *prog, + struct bpf_tracing_multi_link *link) +{ + return -ENOTSUPP; +} #endif struct bpf_func_info_aux { @@ -1615,7 +1684,7 @@ struct bpf_ctx_arg_aux { enum bpf_reg_type reg_type; struct btf *btf; u32 btf_id; - u32 ref_obj_id; + u32 ref_id; bool refcounted; }; @@ -1657,6 +1726,19 @@ struct bpf_stream_stage { int len; }; +enum bpf_sig_verdict { + BPF_SIG_UNSIGNED = 0, + BPF_SIG_VERIFIED, +}; + +enum bpf_sig_keyring { + BPF_SIG_KEYRING_NONE = 0, + BPF_SIG_KEYRING_BUILTIN, + BPF_SIG_KEYRING_SECONDARY, + BPF_SIG_KEYRING_PLATFORM, + BPF_SIG_KEYRING_USER, +}; + struct bpf_prog_aux { atomic64_t refcnt; u32 used_map_cnt; @@ -1699,6 +1781,11 @@ struct bpf_prog_aux { bool changes_pkt_data; bool might_sleep; bool kprobe_write_ctx; + struct { + s32 keyring_serial; + u8 keyring_type; + u8 verdict; + } sig; u64 prog_array_member_cnt; /* counts how many times as member of prog_array */ struct mutex ext_mutex; /* mutex for is_extended and prog_array_member_cnt */ struct bpf_arena *arena; @@ -1731,6 +1818,7 @@ struct bpf_prog_aux { struct bpf_map *cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]; char name[BPF_OBJ_NAME_LEN]; u64 (*bpf_exception_cb)(u64 cookie, u64 sp, u64 bp, u64, u64); + u16 stack_arg_sp_adjust; #ifdef CONFIG_SECURITY void *security; #endif @@ -1874,12 +1962,17 @@ struct bpf_link_ops { __poll_t (*poll)(struct file *file, struct poll_table_struct *pts); }; -struct bpf_tramp_link { - struct bpf_link link; +struct bpf_tramp_node { + struct bpf_link *link; struct hlist_node tramp_hlist; u64 cookie; }; +struct bpf_tramp_link { + struct bpf_link link; + struct bpf_tramp_node node; +}; + struct bpf_shim_tramp_link { struct bpf_tramp_link link; struct bpf_trampoline *trampoline; @@ -1887,13 +1980,31 @@ struct bpf_shim_tramp_link { struct bpf_tracing_link { struct bpf_tramp_link link; + struct bpf_tramp_node fexit; struct bpf_trampoline *trampoline; struct bpf_prog *tgt_prog; }; -struct bpf_fsession_link { - struct bpf_tracing_link link; - struct bpf_tramp_link fexit; +struct bpf_tracing_multi_node { + struct bpf_tramp_node node; + struct bpf_trampoline *trampoline; + struct ftrace_func_entry entry; +}; + +struct bpf_tracing_multi_data { + struct ftrace_hash *unreg; + struct ftrace_hash *modify; + struct ftrace_hash *reg; + struct ftrace_func_entry *entry; +}; + +struct bpf_tracing_multi_link { + struct bpf_link link; + struct bpf_tracing_multi_data data; + u64 *cookies; + struct bpf_tramp_node *fexits; + int nodes_cnt; + struct bpf_tracing_multi_node nodes[] __counted_by(nodes_cnt); }; struct bpf_raw_tp_link { @@ -2079,6 +2190,12 @@ static inline void bpf_prog_put_recursion_context(struct bpf_prog *prog) #endif } +static inline bool is_tracing_multi(enum bpf_attach_type type) +{ + return type == BPF_TRACE_FENTRY_MULTI || type == BPF_TRACE_FEXIT_MULTI || + type == BPF_TRACE_FSESSION_MULTI; +} + #if defined(CONFIG_BPF_JIT) && defined(CONFIG_BPF_SYSCALL) /* This macro helps developer to register a struct_ops type and generate * type information correctly. Developers should use this macro to register @@ -2099,8 +2216,8 @@ void bpf_struct_ops_put(const void *kdata); int bpf_struct_ops_supported(const struct bpf_struct_ops *st_ops, u32 moff); int bpf_struct_ops_map_sys_lookup_elem(struct bpf_map *map, void *key, void *value); -int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_links *tlinks, - struct bpf_tramp_link *link, +int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_nodes *tnodes, + struct bpf_tramp_node *node, const struct btf_func_model *model, void *stub_func, void **image, u32 *image_off, @@ -2125,6 +2242,9 @@ int bpf_prog_assoc_struct_ops(struct bpf_prog *prog, struct bpf_map *map); void bpf_prog_disassoc_struct_ops(struct bpf_prog *prog); void *bpf_prog_get_assoc_struct_ops(const struct bpf_prog_aux *aux); u32 bpf_struct_ops_id(const void *kdata); +int bpf_struct_ops_for_each_prog(const void *kdata, + int (*cb)(struct bpf_prog *prog, void *data), + void *data); #ifdef CONFIG_NET /* Define it here to avoid the use of forward declaration */ @@ -2192,31 +2312,33 @@ static inline void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_op #endif -static inline int bpf_fsession_cnt(struct bpf_tramp_links *links) +static inline int bpf_fsession_cnt(struct bpf_tramp_nodes *nodes) { - struct bpf_tramp_links fentries = links[BPF_TRAMP_FENTRY]; + struct bpf_tramp_nodes fentries = nodes[BPF_TRAMP_FENTRY]; int cnt = 0; - for (int i = 0; i < links[BPF_TRAMP_FENTRY].nr_links; i++) { - if (fentries.links[i]->link.prog->expected_attach_type == BPF_TRACE_FSESSION) + for (int i = 0; i < nodes[BPF_TRAMP_FENTRY].nr_nodes; i++) { + if (fentries.nodes[i]->link->prog->expected_attach_type == BPF_TRACE_FSESSION) + cnt++; + if (fentries.nodes[i]->link->prog->expected_attach_type == BPF_TRACE_FSESSION_MULTI) cnt++; } return cnt; } -static inline bool bpf_prog_calls_session_cookie(struct bpf_tramp_link *link) +static inline bool bpf_prog_calls_session_cookie(struct bpf_tramp_node *node) { - return link->link.prog->call_session_cookie; + return node->link->prog->call_session_cookie; } -static inline int bpf_fsession_cookie_cnt(struct bpf_tramp_links *links) +static inline int bpf_fsession_cookie_cnt(struct bpf_tramp_nodes *nodes) { - struct bpf_tramp_links fentries = links[BPF_TRAMP_FENTRY]; + struct bpf_tramp_nodes fentries = nodes[BPF_TRAMP_FENTRY]; int cnt = 0; - for (int i = 0; i < links[BPF_TRAMP_FENTRY].nr_links; i++) { - if (bpf_prog_calls_session_cookie(fentries.links[i])) + for (int i = 0; i < nodes[BPF_TRAMP_FENTRY].nr_nodes; i++) { + if (bpf_prog_calls_session_cookie(fentries.nodes[i])) cnt++; } @@ -2598,6 +2720,7 @@ bool btf_record_equal(const struct btf_record *rec_a, const struct btf_record *r void bpf_obj_free_timer(const struct btf_record *rec, void *obj); void bpf_obj_free_workqueue(const struct btf_record *rec, void *obj); void bpf_obj_free_task_work(const struct btf_record *rec, void *obj); +void bpf_obj_cancel_fields(struct bpf_map *map, void *obj); void bpf_obj_free_fields(const struct btf_record *rec, void *obj); void __bpf_obj_drop_impl(void *p, const struct btf_record *rec, bool percpu); @@ -2764,6 +2887,9 @@ void bpf_link_init(struct bpf_link *link, enum bpf_link_type type, void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_type type, const struct bpf_link_ops *ops, struct bpf_prog *prog, enum bpf_attach_type attach_type, bool sleepable); +void bpf_tramp_link_init(struct bpf_tramp_link *link, enum bpf_link_type type, + const struct bpf_link_ops *ops, struct bpf_prog *prog, + enum bpf_attach_type attach_type, u64 cookie); int bpf_link_prime(struct bpf_link *link, struct bpf_link_primer *primer); int bpf_link_settle(struct bpf_link_primer *primer); void bpf_link_cleanup(struct bpf_link_primer *primer); @@ -2917,7 +3043,9 @@ int bpf_check_uarg_tail_zero(bpfptr_t uaddr, size_t expected_size, size_t actual_size); /* verify correctness of eBPF program */ -int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size); +struct bpf_log_attr; +int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, + struct bpf_log_attr *attr_log); #ifndef CONFIG_BPF_JIT_ALWAYS_ON int bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth); @@ -3088,6 +3216,56 @@ void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr); void bpf_dynptr_set_rdonly(struct bpf_dynptr_kern *ptr); void bpf_prog_report_arena_violation(bool write, unsigned long addr, unsigned long fault_ip); +static __always_inline u32 +bpf_prog_run_array_sleepable(const struct bpf_prog_array *array, + const void *ctx, bpf_prog_run_fn run_prog) +{ + const struct bpf_prog_array_item *item; + struct bpf_prog *prog; + struct bpf_run_ctx *old_run_ctx; + struct bpf_trace_run_ctx run_ctx; + u32 ret = 1; + + if (unlikely(!array)) + return ret; + + migrate_disable(); + + run_ctx.is_uprobe = false; + + old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); + item = &array->items[0]; + while ((prog = READ_ONCE(item->prog))) { + /* Skip dummy_bpf_prog placeholder (len == 0) */ + if (unlikely(!prog->len)) { + item++; + continue; + } + + if (unlikely(!bpf_prog_get_recursion_context(prog))) { + bpf_prog_inc_misses_counter(prog); + bpf_prog_put_recursion_context(prog); + item++; + continue; + } + + run_ctx.bpf_cookie = item->bpf_cookie; + + if (!prog->sleepable) { + guard(rcu)(); + ret &= run_prog(prog, ctx); + } else { + ret &= run_prog(prog, ctx); + } + + bpf_prog_put_recursion_context(prog); + item++; + } + bpf_reset_run_ctx(old_run_ctx); + migrate_enable(); + return ret; +} + #else /* !CONFIG_BPF_SYSCALL */ static inline struct bpf_prog *bpf_prog_get(u32 ufd) { @@ -3135,6 +3313,12 @@ static inline void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_ { } +static inline void bpf_tramp_link_init(struct bpf_tramp_link *link, enum bpf_link_type type, + const struct bpf_link_ops *ops, struct bpf_prog *prog, + enum bpf_attach_type attach_type, u64 cookie) +{ +} + static inline int bpf_link_prime(struct bpf_link *link, struct bpf_link_primer *primer) { @@ -3626,15 +3810,25 @@ static inline int bpf_fd_reuseport_array_update_elem(struct bpf_map *map, #endif /* CONFIG_BPF_SYSCALL */ #endif /* defined(CONFIG_INET) && defined(CONFIG_BPF_SYSCALL) */ -#if defined(CONFIG_KEYS) && defined(CONFIG_BPF_SYSCALL) +#ifdef CONFIG_KEYS +struct bpf_key { + struct key *key; + bool has_ref; +}; +#endif /* CONFIG_KEYS */ +#if defined(CONFIG_KEYS) && defined(CONFIG_BPF_SYSCALL) struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags); struct bpf_key *bpf_lookup_system_key(u64 id); void bpf_key_put(struct bpf_key *bkey); -int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_p, - struct bpf_dynptr *sig_p, +int bpf_verify_pkcs7_signature(const struct bpf_dynptr *data_p, + const struct bpf_dynptr *sig_p, struct bpf_key *trusted_keyring); +static inline s32 bpf_key_serial(const struct bpf_key *key) +{ + return key->has_ref ? key->key->serial : 0; +} #else static inline struct bpf_key *bpf_lookup_user_key(u32 serial, u64 flags) { @@ -3650,12 +3844,17 @@ static inline void bpf_key_put(struct bpf_key *bkey) { } -static inline int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_p, - struct bpf_dynptr *sig_p, +static inline int bpf_verify_pkcs7_signature(const struct bpf_dynptr *data_p, + const struct bpf_dynptr *sig_p, struct bpf_key *trusted_keyring) { return -EOPNOTSUPP; } + +static inline s32 bpf_key_serial(const struct bpf_key *key) +{ + return 0; +} #endif /* defined(CONFIG_KEYS) && defined(CONFIG_BPF_SYSCALL) */ /* verifier prototypes for helper functions called from eBPF programs */ @@ -3931,15 +4130,6 @@ static inline void bpf_cgroup_atype_get(u32 attach_btf_id, int cgroup_atype) {} static inline void bpf_cgroup_atype_put(int cgroup_atype) {} #endif /* CONFIG_BPF_LSM */ -struct key; - -#ifdef CONFIG_KEYS -struct bpf_key { - struct key *key; - bool has_ref; -}; -#endif /* CONFIG_KEYS */ - static inline bool type_is_alloc(u32 type) { return type & MEM_ALLOC; diff --git a/include/linux/bpf_defs.h b/include/linux/bpf_defs.h new file mode 100644 index 000000000000..2185cd3966d4 --- /dev/null +++ b/include/linux/bpf_defs.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Subset of bpf.h declarations, split out so files that need only these + * declarations can avoid bpf.h's full include cost. + */ +#ifndef _LINUX_BPF_DEFS_H +#define _LINUX_BPF_DEFS_H + +#ifdef CONFIG_BPF_SYSCALL +bool bpf_arena_handle_page_fault(unsigned long addr, bool is_write, unsigned long fault_ip); +#else +static inline bool bpf_arena_handle_page_fault(unsigned long addr, bool is_write, + unsigned long fault_ip) +{ + return false; +} +#endif + +#endif /* _LINUX_BPF_DEFS_H */ diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h index 643809cc78c3..143775a27a2a 100644 --- a/include/linux/bpf_lsm.h +++ b/include/linux/bpf_lsm.h @@ -52,6 +52,7 @@ int bpf_set_dentry_xattr_locked(struct dentry *dentry, const char *name__str, const struct bpf_dynptr *value_p, int flags); int bpf_remove_dentry_xattr_locked(struct dentry *dentry, const char *name__str); bool bpf_lsm_has_d_inode_locked(const struct bpf_prog *prog); +bool bpf_lsm_hook_returns_errno(u32 btf_id); #else /* !CONFIG_BPF_LSM */ @@ -104,6 +105,11 @@ static inline bool bpf_lsm_has_d_inode_locked(const struct bpf_prog *prog) { return false; } + +static inline bool bpf_lsm_hook_returns_errno(u32 btf_id) +{ + return true; +} #endif /* CONFIG_BPF_LSM */ #endif /* _LINUX_BPF_LSM_H */ diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h index b13de31e163f..e5906829aa6f 100644 --- a/include/linux/bpf_types.h +++ b/include/linux/bpf_types.h @@ -134,6 +134,7 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_BLOOM_FILTER, bloom_filter_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_USER_RINGBUF, user_ringbuf_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_ARENA, arena_map_ops) BPF_MAP_TYPE(BPF_MAP_TYPE_INSN_ARRAY, insn_array_map_ops) +BPF_MAP_TYPE(BPF_MAP_TYPE_RHASH, rhtab_map_ops) BPF_LINK_TYPE(BPF_LINK_TYPE_RAW_TRACEPOINT, raw_tracepoint) BPF_LINK_TYPE(BPF_LINK_TYPE_TRACING, tracing) @@ -155,3 +156,4 @@ BPF_LINK_TYPE(BPF_LINK_TYPE_PERF_EVENT, perf) BPF_LINK_TYPE(BPF_LINK_TYPE_KPROBE_MULTI, kprobe_multi) BPF_LINK_TYPE(BPF_LINK_TYPE_STRUCT_OPS, struct_ops) BPF_LINK_TYPE(BPF_LINK_TYPE_UPROBE_MULTI, uprobe_multi) +BPF_LINK_TYPE(BPF_LINK_TYPE_TRACING_MULTI, tracing_multi) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 185b2aa43a42..39a851e690ec 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -8,6 +8,7 @@ #include <linux/btf.h> /* for struct btf and btf_id() */ #include <linux/filter.h> /* for MAX_BPF_STACK */ #include <linux/tnum.h> +#include <linux/cnum.h> /* Maximum variable offset umax_value permitted when resolving memory accesses. * In practice this is far bigger than any realistic pointer offset; this limit @@ -65,7 +66,6 @@ struct bpf_reg_state { struct { /* for PTR_TO_MEM | PTR_TO_MEM_OR_NULL */ u32 mem_size; - u32 dynptr_id; /* for dynptr slices */ }; /* For dynptr stack slots */ @@ -120,14 +120,8 @@ struct bpf_reg_state { * These refer to the same value as var_off, not necessarily the actual * contents of the register. */ - s64 smin_value; /* minimum possible (s64)value */ - s64 smax_value; /* maximum possible (s64)value */ - u64 umin_value; /* minimum possible (u64)value */ - u64 umax_value; /* maximum possible (u64)value */ - s32 s32_min_value; /* minimum possible (s32)value */ - s32 s32_max_value; /* maximum possible (s32)value */ - u32 u32_min_value; /* minimum possible (u32)value */ - u32 u32_max_value; /* maximum possible (u32)value */ + struct cnum64 r64; /* 64-bit range as circular number */ + struct cnum32 r32; /* 32-bit range as circular number */ /* 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 @@ -153,46 +147,14 @@ struct bpf_reg_state { #define BPF_ADD_CONST32 (1U << 30) #define BPF_ADD_CONST (BPF_ADD_CONST64 | BPF_ADD_CONST32) u32 id; - /* PTR_TO_SOCKET and PTR_TO_TCP_SOCK could be a ptr returned - * from a pointer-cast helper, bpf_sk_fullsock() and - * bpf_tcp_sock(). - * - * Consider the following where "sk" is a reference counted - * pointer returned from "sk = bpf_sk_lookup_tcp();": - * - * 1: sk = bpf_sk_lookup_tcp(); - * 2: if (!sk) { return 0; } - * 3: fullsock = bpf_sk_fullsock(sk); - * 4: if (!fullsock) { bpf_sk_release(sk); return 0; } - * 5: tp = bpf_tcp_sock(fullsock); - * 6: if (!tp) { bpf_sk_release(sk); return 0; } - * 7: bpf_sk_release(sk); - * 8: snd_cwnd = tp->snd_cwnd; // verifier will complain - * - * After bpf_sk_release(sk) at line 7, both "fullsock" ptr and - * "tp" ptr should be invalidated also. In order to do that, - * the reg holding "fullsock" and "sk" need to remember - * the original refcounted ptr id (i.e. sk_reg->id) in ref_obj_id - * such that the verifier can reset all regs which have - * ref_obj_id matching the sk_reg->id. - * - * sk_reg->ref_obj_id is set to sk_reg->id at line 1. - * sk_reg->id will stay as NULL-marking purpose only. - * After NULL-marking is done, sk_reg->id can be reset to 0. - * - * After "fullsock = bpf_sk_fullsock(sk);" at line 3, - * fullsock_reg->ref_obj_id is set to sk_reg->ref_obj_id. - * - * After "tp = bpf_tcp_sock(fullsock);" at line 5, - * tp_reg->ref_obj_id is set to fullsock_reg->ref_obj_id - * which is the same as sk_reg->ref_obj_id. - * - * From the verifier perspective, if sk, fullsock and tp - * are not NULL, they are the same ptr with different - * reg->type. In particular, bpf_sk_release(tp) is also - * allowed and has the same effect as bpf_sk_release(sk). + /* + * Tracks the parent object this register was derived from. + * Used for cascading invalidation: when the parent object is + * released or invalidated, all registers with matching parent_id + * are also invalidated. For example, a slice from bpf_dynptr_data() + * gets parent_id set to the dynptr's id. */ - u32 ref_obj_id; + u32 parent_id; /* Inside the callee two registers can be both PTR_TO_STACK like * R1=fp-8 and R2=fp-8, but one of them points to this function stack * while another to the caller's stack. To differentiate them 'frameno' @@ -209,6 +171,66 @@ struct bpf_reg_state { bool precise; }; +static inline s64 reg_smin(const struct bpf_reg_state *reg) +{ + return cnum64_smin(reg->r64); +} + +static inline s64 reg_smax(const struct bpf_reg_state *reg) +{ + return cnum64_smax(reg->r64); +} + +static inline u64 reg_umin(const struct bpf_reg_state *reg) +{ + return cnum64_umin(reg->r64); +} + +static inline u64 reg_umax(const struct bpf_reg_state *reg) +{ + return cnum64_umax(reg->r64); +} + +static inline s32 reg_s32_min(const struct bpf_reg_state *reg) +{ + return cnum32_smin(reg->r32); +} + +static inline s32 reg_s32_max(const struct bpf_reg_state *reg) +{ + return cnum32_smax(reg->r32); +} + +static inline u32 reg_u32_min(const struct bpf_reg_state *reg) +{ + return cnum32_umin(reg->r32); +} + +static inline u32 reg_u32_max(const struct bpf_reg_state *reg) +{ + return cnum32_umax(reg->r32); +} + +static inline void reg_set_srange32(struct bpf_reg_state *reg, s32 smin, s32 smax) +{ + reg->r32 = cnum32_from_srange(smin, smax); +} + +static inline void reg_set_urange32(struct bpf_reg_state *reg, u32 umin, u32 umax) +{ + reg->r32 = cnum32_from_urange(umin, umax); +} + +static inline void reg_set_srange64(struct bpf_reg_state *reg, s64 smin, s64 smax) +{ + reg->r64 = cnum64_from_srange(smin, smax); +} + +static inline void reg_set_urange64(struct bpf_reg_state *reg, u64 umin, u64 umax) +{ + reg->r64 = cnum64_from_urange(umin, umax); +} + enum bpf_stack_slot_type { STACK_INVALID, /* nothing was stored in this stack slot */ STACK_SPILL, /* register spilled into stack */ @@ -309,10 +331,14 @@ struct bpf_reference_state { * is used purely to inform the user of a reference leak. */ int insn_idx; - /* Use to keep track of the source object of a lock, to ensure - * it matches on unlock. - */ - void *ptr; + union { + /* For REF_TYPE_PTR */ + int parent_id; + /* Use to keep track of the source object of a lock, to ensure + * it matches on unlock. + */ + void *ptr; + }; }; struct bpf_retval_range { @@ -347,6 +373,7 @@ struct bpf_func_state { bool in_callback_fn; bool in_async_callback_fn; bool in_exception_callback_fn; + bool no_stack_arg_load; /* For callback calling functions that limit number of possible * callback executions (e.g. bpf_loop) keeps track of current * simulated iteration number. @@ -372,46 +399,49 @@ struct bpf_func_state { * `stack`. allocated_stack is always a multiple of BPF_REG_SIZE. */ int allocated_stack; + + u16 out_stack_arg_cnt; /* Number of outgoing on-stack argument slots */ + struct bpf_reg_state *stack_arg_regs; /* Outgoing on-stack arguments */ }; -#define MAX_CALL_FRAMES 8 +#define MAX_CALL_FRAMES 16 -/* instruction history flags, used in bpf_jmp_history_entry.flags field */ +/* instruction history flags, used in bpf_jmp_history_entry.flags field. + * Frame number and SPI are stored in dedicated fields of bpf_jmp_history_entry. + */ enum { - /* instruction references stack slot through PTR_TO_STACK register; - * we also store stack's frame number in lower 3 bits (MAX_CALL_FRAMES is 8) - * and accessed stack slot's index in next 6 bits (MAX_BPF_STACK is 512, - * 8 bytes per slot, so slot index (spi) is [0, 63]) - */ - INSN_F_FRAMENO_MASK = 0x7, /* 3 bits */ - - INSN_F_SPI_MASK = 0x3f, /* 6 bits */ - INSN_F_SPI_SHIFT = 3, /* shifted 3 bits to the left */ + INSN_F_STACK_ACCESS = BIT(0), - INSN_F_STACK_ACCESS = BIT(9), + INSN_F_DST_REG_STACK = BIT(1), /* dst_reg is PTR_TO_STACK */ + INSN_F_SRC_REG_STACK = BIT(2), /* src_reg is PTR_TO_STACK */ - INSN_F_DST_REG_STACK = BIT(10), /* dst_reg is PTR_TO_STACK */ - INSN_F_SRC_REG_STACK = BIT(11), /* src_reg is PTR_TO_STACK */ - /* total 12 bits are used now. */ + INSN_F_STACK_ARG_ACCESS = BIT(3), }; -static_assert(INSN_F_FRAMENO_MASK + 1 >= MAX_CALL_FRAMES); -static_assert(INSN_F_SPI_MASK + 1 >= MAX_BPF_STACK / 8); - struct bpf_jmp_history_entry { - u32 idx; /* insn idx can't be bigger than 1 million */ + u32 idx : 20; + u32 frame : 4; /* stack access frame number */ + u32 spi : 6; /* stack slot index (0..63) */ + u32 : 2; u32 prev_idx : 20; /* special INSN_F_xxx flags */ - u32 flags : 12; - /* additional registers that need precision tracking when this - * jump is backtracked, vector of six 10-bit records + u32 flags : 4; + u32 : 8; + /* + * additional registers that need precision tracking when this + * jump is backtracked, vector of five 11-bit records */ u64 linked_regs; }; -/* Maximum number of register states that can exist at once */ -#define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE) * MAX_CALL_FRAMES) +static_assert(MAX_CALL_FRAMES <= (1 << 4)); +static_assert(MAX_BPF_STACK / 8 <= (1 << 6)); + +/* Maximum number of bpf_reg_state objects that can exist at once */ +#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 / BPF_REG_SIZE + \ + MAX_STACK_ARG_SLOTS) * MAX_CALL_FRAMES) struct bpf_verifier_state { /* call stack tracking */ struct bpf_func_state *frame[MAX_CALL_FRAMES]; @@ -497,10 +527,23 @@ struct bpf_verifier_state { u32 may_goto_depth; }; -#define bpf_get_spilled_reg(slot, frame, mask) \ - (((slot < frame->allocated_stack / BPF_REG_SIZE) && \ - ((1 << frame->stack[slot].slot_type[BPF_REG_SIZE - 1]) & (mask))) \ - ? &frame->stack[slot].spilled_ptr : NULL) +static inline struct bpf_reg_state * +bpf_get_spilled_reg(int slot, struct bpf_func_state *frame, u32 mask) +{ + if (slot < frame->allocated_stack / BPF_REG_SIZE && + (1 << frame->stack[slot].slot_type[BPF_REG_SIZE - 1]) & mask) + return &frame->stack[slot].spilled_ptr; + return NULL; +} + +static inline struct bpf_reg_state * +bpf_get_spilled_stack_arg(int slot, struct bpf_func_state *frame) +{ + if (slot < frame->out_stack_arg_cnt && + frame->stack_arg_regs[slot].type != NOT_INIT) + return &frame->stack_arg_regs[slot]; + return NULL; +} /* Iterate over 'frame', setting 'reg' to either NULL or a spilled register. */ #define bpf_for_each_spilled_reg(iter, frame, reg, mask) \ @@ -508,7 +551,13 @@ struct bpf_verifier_state { iter < frame->allocated_stack / BPF_REG_SIZE; \ iter++, reg = bpf_get_spilled_reg(iter, frame, mask)) -#define bpf_for_each_reg_in_vstate_mask(__vst, __state, __reg, __mask, __expr) \ +/* Iterate over 'frame', setting 'reg' to either NULL or a spilled stack arg. */ +#define bpf_for_each_spilled_stack_arg(iter, frame, reg) \ + for (iter = 0, reg = bpf_get_spilled_stack_arg(iter, frame); \ + iter < frame->out_stack_arg_cnt; \ + iter++, reg = bpf_get_spilled_stack_arg(iter, frame)) + +#define bpf_for_each_reg_in_vstate_mask(__vst, __state, __reg, __stack, __mask, __expr) \ ({ \ struct bpf_verifier_state *___vstate = __vst; \ int ___i, ___j; \ @@ -516,6 +565,7 @@ struct bpf_verifier_state { struct bpf_reg_state *___regs; \ __state = ___vstate->frame[___i]; \ ___regs = __state->regs; \ + __stack = NULL; \ for (___j = 0; ___j < MAX_BPF_REG; ___j++) { \ __reg = &___regs[___j]; \ (void)(__expr); \ @@ -523,14 +573,27 @@ struct bpf_verifier_state { bpf_for_each_spilled_reg(___j, __state, __reg, __mask) { \ if (!__reg) \ continue; \ + __stack = &__state->stack[___j]; \ (void)(__expr); \ } \ + __stack = NULL; \ + bpf_for_each_spilled_stack_arg(___j, __state, __reg) { \ + if (!__reg) \ + continue; \ + (void)(__expr); \ + } \ } \ + (void)__stack; \ }) /* Invoke __expr over regsiters in __vst, setting __state and __reg */ -#define bpf_for_each_reg_in_vstate(__vst, __state, __reg, __expr) \ - bpf_for_each_reg_in_vstate_mask(__vst, __state, __reg, 1 << STACK_SPILL, __expr) +#define bpf_for_each_reg_in_vstate(__vst, __state, __reg, __expr) \ + ({ \ + struct bpf_stack_state * ___stack; \ + (void)___stack; \ + bpf_for_each_reg_in_vstate_mask(__vst, __state, __reg, ___stack,\ + 1 << STACK_SPILL, __expr); \ + }) /* linked list of verifier states used to prune search */ struct bpf_verifier_state_list { @@ -700,6 +763,22 @@ static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log) return log && log->level; } +struct bpf_log_attr { + char __user *ubuf; + u32 size; + u32 level; + u32 offsetof_true_size; + bpfptr_t uattr; +}; + +int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size, u32 log_level, + u32 offsetof_log_true_size, bpfptr_t uattr, struct bpf_common_attr *common, + bpfptr_t uattr_common, u32 size_common); +struct bpf_verifier_log *bpf_log_attr_create_vlog(struct bpf_log_attr *attr_log, + struct bpf_common_attr *common, bpfptr_t uattr, + u32 size); +int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *log); + #define BPF_MAX_SUBPROGS 256 struct bpf_subprog_arg_info { @@ -724,6 +803,7 @@ struct bpf_subprog_info { u32 exit_idx; /* Index of one of the BPF_EXIT instructions in this subprogram */ u16 stack_depth; /* max. stack depth used by this function */ u16 stack_extra; + u32 insn_processed; /* offsets in range [stack_depth .. fastcall_stack_off) * are used for bpf_fastcall spills and fills. */ @@ -740,12 +820,21 @@ struct bpf_subprog_info { bool keep_fastcall_stack: 1; bool changes_pkt_data: 1; bool might_sleep: 1; - u8 arg_cnt:3; + u8 arg_cnt:4; enum priv_stack_mode priv_stack_mode; - struct bpf_subprog_arg_info args[MAX_BPF_FUNC_REG_ARGS]; + struct bpf_subprog_arg_info args[MAX_BPF_FUNC_ARGS]; + u16 stack_arg_cnt; /* incoming + max outgoing */ + u16 max_out_stack_arg_cnt; }; +static inline u16 bpf_in_stack_arg_cnt(const struct bpf_subprog_info *sub) +{ + if (sub->arg_cnt > MAX_BPF_FUNC_REG_ARGS) + return sub->arg_cnt - MAX_BPF_FUNC_REG_ARGS; + return 0; +} + struct bpf_verifier_env; struct backtrack_state { @@ -753,6 +842,7 @@ struct backtrack_state { u32 frame; u32 reg_masks[MAX_CALL_FRAMES]; u64 stack_masks[MAX_CALL_FRAMES]; + u8 stack_arg_masks[MAX_CALL_FRAMES]; }; struct bpf_id_pair { @@ -881,6 +971,8 @@ struct bpf_verifier_env { u32 prev_insn_processed, insn_processed; /* number of jmps, calls, exits analyzed so far */ u32 prev_jmps_processed, jmps_processed; + /* maximum combined stack depth */ + u32 max_stack_depth; /* total verification time */ u64 verification_time; /* maximum number of verifier states kept in 'branching' instructions */ @@ -914,6 +1006,7 @@ struct bpf_verifier_env { * e.g., in reg_type_str() to generate reg_type string */ char tmp_str_buf[TMP_STR_BUF_LEN]; + char tmp_arg_name[32]; struct bpf_insn insn_buf[INSN_BUF_SIZE]; struct bpf_insn epilogue_buf[INSN_BUF_SIZE]; struct bpf_scc_callchain callchain_buf; @@ -1087,7 +1180,7 @@ struct list_head *bpf_explored_state(struct bpf_verifier_env *env, int idx); void bpf_free_verifier_state(struct bpf_verifier_state *state, bool free_self); void bpf_free_backedges(struct bpf_scc_visit *visit); int bpf_push_jmp_history(struct bpf_verifier_env *env, struct bpf_verifier_state *cur, - int insn_flags, u64 linked_regs); + int insn_flags, int spi, int frame, u64 linked_regs); 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); @@ -1150,6 +1243,11 @@ static inline void bpf_bt_set_frame_slot(struct backtrack_state *bt, u32 frame, bt->stack_masks[frame] |= 1ull << slot; } +static inline void bt_set_frame_stack_arg_slot(struct backtrack_state *bt, u32 frame, u32 slot) +{ + bt->stack_arg_masks[frame] |= 1 << slot; +} + static inline bool bt_is_frame_reg_set(struct backtrack_state *bt, u32 frame, u32 reg) { return bt->reg_masks[frame] & (1 << reg); @@ -1321,6 +1419,25 @@ struct bpf_map_desc { int uid; }; +/* The last initialized dynptr; Populated by process_dynptr_func() */ +struct bpf_dynptr_desc { + enum bpf_dynptr_type type; + u32 id; + u32 parent_id; +}; + +/* + * The last seen rereferenced object; Updated by update_ref_obj() when a register refers to a + * referenced object. Used when the helper or kfunc is casting a referenced object, returning + * allocated memory derived from referenced object or creating a dynptr with a referenced + * object as parent. + */ +struct ref_obj_desc { + u32 id; + u32 parent_id; + u8 cnt; +}; + struct bpf_kfunc_call_arg_meta { /* In parameters */ struct btf *btf; @@ -1329,7 +1446,6 @@ struct bpf_kfunc_call_arg_meta { const struct btf_type *func_proto; const char *func_name; /* Out parameters */ - u32 ref_obj_id; u8 release_regno; bool r0_rdonly; u32 ret_btf_id; @@ -1362,15 +1478,12 @@ struct bpf_kfunc_call_arg_meta { struct btf_field *field; } arg_rbtree_root; struct { - enum bpf_dynptr_type type; - u32 id; - u32 ref_obj_id; - } initialized_dynptr; - struct { u8 spi; u8 frameno; } iter; struct bpf_map_desc map; + struct bpf_dynptr_desc dynptr; + struct ref_obj_desc ref_obj; u64 mem_size; }; @@ -1479,6 +1592,10 @@ int bpf_add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, u16 offset); int bpf_fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, struct bpf_insn *insn_buf, int insn_idx, int *cnt); +/* Functions exported from verifier.c, used by trampoline.c */ +int bpf_check_attach_btf_id_multi(struct btf *btf, struct bpf_prog *prog, u32 btf_id, + struct bpf_attach_target_info *tgt_info); + /* Functions in fixups.c, called from bpf_check() */ int bpf_remove_fastcall_spills_fills(struct bpf_verifier_env *env); int bpf_optimize_bpf_loop(struct bpf_verifier_env *env); diff --git a/include/linux/btf.h b/include/linux/btf.h index 48108471c5b1..240401d9b25b 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -145,7 +145,8 @@ const char *btf_get_name(const struct btf *btf); void btf_get(struct btf *btf); void btf_put(struct btf *btf); const struct btf_header *btf_header(const struct btf *btf); -int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz); +struct bpf_log_attr; +int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_attr *attr_log); struct btf *btf_get_by_fd(int fd); int btf_get_info_by_fd(const struct btf *btf, const union bpf_attr *attr, @@ -415,12 +416,12 @@ static inline bool btf_type_is_array(const struct btf_type *t) return BTF_INFO_KIND(t->info) == BTF_KIND_ARRAY; } -static inline u16 btf_type_vlen(const struct btf_type *t) +static inline u32 btf_type_vlen(const struct btf_type *t) { return BTF_INFO_VLEN(t->info); } -static inline u16 btf_vlen(const struct btf_type *t) +static inline u32 btf_vlen(const struct btf_type *t) { return btf_type_vlen(t); } diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h index af011db39ab3..8b5a9ee92513 100644 --- a/include/linux/btf_ids.h +++ b/include/linux/btf_ids.h @@ -284,5 +284,6 @@ extern u32 bpf_cgroup_btf_id[]; extern u32 bpf_local_storage_map_btf_id[]; extern u32 btf_bpf_map_id[]; extern u32 bpf_kmem_cache_btf_id[]; +extern u32 bpf_multi_func_btf_id[]; #endif diff --git a/include/linux/call_once.h b/include/linux/call_once.h index 13cd6469e7e5..1625a9d6ff5b 100644 --- a/include/linux/call_once.h +++ b/include/linux/call_once.h @@ -36,7 +36,7 @@ do { \ * it returns a zero or positive value, mark @once as completed. Return * the value returned by @cb * - * If @once has completed succesfully before, return 0. + * If @once has completed successfully before, return 0. * * The call to @cb is implicitly surrounded by a mutex, though for * efficiency the * function avoids taking it after the first call. diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 50a784da7a81..de2cd6238c2a 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -254,6 +254,18 @@ struct cgroup_subsys_state { int nr_descendants; /* + * Hierarchical populated state. For cgroup->self, nr_populated_csets + * counts populated csets linked via cgrp_cset_link. + * nr_populated_children counts immediate-child csses whose own + * populated state is nonzero. Protected by css_set_lock. + */ + int nr_populated_csets; + int nr_populated_children; + + /* deferred kill_css_finish() queued by css_update_populated() */ + struct work_struct kill_finish_work; + + /* * A singly-linked list of css structures to be rstat flushed. * This is a scratch field to be used exclusively by * css_rstat_flush(). @@ -504,17 +516,12 @@ struct cgroup { int max_descendants; /* - * Each non-empty css_set associated with this cgroup contributes - * one to nr_populated_csets. The counter is zero iff this cgroup - * doesn't have any tasks. - * - * All children which have non-zero nr_populated_csets and/or - * nr_populated_children of their own contribute one to either - * nr_populated_domain_children or nr_populated_threaded_children - * depending on their type. Each counter is zero iff all cgroups - * of the type in the subtree proper don't have any tasks. + * Domain/threaded split of self.nr_populated_children: each counts + * immediate-child cgroups whose subtree is populated and sums to + * self.nr_populated_children. Kept as separate fields to allow readers + * like cgroup_can_be_thread_root() unlocked access. Protected by + * css_set_lock; updated by css_update_populated(). */ - int nr_populated_csets; int nr_populated_domain_children; int nr_populated_threaded_children; @@ -611,9 +618,6 @@ struct cgroup { /* used to wait for offlining of csses */ wait_queue_head_t offline_waitq; - /* defers killing csses after removal until cgroup is depopulated */ - struct work_struct finish_destroy_work; - /* used to schedule release agent */ struct work_struct release_agent_work; diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index c5648fcf74e2..f2aa46a4f871 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -640,11 +640,32 @@ static inline bool task_under_cgroup_hierarchy(struct task_struct *task, return cgroup_is_descendant(cset->dfl_cgrp, ancestor); } -/* no synchronization, the result can only be used as a hint */ +/* + * Populated counters: writes happen under css_set_lock. The accessors below + * may read unlocked. What an unpopulated result means depends on context: + * + * - No lock held. Just a snapshot. May race with concurrent updates and is + * useful only as a hint. + * + * - cgroup_mutex held. Migration into the cgroup is blocked, so an observed + * !populated stays !populated until cgroup_mutex is dropped. + * + * - CSS_DYING set. The css can no longer be repopulated, so !populated is + * sticky once observed. + */ +static inline bool cgroup_has_tasks(struct cgroup *cgrp) +{ + return READ_ONCE(cgrp->self.nr_populated_csets); +} + +static inline bool css_is_populated(struct cgroup_subsys_state *css) +{ + return READ_ONCE(css->nr_populated_csets) || READ_ONCE(css->nr_populated_children); +} + static inline bool cgroup_is_populated(struct cgroup *cgrp) { - return cgrp->nr_populated_csets + cgrp->nr_populated_domain_children + - cgrp->nr_populated_threaded_children; + return css_is_populated(&cgrp->self); } /* returns ino associated with a cgroup */ diff --git a/include/linux/cgroup_rdma.h b/include/linux/cgroup_rdma.h index 80edae03c313..404e746552ca 100644 --- a/include/linux/cgroup_rdma.h +++ b/include/linux/cgroup_rdma.h @@ -24,6 +24,10 @@ struct rdma_cgroup { * that belongs to this cgroup. */ struct list_head rpools; + + /* Handles for rdma.events[.local] */ + struct cgroup_file events_file; + struct cgroup_file events_local_file; }; struct rdmacg_device { diff --git a/include/linux/cnt32_to_63.h b/include/linux/cnt32_to_63.h deleted file mode 100644 index 064428479f2d..000000000000 --- a/include/linux/cnt32_to_63.h +++ /dev/null @@ -1,104 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Extend a 32-bit counter to 63 bits - * - * Author: Nicolas Pitre - * Created: December 3, 2006 - * Copyright: MontaVista Software, Inc. - */ - -#ifndef __LINUX_CNT32_TO_63_H__ -#define __LINUX_CNT32_TO_63_H__ - -#include <linux/compiler.h> -#include <linux/types.h> -#include <asm/byteorder.h> - -/* this is used only to give gcc a clue about good code generation */ -union cnt32_to_63 { - struct { -#if defined(__LITTLE_ENDIAN) - u32 lo, hi; -#elif defined(__BIG_ENDIAN) - u32 hi, lo; -#endif - }; - u64 val; -}; - - -/** - * cnt32_to_63 - Expand a 32-bit counter to a 63-bit counter - * @cnt_lo: The low part of the counter - * - * Many hardware clock counters are only 32 bits wide and therefore have - * a relatively short period making wrap-arounds rather frequent. This - * is a problem when implementing sched_clock() for example, where a 64-bit - * non-wrapping monotonic value is expected to be returned. - * - * To overcome that limitation, let's extend a 32-bit counter to 63 bits - * in a completely lock free fashion. Bits 0 to 31 of the clock are provided - * by the hardware while bits 32 to 62 are stored in memory. The top bit in - * memory is used to synchronize with the hardware clock half-period. When - * the top bit of both counters (hardware and in memory) differ then the - * memory is updated with a new value, incrementing it when the hardware - * counter wraps around. - * - * Because a word store in memory is atomic then the incremented value will - * always be in synch with the top bit indicating to any potential concurrent - * reader if the value in memory is up to date or not with regards to the - * needed increment. And any race in updating the value in memory is harmless - * as the same value would simply be stored more than once. - * - * The restrictions for the algorithm to work properly are: - * - * 1) this code must be called at least once per each half period of the - * 32-bit counter; - * - * 2) this code must not be preempted for a duration longer than the - * 32-bit counter half period minus the longest period between two - * calls to this code; - * - * Those requirements ensure proper update to the state bit in memory. - * This is usually not a problem in practice, but if it is then a kernel - * timer should be scheduled to manage for this code to be executed often - * enough. - * - * And finally: - * - * 3) the cnt_lo argument must be seen as a globally incrementing value, - * meaning that it should be a direct reference to the counter data which - * can be evaluated according to a specific ordering within the macro, - * and not the result of a previous evaluation stored in a variable. - * - * For example, this is wrong: - * - * u32 partial = get_hw_count(); - * u64 full = cnt32_to_63(partial); - * return full; - * - * This is fine: - * - * u64 full = cnt32_to_63(get_hw_count()); - * return full; - * - * Note that the top bit (bit 63) in the returned value should be considered - * as garbage. It is not cleared here because callers are likely to use a - * multiplier on the returned value which can get rid of the top bit - * implicitly by making the multiplier even, therefore saving on a runtime - * clear-bit instruction. Otherwise caller must remember to clear the top - * bit explicitly. - */ -#define cnt32_to_63(cnt_lo) \ -({ \ - static u32 __m_cnt_hi; \ - union cnt32_to_63 __x; \ - __x.hi = __m_cnt_hi; \ - smp_rmb(); \ - __x.lo = (cnt_lo); \ - if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \ - __m_cnt_hi = __x.hi = (__x.hi ^ 0x80000000) + (__x.hi >> 31); \ - __x.val; \ -}) - -#endif diff --git a/include/linux/cnum.h b/include/linux/cnum.h new file mode 100644 index 000000000000..49b7d0c7645d --- /dev/null +++ b/include/linux/cnum.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */ + +#ifndef _LINUX_CNUM_H +#define _LINUX_CNUM_H + +#include <linux/types.h> + +/* + * cnum32: a circular number. + * A unified representation for signed and unsigned ranges. + * + * Assume that a 32-bit range is a circle, with 0 being in the 12 o'clock + * position, numbers placed sequentially in clockwise order and U32_MAX + * in the 11 o'clock position. Signed values map onto the same circle: + * S32_MAX sits at 5 o'clock, S32_MIN sits at 6 o'clock (opposite 0), + * negative values occupy the left half and positive values the right half. + * + * @cnum32 represents an arc on this circle drawn clockwise. + * @base corresponds to the first value of the range. + * @size corresponds to the number of integers in the range excluding @base. + * (The @base is excluded to avoid integer overflow when representing the full + * 0..U32_MAX range, which corresponds to 2^32, which can't be stored in u32). + * + * For example: {U32_MAX, 1} corresponds to signed range [-1, 0], + * {S32_MAX, 1} corresponds to unsigned range [S32_MAX, S32_MIN]. + */ +struct cnum32 { + u32 base; + u32 size; +}; + +#define CNUM32_UNBOUNDED ((struct cnum32){ .base = 0, .size = U32_MAX }) +#define CNUM32_EMPTY ((struct cnum32){ .base = U32_MAX, .size = U32_MAX }) + +struct cnum32 cnum32_from_urange(u32 min, u32 max); +struct cnum32 cnum32_from_srange(s32 min, s32 max); +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_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); +void cnum32_intersect_with_srange(struct cnum32 *dst, s32 min, s32 max); +bool cnum32_contains(struct cnum32 cnum, u32 v); +bool cnum32_is_const(struct cnum32 cnum); +bool cnum32_is_empty(struct cnum32 cnum); +struct cnum32 cnum32_add(struct cnum32 a, struct cnum32 b); +struct cnum32 cnum32_negate(struct cnum32 a); +bool cnum32_is_subset(struct cnum32 outer, struct cnum32 inner); + +/* Same as cnum32 but for 64-bit ranges */ +struct cnum64 { + u64 base; + u64 size; +}; + +#define CNUM64_UNBOUNDED ((struct cnum64){ .base = 0, .size = U64_MAX }) +#define CNUM64_EMPTY ((struct cnum64){ .base = U64_MAX, .size = U64_MAX }) + +struct cnum64 cnum64_from_urange(u64 min, u64 max); +struct cnum64 cnum64_from_srange(s64 min, s64 max); +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_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); +void cnum64_intersect_with_srange(struct cnum64 *dst, s64 min, s64 max); +bool cnum64_contains(struct cnum64 cnum, u64 v); +bool cnum64_is_const(struct cnum64 cnum); +bool cnum64_is_empty(struct cnum64 cnum); +struct cnum64 cnum64_add(struct cnum64 a, struct cnum64 b); +struct cnum64 cnum64_negate(struct cnum64 a); +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); + +#endif /* _LINUX_CNUM_H */ diff --git a/include/linux/compaction.h b/include/linux/compaction.h index 173d9c07a895..f29ef0653546 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h @@ -2,6 +2,8 @@ #ifndef _LINUX_COMPACTION_H #define _LINUX_COMPACTION_H +#include <linux/swap.h> + /* * Determines how hard direct compaction should try to succeed. * Lower value means higher priority, analogically to reclaim priority. @@ -73,11 +75,9 @@ static inline unsigned long compact_gap(unsigned int order) * effectively limited by COMPACT_CLUSTER_MAX, as that's the maximum * that the migrate scanner can have isolated on migrate list, and free * scanner is only invoked when the number of isolated free pages is - * lower than that. But it's not worth to complicate the formula here - * as a bigger gap for higher orders than strictly necessary can also - * improve chances of compaction success. + * lower than that. */ - return 2UL << order; + return min(2UL << order, COMPACT_CLUSTER_MAX); } static inline int current_is_kcompactd(void) @@ -101,7 +101,7 @@ extern void compaction_defer_reset(struct zone *zone, int order, bool alloc_success); bool compaction_zonelist_suitable(struct alloc_context *ac, int order, - int alloc_flags); + int alloc_flags, gfp_t gfp_mask); extern void __meminit kcompactd_run(int nid); extern void __meminit kcompactd_stop(int nid); diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 80211900f373..d3cda0544954 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -13,8 +13,10 @@ #include <linux/cpumask_types.h> #include <linux/gfp_types.h> #include <linux/numa.h> +#include <linux/sprintf.h> #include <linux/threads.h> #include <linux/types.h> +#include <vdso/page.h> #include <asm/bug.h> @@ -1326,8 +1328,9 @@ static __always_inline bool cpu_dying(unsigned int cpu) static __always_inline ssize_t cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) { - return bitmap_print_to_pagebuf(list, buf, cpumask_bits(mask), - nr_cpu_ids); + /* Opencode offset_in_page(buf) to not include linux/mm.h */ + return scnprintf(buf, PAGE_SIZE - ((unsigned long)buf & ~PAGE_MASK), + list ? "%*pbl\n" : "%*pb\n", cpumask_pr_args(mask)); } /** diff --git a/include/linux/crypto.h b/include/linux/crypto.h index a2137e19be7d..b7c97f1c47c9 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -409,7 +409,6 @@ int crypto_has_alg(const char *name, u32 type, u32 mask); */ struct crypto_tfm { - refcount_t refcnt; u32 crt_flags; diff --git a/include/linux/damon.h b/include/linux/damon.h index f2cdb7c3f5e6..6f7edb3590ef 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -8,23 +8,20 @@ #ifndef _DAMON_H_ #define _DAMON_H_ +#include <linux/math64.h> #include <linux/memcontrol.h> #include <linux/mutex.h> +#include <linux/prandom.h> #include <linux/time64.h> #include <linux/types.h> -#include <linux/random.h> /* Minimal region size. Every damon_region is aligned by this. */ #define DAMON_MIN_REGION_SZ PAGE_SIZE +/* Maximum number of monitoring probes. */ +#define DAMON_MAX_PROBES (4) /* Max priority score for DAMON-based operation schemes */ #define DAMOS_MAX_SCORE (99) -/* Get a random number in [l, r) */ -static inline unsigned long damon_rand(unsigned long l, unsigned long r) -{ - return l + get_random_u32_below(r - l); -} - /** * struct damon_addr_range - Represents an address region of [@start, @end). * @start: Start address of the region (inclusive). @@ -52,6 +49,7 @@ struct damon_size_range { * @nr_accesses: Access frequency of this region. * @nr_accesses_bp: @nr_accesses in basis point (0.01%) that updated for * each sampling interval. + * @probe_hits: Number of probe-positive region samples. * @list: List head for siblings. * @age: Age of this region. * @@ -80,6 +78,7 @@ struct damon_region { unsigned long sampling_addr; unsigned int nr_accesses; unsigned int nr_accesses_bp; + unsigned char probe_hits[DAMON_MAX_PROBES]; struct list_head list; unsigned int age; @@ -121,6 +120,7 @@ struct damon_target { * @DAMOS_PAGEOUT: Reclaim the region. * @DAMOS_HUGEPAGE: Call ``madvise()`` for the region with MADV_HUGEPAGE. * @DAMOS_NOHUGEPAGE: Call ``madvise()`` for the region with MADV_NOHUGEPAGE. + * @DAMOS_COLLAPSE: Call ``madvise()`` for the region with MADV_COLLAPSE. * @DAMOS_LRU_PRIO: Prioritize the region on its LRU lists. * @DAMOS_LRU_DEPRIO: Deprioritize the region on its LRU lists. * @DAMOS_MIGRATE_HOT: Migrate the regions prioritizing warmer regions. @@ -140,6 +140,7 @@ enum damos_action { DAMOS_PAGEOUT, DAMOS_HUGEPAGE, DAMOS_NOHUGEPAGE, + DAMOS_COLLAPSE, DAMOS_LRU_PRIO, DAMOS_LRU_DEPRIO, DAMOS_MIGRATE_HOT, @@ -159,6 +160,8 @@ enum damos_action { * @DAMOS_QUOTA_NODE_MEMCG_FREE_BP: MemFree ratio of a node for a cgroup. * @DAMOS_QUOTA_ACTIVE_MEM_BP: Active to total LRU memory ratio. * @DAMOS_QUOTA_INACTIVE_MEM_BP: Inactive to total LRU memory ratio. + * @DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP: Scheme-eligible memory ratio of a + * node in basis points (0-10000). * @NR_DAMOS_QUOTA_GOAL_METRICS: Number of DAMOS quota goal metrics. * * Metrics equal to larger than @NR_DAMOS_QUOTA_GOAL_METRICS are unsupported. @@ -172,6 +175,7 @@ enum damos_quota_goal_metric { DAMOS_QUOTA_NODE_MEMCG_FREE_BP, DAMOS_QUOTA_ACTIVE_MEM_BP, DAMOS_QUOTA_INACTIVE_MEM_BP, + DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP, NR_DAMOS_QUOTA_GOAL_METRICS, }; @@ -233,6 +237,8 @@ enum damos_quota_goal_tuner { * @goals: Head of quota tuning goals (&damos_quota_goal) list. * @goal_tuner: Goal-based @esz tuning algorithm to use. * @esz: Effective size quota in bytes. + * @fail_charge_num: Failed regions charge rate numerator. + * @fail_charge_denom: Failed regions charge rate denominator. * * @weight_sz: Weight of the region's size for prioritization. * @weight_nr_accesses: Weight of the region's nr_accesses for prioritization. @@ -262,6 +268,10 @@ enum damos_quota_goal_tuner { * * The resulting effective size quota in bytes is set to @esz. * + * For DAMOS action applying failed amount of regions, charging those same to + * those that the action has successfully applied may be unfair. For the + * reason, 'the size * @fail_charge_num / @fail_charge_denom' is charged. + * * For selecting regions within the quota, DAMON prioritizes current scheme's * target memory regions using the &struct damon_operations->get_scheme_score. * You could customize the prioritization logic by setting &weight_sz, @@ -276,6 +286,9 @@ struct damos_quota { enum damos_quota_goal_tuner goal_tuner; unsigned long esz; + unsigned int fail_charge_num; + unsigned int fail_charge_denom; + unsigned int weight_sz; unsigned int weight_nr_accesses; unsigned int weight_age; @@ -617,6 +630,7 @@ enum damon_ops_id { * @update: Update operations-related data structures. * @prepare_access_checks: Prepare next access check of target regions. * @check_accesses: Check the accesses to target regions. + * @apply_probes: Apply probes for each region. * @get_scheme_score: Get the score of a region for a scheme. * @apply_scheme: Apply a DAMON-based operation scheme. * @target_valid: Determine if the target is valid. @@ -643,6 +657,8 @@ enum damon_ops_id { * last preparation and update the number of observed accesses of each region. * It should also return max number of observed accesses that made as a result * of its update. The value will be used for regions adjustment threshold. + * @apply_probes should apply the data attribute probes to each region and + * accordingly update the probe hits counter of the region. * @get_scheme_score should return the priority score of a region for a scheme * as an integer in [0, &DAMOS_MAX_SCORE]. * @apply_scheme is called from @kdamond when a region for user provided @@ -660,6 +676,7 @@ struct damon_operations { void (*update)(struct damon_ctx *context); void (*prepare_access_checks)(struct damon_ctx *context); unsigned int (*check_accesses)(struct damon_ctx *context); + void (*apply_probes)(struct damon_ctx *context); int (*get_scheme_score)(struct damon_ctx *context, struct damon_region *r, struct damos *scheme); unsigned long (*apply_scheme)(struct damon_ctx *context, @@ -722,6 +739,47 @@ struct damon_intervals_goal { }; /** + * enum damon_filter_type - Type of &struct damon_filter + * + * @DAMON_FILTER_TYPE_ANON: Anonymous pages. + * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages. + */ +enum damon_filter_type { + DAMON_FILTER_TYPE_ANON, + DAMON_FILTER_TYPE_MEMCG, +}; + +/** + * struct damon_filter - DAMON region filter for &struct damon_probe. + * + * @type: Type of the region. + * @matching: Whether this filter is for the type-matching ones. + * @allow: Whether the @type-@matching ones should pass this filter. + * @memcg_id: Memcg id of the question if @type is DAMON_FILTER_MEMCG. + * @list: Siblings list. + */ +struct damon_filter { + enum damon_filter_type type; + bool matching; + bool allow; + union { + u64 memcg_id; + }; + struct list_head list; +}; + +/** + * struct damon_probe - Data region attribute probe. + * + * @filters: Filters for assessing if a given region is for this probe. + * @list: Siblings list. + */ +struct damon_probe { + struct list_head filters; + struct list_head list; +}; + +/** * struct damon_attrs - Monitoring attributes for accuracy/overhead control. * * @sample_interval: The time between access samplings. @@ -787,6 +845,7 @@ struct damon_attrs { * @ops: Set of monitoring operations for given use cases. * @addr_unit: Scale factor for core to ops address conversion. * @min_region_sz: Minimum region size. + * @pause: Pause kdamond main loop. * @adaptive_targets: Head of monitoring targets (&damon_target) list. * @schemes: Head of schemes (&damos) list. */ @@ -838,13 +897,34 @@ struct damon_ctx { /* public: */ struct damon_operations ops; + struct list_head probes; unsigned long addr_unit; unsigned long min_region_sz; + bool pause; struct list_head adaptive_targets; struct list_head schemes; + + /* Per-ctx PRNG state for damon_rand(); kdamond is the sole consumer. */ + struct rnd_state rnd_state; }; +/* Get a random number in [@l, @r) using @ctx's lockless PRNG. */ +static inline unsigned long damon_rand(struct damon_ctx *ctx, + unsigned long l, unsigned long r) +{ + unsigned long span = r - l; + u64 rnd; + + if (span <= U32_MAX) { + rnd = prandom_u32_state(&ctx->rnd_state); + return l + (unsigned long)((rnd * span) >> 32); + } + rnd = ((u64)prandom_u32_state(&ctx->rnd_state) << 32) | + prandom_u32_state(&ctx->rnd_state); + return l + mul_u64_u64_shr(rnd, span, 64); +} + static inline struct damon_region *damon_next_region(struct damon_region *r) { return container_of(r->list.next, struct damon_region, list); @@ -870,15 +950,26 @@ static inline unsigned long damon_sz_region(struct damon_region *r) return r->ar.end - r->ar.start; } +#define damon_for_each_filter(f, p) \ + list_for_each_entry(f, &(p)->filters, list) + +#define damon_for_each_filter_safe(f, next, p) \ + list_for_each_entry_safe(f, next, &(p)->filters, list) + +#define damon_for_each_probe(p, ctx) \ + list_for_each_entry(p, &(ctx)->probes, list) + +#define damon_for_each_probe_safe(p, next, ctx) \ + list_for_each_entry_safe(p, next, &(ctx)->probes, list) #define damon_for_each_region(r, t) \ - list_for_each_entry(r, &t->regions_list, list) + list_for_each_entry(r, &(t)->regions_list, list) #define damon_for_each_region_from(r, t) \ - list_for_each_entry_from(r, &t->regions_list, list) + list_for_each_entry_from(r, &(t)->regions_list, list) #define damon_for_each_region_safe(r, next, t) \ - list_for_each_entry_safe(r, next, &t->regions_list, list) + list_for_each_entry_safe(r, next, &(t)->regions_list, list) #define damon_for_each_target(t, ctx) \ list_for_each_entry(t, &(ctx)->adaptive_targets, list) @@ -893,7 +984,7 @@ static inline unsigned long damon_sz_region(struct damon_region *r) list_for_each_entry_safe(s, next, &(ctx)->schemes, list) #define damos_for_each_quota_goal(goal, quota) \ - list_for_each_entry(goal, "a->goals, list) + list_for_each_entry(goal, &(quota)->goals, list) #define damos_for_each_quota_goal_safe(goal, next, quota) \ list_for_each_entry_safe(goal, next, &(quota)->goals, list) @@ -912,21 +1003,16 @@ static inline unsigned long damon_sz_region(struct damon_region *r) #ifdef CONFIG_DAMON -struct damon_region *damon_new_region(unsigned long start, unsigned long end); +struct damon_filter *damon_new_filter(enum damon_filter_type type, + bool matching, bool allow); +void damon_add_filter(struct damon_probe *probe, struct damon_filter *f); +void damon_destroy_filter(struct damon_filter *f); -/* - * Add a region between two other regions - */ -static inline void damon_insert_region(struct damon_region *r, - struct damon_region *prev, struct damon_region *next, - struct damon_target *t) -{ - __list_add(&r->list, &prev->list, &next->list); - t->nr_regions++; -} +struct damon_probe *damon_new_probe(void); +void damon_add_probe(struct damon_ctx *ctx, struct damon_probe *probe); + +struct damon_region *damon_new_region(unsigned long start, unsigned long end); -void damon_add_region(struct damon_region *r, struct damon_target *t); -void damon_destroy_region(struct damon_region *r, struct damon_target *t); int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges, unsigned int nr_ranges, unsigned long min_region_sz); void damon_update_region_access_rate(struct damon_region *r, bool accessed, @@ -994,7 +1080,7 @@ int damon_kdamond_pid(struct damon_ctx *ctx); int damon_call(struct damon_ctx *ctx, struct damon_call_control *control); int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control); -int damon_set_region_biggest_system_ram_default(struct damon_target *t, +int damon_set_region_system_rams_default(struct damon_target *t, unsigned long *start, unsigned long *end, unsigned long addr_unit, unsigned long min_region_sz); diff --git a/include/linux/dma-fence-array.h b/include/linux/dma-fence-array.h index 370b3d2bba37..1b1d87579c38 100644 --- a/include/linux/dma-fence-array.h +++ b/include/linux/dma-fence-array.h @@ -81,13 +81,11 @@ to_dma_fence_array(struct dma_fence *fence) struct dma_fence_array *dma_fence_array_alloc(int num_fences); void dma_fence_array_init(struct dma_fence_array *array, int num_fences, struct dma_fence **fences, - u64 context, unsigned seqno, - bool signal_on_any); + u64 context, unsigned seqno); struct dma_fence_array *dma_fence_array_create(int num_fences, struct dma_fence **fences, - u64 context, unsigned seqno, - bool signal_on_any); + u64 context, unsigned seqno); bool dma_fence_match_context(struct dma_fence *fence, u64 context); diff --git a/include/linux/dpll.h b/include/linux/dpll.h index 2dbe8567eafc..7a6f8796cda2 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -13,6 +13,7 @@ #include <linux/netdevice.h> #include <linux/notifier.h> #include <linux/rtnetlink.h> +#include <net/netlink.h> struct dpll_device; struct dpll_pin; @@ -60,7 +61,20 @@ struct dpll_device_ops { struct netlink_ext_ack *extack); }; +enum dpll_ffo_type { + DPLL_FFO_PORT_RXTX_RATE, + DPLL_FFO_PIN_DEVICE, + + __DPLL_FFO_TYPE_MAX, +}; + +struct dpll_ffo_param { + enum dpll_ffo_type type; + s64 ffo; +}; + struct dpll_pin_ops { + unsigned long supported_ffo; int (*frequency_set)(const struct dpll_pin *pin, void *pin_priv, const struct dpll_device *dpll, void *dpll_priv, const u64 frequency, @@ -85,6 +99,12 @@ struct dpll_pin_ops { const struct dpll_device *dpll, void *dpll_priv, enum dpll_pin_state *state, struct netlink_ext_ack *extack); + int (*operstate_on_dpll_get)(const struct dpll_pin *pin, + void *pin_priv, + const struct dpll_device *dpll, + void *dpll_priv, + enum dpll_pin_operstate *operstate, + struct netlink_ext_ack *extack); int (*state_on_pin_set)(const struct dpll_pin *pin, void *pin_priv, const struct dpll_pin *parent_pin, void *parent_pin_priv, @@ -115,7 +135,8 @@ struct dpll_pin_ops { struct netlink_ext_ack *extack); int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv, const struct dpll_device *dpll, void *dpll_priv, - s64 *ffo, struct netlink_ext_ack *extack); + struct dpll_ffo_param *ffo, + struct netlink_ext_ack *extack); int (*measured_freq_get)(const struct dpll_pin *pin, void *pin_priv, const struct dpll_device *dpll, void *dpll_priv, u64 *measured_freq, @@ -212,13 +233,18 @@ struct dpll_pin_notifier_info { u64 clock_id; const struct fwnode_handle *fwnode; const struct dpll_pin_properties *prop; + u64 src_clock_id; }; #if IS_ENABLED(CONFIG_DPLL) void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin); void dpll_netdev_pin_clear(struct net_device *dev); -size_t dpll_netdev_pin_handle_size(const struct net_device *dev); +static inline size_t dpll_netdev_pin_handle_size(void) +{ + return nla_total_size(4); /* DPLL_A_PIN_ID */ +} + int dpll_netdev_add_pin_handle(struct sk_buff *msg, const struct net_device *dev); @@ -229,7 +255,7 @@ static inline void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) { } static inline void dpll_netdev_pin_clear(struct net_device *dev) { } -static inline size_t dpll_netdev_pin_handle_size(const struct net_device *dev) +static inline size_t dpll_netdev_pin_handle_size(void) { return 0; } diff --git a/include/linux/dsa/tag_netc.h b/include/linux/dsa/tag_netc.h new file mode 100644 index 000000000000..fe964722e5b0 --- /dev/null +++ b/include/linux/dsa/tag_netc.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2025-2026 NXP + */ + +#ifndef __NET_DSA_TAG_NETC_H +#define __NET_DSA_TAG_NETC_H + +#include <linux/skbuff.h> +#include <net/dsa.h> + +#define NETC_TAG_MAX_LEN 14 + +#endif diff --git a/include/linux/err.h b/include/linux/err.h index 8c37be0620ab..d3e38d5b3a98 100644 --- a/include/linux/err.h +++ b/include/linux/err.h @@ -36,7 +36,7 @@ * * Return: A pointer with @error encoded within its value. */ -static inline void * __must_check ERR_PTR(long error) +static __always_inline void * __must_check ERR_PTR(long error) { return (void *) error; } @@ -60,7 +60,7 @@ static inline void * __must_check ERR_PTR(long error) * @ptr: An error pointer. * Return: The error code within @ptr. */ -static inline long __must_check PTR_ERR(__force const void *ptr) +static __always_inline long __must_check PTR_ERR(__force const void *ptr) { return (long) ptr; } @@ -73,7 +73,7 @@ static inline long __must_check PTR_ERR(__force const void *ptr) * @ptr: The pointer to check. * Return: true if @ptr is an error pointer, false otherwise. */ -static inline bool __must_check IS_ERR(__force const void *ptr) +static __always_inline bool __must_check IS_ERR(__force const void *ptr) { return IS_ERR_VALUE((unsigned long)ptr); } @@ -87,7 +87,7 @@ static inline bool __must_check IS_ERR(__force const void *ptr) * * Like IS_ERR(), but also returns true for a null pointer. */ -static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) +static __always_inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) { return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr); } @@ -99,7 +99,7 @@ static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) * Explicitly cast an error-valued pointer to another pointer type in such a * way as to make it clear that's what's going on. */ -static inline void * __must_check ERR_CAST(__force const void *ptr) +static __always_inline void * __must_check ERR_CAST(__force const void *ptr) { /* cast away the const */ return (void *) ptr; @@ -122,7 +122,7 @@ static inline void * __must_check ERR_CAST(__force const void *ptr) * * Return: The error code within @ptr if it is an error pointer; 0 otherwise. */ -static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) +static __always_inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) { if (IS_ERR(ptr)) return PTR_ERR(ptr); diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 1cb0740ba331..1b834e2a522e 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -325,6 +325,8 @@ struct ethtool_link_ksettings { extern int __ethtool_get_link_ksettings(struct net_device *dev, struct ethtool_link_ksettings *link_ksettings); +int netif_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *link_ksettings); struct ethtool_keee { __ETHTOOL_DECLARE_LINK_MODE_MASK(supported); @@ -928,6 +930,19 @@ struct kernel_ethtool_ts_info { u32 rx_filters; }; +/* Bits for ethtool_ops::op_needs_rtnl + * LINKSETTINGS cover a number of commands, but in most cases we want to keep + * these bits separate, per GET and SET. GET is much easier to "unlock". + */ +#define ETHTOOL_OP_NEEDS_RTNL_LINKSETTINGS BIT(0) +#define ETHTOOL_OP_NEEDS_RTNL_SPFLAGS BIT(1) +#define ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM BIT(2) +#define ETHTOOL_OP_NEEDS_RTNL_SCHANNELS BIT(3) +#define ETHTOOL_OP_NEEDS_RTNL_SCOALESCE BIT(4) +#define ETHTOOL_OP_NEEDS_RTNL_GPAUSEPARAM BIT(5) +#define ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM BIT(6) +#define ETHTOOL_OP_NEEDS_RTNL_RSS BIT(7) + /** * struct ethtool_ops - optional netdev operations * @supported_input_xfrm: supported types of input xfrm from %RXH_XFRM_*. @@ -954,6 +969,16 @@ struct kernel_ethtool_ts_info { * @supported_coalesce_params: supported types of interrupt coalescing. * @supported_ring_params: supported ring params. * @supported_hwtstamp_qualifiers: bitfield of supported hwtstamp qualifier. + * @op_needs_rtnl: mask of %ETHTOOL_OP_NEEDS_RTNL_* bits. + * For use with ops-locked drivers (ignored otherwise). Selects which + * ethtool callbacks driver needs to still be executed under rtnl_lock + * (in addition to the netdev instance lock). + * The following commonly used core APIs currently require rtnl_lock + * (this list may not be exhaustive): + * - phylink helpers (note that phydev is currently unsupported!) + * - netdev_update_features() + * - netif_set_real_num_tx_queues() + * * @get_drvinfo: Report driver/device information. Modern drivers no * longer have to implement this callback. Most fields are * correctly filled in by the core using system information, or @@ -1152,8 +1177,14 @@ struct kernel_ethtool_ts_info { * @get_mm_stats: Query the 802.3 MAC Merge layer statistics. * * All operations are optional (i.e. the function pointer may be set - * to %NULL) and callers must take this into account. Callers must - * hold the RTNL lock. + * to %NULL) and callers must take this into account. + * + * For traditional drivers callers hold ``rtnl_lock`` across the call. + * For "ops locked" drivers (see Documentation/networking/netdevices.rst) + * callers instead hold the netdev instance lock (``netdev_lock_ops``); + * ``rtnl_lock`` is additionally held only for callbacks for which + * the driver opts in via the matching ``ETHTOOL_OP_NEEDS_RTNL_*`` bit + * in @op_needs_rtnl. * * See the structures used by these operations for further documentation. * Note that for all operations using a structure ending with a zero- @@ -1176,6 +1207,7 @@ struct ethtool_ops { u32 supported_coalesce_params; u32 supported_ring_params; u32 supported_hwtstamp_qualifiers; + u32 op_needs_rtnl; void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); int (*get_regs_len)(struct net_device *); void (*get_regs)(struct net_device *, struct ethtool_regs *, void *); @@ -1349,6 +1381,7 @@ int ethtool_virtdev_set_link_ksettings(struct net_device *dev, * within RTNL. * @rss_indir_user_size: Number of user provided entries for the default * (context 0) indirection table. + * @phys_id_busy: Loop blinking the device LED is running. * @wol_enabled: Wake-on-LAN is enabled * @module_fw_flash_in_progress: Module firmware flashing is in progress. */ @@ -1356,6 +1389,7 @@ struct ethtool_netdev_state { struct xarray rss_ctx; struct mutex rss_lock; u32 rss_indir_user_size; + unsigned phys_id_busy:1; unsigned wol_enabled:1; unsigned module_fw_flash_in_progress:1; }; diff --git a/include/linux/filter.h b/include/linux/filter.h index 88a241aac36a..67d337ede91b 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -58,8 +58,9 @@ struct ctl_table_header; #define BPF_REG_H BPF_REG_9 /* hlen, callee-saved */ /* Kernel hidden auxiliary/helper register. */ -#define BPF_REG_AX MAX_BPF_REG -#define MAX_BPF_EXT_REG (MAX_BPF_REG + 1) +#define BPF_REG_PARAMS MAX_BPF_REG +#define BPF_REG_AX (MAX_BPF_REG + 1) +#define MAX_BPF_EXT_REG (MAX_BPF_REG + 2) #define MAX_BPF_JIT_REG MAX_BPF_EXT_REG /* unused opcode to mark special call to bpf_tail_call() helper */ @@ -748,6 +749,27 @@ static inline u32 bpf_prog_run_pin_on_cpu(const struct bpf_prog *prog, return ret; } +static inline bool is_stack_arg_ldx(const struct bpf_insn *insn) +{ + return insn->code == (BPF_LDX | BPF_MEM | BPF_DW) && + insn->src_reg == BPF_REG_PARAMS && + insn->off > 0 && insn->off % 8 == 0; +} + +static inline bool is_stack_arg_st(const struct bpf_insn *insn) +{ + return insn->code == (BPF_ST | BPF_MEM | BPF_DW) && + insn->dst_reg == BPF_REG_PARAMS && + insn->off < 0 && insn->off % 8 == 0; +} + +static inline bool is_stack_arg_stx(const struct bpf_insn *insn) +{ + return insn->code == (BPF_STX | BPF_MEM | BPF_DW) && + insn->dst_reg == BPF_REG_PARAMS && + insn->off < 0 && insn->off % 8 == 0; +} + #define BPF_SKB_CB_LEN QDISC_CB_PRIV_LEN struct bpf_skb_data_end { @@ -1159,6 +1181,7 @@ bool bpf_jit_inlines_helper_call(s32 imm); bool bpf_jit_supports_subprog_tailcalls(void); bool bpf_jit_supports_percpu_insn(void); bool bpf_jit_supports_kfunc_call(void); +bool bpf_jit_supports_stack_args(void); bool bpf_jit_supports_far_kfunc_call(void); bool bpf_jit_supports_exceptions(void); bool bpf_jit_supports_ptr_xchg(void); diff --git a/include/linux/find.h b/include/linux/find.h index 6c2be8ca615d..a129f8205fb6 100644 --- a/include/linux/find.h +++ b/include/linux/find.h @@ -249,7 +249,7 @@ unsigned long find_nth_bit(const unsigned long *addr, unsigned long size, unsign * @n: The number of set bit, which position is needed, counting from 0 * * Returns the bit number of the N'th set bit. - * If no such, returns @size. + * If no such, returns >= @size. */ static __always_inline unsigned long find_nth_and_bit(const unsigned long *addr1, const unsigned long *addr2, @@ -277,7 +277,7 @@ unsigned long find_nth_and_bit(const unsigned long *addr1, const unsigned long * * @n: The number of set bit, which position is needed, counting from 0 * * Returns the bit number of the N'th set bit. - * If no such, returns @size. + * If no such, returns >= @size. */ static __always_inline unsigned long find_nth_and_andnot_bit(const unsigned long *addr1, @@ -655,8 +655,8 @@ unsigned long find_next_bit_le(const void *addr, unsigned /** * for_each_clear_bitrange_from - iterate over all unset bit ranges [b; e) - * @b: bit offset of start of current bitrange (first set bit); must be initialized - * @e: bit offset of end of current bitrange (first unset bit) + * @b: bit offset of start of current bitrange (first unset bit); must be initialized + * @e: bit offset of end of current bitrange (first set bit) * @addr: bitmap address to base the search on * @size: bitmap size in number of bits */ diff --git a/include/linux/firmware.h b/include/linux/firmware.h index aae1b85ffc10..0fa3b027f02f 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -110,6 +110,9 @@ int request_firmware_nowait( struct module *module, bool uevent, const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)); +void request_firmware_nowait_cancel(struct device *device, void *context, + void (*cont)(const struct firmware *fw, + void *context)); int request_firmware_direct(const struct firmware **fw, const char *name, struct device *device); int request_firmware_into_buf(const struct firmware **firmware_p, @@ -157,6 +160,13 @@ static inline int request_firmware_nowait( return -EINVAL; } +static inline void request_firmware_nowait_cancel(struct device *device, + void *context, + void (*cont)(const struct firmware *fw, + void *context)) +{ +} + static inline void release_firmware(const struct firmware *fw) { } diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h index 13f17dc4443b..c6b35c0ff300 100644 --- a/include/linux/firmware/samsung/exynos-acpm-protocol.h +++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h @@ -34,31 +34,41 @@ struct acpm_pmic_ops { u8 type, u8 reg, u8 chan, u8 value, u8 mask); }; +struct acpm_tmu_ops { + int (*init)(struct acpm_handle *handle, unsigned int acpm_chan_id); + int (*read_temp)(struct acpm_handle *handle, unsigned int acpm_chan_id, + u8 tz, int *temp); + int (*set_threshold)(struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, + const u8 temperature[8], size_t tlen); + int (*set_interrupt_enable)(struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, u8 inten); + int (*tz_control)(struct acpm_handle *handle, unsigned int acpm_chan_id, + u8 tz, bool enable); + int (*clear_tz_irq)(struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz); + int (*suspend)(struct acpm_handle *handle, unsigned int acpm_chan_id); + int (*resume)(struct acpm_handle *handle, unsigned int acpm_chan_id); +}; + struct acpm_ops { - struct acpm_dvfs_ops dvfs_ops; - struct acpm_pmic_ops pmic_ops; + struct acpm_dvfs_ops dvfs; + struct acpm_pmic_ops pmic; + struct acpm_tmu_ops tmu; }; /** * struct acpm_handle - Reference to an initialized protocol instance - * @ops: + * @ops: pointer to the constant ACPM protocol operations. */ struct acpm_handle { - struct acpm_ops ops; + const struct acpm_ops *ops; }; struct device; -#if IS_ENABLED(CONFIG_EXYNOS_ACPM_PROTOCOL) struct acpm_handle *devm_acpm_get_by_node(struct device *dev, struct device_node *np); -#else - -static inline struct acpm_handle *devm_acpm_get_by_node(struct device *dev, - struct device_node *np) -{ - return NULL; -} -#endif +struct acpm_handle *devm_acpm_get_by_phandle(struct device *dev); #endif /* __EXYNOS_ACPM_PROTOCOL_H */ diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index d70dcd462b44..7e27b0f7bf7e 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -543,6 +543,18 @@ enum pm_gem_config_type { }; /** + * enum pm_node_status - Device node status provided by xilpm fw + * @PM_NODE_UNUSED: Device is not used + * @PM_NODE_RUNNING: Device is power-on and out of reset + * @PM_NODE_HALT: Device is power-on but in the reset state + */ +enum pm_node_status { + PM_NODE_UNUSED = 0, + PM_NODE_RUNNING = 1, + PM_NODE_HALT = 12, +}; + +/** * struct zynqmp_pm_query_data - PM query data * @qid: query ID * @arg1: Argument 1 of query data @@ -630,6 +642,8 @@ int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode); int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode); int zynqmp_pm_get_node_status(const u32 node, u32 *const status, u32 *const requirements, u32 *const usage); +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status, + u32 *const requirements, u32 *const usage); int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value); int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config, u32 value); @@ -939,6 +953,13 @@ static inline int zynqmp_pm_get_node_status(const u32 node, u32 *const status, return -ENODEV; } +static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status, + u32 *const requirements, + u32 *const usage) +{ + return -ENODEV; +} + static inline int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 171982e53c9a..cf841dc71fef 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -26,7 +26,6 @@ #define FORTIFY_WRITE 1 #define EACH_FORTIFY_FUNC(macro) \ - macro(strncpy), \ macro(strnlen), \ macro(strlen), \ macro(strscpy), \ @@ -95,8 +94,6 @@ extern char *__underlying_strcat(char *p, const char *q) __RENAME(strcat); extern char *__underlying_strcpy(char *p, const char *q) __RENAME(strcpy); extern __kernel_size_t __underlying_strlen(const char *p) __RENAME(strlen); extern char *__underlying_strncat(char *p, const char *q, __kernel_size_t count) __RENAME(strncat); -extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) __RENAME(strncpy); - #else #if defined(__SANITIZE_MEMORY__) @@ -120,7 +117,6 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) #define __underlying_strcpy __builtin_strcpy #define __underlying_strlen __builtin_strlen #define __underlying_strncat __builtin_strncat -#define __underlying_strncpy __builtin_strncpy #endif @@ -159,50 +155,6 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) (bounds) < (length) \ ) -/** - * strncpy - Copy a string to memory with non-guaranteed NUL padding - * - * @p: pointer to destination of copy - * @q: pointer to NUL-terminated source string to copy - * @size: bytes to write at @p - * - * If strlen(@q) >= @size, the copy of @q will stop after @size bytes, - * and @p will NOT be NUL-terminated - * - * If strlen(@q) < @size, following the copy of @q, trailing NUL bytes - * will be written to @p until @size total bytes have been written. - * - * Do not use this function. While FORTIFY_SOURCE tries to avoid - * over-reads of @q, it cannot defend against writing unterminated - * results to @p. Using strncpy() remains ambiguous and fragile. - * Instead, please choose an alternative, so that the expectation - * of @p's contents is unambiguous: - * - * +--------------------+--------------------+------------+ - * | **p** needs to be: | padded to **size** | not padded | - * +====================+====================+============+ - * | NUL-terminated | strscpy_pad() | strscpy() | - * +--------------------+--------------------+------------+ - * | not NUL-terminated | strtomem_pad() | strtomem() | - * +--------------------+--------------------+------------+ - * - * Note strscpy*()'s differing return values for detecting truncation, - * and strtomem*()'s expectation that the destination is marked with - * __nonstring when it is a character array. - * - */ -__FORTIFY_INLINE __diagnose_as(__builtin_strncpy, 1, 2, 3) -char *strncpy(char * const POS p, const char *q, __kernel_size_t size) -{ - const size_t p_size = __member_size(p); - - if (__compiletime_lessthan(p_size, size)) - __write_overflow(); - if (p_size < size) - fortify_panic(FORTIFY_FUNC_strncpy, FORTIFY_WRITE, p_size, size, p); - return __underlying_strncpy(p, q, size); -} - extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen); /** * strnlen - Return bounded count of characters in a NUL-terminated string @@ -809,7 +761,6 @@ char *strcpy(char * const POS p, const char * const POS q) #undef __underlying_strcpy #undef __underlying_strlen #undef __underlying_strncat -#undef __underlying_strncpy #undef POS #undef POS0 diff --git a/include/linux/fs/super.h b/include/linux/fs/super.h index f21ffbb6dea5..405612678115 100644 --- a/include/linux/fs/super.h +++ b/include/linux/fs/super.h @@ -235,4 +235,6 @@ int freeze_super(struct super_block *super, enum freeze_holder who, int thaw_super(struct super_block *super, enum freeze_holder who, const void *freeze_owner); +int sb_init_dio_done_wq(struct super_block *sb); + #endif /* _LINUX_FS_SUPER_H */ diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index 1da63f2d7040..9f671e87c80c 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -357,9 +357,11 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct fsl_mc_command *cmd); #ifdef CONFIG_FSL_MC_BUS #define dev_is_fsl_mc(_dev) ((_dev)->bus == &fsl_mc_bus_type) +u32 fsl_mc_get_msi_id(struct device *dev); #else /* If fsl-mc bus is not present device cannot belong to fsl-mc bus */ #define dev_is_fsl_mc(_dev) (0) +#define fsl_mc_get_msi_id(_dev) (0) #endif /* Macro to check if a device is a container device */ @@ -419,10 +421,6 @@ int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev, void fsl_mc_object_free(struct fsl_mc_device *mc_adev); -struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode, - struct msi_domain_info *info, - struct irq_domain *parent); - int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev); void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev); diff --git a/include/linux/fsl/netc_global.h b/include/linux/fsl/netc_global.h index fdecca8c90f0..5b8ff528d369 100644 --- a/include/linux/fsl/netc_global.h +++ b/include/linux/fsl/netc_global.h @@ -5,6 +5,7 @@ #define __NETC_GLOBAL_H #include <linux/io.h> +#include <linux/io-64-nonatomic-lo-hi.h> static inline u32 netc_read(void __iomem *reg) { @@ -16,4 +17,9 @@ static inline void netc_write(void __iomem *reg, u32 val) iowrite32(val, reg); } +static inline u64 netc_read64(void __iomem *reg) +{ + return ioread64(reg); +} + #endif diff --git a/include/linux/fsl/ntmp.h b/include/linux/fsl/ntmp.h index 83a449b4d6ec..d3b6c476b91a 100644 --- a/include/linux/fsl/ntmp.h +++ b/include/linux/fsl/ntmp.h @@ -1,11 +1,15 @@ /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -/* Copyright 2025 NXP */ +/* Copyright 2025-2026 NXP */ #ifndef __NETC_NTMP_H #define __NETC_NTMP_H +#include <linux/bitmap.h> #include <linux/bitops.h> #include <linux/if_ether.h> +#define NTMP_NULL_ENTRY_ID 0xffffffffU +#define IPFT_MAX_PLD_LEN 24 + struct maft_keye_data { u8 mac_addr[ETH_ALEN]; __le16 resv; @@ -29,6 +33,12 @@ struct netc_cbdr_regs { struct netc_tbl_vers { u8 maft_ver; u8 rsst_ver; + u8 fdbt_ver; + u8 vft_ver; + u8 bpt_ver; + u8 ipft_ver; + u8 ett_ver; + u8 ect_ver; }; struct netc_swcbd { @@ -61,6 +71,12 @@ struct ntmp_user { struct device *dev; struct netc_cbdr *ring; struct netc_tbl_vers tbl; + + /* NTMP table bitmaps for resource management */ + u32 ett_bitmap_size; + u32 ect_bitmap_size; + unsigned long *ett_gid_bitmap; /* only valid for switch */ + unsigned long *ect_gid_bitmap; /* only valid for switch */ }; struct maft_entry_data { @@ -68,10 +84,205 @@ struct maft_entry_data { struct maft_cfge_data cfge; }; +struct ipft_pld_byte { + u8 data; + u8 mask; +}; + +struct ipft_keye_data { + __le16 precedence; + __le16 resv0[3]; + __le16 frm_attr_flags; +#define IPFT_FAF_OVLAN BIT(2) +#define IPFT_FAF_IVLAN BIT(3) +#define IPFT_FAF_IP_HDR BIT(7) +#define IPFT_FAF_IP_VER6 BIT(8) +#define IPFT_FAF_L4_CODE GENMASK(11, 10) +#define IPFT_FAF_TCP_HDR 1 +#define IPFT_FAF_UDP_HDR 2 +#define IPFT_FAF_SCTP_HDR 3 +#define IPFT_FAF_WOL_MAGIC BIT(12) + __le16 frm_attr_flags_mask; + __le16 dscp; +#define IPFT_DSCP GENMASK(5, 0) +#define IPFT_DSCP_MASK GENMASK(11, 6) +#define IPFT_DSCP_MASK_ALL 0x3f + __le16 src_port; /* This field is reserved for ENETC */ +#define IPFT_SRC_PORT GENMASK(4, 0) +#define IPFT_SRC_PORT_MASK GENMASK(9, 5) +#define IPFT_SRC_PORT_MASK_ALL 0x1f + __be16 outer_vlan_tci; + __be16 outer_vlan_tci_mask; + u8 dmac[ETH_ALEN]; + u8 dmac_mask[ETH_ALEN]; + u8 smac[ETH_ALEN]; + u8 smac_mask[ETH_ALEN]; + __be16 inner_vlan_tci; + __be16 inner_vlan_tci_mask; + __be16 ethertype; + __be16 ethertype_mask; + u8 ip_protocol; + u8 ip_protocol_mask; + __le16 resv1[7]; + __be32 ip_src[4]; + __le32 resv2[2]; + __be32 ip_src_mask[4]; + __be16 l4_src_port; + __be16 l4_src_port_mask; + __le32 resv3; + __be32 ip_dst[4]; + __le32 resv4[2]; + __be32 ip_dst_mask[4]; + __be16 l4_dst_port; + __be16 l4_dst_port_mask; + __le32 resv5; + struct ipft_pld_byte byte[IPFT_MAX_PLD_LEN]; +}; + +struct ipft_cfge_data { + __le32 cfg; +#define IPFT_IPV GENMASK(3, 0) +#define IPFT_OIPV BIT(4) +#define IPFT_DR GENMASK(6, 5) +#define IPFT_ODR BIT(7) +#define IPFT_FLTFA GENMASK(10, 8) +#define IPFT_FLTFA_DISCARD 0 +#define IPFT_FLTFA_PERMIT 1 +/* Redirect is only for switch */ +#define IPFT_FLTFA_REDIRECT 2 +#define IPFT_IMIRE BIT(11) +#define IPFT_WOLTE BIT(12) +#define IPFT_FLTA GENMASK(14, 13) +#define IPFT_FLTA_RP 1 +#define IPFT_FLTA_IS 2 +#define IPFT_FLTA_SI_BITMAP 3 +#define IPFT_RPR GENMASK(16, 15) +#define IPFT_CTD BIT(17) +#define IPFT_HR GENMASK(21, 18) +#define IPFT_TIMECAPE BIT(22) +#define IPFT_RRT BIT(23) +#define IPFT_BL2F BIT(24) +#define IPFT_EVMEID GENMASK(31, 28) + __le32 flta_tgt; +}; + +struct ipft_entry_data { + u32 entry_id; /* hardware assigns entry ID */ + struct ipft_keye_data keye; + struct ipft_cfge_data cfge; +}; + +struct fdbt_keye_data { + u8 mac_addr[ETH_ALEN]; /* big-endian */ + __le16 resv0; + __le16 fid; +#define FDBT_FID GENMASK(11, 0) + __le16 resv1; +}; + +struct fdbt_cfge_data { + __le32 port_bitmap; +#define FDBT_PORT_BITMAP GENMASK(23, 0) + __le32 cfg; +#define FDBT_OETEID GENMASK(1, 0) +#define FDBT_EPORT GENMASK(6, 2) +#define FDBT_IMIRE BIT(7) +#define FDBT_CTD GENMASK(10, 9) +#define FDBT_DYNAMIC BIT(11) +#define FDBT_TIMECAPE BIT(12) + __le32 et_eid; +}; + +struct fdbt_entry_data { + u32 entry_id; + struct fdbt_keye_data keye; + struct fdbt_cfge_data cfge; + u8 acte; +#define FDBT_ACT_CNT GENMASK(6, 0) +#define FDBT_ACT_FLAG BIT(7) +}; + +struct vft_cfge_data { + __le32 bitmap_stg; +#define VFT_PORT_MEMBERSHIP GENMASK(23, 0) +#define VFT_STG_ID_MASK GENMASK(27, 24) +#define VFT_STG_ID(g) FIELD_PREP(VFT_STG_ID_MASK, (g)) + __le16 fid; +#define VFT_FID GENMASK(11, 0) + __le16 cfg; +#define VFT_MLO GENMASK(2, 0) +#define VFT_MFO GENMASK(4, 3) +#define VFT_IPMFE BIT(6) +#define VFT_IPMFLE BIT(7) +#define VFT_PGA BIT(8) +#define VFT_SFDA BIT(10) +#define VFT_OSFDA BIT(11) +#define VFT_FDBAFSS BIT(12) + __le32 eta_port_bitmap; +#define VFT_ETA_PORT_BITMAP GENMASK(23, 0) + __le32 et_eid; +}; + +struct ett_cfge_data { + __le16 efm_cfg; +#define ETT_EFM_MODE GENMASK(1, 0) +#define ETT_ESQA GENMASK(5, 4) +#define ETT_ECA GENMASK(8, 6) +#define ETT_ECA_INC 1 +#define ETT_EFM_LEN_CHANGE GENMASK(15, 9) +#define ETT_FRM_LEN_DEL_VLAN 0x7c +#define ETT_FRM_LEN_DEL_RTAG 0x7a +#define ETT_FRM_LEN_DEL_VLAN_RTAG 0x76 + __le16 efm_data_len; +#define ETT_EFM_DATA_LEN GENMASK(10, 0) + __le32 efm_eid; + __le32 ec_eid; + __le32 esqa_tgt_eid; +}; + +struct bpt_bpse_data { + __le32 amount_used; + __le32 amount_used_hwm; + u8 bpd_fc_state; +#define BPT_FC_STATE BIT(0) +#define BPT_BPD BIT(1) +} __packed; + +struct bpt_cfge_data { + u8 fccfg_sbpen; +#define BPT_FC_CFG GENMASK(2, 1) +#define BPT_FC_CFG_EN_BPFC 1 + u8 pfc_vector; + __le16 max_thresh; + __le16 fc_on_thresh; + __le16 fc_off_thresh; + __le16 sbp_thresh; + __le16 resv; + __le32 sbp_eid; + __le32 fc_ports; +}; + +union ntmp_fmt_eid { + __le32 index; +#define FMTEID_INDEX GENMASK(12, 0) + __le32 vuda_sqta; +#define FMTEID_VUDA GENMASK(1, 0) +#define FMTEID_VUDA_DEL_OTAG 2 +#define FMTEID_SQTA GENMASK(4, 2) +#define FMTEID_SQTA_DEL 2 +#define FMTEID_VUDA_SQTA BIT(13) + __le32 vara_vid; +#define FMTEID_VID GENMASK(11, 0) +#define FMTEID_VARA GENMASK(13, 12) +#define FMTEID_VARA_VID BIT(14) +}; + #if IS_ENABLED(CONFIG_NXP_NETC_LIB) int ntmp_init_cbdr(struct netc_cbdr *cbdr, struct device *dev, const struct netc_cbdr_regs *regs); void ntmp_free_cbdr(struct netc_cbdr *cbdr); +u32 ntmp_lookup_free_eid(unsigned long *bitmap, u32 size); +void ntmp_clear_eid_bitmap(unsigned long *bitmap, u32 entry_id); /* NTMP APIs */ int ntmp_maft_add_entry(struct ntmp_user *user, u32 entry_id, @@ -83,6 +294,34 @@ int ntmp_rsst_update_entry(struct ntmp_user *user, const u32 *table, int count); int ntmp_rsst_query_entry(struct ntmp_user *user, u32 *table, int count); +int ntmp_ipft_add_entry(struct ntmp_user *user, + struct ipft_entry_data *entry); +int ntmp_ipft_delete_entry(struct ntmp_user *user, u32 entry_id); +int ntmp_fdbt_add_entry(struct ntmp_user *user, u32 *entry_id, + const struct fdbt_keye_data *keye, + const struct fdbt_cfge_data *cfge); +int ntmp_fdbt_update_entry(struct ntmp_user *user, u32 entry_id, + const struct fdbt_cfge_data *cfge); +int ntmp_fdbt_delete_entry(struct ntmp_user *user, u32 entry_id); +int ntmp_fdbt_search_port_entry(struct ntmp_user *user, int port, + u32 *resume_entry_id, + struct fdbt_entry_data *entry); +int ntmp_fdbt_update_activity_element(struct ntmp_user *user); +int ntmp_fdbt_delete_ageing_entries(struct ntmp_user *user, u8 act_cnt); +int ntmp_fdbt_delete_port_dynamic_entries(struct ntmp_user *user, int port); +int ntmp_vft_add_entry(struct ntmp_user *user, u16 vid, + const struct vft_cfge_data *cfge); +int ntmp_vft_update_entry(struct ntmp_user *user, u16 vid, + const struct vft_cfge_data *cfge); +int ntmp_vft_delete_entry(struct ntmp_user *user, u16 vid); +int ntmp_ett_add_entry(struct ntmp_user *user, u32 entry_id, + const struct ett_cfge_data *cfge); +int ntmp_ett_update_entry(struct ntmp_user *user, u32 entry_id, + const struct ett_cfge_data *cfge); +int ntmp_ett_delete_entry(struct ntmp_user *user, u32 entry_id); +int ntmp_ect_update_entry(struct ntmp_user *user, u32 entry_id); +int ntmp_bpt_update_entry(struct ntmp_user *user, u32 entry_id, + const struct bpt_cfge_data *cfge); #else static inline int ntmp_init_cbdr(struct netc_cbdr *cbdr, struct device *dev, const struct netc_cbdr_regs *regs) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 28b30c6f1031..02bc5027523a 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -415,6 +415,8 @@ struct ftrace_hash *alloc_ftrace_hash(int size_bits); 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); +void ftrace_hash_remove(struct ftrace_hash *hash); /* The hash used to know what functions callbacks trace */ struct ftrace_ops_hash { @@ -551,6 +553,8 @@ int update_ftrace_direct_mod(struct ftrace_ops *ops, struct ftrace_hash *hash, b void ftrace_stub_direct_tramp(void); +unsigned long ftrace_hash_count(struct ftrace_hash *hash); + #else struct ftrace_ops; static inline unsigned long ftrace_find_rec_direct(unsigned long ip) @@ -590,6 +594,11 @@ static inline int update_ftrace_direct_mod(struct ftrace_ops *ops, struct ftrace return -ENODEV; } +static inline unsigned long ftrace_hash_count(struct ftrace_hash *hash) +{ + return 0; +} + /* * This must be implemented by the architecture. * It is the way the ftrace direct_ops helper, when called diff --git a/include/linux/generic_pt/common.h b/include/linux/generic_pt/common.h index fc5d0b5edadc..07ef1c8341a4 100644 --- a/include/linux/generic_pt/common.h +++ b/include/linux/generic_pt/common.h @@ -134,6 +134,11 @@ enum pt_features { * significant amount of page table. */ PT_FEAT_FLUSH_RANGE_NO_GAPS, + /** + * @PT_FEAT_DETAILED_GATHER: Fill in the struct iommu_iotlb_gather pt + * sub structure with information about which levels were changed. + */ + PT_FEAT_DETAILED_GATHER, /* private: */ PT_FEAT_FMT_START, }; @@ -188,6 +193,10 @@ enum { * Support the 64k contiguous page size following the Svnapot extension. */ PT_FEAT_RISCV_SVNAPOT_64K = PT_FEAT_FMT_START, + /* + * Support Svpbmt extension: encode page-based memory type (PBMT) in PTEs. + */ + PT_FEAT_RISCV_SVPBMT, }; diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 51ef13ed756e..cdf95a9f0b87 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -239,6 +239,8 @@ unsigned long alloc_pages_bulk_noprof(gfp_t gfp, int preferred_nid, struct page **page_array); #define __alloc_pages_bulk(...) alloc_hooks(alloc_pages_bulk_noprof(__VA_ARGS__)) +void free_pages_bulk(struct page **page_array, unsigned long nr_pages); + unsigned long alloc_pages_bulk_mempolicy_noprof(gfp_t gfp, unsigned long nr_pages, struct page **page_array); @@ -467,6 +469,8 @@ void free_contig_frozen_range(unsigned long pfn, unsigned long nr_pages); void free_contig_range(unsigned long pfn, unsigned long nr_pages); #endif +void __free_contig_range(unsigned long pfn, unsigned long nr_pages); + DEFINE_FREE(free_page, void *, free_page((unsigned long)_T)) #endif /* __LINUX_GFP_H */ diff --git a/include/linux/gfp_types.h b/include/linux/gfp_types.h index cd4972a7c97c..54ca0c88bab6 100644 --- a/include/linux/gfp_types.h +++ b/include/linux/gfp_types.h @@ -281,9 +281,9 @@ enum { * * %__GFP_SKIP_KASAN makes KASAN skip unpoisoning on page allocation. * Used for userspace and vmalloc pages; the latter are unpoisoned by - * kasan_unpoison_vmalloc instead. For userspace pages, results in - * poisoning being skipped as well, see should_skip_kasan_poison for - * details. Only effective in HW_TAGS mode. + * kasan_unpoison_vmalloc instead. If passed to vmalloc, kasan_unpoison_vmalloc + * is skipped too. For userspace pages, results in poisoning being skipped as + * well, see should_skip_kasan_poison for details. Only effective in HW_TAGS mode. */ #define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN) #define __GFP_COMP ((__force gfp_t)___GFP_COMP) diff --git a/include/linux/gpu_buddy.h b/include/linux/gpu_buddy.h index 5fa917ba5450..71941a039648 100644 --- a/include/linux/gpu_buddy.h +++ b/include/linux/gpu_buddy.h @@ -154,6 +154,7 @@ struct gpu_buddy_block { * @avail: Total free space currently available for allocation in bytes. * @clear_avail: Free space available in the clear tree (zeroed memory) in bytes. * This is a subset of @avail. + * @lock_dep_map: Annotates gpu_buddy API with a driver provided lock. */ struct gpu_buddy { /* private: */ @@ -179,8 +180,48 @@ struct gpu_buddy { u64 size; u64 avail; u64 clear_avail; +#ifdef CONFIG_LOCKDEP + struct lockdep_map *lock_dep_map; +#endif }; +#ifdef CONFIG_LOCKDEP +/** + * gpu_buddy_driver_set_lock() - Set the lock protecting accesses to GPU BUDDY + * @mm: Pointer to GPU buddy structure. + * @lock: the lock used to protect the gpu buddy. The locking primitive + * must contain a dep_map field. + * + * Call this to annotate gpu_buddy APIs which access/modify gpu_buddy manager + */ +#define gpu_buddy_driver_set_lock(mm, lock) \ + do { \ + struct gpu_buddy *__mm = (mm); \ + if (!WARN(__mm->lock_dep_map, "GPU BUDDY MM lock should be set only once.")) \ + __mm->lock_dep_map = &(lock)->dep_map; \ + } while (0) +#else +#define gpu_buddy_driver_set_lock(mm, lock) do { (void)(mm); (void)(lock); } while (0) +#endif + +#ifdef CONFIG_LOCKDEP +/** + * gpu_buddy_driver_lock_held() - Assert GPU BUDDY manager lock is held + * @mm: Pointer to the GPU BUDDY structure. + * + * Ensure driver lock is held. + */ +static inline void gpu_buddy_driver_lock_held(struct gpu_buddy *mm) +{ + if (mm->lock_dep_map) + lockdep_assert(lock_is_held_type(mm->lock_dep_map, 0)); +} +#else +static inline void gpu_buddy_driver_lock_held(struct gpu_buddy *mm) +{ +} +#endif + static inline u64 gpu_buddy_block_offset(const struct gpu_buddy_block *block) { diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 96bda41d9148..8dab78e1f61b 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -50,6 +50,12 @@ enum hdmi_infoframe_type { HDMI_INFOFRAME_TYPE_DRM = 0x87, }; +/* HDMI spec maximum TMDS character rates, in Hz */ +#define HDMI_TMDS_CHAR_RATE_MIN_HZ 25000000 +#define HDMI_1_0_TMDS_CHAR_RATE_MAX_HZ 165000000 +#define HDMI_1_3_TMDS_CHAR_RATE_MAX_HZ 340000000 +#define HDMI_2_0_TMDS_CHAR_RATE_MAX_HZ 600000000 + #define HDMI_IEEE_OUI 0x000c03 #define HDMI_FORUM_IEEE_OUI 0xc45dd8 #define HDMI_INFOFRAME_HEADER_SIZE 4 diff --git a/include/linux/highmem-internal.h b/include/linux/highmem-internal.h index 0574c21ca45d..bb71e7dba4f7 100644 --- a/include/linux/highmem-internal.h +++ b/include/linux/highmem-internal.h @@ -262,7 +262,7 @@ static inline bool is_kmap_addr(const void *x) * @__addr: Virtual address to be unmapped * * Unmaps an address previously mapped by kmap_atomic() and re-enables - * pagefaults. Depending on PREEMP_RT configuration, re-enables also + * pagefaults. Depending on PREEMPT_RT configuration, re-enables also * migration and preemption. Users should not count on these side effects. * * Mappings should be unmapped in the reverse order that they were mapped. diff --git a/include/linux/host1x.h b/include/linux/host1x.h index 1f5f55917d1c..a7a675783136 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -143,6 +143,12 @@ static inline struct host1x_bo_mapping *to_host1x_bo_mapping(struct kref *ref) return container_of(ref, struct host1x_bo_mapping, ref); } +/** + * struct host1x_bo_ops - operations implemented by a host1x_bo provider + * + * @pin: create a DMA mapping. Implementation must not touch the bo's refcount. + * @unpin: destroy a DMA mapping. Implementation must not touch the bo's refcount. + */ struct host1x_bo_ops { struct host1x_bo *(*get)(struct host1x_bo *bo); void (*put)(struct host1x_bo *bo); @@ -181,6 +187,7 @@ struct host1x_bo_mapping *host1x_bo_pin(struct device *dev, struct host1x_bo *bo enum dma_data_direction dir, struct host1x_bo_cache *cache); void host1x_bo_unpin(struct host1x_bo_mapping *map); +void host1x_bo_clear_cached_mappings(struct host1x_bo *bo); static inline void *host1x_bo_mmap(struct host1x_bo *bo) { diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 2949e5acff35..c0d223d0c556 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -238,6 +238,31 @@ static inline bool thp_vma_suitable_order(struct vm_area_struct *vma, } /* + * Make sure huge_gfp is always more limited than limit_gfp. + * Some shmem users want THP allocation to be done less aggressively + * and only in certain zone. + */ +static inline gfp_t thp_shmem_limit_gfp_mask(gfp_t huge_gfp, gfp_t limit_gfp) +{ + gfp_t allowflags = __GFP_IO | __GFP_FS | __GFP_RECLAIM; + gfp_t denyflags = __GFP_NOWARN | __GFP_NORETRY; + gfp_t zoneflags = limit_gfp & GFP_ZONEMASK; + gfp_t result = huge_gfp & ~(allowflags | GFP_ZONEMASK); + + /* Allow allocations only from the originally specified zones. */ + result |= zoneflags; + + /* + * Minimize the result gfp by taking the union with the deny flags, + * and the intersection of the allow flags. + */ + result |= (limit_gfp & denyflags); + result |= (huge_gfp & limit_gfp) & allowflags; + + return result; +} + +/* * Filter the bitfield of input orders to the ones suitable for use in the vma. * See thp_vma_suitable_order(). * All orders that pass the checks are returned as a bitfield. @@ -414,10 +439,10 @@ static inline int split_huge_page(struct page *page) { return split_huge_page_to_list_to_order(page, NULL, 0); } + +int folio_memcg_alloc_deferred(struct folio *folio); + void deferred_split_folio(struct folio *folio, bool partially_mapped); -#ifdef CONFIG_MEMCG -void reparent_deferred_split_queue(struct mem_cgroup *memcg); -#endif void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, unsigned long address, bool freeze); @@ -581,6 +606,11 @@ static inline bool thp_vma_suitable_order(struct vm_area_struct *vma, return false; } +static inline gfp_t thp_shmem_limit_gfp_mask(gfp_t huge_gfp, gfp_t limit_gfp) +{ + return huge_gfp; +} + static inline unsigned long thp_vma_suitable_orders(struct vm_area_struct *vma, unsigned long addr, unsigned long orders) { @@ -649,8 +679,15 @@ static inline int try_folio_split_to_order(struct folio *folio, return -EINVAL; } -static inline void deferred_split_folio(struct folio *folio, bool partially_mapped) {} -static inline void reparent_deferred_split_queue(struct mem_cgroup *memcg) {} +static inline int folio_memcg_alloc_deferred(struct folio *folio) +{ + return 0; +} + +static inline void deferred_split_folio(struct folio *folio, bool partially_mapped) +{ +} + #define split_huge_pmd(__vma, __pmd, __address) \ do { } while (0) diff --git a/include/linux/ieee80211-eht.h b/include/linux/ieee80211-eht.h index a97b1d01f3ac..18f9c662cf4c 100644 --- a/include/linux/ieee80211-eht.h +++ b/include/linux/ieee80211-eht.h @@ -9,7 +9,7 @@ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright (c) 2016 - 2017 Intel Deutschland GmbH - * Copyright (c) 2018 - 2025 Intel Corporation + * Copyright (c) 2018 - 2026 Intel Corporation */ #ifndef LINUX_IEEE80211_EHT_H @@ -394,13 +394,23 @@ ieee80211_eht_oper_size_ok(const u8 *data, u8 len) } /* must validate ieee80211_eht_oper_size_ok() first */ +static inline const struct ieee80211_eht_operation_info * +ieee80211_eht_oper_info(const struct ieee80211_eht_operation *eht_oper) +{ + if (!(eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT)) + return NULL; + + return (const void *)eht_oper->optional; +} + +/* must validate ieee80211_eht_oper_size_ok() first */ static inline u16 ieee80211_eht_oper_dis_subchan_bitmap(const struct ieee80211_eht_operation *eht_oper) { - const struct ieee80211_eht_operation_info *info = - (const void *)eht_oper->optional; + const struct ieee80211_eht_operation_info *info; - if (!(eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT)) + info = ieee80211_eht_oper_info(eht_oper); + if (!info) return 0; if (!(eht_oper->params & IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT)) @@ -485,26 +495,28 @@ struct ieee80211_multi_link_elem { #define IEEE80211_MED_SYNC_DELAY_DEFAULT 0x10ac #define IEEE80211_EML_CAP_EMLSR_SUPP 0x0001 -#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY 0x000e -#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_0US 0 -#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_32US 1 -#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_64US 2 -#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_128US 3 -#define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US 4 -#define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY 0x0070 +#define IEEE80211_EML_CAP_EML_PADDING_DELAY 0x000e +/* Described Tables 9-417i & 9-417k in 802.11be-2024, which have the same values */ +#define IEEE80211_EML_CAP_EML_PADDING_DELAY_0US 0 +#define IEEE80211_EML_CAP_EML_PADDING_DELAY_32US 1 +#define IEEE80211_EML_CAP_EML_PADDING_DELAY_64US 2 +#define IEEE80211_EML_CAP_EML_PADDING_DELAY_128US 3 +#define IEEE80211_EML_CAP_EML_PADDING_DELAY_256US 4 +#define IEEE80211_EML_CAP_EML_TRANSITION_DELAY 0x0070 +/* Described in Table 9-417j in 802.11be-2024 */ #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_0US 0 #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_16US 1 #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_32US 2 #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_64US 3 #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_128US 4 #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US 5 +/* Described in Table 9-417l in 802.11be-2024 */ +#define IEEE80211_EML_CAP_EMLMR_TRANSITION_DELAY_0US 0 +#define IEEE80211_EML_CAP_EMLMR_TRANSITION_DELAY_32US 1 +#define IEEE80211_EML_CAP_EMLMR_TRANSITION_DELAY_64US 2 +#define IEEE80211_EML_CAP_EMLMR_TRANSITION_DELAY_128US 3 +#define IEEE80211_EML_CAP_EMLMR_TRANSITION_DELAY_256US 4 #define IEEE80211_EML_CAP_EMLMR_SUPPORT 0x0080 -#define IEEE80211_EML_CAP_EMLMR_DELAY 0x0700 -#define IEEE80211_EML_CAP_EMLMR_DELAY_0US 0 -#define IEEE80211_EML_CAP_EMLMR_DELAY_32US 1 -#define IEEE80211_EML_CAP_EMLMR_DELAY_64US 2 -#define IEEE80211_EML_CAP_EMLMR_DELAY_128US 3 -#define IEEE80211_EML_CAP_EMLMR_DELAY_256US 4 #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT 0x7800 #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_0 0 #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128US 1 @@ -517,7 +529,6 @@ struct ieee80211_multi_link_elem { #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_16TU 8 #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_32TU 9 #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_64TU 10 -#define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU 11 #define IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS 0x000f #define IEEE80211_MLD_CAP_OP_SRS_SUPPORT 0x0010 @@ -749,11 +760,13 @@ static inline u16 ieee80211_mle_get_mld_capa_op(const u8 *data) } /* Defined in Figure 9-1074t in P802.11be_D7.0 */ -#define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_PARAM_UPDATE 0x0001 -#define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_RECO_MAX_LINKS_MASK 0x001e -#define IEEE80211_EHT_ML_EXT_MLD_CAPA_NSTR_UPDATE 0x0020 -#define IEEE80211_EHT_ML_EXT_MLD_CAPA_EMLSR_ENA_ON_ONE_LINK 0x0040 -#define IEEE80211_EHT_ML_EXT_MLD_CAPA_BTM_MLD_RECO_MULTI_AP 0x0080 +#define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_PARAM_UPDATE 0x0001 +#define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_RECO_MAX_LINKS_MASK 0x001e +#define IEEE80211_EHT_ML_EXT_MLD_CAPA_NSTR_UPDATE 0x0020 +#define IEEE80211_EHT_ML_EXT_MLD_CAPA_EMLSR_ENA_ON_ONE_LINK 0x0040 +#define IEEE80211_EHT_ML_EXT_MLD_CAPA_BTM_MLD_RECO_MULTI_AP 0x0080 +/* defined by UHR Draft P802.11bn_D1.3 Figure 9-1147 */ +#define IEEE80211_UHR_ML_EXT_MLD_CAPA_ML_PM 0x0100 /** * ieee80211_mle_get_ext_mld_capa_op - returns the extended MLD capabilities @@ -1035,13 +1048,17 @@ ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta #define IEEE80211_MLE_STA_RECONF_CONTROL_COMPLETE_PROFILE 0x0010 #define IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 #define IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT 0x0040 -#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE 0x0780 -#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_AP_REM 0 -#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_OP_PARAM_UPDATE 1 -#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_ADD_LINK 2 -#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_DEL_LINK 3 -#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_NSTR_STATUS 4 -#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT 0x0800 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE 0x0780 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_AP_REM 0 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_OP_PARAM_UPDATE 1 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_ADD_LINK 2 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_DEL_LINK 3 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_NSTR_STATUS 4 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_UHR_OMP_UPD 5 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT 0x0800 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_NSTR_BMAP_SIZE 0x1000 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_NSTR_IND_BMAP_PRES 0x2000 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_DSO_INFO_PRESENT 0x4000 /** * ieee80211_mle_reconf_sta_prof_size_ok - validate reconfiguration multi-link @@ -1121,14 +1138,20 @@ static inline bool ieee80211_tid_to_link_map_size_ok(const u8 *data, size_t len) static inline u32 ieee80211_emlsr_pad_delay_in_us(u16 eml_cap) { + u32 emlsr_supp = + u16_get_bits(eml_cap, IEEE80211_EML_CAP_EMLSR_SUPP); + + if (!emlsr_supp) + return 0; + /* IEEE Std 802.11be-2024 Table 9-417i—Encoding of the EMLSR * Padding Delay subfield. */ u32 pad_delay = u16_get_bits(eml_cap, - IEEE80211_EML_CAP_EMLSR_PADDING_DELAY); + IEEE80211_EML_CAP_EML_PADDING_DELAY); if (!pad_delay || - pad_delay > IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US) + pad_delay > IEEE80211_EML_CAP_EML_PADDING_DELAY_256US) return 0; return 32 * (1 << (pad_delay - 1)); @@ -1145,12 +1168,18 @@ static inline u32 ieee80211_emlsr_pad_delay_in_us(u16 eml_cap) static inline u32 ieee80211_emlsr_trans_delay_in_us(u16 eml_cap) { + u32 emlsr_supp = + u16_get_bits(eml_cap, IEEE80211_EML_CAP_EMLSR_SUPP); + + if (!emlsr_supp) + return 0; + /* IEEE Std 802.11be-2024 Table 9-417j—Encoding of the EMLSR * Transition Delay subfield. */ u32 trans_delay = u16_get_bits(eml_cap, - IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY); + IEEE80211_EML_CAP_EML_TRANSITION_DELAY); /* invalid values also just use 0 */ if (!trans_delay || @@ -1161,11 +1190,73 @@ static inline u32 ieee80211_emlsr_trans_delay_in_us(u16 eml_cap) } /** - * ieee80211_eml_trans_timeout_in_us - Fetch the EMLSR Transition + * ieee80211_emlmr_pad_delay_in_us - Fetch the EMLMR Padding delay + * in microseconds + * @eml_cap: EML capabilities field value from common info field of + * the Multi-link element + * Return: the EMLMR Padding delay (in microseconds) encoded in the + * EML Capabilities field + */ + +static inline u32 ieee80211_emlmr_pad_delay_in_us(u16 eml_cap) +{ + u32 emlmr_supp = + u16_get_bits(eml_cap, IEEE80211_EML_CAP_EMLMR_SUPPORT); + + if (!emlmr_supp) + return 0; + + /* IEEE Std 802.11be-2024 Table 9-417k—Encoding of the EMLMR + * Padding Delay subfield. + */ + u32 pad_delay = u16_get_bits(eml_cap, + IEEE80211_EML_CAP_EML_PADDING_DELAY); + + if (!pad_delay || + pad_delay > IEEE80211_EML_CAP_EML_PADDING_DELAY_256US) + return 0; + + return 32 * (1 << (pad_delay - 1)); +} + +/** + * ieee80211_emlmr_trans_delay_in_us - Fetch the EMLMR Transition + * delay in microseconds + * @eml_cap: EML capabilities field value from common info field of + * the Multi-link element + * Return: the EMLMR Transition delay (in microseconds) encoded in the + * EML Capabilities field + */ + +static inline u32 ieee80211_emlmr_trans_delay_in_us(u16 eml_cap) +{ + u32 emlmr_supp = + u16_get_bits(eml_cap, IEEE80211_EML_CAP_EMLMR_SUPPORT); + + if (!emlmr_supp) + return 0; + + /* IEEE Std 802.11be-2024 Table 9-417l—Encoding of the EMLMR + * Transition Delay subfield. + */ + u32 trans_delay = + u16_get_bits(eml_cap, + IEEE80211_EML_CAP_EML_TRANSITION_DELAY); + + /* invalid values also just use 0 */ + if (!trans_delay || + trans_delay > IEEE80211_EML_CAP_EMLMR_TRANSITION_DELAY_256US) + return 0; + + return 32 * (1 << (trans_delay - 1)); +} + +/** + * ieee80211_eml_trans_timeout_in_us - Fetch the EML Transition * timeout value in microseconds * @eml_cap: EML capabilities field value from common info field of * the Multi-link element - * Return: the EMLSR Transition timeout (in microseconds) encoded in + * Return: the EML Transition timeout (in microseconds) encoded in * the EML Capabilities field */ @@ -1178,7 +1269,7 @@ static inline u32 ieee80211_eml_trans_timeout_in_us(u16 eml_cap) IEEE80211_EML_CAP_TRANSITION_TIMEOUT); /* invalid values also just use 0 */ - if (!timeout || timeout > IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU) + if (!timeout || timeout > IEEE80211_EML_CAP_TRANSITION_TIMEOUT_64TU) return 0; return 128 * (1 << (timeout - 1)); diff --git a/include/linux/ieee80211-mesh.h b/include/linux/ieee80211-mesh.h index 4b829bcb38b6..7eb15834531c 100644 --- a/include/linux/ieee80211-mesh.h +++ b/include/linux/ieee80211-mesh.h @@ -28,12 +28,73 @@ struct ieee80211s_hdr { u8 eaddr2[ETH_ALEN]; } __packed __aligned(2); +struct ieee80211_mesh_hwmp_preq_target { + u8 flags; + u8 addr[ETH_ALEN]; + __le32 sn; +} __packed; + +struct ieee80211_mesh_hwmp_preq_top { + u8 flags; + u8 hopcount; + u8 ttl; + __le32 preq_id; + u8 orig_addr[ETH_ALEN]; + __le32 orig_sn; + + /* optional AE, lifetime, metric, target */ + u8 variable[]; +} __packed; + +struct ieee80211_mesh_hwmp_preq_bottom { + __le32 lifetime; + __le32 metric; + u8 target_count; + struct ieee80211_mesh_hwmp_preq_target targets[]; +} __packed; + +struct ieee80211_mesh_hwmp_prep_top { + u8 flags; + u8 hopcount; + u8 ttl; + u8 target_addr[ETH_ALEN]; + __le32 target_sn; + + /* optional Target External Address */ + u8 variable[]; +} __packed; + +struct ieee80211_mesh_hwmp_prep_bottom { + __le32 lifetime; + __le32 metric; + u8 orig_addr[ETH_ALEN]; + __le32 orig_sn; +} __packed; + +struct ieee80211_mesh_hwmp_perr_dst { + u8 flags; + u8 addr[ETH_ALEN]; + __le32 sn; + /* optional Destination External Address */ + u8 variable[]; +} __packed; + +struct ieee80211_mesh_hwmp_perr { + u8 ttl; + u8 number_of_dst; + /* Destinations */ + u8 variable[]; +} __packed; + /* Mesh flags */ #define MESH_FLAGS_AE_A4 0x1 #define MESH_FLAGS_AE_A5_A6 0x2 #define MESH_FLAGS_AE 0x3 #define MESH_FLAGS_PS_DEEP 0x4 +/* HWMP IE processing macros */ +#define AE_F (1<<6) + /** * enum ieee80211_preq_flags - mesh PREQ element flags * @@ -227,4 +288,155 @@ enum ieee80211_root_mode_identifier { IEEE80211_PROACTIVE_RANN = 4, }; +static inline bool ieee80211_mesh_preq_prep_ae_enabled(const u8 *ie) +{ + return ie[0] & AE_F; +} + +static inline struct ieee80211_mesh_hwmp_preq_bottom * +ieee80211_mesh_hwmp_preq_get_bottom(const u8 *ie) +{ + struct ieee80211_mesh_hwmp_preq_top *top = (void *)ie; + + return (void *)&top->variable[ + ieee80211_mesh_preq_prep_ae_enabled(ie) ? ETH_ALEN : 0]; +} + +static inline struct ieee80211_mesh_hwmp_prep_bottom * +ieee80211_mesh_hwmp_prep_get_bottom(const u8 *ie) +{ + struct ieee80211_mesh_hwmp_prep_top *top = (void *)ie; + + return (void *)&top->variable[ + ieee80211_mesh_preq_prep_ae_enabled(ie) ? ETH_ALEN : 0]; +} + +static inline struct ieee80211_mesh_hwmp_perr_dst * +ieee80211_mesh_hwmp_perr_get_dst(const u8 *ie, u8 dst_idx) +{ + struct ieee80211_mesh_hwmp_perr *perr_ie = (void *)ie; + struct ieee80211_mesh_hwmp_perr_dst *dst; + u8 *pos = perr_ie->variable; + int i; + + for (i = 0; i < dst_idx + 1; i++) { + dst = (void *)pos; + pos += sizeof(struct ieee80211_mesh_hwmp_perr_dst) + + ((dst->flags & AE_F) ? ETH_ALEN : 0) + /* Destination External Address */ + + 2 /* Reason Code */; + } + + return dst; +} + +static inline u8 * +ieee80211_mesh_hwmp_perr_get_addr(const u8 *ie, u8 dst_idx) +{ + struct ieee80211_mesh_hwmp_perr_dst *dst = + ieee80211_mesh_hwmp_perr_get_dst(ie, dst_idx); + + return dst->addr; +} + +static inline u32 +ieee80211_mesh_hwmp_perr_get_sn(const u8 *ie, u8 dst_idx) +{ + struct ieee80211_mesh_hwmp_perr_dst *dst = + ieee80211_mesh_hwmp_perr_get_dst(ie, dst_idx); + + return le32_to_cpu(dst->sn); +} + +static inline u16 +ieee80211_mesh_hwmp_perr_get_rcode(const u8 *ie, u8 dst_idx) +{ + struct ieee80211_mesh_hwmp_perr_dst *dst = + ieee80211_mesh_hwmp_perr_get_dst(ie, dst_idx); + + return get_unaligned_le16(&dst->variable[ + (dst->flags & AE_F) ? ETH_ALEN : 0]); +} + +/* IEEE Std 802.11-2016 9.4.2.113 PREQ element */ +static inline bool ieee80211_mesh_preq_size_ok(const u8 *pos, u8 elen) +{ + struct ieee80211_mesh_hwmp_preq_bottom *preq_elem_bottom = + ieee80211_mesh_hwmp_preq_get_bottom(pos); + u8 target_count; + int needed; + + /* Check if the element contains flags */ + needed = sizeof(struct ieee80211_mesh_hwmp_preq_top); + if (elen < needed) + return false; + + /* Check if the element contains target_count */ + needed += (ieee80211_mesh_preq_prep_ae_enabled(pos) ? ETH_ALEN : 0) + /* Originator External Address */ + + sizeof(struct ieee80211_mesh_hwmp_preq_bottom); + if (elen < needed) + return false; + + target_count = preq_elem_bottom->target_count; + /* IEEE Std 802.11-2016 Table 14-10 to 14-16 */ + if (target_count < 1) + return false; + + needed += target_count * sizeof(struct ieee80211_mesh_hwmp_preq_target); + return elen == needed; +} + +/* IEEE Std 802.11-2016 9.4.2.114 PREP element */ +static inline bool ieee80211_mesh_prep_size_ok(const u8 *pos, u8 elen) +{ + u8 needed; + + /* Check if the element contains flags */ + needed = sizeof(struct ieee80211_mesh_hwmp_prep_top); + if (elen < needed) + return false; + + needed += (ieee80211_mesh_preq_prep_ae_enabled(pos) ? ETH_ALEN : 0) + /* Target External Address */ + + sizeof(struct ieee80211_mesh_hwmp_prep_bottom); + return elen == needed; +} + +/* IEEE Std 802.11-2016 9.4.2.115 PERR element */ +static inline bool ieee80211_mesh_perr_size_ok(const u8 *pos, u8 elen) +{ + struct ieee80211_mesh_hwmp_perr *perr_elem = (void *)pos; + const u8 *start = pos; + u8 number_of_dst; + int needed; + int i; + + needed = sizeof(struct ieee80211_mesh_hwmp_perr); + + /* Check if the element contains number of dst */ + if (elen < needed) + return false; + + pos += sizeof(struct ieee80211_mesh_hwmp_perr); + number_of_dst = perr_elem->number_of_dst; + + for (i = 0; i < number_of_dst; i++) { + struct ieee80211_mesh_hwmp_perr_dst *dst = (void *)pos; + u8 dst_len = sizeof(struct ieee80211_mesh_hwmp_perr_dst); + + /* Check if the element contains flags */ + if (elen < pos - start + dst_len) + return false; + + dst_len += ((dst->flags & AE_F) ? ETH_ALEN : 0) + /* Destination External Address */ + + 2 /* Reason Code */; + needed += dst_len; + pos += dst_len; + } + + return elen == needed; +} + #endif /* LINUX_IEEE80211_MESH_H */ diff --git a/include/linux/ieee80211-s1g.h b/include/linux/ieee80211-s1g.h index 22dde4cbc1b0..3f9626ad3d97 100644 --- a/include/linux/ieee80211-s1g.h +++ b/include/linux/ieee80211-s1g.h @@ -556,7 +556,7 @@ static inline bool ieee80211_s1g_check_tim(const struct ieee80211_tim_ie *tim, */ err = ieee80211_s1g_find_target_block(&enc_blk, &target_aid, tim->virtual_map, - (const u8 *)tim + tim_len + 2); + (const u8 *)tim + tim_len); if (err) return false; diff --git a/include/linux/ieee80211-uhr.h b/include/linux/ieee80211-uhr.h index d199f3ebdba0..597c9e559261 100644 --- a/include/linux/ieee80211-uhr.h +++ b/include/linux/ieee80211-uhr.h @@ -8,12 +8,15 @@ #define LINUX_IEEE80211_UHR_H #include <linux/types.h> +#include <linux/bitfield.h> #include <linux/if_ether.h> +#include "ieee80211-eht.h" #define IEEE80211_UHR_OPER_PARAMS_DPS_ENA 0x0001 #define IEEE80211_UHR_OPER_PARAMS_NPCA_ENA 0x0002 #define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0004 #define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0008 +#define IEEE80211_UHR_OPER_PARAMS_DBE_BW 0x0070 struct ieee80211_uhr_operation { __le16 params; @@ -177,6 +180,29 @@ enum ieee80211_uhr_dbe_oper_bw { }; /** + * ieee80211_uhr_dbe_bw_mhz - get bandwidth in MHz from UHR DBE bandwidth + * @bw: UHR DBE bandwidth + * + * Return: the bandwidth in MHz, or -1 for invalid values + */ +static inline int ieee80211_uhr_dbe_bw_mhz(enum ieee80211_uhr_dbe_oper_bw bw) +{ + switch (bw) { + case IEEE80211_UHR_DBE_OPER_BW_40: + return 40; + case IEEE80211_UHR_DBE_OPER_BW_80: + return 80; + case IEEE80211_UHR_DBE_OPER_BW_160: + return 160; + case IEEE80211_UHR_DBE_OPER_BW_320_1: + case IEEE80211_UHR_DBE_OPER_BW_320_2: + return 320; + default: + return -1; + } +} + +/** * struct ieee80211_uhr_dbe_info - DBE operation information * * This structure is the "DBE Operation Parameters field" of @@ -334,6 +360,35 @@ ieee80211_uhr_npca_dis_subch_bitmap(const struct ieee80211_uhr_operation *oper) return npca->dis_subch_bmap; } +/* + * Note: cannot call this on the element coming from a beacon, + * must ensure ieee80211_uhr_oper_size_ok(..., false) first + */ +static inline const struct ieee80211_uhr_dbe_info * +ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper) +{ + const u8 *pos = oper->variable; + + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_ENA))) + return NULL; + + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA)) + pos += sizeof(struct ieee80211_uhr_dps_info); + + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) { + const struct ieee80211_uhr_npca_info *npca = (const void *)pos; + + pos += sizeof(*npca); + if (npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES)) + pos += sizeof(npca->dis_subch_bmap[0]); + } + + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA)) + pos += sizeof(struct ieee80211_uhr_p_edca_info); + + return (const void *)pos; +} + #define IEEE80211_UHR_MAC_CAP0_DPS_SUPP 0x01 #define IEEE80211_UHR_MAC_CAP0_DPS_ASSIST_SUPP 0x02 #define IEEE80211_UHR_MAC_CAP0_DPS_AP_STATIC_HCM_SUPP 0x04 @@ -372,6 +427,12 @@ ieee80211_uhr_npca_dis_subch_bitmap(const struct ieee80211_uhr_operation *oper) #define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES 0x08 #define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES 0x10 +struct ieee80211_uhr_cap_dbe { + u8 cap; + /* present 0, 1 or 2 times depending on _PRES bits */ + struct ieee80211_eht_mcs_nss_supp_bw eht_mcs_map[]; +} __packed; + /** * enum ieee80211_uhr_dbe_max_supported_bw - DBE Maximum Supported Bandwidth * @@ -391,33 +452,56 @@ enum ieee80211_uhr_dbe_max_supported_bw { }; struct ieee80211_uhr_cap_mac { - u8 mac_cap[5]; + u8 mac_cap[6]; +} __packed; + +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 0x00000001 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 0x00000002 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 0x00000004 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 0x00000008 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 0x00000010 +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 0x00000020 +#define IEEE80211_UHR_PHY_CAP_ELR_TX 0x00000040 +#define IEEE80211_UHR_PHY_CAP_ELR_RX 0x00000080 +#define IEEE80211_UHR_PHY_CAP_PART_BW_DL_MUMIMO 0x00000100 +#define IEEE80211_UHR_PHY_CAP_PART_BW_UL_MUMIMO 0x00000200 +#define IEEE80211_UHR_PHY_CAP_MCS15 0x00000400 +#define IEEE80211_UHR_PHY_CAP_2XLDPC_TX 0x00000800 +#define IEEE80211_UHR_PHY_CAP_2XLDPC_RX 0x00001000 +#define IEEE80211_UHR_PHY_CAP_UEQM_TX_MAX_NSS 0x00006000 +#define IEEE80211_UHR_PHY_CAP_UEQM_RX_MAX_NSS 0x00018000 +#define IEEE80211_UHR_PHY_CAP_CO_BF_JOINT_SOUNDING 0x00040000 +#define IEEE80211_UHR_PHY_CAP_IM_TX 0x00080000 +#define IEEE80211_UHR_PHY_CAP_IM_RX 0x00100000 +#define IEEE80211_UHR_PHY_CAP_CO_SR_MODE_1 0x00200000 +#define IEEE80211_UHR_PHY_CAP_CO_SR_MODE_2 0x00400000 +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_20_IN_PBW_20 0x00800000 +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_40_IN_PBW_40 0x01000000 +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_80 0x02000000 +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_160 0x04000000 +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_320 0x08000000 +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_20_IN_PBW_GE80 0x10000000 +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_40_IN_PBW_GE80 0x20000000 +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_60_IN_PBW_GE80 0x40000000 +#define IEEE80211_UHR_PHY_CAP_DRU_RRU_HYBRID_MODE 0x80000000 + +struct ieee80211_uhr_cap_phy { + __le32 cap; + u8 reserved; } __packed; struct ieee80211_uhr_cap { struct ieee80211_uhr_cap_mac mac; - /* DBE, PHY capabilities */ + struct ieee80211_uhr_cap_phy phy; + /* optional DBE capabilities */ u8 variable[]; } __packed; -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 0x01 -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 0x02 -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 0x04 -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 0x08 -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 0x10 -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 0x20 -#define IEEE80211_UHR_PHY_CAP_ELR_RX 0x40 -#define IEEE80211_UHR_PHY_CAP_ELR_TX 0x80 - -struct ieee80211_uhr_cap_phy { - u8 cap; -} __packed; - static inline bool ieee80211_uhr_capa_size_ok(const u8 *data, u8 len, bool from_ap) { const struct ieee80211_uhr_cap *cap = (const void *)data; - size_t needed = sizeof(*cap) + sizeof(struct ieee80211_uhr_cap_phy); + size_t needed = sizeof(*cap); if (len < needed) return false; @@ -427,42 +511,60 @@ static inline bool ieee80211_uhr_capa_size_ok(const u8 *data, u8 len, * in the UHR MAC Capabilities Information field. */ if (from_ap && cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) { - u8 dbe; + const struct ieee80211_uhr_cap_dbe *dbe; - needed += 1; + needed += sizeof(struct ieee80211_uhr_cap_dbe); if (len < needed) return false; - dbe = cap->variable[0]; + dbe = (const void *)cap->variable; - if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES) - needed += 3; + if (dbe->cap & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES) + needed += sizeof(dbe->eht_mcs_map[0]); - if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES) - needed += 3; + if (dbe->cap & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES) + needed += sizeof(dbe->eht_mcs_map[0]); } return len >= needed; } -static inline const struct ieee80211_uhr_cap_phy * -ieee80211_uhr_phy_cap(const struct ieee80211_uhr_cap *cap, bool from_ap) +#define IEEE80211_UHR_OM_PU_TO_128TU 11 + +/** + * ieee80211_uhr_capa_get_om_pu_to_us - get OM parameter update timeout in usec + * @cap: the UHR capability element, size must be validated + * + * Return: the OM parameter update timeout in usec, or -1 if it's not valid + */ +static inline int +ieee80211_uhr_capa_get_om_pu_to_us(const struct ieee80211_uhr_cap *cap) { - u8 offs = 0; + u8 timeout; - if (from_ap && cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) { - u8 dbe = cap->variable[0]; + timeout = u8_get_bits(cap->mac.mac_cap[3], + IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH); + timeout <<= 2; + timeout |= u8_get_bits(cap->mac.mac_cap[2], + IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW); - offs += 1; + if (timeout > IEEE80211_UHR_OM_PU_TO_128TU) + return -1; - if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES) - offs += 3; + if (!timeout) + return 0; - if (dbe & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES) - offs += 3; - } + return 128 << (timeout - 1); +} + +/* only valid from AP, must check ieee80211_uhr_capa_size_ok(..., true) */ +static inline const struct ieee80211_uhr_cap_dbe * +ieee80211_uhr_dbe_cap(const struct ieee80211_uhr_cap *cap) +{ + if (!(cap->mac.mac_cap[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP)) + return NULL; - return (const void *)&cap->variable[offs]; + return (const void *)cap->variable; } #define IEEE80211_SMD_INFO_CAPA_DL_DATA_FWD 0x01 @@ -476,4 +578,70 @@ struct ieee80211_smd_info { __le16 timeout; } __packed; +enum ieee80211_protected_uhr_action { + IEEE80211_PROTECTED_UHR_ACTION_LINK_RECONFIG_REQUEST = 0, + IEEE80211_PROTECTED_UHR_ACTION_LINK_RECONFIG_RESPONSE = 1, + IEEE80211_PROTECTED_UHR_ACTION_LINK_RECONFIG_NOTIFY = 2, +}; + +enum ieee80211_uhr_link_reconfig_request_type { + IEEE80211_UHR_LINK_RECONFIG_REQUEST_ST_PREP = 0, + IEEE80211_UHR_LINK_RECONFIG_REQUEST_ST_EXEC = 1, + IEEE80211_UHR_LINK_RECONFIG_REQUEST_OMP_REQUEST = 3, +}; + +enum ieee80211_uhr_link_reconfig_response_type { + IEEE80211_UHR_LINK_RECONFIG_RESPONSE_ST_PREP = 0, + IEEE80211_UHR_LINK_RECONFIG_RESPONSE_ST_EXEC = 1, +}; + +enum ieee80211_uhr_link_reconfig_notify_type { + IEEE80211_UHR_LINK_RECONFIG_NOTIFY_DL_DRAINED = 2, + IEEE80211_UHR_LINK_RECONFIG_NOTIFY_OMP_RESPONSE = 3, +}; + +enum ieee80211_uhr_mode_change_control { + IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_ID = 0x003f, + IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_ENABLE = 0x0040, + IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_UPDATE = 0x0080, + IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_LENGTH = 0x0f00, + IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_SPECIFIC = 0xf000, +}; + +enum ieee80211_uhr_mode_change_mode_id { + IEEE80211_UHR_MODE_CHANGE_MODE_ID_DPS = 0, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_NPCA = 1, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_DUO = 2, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_DSO = 3, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_P_EDCA = 4, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_ELR_RX = 5, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_AOM = 6, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_LLI = 7, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_CO_BF = 8, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_CO_SR = 9, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_EMLSR = 10, + IEEE80211_UHR_MODE_CHANGE_MODE_ID_DBE = 11, +}; + +struct ieee80211_uhr_mode_change_tuple { + __le16 control; + u8 variable[]; +} __packed; + +static inline int +ieee80211_uhr_mode_change_tuple_size(const struct ieee80211_uhr_mode_change_tuple *tuple) +{ + return sizeof(*tuple) + + le16_get_bits(tuple->control, + IEEE80211_UHR_MODE_CHANGE_CONTROL_MODE_LENGTH); +} + +#define for_each_uhr_mode_change_tuple(data, len, tuple) \ + for (tuple = (const void *)(data); \ + (len) - ((const u8 *)tuple - (data)) >= sizeof(*tuple) && \ + (len) - ((const u8 *)tuple - (data)) >= \ + ieee80211_uhr_mode_change_tuple_size(tuple); \ + tuple = (const void *)((const u8 *)tuple + \ + ieee80211_uhr_mode_change_tuple_size(tuple))) + #endif /* LINUX_IEEE80211_UHR_H */ diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 23f9df9be837..d40484451e9a 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1174,6 +1174,22 @@ struct ieee80211_mgmt { u8 control; u8 variable[]; } __packed eml_omn; + struct { + u8 dialog_token; + u8 type; + u8 variable[]; + } __packed uhr_link_reconf_req; + struct { + u8 dialog_token; + u8 type; + u8 count; + u8 variable[]; + } __packed uhr_link_reconf_resp; + struct { + u8 dialog_token; + u8 type; + u8 variable[]; + } __packed uhr_link_reconf_notif; }; } __packed action; DECLARE_FLEX_ARRAY(u8, body); /* Generic frame body */ @@ -1837,6 +1853,7 @@ enum ieee80211_category { WLAN_CATEGORY_VHT = 21, WLAN_CATEGORY_S1G = 22, WLAN_CATEGORY_PROTECTED_EHT = 37, + WLAN_CATEGORY_PROTECTED_UHR = 43, WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, WLAN_CATEGORY_VENDOR_SPECIFIC = 127, }; @@ -2236,6 +2253,7 @@ struct ieee80211_multiple_bssid_configuration { #define WLAN_AKM_SUITE_WFA_DPP SUITE(WLAN_OUI_WFA, 2) #define WLAN_MAX_KEY_LEN 32 +#define WLAN_MAX_SECURE_LTF_KEYSEED_LEN 48 #define WLAN_PMK_NAME_LEN 16 #define WLAN_PMKID_LEN 16 diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index c5fe3b2a53e8..75673b8bffcb 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -36,31 +36,60 @@ struct br_ip_list { struct br_ip addr; }; -#define BR_HAIRPIN_MODE BIT(0) -#define BR_BPDU_GUARD BIT(1) -#define BR_ROOT_BLOCK BIT(2) -#define BR_MULTICAST_FAST_LEAVE BIT(3) -#define BR_ADMIN_COST BIT(4) -#define BR_LEARNING BIT(5) -#define BR_FLOOD BIT(6) +enum bridge_flags_bit { + BR_HAIRPIN_MODE_BIT, + BR_BPDU_GUARD_BIT, + BR_ROOT_BLOCK_BIT, + BR_MULTICAST_FAST_LEAVE_BIT, + BR_ADMIN_COST_BIT, + BR_LEARNING_BIT, + BR_FLOOD_BIT, + BR_PROMISC_BIT, + BR_PROXYARP_BIT, + BR_LEARNING_SYNC_BIT, + BR_PROXYARP_WIFI_BIT, + BR_MCAST_FLOOD_BIT, + BR_MULTICAST_TO_UNICAST_BIT, + BR_VLAN_TUNNEL_BIT, + BR_BCAST_FLOOD_BIT, + BR_NEIGH_SUPPRESS_BIT, + BR_ISOLATED_BIT, + BR_MRP_AWARE_BIT, + BR_MRP_LOST_CONT_BIT, + BR_MRP_LOST_IN_CONT_BIT, + BR_TX_FWD_OFFLOAD_BIT, + BR_PORT_LOCKED_BIT, + BR_PORT_MAB_BIT, + BR_NEIGH_VLAN_SUPPRESS_BIT, + BR_NEIGH_FORWARD_GRAT_BIT, +}; + +#define BR_HAIRPIN_MODE BIT(BR_HAIRPIN_MODE_BIT) +#define BR_BPDU_GUARD BIT(BR_BPDU_GUARD_BIT) +#define BR_ROOT_BLOCK BIT(BR_ROOT_BLOCK_BIT) +#define BR_MULTICAST_FAST_LEAVE BIT(BR_MULTICAST_FAST_LEAVE_BIT) +#define BR_ADMIN_COST BIT(BR_ADMIN_COST_BIT) +#define BR_LEARNING BIT(BR_LEARNING_BIT) +#define BR_FLOOD BIT(BR_FLOOD_BIT) #define BR_AUTO_MASK (BR_FLOOD | BR_LEARNING) -#define BR_PROMISC BIT(7) -#define BR_PROXYARP BIT(8) -#define BR_LEARNING_SYNC BIT(9) -#define BR_PROXYARP_WIFI BIT(10) -#define BR_MCAST_FLOOD BIT(11) -#define BR_MULTICAST_TO_UNICAST BIT(12) -#define BR_VLAN_TUNNEL BIT(13) -#define BR_BCAST_FLOOD BIT(14) -#define BR_NEIGH_SUPPRESS BIT(15) -#define BR_ISOLATED BIT(16) -#define BR_MRP_AWARE BIT(17) -#define BR_MRP_LOST_CONT BIT(18) -#define BR_MRP_LOST_IN_CONT BIT(19) -#define BR_TX_FWD_OFFLOAD BIT(20) -#define BR_PORT_LOCKED BIT(21) -#define BR_PORT_MAB BIT(22) -#define BR_NEIGH_VLAN_SUPPRESS BIT(23) +#define BR_PROMISC BIT(BR_PROMISC_BIT) +#define BR_PROXYARP BIT(BR_PROXYARP_BIT) +#define BR_LEARNING_SYNC BIT(BR_LEARNING_SYNC_BIT) +#define BR_PROXYARP_WIFI BIT(BR_PROXYARP_WIFI_BIT) +#define BR_MCAST_FLOOD BIT(BR_MCAST_FLOOD_BIT) +#define BR_MULTICAST_TO_UNICAST BIT(BR_MULTICAST_TO_UNICAST_BIT) +#define BR_VLAN_TUNNEL BIT(BR_VLAN_TUNNEL_BIT) +#define BR_BCAST_FLOOD BIT(BR_BCAST_FLOOD_BIT) +#define BR_NEIGH_SUPPRESS BIT(BR_NEIGH_SUPPRESS_BIT) +#define BR_ISOLATED BIT(BR_ISOLATED_BIT) +#define BR_MRP_AWARE BIT(BR_MRP_AWARE_BIT) +#define BR_MRP_LOST_CONT BIT(BR_MRP_LOST_CONT_BIT) +#define BR_MRP_LOST_IN_CONT BIT(BR_MRP_LOST_IN_CONT_BIT) +#define BR_TX_FWD_OFFLOAD BIT(BR_TX_FWD_OFFLOAD_BIT) +#define BR_PORT_LOCKED BIT(BR_PORT_LOCKED_BIT) +#define BR_PORT_MAB BIT(BR_PORT_MAB_BIT) +#define BR_NEIGH_VLAN_SUPPRESS BIT(BR_NEIGH_VLAN_SUPPRESS_BIT) +#define BR_NEIGH_FORWARD_GRAT BIT(BR_NEIGH_FORWARD_GRAT_BIT) #define BR_DEFAULT_AGEING_TIME (300 * HZ) diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index 80166eb62f41..5f3e206c7a73 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h @@ -22,6 +22,7 @@ struct tun_msg_ctl { #if defined(CONFIG_TUN) || defined(CONFIG_TUN_MODULE) struct socket *tun_get_socket(struct file *); struct ptr_ring *tun_get_tx_ring(struct file *file); +void tun_wake_queue(struct file *file, int consumed); static inline bool tun_is_xdp_frame(void *ptr) { @@ -55,6 +56,8 @@ static inline struct ptr_ring *tun_get_tx_ring(struct file *f) return ERR_PTR(-EINVAL); } +static inline void tun_wake_queue(struct file *f, int consumed) {} + static inline bool tun_is_xdp_frame(void *ptr) { return false; diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 073b30a9b850..3a2d35a9f307 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -92,15 +92,166 @@ struct ip_mc_list { struct rcu_head rcu; }; +/* RFC3376, relevant sections: + * - 4.1.1. Maximum Response Code + * - 4.1.7. QQIC (Querier's Query Interval Code) + * + * For both MRC and QQIC, values >= 128 use the same floating-point + * encoding as follows: + * + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * |1| exp | mant | + * +-+-+-+-+-+-+-+-+ + */ +#define IGMPV3_FP_EXP(value) (((value) >> 4) & 0x07) +#define IGMPV3_FP_MAN(value) ((value) & 0x0f) + +/* IGMPv3 floating-point exponential field min threshold */ +#define IGMPV3_EXP_MIN_THRESHOLD 128 +/* IGMPv3 FP max threshold (mant = 0xF, exp = 7) -> 31744 */ +#define IGMPV3_EXP_MAX_THRESHOLD 31744 + +/* V3 exponential field encoding */ + +/* IGMPv3 MRC/QQIC 8-bit exponential field encode + * + * RFC3376, 4.1.1 & 4.1.7. defines only the decoding formula: + * MRT/QQI = (mant | 0x10) << (exp + 3) + * + * but does NOT define the encoding procedure. To derive exponent: + * + * For any value of mantissa and exponent, the decoding formula + * indicates that the "hidden bit" (0x10) is shifted 4 bits left + * to sit above the 4-bit mantissa. The RFC again shifts this + * entire block left by (exp + 3) to reconstruct the value. + * So, 'hidden bit' is the MSB which is shifted by (4 + exp + 3). + * + * Total left shift of the 'hidden bit' = 4 + (exp + 3) = exp + 7. + * This is the MSB at the 0-based bit position: (exp + 7). + * Since fls() is 1-based, fls(value) - 1 = exp + 7. + * + * Therefore: + * exp = fls(value) - 8 + * mant = (value >> (exp + 3)) & 0x0F + * + * Final encoding formula: + * 0x80 | (exp << 4) | mant + * + * Example (value = 3200): + * 0 1 + * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0| (value = 3200) + * | ^-^-mant^ ^..(exp+3)..^| exp = 4, mant = 9 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Encoded: + * 0x80 | (4 << 4) | 9 = 0xC9 + */ +static inline u8 igmpv3_exp_field_encode(unsigned long value) +{ + u8 mc_exp, mc_man; + + /* MRC/QQIC < 128 is literal */ + if (value < IGMPV3_EXP_MIN_THRESHOLD) + return value; + + /* Saturate at max representable (mant = 0xF, exp = 7) -> 31744 */ + if (value >= IGMPV3_EXP_MAX_THRESHOLD) + return 0xFF; + + mc_exp = fls(value) - 8; + mc_man = (value >> (mc_exp + 3)) & 0x0F; + + return 0x80 | (mc_exp << 4) | mc_man; +} + +/* Calculate Maximum Response Code from Max Resp Time + * + * RFC3376, relevant sections: + * - 4.1.1. Maximum Response Code + * - 8.3. Query Response Interval + * + * MRC represents the encoded form of Max Resp Time (MRT); once + * decoded, the resulting value is in units of 0.1 seconds (100 ms). + */ +static inline u8 igmpv3_mrc(unsigned long mrt) +{ + return igmpv3_exp_field_encode(mrt); +} + +/* Calculate Querier's Query Interval Code from Querier's Query Interval + * + * RFC3376, relevant sections: + * - 4.1.7. QQIC (Querier's Query Interval Code) + * - 8.2. Query Interval + * - 8.12. Older Version Querier Present Timeout + * (the [Query Interval] in the last Query received) + * + * QQIC represents the encoded form of Querier's Query Interval (QQI); + * once decoded, the resulting value is in units of seconds. + */ +static inline u8 igmpv3_qqic(unsigned long qi) +{ + return igmpv3_exp_field_encode(qi); +} + /* V3 exponential field decoding */ -#define IGMPV3_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value)) -#define IGMPV3_EXP(thresh, nbmant, nbexp, value) \ - ((value) < (thresh) ? (value) : \ - ((IGMPV3_MASK(value, nbmant) | (1<<(nbmant))) << \ - (IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp)))) - -#define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value) -#define IGMPV3_MRC(value) IGMPV3_EXP(0x80, 4, 3, value) + +/* IGMPv3 MRC/QQIC 8-bit exponential field decode + * + * RFC3376, 4.1.1 & 4.1.7. defines the decoding formula: + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * |1| exp | mant | + * +-+-+-+-+-+-+-+-+ + * Max Resp Time = (mant | 0x10) << (exp + 3) + * QQI = (mant | 0x10) << (exp + 3) + */ +static inline unsigned long igmpv3_exp_field_decode(const u8 code) +{ + if (code < IGMPV3_EXP_MIN_THRESHOLD) { + return code; + } else { + unsigned long mc_man, mc_exp; + + mc_exp = IGMPV3_FP_EXP(code); + mc_man = IGMPV3_FP_MAN(code); + + return (mc_man | 0x10) << (mc_exp + 3); + } +} + +/* Calculate Max Resp Time from Maximum Response Code + * + * RFC3376, relevant sections: + * - 4.1.1. Maximum Response Code + * - 8.3. Query Response Interval + * + * After decode, MRC represents the Maximum Response Time (MRT) in + * units of 0.1 seconds (100 ms). + */ +static inline unsigned long igmpv3_mrt(const struct igmpv3_query *ih3) +{ + return igmpv3_exp_field_decode(ih3->code); +} + +/* Calculate Querier's Query Interval from Querier's Query Interval Code + * + * RFC3376, relevant sections: + * - 4.1.7. QQIC (Querier's Query Interval Code) + * - 8.2. Query Interval + * - 8.12. Older Version Querier Present Timeout + * (the [Query Interval] in the last Query received) + * + * After decode, QQIC represents the Querier's Query Interval in units + * of seconds. + */ +static inline unsigned long igmpv3_qqi(const struct igmpv3_query *ih3) +{ + return igmpv3_exp_field_decode(ih3->qqic); +} static inline int ip_mc_may_pull(struct sk_buff *skb, unsigned int len) { diff --git a/include/linux/init.h b/include/linux/init.h index 40331923b9f4..6326c61e2332 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -47,7 +47,7 @@ #define __initdata __section(".init.data") #define __initconst __section(".init.rodata") #define __exitdata __section(".exit.data") -#define __exit_call __used __section(".exitcall.exit") +#define __exit_call __maybe_unused __section(".exitcall.exit") /* * modpost check for section mismatches during the kernel build. diff --git a/include/linux/iommu.h b/include/linux/iommu.h index e587d4ac4d33..d20aa6f6863a 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -345,12 +345,6 @@ struct iommu_pages_list { /** * struct iommu_iotlb_gather - Range information for a pending IOTLB flush * - * @start: IOVA representing the start of the range to be flushed - * @end: IOVA representing the end of the range to be flushed (inclusive) - * @pgsize: The interval at which to perform the flush - * @freelist: Removed pages to free after sync - * @queued: Indicates that the flush will be queued - * * This structure is intended to be updated by multiple calls to the * ->unmap() function in struct iommu_ops before eventually being passed * into ->iotlb_sync(). Drivers can add pages to @freelist to be freed after @@ -359,10 +353,44 @@ struct iommu_pages_list { * later instead of ->iotlb_sync(), so drivers may optimise accordingly. */ struct iommu_iotlb_gather { + /** @start: IOVA representing the start of the range to be flushed */ unsigned long start; + /** + * @end: IOVA representing the end of the range to be + * flushed (inclusive) + */ unsigned long end; - size_t pgsize; + + union { + /** + * @pgsize: The interval at which to perform the flush, only + * used by arm-smmu-v3 + */ + size_t pgsize; + struct { + /** + * @pt.leaf_levels_bitmap: Bitmap of generic_pt + * levels where leaf entries were unmapped. Bit 0 + * means the leaf only level. If 0 no leafs + * were unmapped. + */ + u8 leaf_levels_bitmap; + /** + * @pt.table_levels_bitmap: Bitmap of generic_pt levels + * of table entries that were removed. Bit 0 is never + * set, bit 1 means a table of all leafs was removed. + * When freelist is empty this must be 0. + */ + u8 table_levels_bitmap; + } pt; + }; + + /** + * @freelist: Removed pages to free after sync, only used by + * iommupt + */ struct iommu_pages_list freelist; + /** @queued: True if the gather will be completed with a flush all */ bool queued; }; @@ -547,6 +575,7 @@ iommu_copy_struct_from_full_user_array(void *kdst, size_t kdst_entry_size, user_array->entry_num * user_array->entry_len)) return -EFAULT; + return 0; } /* Copy item by item */ diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h index 4b348836de7a..61af3a5bea09 100644 --- a/include/linux/irqchip/riscv-imsic.h +++ b/include/linux/irqchip/riscv-imsic.h @@ -40,6 +40,9 @@ struct imsic_local_config { phys_addr_t msi_pa; void __iomem *msi_va; + + /* Number of guest interrupt files per-HART */ + u32 nr_guest_files; }; struct imsic_global_config { @@ -68,7 +71,7 @@ struct imsic_global_config { /* Number of guest interrupt identities */ u32 nr_guest_ids; - /* Number of guest interrupt files per core */ + /* Number of guest interrupt files across all HARTs */ u32 nr_guest_files; /* Per-CPU IMSIC addresses */ diff --git a/include/linux/irqdomain_defs.h b/include/linux/irqdomain_defs.h index 36653e2ee1c9..3a03bdfeeee9 100644 --- a/include/linux/irqdomain_defs.h +++ b/include/linux/irqdomain_defs.h @@ -17,7 +17,6 @@ enum irq_domain_bus_token { DOMAIN_BUS_PLATFORM_MSI, DOMAIN_BUS_NEXUS, DOMAIN_BUS_IPI, - DOMAIN_BUS_FSL_MC_MSI, DOMAIN_BUS_TI_SCI_INTA_MSI, DOMAIN_BUS_WAKEUP, DOMAIN_BUS_VMD_MSI, diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 7e785aa6d35d..b68561187e90 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -63,9 +63,6 @@ void __jbd2_debug(int level, const char *file, const char *func, #define jbd2_debug(n, fmt, a...) no_printk(fmt, ##a) #endif -extern void *jbd2_alloc(size_t size, gfp_t flags); -extern void jbd2_free(void *ptr, size_t size); - #define JBD2_MIN_JOURNAL_BLOCKS 1024 #define JBD2_DEFAULT_FAST_COMMIT_BLOCKS 256 diff --git a/include/linux/jz4740-adc.h b/include/linux/jz4740-adc.h deleted file mode 100644 index 19d995c8bf06..000000000000 --- a/include/linux/jz4740-adc.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef __LINUX_JZ4740_ADC -#define __LINUX_JZ4740_ADC - -struct device; - -/* - * jz4740_adc_set_config - Configure a JZ4740 adc device - * @dev: Pointer to a jz4740-adc device - * @mask: Mask for the config value to be set - * @val: Value to be set - * - * This function can be used by the JZ4740 ADC mfd cells to configure their - * options in the shared config register. -*/ -int jz4740_adc_set_config(struct device *dev, uint32_t mask, uint32_t val); - -#define JZ_ADC_CONFIG_SPZZ BIT(31) -#define JZ_ADC_CONFIG_EX_IN BIT(30) -#define JZ_ADC_CONFIG_DNUM_MASK (0x7 << 16) -#define JZ_ADC_CONFIG_DMA_ENABLE BIT(15) -#define JZ_ADC_CONFIG_XYZ_MASK (0x2 << 13) -#define JZ_ADC_CONFIG_SAMPLE_NUM_MASK (0x7 << 10) -#define JZ_ADC_CONFIG_CLKDIV_MASK (0xf << 5) -#define JZ_ADC_CONFIG_BAT_MB BIT(4) - -#define JZ_ADC_CONFIG_DNUM(dnum) ((dnum) << 16) -#define JZ_ADC_CONFIG_XYZ_OFFSET(dnum) ((xyz) << 13) -#define JZ_ADC_CONFIG_SAMPLE_NUM(x) ((x) << 10) -#define JZ_ADC_CONFIG_CLKDIV(div) ((div) << 5) - -#endif diff --git a/include/linux/kcov.h b/include/linux/kcov.h index 0143358874b0..895b761b2db1 100644 --- a/include/linux/kcov.h +++ b/include/linux/kcov.h @@ -21,8 +21,6 @@ enum kcov_mode { KCOV_MODE_TRACE_PC = 2, /* Collecting comparison operands mode. */ KCOV_MODE_TRACE_CMP = 3, - /* The process owns a KCOV remote reference. */ - KCOV_MODE_REMOTE = 4, }; #define KCOV_IN_CTXSW (1 << 30) @@ -43,11 +41,11 @@ do { \ /* See Documentation/dev-tools/kcov.rst for usage details. */ void kcov_remote_start(u64 handle); void kcov_remote_stop(void); -u64 kcov_common_handle(void); +struct kcov_common_handle_id kcov_common_handle(void); -static inline void kcov_remote_start_common(u64 id) +static inline void kcov_remote_start_common(struct kcov_common_handle_id id) { - kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id)); + kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id.val)); } static inline void kcov_remote_start_usb(u64 id) @@ -99,11 +97,11 @@ static inline void kcov_prepare_switch(struct task_struct *t) {} static inline void kcov_finish_switch(struct task_struct *t) {} static inline void kcov_remote_start(u64 handle) {} static inline void kcov_remote_stop(void) {} -static inline u64 kcov_common_handle(void) +static inline struct kcov_common_handle_id kcov_common_handle(void) { - return 0; + return (struct kcov_common_handle_id){}; } -static inline void kcov_remote_start_common(u64 id) {} +static inline void kcov_remote_start_common(struct kcov_common_handle_id id) {} static inline void kcov_remote_start_usb(u64 id) {} static inline void kcov_remote_start_usb_softirq(u64 id) {} static inline void kcov_remote_stop_softirq(void) {} diff --git a/include/linux/kho/abi/block.h b/include/linux/kho/abi/block.h new file mode 100644 index 000000000000..d06d64b963be --- /dev/null +++ b/include/linux/kho/abi/block.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2026, Google LLC. + * Pasha Tatashin <pasha.tatashin@soleen.com> + */ + +/** + * DOC: KHO Serialization Blocks ABI + * + * Subsystems using the KHO Serialization Blocks framework rely on the stable + * Application Binary Interface defined below to pass serialized state from a + * pre-update kernel to a post-update kernel. + * + * This interface is a contract. Any modification to the structure fields, + * compatible strings, or the layout of the `__packed` serialization + * structures defined here constitutes a breaking change. Such changes require + * incrementing the version number in the `KHO_FDT_COMPATIBLE` string to + * prevent a new kernel from misinterpreting data from an old kernel. + * + * Changes are allowed provided the compatibility version is incremented; + * however, backward/forward compatibility is only guaranteed for kernels + * supporting the same ABI version. + */ + +#ifndef _LINUX_KHO_ABI_BLOCK_H +#define _LINUX_KHO_ABI_BLOCK_H + +#include <asm/page.h> +#include <linux/types.h> + +/** + * KHO_BLOCK_SIZE - The size of each serialization block. + * + * This is defined as PAGE_SIZE. PAGE_SIZE is ABI compliant because live + * update between kernels with different page sizes is not supported by KHO. + */ +#define KHO_BLOCK_SIZE PAGE_SIZE + +/** + * struct kho_block_header_ser - Header for the serialized data block. + * @next: Physical address of the next struct kho_block_header_ser. + * @count: The number of entries that immediately follow this header in the + * memory block. + * + * This structure is located at the beginning of a block of physical memory + * preserved across a kexec. It provides the necessary metadata to interpret + * the array of entries that follow. + */ +struct kho_block_header_ser { + u64 next; + u64 count; +} __packed; + +#endif /* _LINUX_KHO_ABI_BLOCK_H */ diff --git a/include/linux/kho/abi/kexec_handover.h b/include/linux/kho/abi/kexec_handover.h index db9bda6dd310..5e2eb8519bda 100644 --- a/include/linux/kho/abi/kexec_handover.h +++ b/include/linux/kho/abi/kexec_handover.h @@ -64,7 +64,7 @@ * Root KHO Node (/): * - compatible: "kho-v3" * - * Indentifies the overall KHO ABI version. + * Identifies the overall KHO ABI version. * * - preserved-memory-map: u64 * @@ -90,7 +90,7 @@ */ /* The compatible string for the KHO FDT root node. */ -#define KHO_FDT_COMPATIBLE "kho-v3" +#define KHO_FDT_COMPATIBLE "kho-v4" /* The FDT property for the preserved memory map. */ #define KHO_FDT_MEMORY_MAP_PROP_NAME "preserved-memory-map" diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h index 46750a0ddf88..288076de6d4a 100644 --- a/include/linux/kho/abi/luo.h +++ b/include/linux/kho/abi/luo.h @@ -10,11 +10,11 @@ * * Live Update Orchestrator uses the stable Application Binary Interface * defined below to pass state from a pre-update kernel to a post-update - * kernel. The ABI is built upon the Kexec HandOver framework and uses a - * Flattened Device Tree to describe the preserved data. + * kernel. The ABI is built upon the Kexec HandOver framework and registers + * the central `struct luo_ser` via the KHO raw subtree API. * - * This interface is a contract. Any modification to the FDT structure, node - * properties, compatible strings, or the layout of the `__packed` serialization + * This interface is a contract. Any modification to the structure fields, + * compatible strings, or the layout of the `__packed` serialization * structures defined here constitutes a breaking change. Such changes require * incrementing the version number in the relevant `_COMPATIBLE` string to * prevent a new kernel from misinterpreting data from an old kernel. @@ -23,68 +23,20 @@ * however, backward/forward compatibility is only guaranteed for kernels * supporting the same ABI version. * - * FDT Structure Overview: + * KHO Structure Overview: * The entire LUO state is encapsulated within a single KHO entry named "LUO". - * This entry contains an FDT with the following layout: - * - * .. code-block:: none - * - * / { - * compatible = "luo-v1"; - * liveupdate-number = <...>; - * - * luo-session { - * compatible = "luo-session-v1"; - * luo-session-header = <phys_addr_of_session_header_ser>; - * }; - * - * luo-flb { - * compatible = "luo-flb-v1"; - * luo-flb-header = <phys_addr_of_flb_header_ser>; - * }; - * }; - * - * Main LUO Node (/): - * - * - compatible: "luo-v1" - * Identifies the overall LUO ABI version. - * - liveupdate-number: u64 - * A counter tracking the number of successful live updates performed. - * - * Session Node (luo-session): - * This node describes all preserved user-space sessions. - * - * - compatible: "luo-session-v1" - * Identifies the session ABI version. - * - luo-session-header: u64 - * The physical address of a `struct luo_session_header_ser`. This structure - * is the header for a contiguous block of memory containing an array of - * `struct luo_session_ser`, one for each preserved session. - * - * File-Lifecycle-Bound Node (luo-flb): - * This node describes all preserved global objects whose lifecycle is bound - * to that of the preserved files (e.g., shared IOMMU state). - * - * - compatible: "luo-flb-v1" - * Identifies the FLB ABI version. - * - luo-flb-header: u64 - * The physical address of a `struct luo_flb_header_ser`. This structure is - * the header for a contiguous block of memory containing an array of - * `struct luo_flb_ser`, one for each preserved global object. + * This entry contains the `struct luo_ser` structure. * * Serialization Structures: - * The FDT properties point to memory regions containing arrays of simple, - * `__packed` structures. These structures contain the actual preserved state. - * - * - struct luo_session_header_ser: - * Header for the session array. Contains the total page count of the - * preserved memory block and the number of `struct luo_session_ser` - * entries that follow. + * - struct luo_ser: + * The central ABI structure that contains the overall state of the LUO. + * It includes the compatibility string, the liveupdate-number, and pointers + * to sessions and FLBs. * * - struct luo_session_ser: * Metadata for a single session, including its name and a physical pointer - * to another preserved memory block containing an array of - * `struct luo_file_ser` for all files in that session. + * to the first `struct kho_block_header_ser` for all files in that session. + * Multiple blocks are linked via the `next` field in the header. * * - struct luo_file_ser: * Metadata for a single preserved file. Contains the `compatible` string to @@ -105,17 +57,32 @@ #ifndef _LINUX_KHO_ABI_LUO_H #define _LINUX_KHO_ABI_LUO_H +#include <linux/align.h> +#include <linux/kho/abi/block.h> #include <uapi/linux/liveupdate.h> /* - * The LUO FDT hooks all LUO state for sessions, fds, etc. - * In the root it also carries "liveupdate-number" 64-bit property that - * corresponds to the number of live-updates performed on this machine. + * The LUO state is registered under this KHO entry name. */ -#define LUO_FDT_SIZE PAGE_SIZE -#define LUO_FDT_KHO_ENTRY_NAME "LUO" -#define LUO_FDT_COMPATIBLE "luo-v1" -#define LUO_FDT_LIVEUPDATE_NUM "liveupdate-number" +#define LUO_KHO_ENTRY_NAME "LUO" +#define LUO_ABI_COMPATIBLE "luo-v5" +#define LUO_ABI_COMPAT_LEN ALIGN(sizeof(LUO_ABI_COMPATIBLE), 8) + +/** + * struct luo_ser - Centralized LUO ABI header. + * @compatible: Compatibility string identifying the LUO ABI version. + * @liveupdate_num: A counter tracking the number of successful live updates. + * @sessions_pa: Physical address of the first session block header. + * @flbs_pa: Physical address of the FLB header. + * + * This structure is the root of all preserved LUO state. + */ +struct luo_ser { + char compatible[LUO_ABI_COMPAT_LEN]; + u64 liveupdate_num; + u64 sessions_pa; + u64 flbs_pa; +} __packed; #define LIVEUPDATE_HNDL_COMPAT_LENGTH 48 @@ -125,7 +92,7 @@ * @data: Private data * @token: User provided token for this file * - * If this structure is modified, LUO_SESSION_COMPATIBLE must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_file_ser { char compatible[LIVEUPDATE_HNDL_COMPAT_LENGTH]; @@ -135,9 +102,10 @@ struct luo_file_ser { /** * struct luo_file_set_ser - Represents the serialized metadata for file set - * @files: The physical address of a contiguous memory block that holds - * the serialized state of files (array of luo_file_ser) in this file - * set. + * @files: The physical address of the first `struct kho_block_header_ser`. + * This structure is the header for a block of memory containing + * an array of `struct luo_file_ser` entries. Multiple blocks are + * linked via the `next` field in the header. * @count: The total number of files that were part of this session during * serialization. Used for iteration and validation during * restoration. @@ -147,30 +115,6 @@ struct luo_file_set_ser { u64 count; } __packed; -/* - * LUO FDT session node - * LUO_FDT_SESSION_HEADER: is a u64 physical address of struct - * luo_session_header_ser - */ -#define LUO_FDT_SESSION_NODE_NAME "luo-session" -#define LUO_FDT_SESSION_COMPATIBLE "luo-session-v2" -#define LUO_FDT_SESSION_HEADER "luo-session-header" - -/** - * struct luo_session_header_ser - Header for the serialized session data block. - * @count: The number of `struct luo_session_ser` entries that immediately - * follow this header in the memory block. - * - * This structure is located at the beginning of a contiguous block of - * physical memory preserved across the kexec. It provides the necessary - * metadata to interpret the array of session entries that follow. - * - * If this structure is modified, `LUO_FDT_SESSION_COMPATIBLE` must be updated. - */ -struct luo_session_header_ser { - u64 count; -} __packed; - /** * struct luo_session_ser - Represents the serialized metadata for a LUO session. * @name: The unique name of the session, provided by the userspace at @@ -182,7 +126,7 @@ struct luo_session_header_ser { * session) is created and passed to the new kernel, allowing it to reconstruct * the session context. * - * If this structure is modified, `LUO_FDT_SESSION_COMPATIBLE` must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_session_ser { char name[LIVEUPDATE_SESSION_NAME_LENGTH]; @@ -192,10 +136,6 @@ struct luo_session_ser { /* The max size is set so it can be reliably used during in serialization */ #define LIVEUPDATE_FLB_COMPAT_LENGTH 48 -#define LUO_FDT_FLB_NODE_NAME "luo-flb" -#define LUO_FDT_FLB_COMPATIBLE "luo-flb-v1" -#define LUO_FDT_FLB_HEADER "luo-flb-header" - /** * struct luo_flb_header_ser - Header for the serialized FLB data block. * @pgcnt: The total number of pages occupied by the entire preserved memory @@ -205,11 +145,9 @@ struct luo_session_ser { * in the memory block. * * This structure is located at the physical address specified by the - * `LUO_FDT_FLB_HEADER` FDT property. It provides the new kernel with the - * necessary information to find and iterate over the array of preserved - * File-Lifecycle-Bound objects and to manage the underlying memory. + * flbs_pa in luo_ser. * - * If this structure is modified, LUO_FDT_FLB_COMPATIBLE must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_flb_header_ser { u64 pgcnt; @@ -231,7 +169,7 @@ struct luo_flb_header_ser { * passed to the new kernel. Each entry allows the LUO core to restore one * global, shared object. * - * If this structure is modified, LUO_FDT_FLB_COMPATIBLE must be updated. + * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated. */ struct luo_flb_ser { char name[LIVEUPDATE_FLB_COMPAT_LENGTH]; diff --git a/include/linux/kho_block.h b/include/linux/kho_block.h new file mode 100644 index 000000000000..93a7cc2be5f5 --- /dev/null +++ b/include/linux/kho_block.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2026, Google LLC. + * Pasha Tatashin <pasha.tatashin@soleen.com> + */ + +#ifndef _LINUX_KHO_BLOCK_H +#define _LINUX_KHO_BLOCK_H + +#include <linux/list.h> +#include <linux/types.h> +#include <linux/kho/abi/block.h> + +/** + * struct kho_block - Internal representation of a serialization block. + * @list: List head for linking blocks in memory. + * @ser: Pointer to the serialized header in preserved memory. + */ +struct kho_block { + struct list_head list; + struct kho_block_header_ser *ser; +}; + +/** + * struct kho_block_set - A set of blocks containing serialized entries of the same type. + * @blocks: The list of serialization blocks (struct kho_block). + * @nblocks: The number of allocated serialization blocks. + * @head_pa: Physical address of the first block header. + * @entry_size: The size of each entry in the blocks. + * @count_per_block: The maximum number of entries each block can hold. + * @incoming: True if this block set was restored from the previous kernel. + * + * Note: Synchronization and locking are the responsibility of the caller. + * The block set structure itself is not internally synchronized. + */ +struct kho_block_set { + struct list_head blocks; + long nblocks; + u64 head_pa; + size_t entry_size; + u64 count_per_block; + bool incoming; +}; + +/** + * struct kho_block_set_it - Iterator for serializing entries into blocks. + * @bs: The block set being iterated. + * @block: The current block. + * @i: The current entry index within @block. + */ +struct kho_block_set_it { + struct kho_block_set *bs; + struct kho_block *block; + u64 i; +}; + +/** + * KHO_BLOCK_SET_INIT - Initialize a static kho_block_set. + * @_name: Name of the kho_block_set variable. + * @_entry_size: The size of each entry in the block set. + */ +#define KHO_BLOCK_SET_INIT(_name, _entry_size) { \ + .blocks = LIST_HEAD_INIT((_name).blocks), \ + .entry_size = _entry_size, \ + .count_per_block = (KHO_BLOCK_SIZE - \ + sizeof(struct kho_block_header_ser)) / \ + (_entry_size), \ +} + +void kho_block_set_init(struct kho_block_set *bs, size_t entry_size); + +int kho_block_set_grow(struct kho_block_set *bs, u64 count); +void kho_block_set_shrink(struct kho_block_set *bs, u64 count); + +int kho_block_set_restore(struct kho_block_set *bs, u64 head_pa); +void kho_block_set_destroy(struct kho_block_set *bs); +void kho_block_set_clear(struct kho_block_set *bs); + +/** + * kho_block_set_head_pa - Get the physical address of the first block header. + * @bs: The block set. + * + * Return: The physical address of the first block header, or 0 if empty. + */ +static inline u64 kho_block_set_head_pa(struct kho_block_set *bs) +{ + return bs->head_pa; +} + +/** + * kho_block_set_is_empty - Check if the block set has no allocated blocks. + * @bs: The block set. + * + * Return: True if there are no blocks in the set, false otherwise. + */ +static inline bool kho_block_set_is_empty(struct kho_block_set *bs) +{ + return list_empty(&bs->blocks); +} + +void kho_block_set_it_init(struct kho_block_set_it *it, struct kho_block_set *bs); +void *kho_block_set_it_reserve_entry(struct kho_block_set_it *it); +void *kho_block_set_it_read_entry(struct kho_block_set_it *it); +void *kho_block_set_it_prev(struct kho_block_set_it *it); + +#endif /* _LINUX_KHO_BLOCK_H */ diff --git a/include/linux/ks8851_mll.h b/include/linux/ks8851_mll.h deleted file mode 100644 index 57c0a39ed796..000000000000 --- a/include/linux/ks8851_mll.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * ks8861_mll platform data struct definition - * Copyright (c) 2012 BTicino S.p.A. - */ - -#ifndef _LINUX_KS8851_MLL_H -#define _LINUX_KS8851_MLL_H - -#include <linux/if_ether.h> - -/** - * struct ks8851_mll_platform_data - Platform data of the KS8851_MLL network driver - * @macaddr: The MAC address of the device, set to all 0:s to use the on in - * the chip. - */ -struct ks8851_mll_platform_data { - u8 mac_addr[ETH_ALEN]; -}; - -#endif diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 4c14aee1fb06..ab8cfaec82d3 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1390,20 +1390,20 @@ void mark_page_dirty_in_slot(struct kvm *kvm, const struct kvm_memory_slot *mems void mark_page_dirty(struct kvm *kvm, gfn_t gfn); void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn); -int __kvm_vcpu_map(struct kvm_vcpu *vcpu, gpa_t gpa, struct kvm_host_map *map, +int __kvm_vcpu_map(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map, bool writable); void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map); -static inline int kvm_vcpu_map(struct kvm_vcpu *vcpu, gpa_t gpa, +static inline int kvm_vcpu_map(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map) { - return __kvm_vcpu_map(vcpu, gpa, map, true); + return __kvm_vcpu_map(vcpu, gfn, map, true); } -static inline int kvm_vcpu_map_readonly(struct kvm_vcpu *vcpu, gpa_t gpa, +static inline int kvm_vcpu_map_readonly(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map) { - return __kvm_vcpu_map(vcpu, gpa, map, false); + return __kvm_vcpu_map(vcpu, gfn, map, false); } static inline void kvm_vcpu_map_mark_dirty(struct kvm_vcpu *vcpu, @@ -1562,7 +1562,7 @@ void kvm_mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc); void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc); #endif -void kvm_mmu_invalidate_begin(struct kvm *kvm); +void kvm_mmu_invalidate_start(struct kvm *kvm); void kvm_mmu_invalidate_range_add(struct kvm *kvm, gfn_t start, gfn_t end); void kvm_mmu_invalidate_end(struct kvm *kvm); bool kvm_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range); @@ -1815,6 +1815,11 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm, struct kvm_irq_ack_notifier *kian); bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args); +static inline bool is_gfn_in_memslot(const struct kvm_memory_slot *slot, gfn_t gfn) +{ + return gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages; +} + /* * Returns a pointer to the memslot if it contains gfn. * Otherwise returns NULL. @@ -1825,7 +1830,7 @@ try_get_memslot(struct kvm_memory_slot *slot, gfn_t gfn) if (!slot) return NULL; - if (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages) + if (is_gfn_in_memslot(slot, gfn)) return slot; else return NULL; @@ -2596,7 +2601,8 @@ int kvm_arch_gmem_prepare(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, int max_ord typedef int (*kvm_gmem_populate_cb)(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, struct page *page, void *opaque); -long kvm_gmem_populate(struct kvm *kvm, gfn_t gfn, void __user *src, long npages, +long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, + long npages, bool may_writeback_src, kvm_gmem_populate_cb post_populate, void *opaque); #endif diff --git a/include/linux/led-class-multicolor.h b/include/linux/led-class-multicolor.h index db9f34c6736e..8a05836cae25 100644 --- a/include/linux/led-class-multicolor.h +++ b/include/linux/led-class-multicolor.h @@ -9,10 +9,31 @@ #include <linux/leds.h> #include <dt-bindings/leds/common.h> +/** + * struct mc_subled - Color component description. + * @color_index: Color ID. + * @brightness: Scaled intensity. + * @intensity: Current intensity. + * @max_intensity: Maximum supported intensity value. + * @channel: Channel index. + * + * Describes a color component of a multicolor LED. Many multicolor LEDs + * do not support global brightness control in hardware, so they use + * the brightness field in connection with led_mc_calc_color_components() + * to perform the intensity scaling in software. + * Such drivers should set max_intensity to 0 to signal the multicolor LED core + * that the maximum global brightness of the LED class device should be used for + * limiting incoming intensity values. + * + * Multicolor LEDs that do support global brightness control in hardware + * should instead set max_intensity to the maximum intensity value supported + * by the hardware for a given color component. + */ struct mc_subled { unsigned int color_index; unsigned int brightness; unsigned int intensity; + unsigned int max_intensity; unsigned int channel; }; @@ -53,7 +74,14 @@ int led_classdev_multicolor_register_ext(struct device *parent, */ void led_classdev_multicolor_unregister(struct led_classdev_mc *mcled_cdev); -/* Calculate brightness for the monochrome LED cluster */ +/** + * led_mc_calc_color_components() - Calculates component brightness values of a LED cluster. + * @mcled_cdev - Multicolor LED class device of the LED cluster. + * @brightness - Global brightness of the LED cluster. + * + * Calculates the brightness values for each color component of a monochrome LED cluster, + * see Documentation/leds/leds-class-multicolor.rst for details. + */ int led_mc_calc_color_components(struct led_classdev_mc *mcled_cdev, enum led_brightness brightness); diff --git a/include/linux/libata.h b/include/linux/libata.h index 127229fbd1a6..96e626d6a7ca 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -984,7 +984,8 @@ struct ata_port_operations { void (*thaw)(struct ata_port *ap); struct ata_reset_operations reset; struct ata_reset_operations pmp_reset; - void (*error_handler)(struct ata_port *ap); + void (*error_handler)(struct ata_port *ap) + __must_hold(&ap->host->eh_mutex); void (*lost_interrupt)(struct ata_port *ap); void (*post_internal_cmd)(struct ata_queued_cmd *qc); void (*sched_eh)(struct ata_port *ap); @@ -1314,7 +1315,8 @@ extern int ata_tport_add(struct device *parent, struct ata_port *ap); extern void ata_tport_delete(struct ata_port *ap); int ata_sas_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim, struct ata_port *ap); -extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap); +extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) + __must_hold(ap->lock); extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); @@ -1419,7 +1421,8 @@ extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -extern void ata_std_error_handler(struct ata_port *ap); +extern void ata_std_error_handler(struct ata_port *ap) + __must_hold(&ap->host->eh_mutex); extern void ata_std_sched_eh(struct ata_port *ap); extern void ata_std_end_eh(struct ata_port *ap); extern int ata_link_nr_enabled(struct ata_link *link); @@ -1999,7 +2002,8 @@ extern void ata_timing_merge(const struct ata_timing *, extern const struct ata_port_operations sata_pmp_port_ops; extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc); -extern void sata_pmp_error_handler(struct ata_port *ap); +extern void sata_pmp_error_handler(struct ata_port *ap) + __must_hold(&ap->host->eh_mutex); #else /* CONFIG_SATA_PMP */ @@ -2063,7 +2067,8 @@ extern int sata_sff_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes); extern void ata_sff_drain_fifo(struct ata_queued_cmd *qc); -extern void ata_sff_error_handler(struct ata_port *ap); +extern void ata_sff_error_handler(struct ata_port *ap) + __must_hold(&ap->host->eh_mutex); extern void ata_sff_std_ports(struct ata_ioports *ioaddr); #ifdef CONFIG_PCI extern int ata_pci_sff_init_host(struct ata_host *host); @@ -2093,7 +2098,8 @@ extern enum ata_completion_errors ata_bmdma_dumb_qc_prep(struct ata_queued_cmd * extern unsigned int ata_bmdma_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance); -extern void ata_bmdma_error_handler(struct ata_port *ap); +extern void ata_bmdma_error_handler(struct ata_port *ap) + __must_hold(&ap->host->eh_mutex); extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); extern void ata_bmdma_irq_clear(struct ata_port *ap); extern void ata_bmdma_setup(struct ata_queued_cmd *qc); diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h index fe739d35a864..a450fffe1550 100644 --- a/include/linux/list_lru.h +++ b/include/linux/list_lru.h @@ -81,9 +81,76 @@ static inline int list_lru_init_memcg_key(struct list_lru *lru, struct shrinker int memcg_list_lru_alloc(struct mem_cgroup *memcg, struct list_lru *lru, gfp_t gfp); + +#ifdef CONFIG_MEMCG +/** + * folio_memcg_list_lru_alloc - allocate list_lru heads for shrinkable folio + * @folio: the newly allocated & charged folio + * @lru: the list_lru this might be queued on + * @gfp: gfp mask + * + * Allocate list_lru heads (per-memcg, per-node) needed to queue this + * particular folio down the line. + * + * This does memcg_list_lru_alloc(), but on the memcg that @folio is + * associated with. Handles folio_memcg() access rules in the fast + * path (list_lru heads allocated) and the allocation slowpath. + * + * Returns 0 on success, a negative error value otherwise. + */ +int folio_memcg_list_lru_alloc(struct folio *folio, struct list_lru *lru, + gfp_t gfp); +#else +static inline int folio_memcg_list_lru_alloc(struct folio *folio, + struct list_lru *lru, gfp_t gfp) +{ + return 0; +} +#endif + void memcg_reparent_list_lrus(struct mem_cgroup *memcg, struct mem_cgroup *parent); /** + * list_lru_lock: lock the sublist for the given node and memcg + * @lru: the lru pointer + * @nid: the node id of the sublist to lock. + * @memcg: pointer to the cgroup of the sublist to lock. On return, + * updated to the cgroup whose sublist was actually locked, + * which may be an ancestor if the original memcg was dying. + * + * Returns the locked list_lru_one sublist. The caller must call + * list_lru_unlock() when done. + * + * You must ensure that the memcg is not freed during this call (e.g., with + * rcu or by taking a css refcnt). + * + * Return: the locked list_lru_one, or NULL on failure + */ +struct list_lru_one *list_lru_lock(struct list_lru *lru, int nid, + struct mem_cgroup **memcg); + +/** + * list_lru_unlock: unlock a sublist locked by list_lru_lock() + * @l: the list_lru_one to unlock + */ +void list_lru_unlock(struct list_lru_one *l); + +struct list_lru_one *list_lru_lock_irq(struct list_lru *lru, int nid, + struct mem_cgroup **memcg); +void list_lru_unlock_irq(struct list_lru_one *l); + +struct list_lru_one *list_lru_lock_irqsave(struct list_lru *lru, int nid, + struct mem_cgroup **memcg, unsigned long *irq_flags); +void list_lru_unlock_irqrestore(struct list_lru_one *l, + unsigned long *irq_flags); + +/* Caller-locked variants, see list_lru_add() etc for documentation */ +bool __list_lru_add(struct list_lru *lru, struct list_lru_one *l, + struct list_head *item, int nid, struct mem_cgroup *memcg); +bool __list_lru_del(struct list_lru *lru, struct list_lru_one *l, + struct list_head *item, int nid); + +/** * list_lru_add: add an element to the lru list's tail * @lru: the lru pointer * @item: the item to be added. @@ -115,6 +182,9 @@ void memcg_reparent_list_lrus(struct mem_cgroup *memcg, struct mem_cgroup *paren bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid, struct mem_cgroup *memcg); +bool list_lru_add_irq(struct list_lru *lru, struct list_head *item, int nid, + struct mem_cgroup *memcg); + /** * list_lru_add_obj: add an element to the lru list's tail * @lru: the lru pointer diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index 30c5a39ff9e9..88722e5caf02 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -12,6 +12,7 @@ #include <linux/kho/abi/luo.h> #include <linux/list.h> #include <linux/mutex.h> +#include <linux/refcount.h> #include <linux/rwsem.h> #include <linux/types.h> #include <uapi/linux/liveupdate.h> @@ -175,7 +176,7 @@ struct liveupdate_flb_ops { * @retrieved: True once the FLB's retrieve() callback has run. */ struct luo_flb_private_state { - long count; + refcount_t count; u64 data; void *obj; struct mutex lock; @@ -239,6 +240,8 @@ void liveupdate_unregister_flb(struct liveupdate_file_handler *fh, struct liveupdate_flb *flb); int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, void **objp); +void liveupdate_flb_put_incoming(struct liveupdate_flb *flb); + int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, void **objp); #else /* CONFIG_LIVEUPDATE */ @@ -279,6 +282,10 @@ static inline int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, return -EOPNOTSUPP; } +static inline void liveupdate_flb_put_incoming(struct liveupdate_flb *flb) +{ +} + static inline int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, void **objp) { diff --git a/include/linux/llc.h b/include/linux/llc.h index b965314d017f..944e9e213112 100644 --- a/include/linux/llc.h +++ b/include/linux/llc.h @@ -1,14 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IEEE 802.2 User Interface SAPs for Linux, data structures and indicators. * * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org> - * - * This program can be redistributed or modified under the terms of the - * GNU General Public License as published by the Free Software Foundation. - * This program is distributed without any warranty or implied warranty - * of merchantability or fitness for a particular purpose. - * - * See the GNU General Public License for more details. */ #ifndef __LINUX_LLC_H #define __LINUX_LLC_H diff --git a/include/linux/llist.h b/include/linux/llist.h index 607b2360c938..8846b7709669 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h @@ -26,8 +26,8 @@ * * | add | del_first | del_all * add | - | - | - - * del_first | | L | L - * del_all | | | - + * del_first | - | L | L + * del_all | - | - | - * * Where, a particular row's operation can happen concurrently with a column's * operation, with "-" being no lock needed, while "L" being lock is needed. diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 2b8dfb35caed..65c9609ec207 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -176,8 +176,8 @@ LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, struct mnt_idmap *idmap, struct inode *inode, const char *name, void **buffer, bool alloc) LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode, const char *name, const void *value, size_t size, int flags) -LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char *buffer, - size_t buffer_size) +LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char **buffer, + ssize_t *remaining_size) LSM_HOOK(void, LSM_RET_VOID, inode_getlsmprop, struct inode *inode, struct lsm_prop *prop) LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index b0f750d22a7b..5afcd99aa8c1 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -613,11 +613,28 @@ static inline void memtest_report_meminfo(struct seq_file *m) { } #ifdef CONFIG_MEMBLOCK_KHO_SCRATCH void memblock_set_kho_scratch_only(void); void memblock_clear_kho_scratch_only(void); -void memmap_init_kho_scratch_pages(void); +bool memblock_is_kho_scratch_memory(phys_addr_t addr); + +static inline enum migratetype kho_scratch_migratetype(unsigned long pfn, + enum migratetype mt) +{ + if (memblock_is_kho_scratch_memory(PFN_PHYS(pfn))) + return MIGRATE_CMA; + return mt; +} #else static inline void memblock_set_kho_scratch_only(void) { } static inline void memblock_clear_kho_scratch_only(void) { } -static inline void memmap_init_kho_scratch_pages(void) {} +static inline bool memblock_is_kho_scratch_memory(phys_addr_t addr) +{ + return false; +} + +static inline enum migratetype kho_scratch_migratetype(unsigned long pfn, + enum migratetype mt) +{ + return mt; +} #endif #endif /* _LINUX_MEMBLOCK_H */ diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index dc3fa687759b..e1f46a0016fc 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -29,6 +29,7 @@ struct obj_cgroup; struct page; struct mm_struct; struct kmem_cache; +struct swap_cluster_info; /* Cgroup-specific page state, on top of universal node page state */ enum memcg_stat_item { @@ -277,10 +278,6 @@ struct mem_cgroup { struct memcg_cgwb_frn cgwb_frn[MEMCG_CGWB_FRN_CNT]; #endif -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - struct deferred_split deferred_split_queue; -#endif - #ifdef CONFIG_LRU_GEN_WALKS_MMU /* per-memcg mm_struct list */ struct lru_gen_mm_list mm_list; @@ -646,8 +643,8 @@ static inline int mem_cgroup_charge(struct folio *folio, struct mm_struct *mm, int mem_cgroup_charge_hugetlb(struct folio* folio, gfp_t gfp); -int mem_cgroup_swapin_charge_folio(struct folio *folio, struct mm_struct *mm, - gfp_t gfp, swp_entry_t entry); +int mem_cgroup_swapin_charge_folio(struct folio *folio, unsigned short id, + struct mm_struct *mm, gfp_t gfp); void __mem_cgroup_uncharge(struct folio *folio); @@ -1137,7 +1134,7 @@ static inline int mem_cgroup_charge_hugetlb(struct folio* folio, gfp_t gfp) } static inline int mem_cgroup_swapin_charge_folio(struct folio *folio, - struct mm_struct *mm, gfp_t gfp, swp_entry_t entry) + unsigned short id, struct mm_struct *mm, gfp_t gfp) { return 0; } @@ -1899,9 +1896,6 @@ static inline void mem_cgroup_exit_user_fault(void) current->in_user_fault = 0; } -void memcg1_swapout(struct folio *folio, swp_entry_t entry); -void memcg1_swapin(swp_entry_t entry, unsigned int nr_pages); - #else /* CONFIG_MEMCG_V1 */ static inline unsigned long memcg1_soft_limit_reclaim(pg_data_t *pgdat, int order, @@ -1929,14 +1923,23 @@ static inline void mem_cgroup_exit_user_fault(void) { } -static inline void memcg1_swapout(struct folio *folio, swp_entry_t entry) +#endif /* CONFIG_MEMCG_V1 */ + +#if defined(CONFIG_MEMCG_V1) && defined(CONFIG_SWAP) + +void __memcg1_swapout(struct folio *folio, struct swap_cluster_info *ci); +void memcg1_swapin(struct folio *folio); + +#else + +static inline void __memcg1_swapout(struct folio *folio, + struct swap_cluster_info *ci) { } -static inline void memcg1_swapin(swp_entry_t entry, unsigned int nr_pages) +static inline void memcg1_swapin(struct folio *folio) { } - -#endif /* CONFIG_MEMCG_V1 */ +#endif #endif /* _LINUX_MEMCONTROL_H */ diff --git a/include/linux/memory.h b/include/linux/memory.h index 5bb5599c6b2b..463dc02f6cff 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -158,7 +158,11 @@ int create_memory_block_devices(unsigned long start, unsigned long size, void remove_memory_block_devices(unsigned long start, unsigned long size); extern void memory_dev_init(void); extern int memory_notify(enum memory_block_state state, void *v); -extern struct memory_block *find_memory_block(unsigned long section_nr); +struct memory_block *memory_block_get(unsigned long block_id); +static inline void memory_block_put(struct memory_block *mem) +{ + put_device(&mem->dev); +} typedef int (*walk_memory_blocks_func_t)(struct memory_block *, void *); extern int walk_memory_blocks(unsigned long start, unsigned long size, void *arg, walk_memory_blocks_func_t func); @@ -171,7 +175,6 @@ struct memory_group *memory_group_find_by_id(int mgid); typedef int (*walk_memory_groups_func_t)(struct memory_group *, void *); int walk_dynamic_memory_groups(int nid, walk_memory_groups_func_t func, struct memory_group *excluded, void *arg); -struct memory_block *find_memory_block_by_id(unsigned long block_id); #define hotplug_memory_notifier(fn, pri) ({ \ static __meminitdata struct notifier_block fn##_mem_nb =\ { .notifier_call = fn, .priority = pri };\ diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 815e908c4135..7c9d66729c60 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -135,9 +135,10 @@ static inline bool movable_node_is_enabled(void) return movable_node_enabled; } -extern void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap); +extern void arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap, + struct dev_pagemap *pgmap); extern void __remove_pages(unsigned long start_pfn, unsigned long nr_pages, - struct vmem_altmap *altmap); + struct vmem_altmap *altmap, struct dev_pagemap *pgmap); /* reasonably generic interface to expand the physical pages */ extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, @@ -307,7 +308,8 @@ extern int sparse_add_section(int nid, unsigned long pfn, unsigned long nr_pages, struct vmem_altmap *altmap, struct dev_pagemap *pgmap); extern void sparse_remove_section(unsigned long pfn, unsigned long nr_pages, - struct vmem_altmap *altmap); + struct vmem_altmap *altmap, + struct dev_pagemap *pgmap); extern struct zone *zone_for_pfn_range(enum mmop online_type, int nid, struct memory_group *group, unsigned long start_pfn, unsigned long nr_pages); diff --git a/include/linux/mfd/bq257xx.h b/include/linux/mfd/bq257xx.h index 1d6ddc7fb09f..4ec72eb920f2 100644 --- a/include/linux/mfd/bq257xx.h +++ b/include/linux/mfd/bq257xx.h @@ -98,7 +98,419 @@ #define BQ25703_EN_OTG_MASK BIT(12) +#define BQ25792_REG00_MIN_SYS_VOLTAGE 0x00 +#define BQ25792_REG01_CHARGE_VOLTAGE_LIMIT 0x01 +#define BQ25792_REG03_CHARGE_CURRENT_LIMIT 0x03 +#define BQ25792_REG05_INPUT_VOLTAGE_LIMIT 0x05 +#define BQ25792_REG06_INPUT_CURRENT_LIMIT 0x06 +#define BQ25792_REG08_PRECHARGE_CONTROL 0x08 +#define BQ25792_REG09_TERMINATION_CONTROL 0x09 +#define BQ25792_REG0A_RECHARGE_CONTROL 0x0a +#define BQ25792_REG0B_VOTG_REGULATION 0x0b +#define BQ25792_REG0D_IOTG_REGULATION 0x0d +#define BQ25792_REG0E_TIMER_CONTROL 0x0e +#define BQ25792_REG0F_CHARGER_CONTROL_0 0x0f +#define BQ25792_REG10_CHARGER_CONTROL_1 0x10 +#define BQ25792_REG11_CHARGER_CONTROL_2 0x11 +#define BQ25792_REG12_CHARGER_CONTROL_3 0x12 +#define BQ25792_REG13_CHARGER_CONTROL_4 0x13 +#define BQ25792_REG14_CHARGER_CONTROL_5 0x14 +/* REG15 reserved */ +#define BQ25792_REG16_TEMPERATURE_CONTROL 0x16 +#define BQ25792_REG17_NTC_CONTROL_0 0x17 +#define BQ25792_REG18_NTC_CONTROL_1 0x18 +#define BQ25792_REG19_ICO_CURRENT_LIMIT 0x19 +#define BQ25792_REG1B_CHARGER_STATUS_0 0x1b +#define BQ25792_REG1C_CHARGER_STATUS_1 0x1c +#define BQ25792_REG1D_CHARGER_STATUS_2 0x1d +#define BQ25792_REG1E_CHARGER_STATUS_3 0x1e +#define BQ25792_REG1F_CHARGER_STATUS_4 0x1f +#define BQ25792_REG20_FAULT_STATUS_0 0x20 +#define BQ25792_REG21_FAULT_STATUS_1 0x21 +#define BQ25792_REG22_CHARGER_FLAG_0 0x22 +#define BQ25792_REG23_CHARGER_FLAG_1 0x23 +#define BQ25792_REG24_CHARGER_FLAG_2 0x24 +#define BQ25792_REG25_CHARGER_FLAG_3 0x25 +#define BQ25792_REG26_FAULT_FLAG_0 0x26 +#define BQ25792_REG27_FAULT_FLAG_1 0x27 +#define BQ25792_REG28_CHARGER_MASK_0 0x28 +#define BQ25792_REG29_CHARGER_MASK_1 0x29 +#define BQ25792_REG2A_CHARGER_MASK_2 0x2a +#define BQ25792_REG2B_CHARGER_MASK_3 0x2b +#define BQ25792_REG2C_FAULT_MASK_0 0x2c +#define BQ25792_REG2D_FAULT_MASK_1 0x2d +#define BQ25792_REG2E_ADC_CONTROL 0x2e +#define BQ25792_REG2F_ADC_FUNCTION_DISABLE_0 0x2f +#define BQ25792_REG30_ADC_FUNCTION_DISABLE_1 0x30 +#define BQ25792_REG31_IBUS_ADC 0x31 +#define BQ25792_REG33_IBAT_ADC 0x33 +#define BQ25792_REG35_VBUS_ADC 0x35 +#define BQ25792_REG37_VAC1_ADC 0x37 +#define BQ25792_REG39_VAC2_ADC 0x39 +#define BQ25792_REG3B_VBAT_ADC 0x3b +#define BQ25792_REG3D_VSYS_ADC 0x3d +#define BQ25792_REG3F_TS_ADC 0x3f +#define BQ25792_REG41_TDIE_ADC 0x41 +#define BQ25792_REG43_DP_ADC 0x43 +#define BQ25792_REG45_DM_ADC 0x45 +#define BQ25792_REG47_DPDM_DRIVER 0x47 +#define BQ25792_REG48_PART_INFORMATION 0x48 + +/* Minimal System Voltage */ +#define BQ25792_REG00_VSYSMIN_MASK GENMASK(5, 0) + +#define BQ25792_MINVSYS_MIN_UV 2500000 +#define BQ25792_MINVSYS_STEP_UV 250000 +#define BQ25792_MINVSYS_MAX_UV 16000000 + +/* Charge Voltage Limit */ +#define BQ25792_REG01_VREG_MASK GENMASK(10, 0) + +#define BQ25792_VBATREG_MIN_UV 3000000 +#define BQ25792_VBATREG_STEP_UV 10000 +#define BQ25792_VBATREG_MAX_UV 18800000 + +/* Charge Current Limit */ +#define BQ25792_REG03_ICHG_MASK GENMASK(8, 0) + +#define BQ25792_ICHG_MIN_UA 50000 +#define BQ25792_ICHG_STEP_UA 10000 +#define BQ25792_ICHG_MAX_UA 5000000 + +/* Input Voltage Limit */ +#define BQ25792_REG05_VINDPM_MASK GENMASK(7, 0) + +/* Input Current Limit */ +#define BQ25792_REG06_IINDPM_MASK GENMASK(8, 0) +#define BQ25792_IINDPM_DEFAULT_UA 3000000 +#define BQ25792_IINDPM_STEP_UA 10000 +#define BQ25792_IINDPM_MIN_UA 100000 +#define BQ25792_IINDPM_MAX_UA 3300000 + +/* Precharge Control */ +#define BQ25792_REG08_VBAT_LOWV_MASK GENMASK(7, 6) +#define BQ25792_REG08_IPRECHG_MASK GENMASK(5, 0) + +/* Termination Control */ +#define BQ25792_REG09_REG_RST BIT(6) +#define BQ25792_REG09_ITERM_MASK GENMASK(4, 0) + +/* Re-charge Control */ +#define BQ25792_REG0A_CELL_MASK GENMASK(7, 6) +#define BQ25792_REG0A_TRECHG_MASK GENMASK(5, 4) +#define BQ25792_REG0A_VRECHG_MASK GENMASK(3, 0) + +/* VOTG regulation */ +#define BQ25792_REG0B_VOTG_MASK GENMASK(10, 0) + +#define BQ25792_OTG_VOLT_MIN_UV 2800000 +#define BQ25792_OTG_VOLT_STEP_UV 10000 +#define BQ25792_OTG_VOLT_MAX_UV 22000000 +#define BQ25792_OTG_VOLT_NUM_VOLT ((BQ25792_OTG_VOLT_MAX_UV \ + - BQ25792_OTG_VOLT_MIN_UV) \ + / BQ25792_OTG_VOLT_STEP_UV + 1) + +/* IOTG regulation */ +#define BQ25792_REG0D_PRECHG_TMR BIT(7) +#define BQ25792_REG0D_IOTG_MASK GENMASK(6, 0) + +#define BQ25792_OTG_CUR_MIN_UA 120000 +#define BQ25792_OTG_CUR_STEP_UA 40000 +#define BQ25792_OTG_CUR_MAX_UA 3320000 + +/* Timer Control */ +#define BQ25792_REG0E_TOPOFF_TMR_MASK GENMASK(7, 6) +#define BQ25792_REG0E_EN_TRICHG_TMR BIT(5) +#define BQ25792_REG0E_EN_PRECHG_TMR BIT(4) +#define BQ25792_REG0E_EN_CHG_TMR BIT(3) +#define BQ25792_REG0E_CHG_TMR_MASK GENMASK(2, 1) +#define BQ25792_REG0E_TMR2X_EN BIT(0) + +/* Charger Control 0 */ +#define BQ25792_REG0F_EN_AUTO_IBATDIS BIT(7) +#define BQ25792_REG0F_FORCE_IBATDIS BIT(6) +#define BQ25792_REG0F_EN_CHG BIT(5) +#define BQ25792_REG0F_EN_ICO BIT(4) +#define BQ25792_REG0F_FORCE_ICO BIT(3) +#define BQ25792_REG0F_EN_HIZ BIT(2) +#define BQ25792_REG0F_EN_TERM BIT(1) +/* bit0 reserved */ + +/* Charger Control 1 */ +#define BQ25792_REG10_VAC_OVP_MASK GENMASK(5, 4) +#define BQ25792_REG10_WD_RST BIT(3) +#define BQ25792_REG10_WATCHDOG_MASK GENMASK(2, 0) + +/* Charger Control 2 */ +#define BQ25792_REG11_FORCE_INDET BIT(7) +#define BQ25792_REG11_AUTO_INDET_EN BIT(6) +#define BQ25792_REG11_EN_12V BIT(5) +#define BQ25792_REG11_EN_9V BIT(4) +#define BQ25792_REG11_HVDCP_EN BIT(3) +#define BQ25792_REG11_SDRV_CTRL_MASK GENMASK(2, 1) +#define BQ25792_REG11_SDRV_DLY BIT(0) + +/* Charger Control 3 */ +#define BQ25792_REG12_DIS_ACDRV BIT(7) +#define BQ25792_REG12_EN_OTG BIT(6) +#define BQ25792_REG12_PFM_OTG_DIS BIT(5) +#define BQ25792_REG12_PFM_FWD_DIS BIT(4) +#define BQ25792_REG12_WKUP_DLY BIT(3) +#define BQ25792_REG12_DIS_LDO BIT(2) +#define BQ25792_REG12_DIS_OTG_OOA BIT(1) +#define BQ25792_REG12_DIS_FWD_OOA BIT(0) + +/* Charger Control 4 */ +#define BQ25792_REG13_EN_ACDRV2 BIT(7) +#define BQ25792_REG13_EN_ACDRV1 BIT(6) +#define BQ25792_REG13_PWM_FREQ BIT(5) +#define BQ25792_REG13_DIS_STAT BIT(4) +#define BQ25792_REG13_DIS_VSYS_SHORT BIT(3) +#define BQ25792_REG13_DIS_VOTG_UVP BIT(2) +#define BQ25792_REG13_FORCE_VINDPM_DET BIT(1) +#define BQ25792_REG13_EN_IBUS_OCP BIT(0) + +/* Charger Control 5 */ +#define BQ25792_REG14_SFET_PRESENT BIT(7) +/* bit6 reserved */ +#define BQ25792_REG14_EN_IBAT BIT(5) +#define BQ25792_REG14_IBAT_REG_MASK GENMASK(4, 3) +#define BQ25792_REG14_EN_IINDPM BIT(2) +#define BQ25792_REG14_EN_EXTILIM BIT(1) +#define BQ25792_REG14_EN_BATOC BIT(0) + +#define BQ25792_IBAT_3A FIELD_PREP(BQ25792_REG14_IBAT_REG_MASK, 0) +#define BQ25792_IBAT_4A FIELD_PREP(BQ25792_REG14_IBAT_REG_MASK, 1) +#define BQ25792_IBAT_5A FIELD_PREP(BQ25792_REG14_IBAT_REG_MASK, 2) +#define BQ25792_IBAT_UNLIM FIELD_PREP(BQ25792_REG14_IBAT_REG_MASK, 3) + +/* Temperature Control */ +#define BQ25792_REG16_TREG_MASK GENMASK(7, 6) +#define BQ25792_REG16_TSHUT_MASK GENMASK(5, 4) +#define BQ25792_REG16_VBUS_PD_EN BIT(3) +#define BQ25792_REG16_VAC1_PD_EN BIT(2) +#define BQ25792_REG16_VAC2_PD_EN BIT(1) + +/* NTC Control 0 */ +#define BQ25792_REG17_JEITA_VSET_MASK GENMASK(7, 5) +#define BQ25792_REG17_JEITA_ISETH_MASK GENMASK(4, 3) +#define BQ25792_REG17_JEITA_ISETC_MASK GENMASK(2, 1) + +/* NTC Control 1 */ +#define BQ25792_REG18_TS_COOL_MASK GENMASK(7, 6) +#define BQ25792_REG18_TS_WARM_MASK GENMASK(5, 4) +#define BQ25792_REG18_BHOT_MASK GENMASK(3, 2) +#define BQ25792_REG18_BCOLD BIT(1) +#define BQ25792_REG18_TS_IGNORE BIT(0) + +/* ICO Current Limit */ +#define BQ25792_REG19_ICO_ILIM_MASK GENMASK(8, 0) + +/* Charger Status 0 */ +#define BQ25792_REG1B_IINDPM_STAT BIT(7) +#define BQ25792_REG1B_VINDPM_STAT BIT(6) +#define BQ25792_REG1B_WD_STAT BIT(5) +#define BQ25792_REG1B_POORSRC_STAT BIT(4) +#define BQ25792_REG1B_PG_STAT BIT(3) +#define BQ25792_REG1B_AC2_PRESENT_STAT BIT(2) +#define BQ25792_REG1B_AC1_PRESENT_STAT BIT(1) +#define BQ25792_REG1B_VBUS_PRESENT_STAT BIT(0) + +/* Charger Status 1 */ +#define BQ25792_REG1C_CHG_STAT_MASK GENMASK(7, 5) +#define BQ25792_REG1C_VBUS_STAT_MASK GENMASK(4, 1) +#define BQ25792_REG1C_BC12_DONE_STAT BIT(0) + +/* Charger Status 2 */ +#define BQ25792_REG1D_ICO_STAT_MASK GENMASK(7, 6) +#define BQ25792_REG1D_TREG_STAT BIT(2) +#define BQ25792_REG1D_DPDM_STAT BIT(1) +#define BQ25792_REG1D_VBAT_PRESENT_STAT BIT(0) + +/* Charger Status 3 */ +#define BQ25792_REG1E_ACRB2_STAT BIT(7) +#define BQ25792_REG1E_ACRB1_STAT BIT(6) +#define BQ25792_REG1E_ADC_DONE_STAT BIT(5) +#define BQ25792_REG1E_VSYS_STAT BIT(4) +#define BQ25792_REG1E_CHG_TMR_STAT BIT(3) +#define BQ25792_REG1E_TRICHG_TMR_STAT BIT(2) +#define BQ25792_REG1E_PRECHG_TMR_STAT BIT(1) + +/* Charger Status 4 */ +#define BQ25792_REG1F_VBATOTG_LOW_STAT BIT(4) +#define BQ25792_REG1F_TS_COLD_STAT BIT(3) +#define BQ25792_REG1F_TS_COOL_STAT BIT(2) +#define BQ25792_REG1F_TS_WARM_STAT BIT(1) +#define BQ25792_REG1F_TS_HOT_STAT BIT(0) + +/* FAULT Status 0 */ +#define BQ25792_REG20_IBAT_REG_STAT BIT(7) +#define BQ25792_REG20_VBUS_OVP_STAT BIT(6) +#define BQ25792_REG20_VBAT_OVP_STAT BIT(5) +#define BQ25792_REG20_IBUS_OCP_STAT BIT(4) +#define BQ25792_REG20_IBAT_OCP_STAT BIT(3) +#define BQ25792_REG20_CONV_OCP_STAT BIT(2) +#define BQ25792_REG20_VAC2_OVP_STAT BIT(1) +#define BQ25792_REG20_VAC1_OVP_STAT BIT(0) + +#define BQ25792_REG20_OVERVOLTAGE_MASK (BQ25792_REG20_VBAT_OVP_STAT | \ + BQ25792_REG20_VAC2_OVP_STAT | \ + BQ25792_REG20_VAC1_OVP_STAT) +#define BQ25792_REG20_OVERCURRENT_MASK (BQ25792_REG20_IBAT_OCP_STAT | \ + BQ25792_REG20_CONV_OCP_STAT) + +/* FAULT Status 1 */ +#define BQ25792_REG21_VSYS_SHORT_STAT BIT(7) +#define BQ25792_REG21_VSYS_OVP_STAT BIT(6) +#define BQ25792_REG21_OTG_OVP_STAT BIT(5) +#define BQ25792_REG21_OTG_UVP_STAT BIT(4) +#define BQ25792_REG21_TSHUT_STAT BIT(2) + + +/* Charger Flag 0 */ +#define BQ25792_REG22_IINDPM_FLAG BIT(7) +#define BQ25792_REG22_VINDPM_FLAG BIT(6) +#define BQ25792_REG22_WD_FLAG BIT(5) +#define BQ25792_REG22_POORSRC_FLAG BIT(4) +#define BQ25792_REG22_PG_FLAG BIT(3) +#define BQ25792_REG22_AC2_PRESENT_FLAG BIT(2) +#define BQ25792_REG22_AC1_PRESENT_FLAG BIT(1) +#define BQ25792_REG22_VBUS_PRESENT_FLAG BIT(0) + +/* Charger Flag 1 */ +#define BQ25792_REG23_CHG_FLAG BIT(7) +#define BQ25792_REG23_ICO_FLAG BIT(6) +#define BQ25792_REG23_VBUS_FLAG BIT(4) +#define BQ25792_REG23_TREG_FLAG BIT(2) +#define BQ25792_REG23_VBAT_PRESENT_FLAG BIT(1) +#define BQ25792_REG23_BC12_DONE_FLAG BIT(0) + +/* Charger Flag 2 */ +#define BQ25792_REG24_DPDM_DONE_FLAG BIT(6) +#define BQ25792_REG24_ADC_DONE_FLAG BIT(5) +#define BQ25792_REG24_VSYS_FLAG BIT(4) +#define BQ25792_REG24_CHG_TMR_FLAG BIT(3) +#define BQ25792_REG24_TRICHG_TMR_FLAG BIT(2) +#define BQ25792_REG24_PRECHG_TMR_FLAG BIT(1) +#define BQ25792_REG24_TOPOFF_TMR_FLAG BIT(0) + +/* Charger Flag 3 */ +#define BQ25792_REG25_VBATOTG_LOW_FLAG BIT(4) +#define BQ25792_REG25_TS_COLD_FLAG BIT(3) +#define BQ25792_REG25_TS_COOL_FLAG BIT(2) +#define BQ25792_REG25_TS_WARM_FLAG BIT(1) +#define BQ25792_REG25_TS_HOT_FLAG BIT(0) + +/* FAULT Flag 0 */ +#define BQ25792_REG26_IBAT_REG_FLAG BIT(7) +#define BQ25792_REG26_VBUS_OVP_FLAG BIT(6) +#define BQ25792_REG26_VBAT_OVP_FLAG BIT(5) +#define BQ25792_REG26_IBUS_OCP_FLAG BIT(4) +#define BQ25792_REG26_IBAT_OCP_FLAG BIT(3) +#define BQ25792_REG26_CONV_OCP_FLAG BIT(2) +#define BQ25792_REG26_VAC2_OVP_FLAG BIT(1) +#define BQ25792_REG26_VAC1_OVP_FLAG BIT(0) + +/* FAULT Flag 1 */ +#define BQ25792_REG27_VSYS_SHORT_FLAG BIT(7) +#define BQ25792_REG27_VSYS_OVP_FLAG BIT(6) +#define BQ25792_REG27_OTG_OVP_FLAG BIT(5) +#define BQ25792_REG27_OTG_UVP_FLAG BIT(4) +#define BQ25792_REG27_TSHUT_FLAG BIT(2) + +/* Charger Mask 0 */ +#define BQ25792_REG28_IINDPM_MASK BIT(7) +#define BQ25792_REG28_VINDPM_MASK BIT(6) +#define BQ25792_REG28_WD_MASK BIT(5) +#define BQ25792_REG28_POORSRC_MASK BIT(4) +#define BQ25792_REG28_PG_MASK BIT(3) +#define BQ25792_REG28_AC2_PRESENT_MASK BIT(2) +#define BQ25792_REG28_AC1_PRESENT_MASK BIT(1) +#define BQ25792_REG28_VBUS_PRESENT_MASK BIT(0) + +/* Charger Mask 1 */ +#define BQ25792_REG29_CHG_MASK BIT(7) +#define BQ25792_REG29_ICO_MASK BIT(6) +#define BQ25792_REG29_VBUS_MASK BIT(4) +#define BQ25792_REG29_TREG_MASK BIT(2) +#define BQ25792_REG29_VBAT_PRESENT_MASK BIT(1) +#define BQ25792_REG29_BC12_DONE_MASK BIT(0) + +/* Charger Mask 2 */ +#define BQ25792_REG2A_DPDM_DONE_MASK BIT(6) +#define BQ25792_REG2A_ADC_DONE_MASK BIT(5) +#define BQ25792_REG2A_VSYS_MASK BIT(4) +#define BQ25792_REG2A_CHG_TMR_MASK BIT(3) +#define BQ25792_REG2A_TRICHG_TMR_MASK BIT(2) +#define BQ25792_REG2A_PRECHG_TMR_MASK BIT(1) +#define BQ25792_REG2A_TOPOFF_TMR_MASK BIT(0) + +/* Charger Mask 3 */ +#define BQ25792_REG2B_VBATOTG_LOW_MASK BIT(4) +#define BQ25792_REG2B_TS_COLD_MASK BIT(3) +#define BQ25792_REG2B_TS_COOL_MASK BIT(2) +#define BQ25792_REG2B_TS_WARM_MASK BIT(1) +#define BQ25792_REG2B_TS_HOT_MASK BIT(0) + +/* FAULT Mask 0 */ +#define BQ25792_REG2C_IBAT_REG_MASK BIT(7) +#define BQ25792_REG2C_VBUS_OVP_MASK BIT(6) +#define BQ25792_REG2C_VBAT_OVP_MASK BIT(5) +#define BQ25792_REG2C_IBUS_OCP_MASK BIT(4) +#define BQ25792_REG2C_IBAT_OCP_MASK BIT(3) +#define BQ25792_REG2C_CONV_OCP_MASK BIT(2) +#define BQ25792_REG2C_VAC2_OVP_MASK BIT(1) +#define BQ25792_REG2C_VAC1_OVP_MASK BIT(0) + +/* FAULT Mask 1 */ +#define BQ25792_REG2D_VSYS_SHORT_MASK BIT(7) +#define BQ25792_REG2D_VSYS_OVP_MASK BIT(6) +#define BQ25792_REG2D_OTG_OVP_MASK BIT(5) +#define BQ25792_REG2D_OTG_UVP_MASK BIT(4) +#define BQ25792_REG2D_TSHUT_MASK BIT(2) + +/* ADC Control */ +#define BQ25792_REG2E_ADC_EN BIT(7) +#define BQ25792_REG2E_ADC_RATE BIT(6) +#define BQ25792_REG2E_ADC_SAMPLE_MASK GENMASK(5, 4) +#define BQ25792_REG2E_ADC_AVG BIT(3) +#define BQ25792_REG2E_ADC_AVG_INIT BIT(2) + +/* ADC Function Disable 0 */ +#define BQ25792_REG2F_IBUS_ADC_DIS BIT(7) +#define BQ25792_REG2F_IBAT_ADC_DIS BIT(6) +#define BQ25792_REG2F_VBUS_ADC_DIS BIT(5) +#define BQ25792_REG2F_VBAT_ADC_DIS BIT(4) +#define BQ25792_REG2F_VSYS_ADC_DIS BIT(3) +#define BQ25792_REG2F_TS_ADC_DIS BIT(2) +#define BQ25792_REG2F_TDIE_ADC_DIS BIT(1) + +/* ADC Function Disable 1 */ +#define BQ25792_REG30_DP_ADC_DIS BIT(7) +#define BQ25792_REG30_DM_ADC_DIS BIT(6) +#define BQ25792_REG30_VAC2_ADC_DIS BIT(5) +#define BQ25792_REG30_VAC1_ADC_DIS BIT(4) + +/* 0x31-0x45: ADC result registers (16-bit, RO): single full-width field */ + +#define BQ25792_ADCVSYSVBAT_STEP_UV 1000 +#define BQ25792_ADCIBAT_STEP_UA 1000 + +/* DPDM Driver */ +#define BQ25792_REG47_DPLUS_DAC_MASK GENMASK(7, 5) +#define BQ25792_REG47_DMINUS_DAC_MASK GENMASK(4, 2) + +/* Part Information */ +#define BQ25792_REG48_PN_MASK GENMASK(5, 3) +#define BQ25792_REG48_DEV_REV_MASK GENMASK(2, 0) + +enum bq257xx_type { + BQ25703A = 1, + BQ25792, +}; + struct bq257xx_device { struct i2c_client *client; struct regmap *regmap; + enum bq257xx_type type; }; diff --git a/include/linux/mfd/cs5535.h b/include/linux/mfd/cs5535.h new file mode 100644 index 000000000000..2e4ebf5d06af --- /dev/null +++ b/include/linux/mfd/cs5535.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __MFD_CS5535_H__ +#define __MFD_CS5535_H__ + +extern const struct software_node cs5535_gpio_swnode; + +#endif /* __MFD_CS5535_H__ */ diff --git a/include/linux/mfd/ezx-pcap.h b/include/linux/mfd/ezx-pcap.h deleted file mode 100644 index ea51b1cdca5a..000000000000 --- a/include/linux/mfd/ezx-pcap.h +++ /dev/null @@ -1,253 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright 2009 Daniel Ribeiro <drwyrm@gmail.com> - * - * For further information, please see http://wiki.openezx.org/PCAP2 - */ - -#ifndef EZX_PCAP_H -#define EZX_PCAP_H - -struct pcap_subdev { - int id; - const char *name; - void *platform_data; -}; - -struct pcap_platform_data { - unsigned int irq_base; - unsigned int config; - int gpio; - void (*init) (void *); /* board specific init */ - int num_subdevs; - struct pcap_subdev *subdevs; -}; - -struct pcap_chip; - -int ezx_pcap_write(struct pcap_chip *, u8, u32); -int ezx_pcap_read(struct pcap_chip *, u8, u32 *); -int ezx_pcap_set_bits(struct pcap_chip *, u8, u32, u32); -int pcap_to_irq(struct pcap_chip *, int); -int irq_to_pcap(struct pcap_chip *, int); -int pcap_adc_async(struct pcap_chip *, u8, u32, u8[], void *, void *); -void pcap_set_ts_bits(struct pcap_chip *, u32); - -#define PCAP_SECOND_PORT 1 -#define PCAP_CS_AH 2 - -#define PCAP_REGISTER_WRITE_OP_BIT 0x80000000 -#define PCAP_REGISTER_READ_OP_BIT 0x00000000 - -#define PCAP_REGISTER_VALUE_MASK 0x01ffffff -#define PCAP_REGISTER_ADDRESS_MASK 0x7c000000 -#define PCAP_REGISTER_ADDRESS_SHIFT 26 -#define PCAP_REGISTER_NUMBER 32 -#define PCAP_CLEAR_INTERRUPT_REGISTER 0x01ffffff -#define PCAP_MASK_ALL_INTERRUPT 0x01ffffff - -/* registers accessible by both pcap ports */ -#define PCAP_REG_ISR 0x0 /* Interrupt Status */ -#define PCAP_REG_MSR 0x1 /* Interrupt Mask */ -#define PCAP_REG_PSTAT 0x2 /* Processor Status */ -#define PCAP_REG_VREG2 0x6 /* Regulator Bank 2 Control */ -#define PCAP_REG_AUXVREG 0x7 /* Auxiliary Regulator Control */ -#define PCAP_REG_BATT 0x8 /* Battery Control */ -#define PCAP_REG_ADC 0x9 /* AD Control */ -#define PCAP_REG_ADR 0xa /* AD Result */ -#define PCAP_REG_CODEC 0xb /* Audio Codec Control */ -#define PCAP_REG_RX_AMPS 0xc /* RX Audio Amplifiers Control */ -#define PCAP_REG_ST_DAC 0xd /* Stereo DAC Control */ -#define PCAP_REG_BUSCTRL 0x14 /* Connectivity Control */ -#define PCAP_REG_PERIPH 0x15 /* Peripheral Control */ -#define PCAP_REG_LOWPWR 0x18 /* Regulator Low Power Control */ -#define PCAP_REG_TX_AMPS 0x1a /* TX Audio Amplifiers Control */ -#define PCAP_REG_GP 0x1b /* General Purpose */ -#define PCAP_REG_TEST1 0x1c -#define PCAP_REG_TEST2 0x1d -#define PCAP_REG_VENDOR_TEST1 0x1e -#define PCAP_REG_VENDOR_TEST2 0x1f - -/* registers accessible by pcap port 1 only (a1200, e2 & e6) */ -#define PCAP_REG_INT_SEL 0x3 /* Interrupt Select */ -#define PCAP_REG_SWCTRL 0x4 /* Switching Regulator Control */ -#define PCAP_REG_VREG1 0x5 /* Regulator Bank 1 Control */ -#define PCAP_REG_RTC_TOD 0xe /* RTC Time of Day */ -#define PCAP_REG_RTC_TODA 0xf /* RTC Time of Day Alarm */ -#define PCAP_REG_RTC_DAY 0x10 /* RTC Day */ -#define PCAP_REG_RTC_DAYA 0x11 /* RTC Day Alarm */ -#define PCAP_REG_MTRTMR 0x12 /* AD Monitor Timer */ -#define PCAP_REG_PWR 0x13 /* Power Control */ -#define PCAP_REG_AUXVREG_MASK 0x16 /* Auxiliary Regulator Mask */ -#define PCAP_REG_VENDOR_REV 0x17 -#define PCAP_REG_PERIPH_MASK 0x19 /* Peripheral Mask */ - -/* PCAP2 Interrupts */ -#define PCAP_NIRQS 23 -#define PCAP_IRQ_ADCDONE 0 /* ADC done port 1 */ -#define PCAP_IRQ_TS 1 /* Touch Screen */ -#define PCAP_IRQ_1HZ 2 /* 1HZ timer */ -#define PCAP_IRQ_WH 3 /* ADC above high limit */ -#define PCAP_IRQ_WL 4 /* ADC below low limit */ -#define PCAP_IRQ_TODA 5 /* Time of day alarm */ -#define PCAP_IRQ_USB4V 6 /* USB above 4V */ -#define PCAP_IRQ_ONOFF 7 /* On/Off button */ -#define PCAP_IRQ_ONOFF2 8 /* On/Off button 2 */ -#define PCAP_IRQ_USB1V 9 /* USB above 1V */ -#define PCAP_IRQ_MOBPORT 10 -#define PCAP_IRQ_MIC 11 /* Mic attach/HS button */ -#define PCAP_IRQ_HS 12 /* Headset attach */ -#define PCAP_IRQ_ST 13 -#define PCAP_IRQ_PC 14 /* Power Cut */ -#define PCAP_IRQ_WARM 15 -#define PCAP_IRQ_EOL 16 /* Battery End Of Life */ -#define PCAP_IRQ_CLK 17 -#define PCAP_IRQ_SYSRST 18 /* System Reset */ -#define PCAP_IRQ_DUMMY 19 -#define PCAP_IRQ_ADCDONE2 20 /* ADC done port 2 */ -#define PCAP_IRQ_SOFTRESET 21 -#define PCAP_IRQ_MNEXB 22 - -/* voltage regulators */ -#define V1 0 -#define V2 1 -#define V3 2 -#define V4 3 -#define V5 4 -#define V6 5 -#define V7 6 -#define V8 7 -#define V9 8 -#define V10 9 -#define VAUX1 10 -#define VAUX2 11 -#define VAUX3 12 -#define VAUX4 13 -#define VSIM 14 -#define VSIM2 15 -#define VVIB 16 -#define SW1 17 -#define SW2 18 -#define SW3 19 -#define SW1S 20 -#define SW2S 21 - -#define PCAP_BATT_DAC_MASK 0x000000ff -#define PCAP_BATT_DAC_SHIFT 0 -#define PCAP_BATT_B_FDBK (1 << 8) -#define PCAP_BATT_EXT_ISENSE (1 << 9) -#define PCAP_BATT_V_COIN_MASK 0x00003c00 -#define PCAP_BATT_V_COIN_SHIFT 10 -#define PCAP_BATT_I_COIN (1 << 14) -#define PCAP_BATT_COIN_CH_EN (1 << 15) -#define PCAP_BATT_EOL_SEL_MASK 0x000e0000 -#define PCAP_BATT_EOL_SEL_SHIFT 17 -#define PCAP_BATT_EOL_CMP_EN (1 << 20) -#define PCAP_BATT_BATT_DET_EN (1 << 21) -#define PCAP_BATT_THERMBIAS_CTRL (1 << 22) - -#define PCAP_ADC_ADEN (1 << 0) -#define PCAP_ADC_RAND (1 << 1) -#define PCAP_ADC_AD_SEL1 (1 << 2) -#define PCAP_ADC_AD_SEL2 (1 << 3) -#define PCAP_ADC_ADA1_MASK 0x00000070 -#define PCAP_ADC_ADA1_SHIFT 4 -#define PCAP_ADC_ADA2_MASK 0x00000380 -#define PCAP_ADC_ADA2_SHIFT 7 -#define PCAP_ADC_ATO_MASK 0x00003c00 -#define PCAP_ADC_ATO_SHIFT 10 -#define PCAP_ADC_ATOX (1 << 14) -#define PCAP_ADC_MTR1 (1 << 15) -#define PCAP_ADC_MTR2 (1 << 16) -#define PCAP_ADC_TS_M_MASK 0x000e0000 -#define PCAP_ADC_TS_M_SHIFT 17 -#define PCAP_ADC_TS_REF_LOWPWR (1 << 20) -#define PCAP_ADC_TS_REFENB (1 << 21) -#define PCAP_ADC_BATT_I_POLARITY (1 << 22) -#define PCAP_ADC_BATT_I_ADC (1 << 23) - -#define PCAP_ADC_BANK_0 0 -#define PCAP_ADC_BANK_1 1 -/* ADC bank 0 */ -#define PCAP_ADC_CH_COIN 0 -#define PCAP_ADC_CH_BATT 1 -#define PCAP_ADC_CH_BPLUS 2 -#define PCAP_ADC_CH_MOBPORTB 3 -#define PCAP_ADC_CH_TEMPERATURE 4 -#define PCAP_ADC_CH_CHARGER_ID 5 -#define PCAP_ADC_CH_AD6 6 -/* ADC bank 1 */ -#define PCAP_ADC_CH_AD7 0 -#define PCAP_ADC_CH_AD8 1 -#define PCAP_ADC_CH_AD9 2 -#define PCAP_ADC_CH_TS_X1 3 -#define PCAP_ADC_CH_TS_X2 4 -#define PCAP_ADC_CH_TS_Y1 5 -#define PCAP_ADC_CH_TS_Y2 6 - -#define PCAP_ADC_T_NOW 0 -#define PCAP_ADC_T_IN_BURST 1 -#define PCAP_ADC_T_OUT_BURST 2 - -#define PCAP_ADC_ATO_IN_BURST 6 -#define PCAP_ADC_ATO_OUT_BURST 0 - -#define PCAP_ADC_TS_M_XY 1 -#define PCAP_ADC_TS_M_PRESSURE 2 -#define PCAP_ADC_TS_M_PLATE_X 3 -#define PCAP_ADC_TS_M_PLATE_Y 4 -#define PCAP_ADC_TS_M_STANDBY 5 -#define PCAP_ADC_TS_M_NONTS 6 - -#define PCAP_ADR_ADD1_MASK 0x000003ff -#define PCAP_ADR_ADD1_SHIFT 0 -#define PCAP_ADR_ADD2_MASK 0x000ffc00 -#define PCAP_ADR_ADD2_SHIFT 10 -#define PCAP_ADR_ADINC1 (1 << 20) -#define PCAP_ADR_ADINC2 (1 << 21) -#define PCAP_ADR_ASC (1 << 22) -#define PCAP_ADR_ONESHOT (1 << 23) - -#define PCAP_BUSCTRL_FSENB (1 << 0) -#define PCAP_BUSCTRL_USB_SUSPEND (1 << 1) -#define PCAP_BUSCTRL_USB_PU (1 << 2) -#define PCAP_BUSCTRL_USB_PD (1 << 3) -#define PCAP_BUSCTRL_VUSB_EN (1 << 4) -#define PCAP_BUSCTRL_USB_PS (1 << 5) -#define PCAP_BUSCTRL_VUSB_MSTR_EN (1 << 6) -#define PCAP_BUSCTRL_VBUS_PD_ENB (1 << 7) -#define PCAP_BUSCTRL_CURRLIM (1 << 8) -#define PCAP_BUSCTRL_RS232ENB (1 << 9) -#define PCAP_BUSCTRL_RS232_DIR (1 << 10) -#define PCAP_BUSCTRL_SE0_CONN (1 << 11) -#define PCAP_BUSCTRL_USB_PDM (1 << 12) -#define PCAP_BUSCTRL_BUS_PRI_ADJ (1 << 24) - -/* leds */ -#define PCAP_LED0 0 -#define PCAP_LED1 1 -#define PCAP_BL0 2 -#define PCAP_BL1 3 -#define PCAP_LED_3MA 0 -#define PCAP_LED_4MA 1 -#define PCAP_LED_5MA 2 -#define PCAP_LED_9MA 3 -#define PCAP_LED_T_MASK 0xf -#define PCAP_LED_C_MASK 0x3 -#define PCAP_BL_MASK 0x1f -#define PCAP_BL0_SHIFT 0 -#define PCAP_LED0_EN (1 << 5) -#define PCAP_LED1_EN (1 << 6) -#define PCAP_LED0_T_SHIFT 7 -#define PCAP_LED1_T_SHIFT 11 -#define PCAP_LED0_C_SHIFT 15 -#define PCAP_LED1_C_SHIFT 17 -#define PCAP_BL1_SHIFT 20 - -/* RTC */ -#define PCAP_RTC_DAY_MASK 0x3fff -#define PCAP_RTC_TOD_MASK 0xffff -#define PCAP_RTC_PC_MASK 0x7 -#define SEC_PER_DAY 86400 - -#endif diff --git a/include/linux/mfd/max77759.h b/include/linux/mfd/max77759.h index ec19be952877..7c0b13219d51 100644 --- a/include/linux/mfd/max77759.h +++ b/include/linux/mfd/max77759.h @@ -106,9 +106,9 @@ #define MAX77759_CHGR_REG_CHG_CNFG_10 0xc3 #define MAX77759_CHGR_REG_CHG_CNFG_11 0xc4 #define MAX77759_CHGR_REG_CHG_CNFG_12 0xc5 -/* Wireless Charging input channel select */ +/* Setting this enables the Wireless Charging input channel. */ #define MAX77759_CHGR_REG_CHG_CNFG_12_WCINSEL BIT(6) -/* CHGIN/USB input channel select */ +/* Setting this enables the CHGIN/USB input channel. */ #define MAX77759_CHGR_REG_CHG_CNFG_12_CHGINSEL BIT(5) #define MAX77759_CHGR_REG_CHG_CNFG_13 0xc6 #define MAX77759_CHGR_REG_CHG_CNFG_14 0xc7 @@ -204,7 +204,7 @@ enum max77759_chgr_chg_dtls_states { }; enum max77759_chgr_mode { - MAX77759_CHGR_MODE_OFF, + MAX77759_CHGR_MODE_OFF = 0x0, MAX77759_CHGR_MODE_CHG_BUCK_ON = 0x5, MAX77759_CHGR_MODE_OTG_BOOST_ON = 0xA, }; diff --git a/include/linux/mfd/rohm-bd72720.h b/include/linux/mfd/rohm-bd72720.h index ae7343bcab06..d8ddbf232bb3 100644 --- a/include/linux/mfd/rohm-bd72720.h +++ b/include/linux/mfd/rohm-bd72720.h @@ -21,7 +21,6 @@ enum { BD72720_BUCK8, BD72720_BUCK9, BD72720_BUCK10, - BD72720_BUCK11, BD72720_LDO1, BD72720_LDO2, BD72720_LDO3, diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index 4480c631110a..6191f409de94 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -47,6 +47,7 @@ enum sec_device_type { S2MPS15X, S2MPU02, S2MPU05, + S2MU005, }; /** diff --git a/include/linux/mfd/samsung/irq.h b/include/linux/mfd/samsung/irq.h index 6eab95de6fa8..19d0f0e12944 100644 --- a/include/linux/mfd/samsung/irq.h +++ b/include/linux/mfd/samsung/irq.h @@ -408,6 +408,72 @@ enum s2mpu05_irq { #define S2MPU05_IRQ_INT140C_MASK BIT(1) #define S2MPU05_IRQ_TSD_MASK BIT(2) +enum s2mu005_irq { + S2MU005_IRQ_CHGR_DETBAT, + S2MU005_IRQ_CHGR_BAT, + S2MU005_IRQ_CHGR_IVR, + S2MU005_IRQ_CHGR_EVENT, + S2MU005_IRQ_CHGR_CHG, + S2MU005_IRQ_CHGR_VMID, + S2MU005_IRQ_CHGR_WCIN, + S2MU005_IRQ_CHGR_VBUS, + + S2MU005_IRQ_FLED_LBPROT, + S2MU005_IRQ_FLED_OPENCH2, + S2MU005_IRQ_FLED_OPENCH1, + S2MU005_IRQ_FLED_SHORTCH2, + S2MU005_IRQ_FLED_SHORTCH1, + + S2MU005_IRQ_MUIC_ATTACH, + S2MU005_IRQ_MUIC_DETACH, + S2MU005_IRQ_MUIC_KP, + S2MU005_IRQ_MUIC_LKP, + S2MU005_IRQ_MUIC_LKR, + S2MU005_IRQ_MUIC_RIDCHG, + + S2MU005_IRQ_MUIC_VBUSON, + S2MU005_IRQ_MUIC_RSVD, + S2MU005_IRQ_MUIC_ADC, + S2MU005_IRQ_MUIC_STUCK, + S2MU005_IRQ_MUIC_STUCKRCV, + S2MU005_IRQ_MUIC_MHDL, + S2MU005_IRQ_MUIC_AVCHG, + S2MU005_IRQ_MUIC_VBUSOFF, + + S2MU005_IRQ_NR, +}; + +#define S2MU005_IRQ_CHGR_DETBAT_MASK BIT(0) +#define S2MU005_IRQ_CHGR_BAT_MASK BIT(1) +#define S2MU005_IRQ_CHGR_IVR_MASK BIT(2) +#define S2MU005_IRQ_CHGR_EVENT_MASK BIT(3) +#define S2MU005_IRQ_CHGR_CHG_MASK BIT(4) +#define S2MU005_IRQ_CHGR_VMID_MASK BIT(5) +#define S2MU005_IRQ_CHGR_WCIN_MASK BIT(6) +#define S2MU005_IRQ_CHGR_VBUS_MASK BIT(7) + +#define S2MU005_IRQ_FLED_LBPROT_MASK BIT(2) +#define S2MU005_IRQ_FLED_OPENCH2_MASK BIT(4) +#define S2MU005_IRQ_FLED_OPENCH1_MASK BIT(5) +#define S2MU005_IRQ_FLED_SHORTCH2_MASK BIT(6) +#define S2MU005_IRQ_FLED_SHORTCH1_MASK BIT(7) + +#define S2MU005_IRQ_MUIC_ATTACH_MASK BIT(0) +#define S2MU005_IRQ_MUIC_DETACH_MASK BIT(1) +#define S2MU005_IRQ_MUIC_KP_MASK BIT(2) +#define S2MU005_IRQ_MUIC_LKP_MASK BIT(3) +#define S2MU005_IRQ_MUIC_LKR_MASK BIT(4) +#define S2MU005_IRQ_MUIC_RIDCHG_MASK BIT(5) + +#define S2MU005_IRQ_MUIC_VBUSON_MASK BIT(0) +#define S2MU005_IRQ_MUIC_RSVD_MASK BIT(1) +#define S2MU005_IRQ_MUIC_ADC_MASK BIT(2) +#define S2MU005_IRQ_MUIC_STUCK_MASK BIT(3) +#define S2MU005_IRQ_MUIC_STUCKRCV_MASK BIT(4) +#define S2MU005_IRQ_MUIC_MHDL_MASK BIT(5) +#define S2MU005_IRQ_MUIC_AVCHG_MASK BIT(6) +#define S2MU005_IRQ_MUIC_VBUSOFF_MASK BIT(7) + enum s5m8767_irq { S5M8767_IRQ_PWRR, S5M8767_IRQ_PWRF, diff --git a/include/linux/mfd/samsung/s2mu005.h b/include/linux/mfd/samsung/s2mu005.h new file mode 100644 index 000000000000..46e7759545af --- /dev/null +++ b/include/linux/mfd/samsung/s2mu005.h @@ -0,0 +1,332 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd + * Copyright (c) 2026 Kaustabh Chakraborty <kauschluss@disroot.org> + * Copyright (c) 2026 Łukasz Lebiedziński <kernel@lvkasz.us> + */ + +#ifndef __LINUX_MFD_S2MU005_H +#define __LINUX_MFD_S2MU005_H + +#include <linux/bitfield.h> +#include <linux/bits.h> + +/* S2MU005 registers */ +enum s2mu005_reg { + S2MU005_REG_CHGR_INT1, + S2MU005_REG_CHGR_INT1M, + + S2MU005_REG_FLED_INT1, + S2MU005_REG_FLED_INT1M, + + S2MU005_REG_MUIC_INT1, + S2MU005_REG_MUIC_INT2, + S2MU005_REG_MUIC_INT1M, + S2MU005_REG_MUIC_INT2M, + + S2MU005_REG_CHGR_STATUS0, + S2MU005_REG_CHGR_STATUS1, + S2MU005_REG_CHGR_STATUS2, + S2MU005_REG_CHGR_STATUS3, + S2MU005_REG_CHGR_STATUS4, + S2MU005_REG_CHGR_STATUS5, + S2MU005_REG_CHGR_CTRL0, + S2MU005_REG_CHGR_CTRL1, + S2MU005_REG_CHGR_CTRL2, + S2MU005_REG_CHGR_CTRL3, + S2MU005_REG_CHGR_CTRL4, + S2MU005_REG_CHGR_CTRL5, + S2MU005_REG_CHGR_CTRL6, + S2MU005_REG_CHGR_CTRL7, + S2MU005_REG_CHGR_CTRL8, + S2MU005_REG_CHGR_CTRL9, + S2MU005_REG_CHGR_CTRL10, + S2MU005_REG_CHGR_CTRL11, + S2MU005_REG_CHGR_CTRL12, + S2MU005_REG_CHGR_CTRL13, + S2MU005_REG_CHGR_CTRL14, + S2MU005_REG_CHGR_CTRL15, + S2MU005_REG_CHGR_CTRL16, + S2MU005_REG_CHGR_CTRL17, + S2MU005_REG_CHGR_CTRL18, + S2MU005_REG_CHGR_CTRL19, + S2MU005_REG_CHGR_TEST0, + S2MU005_REG_CHGR_TEST1, + S2MU005_REG_CHGR_TEST2, + S2MU005_REG_CHGR_TEST3, + S2MU005_REG_CHGR_TEST4, + S2MU005_REG_CHGR_TEST5, + S2MU005_REG_CHGR_TEST6, + S2MU005_REG_CHGR_TEST7, + S2MU005_REG_CHGR_TEST8, + S2MU005_REG_CHGR_TEST9, + S2MU005_REG_CHGR_TEST10, + + S2MU005_REG_FLED_STATUS, + S2MU005_REG_FLED_CH0_CTRL0, + S2MU005_REG_FLED_CH0_CTRL1, + S2MU005_REG_FLED_CH0_CTRL2, + S2MU005_REG_FLED_CH0_CTRL3, + S2MU005_REG_FLED_CH1_CTRL0, + S2MU005_REG_FLED_CH1_CTRL1, + S2MU005_REG_FLED_CH1_CTRL2, + S2MU005_REG_FLED_CH1_CTRL3, + S2MU005_REG_FLED_CTRL0, + S2MU005_REG_FLED_CTRL1, + S2MU005_REG_FLED_CTRL2, + S2MU005_REG_FLED_CTRL3, + S2MU005_REG_FLED_CTRL4, + S2MU005_REG_FLED_CTRL5, + S2MU005_REG_FLED_CTRL6, + + S2MU005_REG_RGB_EN, + S2MU005_REG_RGB_CH0_CTRL, + S2MU005_REG_RGB_CH1_CTRL, + S2MU005_REG_RGB_CH2_CTRL, + S2MU005_REG_RGB_CH0_RAMP, + S2MU005_REG_RGB_CH0_STAY, + S2MU005_REG_RGB_CH1_RAMP, + S2MU005_REG_RGB_CH1_STAY, + S2MU005_REG_RGB_CH2_RAMP, + S2MU005_REG_RGB_CH2_STAY, + S2MU005_REG_RGB_TEST0, + S2MU005_REG_RGB_CTRL0, + + S2MU005_REG_MUIC_ADC, + S2MU005_REG_MUIC_DEV1, + S2MU005_REG_MUIC_DEV2, + S2MU005_REG_MUIC_DEV3, + S2MU005_REG_MUIC_BUTTON1, + S2MU005_REG_MUIC_BUTTON2, + S2MU005_REG_MUIC_RESET, + S2MU005_REG_MUIC_CHGTYPE, + S2MU005_REG_MUIC_DEVAPPLE, + S2MU005_REG_MUIC_BCDRESCAN, + S2MU005_REG_MUIC_TEST1, + S2MU005_REG_MUIC_TEST2, + S2MU005_REG_MUIC_TEST3, + + S2MU005_REG_ID = 0x73, + + S2MU005_REG_MUIC_CTRL1 = 0xb2, + S2MU005_REG_MUIC_TIMERSET1, + S2MU005_REG_MUIC_TIMERSET2, + S2MU005_REG_MUIC_SWCTRL, + S2MU005_REG_MUIC_TIMERSET3, + S2MU005_REG_MUIC_CTRL2, + S2MU005_REG_MUIC_CTRL3, + + S2MU005_REG_MUIC_LDOADC_L = 0xbf, + S2MU005_REG_MUIC_LDOADC_H, +}; + +#define S2MU005_REG_FLED_CH_CTRL0(x) (S2MU005_REG_FLED_CH0_CTRL0 + 4 * (x)) +#define S2MU005_REG_FLED_CH_CTRL1(x) (S2MU005_REG_FLED_CH0_CTRL1 + 4 * (x)) +#define S2MU005_REG_FLED_CH_CTRL2(x) (S2MU005_REG_FLED_CH0_CTRL2 + 4 * (x)) +#define S2MU005_REG_FLED_CH_CTRL3(x) (S2MU005_REG_FLED_CH0_CTRL3 + 4 * (x)) + +#define S2MU005_REG_RGB_CH_CTRL(x) (S2MU005_REG_RGB_CH0_CTRL + 1 * (x)) +#define S2MU005_REG_RGB_CH_RAMP(x) (S2MU005_REG_RGB_CH0_RAMP + 2 * (x)) +#define S2MU005_REG_RGB_CH_STAY(x) (S2MU005_REG_RGB_CH0_STAY + 2 * (x)) + +/* S2MU005_REG_CHGR_STATUS0 */ +#define S2MU005_CHGR_VBUS BIT(7) +#define S2MU005_CHGR_WCIN BIT(6) +#define S2MU005_CHGR_VMID BIT(5) +#define S2MU005_CHGR_CHG BIT(4) +#define S2MU005_CHGR_STAT GENMASK(3, 0) + +#define S2MU005_CHGR_STAT_DONE 8 +#define S2MU005_CHGR_STAT_TOPOFF 7 +#define S2MU005_CHGR_STAT_DONE_FLAG 6 +#define S2MU005_CHGR_STAT_CV 5 +#define S2MU005_CHGR_STAT_CC 4 +#define S2MU005_CHGR_STAT_COOL_CHG 3 +#define S2MU005_CHGR_STAT_PRE_CHG 2 + +/* S2MU005_REG_CHGR_STATUS1 */ +#define S2MU005_CHGR_DETBAT BIT(7) +#define S2MU005_CHGR_VBUS_OVP GENMASK(6, 4) + +#define S2MU005_CHGR_VBUS_OVP_OVERVOLT 2 + +/* S2MU005_REG_CHGR_STATUS2 */ +#define S2MU005_CHGR_BAT GENMASK(6, 4) + +#define S2MU005_CHGR_BAT_VOLT_DET 7 +#define S2MU005_CHGR_BAT_FAST_CHG_DET 6 +#define S2MU005_CHGR_BAT_COOL_CHG_DET 5 +#define S2MU005_CHGR_BAT_LOW_CHG 2 +#define S2MU005_CHGR_BAT_SELF_DISCHG 1 +#define S2MU005_CHGR_BAT_OVP_DET 0 + +/* S2MU005_REG_CHGR_STATUS3 */ +#define S2MU005_CHGR_EVT GENMASK(3, 0) + +#define S2MU005_CHGR_EVT_WDT_RST 6 +#define S2MU005_CHGR_EVT_WDT_SUSP 5 +#define S2MU005_CHGR_EVT_VSYS_VUVLO 4 +#define S2MU005_CHGR_EVT_VSYS_VOVP 3 +#define S2MU005_CHGR_EVT_THERM_FOLDBACK 2 +#define S2MU005_CHGR_EVT_THERM_SHUTDOWN 1 + +/* S2MU005_REG_CHGR_CTRL0 */ +#define S2MU005_CHGR_CHG_EN BIT(4) +#define S2MU005_CHGR_OP_MODE GENMASK(2, 0) + +#define S2MU005_CHGR_OP_MODE_OTG BIT(2) +#define S2MU005_CHGR_OP_MODE_CHG BIT(1) + +/* S2MU005_REG_CHGR_CTRL1 */ +#define S2MU005_CHGR_VIN_DROP GENMASK(6, 4) + +/* S2MU005_REG_CHGR_CTRL2 */ +#define S2MU005_CHGR_IN_CURR_LIM GENMASK(5, 0) + +/* S2MU005_REG_CHGR_CTRL4 */ +#define S2MU005_CHGR_OTG_OCP_ON BIT(5) +#define S2MU005_CHGR_OTG_OCP_OFF BIT(4) +#define S2MU005_CHGR_OTG_OCP GENMASK(3, 2) +#define S2MU005_CHGR_OTG_OCP_1P5A 0x3 + +/* S2MU005_REG_CHGR_CTRL5 */ +#define S2MU005_CHGR_VMID_BOOST GENMASK(4, 0) +#define S2MU005_CHGR_VMID_BOOST_5P1V 0x16 + +/* S2MU005_REG_CHGR_CTRL6 */ +#define S2MU005_CHGR_COOL_CHG_CURR GENMASK(5, 0) + +/* S2MU005_REG_CHGR_CTRL7 */ +#define S2MU005_CHGR_FAST_CHG_CURR GENMASK(5, 0) + +/* S2MU005_REG_CHGR_CTRL8 */ +#define S2MU005_CHGR_VF_VBAT GENMASK(6, 1) + +/* S2MU005_REG_CHGR_CTRL10 */ +#define S2MU005_CHGR_TOPOFF_CURR(x) (GENMASK(3, 0) << 4 * (x)) + +/* S2MU005_REG_CHGR_CTRL11 */ +#define S2MU005_CHGR_OSC_BOOST GENMASK(6, 5) +#define S2MU005_CHGR_OSC_BUCK GENMASK(4, 3) +#define S2MU005_CHGR_OSC_BOOST_2MHZ 0x3 + +/* S2MU005_REG_CHGR_CTRL12 */ +#define S2MU005_CHGR_WDT GENMASK(2, 0) + +#define S2MU005_CHGR_WDT_ON BIT(2) +#define S2MU005_CHGR_WDT_OFF BIT(1) + +/* S2MU005_REG_CHGR_CTRL15 */ +#define S2MU005_CHGR_OTG_EN GENMASK(3, 2) +#define S2MU005_CHGR_OTG_EN_ON 0x3 + +/* S2MU005_REG_FLED_STATUS */ +#define S2MU005_FLED_FLASH_STATUS(x) (BIT(7) >> 2 * (x)) +#define S2MU005_FLED_TORCH_STATUS(x) (BIT(6) >> 2 * (x)) + +/* S2MU005_REG_FLED_CHx_CTRL0 */ +#define S2MU005_FLED_FLASH_IOUT GENMASK(3, 0) + +/* S2MU005_REG_FLED_CHx_CTRL1 */ +#define S2MU005_FLED_TORCH_IOUT GENMASK(3, 0) + +/* S2MU005_REG_FLED_CHx_CTRL2 */ +#define S2MU005_FLED_TORCH_TIMEOUT GENMASK(3, 0) + +/* S2MU005_REG_FLED_CHx_CTRL3 */ +#define S2MU005_FLED_FLASH_TIMEOUT GENMASK(3, 0) + +/* S2MU005_REG_FLED_CTRL1 */ +#define S2MU005_FLED_CH_EN BIT(7) + +/* + * S2MU005_REG_FLED_CTRL4 - Rev. EVT0 + * S2MU005_REG_FLED_CTRL6 - Rev. EVT1 and later + */ +#define S2MU005_FLED_FLASH_EN(x) (GENMASK(7, 6) >> 4 * (x)) +#define S2MU005_FLED_TORCH_EN(x) (GENMASK(5, 4) >> 4 * (x)) + +/* S2MU005_REG_RGB_EN */ +#define S2MU005_RGB_RESET BIT(6) +#define S2MU005_RGB_SLOPE GENMASK(5, 0) + +#define S2MU005_RGB_SLOPE_CONST (BIT(4) | BIT(2) | BIT(0)) +#define S2MU005_RGB_SLOPE_SMOOTH (BIT(5) | BIT(3) | BIT(1)) + +/* S2MU005_REG_RGB_CHx_RAMP */ +#define S2MU005_RGB_CH_RAMP_UP GENMASK(7, 4) +#define S2MU005_RGB_CH_RAMP_DN GENMASK(3, 0) + +/* S2MU005_REG_RGB_CHx_STAY */ +#define S2MU005_RGB_CH_STAY_HI GENMASK(7, 4) +#define S2MU005_RGB_CH_STAY_LO GENMASK(3, 0) + +/* S2MU005_REG_MUIC_DEV1 */ +#define S2MU005_MUIC_OTG BIT(7) +#define S2MU005_MUIC_DCP BIT(6) +#define S2MU005_MUIC_CDP BIT(5) +#define S2MU005_MUIC_T1_T2_CHG BIT(4) +#define S2MU005_MUIC_UART BIT(3) +#define S2MU005_MUIC_SDP BIT(2) +#define S2MU005_MUIC_LANHUB BIT(1) +#define S2MU005_MUIC_AUDIO BIT(0) + +/* S2MU005_REG_MUIC_DEV2 */ +#define S2MU005_MUIC_SDP_1P8S BIT(7) +#define S2MU005_MUIC_AV BIT(6) +#define S2MU005_MUIC_TTY BIT(5) +#define S2MU005_MUIC_PPD BIT(4) +#define S2MU005_MUIC_JIG_UART_OFF BIT(3) +#define S2MU005_MUIC_JIG_UART_ON BIT(2) +#define S2MU005_MUIC_JIG_USB_OFF BIT(1) +#define S2MU005_MUIC_JIG_USB_ON BIT(0) + +/* S2MU005_REG_MUIC_DEV3 */ +#define S2MU005_MUIC_U200_CHG BIT(7) +#define S2MU005_MUIC_VBUS_AV BIT(4) +#define S2MU005_MUIC_VBUS_R255 BIT(1) +#define S2MU005_MUIC_MHL BIT(0) + +/* S2MU005_REG_MUIC_DEVAPPLE */ +#define S2MU005_MUIC_APPLE_CHG_0P5A BIT(7) +#define S2MU005_MUIC_APPLE_CHG_1P0A BIT(6) +#define S2MU005_MUIC_APPLE_CHG_2P0A BIT(5) +#define S2MU005_MUIC_APPLE_CHG_2P4A BIT(4) +#define S2MU005_MUIC_SDP_DCD_OUT BIT(3) +#define S2MU005_MUIC_RID_WAKEUP BIT(2) +#define S2MU005_MUIC_VBUS_WAKEUP BIT(1) +#define S2MU005_MUIC_BCV1P2_OR_OPEN BIT(0) + +/* S2MU005_REG_ID */ +#define S2MU005_ID_MASK GENMASK(3, 0) + +/* S2MU005_REG_MUIC_SWCTRL */ +#define S2MU005_MUIC_DM_DP GENMASK(7, 2) +#define S2MU005_MUIC_JIG BIT(0) + +#define S2MU005_MUIC_DM_DP_UART 0x12 +#define S2MU005_MUIC_DM_DP_USB 0x09 + +/* S2MU005_REG_MUIC_CTRL1 */ +#define S2MU005_MUIC_OPEN BIT(4) +#define S2MU005_MUIC_RAW_DATA BIT(3) +#define S2MU005_MUIC_MAN_SW BIT(2) +#define S2MU005_MUIC_WAIT BIT(1) +#define S2MU005_MUIC_IRQ BIT(0) + +/* S2MU005_REG_MUIC_CTRL3 */ +#define S2MU005_MUIC_ONESHOT_ADC BIT(2) + +/* S2MU005_REG_MUIC_LDOADC_L and S2MU005_REG_MUIC_LDOADC_H */ +#define S2MU005_MUIC_VSET GENMASK(4, 0) + +#define S2MU005_MUIC_VSET_3P0V 0x1f +#define S2MU005_MUIC_VSET_2P6V 0x0e +#define S2MU005_MUIC_VSET_2P4V 0x0c +#define S2MU005_MUIC_VSET_2P2V 0x0a +#define S2MU005_MUIC_VSET_2P0V 0x08 +#define S2MU005_MUIC_VSET_1P5V 0x03 +#define S2MU005_MUIC_VSET_1P4V 0x02 +#define S2MU005_MUIC_VSET_1P2V 0x00 + +#endif /* __LINUX_MFD_S2MU005_H */ diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 6e2962ef5b81..b95a56a338c3 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -226,11 +226,6 @@ struct wm8994_pdata { * lines is mastered. */ int max_channels_clocked[WM8994_NUM_AIF]; - - /** - * GPIO for the IRQ pin if host only supports edge triggering - */ - int irq_gpio; }; #endif diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 04b96c5abb57..b1871c0821d0 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -343,9 +343,11 @@ struct mlx5_cmd_mailbox { struct mlx5_cmd_mailbox *next; }; +struct mlx5_dma_pool_page; struct mlx5_buf_list { void *buf; dma_addr_t map; + struct mlx5_dma_pool_page *frag_page; }; struct mlx5_frag_buf { @@ -545,6 +547,7 @@ struct mlx5_debugfs_entries { struct dentry *eq_debugfs; struct dentry *cq_debugfs; struct dentry *cmdif_debugfs; + struct dentry *frag_buf_dma_pools_debugfs; struct dentry *pages_debugfs; struct dentry *lag_debugfs; }; @@ -554,10 +557,18 @@ enum mlx5_func_type { MLX5_VF, MLX5_SF, MLX5_HOST_PF, + MLX5_SPF, MLX5_EC_VF, MLX5_FUNC_TYPE_NUM, + MLX5_FUNC_TYPE_NONE = MLX5_FUNC_TYPE_NUM, }; +enum mlx5_page_mgt_mode { + MLX5_PAGE_MGT_MODE_FUNC_ID, + MLX5_PAGE_MGT_MODE_VHCA_ID, +}; + +struct mlx5_frag_buf_node_pools; struct mlx5_ft_pool; struct mlx5_priv { /* IRQ table valid only for real pci devices PF or VF */ @@ -575,20 +586,23 @@ struct mlx5_priv { u32 fw_pages_alloc_failed; u32 give_pages_dropped; u32 reclaim_pages_discard; + enum mlx5_page_mgt_mode page_mgt_mode; struct mlx5_core_health health; struct list_head traps; struct mlx5_debugfs_entries dbg; - /* start: alloc staff */ + /* start: alloc stuff */ /* protect buffer allocation according to numa node */ struct mutex alloc_mutex; int numa_node; struct mutex pgdir_mutex; struct list_head pgdir_list; - /* end: alloc staff */ + + struct mlx5_frag_buf_node_pools **frag_buf_node_pools; + /* end: alloc stuff */ struct mlx5_adev **adev; int adev_idx; @@ -1034,6 +1048,8 @@ void mlx5_pagealloc_start(struct mlx5_core_dev *dev); void mlx5_pagealloc_stop(struct mlx5_core_dev *dev); void mlx5_pages_debugfs_init(struct mlx5_core_dev *dev); void mlx5_pages_debugfs_cleanup(struct mlx5_core_dev *dev); +void mlx5_pages_by_func_type_debugfs_init(struct mlx5_core_dev *dev); +void mlx5_pages_by_func_type_debugfs_cleanup(struct mlx5_core_dev *dev); int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot); int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev); void mlx5_register_debugfs(void); diff --git a/include/linux/mlx5/eswitch.h b/include/linux/mlx5/eswitch.h index 67256e776566..a0dd162baa78 100644 --- a/include/linux/mlx5/eswitch.h +++ b/include/linux/mlx5/eswitch.h @@ -63,7 +63,13 @@ struct mlx5_eswitch_rep { void mlx5_eswitch_register_vport_reps(struct mlx5_eswitch *esw, const struct mlx5_eswitch_rep_ops *ops, u8 rep_type); +void +mlx5_eswitch_register_vport_reps_nested(struct mlx5_eswitch *esw, + const struct mlx5_eswitch_rep_ops *ops, + u8 rep_type); void mlx5_eswitch_unregister_vport_reps(struct mlx5_eswitch *esw, u8 rep_type); +void mlx5_eswitch_unregister_vport_reps_nested(struct mlx5_eswitch *esw, + u8 rep_type); void *mlx5_eswitch_get_proto_dev(struct mlx5_eswitch *esw, u16 vport_num, u8 rep_type); @@ -217,7 +223,7 @@ static inline bool is_mdev_switchdev_mode(struct mlx5_core_dev *dev) static inline u16 mlx5_eswitch_manager_vport(struct mlx5_core_dev *dev) { return mlx5_core_is_ecpf_esw_manager(dev) ? - MLX5_VPORT_ECPF : MLX5_VPORT_PF; + MLX5_VPORT_ECPF : MLX5_VPORT_HOST_PF; } #endif diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 49f3ad4b1a7c..695c86ee6d7a 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -1116,7 +1116,10 @@ struct mlx5_ifc_qos_cap_bits { u8 log_esw_max_sched_depth[0x4]; u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x9]; + u8 reserved_at_20[0x2]; + u8 packet_pacing_req_ud[0x1]; + u8 packet_pacing_req_uc[0x1]; + u8 reserved_at_24[0x5]; u8 esw_cross_esw_sched[0x1]; u8 reserved_at_2a[0x1]; u8 log_max_qos_nic_queue_group[0x5]; @@ -1935,7 +1938,8 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 max_flow_counter_31_16[0x10]; u8 max_wqe_sz_sq_dc[0x10]; - u8 reserved_at_2e0[0x7]; + u8 query_host_net_function_num_max[0x5]; + u8 reserved_at_2e5[0x2]; u8 max_qp_mcg[0x19]; u8 reserved_at_300[0x10]; @@ -1985,7 +1989,8 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 basic_cyclic_rcv_wqe[0x1]; u8 reserved_at_381[0x2]; u8 log_max_rmp[0x5]; - u8 reserved_at_388[0x3]; + u8 sd_group_size[0x1]; + u8 reserved_at_389[0x2]; u8 log_max_rqt[0x5]; u8 reserved_at_390[0x3]; u8 log_max_rqt_size[0x5]; @@ -2027,7 +2032,7 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 log_max_current_mc_list[0x5]; u8 reserved_at_3f8[0x1]; u8 silent_mode_query[0x1]; - u8 reserved_at_3fa[0x1]; + u8 query_host_net_function_v1[0x1]; u8 log_max_current_uc_list[0x5]; u8 general_obj_types[0x40]; @@ -3707,7 +3712,8 @@ struct mlx5_ifc_qpc_bits { u8 cur_retry_count[0x3]; u8 reserved_at_39b[0x5]; - u8 reserved_at_3a0[0x20]; + u8 reserved_at_3a0[0x10]; + u8 packet_pacing_rate_limit_index[0x10]; u8 reserved_at_3c0[0x8]; u8 next_send_psn[0x18]; @@ -4468,7 +4474,9 @@ struct mlx5_ifc_nic_vport_context_bits { u8 reserved_at_100[0x1]; u8 sd_group[0x3]; - u8 reserved_at_104[0x1c]; + u8 reserved_at_104[0x4]; + u8 sd_group_size[0x8]; + u8 reserved_at_110[0x10]; u8 reserved_at_120[0x10]; u8 mtu[0x10]; @@ -4486,8 +4494,8 @@ struct mlx5_ifc_nic_vport_context_bits { u8 promisc_all[0x1]; u8 reserved_at_783[0x2]; u8 allowed_list_type[0x3]; - u8 reserved_at_788[0xc]; - u8 allowed_list_size[0xc]; + u8 reserved_at_788[0x8]; + u8 allowed_list_size[0x10]; struct mlx5_ifc_mac_address_layout_bits permanent_address; @@ -8452,7 +8460,9 @@ struct mlx5_ifc_enable_hca_in_bits { u8 op_mod[0x10]; u8 embedded_cpu_function[0x1]; - u8 reserved_at_41[0xf]; + u8 reserved_at_41[0x2]; + u8 function_id_type[0x1]; + u8 reserved_at_44[0xc]; u8 function_id[0x10]; u8 reserved_at_60[0x20]; @@ -8497,7 +8507,9 @@ struct mlx5_ifc_disable_hca_in_bits { u8 op_mod[0x10]; u8 embedded_cpu_function[0x1]; - u8 reserved_at_41[0xf]; + u8 reserved_at_41[0x2]; + u8 function_id_type[0x1]; + u8 reserved_at_44[0xc]; u8 function_id[0x10]; u8 reserved_at_60[0x20]; @@ -12700,6 +12712,54 @@ struct mlx5_ifc_host_params_context_bits { u8 reserved_at_80[0x180]; }; +enum mlx5_ifc_vhca_state { + MLX5_VHCA_STATE_INVALID = 0x0, + MLX5_VHCA_STATE_ALLOCATED = 0x1, + MLX5_VHCA_STATE_ACTIVE = 0x2, + MLX5_VHCA_STATE_IN_USE = 0x3, + MLX5_VHCA_STATE_TEARDOWN_REQUEST = 0x4, +}; + +enum { + MLX5_PCI_PF_TYPE_EXTERNAL_HOST_PF = 0x0, + MLX5_PCI_PF_TYPE_SATELLITE_PF = 0x1, +}; + +struct mlx5_ifc_network_function_params_bits { + u8 host_number[0x8]; + u8 pci_pf_type[0x4]; + u8 reserved_at_c[0x4]; + u8 pci_num_vfs[0x10]; + + u8 pci_total_vfs[0x10]; + u8 pci_bus[0x8]; + u8 pci_device_function[0x8]; + + u8 vhca_id[0x10]; + u8 vhca_state[0x4]; + u8 reserved_at_54[0xc]; + + u8 reserved_at_60[0xa]; + u8 esw_vport_manual[0x1]; + u8 pci_bus_assigned[0x1]; + u8 pci_vf_info_valid[0x1]; + u8 reserved_at_6d[0x13]; + + u8 pci_vf_stride[0x10]; + u8 pci_first_vf_offset[0x10]; + + u8 reserved_at_a0[0x160]; +}; + +union mlx5_ifc_net_function_params_bits { + struct mlx5_ifc_host_params_context_bits host_params_context; + struct mlx5_ifc_network_function_params_bits network_function_params; +}; + +enum { + MLX5_QUERY_ESW_FUNC_OP_MOD_LAYOUT_V1 = BIT(14), +}; + struct mlx5_ifc_query_esw_functions_in_bits { u8 opcode[0x10]; u8 reserved_at_10[0x10]; @@ -12716,12 +12776,16 @@ struct mlx5_ifc_query_esw_functions_out_bits { u8 syndrome[0x20]; - u8 reserved_at_40[0x40]; + u8 reserved_at_40[0x20]; - struct mlx5_ifc_host_params_context_bits host_params_context; + u8 net_function_num[0x8]; + u8 reserved_at_68[0x18]; - u8 reserved_at_280[0x180]; - u8 host_sf_enable[][0x40]; + union { + u8 reserved_at_80[0x380]; + DECLARE_FLEX_ARRAY(union mlx5_ifc_net_function_params_bits, + net_function_params); + }; }; struct mlx5_ifc_sf_partition_bits { diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h index d67aedc6ea68..40f889403b07 100644 --- a/include/linux/mlx5/qp.h +++ b/include/linux/mlx5/qp.h @@ -72,6 +72,7 @@ enum mlx5_qp_optpar { MLX5_QP_OPTPAR_CQN_RCV = 1 << 19, MLX5_QP_OPTPAR_DC_HS = 1 << 20, MLX5_QP_OPTPAR_DC_KEY = 1 << 21, + MLX5_QP_OPTPAR_PP_INDEX = 1 << 22, MLX5_QP_OPTPAR_COUNTER_SET_ID = 1 << 25, }; diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h index 282ed5442282..ee34d3ed335f 100644 --- a/include/linux/mlx5/vport.h +++ b/include/linux/mlx5/vport.h @@ -51,8 +51,8 @@ enum { /* Vport number for each function must keep unchanged */ enum { - MLX5_VPORT_PF = 0x0, - MLX5_VPORT_FIRST_VF = 0x1, + MLX5_VPORT_HOST_PF = 0x0, + MLX5_VPORT_FIRST_HOST_VF = 0x1, MLX5_VPORT_ECPF = 0xfffe, MLX5_VPORT_UPLINK = 0xffff }; diff --git a/include/linux/mm.h b/include/linux/mm.h index fc2acedf0b76..485df9c2dbdd 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -496,6 +496,21 @@ enum { #else #define VM_UFFD_MINOR VM_NONE #endif + +/* + * vma_flags_t masks for the userfaultfd VMA flags. VMA_UFFD_MINOR is gated on + * the same config as VM_UFFD_MINOR -- which implies 64BIT, where the bit fits + * -- so an out-of-range bit is never fed to mk_vma_flags() on a build whose + * bitmap cannot hold it. + */ +#define VMA_UFFD_MISSING mk_vma_flags(VMA_UFFD_MISSING_BIT) +#define VMA_UFFD_WP mk_vma_flags(VMA_UFFD_WP_BIT) +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR +#define VMA_UFFD_MINOR mk_vma_flags(VMA_UFFD_MINOR_BIT) +#else +#define VMA_UFFD_MINOR EMPTY_VMA_FLAGS +#endif + #ifdef CONFIG_64BIT #define VM_ALLOW_ANY_UNCACHED INIT_VM_FLAG(ALLOW_ANY_UNCACHED) #define VM_SEALED INIT_VM_FLAG(SEALED) @@ -1238,6 +1253,30 @@ static __always_inline void vma_flags_set_mask(vma_flags_t *flags, #define vma_flags_set(flags, ...) \ vma_flags_set_mask(flags, mk_vma_flags(__VA_ARGS__)) +static __always_inline vma_flags_t __mk_vma_flags_from_masks(size_t count, + const vma_flags_t *masks) +{ + vma_flags_t flags = EMPTY_VMA_FLAGS; + size_t i; + + for (i = 0; i < count; i++) + vma_flags_set_mask(&flags, masks[i]); + return flags; +} + +/* + * Combine pre-computed vma_flags_t masks into one value, e.g.: + * + * vma_flags_t flags = mk_vma_flags_from_masks(VMA_UFFD_WP, VMA_UFFD_MINOR); + * + * Unlike mk_vma_flags(), which takes bit numbers, this takes whole masks -- + * each of which may be EMPTY_VMA_FLAGS when its feature is unavailable -- so a + * bit that does not exist on the current build is never materialised. + */ +#define mk_vma_flags_from_masks(...) \ + __mk_vma_flags_from_masks(COUNT_ARGS(__VA_ARGS__), \ + (const vma_flags_t []){__VA_ARGS__}) + /* Clear all of the to-clear flags in flags, non-atomically. */ static __always_inline void vma_flags_clear_mask(vma_flags_t *flags, vma_flags_t to_clear) @@ -1489,6 +1528,11 @@ static inline void vma_set_anonymous(struct vm_area_struct *vma) vma->vm_ops = NULL; } +static inline void vma_desc_set_anonymous(struct vm_area_desc *desc) +{ + desc->vm_ops = NULL; +} + static inline bool vma_is_anonymous(struct vm_area_struct *vma) { return !vma->vm_ops; @@ -1888,16 +1932,6 @@ static inline bool folio_mapped(const struct folio *folio) return folio_mapcount(folio) >= 1; } -/* - * Return true if this page is mapped into pagetables. - * For compound page it returns true if any sub-page of compound page is mapped, - * even if this particular sub-page is not itself mapped by any PTE or PMD. - */ -static inline bool page_mapped(const struct page *page) -{ - return folio_mapped(page_folio(page)); -} - static inline struct page *virt_to_head_page(const void *x) { struct page *page = virt_to_page(x); @@ -4855,18 +4889,10 @@ static inline void print_vma_addr(char *prefix, unsigned long rip) } #endif -void *sparse_buffer_alloc(unsigned long size); unsigned long section_map_size(void); struct page * __populate_section_memmap(unsigned long pfn, unsigned long nr_pages, int nid, struct vmem_altmap *altmap, struct dev_pagemap *pgmap); -pgd_t *vmemmap_pgd_populate(unsigned long addr, int node); -p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node); -pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node); -pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node); -pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, - struct vmem_altmap *altmap, unsigned long ptpfn, - unsigned long flags); void *vmemmap_alloc_block(unsigned long size, int node); struct vmem_altmap; void *vmemmap_alloc_block_buf(unsigned long size, int node, diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index a171070e15f0..a8430a7ae054 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -247,7 +247,7 @@ static inline unsigned long lru_gen_folio_seq(const struct lruvec *lruvec, (folio_test_dirty(folio) || folio_test_writeback(folio)))) gen = MIN_NR_GENS; else - gen = MAX_NR_GENS - folio_test_workingset(folio); + gen = MAX_NR_GENS - (folio_test_workingset(folio) || folio_test_referenced(folio)); return max(READ_ONCE(lrugen->max_seq) - gen + 1, READ_ONCE(lrugen->min_seq[type])); } diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 5cadb00d9352..b18c2b2e7d2c 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -845,23 +845,10 @@ struct mmap_action { enum mmap_action_type type; /* - * If specified, this hook is invoked after the selected action has been - * successfully completed. Note that the VMA write lock still held. - * - * The absolute minimum ought to be done here. - * - * Returns 0 on success, or an error code. - */ - int (*success_hook)(const struct vm_area_struct *vma); - - /* - * If specified, this hook is invoked when an error occurred when - * attempting the selected action. - * - * The hook can return an error code in order to filter the error, but - * it is not valid to clear the error here. + * If non-zero, replace errors that arise from mmap actions with this + * value instead. Only valid error codes may be specified. */ - int (*error_hook)(int err); + int error_override; /* * This should be set in rare instances where the operation required diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 69c304b467df..a11a44eef521 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -134,8 +134,8 @@ struct mmu_notifier_ops { * Invalidation of multiple concurrent ranges may be * optionally permitted by the driver. Either way the * establishment of sptes is forbidden in the range passed to - * invalidate_range_begin/end for the whole duration of the - * invalidate_range_begin/end critical section. + * invalidate_range_start/end for the whole duration of the + * invalidate_range_start/end critical section. * * invalidate_range_start() is called when all pages in the * range are still mapped and have at least a refcount of one. diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9adb2ad21da5..ca2712187147 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -177,9 +177,12 @@ static inline bool migratetype_is_mergeable(int mt) return mt < MIGRATE_PCPTYPES; } -#define for_each_migratetype_order(order, type) \ - for (order = 0; order < NR_PAGE_ORDERS; order++) \ - for (type = 0; type < MIGRATE_TYPES; type++) +#define for_each_free_list(list, zone, order) \ + for (order = 0; order < NR_PAGE_ORDERS; order++) \ + for (unsigned int __type = 0; \ + __type < MIGRATE_TYPES && \ + (list = &(zone)->free_area[order].free_list[__type], 1); \ + __type++) extern int page_group_by_mobility_disabled; @@ -211,7 +214,6 @@ enum numa_stat_item { #endif enum zone_stat_item { - /* First 128 byte cacheline (assuming 64 bit words) */ NR_FREE_PAGES, NR_FREE_PAGES_BLOCKS, NR_ZONE_LRU_BASE, /* Used only for compaction and reclaim retry */ @@ -222,7 +224,6 @@ enum zone_stat_item { NR_ZONE_UNEVICTABLE, NR_ZONE_WRITE_PENDING, /* Count of dirty, writeback and unstable pages */ NR_MLOCK, /* mlock()ed pages found and moved off LRU */ - /* Second 128 byte cacheline */ #if IS_ENABLED(CONFIG_ZSMALLOC) NR_ZSPAGES, /* allocated in zsmalloc */ #endif @@ -1428,14 +1429,6 @@ struct zonelist { */ extern struct page *mem_map; -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -struct deferred_split { - spinlock_t split_queue_lock; - struct list_head split_queue; - unsigned long split_queue_len; -}; -#endif - #ifdef CONFIG_MEMORY_FAILURE /* * Per NUMA node memory failure handling statistics. @@ -1561,10 +1554,6 @@ typedef struct pglist_data { unsigned long first_deferred_pfn; #endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */ -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - struct deferred_split deferred_split_queue; -#endif - #ifdef CONFIG_NUMA_BALANCING /* start time in ms of current promote rate limit period */ unsigned int nbp_rl_start; diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 23ff24080dfd..3b0c9a251a2e 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -61,7 +61,10 @@ struct ieee1394_device_id { __u32 model_id; __u32 specifier_id; __u32 version; - kernel_ulong_t driver_data; + union { + kernel_ulong_t driver_data; + const void *driver_data_ptr; + }; }; diff --git a/include/linux/mroute_base.h b/include/linux/mroute_base.h index 5d75cc5b057e..4d55827e9705 100644 --- a/include/linux/mroute_base.h +++ b/include/linux/mroute_base.h @@ -256,7 +256,7 @@ struct mr_table { struct rhltable mfc_hash; struct list_head mfc_cache_list; int maxvif; - atomic_t cache_resolve_queue_len; + u32 cache_resolve_queue_len; bool mroute_do_assert; bool mroute_do_pim; bool mroute_do_wrvifwhole; diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h index e8201d1b7cf9..006ca8c978a9 100644 --- a/include/linux/mtd/nand-qpic-common.h +++ b/include/linux/mtd/nand-qpic-common.h @@ -9,6 +9,8 @@ #ifndef __MTD_NAND_QPIC_COMMON_H__ #define __MTD_NAND_QPIC_COMMON_H__ +#include <linux/mtd/rawnand.h> + /* NANDc reg offsets */ #define NAND_FLASH_CMD 0x00 #define NAND_ADDR0 0x04 @@ -394,7 +396,7 @@ struct qcom_nand_controller { const struct qcom_nandc_props *props; - struct nand_controller *controller; + struct nand_controller controller; struct qpic_spi_nand *qspi; struct list_head host_list; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index cdcfe0fd2e7d..4b92494827b1 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -21,8 +21,8 @@ /* Flash opcodes. */ #define SPINOR_OP_WRDI 0x04 /* Write disable */ #define SPINOR_OP_WREN 0x06 /* Write enable */ -#define SPINOR_OP_RDSR 0x05 /* Read status register */ -#define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ +#define SPINOR_OP_RDSR 0x05 /* Read status register 1 */ +#define SPINOR_OP_WRSR 0x01 /* Write status register 1 */ #define SPINOR_OP_RDSR2 0x3f /* Read status register 2 */ #define SPINOR_OP_WRSR2 0x3e /* Write status register 2 */ #define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */ @@ -125,6 +125,7 @@ #define SR2_LB1 BIT(3) /* Security Register Lock Bit 1 */ #define SR2_LB2 BIT(4) /* Security Register Lock Bit 2 */ #define SR2_LB3 BIT(5) /* Security Register Lock Bit 3 */ +#define SR2_CMP_BIT6 BIT(6) #define SR2_QUAD_EN_BIT7 BIT(7) /* Supported SPI protocols */ @@ -371,6 +372,7 @@ struct spi_nor_flash_parameter; * @reg_proto: the SPI protocol for read_reg/write_reg/erase operations * @sfdp: the SFDP data of the flash * @debugfs_root: pointer to the debugfs directory + * @dfs_sr_cache: Status Register cached value for debugfs use only * @controller_ops: SPI NOR controller driver specific operations. * @params: [FLASH-SPECIFIC] SPI NOR flash parameters and settings. * The structure includes legacy flash parameters and @@ -409,6 +411,7 @@ struct spi_nor { enum spi_nor_cmd_ext cmd_ext_type; struct sfdp *sfdp; struct dentry *debugfs_root; + u8 dfs_sr_cache[2]; const struct spi_nor_controller_ops *controller_ops; diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index f53f5f0499b4..ec6efcfeef83 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -583,6 +583,7 @@ enum spinand_bus_interface { * @op_variants.read_cache: variants of the read-cache operation * @op_variants.write_cache: variants of the write-cache operation * @op_variants.update_cache: variants of the update-cache operation + * @op_variants.cont_read_cache: variants of the continuous read-cache operation * @vendor_ops: vendor specific operations * @select_target: function used to select a target/die. Required only for * multi-die chips @@ -592,6 +593,7 @@ enum spinand_bus_interface { * @user_otp: SPI NAND user OTP info. * @read_retries: the number of read retry modes supported * @set_read_retry: enable/disable read retry for data recovery + * @set_randomizer: enable/disable randomizer support * * Each SPI NAND manufacturer driver should have a spinand_info table * describing all the chips supported by the driver. @@ -607,6 +609,7 @@ struct spinand_info { const struct spinand_op_variants *read_cache; const struct spinand_op_variants *write_cache; const struct spinand_op_variants *update_cache; + const struct spinand_op_variants *cont_read_cache; } op_variants; const struct spinand_op_variants *vendor_ops; int (*select_target)(struct spinand_device *spinand, @@ -620,6 +623,8 @@ struct spinand_info { unsigned int read_retries; int (*set_read_retry)(struct spinand_device *spinand, unsigned int read_retry); + int (*set_randomizer)(struct spinand_device *spinand, + bool enable); }; #define SPINAND_ID(__method, ...) \ @@ -636,6 +641,14 @@ struct spinand_info { .update_cache = __update, \ } +#define SPINAND_INFO_OP_VARIANTS_WITH_CONT(__read, __write, __update, __cont_read) \ + { \ + .read_cache = __read, \ + .write_cache = __write, \ + .update_cache = __update, \ + .cont_read_cache = __cont_read, \ + } + #define SPINAND_INFO_VENDOR_OPS(__ops) \ .vendor_ops = __ops @@ -676,6 +689,9 @@ struct spinand_info { .read_retries = __read_retries, \ .set_read_retry = __set_read_retry +#define SPINAND_RANDOMIZER(__set_randomizer) \ + .set_randomizer = __set_randomizer + #define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants, \ __flags, ...) \ { \ @@ -707,6 +723,7 @@ struct spinand_dirmap { * @read_cache: read cache op template * @write_cache: write cache op template * @update_cache: update cache op template + * @cont_read_cache: continuous read cache op template (optional) */ struct spinand_mem_ops { struct spi_mem_op reset; @@ -721,6 +738,7 @@ struct spinand_mem_ops { const struct spi_mem_op *read_cache; const struct spi_mem_op *write_cache; const struct spi_mem_op *update_cache; + const struct spi_mem_op *cont_read_cache; }; /** @@ -759,6 +777,7 @@ struct spinand_mem_ops { * @user_otp: SPI NAND user OTP info. * @read_retries: the number of read retry modes supported * @set_read_retry: Enable/disable the read retry feature + * @set_randomizer: Enable/disable the randomizer feature */ struct spinand_device { struct nand_device base; @@ -792,6 +811,8 @@ struct spinand_device { bool cont_read_possible; int (*set_cont_read)(struct spinand_device *spinand, bool enable); + int (*set_randomizer)(struct spinand_device *spinand, + bool enable); const struct spinand_fact_otp *fact_otp; const struct spinand_user_otp *user_otp; diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h index a961861a503b..449e38e6e2c5 100644 --- a/include/linux/mux/consumer.h +++ b/include/linux/mux/consumer.h @@ -60,7 +60,10 @@ struct mux_control *mux_control_get_optional(struct device *dev, const char *mux void mux_control_put(struct mux_control *mux); struct mux_control *devm_mux_control_get(struct device *dev, const char *mux_name); -struct mux_state *devm_mux_state_get(struct device *dev, const char *mux_name); + +struct mux_state * +devm_mux_state_get_from_np(struct device *dev, const char *mux_name, struct device_node *np); + struct mux_state *devm_mux_state_get_optional(struct device *dev, const char *mux_name); struct mux_state *devm_mux_state_get_selected(struct device *dev, const char *mux_name); struct mux_state *devm_mux_state_get_optional_selected(struct device *dev, const char *mux_name); @@ -161,4 +164,7 @@ static inline struct mux_state *devm_mux_state_get_optional_selected(struct devi #endif /* CONFIG_MULTIPLEXER */ +#define devm_mux_state_get(dev, mux_name) \ + devm_mux_state_get_from_np(dev, mux_name, NULL) + #endif /* _LINUX_MUX_CONSUMER_H */ diff --git a/include/linux/net/intel/libie/adminq.h b/include/linux/net/intel/libie/adminq.h index ab13bd777a28..839114d8975a 100644 --- a/include/linux/net/intel/libie/adminq.h +++ b/include/linux/net/intel/libie/adminq.h @@ -196,6 +196,7 @@ LIBIE_CHECK_STRUCT_LEN(16, libie_aqc_list_caps); #define LIBIE_AQC_BIT_ROCEV2_LAG BIT(0) #define LIBIE_AQC_BIT_SRIOV_LAG BIT(1) #define LIBIE_AQC_BIT_SRIOV_AA_LAG BIT(2) +#define LIBIE_AQC_CAPS_EEE 0x009B #define LIBIE_AQC_CAPS_FLEX10 0x00F1 #define LIBIE_AQC_CAPS_CEM 0x00F2 diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index 93e4da7046a1..8eb6b8033606 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h @@ -79,7 +79,7 @@ enum { NETIF_F_HW_TLS_RX_BIT, /* Hardware TLS RX offload */ NETIF_F_GRO_HW_BIT, /* Hardware Generic receive offload */ - NETIF_F_HW_TLS_RECORD_BIT, /* Offload TLS record */ + __UNUSED_NETIF_F_56, NETIF_F_GRO_FRAGLIST_BIT, /* Fraglist GRO */ NETIF_F_HW_MACSEC_BIT, /* Offload MACsec operations */ @@ -153,7 +153,6 @@ enum { #define NETIF_F_HW_ESP __NETIF_F(HW_ESP) #define NETIF_F_HW_ESP_TX_CSUM __NETIF_F(HW_ESP_TX_CSUM) #define NETIF_F_RX_UDP_TUNNEL_PORT __NETIF_F(RX_UDP_TUNNEL_PORT) -#define NETIF_F_HW_TLS_RECORD __NETIF_F(HW_TLS_RECORD) #define NETIF_F_GSO_UDP_L4 __NETIF_F(GSO_UDP_L4) #define NETIF_F_HW_TLS_TX __NETIF_F(HW_TLS_TX) #define NETIF_F_HW_TLS_RX __NETIF_F(HW_TLS_RX) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 0e1e581efc5a..b67a12541eac 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1122,13 +1122,14 @@ struct netdev_net_notifier { * Cannot sleep, called with netif_addr_lock_bh held. * Deprecated in favor of ndo_set_rx_mode_async. * - * void (*ndo_set_rx_mode_async)(struct net_device *dev, - * struct netdev_hw_addr_list *uc, - * struct netdev_hw_addr_list *mc); + * int (*ndo_set_rx_mode_async)(struct net_device *dev, + * struct netdev_hw_addr_list *uc, + * struct netdev_hw_addr_list *mc); * Async version of ndo_set_rx_mode which runs in process context * with rtnl_lock and netdev_lock_ops(dev) held. The uc/mc parameters * are snapshots of the address lists - iterate with - * netdev_hw_addr_list_for_each(ha, uc). + * netdev_hw_addr_list_for_each(ha, uc). Return 0 on success or a + * negative errno to request a retry via the core backoff. * * int (*ndo_set_mac_address)(struct net_device *dev, void *addr); * This function is called when the Media Access Control address @@ -1149,8 +1150,8 @@ struct netdev_net_notifier { * SIOCBONDSLAVEINFOQUERY, and SIOCBONDINFOQUERY * * * int (*ndo_eth_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); - * Called for ethernet specific ioctls: SIOCGMIIPHY, SIOCGMIIREG, - * SIOCSMIIREG, SIOCSHWTSTAMP and SIOCGHWTSTAMP. + * Called for ethernet specific ioctls: SIOCGMIIPHY, SIOCGMIIREG and + * SIOCSMIIREG. * * int (*ndo_set_config)(struct net_device *dev, struct ifmap *map); * Used to set network devices bus interface parameters. This interface @@ -1223,6 +1224,12 @@ struct netdev_net_notifier { * tx queues stopped. This allows the netdevice to perform queue * management safely. * + * NB: Returning -EOPNOTSUPP for whatever commands means "this qdisc + * is not offloaded (anymore, offloading may have silently stopped)", + * and the offloading flag is cleared. Notably, this is also true for + * dump queries (e.g. TC_*_STATS commands). If the underlying device does + * not report any statistics but is still offloading, return 0 instead. + * * Fiber Channel over Ethernet (FCoE) offload functions. * int (*ndo_fcoe_enable)(struct net_device *dev); * Called when the FCoE protocol stack wants to start using LLD for FCoE @@ -1449,7 +1456,7 @@ struct net_device_ops { void (*ndo_change_rx_flags)(struct net_device *dev, int flags); void (*ndo_set_rx_mode)(struct net_device *dev); - void (*ndo_set_rx_mode_async)( + int (*ndo_set_rx_mode_async)( struct net_device *dev, struct netdev_hw_addr_list *uc, struct netdev_hw_addr_list *mc); @@ -1788,6 +1795,12 @@ enum netdev_stat_type { NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */ }; +enum netmem_tx_mode { + NETMEM_TX_NONE, /* no netmem TX support */ + NETMEM_TX_DMA, /* DMA-capable netmem TX (real HW) */ + NETMEM_TX_NO_DMA, /* no DMA, e.g. passthrough for virtual devs */ +}; + enum netdev_reg_state { NETREG_UNINITIALIZED = 0, NETREG_REGISTERED, /* completed register_netdevice */ @@ -1809,7 +1822,7 @@ enum netdev_reg_state { * @lltx: device supports lockless Tx. Deprecated for real HW * drivers. Mainly used by logical interfaces, such as * bonding and tunnels - * @netmem_tx: device support netmem_tx. + * @netmem_tx: device netmem TX mode * * @name: This is the first field of the "visible" part of this structure * (i.e. as seen by users in the "Space.c" file). It is the name @@ -1920,6 +1933,8 @@ enum netdev_reg_state { * @rx_mode_node: List entry for rx_mode work processing * @rx_mode_tracker: Refcount tracker for rx_mode work * @rx_mode_addr_cache: Recycled snapshot entries for rx_mode work + * @rx_mode_retry_timer: Timer that re-queues rx_mode work after failure + * @rx_mode_retry_count: Number of consecutive retries already scheduled * @uc: unicast mac addresses * @mc: multicast mac addresses * @dev_addrs: list of device hw addresses @@ -1932,10 +1947,8 @@ enum netdev_reg_state { * @vlan_info: VLAN info * @dsa_ptr: dsa specific data * @tipc_ptr: TIPC specific data - * @atalk_ptr: AppleTalk link * @ip_ptr: IPv4 specific data * @ip6_ptr: IPv6 specific data - * @ax25_ptr: AX.25 specific data * @ieee80211_ptr: IEEE 802.11 specific data, assign before registering * @ieee802154_ptr: IEEE 802.15.4 low-rate Wireless Personal Area Network * device struct @@ -1980,6 +1993,8 @@ enum netdev_reg_state { * @qdisc_hash: qdisc hash table * @watchdog_timeo: Represents the timeout that is used by * the watchdog (see dev_watchdog()) + * @watchdog_lock: protect watchdog_ref_held + * @watchdog_ref_held: True if the watchdog device ref is taken. * @watchdog_timer: List of timers * * @proto_down_reason: reason a netdev interface is held down @@ -2132,7 +2147,7 @@ struct net_device { struct_group(priv_flags_fast, unsigned long priv_flags:32; unsigned long lltx:1; - unsigned long netmem_tx:1; + unsigned long netmem_tx:2; ); const struct net_device_ops *netdev_ops; const struct header_ops *header_ops; @@ -2314,6 +2329,8 @@ struct net_device { struct list_head rx_mode_node; netdevice_tracker rx_mode_tracker; struct netdev_hw_addr_list rx_mode_addr_cache; + struct timer_list rx_mode_retry_timer; + unsigned int rx_mode_retry_count; #ifdef CONFIG_LOCKDEP unsigned char nested_level; #endif @@ -2333,9 +2350,6 @@ struct net_device { #if IS_ENABLED(CONFIG_TIPC) struct tipc_bearer __rcu *tipc_ptr; #endif -#if IS_ENABLED(CONFIG_ATALK) - void *atalk_ptr; -#endif #if IS_ENABLED(CONFIG_CFG80211) struct wireless_dev *ieee80211_ptr; #endif @@ -2392,6 +2406,8 @@ struct net_device { /* These may be needed for future network-power-down code. */ struct timer_list watchdog_timer; int watchdog_timeo; + spinlock_t watchdog_lock; + bool watchdog_ref_held; u32 proto_down_reason; @@ -2572,6 +2588,9 @@ struct net_device { * Double protects: * @up, @moving_ns, @nd_net, @xdp_features * + * Ops protects: + * @cfg, @cfg_pending, @ethtool, @hwprov + * * Double ops protects: * @real_num_rx_queues, @real_num_tx_queues * @@ -3378,7 +3397,6 @@ static inline struct net_device *first_net_device(struct net *net) net_device_entry(net->dev_base_head.next); } -int netdev_boot_setup_check(struct net_device *dev); struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, const char *hwaddr); struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, @@ -5138,6 +5156,7 @@ static inline void __dev_mc_unsync(struct net_device *dev, /* Functions used for secondary unicast and multicast support */ void dev_set_rx_mode(struct net_device *dev); +void netif_rx_mode_schedule_retry(struct net_device *dev); int netif_set_promiscuity(struct net_device *dev, int inc); int dev_set_promiscuity(struct net_device *dev, int inc); int netif_set_allmulti(struct net_device *dev, int inc, bool notify); diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 5a1c5c336fa4..20d70dddbe50 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -534,4 +534,21 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems, unsigned int next_offset); #endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ + +static inline bool xt_compat_check(void) +{ +#ifdef CONFIG_NETFILTER_XTABLES_COMPAT + if (!in_compat_syscall()) + return true; + + pr_warn_once("%s %s\n", + "xtables 32bit compat interface no longer supported", + "in namespaces and will be removed soon."); + + if (!capable(CAP_NET_ADMIN)) + return false; +#endif + return true; +} + #endif /* _X_TABLES_H */ diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index f22eec466040..88f7daa8560e 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -13,12 +13,28 @@ #include <linux/rcupdate.h> #include <linux/list.h> #include <linux/refcount.h> +#include <linux/ip.h> +#include <linux/udp.h> union inet_addr { __be32 ip; struct in6_addr in6; }; +/* + * Maximum payload netpoll's preallocated skb pool can carry. Keep this in + * sync with the buffer size used by refill_skbs() in net/core/netpoll.c; + * callers (e.g. netconsole) use it to detect requests the pool can never + * satisfy and avoid dequeuing a pooled skb that would later trip + * skb_over_panic() in skb_put(). + */ +#define MAX_UDP_CHUNK 1460 +#define MAX_SKB_SIZE \ + (sizeof(struct ethhdr) + \ + sizeof(struct iphdr) + \ + sizeof(struct udphdr) + \ + MAX_UDP_CHUNK) + struct netpoll { struct net_device *dev; netdevice_tracker dev_tracker; @@ -67,13 +83,13 @@ static inline void netpoll_poll_disable(struct net_device *dev) { return; } static inline void netpoll_poll_enable(struct net_device *dev) { return; } #endif -int netpoll_send_udp(struct netpoll *np, const char *msg, int len); int __netpoll_setup(struct netpoll *np, struct net_device *ndev); int netpoll_setup(struct netpoll *np); void __netpoll_free(struct netpoll *np); void netpoll_cleanup(struct netpoll *np); void do_netpoll_cleanup(struct netpoll *np); netdev_tx_t netpoll_send_skb(struct netpoll *np, struct sk_buff *skb); +void netpoll_zap_completion_queue(void); #ifdef CONFIG_NETPOLL static inline void *netpoll_poll_lock(struct napi_struct *napi) diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 204c92462f3c..b842aa525546 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -24,23 +24,23 @@ * void nodes_setall(mask) set all bits * void nodes_clear(mask) clear all bits * int node_isset(node, mask) true iff bit 'node' set in mask - * int node_test_and_set(node, mask) test and set bit 'node' in mask + * bool node_test_and_set(node, mask) test and set bit 'node' in mask * - * void nodes_and(dst, src1, src2) dst = src1 & src2 [intersection] + * bool nodes_and(dst, src1, src2) dst = src1 & src2 [intersection] * void nodes_or(dst, src1, src2) dst = src1 | src2 [union] * void nodes_xor(dst, src1, src2) dst = src1 ^ src2 - * void nodes_andnot(dst, src1, src2) dst = src1 & ~src2 + * bool nodes_andnot(dst, src1, src2) dst = src1 & ~src2 * void nodes_complement(dst, src) dst = ~src * - * int nodes_equal(mask1, mask2) Does mask1 == mask2? - * int nodes_intersects(mask1, mask2) Do mask1 and mask2 intersect? - * int nodes_subset(mask1, mask2) Is mask1 a subset of mask2? - * int nodes_empty(mask) Is mask empty (no bits sets)? - * int nodes_full(mask) Is mask full (all bits sets)? + * bool nodes_equal(mask1, mask2) Does mask1 == mask2? + * bool nodes_intersects(mask1, mask2) Do mask1 and mask2 intersect? + * bool nodes_subset(mask1, mask2) Is mask1 a subset of mask2? + * bool nodes_empty(mask) Is mask empty (no bits sets)? + * bool nodes_full(mask) Is mask full (all bits sets)? * int nodes_weight(mask) Hamming weight - number of set bits * * unsigned int first_node(mask) Number lowest set bit, or MAX_NUMNODES - * unsigend int next_node(node, mask) Next node past 'node', or MAX_NUMNODES + * unsigned int next_node(node, mask) Next node past 'node', or MAX_NUMNODES * unsigned int next_node_in(node, mask) Next node past 'node', or wrap to first, * or MAX_NUMNODES * unsigned int first_unset_node(mask) First node not set in mask, or diff --git a/include/linux/of.h b/include/linux/of.h index 959786f8f196..20e4f752d5b6 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -465,8 +465,17 @@ const char *of_prop_next_string(const struct property *prop, const char *cur); bool of_console_check(const struct device_node *dn, char *name, int index); int of_map_id(const struct device_node *np, u32 id, - const char *map_name, const char *map_mask_name, - struct device_node **target, u32 *id_out); + const char *map_name, const char *cells_name, + const char *map_mask_name, + struct device_node * const *filter_np, + struct of_phandle_args *arg); + +int of_map_iommu_id(const struct device_node *np, u32 id, + struct of_phandle_args *arg); + +int of_map_msi_id(const struct device_node *np, u32 id, + struct device_node * const *filter_np, + struct of_phandle_args *arg); phys_addr_t of_dma_get_max_cpu_address(struct device_node *np); @@ -942,8 +951,23 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag } static inline int of_map_id(const struct device_node *np, u32 id, - const char *map_name, const char *map_mask_name, - struct device_node **target, u32 *id_out) + const char *map_name, const char *cells_name, + const char *map_mask_name, + struct device_node * const *filter_np, + struct of_phandle_args *arg) +{ + return -EINVAL; +} + +static inline int of_map_iommu_id(const struct device_node *np, u32 id, + struct of_phandle_args *arg) +{ + return -EINVAL; +} + +static inline int of_map_msi_id(const struct device_node *np, u32 id, + struct device_node * const *filter_np, + struct of_phandle_args *arg) { return -EINVAL; } @@ -1476,6 +1500,13 @@ static inline int of_property_read_s32(const struct device_node *np, return of_property_read_u32(np, propname, (u32*) out_value); } +static inline int of_property_read_s32_index(const struct device_node *np, + const char *propname, u32 index, + s32 *out_value) +{ + return of_property_read_u32_index(np, propname, index, (u32 *)out_value); +} + #define of_for_each_phandle(it, err, np, ln, cn, cc) \ for (of_phandle_iterator_init((it), (np), (ln), (cn), (cc)), \ err = of_phandle_iterator_next(it); \ diff --git a/include/linux/page_ref.h b/include/linux/page_ref.h index 94d3f0e71c06..9f5c75d06f76 100644 --- a/include/linux/page_ref.h +++ b/include/linux/page_ref.h @@ -71,6 +71,12 @@ static inline int page_ref_count(const struct page *page) * folio_ref_count - The reference count on this folio. * @folio: The folio. * + * Folios contain a reference count. When that reference count reaches + * zero, the folio is referred to as frozen. At this point, it will + * usually be returned to the memory allocator, but some parts of the + * kernel freeze folios in order to perform unusual operations on them + * such as splitting or migration. + * * The refcount is usually incremented by calls to folio_get() and * decremented by calls to folio_put(). Some typical users of the * folio refcount: @@ -82,6 +88,18 @@ static inline int page_ref_count(const struct page *page) * - Pipes * - Direct IO which references this page in the process address space * + * The reference count has three components: expected, temporary and + * spurious. The expected reference count of a folio is that which + * we would logically expect it to be from just reading the code. + * Temporary refcounts are gained by threads which need a temporary + * reference to make sure the folio isn't reallocated while they use it. + * Spurious refcounts are gained by threads which, thanks to RCU walks + * of the page tables or file cache, find a stale pointer to a folio. + * These threads will drop the refcount after discoveering the pointer + * is stale, but it can surprise other users to see the spurious refcount + * on a freshly allocated folio (eg they may see a refcount of 2 instead + * of 1). + * * Return: The number of references to this folio. */ static inline int folio_ref_count(const struct folio *folio) diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h index e046278a01fa..9a6c3ea17684 100644 --- a/include/linux/pageblock-flags.h +++ b/include/linux/pageblock-flags.h @@ -36,12 +36,12 @@ enum pageblock_bits { #define NR_PAGEBLOCK_BITS (roundup_pow_of_two(__NR_PAGEBLOCK_BITS)) -#define MIGRATETYPE_MASK (BIT(PB_migrate_0)|BIT(PB_migrate_1)|BIT(PB_migrate_2)) +#define PAGEBLOCK_MIGRATETYPE_MASK (BIT(PB_migrate_0)|BIT(PB_migrate_1)|BIT(PB_migrate_2)) #ifdef CONFIG_MEMORY_ISOLATION -#define MIGRATETYPE_AND_ISO_MASK (MIGRATETYPE_MASK | BIT(PB_migrate_isolate)) +#define PAGEBLOCK_ISO_MASK BIT(PB_migrate_isolate) #else -#define MIGRATETYPE_AND_ISO_MASK MIGRATETYPE_MASK +#define PAGEBLOCK_ISO_MASK 0 #endif #if defined(CONFIG_HUGETLB_PAGE) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 31a848485ad9..1f50991b43e3 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -1350,6 +1350,7 @@ struct readahead_control { struct file_ra_state *ra; /* private: use the readahead_* accessors instead */ pgoff_t _index; + pgoff_t _max_index; /* limit readahead to _max_index, inclusive */ unsigned int _nr_pages; unsigned int _batch_count; bool dropbehind; @@ -1363,6 +1364,7 @@ struct readahead_control { .mapping = m, \ .ra = r, \ ._index = i, \ + ._max_index = ULONG_MAX, \ } #define VM_READAHEAD_PAGES (SZ_128K / PAGE_SIZE) diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h index 75c6c86cf09d..f3723b686129 100644 --- a/include/linux/pci-ats.h +++ b/include/linux/pci-ats.h @@ -12,6 +12,7 @@ int pci_prepare_ats(struct pci_dev *dev, int ps); void pci_disable_ats(struct pci_dev *dev); int pci_ats_queue_depth(struct pci_dev *dev); int pci_ats_page_aligned(struct pci_dev *dev); +bool pci_ats_required(struct pci_dev *dev); #else /* CONFIG_PCI_ATS */ static inline bool pci_ats_supported(struct pci_dev *d) { return false; } @@ -24,6 +25,8 @@ static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; } static inline int pci_ats_page_aligned(struct pci_dev *dev) { return 0; } +static inline bool pci_ats_required(struct pci_dev *dev) +{ return false; } #endif /* CONFIG_PCI_ATS */ #ifdef CONFIG_PCI_PRI diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index eca14547f9c1..2981e386da7b 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -1070,6 +1070,49 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres } #endif +#ifndef ptep_try_set +/** + * ptep_try_set - atomically set an empty kernel PTE + * @ptep: page table entry + * @new_pte: value to install + * + * Atomically set *@ptep to @new_pte iff *@ptep is pte_none(). Return true on + * success, false if the slot was already populated or the arch has no + * implementation. + * + * For special kernel page tables only - never user page tables. The caller must + * prevent concurrent teardown of @ptep and must accept that other writers may + * race. Concurrent clearers must use ptep_get_and_clear() so racing accesses + * agree on the outcome. + * + * Architectures opt in by providing a cmpxchg-based override and defining + * ptep_try_set as an identity macro. The generic stub returns false, which is + * correct for callers that fall through to oops on failure. + */ +static inline bool ptep_try_set(pte_t *ptep, pte_t new_pte) +{ + return false; +} +#endif + +#ifndef flush_tlb_before_set +/** + * flush_tlb_before_set - invalidate a kernel PTE's TLB before re-setting it + * @addr: kernel virtual address whose PTE was just cleared + * + * Some architectures (e.g. arm64) do not allow a live page-table entry to be + * repointed at a different page in one step. The old entry must first be made + * invalid and its translation flushed from every TLB, and only then may the new + * entry be written. + * + * This is only for the lockless atomic kernel-PTE installers (ptep_try_set()). + * It must be callable with interrupts disabled. + */ +static inline void flush_tlb_before_set(unsigned long addr) +{ +} +#endif + #ifndef wrprotect_ptes /** * wrprotect_ptes - Write-protect PTEs that map consecutive pages of the same diff --git a/include/linux/phy_link_topology.h b/include/linux/phy_link_topology.h index 68a59e25821c..95575f68d5bc 100644 --- a/include/linux/phy_link_topology.h +++ b/include/linux/phy_link_topology.h @@ -36,6 +36,11 @@ struct phy_device_node { struct phy_device *phy; }; +static inline bool phy_link_topo_empty(struct net_device *dev) +{ + return !dev->link_topo; +} + #if IS_ENABLED(CONFIG_PHYLIB) int phy_link_topo_add_phy(struct net_device *dev, struct phy_device *phy, diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h index 094bbe2fd6fd..77664937eeb2 100644 --- a/include/linux/pinctrl/pinmux.h +++ b/include/linux/pinctrl/pinmux.h @@ -51,6 +51,8 @@ struct pinctrl_gpio_range; * are handled by the pinmux subsystem. The @func_selector selects a * certain function whereas @group_selector selects a certain set of pins * to be used. On simple controllers the latter argument may be ignored + * @release_mux: Release software resources acquired by @set_mux. This callback + * must not change hardware state to avoid glitches when switching mux. * @gpio_request_enable: requests and enables GPIO on a certain pin. * Implement this only if you can mux every pin individually as GPIO. The * affected GPIO range is passed along with an offset(pin number) into that @@ -80,6 +82,9 @@ struct pinmux_ops { unsigned int selector); int (*set_mux) (struct pinctrl_dev *pctldev, unsigned int func_selector, unsigned int group_selector); + void (*release_mux) (struct pinctrl_dev *pctldev, + unsigned int func_selector, + unsigned int group_selector); int (*gpio_request_enable) (struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int offset); diff --git a/include/linux/platform_data/asoc-pxa.h b/include/linux/platform_data/asoc-pxa.h index 7b5b9e20fbf5..0d5eaf4b100c 100644 --- a/include/linux/platform_data/asoc-pxa.h +++ b/include/linux/platform_data/asoc-pxa.h @@ -6,27 +6,6 @@ #include <sound/pcm.h> #include <sound/ac97_codec.h> -/* - * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) - * a -1 value means no gpio will be used for reset - * @codec_pdata: AC97 codec platform_data - - * reset_gpio should only be specified for pxa27x CPUs where a silicon - * bug prevents correct operation of the reset line. If not specified, - * the default behaviour on these CPUs is to consider gpio 113 as the - * AC97 reset line, which is the default on most boards. - */ -typedef struct { - int (*startup)(struct snd_pcm_substream *, void *); - void (*shutdown)(struct snd_pcm_substream *, void *); - void (*suspend)(void *); - void (*resume)(void *); - void *priv; - int reset_gpio; - void *codec_pdata[AC97_BUS_MAX_DEVICES]; -} pxa2xx_audio_ops_t; - -extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); -extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio); +extern void pxa27x_configure_ac97reset(struct gpio_desc *reset_gpio, bool to_gpio); #endif diff --git a/include/linux/platform_data/wiznet.h b/include/linux/platform_data/wiznet.h deleted file mode 100644 index 1154c4db8a13..000000000000 --- a/include/linux/platform_data/wiznet.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Ethernet driver for the WIZnet W5x00 chip. - */ - -#ifndef PLATFORM_DATA_WIZNET_H -#define PLATFORM_DATA_WIZNET_H - -#include <linux/if_ether.h> - -struct wiznet_platform_data { - int link_gpio; - u8 mac_addr[ETH_ALEN]; -}; - -#ifndef CONFIG_WIZNET_BUS_SHIFT -#define CONFIG_WIZNET_BUS_SHIFT 0 -#endif - -#define W5100_BUS_DIRECT_SIZE (0x8000 << CONFIG_WIZNET_BUS_SHIFT) -#define W5300_BUS_DIRECT_SIZE (0x0400 << CONFIG_WIZNET_BUS_SHIFT) - -#endif /* PLATFORM_DATA_WIZNET_H */ diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index b299dc0128d6..f925614aebdb 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -467,6 +467,10 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np); int of_genpd_parse_idle_states(struct device_node *dn, struct genpd_power_state **states, int *n); void of_genpd_sync_state(struct device_node *np); +int of_genpd_add_child_ids(struct device_node *np, + struct genpd_onecell_data *data); +int of_genpd_remove_child_ids(struct device_node *np, + struct genpd_onecell_data *data); int genpd_dev_pm_attach(struct device *dev); struct device *genpd_dev_pm_attach_by_id(struct device *dev, @@ -536,6 +540,18 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np) { return ERR_PTR(-EOPNOTSUPP); } + +static inline int of_genpd_add_child_ids(struct device_node *np, + struct genpd_onecell_data *data) +{ + return -EOPNOTSUPP; +} + +static inline int of_genpd_remove_child_ids(struct device_node *np, + struct genpd_onecell_data *data) +{ + return -EOPNOTSUPP; +} #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */ #ifdef CONFIG_PM diff --git a/include/linux/power/jz4740-battery.h b/include/linux/power/jz4740-battery.h deleted file mode 100644 index 10da211678c8..000000000000 --- a/include/linux/power/jz4740-battery.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009, Jiejing Zhang <kzjeef@gmail.com> - */ - -#ifndef __JZ4740_BATTERY_H -#define __JZ4740_BATTERY_H - -struct jz_battery_platform_data { - struct power_supply_info info; - int gpio_charge; /* GPIO port of Charger state */ - int gpio_charge_active_low; -}; - -#endif diff --git a/include/linux/power/max17042_battery.h b/include/linux/power/max17042_battery.h index d5b08313cf11..13aeab1597c6 100644 --- a/include/linux/power/max17042_battery.h +++ b/include/linux/power/max17042_battery.h @@ -24,6 +24,8 @@ #define MAX17042_CHARACTERIZATION_DATA_SIZE 48 +#define MAX17055_MODELCFG_REFRESH_BIT BIT(15) + enum max17042_register { MAX17042_STATUS = 0x00, MAX17042_VALRT_Th = 0x01, @@ -198,16 +200,6 @@ enum max170xx_chip_type { MAXIM_DEVICE_TYPE_NUM }; -/* - * used for setting a register to a desired value - * addr : address for a register - * data : setting value for the register - */ -struct max17042_reg_data { - u8 addr; - u16 data; -}; - struct max17042_config_data { /* External current sense resistor value in milli-ohms */ u32 cur_sense_val; @@ -229,6 +221,7 @@ struct max17042_config_data { u16 full_soc_thresh; /* 0x13 */ u16 design_cap; /* 0x18 */ u16 ichgt_term; /* 0x1E */ + u16 model_cfg; /* 0xDB */ /* MG3 config */ u16 at_rate; /* 0x04 */ @@ -265,23 +258,4 @@ struct max17042_config_data { u16 cell_char_tbl[MAX17042_CHARACTERIZATION_DATA_SIZE]; } __packed; -struct max17042_platform_data { - struct max17042_reg_data *init_data; - struct max17042_config_data *config_data; - int num_init_data; /* Number of enties in init_data array */ - bool enable_current_sense; - bool enable_por_init; /* Use POR init from Maxim appnote */ - - /* - * R_sns in micro-ohms. - * default 10000 (if r_sns = 0) as it is the recommended value by - * the datasheet although it can be changed by board designers. - */ - unsigned int r_sns; - int vmin; /* in millivolts */ - int vmax; /* in millivolts */ - int temp_min; /* in tenths of degree Celsius */ - int temp_max; /* in tenths of degree Celsius */ -}; - #endif /* __MAX17042_BATTERY_H_ */ diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h index d5099a2baca5..ce16bbc0b308 100644 --- a/include/linux/psp-sev.h +++ b/include/linux/psp-sev.h @@ -902,6 +902,42 @@ struct snp_feature_info { /* Feature bits in EBX */ #define SNP_SEV_TIO_SUPPORTED BIT(1) +/** + * struct sev_snp_tcb_version_genoa_milan + * + * @boot_loader: SVN of PSP bootloader + * @tee: SVN of PSP operating system + * @reserved: reserved + * @snp: SVN of SNP firmware + * @microcode: Lowest current patch level of all cores + */ +struct sev_snp_tcb_version_genoa_milan { + u8 boot_loader; + u8 tee; + u8 reserved[4]; + u8 snp; + u8 microcode; +}; + +/** + * struct sev_snp_tcb_version_turin + * + * @fmc: SVN of FMC firmware + * @boot_loader: SVN of PSP bootloader + * @tee: SVN of PSP operating system + * @snp: SVN of SNP firmware + * @reserved: reserved + * @microcode: Lowest current patch level of all cores + */ +struct sev_snp_tcb_version_turin { + u8 fmc; + u8 boot_loader; + u8 tee; + u8 snp; + u8 reserved[3]; + u8 microcode; +}; + #ifdef CONFIG_CRYPTO_DEV_SP_PSP /** @@ -1048,6 +1084,7 @@ void snp_free_firmware_page(void *addr); void sev_platform_shutdown(void); bool sev_is_snp_ciphertext_hiding_supported(void); u64 sev_get_snp_policy_bits(void); +int sev_firmware_supported_vm_types(void); #else /* !CONFIG_CRYPTO_DEV_SP_PSP */ diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h index d2c3629bbe45..c95e891903f0 100644 --- a/include/linux/ptr_ring.h +++ b/include/linux/ptr_ring.h @@ -98,13 +98,29 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r) /* Note: callers invoking this in a loop must use a compiler barrier, * for example cpu_relax(). Callers must hold producer_lock. + */ +static inline int __ptr_ring_check_produce(struct ptr_ring *r) +{ + if (unlikely(!r->size)) + return -EINVAL; + + if (data_race(r->queue[r->producer])) + return -ENOSPC; + + return 0; +} + +/* Note: callers invoking this in a loop must use a compiler barrier, + * for example cpu_relax(). Callers must hold producer_lock. * Callers are responsible for making sure pointer that is being queued * points to a valid data. */ static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr) { - if (unlikely(!r->size) || data_race(r->queue[r->producer])) - return -ENOSPC; + int p = __ptr_ring_check_produce(r); + + if (p) + return p; /* Make sure the pointer we are storing points to a valid data. */ /* Pairs with the dependency ordering in __ptr_ring_consume. */ diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h index 2467b3be15c9..b3bf9339cd86 100644 --- a/include/linux/raid/pq.h +++ b/include/linux/raid/pq.h @@ -1,206 +1,24 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -/* -*- linux-c -*- ------------------------------------------------------- * +/* + * Copyright 2003 H. Peter Anvin - All Rights Reserved * - * Copyright 2003 H. Peter Anvin - All Rights Reserved - * - * ----------------------------------------------------------------------- */ - -#ifndef LINUX_RAID_RAID6_H -#define LINUX_RAID_RAID6_H - -#ifdef __KERNEL__ - -#include <linux/blkdev.h> -#include <linux/mm.h> - -/* This should be const but the raid6 code is too convoluted for that. */ -static inline void *raid6_get_zero_page(void) -{ - return page_address(ZERO_PAGE(0)); -} - -#else /* ! __KERNEL__ */ -/* Used for testing in user space */ - -#include <errno.h> -#include <inttypes.h> -#include <stddef.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/time.h> -#include <sys/types.h> - -/* Not standard, but glibc defines it */ -#define BITS_PER_LONG __WORDSIZE - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; - -#ifndef PAGE_SIZE -# define PAGE_SIZE 4096 -#endif -#ifndef PAGE_SHIFT -# define PAGE_SHIFT 12 -#endif -extern const char raid6_empty_zero_page[PAGE_SIZE]; - -#define __init -#define __exit -#ifndef __attribute_const__ -# define __attribute_const__ __attribute__((const)) -#endif -#define noinline __attribute__((noinline)) - -#define preempt_enable() -#define preempt_disable() -#define cpu_has_feature(x) 1 -#define enable_kernel_altivec() -#define disable_kernel_altivec() - -#undef EXPORT_SYMBOL -#define EXPORT_SYMBOL(sym) -#undef EXPORT_SYMBOL_GPL -#define EXPORT_SYMBOL_GPL(sym) -#define MODULE_LICENSE(licence) -#define MODULE_DESCRIPTION(desc) -#define subsys_initcall(x) -#define module_exit(x) - -#define IS_ENABLED(x) (x) -#define CONFIG_RAID6_PQ_BENCHMARK 1 -#endif /* __KERNEL__ */ - -/* Routine choices */ -struct raid6_calls { - void (*gen_syndrome)(int, size_t, void **); - void (*xor_syndrome)(int, int, int, size_t, void **); - int (*valid)(void); /* Returns 1 if this routine set is usable */ - const char *name; /* Name of this routine set */ - int priority; /* Relative priority ranking if non-zero */ -}; - -/* Selected algorithm */ -extern struct raid6_calls raid6_call; - -/* Various routine sets */ -extern const struct raid6_calls raid6_intx1; -extern const struct raid6_calls raid6_intx2; -extern const struct raid6_calls raid6_intx4; -extern const struct raid6_calls raid6_intx8; -extern const struct raid6_calls raid6_mmxx1; -extern const struct raid6_calls raid6_mmxx2; -extern const struct raid6_calls raid6_sse1x1; -extern const struct raid6_calls raid6_sse1x2; -extern const struct raid6_calls raid6_sse2x1; -extern const struct raid6_calls raid6_sse2x2; -extern const struct raid6_calls raid6_sse2x4; -extern const struct raid6_calls raid6_altivec1; -extern const struct raid6_calls raid6_altivec2; -extern const struct raid6_calls raid6_altivec4; -extern const struct raid6_calls raid6_altivec8; -extern const struct raid6_calls raid6_avx2x1; -extern const struct raid6_calls raid6_avx2x2; -extern const struct raid6_calls raid6_avx2x4; -extern const struct raid6_calls raid6_avx512x1; -extern const struct raid6_calls raid6_avx512x2; -extern const struct raid6_calls raid6_avx512x4; -extern const struct raid6_calls raid6_s390vx8; -extern const struct raid6_calls raid6_vpermxor1; -extern const struct raid6_calls raid6_vpermxor2; -extern const struct raid6_calls raid6_vpermxor4; -extern const struct raid6_calls raid6_vpermxor8; -extern const struct raid6_calls raid6_lsx; -extern const struct raid6_calls raid6_lasx; -extern const struct raid6_calls raid6_rvvx1; -extern const struct raid6_calls raid6_rvvx2; -extern const struct raid6_calls raid6_rvvx4; -extern const struct raid6_calls raid6_rvvx8; - -struct raid6_recov_calls { - void (*data2)(int, size_t, int, int, void **); - void (*datap)(int, size_t, int, void **); - int (*valid)(void); - const char *name; - int priority; -}; - -extern const struct raid6_recov_calls raid6_recov_intx1; -extern const struct raid6_recov_calls raid6_recov_ssse3; -extern const struct raid6_recov_calls raid6_recov_avx2; -extern const struct raid6_recov_calls raid6_recov_avx512; -extern const struct raid6_recov_calls raid6_recov_s390xc; -extern const struct raid6_recov_calls raid6_recov_neon; -extern const struct raid6_recov_calls raid6_recov_lsx; -extern const struct raid6_recov_calls raid6_recov_lasx; -extern const struct raid6_recov_calls raid6_recov_rvv; - -extern const struct raid6_calls raid6_neonx1; -extern const struct raid6_calls raid6_neonx2; -extern const struct raid6_calls raid6_neonx4; -extern const struct raid6_calls raid6_neonx8; - -/* Algorithm list */ -extern const struct raid6_calls * const raid6_algos[]; -extern const struct raid6_recov_calls *const raid6_recov_algos[]; -int raid6_select_algo(void); - -/* Return values from chk_syndrome */ -#define RAID6_OK 0 -#define RAID6_P_BAD 1 -#define RAID6_Q_BAD 2 -#define RAID6_PQ_BAD 3 - -/* Galois field tables */ -extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256))); -extern const u8 raid6_vgfmul[256][32] __attribute__((aligned(256))); -extern const u8 raid6_gfexp[256] __attribute__((aligned(256))); -extern const u8 raid6_gflog[256] __attribute__((aligned(256))); -extern const u8 raid6_gfinv[256] __attribute__((aligned(256))); -extern const u8 raid6_gfexi[256] __attribute__((aligned(256))); - -/* Recovery routines */ -extern void (*raid6_2data_recov)(int disks, size_t bytes, int faila, int failb, - void **ptrs); -extern void (*raid6_datap_recov)(int disks, size_t bytes, int faila, - void **ptrs); -void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, - void **ptrs); - -/* Some definitions to allow code to be compiled for testing in userspace */ -#ifndef __KERNEL__ - -# define jiffies raid6_jiffies() -# define printk printf -# define pr_err(format, ...) fprintf(stderr, format, ## __VA_ARGS__) -# define pr_info(format, ...) fprintf(stdout, format, ## __VA_ARGS__) -# define GFP_KERNEL 0 -# define __get_free_pages(x, y) ((unsigned long)mmap(NULL, PAGE_SIZE << (y), \ - PROT_READ|PROT_WRITE, \ - MAP_PRIVATE|MAP_ANONYMOUS,\ - 0, 0)) -# define free_pages(x, y) munmap((void *)(x), PAGE_SIZE << (y)) + * Public interface to the RAID6 P/Q calculation and recovery library. + */ +#ifndef LINUX_RAID_PQ_H +#define LINUX_RAID_PQ_H -static inline void cpu_relax(void) -{ - /* Nothing */ -} +#include <linux/types.h> -#undef HZ -#define HZ 1000 -static inline uint32_t raid6_jiffies(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec*1000 + tv.tv_usec/1000; -} +#define RAID6_MIN_DISKS 4 -static inline void *raid6_get_zero_page(void) -{ - return raid6_empty_zero_page; -} +void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs); +void raid6_xor_syndrome(int disks, int start, int stop, size_t bytes, + void **ptrs); +bool raid6_can_xor_syndrome(void); -#endif /* ! __KERNEL__ */ +void raid6_recov_2data(int disks, size_t bytes, int faila, int failb, + void **ptrs); +void raid6_recov_datap(int disks, size_t bytes, int faila, + void **ptrs); -#endif /* LINUX_RAID_RAID6_H */ +#endif /* LINUX_RAID_PQ_H */ diff --git a/include/linux/raid/pq_tables.h b/include/linux/raid/pq_tables.h new file mode 100644 index 000000000000..7b1ebe675677 --- /dev/null +++ b/include/linux/raid/pq_tables.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright 2003 H. Peter Anvin - All Rights Reserved + * + * Galois field tables for the Linux RAID6 P/Q parity algorithm. + */ +#ifndef _LINUX_RAID_PQ_TABLES_H +#define _LINUX_RAID_PQ_TABLES_H + +#include <linux/types.h> + +extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256))); +extern const u8 raid6_vgfmul[256][32] __attribute__((aligned(256))); +extern const u8 raid6_gfexp[256] __attribute__((aligned(256))); +extern const u8 raid6_gflog[256] __attribute__((aligned(256))); +extern const u8 raid6_gfinv[256] __attribute__((aligned(256))); +extern const u8 raid6_gfexi[256] __attribute__((aligned(256))); + +#endif /* _LINUX_RAID_PQ_TABLES_H */ diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index b4795698d8c2..7c1546d48008 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -42,274 +42,7 @@ #include <linux/completion.h> #include <linux/idr.h> #include <linux/of.h> - -/** - * struct resource_table - firmware resource table header - * @ver: version number - * @num: number of resource entries - * @reserved: reserved (must be zero) - * @offset: array of offsets pointing at the various resource entries - * - * A resource table is essentially a list of system resources required - * by the remote processor. It may also include configuration entries. - * If needed, the remote processor firmware should contain this table - * as a dedicated ".resource_table" ELF section. - * - * Some resources entries are mere announcements, where the host is informed - * of specific remoteproc configuration. Other entries require the host to - * do something (e.g. allocate a system resource). Sometimes a negotiation - * is expected, where the firmware requests a resource, and once allocated, - * the host should provide back its details (e.g. address of an allocated - * memory region). - * - * The header of the resource table, as expressed by this structure, - * contains a version number (should we need to change this format in the - * future), the number of available resource entries, and their offsets - * in the table. - * - * Immediately following this header are the resource entries themselves, - * each of which begins with a resource entry header (as described below). - */ -struct resource_table { - u32 ver; - u32 num; - u32 reserved[2]; - u32 offset[]; -} __packed; - -/** - * struct fw_rsc_hdr - firmware resource entry header - * @type: resource type - * @data: resource data - * - * Every resource entry begins with a 'struct fw_rsc_hdr' header providing - * its @type. The content of the entry itself will immediately follow - * this header, and it should be parsed according to the resource type. - */ -struct fw_rsc_hdr { - u32 type; - u8 data[]; -} __packed; - -/** - * enum fw_resource_type - types of resource entries - * - * @RSC_CARVEOUT: request for allocation of a physically contiguous - * memory region. - * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. - * @RSC_TRACE: announces the availability of a trace buffer into which - * the remote processor will be writing logs. - * @RSC_VDEV: declare support for a virtio device, and serve as its - * virtio header. - * @RSC_LAST: just keep this one at the end of standard resources - * @RSC_VENDOR_START: start of the vendor specific resource types range - * @RSC_VENDOR_END: end of the vendor specific resource types range - * - * For more details regarding a specific resource type, please see its - * dedicated structure below. - * - * Please note that these values are used as indices to the rproc_handle_rsc - * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to - * check the validity of an index before the lookup table is accessed, so - * please update it as needed. - */ -enum fw_resource_type { - RSC_CARVEOUT = 0, - RSC_DEVMEM = 1, - RSC_TRACE = 2, - RSC_VDEV = 3, - RSC_LAST = 4, - RSC_VENDOR_START = 128, - RSC_VENDOR_END = 512, -}; - -#define FW_RSC_ADDR_ANY (-1) - -/** - * struct fw_rsc_carveout - physically contiguous memory request - * @da: device address - * @pa: physical address - * @len: length (in bytes) - * @flags: iommu protection flags - * @reserved: reserved (must be zero) - * @name: human-readable name of the requested memory region - * - * This resource entry requests the host to allocate a physically contiguous - * memory region. - * - * These request entries should precede other firmware resource entries, - * as other entries might request placing other data objects inside - * these memory regions (e.g. data/code segments, trace resource entries, ...). - * - * Allocating memory this way helps utilizing the reserved physical memory - * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries - * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB - * pressure is important; it may have a substantial impact on performance. - * - * If the firmware is compiled with static addresses, then @da should specify - * the expected device address of this memory region. If @da is set to - * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then - * overwrite @da with the dynamically allocated address. - * - * We will always use @da to negotiate the device addresses, even if it - * isn't using an iommu. In that case, though, it will obviously contain - * physical addresses. - * - * Some remote processors needs to know the allocated physical address - * even if they do use an iommu. This is needed, e.g., if they control - * hardware accelerators which access the physical memory directly (this - * is the case with OMAP4 for instance). In that case, the host will - * overwrite @pa with the dynamically allocated physical address. - * Generally we don't want to expose physical addresses if we don't have to - * (remote processors are generally _not_ trusted), so we might want to - * change this to happen _only_ when explicitly required by the hardware. - * - * @flags is used to provide IOMMU protection flags, and @name should - * (optionally) contain a human readable name of this carveout region - * (mainly for debugging purposes). - */ -struct fw_rsc_carveout { - u32 da; - u32 pa; - u32 len; - u32 flags; - u32 reserved; - u8 name[32]; -} __packed; - -/** - * struct fw_rsc_devmem - iommu mapping request - * @da: device address - * @pa: physical address - * @len: length (in bytes) - * @flags: iommu protection flags - * @reserved: reserved (must be zero) - * @name: human-readable name of the requested region to be mapped - * - * This resource entry requests the host to iommu map a physically contiguous - * memory region. This is needed in case the remote processor requires - * access to certain memory-based peripherals; _never_ use it to access - * regular memory. - * - * This is obviously only needed if the remote processor is accessing memory - * via an iommu. - * - * @da should specify the required device address, @pa should specify - * the physical address we want to map, @len should specify the size of - * the mapping and @flags is the IOMMU protection flags. As always, @name may - * (optionally) contain a human readable name of this mapping (mainly for - * debugging purposes). - * - * Note: at this point we just "trust" those devmem entries to contain valid - * physical addresses, but this isn't safe and will be changed: eventually we - * want remoteproc implementations to provide us ranges of physical addresses - * the firmware is allowed to request, and not allow firmwares to request - * access to physical addresses that are outside those ranges. - */ -struct fw_rsc_devmem { - u32 da; - u32 pa; - u32 len; - u32 flags; - u32 reserved; - u8 name[32]; -} __packed; - -/** - * struct fw_rsc_trace - trace buffer declaration - * @da: device address - * @len: length (in bytes) - * @reserved: reserved (must be zero) - * @name: human-readable name of the trace buffer - * - * This resource entry provides the host information about a trace buffer - * into which the remote processor will write log messages. - * - * @da specifies the device address of the buffer, @len specifies - * its size, and @name may contain a human readable name of the trace buffer. - * - * After booting the remote processor, the trace buffers are exposed to the - * user via debugfs entries (called trace0, trace1, etc..). - */ -struct fw_rsc_trace { - u32 da; - u32 len; - u32 reserved; - u8 name[32]; -} __packed; - -/** - * struct fw_rsc_vdev_vring - vring descriptor entry - * @da: device address - * @align: the alignment between the consumer and producer parts of the vring - * @num: num of buffers supported by this vring (must be power of two) - * @notifyid: a unique rproc-wide notify index for this vring. This notify - * index is used when kicking a remote processor, to let it know that this - * vring is triggered. - * @pa: physical address - * - * This descriptor is not a resource entry by itself; it is part of the - * vdev resource type (see below). - * - * Note that @da should either contain the device address where - * the remote processor is expecting the vring, or indicate that - * dynamically allocation of the vring's device address is supported. - */ -struct fw_rsc_vdev_vring { - u32 da; - u32 align; - u32 num; - u32 notifyid; - u32 pa; -} __packed; - -/** - * struct fw_rsc_vdev - virtio device header - * @id: virtio device id (as in virtio_ids.h) - * @notifyid: a unique rproc-wide notify index for this vdev. This notify - * index is used when kicking a remote processor, to let it know that the - * status/features of this vdev have changes. - * @dfeatures: specifies the virtio device features supported by the firmware - * @gfeatures: a place holder used by the host to write back the - * negotiated features that are supported by both sides. - * @config_len: the size of the virtio config space of this vdev. The config - * space lies in the resource table immediate after this vdev header. - * @status: a place holder where the host will indicate its virtio progress. - * @num_of_vrings: indicates how many vrings are described in this vdev header - * @reserved: reserved (must be zero) - * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'. - * - * This resource is a virtio device header: it provides information about - * the vdev, and is then used by the host and its peer remote processors - * to negotiate and share certain virtio properties. - * - * By providing this resource entry, the firmware essentially asks remoteproc - * to statically allocate a vdev upon registration of the rproc (dynamic vdev - * allocation is not yet supported). - * - * Note: - * 1. unlike virtualization systems, the term 'host' here means - * the Linux side which is running remoteproc to control the remote - * processors. We use the name 'gfeatures' to comply with virtio's terms, - * though there isn't really any virtualized guest OS here: it's the host - * which is responsible for negotiating the final features. - * Yeah, it's a bit confusing. - * - * 2. immediately following this structure is the virtio config space for - * this vdev (which is specific to the vdev; for more info, read the virtio - * spec). The size of the config space is specified by @config_len. - */ -struct fw_rsc_vdev { - u32 id; - u32 notifyid; - u32 dfeatures; - u32 gfeatures; - u32 config_len; - u8 status; - u8 num_of_vrings; - u8 reserved[2]; - struct fw_rsc_vdev_vring vring[]; -} __packed; +#include <linux/rsc_table.h> struct rproc; diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index ef5230cece36..79f83b6eec27 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -263,6 +263,8 @@ struct rhash_lock_head __rcu **__rht_bucket_nested( struct rhash_lock_head __rcu **rht_bucket_nested_insert( struct rhashtable *ht, struct bucket_table *tbl, unsigned int hash); +void *rhashtable_next_key(struct rhashtable *ht, const void *prev_key); + #define rht_dereference(p, ht) \ rcu_dereference_protected(p, lockdep_rht_mutex_is_held(ht)) @@ -1117,7 +1119,7 @@ unlocked: atomic_dec(&ht->nelems); if (unlikely(ht->p.automatic_shrinking && rht_shrink_below_30(ht, tbl))) - schedule_work(&ht->run_work); + irq_work_queue(&ht->run_irq_work); err = 0; } diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 994f52b34344..0670742b2d60 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -238,6 +238,7 @@ int ring_buffer_subbuf_size_get(struct trace_buffer *buffer); enum ring_buffer_flags { RB_FL_OVERWRITE = 1 << 0, + RB_FL_TESTING = 1 << 1, }; #ifdef CONFIG_RING_BUFFER diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h new file mode 100644 index 000000000000..c6d6d553d8f1 --- /dev/null +++ b/include/linux/rsc_table.h @@ -0,0 +1,359 @@ +/* + * Resource table and its types data structure + * + * Copyright(c) 2011 Texas Instruments, Inc. + * Copyright(c) 2011 Google, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Texas Instruments nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RSC_TABLE_H +#define RSC_TABLE_H + +/** + * struct resource_table - firmware resource table header + * @ver: version number + * @num: number of resource entries + * @reserved: reserved (must be zero) + * @offset: array of offsets pointing at the various resource entries + * + * A resource table is essentially a list of system resources required + * by the remote processor. It may also include configuration entries. + * If needed, the remote processor firmware should contain this table + * as a dedicated ".resource_table" ELF section. + * + * Some resources entries are mere announcements, where the host is informed + * of specific remoteproc configuration. Other entries require the host to + * do something (e.g. allocate a system resource). Sometimes a negotiation + * is expected, where the firmware requests a resource, and once allocated, + * the host should provide back its details (e.g. address of an allocated + * memory region). + * + * The header of the resource table, as expressed by this structure, + * contains a version number (should we need to change this format in the + * future), the number of available resource entries, and their offsets + * in the table. + * + * Immediately following this header are the resource entries themselves, + * each of which begins with a resource entry header (as described below). + */ +struct resource_table { + u32 ver; + u32 num; + u32 reserved[2]; + u32 offset[]; +} __packed; + +/** + * struct fw_rsc_hdr - firmware resource entry header + * @type: resource type + * @data: resource data + * + * Every resource entry begins with a 'struct fw_rsc_hdr' header providing + * its @type. The content of the entry itself will immediately follow + * this header, and it should be parsed according to the resource type. + */ +struct fw_rsc_hdr { + u32 type; + u8 data[]; +} __packed; + +/** + * enum fw_resource_type - types of resource entries + * + * @RSC_CARVEOUT: request for allocation of a physically contiguous + * memory region. + * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. + * @RSC_TRACE: announces the availability of a trace buffer into which + * the remote processor will be writing logs. + * @RSC_VDEV: declare support for a virtio device, and serve as its + * virtio header. + * @RSC_LAST: just keep this one at the end of standard resources + * @RSC_VENDOR_START: start of the vendor specific resource types range + * @RSC_VENDOR_END: end of the vendor specific resource types range + * + * For more details regarding a specific resource type, please see its + * dedicated structure below. + * + * Please note that these values are used as indices to the rproc_handle_rsc + * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to + * check the validity of an index before the lookup table is accessed, so + * please update it as needed. + */ +enum fw_resource_type { + RSC_CARVEOUT = 0, + RSC_DEVMEM = 1, + RSC_TRACE = 2, + RSC_VDEV = 3, + RSC_LAST = 4, + RSC_VENDOR_START = 128, + RSC_VENDOR_END = 512, +}; + +#define FW_RSC_ADDR_ANY (-1) + +/** + * struct fw_rsc_carveout - physically contiguous memory request + * @da: device address + * @pa: physical address + * @len: length (in bytes) + * @flags: iommu protection flags + * @reserved: reserved (must be zero) + * @name: human-readable name of the requested memory region + * + * This resource entry requests the host to allocate a physically contiguous + * memory region. + * + * These request entries should precede other firmware resource entries, + * as other entries might request placing other data objects inside + * these memory regions (e.g. data/code segments, trace resource entries, ...). + * + * Allocating memory this way helps utilizing the reserved physical memory + * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries + * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB + * pressure is important; it may have a substantial impact on performance. + * + * If the firmware is compiled with static addresses, then @da should specify + * the expected device address of this memory region. If @da is set to + * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then + * overwrite @da with the dynamically allocated address. + * + * We will always use @da to negotiate the device addresses, even if it + * isn't using an iommu. In that case, though, it will obviously contain + * physical addresses. + * + * Some remote processors needs to know the allocated physical address + * even if they do use an iommu. This is needed, e.g., if they control + * hardware accelerators which access the physical memory directly (this + * is the case with OMAP4 for instance). In that case, the host will + * overwrite @pa with the dynamically allocated physical address. + * Generally we don't want to expose physical addresses if we don't have to + * (remote processors are generally _not_ trusted), so we might want to + * change this to happen _only_ when explicitly required by the hardware. + * + * @flags is used to provide IOMMU protection flags, and @name should + * (optionally) contain a human readable name of this carveout region + * (mainly for debugging purposes). + */ +struct fw_rsc_carveout { + u32 da; + u32 pa; + u32 len; + u32 flags; + u32 reserved; + u8 name[32]; +} __packed; + +/** + * struct fw_rsc_devmem - iommu mapping request + * @da: device address + * @pa: physical address + * @len: length (in bytes) + * @flags: iommu protection flags + * @reserved: reserved (must be zero) + * @name: human-readable name of the requested region to be mapped + * + * This resource entry requests the host to iommu map a physically contiguous + * memory region. This is needed in case the remote processor requires + * access to certain memory-based peripherals; _never_ use it to access + * regular memory. + * + * This is obviously only needed if the remote processor is accessing memory + * via an iommu. + * + * @da should specify the required device address, @pa should specify + * the physical address we want to map, @len should specify the size of + * the mapping and @flags is the IOMMU protection flags. As always, @name may + * (optionally) contain a human readable name of this mapping (mainly for + * debugging purposes). + * + * Note: at this point we just "trust" those devmem entries to contain valid + * physical addresses, but this isn't safe and will be changed: eventually we + * want remoteproc implementations to provide us ranges of physical addresses + * the firmware is allowed to request, and not allow firmwares to request + * access to physical addresses that are outside those ranges. + */ +struct fw_rsc_devmem { + u32 da; + u32 pa; + u32 len; + u32 flags; + u32 reserved; + u8 name[32]; +} __packed; + +/** + * struct fw_rsc_trace - trace buffer declaration + * @da: device address + * @len: length (in bytes) + * @reserved: reserved (must be zero) + * @name: human-readable name of the trace buffer + * + * This resource entry provides the host information about a trace buffer + * into which the remote processor will write log messages. + * + * @da specifies the device address of the buffer, @len specifies + * its size, and @name may contain a human readable name of the trace buffer. + * + * After booting the remote processor, the trace buffers are exposed to the + * user via debugfs entries (called trace0, trace1, etc..). + */ +struct fw_rsc_trace { + u32 da; + u32 len; + u32 reserved; + u8 name[32]; +} __packed; + +/** + * struct fw_rsc_vdev_vring - vring descriptor entry + * @da: device address + * @align: the alignment between the consumer and producer parts of the vring + * @num: num of buffers supported by this vring (must be power of two) + * @notifyid: a unique rproc-wide notify index for this vring. This notify + * index is used when kicking a remote processor, to let it know that this + * vring is triggered. + * @pa: physical address + * + * This descriptor is not a resource entry by itself; it is part of the + * vdev resource type (see below). + * + * Note that @da should either contain the device address where + * the remote processor is expecting the vring, or indicate that + * dynamically allocation of the vring's device address is supported. + */ +struct fw_rsc_vdev_vring { + u32 da; + u32 align; + u32 num; + u32 notifyid; + u32 pa; +} __packed; + +/** + * struct fw_rsc_vdev - virtio device header + * @id: virtio device id (as in virtio_ids.h) + * @notifyid: a unique rproc-wide notify index for this vdev. This notify + * index is used when kicking a remote processor, to let it know that the + * status/features of this vdev have changes. + * @dfeatures: specifies the virtio device features supported by the firmware + * @gfeatures: a place holder used by the host to write back the + * negotiated features that are supported by both sides. + * @config_len: the size of the virtio config space of this vdev. The config + * space lies in the resource table immediate after this vdev header. + * @status: a place holder where the host will indicate its virtio progress. + * @num_of_vrings: indicates how many vrings are described in this vdev header + * @reserved: reserved (must be zero) + * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'. + * + * This resource is a virtio device header: it provides information about + * the vdev, and is then used by the host and its peer remote processors + * to negotiate and share certain virtio properties. + * + * By providing this resource entry, the firmware essentially asks remoteproc + * to statically allocate a vdev upon registration of the rproc (dynamic vdev + * allocation is not yet supported). + * + * Note: + * 1. unlike virtualization systems, the term 'host' here means + * the Linux side which is running remoteproc to control the remote + * processors. We use the name 'gfeatures' to comply with virtio's terms, + * though there isn't really any virtualized guest OS here: it's the host + * which is responsible for negotiating the final features. + * Yeah, it's a bit confusing. + * + * 2. immediately following this structure is the virtio config space for + * this vdev (which is specific to the vdev; for more info, read the virtio + * spec). The size of the config space is specified by @config_len. + */ +struct fw_rsc_vdev { + u32 id; + u32 notifyid; + u32 dfeatures; + u32 gfeatures; + u32 config_len; + u8 status; + u8 num_of_vrings; + u8 reserved[2]; + struct fw_rsc_vdev_vring vring[]; +} __packed; + +/** + * rsc_table_for_each_entry() - iterate over all entries in a resource table + * @table: pointer to the resource table + * @table_sz: total size of the table buffer in bytes + * @dev: device used for error logging + * @cb: callback invoked for each entry: + * @type - value from enum fw_resource_type + * @rsc - pointer to the entry payload (past struct fw_rsc_hdr) + * @offset - byte offset of the payload within the table; callers + * that write back into the table (e.g. to record a + * dynamically allocated address) use this to locate the + * entry for later update + * @avail - bytes available in the payload + * @data - caller-supplied private pointer + * Return 0 to continue iteration, non-zero to stop. + * @data: private pointer forwarded to @cb on every call + * + * Iterates over every resource entry in @table, performing the standard + * truncation check, and invokes @cb for each one. Iteration stops on the + * first non-zero return from @cb or on a malformed table. + * + * Returns 0 after a complete iteration, -EINVAL if the table is truncated, + * or the first non-zero value returned by @cb. + */ +static inline int rsc_table_for_each_entry(struct resource_table *table, + size_t table_sz, + struct device *dev, + int (*cb)(u32 type, void *rsc, + int offset, int avail, + void *data), + void *data) { + int i, ret; + + for (i = 0; i < table->num; i++) { + int offset = table->offset[i]; + struct fw_rsc_hdr *hdr = (void *)table + offset; + int avail = table_sz - offset - sizeof(*hdr); + int rsc_offset = offset + sizeof(*hdr); + void *rsc = (void *)hdr + sizeof(*hdr); + + if (avail < 0) { + dev_err(dev, "rsc table is truncated\n"); + return -EINVAL; + } + + ret = cb(hdr->type, rsc, rsc_offset, avail, data); + if (ret) + return ret; + } + + return 0; +} + +#endif /* RSC_TABLE_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index b3204a15d512..373bcc0598d1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1532,6 +1532,9 @@ struct task_struct { /* KCOV descriptor wired with this task or NULL: */ struct kcov *kcov; + /* KCOV descriptor for remote coverage collection from other tasks: */ + struct kcov *kcov_remote; + /* KCOV common handle for remote coverage collection: */ u64 kcov_handle; diff --git a/include/linux/sched/ext.h b/include/linux/sched/ext.h index 2129e18ada58..20b2343aa344 100644 --- a/include/linux/sched/ext.h +++ b/include/linux/sched/ext.h @@ -207,6 +207,15 @@ struct sched_ext_entity { u64 core_sched_at; /* see scx_prio_less() */ #endif + /* + * Unique non-zero task ID assigned at fork. Persists across exec and + * is never reused. Lets BPF schedulers identify tasks without storing + * kernel pointers - arena-backed schedulers being one example. See + * scx_bpf_tid_to_task(). + */ + u64 tid; + struct rhash_head tid_hash_node; /* see SCX_OPS_TID_TO_TASK */ + /* BPF scheduler modifiable fields */ /* diff --git a/include/linux/scmi_imx_protocol.h b/include/linux/scmi_imx_protocol.h index 2407d7693b6b..ab867463c08c 100644 --- a/include/linux/scmi_imx_protocol.h +++ b/include/linux/scmi_imx_protocol.h @@ -52,6 +52,17 @@ struct scmi_imx_misc_ctrl_notify_report { unsigned int flags; }; + +#define MISC_EXT_INFO_LEN_MAX 4 +struct scmi_imx_misc_reset_reason { + bool valid:1; + bool orig_valid:1; + bool err_valid:1; + u32 reason; + u32 origin; + u32 errid; +}; + struct scmi_imx_misc_proto_ops { int (*misc_ctrl_set)(const struct scmi_protocol_handle *ph, u32 id, u32 num, u32 *val); @@ -61,6 +72,9 @@ struct scmi_imx_misc_proto_ops { u32 ctrl_id, u32 evt_id, u32 flags); int (*misc_syslog)(const struct scmi_protocol_handle *ph, u16 *size, void *array); + int (*misc_reset_reason)(const struct scmi_protocol_handle *ph, + bool system, struct scmi_imx_misc_reset_reason *boot_r, + struct scmi_imx_misc_reset_reason *shut_r, u32 *extinfo); }; /* See LMM_ATTRIBUTES in imx95.rst */ diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index aafaac1496b0..5ab73b1ab9aa 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -15,10 +15,9 @@ #define SCMI_MAX_STR_SIZE 64 #define SCMI_SHORT_NAME_MAX_SIZE 16 -#define SCMI_MAX_NUM_RATES 16 /** - * struct scmi_revision_info - version information structure + * struct scmi_base_info - version information structure * * @major_ver: Major ABI version. Change here implies risk of backward * compatibility break. @@ -31,7 +30,7 @@ * @vendor_id: A vendor identifier(Null terminated ASCII string) * @sub_vendor_id: A sub-vendor identifier(Null terminated ASCII string) */ -struct scmi_revision_info { +struct scmi_base_info { u16 major_ver; u16 minor_ver; u8 num_protocols; @@ -41,27 +40,23 @@ struct scmi_revision_info { char sub_vendor_id[SCMI_SHORT_NAME_MAX_SIZE]; }; +struct scmi_clock_rates { + bool rate_discrete; + unsigned int num_rates; + u64 *rates; +}; + struct scmi_clock_info { char name[SCMI_MAX_STR_SIZE]; unsigned int enable_latency; - bool rate_discrete; bool rate_changed_notifications; bool rate_change_requested_notifications; bool state_ctrl_forbidden; bool rate_ctrl_forbidden; bool parent_ctrl_forbidden; bool extended_config; - union { - struct { - int num_rates; - u64 rates[SCMI_MAX_NUM_RATES]; - } list; - struct { - u64 min_rate; - u64 max_rate; - u64 step_size; - } range; - }; + u64 min_rate; + u64 max_rate; int num_parents; u32 *parents; }; @@ -91,6 +86,11 @@ enum scmi_clock_oem_config { * @info_get: get the information of the specified clock * @rate_get: request the current clock rate of a clock * @rate_set: set the clock rate of a clock + * @determine_rate: determine the effective rate that can be supported by a + * clock calculating the closest allowed rate. + * Note that @rate is an input/output parameter used both to + * describe the requested rate and report the closest match + * @all_rates_get: get the list of all available rates for the specified clock. * @enable: enables the specified clock * @disable: disables the specified clock * @state_get: get the status of the specified clock @@ -108,6 +108,10 @@ struct scmi_clk_proto_ops { u64 *rate); int (*rate_set)(const struct scmi_protocol_handle *ph, u32 clk_id, u64 rate); + int (*determine_rate)(const struct scmi_protocol_handle *ph, u32 clk_id, + unsigned long *rate); + const struct scmi_clock_rates __must_check *(*all_rates_get) + (const struct scmi_protocol_handle *ph, u32 clk_id); int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id, bool atomic); int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id, @@ -901,7 +905,7 @@ struct scmi_notify_ops { */ struct scmi_handle { struct device *dev; - struct scmi_revision_info *version; + struct scmi_base_info *version; int __must_check (*devm_protocol_acquire)(struct scmi_device *sdev, u8 proto); diff --git a/include/linux/security.h b/include/linux/security.h index 41d7367cf403..153e9043058f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -459,7 +459,7 @@ int security_inode_getsecurity(struct mnt_idmap *idmap, struct inode *inode, const char *name, void **buffer, bool alloc); int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); -int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); +int security_inode_listsecurity(struct inode *inode, char **buffer, ssize_t *remaining_size); void security_inode_getlsmprop(struct inode *inode, struct lsm_prop *prop); int security_inode_copy_up(struct dentry *src, struct cred **new); int security_inode_copy_up_xattr(struct dentry *src, const char *name); @@ -1097,7 +1097,8 @@ static inline int security_inode_setsecurity(struct inode *inode, const char *na return -EOPNOTSUPP; } -static inline int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) +static inline int security_inode_listsecurity(struct inode *inode, + char **buffer, ssize_t *remaining_size) { return 0; } diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 3f06254ab1b7..22eda1d54a0e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1084,9 +1084,7 @@ struct sk_buff { __u16 network_header; __u16 mac_header; -#ifdef CONFIG_KCOV - u64 kcov_handle; -#endif + struct kcov_common_handle_id kcov_handle; ); /* end headers group */ @@ -1315,7 +1313,8 @@ static inline bool skb_data_unref(const struct sk_buff *skb, return true; } -void __fix_address sk_skb_reason_drop(struct sock *sk, struct sk_buff *skb, +void __fix_address sk_skb_reason_drop(const struct sock *sk, + struct sk_buff *skb, enum skb_drop_reason reason); static inline void @@ -5439,20 +5438,14 @@ static inline void skb_reset_csum_not_inet(struct sk_buff *skb) } static inline void skb_set_kcov_handle(struct sk_buff *skb, - const u64 kcov_handle) + struct kcov_common_handle_id kcov_handle) { -#ifdef CONFIG_KCOV skb->kcov_handle = kcov_handle; -#endif } -static inline u64 skb_get_kcov_handle(struct sk_buff *skb) +static inline struct kcov_common_handle_id skb_get_kcov_handle(struct sk_buff *skb) { -#ifdef CONFIG_KCOV return skb->kcov_handle; -#else - return 0; -#endif } static inline void skb_mark_for_recycle(struct sk_buff *skb) diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index 19f4f253b4f9..a8553401b1c9 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -4,6 +4,7 @@ #ifndef _LINUX_SKMSG_H #define _LINUX_SKMSG_H +#include <linux/bitops.h> #include <linux/bpf.h> #include <linux/filter.h> #include <linux/scatterlist.h> @@ -199,11 +200,14 @@ static inline void sk_msg_xfer(struct sk_msg *dst, struct sk_msg *src, int which, u32 size) { dst->sg.data[which] = src->sg.data[which]; + __assign_bit(which, dst->sg.copy, test_bit(which, src->sg.copy)); dst->sg.data[which].length = size; dst->sg.size += size; src->sg.size -= size; src->sg.data[which].length -= size; src->sg.data[which].offset += size; + if (!src->sg.data[which].length) + __clear_bit(which, src->sg.copy); } static inline void sk_msg_xfer_full(struct sk_msg *dst, struct sk_msg *src) @@ -273,16 +277,19 @@ static inline void sk_msg_page_add(struct sk_msg *msg, struct page *page, static inline void sk_msg_sg_copy(struct sk_msg *msg, u32 i, bool copy_state) { do { - if (copy_state) - __set_bit(i, msg->sg.copy); - else - __clear_bit(i, msg->sg.copy); + __assign_bit(i, msg->sg.copy, copy_state); sk_msg_iter_var_next(i); if (i == msg->sg.end) break; } while (1); } +static inline void sk_msg_sg_copy_assign(struct sk_msg *dst, u32 dst_i, + const struct sk_msg *src, u32 src_i) +{ + __assign_bit(dst_i, dst->sg.copy, test_bit(src_i, src->sg.copy)); +} + static inline void sk_msg_sg_copy_set(struct sk_msg *msg, u32 start) { sk_msg_sg_copy(msg, start, true); @@ -544,15 +551,6 @@ static inline void psock_progs_drop(struct sk_psock_progs *progs) psock_set_prog(&progs->skb_verdict, NULL); } -int sk_psock_tls_strp_read(struct sk_psock *psock, struct sk_buff *skb); - -static inline bool sk_psock_strp_enabled(struct sk_psock *psock) -{ - if (!psock) - return false; - return !!psock->saved_data_ready; -} - /* for tcp only, sk is locked */ static inline ssize_t sk_psock_msg_inq(struct sock *sk) { diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h index a06b5a61f337..03bb85462566 100644 --- a/include/linux/soc/mediatek/mtk-cmdq.h +++ b/include/linux/soc/mediatek/mtk-cmdq.h @@ -446,6 +446,24 @@ static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_ int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa); /** + * cmdq_pkt_jump_rel_temp() - Temporary wrapper for new CMDQ helper API + * @pkt: the CMDQ packet + * @offset: relative offset of target instruction buffer from current PC. + * @shift_pa: [DEPRECATED] shift bits of physical address in CMDQ instruction. + * This value is got by cmdq_get_shift_pa(). + * + * This function is a temporary wrapper that was introduced only for ease of + * migration of the many users of the CMDQ API located in multiple kernel + * subsystems. + * + * This has to be removed after all users are migrated to the newer CMDQ API. + */ +static inline int cmdq_pkt_jump_rel_temp(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa) +{ + return cmdq_pkt_jump_rel(pkt, offset, shift_pa); +} + +/** * cmdq_pkt_eoc() - Append EOC and ask GCE to generate an IRQ at end of execution * @pkt: The CMDQ packet * @@ -599,6 +617,12 @@ static inline int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_p return -EINVAL; } +/* This wrapper has to be removed after all users migrated to jump_rel */ +static inline int cmdq_pkt_jump_rel_temp(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa) +{ + return -EINVAL; +} + static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt) { return -EINVAL; diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h index 0a984e2579fe..c5e6ab85df09 100644 --- a/include/linux/soc/qcom/geni-se.h +++ b/include/linux/soc/qcom/geni-se.h @@ -60,18 +60,24 @@ struct geni_icc_path { * @dev: Pointer to the Serial Engine device * @wrapper: Pointer to the parent QUP Wrapper core * @clk: Handle to the core serial engine clock + * @core_clk: Auxiliary clock, which may be required by a protocol * @num_clk_levels: Number of valid clock levels in clk_perf_tbl * @clk_perf_tbl: Table of clock frequency input to serial engine clock * @icc_paths: Array of ICC paths for SE + * @pd_list: Power domain list for managing power domains + * @has_opp: Indicates if OPP is supported */ struct geni_se { void __iomem *base; struct device *dev; struct geni_wrapper *wrapper; struct clk *clk; + struct clk *core_clk; unsigned int num_clk_levels; unsigned long *clk_perf_tbl; struct geni_icc_path icc_paths[3]; + struct dev_pm_domain_list *pd_list; + bool has_opp; }; /* Common SE registers */ @@ -528,12 +534,25 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len); int geni_icc_get(struct geni_se *se, const char *icc_ddr); int geni_icc_set_bw(struct geni_se *se); +int geni_icc_set_bw_ab(struct geni_se *se, u32 core_ab, u32 cfg_ab, u32 ddr_ab); void geni_icc_set_tag(struct geni_se *se, u32 tag); int geni_icc_enable(struct geni_se *se); int geni_icc_disable(struct geni_se *se); +int geni_se_resources_init(struct geni_se *se); + +int geni_se_resources_activate(struct geni_se *se); + +int geni_se_resources_deactivate(struct geni_se *se); + int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol); + +int geni_se_domain_attach(struct geni_se *se); + +int geni_se_set_perf_level(struct geni_se *se, unsigned long level); + +int geni_se_set_perf_opp(struct geni_se *se, unsigned long clk_freq); #endif #endif diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index 227125d84318..f3ed63e475ab 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -89,18 +89,20 @@ /** * struct llcc_slice_desc - Cache slice descriptor - * @slice_id: llcc slice id - * @slice_size: Size allocated for the llcc slice + * @slice_id: LLCC slice id + * @uid: Unique ID associated with the LLCC device + * @slice_size: Size allocated for the LLCC slice * @refcount: Atomic counter to track activate/deactivate calls */ struct llcc_slice_desc { u32 slice_id; + u32 uid; size_t slice_size; refcount_t refcount; }; /** - * struct llcc_edac_reg_data - llcc edac registers data for each error type + * struct llcc_edac_reg_data - LLCC EDAC registers data for each error type * @name: Name of the error * @reg_cnt: Number of registers * @count_mask: Mask value to get the error count @@ -146,21 +148,23 @@ struct llcc_edac_reg_offset { }; /** - * struct llcc_drv_data - Data associated with the llcc driver - * @regmaps: regmaps associated with the llcc device - * @bcast_regmap: regmap associated with llcc broadcast OR offset - * @bcast_and_regmap: regmap associated with llcc broadcast AND offset + * struct llcc_drv_data - Data associated with the LLCC driver + * @dev: device back-pointer for this LLCC instance + * @regmaps: regmaps associated with the LLCC device + * @bcast_regmap: regmap associated with LLCC broadcast OR offset + * @bcast_and_regmap: regmap associated with LLCC broadcast AND offset * @cfg: pointer to the data structure for slice configuration * @edac_reg_offset: Offset of the LLCC EDAC registers * @lock: mutex associated with each slice * @cfg_size: size of the config data table - * @num_banks: Number of llcc banks - * @ecc_irq: interrupt for llcc cache error detection and reporting + * @num_banks: Number of LLCC banks + * @ecc_irq: interrupt for LLCC cache error detection and reporting * @ecc_irq_configured: 'True' if firmware has already configured the irq propagation - * @desc: Array pointer of pre-allocated LLCC slice descriptors * @version: Indicates the LLCC version + * @desc: Array pointer of pre-allocated LLCC slice descriptors */ struct llcc_drv_data { + struct device *dev; struct regmap **regmaps; struct regmap *bcast_regmap; struct regmap *bcast_and_regmap; @@ -177,38 +181,38 @@ struct llcc_drv_data { #if IS_ENABLED(CONFIG_QCOM_LLCC) /** - * llcc_slice_getd - get llcc slice descriptor + * llcc_slice_getd - get LLCC slice descriptor * @uid: usecase_id of the client */ struct llcc_slice_desc *llcc_slice_getd(u32 uid); /** - * llcc_slice_putd - llcc slice descritpor - * @desc: Pointer to llcc slice descriptor + * llcc_slice_putd - LLCC slice descriptor + * @desc: Pointer to LLCC slice descriptor */ void llcc_slice_putd(struct llcc_slice_desc *desc); /** * llcc_get_slice_id - get slice id - * @desc: Pointer to llcc slice descriptor + * @desc: Pointer to LLCC slice descriptor */ int llcc_get_slice_id(struct llcc_slice_desc *desc); /** - * llcc_get_slice_size - llcc slice size - * @desc: Pointer to llcc slice descriptor + * llcc_get_slice_size - LLCC slice size + * @desc: Pointer to LLCC slice descriptor */ size_t llcc_get_slice_size(struct llcc_slice_desc *desc); /** - * llcc_slice_activate - Activate the llcc slice - * @desc: Pointer to llcc slice descriptor + * llcc_slice_activate - Activate the LLCC slice + * @desc: Pointer to LLCC slice descriptor */ int llcc_slice_activate(struct llcc_slice_desc *desc); /** - * llcc_slice_deactivate - Deactivate the llcc slice - * @desc: Pointer to llcc slice descriptor + * llcc_slice_deactivate - Deactivate the LLCC slice + * @desc: Pointer to LLCC slice descriptor */ int llcc_slice_deactivate(struct llcc_slice_desc *desc); diff --git a/include/linux/soc/qcom/ubwc.h b/include/linux/soc/qcom/ubwc.h index f5d0e2341261..83d2c2a7116c 100644 --- a/include/linux/soc/qcom/ubwc.h +++ b/include/linux/soc/qcom/ubwc.h @@ -50,6 +50,7 @@ struct qcom_ubwc_cfg_data { #define UBWC_1_0 0x10000000 #define UBWC_2_0 0x20000000 #define UBWC_3_0 0x30000000 +#define UBWC_3_1 0x30010000 /* UBWC 3.0 + Macrotile mode */ #define UBWC_4_0 0x40000000 #define UBWC_4_3 0x40030000 #define UBWC_5_0 0x50000000 @@ -99,4 +100,25 @@ static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg) return cfg->ubwc_swizzle; } +static inline u32 qcom_ubwc_version_tag(const struct qcom_ubwc_cfg_data *cfg) +{ + if (cfg->ubwc_enc_version >= UBWC_6_0) + return 5; + if (cfg->ubwc_enc_version >= UBWC_5_0) + return 4; + if (cfg->ubwc_enc_version >= UBWC_4_3) + return 3; + if (cfg->ubwc_enc_version >= UBWC_4_0) + return 2; + if (cfg->ubwc_enc_version >= UBWC_3_0) + return 1; + + return 0; +} + +static inline bool qcom_ubwc_enable_amsbc(const struct qcom_ubwc_cfg_data *cfg) +{ + return cfg->ubwc_enc_version >= UBWC_3_0; +} + #endif /* __QCOM_UBWC_H__ */ diff --git a/include/linux/soc/ti/knav_dma.h b/include/linux/soc/ti/knav_dma.h index 18d806a8e52c..eb1e6b014eaf 100644 --- a/include/linux/soc/ti/knav_dma.h +++ b/include/linux/soc/ti/knav_dma.h @@ -75,7 +75,7 @@ enum knav_dma_desc_type { * struct knav_dma_tx_cfg: Tx channel configuration * @filt_einfo: Filter extended packet info * @filt_pswords: Filter PS words present - * @knav_dma_tx_priority: Tx channel scheduling priority + * @priority: Tx channel scheduling priority */ struct knav_dma_tx_cfg { bool filt_einfo; @@ -87,13 +87,13 @@ struct knav_dma_tx_cfg { * struct knav_dma_rx_cfg: Rx flow configuration * @einfo_present: Extended packet info present * @psinfo_present: PS words present - * @knav_dma_rx_err_mode: Error during buffer starvation - * @knav_dma_desc_type: Host or Monolithic desc + * @err_mode: Error during buffer starvation + * @desc_type: Host or Monolithic desc * @psinfo_at_sop: PS word located at start of packet * @sop_offset: Start of packet offset * @dst_q: Destination queue for a given flow * @thresh: Rx flow size threshold - * @fdq[]: Free desc Queue array + * @fdq: Free desc Queue array * @sz_thresh0: RX packet size threshold 0 * @sz_thresh1: RX packet size threshold 1 * @sz_thresh2: RX packet size threshold 2 @@ -115,7 +115,8 @@ struct knav_dma_rx_cfg { /** * struct knav_dma_cfg: Pktdma channel configuration - * @sl_cfg: Slave configuration + * @direction: DMA transfer mode and direction + * @u: union containing @tx or @rx * @tx: Tx channel configuration * @rx: Rx flow configuration */ diff --git a/include/linux/socket.h b/include/linux/socket.h index 3ffdfe184b23..2a8d7b14f1d1 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -356,7 +356,7 @@ struct ucred { /* Flags to be cleared on entry by sendmsg and sendmmsg syscalls */ #define MSG_INTERNAL_SENDMSG_FLAGS \ - (MSG_SPLICE_PAGES | MSG_SENDPAGE_NOPOLICY | MSG_SENDPAGE_DECRYPTED) + (MSG_SPLICE_PAGES | MSG_SENDPAGE_NOPOLICY | MSG_SENDPAGE_DECRYPTED | MSG_NO_SHARED_FRAGS) /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ #define SOL_IP 0 diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index 6147eb1fb210..a46cbaec5949 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -1093,6 +1093,8 @@ int sdw_slave_get_current_bank(struct sdw_slave *sdev); int sdw_slave_get_scale_index(struct sdw_slave *slave, u8 *base); +int sdw_slave_wait_for_init(struct sdw_slave *slave, int timeout_ms); + /* messaging and data APIs */ int sdw_read(struct sdw_slave *slave, u32 addr); int sdw_write(struct sdw_slave *slave, u32 addr, u8 value); @@ -1136,6 +1138,12 @@ static inline int sdw_slave_get_current_bank(struct sdw_slave *sdev) return -EINVAL; } +static inline int sdw_slave_wait_for_init(struct sdw_slave *slave, int timeout_ms) +{ + WARN_ONCE(1, "SoundWire API is disabled"); + return -EINVAL; +} + /* messaging and data APIs */ static inline int sdw_read(struct sdw_slave *slave, u32 addr) { diff --git a/include/linux/string.h b/include/linux/string.h index b850bd91b3d8..5702daca4326 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -67,9 +67,6 @@ void *vmemdup_array_user(const void __user *src, size_t n, size_t size) #ifndef __HAVE_ARCH_STRCPY extern char * strcpy(char *,const char *); #endif -#ifndef __HAVE_ARCH_STRNCPY -extern char * strncpy(char *,const char *, __kernel_size_t); -#endif ssize_t sized_strscpy(char *, const char *, size_t); /* diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index b1e595c2615b..2735c332ddb7 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h @@ -80,6 +80,9 @@ struct cache_detail { int (*cache_upcall)(struct cache_detail *, struct cache_head *); + int (*cache_notify)(struct cache_detail *cd, + struct cache_head *h); + void (*cache_request)(struct cache_detail *cd, struct cache_head *ch, char **bpp, int *blen); @@ -189,9 +192,9 @@ sunrpc_cache_update(struct cache_detail *detail, struct cache_head *new, struct cache_head *old, int hash); extern int -sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h); +sunrpc_cache_upcall(struct cache_detail *detail, struct cache_head *h); extern int -sunrpc_cache_pipe_upcall_timeout(struct cache_detail *detail, +sunrpc_cache_upcall_warn(struct cache_detail *detail, struct cache_head *h); @@ -248,6 +251,14 @@ extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *, extern void sunrpc_cache_unregister_pipefs(struct cache_detail *); extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *); +int sunrpc_cache_requests_count(struct cache_detail *cd); +int sunrpc_cache_requests_snapshot(struct cache_detail *cd, + struct cache_head **items, + u64 *seqnos, int max, + u64 min_seqno); +int sunrpc_cache_notify(struct cache_detail *cd, struct cache_head *h, + u32 cache_type); + /* Must store cache_detail in seq_file->private if using next three functions */ extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos); extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos); diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 43950b5237c8..1cd452ed1db5 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -37,13 +37,9 @@ #ifndef _LINUX_SUNRPC_GSS_KRB5_H #define _LINUX_SUNRPC_GSS_KRB5_H -#include <crypto/skcipher.h> #include <linux/sunrpc/auth_gss.h> #include <linux/sunrpc/gss_err.h> -/* Length of constant used in key derivation */ -#define GSS_KRB5_K5CLENGTH (5) - /* Maximum key length (in bytes) for the supported crypto algorithms */ #define GSS_KRB5_MAX_KEYLEN (32) @@ -56,11 +52,6 @@ /* The length of the Kerberos GSS token header */ #define GSS_KRB5_TOK_HDR_LEN (16) -#define KG_TOK_MIC_MSG 0x0101 -#define KG_TOK_WRAP_MSG 0x0201 - -#define KG2_TOK_INITIAL 0x0101 -#define KG2_TOK_RESPONSE 0x0202 #define KG2_TOK_MIC 0x0404 #define KG2_TOK_WRAP 0x0504 @@ -68,102 +59,6 @@ #define KG2_TOKEN_FLAG_SEALED 0x02 #define KG2_TOKEN_FLAG_ACCEPTORSUBKEY 0x04 -#define KG2_RESP_FLAG_ERROR 0x0001 -#define KG2_RESP_FLAG_DELEG_OK 0x0002 - -enum sgn_alg { - SGN_ALG_DES_MAC_MD5 = 0x0000, - SGN_ALG_MD2_5 = 0x0001, - SGN_ALG_DES_MAC = 0x0002, - SGN_ALG_3 = 0x0003, /* not published */ - SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004 -}; -enum seal_alg { - SEAL_ALG_NONE = 0xffff, - SEAL_ALG_DES = 0x0000, - SEAL_ALG_1 = 0x0001, /* not published */ - SEAL_ALG_DES3KD = 0x0002 -}; - -/* - * These values are assigned by IANA and published via the - * subregistry at the link below: - * - * https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-2 - */ -#define CKSUMTYPE_CRC32 0x0001 -#define CKSUMTYPE_RSA_MD4 0x0002 -#define CKSUMTYPE_RSA_MD4_DES 0x0003 -#define CKSUMTYPE_DESCBC 0x0004 -#define CKSUMTYPE_RSA_MD5 0x0007 -#define CKSUMTYPE_RSA_MD5_DES 0x0008 -#define CKSUMTYPE_NIST_SHA 0x0009 -#define CKSUMTYPE_HMAC_SHA1_DES3 0x000c -#define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f -#define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010 -#define CKSUMTYPE_CMAC_CAMELLIA128 0x0011 -#define CKSUMTYPE_CMAC_CAMELLIA256 0x0012 -#define CKSUMTYPE_HMAC_SHA256_128_AES128 0x0013 -#define CKSUMTYPE_HMAC_SHA384_192_AES256 0x0014 -#define CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /* Microsoft md5 hmac cksumtype */ - -/* from gssapi_err_krb5.h */ -#define KG_CCACHE_NOMATCH (39756032L) -#define KG_KEYTAB_NOMATCH (39756033L) -#define KG_TGT_MISSING (39756034L) -#define KG_NO_SUBKEY (39756035L) -#define KG_CONTEXT_ESTABLISHED (39756036L) -#define KG_BAD_SIGN_TYPE (39756037L) -#define KG_BAD_LENGTH (39756038L) -#define KG_CTX_INCOMPLETE (39756039L) -#define KG_CONTEXT (39756040L) -#define KG_CRED (39756041L) -#define KG_ENC_DESC (39756042L) -#define KG_BAD_SEQ (39756043L) -#define KG_EMPTY_CCACHE (39756044L) -#define KG_NO_CTYPES (39756045L) - -/* per Kerberos v5 protocol spec crypto types from the wire. - * these get mapped to linux kernel crypto routines. - * - * These values are assigned by IANA and published via the - * subregistry at the link below: - * - * https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-1 - */ -#define ENCTYPE_NULL 0x0000 -#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */ -#define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */ -#define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */ -#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */ -/* XXX deprecated? */ -#define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */ -#define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */ -#define ENCTYPE_DES_HMAC_SHA1 0x0008 -#define ENCTYPE_DES3_CBC_SHA1 0x0010 -#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011 -#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012 -#define ENCTYPE_AES128_CTS_HMAC_SHA256_128 0x0013 -#define ENCTYPE_AES256_CTS_HMAC_SHA384_192 0x0014 -#define ENCTYPE_ARCFOUR_HMAC 0x0017 -#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018 -#define ENCTYPE_CAMELLIA128_CTS_CMAC 0x0019 -#define ENCTYPE_CAMELLIA256_CTS_CMAC 0x001A -#define ENCTYPE_UNKNOWN 0x01ff - -/* - * Constants used for key derivation - */ -/* for 3DES */ -#define KG_USAGE_SEAL (22) -#define KG_USAGE_SIGN (23) -#define KG_USAGE_SEQ (24) - -/* from rfc3961 */ -#define KEY_USAGE_SEED_CHECKSUM (0x99) -#define KEY_USAGE_SEED_ENCRYPTION (0xAA) -#define KEY_USAGE_SEED_INTEGRITY (0x55) - /* from rfc4121 */ #define KG_USAGE_ACCEPTOR_SEAL (22) #define KG_USAGE_ACCEPTOR_SIGN (23) diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index df6e08aaad57..5aadb47b3b0e 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -66,7 +66,6 @@ extern unsigned int svcrdma_ord; extern unsigned int svcrdma_max_requests; extern unsigned int svcrdma_max_bc_requests; extern unsigned int svcrdma_max_req_size; -extern struct workqueue_struct *svcrdma_wq; extern struct percpu_counter svcrdma_stat_read; extern struct percpu_counter svcrdma_stat_recv; @@ -117,6 +116,8 @@ struct svcxprt_rdma { struct llist_head sc_recv_ctxts; + struct llist_head sc_send_release_list; + atomic_t sc_completion_ids; }; /* sc_flags */ @@ -230,13 +231,11 @@ struct svc_rdma_write_info { unsigned int wi_next_off; struct svc_rdma_chunk_ctxt wi_cc; - struct work_struct wi_work; }; struct svc_rdma_send_ctxt { struct llist_node sc_node; struct rpc_rdma_cid sc_cid; - struct work_struct sc_work; struct svcxprt_rdma *sc_rdma; struct ib_send_wr sc_send_wr; @@ -300,6 +299,7 @@ extern int svc_rdma_process_read_list(struct svcxprt_rdma *rdma, /* svc_rdma_sendto.c */ extern void svc_rdma_send_ctxts_destroy(struct svcxprt_rdma *rdma); +extern void svc_rdma_send_ctxts_drain(struct svcxprt_rdma *rdma); extern struct svc_rdma_send_ctxt * svc_rdma_send_ctxt_get(struct svcxprt_rdma *rdma); extern void svc_rdma_send_ctxt_put(struct svcxprt_rdma *rdma, @@ -328,6 +328,7 @@ extern int svc_rdma_result_payload(struct svc_rqst *rqstp, unsigned int offset, unsigned int length); /* svc_rdma_transport.c */ +extern void svc_rdma_xprt_deferred_close(struct svcxprt_rdma *rdma); extern struct svc_xprt_class svc_rdma_class; #ifdef CONFIG_SUNRPC_BACKCHANNEL extern struct svc_xprt_class svc_rdma_bc_class; diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index b639a6fafcbc..b102b4f21e6b 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -138,8 +138,23 @@ void xdr_terminate_string(const struct xdr_buf *, const u32); size_t xdr_buf_pagecount(const struct xdr_buf *buf); int xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp); void xdr_free_bvec(struct xdr_buf *buf); -unsigned int xdr_buf_to_bvec(struct bio_vec *bvec, unsigned int bvec_size, - const struct xdr_buf *xdr); +int xdr_buf_to_bvec(struct bio_vec *bvec, unsigned int bvec_size, + const struct xdr_buf *xdr); +int xdr_buf_to_sg(const struct xdr_buf *buf, unsigned int offset, + unsigned int len, struct scatterlist *sg, unsigned int nsg); +int xdr_buf_to_sg_alloc(const struct xdr_buf *buf, unsigned int offset, + unsigned int len, struct scatterlist *sg_head, + unsigned int sg_head_nents, + struct scatterlist **sg_overflow, gfp_t gfp); + +/* + * Inline scatterlist entries for xdr_buf_to_sg_alloc(). Sized to cover the + * head kvec, tail kvec, and a few page fragments without any heap allocation. + */ +enum { + XDR_BUF_TO_SG_NENTS = 8, +}; + static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len) { @@ -260,7 +275,6 @@ extern void xdr_finish_decode(struct xdr_stream *xdr); extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len); extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len); -extern int xdr_process_buf(const struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data); extern void xdr_set_pagelen(struct xdr_stream *, unsigned int len); extern bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf, unsigned int len); diff --git a/include/linux/sunrpc/xdrgen/nlm3.h b/include/linux/sunrpc/xdrgen/nlm3.h new file mode 100644 index 000000000000..897e7d91807c --- /dev/null +++ b/include/linux/sunrpc/xdrgen/nlm3.h @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Generated by xdrgen. Manual edits will be lost. */ +/* XDR specification file: ../../Documentation/sunrpc/xdr/nlm3.x */ +/* XDR specification modification time: Thu Apr 23 10:56:34 2026 */ + +#ifndef _LINUX_XDRGEN_NLM3_DEF_H +#define _LINUX_XDRGEN_NLM3_DEF_H + +#include <linux/types.h> +#include <linux/sunrpc/xdrgen/_defs.h> + +enum { LM_MAXSTRLEN = 1024 }; + +enum { LM_MAXNAMELEN = 1025 }; + +enum { MAXNETOBJ_SZ = 1024 }; + +typedef opaque netobj; + +enum nlm_stats { + LCK_GRANTED = 0, + LCK_DENIED = 1, + LCK_DENIED_NOLOCKS = 2, + LCK_BLOCKED = 3, + LCK_DENIED_GRACE_PERIOD = 4, +}; + +typedef __be32 nlm_stats; + +struct nlm_stat { + nlm_stats stat; +}; + +struct nlm_res { + netobj cookie; + struct nlm_stat stat; +}; + +struct nlm_holder { + bool exclusive; + s32 uppid; + netobj oh; + u32 l_offset; + u32 l_len; +}; + +struct nlm_testrply { + nlm_stats stat; + union { + struct nlm_holder holder; + } u; +}; + +struct nlm_testres { + netobj cookie; + struct nlm_testrply test_stat; +}; + +struct nlm_lock { + string caller_name; + netobj fh; + netobj oh; + s32 uppid; + u32 l_offset; + u32 l_len; +}; + +struct nlm_lockargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; + bool reclaim; + s32 state; +}; + +struct nlm_cancargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_testargs { + netobj cookie; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_unlockargs { + netobj cookie; + struct nlm_lock alock; +}; + +enum fsh_mode { + fsm_DN = 0, + fsm_DR = 1, + fsm_DW = 2, + fsm_DRW = 3, +}; + +typedef enum fsh_mode fsh_mode; + +enum fsh_access { + fsa_NONE = 0, + fsa_R = 1, + fsa_W = 2, + fsa_RW = 3, +}; + +typedef enum fsh_access fsh_access; + +struct nlm_share { + string caller_name; + netobj fh; + netobj oh; + fsh_mode mode; + fsh_access access; +}; + +struct nlm_shareargs { + netobj cookie; + struct nlm_share share; + bool reclaim; +}; + +struct nlm_shareres { + netobj cookie; + nlm_stats stat; + s32 sequence; +}; + +struct nlm_notify { + string name; + s32 state; +}; + +enum { SM_PRIV_SIZE = 16 }; + +struct nlm_notifyargs { + struct nlm_notify notify; + u8 private[SM_PRIV_SIZE]; +}; + +enum { + NLM_NULL = 0, + NLM_TEST = 1, + NLM_LOCK = 2, + NLM_CANCEL = 3, + NLM_UNLOCK = 4, + NLM_GRANTED = 5, + NLM_TEST_MSG = 6, + NLM_LOCK_MSG = 7, + NLM_CANCEL_MSG = 8, + NLM_UNLOCK_MSG = 9, + NLM_GRANTED_MSG = 10, + NLM_TEST_RES = 11, + NLM_LOCK_RES = 12, + NLM_CANCEL_RES = 13, + NLM_UNLOCK_RES = 14, + NLM_GRANTED_RES = 15, + NLM_SM_NOTIFY = 16, + NLM_SHARE = 20, + NLM_UNSHARE = 21, + NLM_NM_LOCK = 22, + NLM_FREE_ALL = 23, +}; + +#ifndef NLM_PROG +#define NLM_PROG (100021) +#endif + +#define NLM3_netobj_sz (XDR_unsigned_int + XDR_QUADLEN(MAXNETOBJ_SZ)) +#define NLM3_nlm_stats_sz (XDR_int) +#define NLM3_nlm_stat_sz \ + (NLM3_nlm_stats_sz) +#define NLM3_nlm_res_sz \ + (NLM3_netobj_sz + NLM3_nlm_stat_sz) +#define NLM3_nlm_holder_sz \ + (XDR_bool + XDR_int + NLM3_netobj_sz + XDR_unsigned_int + XDR_unsigned_int) +#define NLM3_nlm_testrply_sz \ + (NLM3_nlm_stats_sz + NLM3_nlm_holder_sz) +#define NLM3_nlm_testres_sz \ + (NLM3_netobj_sz + NLM3_nlm_testrply_sz) +#define NLM3_nlm_lock_sz \ + (XDR_unsigned_int + XDR_QUADLEN(LM_MAXSTRLEN) + NLM3_netobj_sz + NLM3_netobj_sz + XDR_int + XDR_unsigned_int + XDR_unsigned_int) +#define NLM3_nlm_lockargs_sz \ + (NLM3_netobj_sz + XDR_bool + XDR_bool + NLM3_nlm_lock_sz + XDR_bool + XDR_int) +#define NLM3_nlm_cancargs_sz \ + (NLM3_netobj_sz + XDR_bool + XDR_bool + NLM3_nlm_lock_sz) +#define NLM3_nlm_testargs_sz \ + (NLM3_netobj_sz + XDR_bool + NLM3_nlm_lock_sz) +#define NLM3_nlm_unlockargs_sz \ + (NLM3_netobj_sz + NLM3_nlm_lock_sz) +#define NLM3_fsh_mode_sz (XDR_int) +#define NLM3_fsh_access_sz (XDR_int) +#define NLM3_nlm_share_sz \ + (XDR_unsigned_int + XDR_QUADLEN(LM_MAXSTRLEN) + NLM3_netobj_sz + NLM3_netobj_sz + NLM3_fsh_mode_sz + NLM3_fsh_access_sz) +#define NLM3_nlm_shareargs_sz \ + (NLM3_netobj_sz + NLM3_nlm_share_sz + XDR_bool) +#define NLM3_nlm_shareres_sz \ + (NLM3_netobj_sz + NLM3_nlm_stats_sz + XDR_int) +#define NLM3_nlm_notify_sz \ + (XDR_unsigned_int + XDR_QUADLEN(LM_MAXNAMELEN) + XDR_long) +#define NLM3_nlm_notifyargs_sz \ + (NLM3_nlm_notify_sz + XDR_QUADLEN(SM_PRIV_SIZE)) +#define NLM3_MAX_ARGS_SZ \ + (NLM3_nlm_lockargs_sz) + +#endif /* _LINUX_XDRGEN_NLM3_DEF_H */ diff --git a/include/linux/swap.h b/include/linux/swap.h index 7a09df6977a5..8f0f68e245ba 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -213,6 +213,7 @@ enum { SWP_PAGE_DISCARD = (1 << 10), /* freed swap page-cluster discards */ SWP_STABLE_WRITES = (1 << 11), /* no overwrite PG_writeback pages */ SWP_SYNCHRONOUS_IO = (1 << 12), /* synchronous IO is efficient */ + SWP_HIBERNATION = (1 << 13), /* pinned for hibernation */ /* add others here before... */ }; @@ -252,7 +253,6 @@ struct swap_info_struct { struct plist_node list; /* entry in swap_active_head */ signed char type; /* strange name for an index */ unsigned int max; /* size of this swap device */ - unsigned long *zeromap; /* kvmalloc'ed bitmap to track zero pages */ struct swap_cluster_info *cluster_info; /* cluster info. Only for SSD */ struct list_head free_clusters; /* free clusters list */ struct list_head full_clusters; /* full clusters list */ @@ -433,7 +433,9 @@ static inline long get_nr_swap_pages(void) } extern void si_swapinfo(struct sysinfo *); -int swap_type_of(dev_t device, sector_t offset); +extern int pin_hibernation_swap_type(dev_t device, sector_t offset); +extern void unpin_hibernation_swap_type(int type); +extern int find_hibernation_swap_type(dev_t device, sector_t offset); int find_first_swap(dev_t *device); extern unsigned int count_swap_pages(int, int); extern sector_t swapdev_block(int, pgoff_t); @@ -571,33 +573,31 @@ static inline void folio_throttle_swaprate(struct folio *folio, gfp_t gfp) #endif #if defined(CONFIG_MEMCG) && defined(CONFIG_SWAP) -int __mem_cgroup_try_charge_swap(struct folio *folio, swp_entry_t entry); -static inline int mem_cgroup_try_charge_swap(struct folio *folio, - swp_entry_t entry) +int __mem_cgroup_try_charge_swap(struct folio *folio); +static inline int mem_cgroup_try_charge_swap(struct folio *folio) { if (mem_cgroup_disabled()) return 0; - return __mem_cgroup_try_charge_swap(folio, entry); + return __mem_cgroup_try_charge_swap(folio); } -extern void __mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages); -static inline void mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages) +extern void __mem_cgroup_uncharge_swap(unsigned short id, unsigned int nr_pages); +static inline void mem_cgroup_uncharge_swap(unsigned short id, unsigned int nr_pages) { if (mem_cgroup_disabled()) return; - __mem_cgroup_uncharge_swap(entry, nr_pages); + __mem_cgroup_uncharge_swap(id, nr_pages); } extern long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg); extern bool mem_cgroup_swap_full(struct folio *folio); #else -static inline int mem_cgroup_try_charge_swap(struct folio *folio, - swp_entry_t entry) +static inline int mem_cgroup_try_charge_swap(struct folio *folio) { return 0; } -static inline void mem_cgroup_uncharge_swap(swp_entry_t entry, +static inline void mem_cgroup_uncharge_swap(unsigned short id, unsigned int nr_pages) { } diff --git a/include/linux/swap_cgroup.h b/include/linux/swap_cgroup.h deleted file mode 100644 index 91cdf12190a0..000000000000 --- a/include/linux/swap_cgroup.h +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __LINUX_SWAP_CGROUP_H -#define __LINUX_SWAP_CGROUP_H - -#include <linux/swap.h> - -#if defined(CONFIG_MEMCG) && defined(CONFIG_SWAP) - -extern void swap_cgroup_record(struct folio *folio, unsigned short id, swp_entry_t ent); -extern unsigned short swap_cgroup_clear(swp_entry_t ent, unsigned int nr_ents); -extern unsigned short lookup_swap_cgroup_id(swp_entry_t ent); -extern int swap_cgroup_swapon(int type, unsigned long max_pages); -extern void swap_cgroup_swapoff(int type); - -#else - -static inline -void swap_cgroup_record(struct folio *folio, unsigned short id, swp_entry_t ent) -{ -} - -static inline -unsigned short swap_cgroup_clear(swp_entry_t ent, unsigned int nr_ents) -{ - return 0; -} - -static inline -unsigned short lookup_swap_cgroup_id(swp_entry_t ent) -{ - return 0; -} - -static inline int -swap_cgroup_swapon(int type, unsigned long max_pages) -{ - return 0; -} - -static inline void swap_cgroup_swapoff(int type) -{ - return; -} - -#endif - -#endif /* __LINUX_SWAP_CGROUP_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 4fb7291f54b6..874d9067a43b 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -940,7 +940,8 @@ asmlinkage long sys_seccomp(unsigned int op, unsigned int flags, asmlinkage long sys_getrandom(char __user *buf, size_t count, unsigned int flags); asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned int flags); -asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size); +asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int size, + struct bpf_common_attr __user *attr_common, unsigned int size_common); asmlinkage long sys_execveat(int dfd, const char __user *filename, const char __user *const __user *argv, const char __user *const __user *envp, int flags); diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 6982f10e826b..8a6807082672 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -253,15 +253,20 @@ struct tcp_sock { /* TX read-write hotpath cache lines */ __cacheline_group_begin(tcp_sock_write_tx) ____cacheline_aligned; - u32 segs_out; /* RFC4898 tcpEStatsPerfSegsOut - * The total number of segments sent. - */ - u32 data_segs_out; /* RFC4898 tcpEStatsPerfDataSegsOut - * total number of data segments sent. + u32 delivered; /* Total data packets delivered incl. rexmits */ + u32 delivered_ce; /* Like the above but only ECE marked packets */ + u64 bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked + * sum(delta(snd_una)), or how many bytes + * were acked. */ u64 bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut * total number of data bytes sent. */ + u64 first_tx_mstamp; /* start of window send phase */ + u64 delivered_mstamp; /* time we reached "delivered" */ + u32 data_segs_out; /* RFC4898 tcpEStatsPerfDataSegsOut + * total number of data segments sent. + */ u32 snd_sml; /* Last byte of the most recently transmitted small packet */ u8 chrono_type; /* current chronograph type */ u32 chrono_start; /* Start time in jiffies of a TCP chrono */ @@ -271,6 +276,10 @@ struct tcp_sock { u32 lsndtime; /* timestamp of last sent data packet (for restart window) */ u32 mdev_us; /* medium deviation */ u32 rtt_seq; /* sequence number to update rttvar */ + u32 max_packets_out; /* max packets_out in last window */ + u32 cwnd_usage_seq; /* right edge of cwnd usage tracking flight */ + u32 rate_delivered; /* saved rate sample: packets delivered */ + u32 rate_interval_us; /* saved rate sample: time elapsed */ u64 tcp_wstamp_ns; /* departure time for next sent data packet */ u64 accecn_opt_tstamp; /* Last AccECN option sent timestamp */ struct list_head tsorted_sent_queue; /* time-sorted sent but un-SACKed skbs */ @@ -307,8 +316,6 @@ struct tcp_sock { u32 srtt_us; /* smoothed round trip time << 3 in usecs */ u32 packets_out; /* Packets which are "in flight" */ u32 snd_up; /* Urgent pointer */ - u32 delivered; /* Total data packets delivered incl. rexmits */ - u32 delivered_ce; /* Like the above but only ECE marked packets */ u32 received_ce; /* Like the above but for rcvd CE marked pkts */ u32 received_ecn_bytes[3]; /* received byte counters for three ECN * types: INET_ECN_ECT_1, INET_ECN_ECT_0, @@ -324,6 +331,12 @@ struct tcp_sock { * Options received (usually on last packet, some only on SYN packets). */ struct tcp_options_received rx_opt; + u32 segs_in; /* RFC4898 tcpEStatsPerfSegsIn + * total number of segments in. + */ + u32 segs_out; /* RFC4898 tcpEStatsPerfSegsOut + * The total number of segments sent. + */ __cacheline_group_end(tcp_sock_write_txrx); /* RX read-write hotpath cache lines */ @@ -333,26 +346,13 @@ struct tcp_sock { * sum(delta(rcv_nxt)), or how many bytes * were acked. */ - u32 segs_in; /* RFC4898 tcpEStatsPerfSegsIn - * total number of segments in. - */ u32 data_segs_in; /* RFC4898 tcpEStatsPerfDataSegsIn * total number of data segments in. */ u32 rcv_wup; /* rcv_nxt on last window update sent */ - u32 max_packets_out; /* max packets_out in last window */ - u32 cwnd_usage_seq; /* right edge of cwnd usage tracking flight */ - u32 rate_delivered; /* saved rate sample: packets delivered */ - u32 rate_interval_us; /* saved rate sample: time elapsed */ u32 rcv_rtt_last_tsecr; u32 delivered_ecn_bytes[3]; u16 pkts_acked_ewma;/* Pkts acked EWMA for AccECN cep heuristic */ - u64 first_tx_mstamp; /* start of window send phase */ - u64 delivered_mstamp; /* time we reached "delivered" */ - u64 bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked - * sum(delta(snd_una)), or how many bytes - * were acked. - */ struct { u32 rtt_us; u32 seq; diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 051e42902690..307b8390fc67 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -92,7 +92,7 @@ static inline long set_restart_fn(struct restart_block *restart, #define THREAD_ALIGN THREAD_SIZE #endif -#define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO) +#define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO | __GFP_SKIP_KASAN) /* * flag set/clear/test wrappers diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 40a43a4c7caf..308c76b57d13 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -770,6 +770,7 @@ trace_trigger_soft_disabled(struct trace_event_file *file) #ifdef CONFIG_BPF_EVENTS unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx); +unsigned int trace_call_bpf_faultable(struct trace_event_call *call, void *ctx); int perf_event_attach_bpf_prog(struct perf_event *event, struct bpf_prog *prog, u64 bpf_cookie); void perf_event_detach_bpf_prog(struct perf_event *event); int perf_event_query_prog_array(struct perf_event *event, void __user *info); @@ -786,12 +787,18 @@ int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, unsigned long *missed); int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); +int bpf_tracing_multi_attach(struct bpf_prog *prog, const union bpf_attr *attr); #else static inline unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx) { return 1; } +static inline unsigned int trace_call_bpf_faultable(struct trace_event_call *call, void *ctx) +{ + return 1; +} + static inline int perf_event_attach_bpf_prog(struct perf_event *event, struct bpf_prog *prog, u64 bpf_cookie) { @@ -838,6 +845,11 @@ bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) { return -EOPNOTSUPP; } +static inline int +bpf_tracing_multi_attach(struct bpf_prog *prog, const union bpf_attr *attr) +{ + return -EOPNOTSUPP; +} #endif enum { diff --git a/include/linux/trace_printk.h b/include/linux/trace_printk.h index 2670ec7f4262..3d54f440dccf 100644 --- a/include/linux/trace_printk.h +++ b/include/linux/trace_printk.h @@ -86,8 +86,7 @@ do { \ #define trace_printk(fmt, ...) \ do { \ - char _______STR[] = __stringify((__VA_ARGS__)); \ - if (sizeof(_______STR) > 3) \ + if (sizeof __stringify((__VA_ARGS__)) > 3) \ do_trace_printk(fmt, ##__VA_ARGS__); \ else \ trace_puts(fmt); \ diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h index d03f74658716..bc354d340046 100644 --- a/include/linux/tracefs.h +++ b/include/linux/tracefs.h @@ -30,7 +30,7 @@ struct eventfs_file; * @data: data to pass to the created file ops * @fops: the file operations of the created file * - * The evetnfs files are dynamically created. The struct eventfs_entry array + * The eventfs files are dynamically created. The struct eventfs_entry array * is passed to eventfs_create_dir() or eventfs_create_events_dir() that will * be used to create the files within those directories. When a lookup * or access to a file within the directory is made, the struct eventfs_entry diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 2d2b9f8cdda4..4a0c36f40fe2 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -294,6 +294,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) static inline bool \ trace_##name##_enabled(void) \ { \ + if (IS_ENABLED(CONFIG_LOCKDEP)) { \ + WARN_ONCE(!rcu_is_watching(), \ + "RCU not watching for tracepoint"); \ + } \ return static_branch_unlikely(&__tracepoint_##name.key);\ } diff --git a/include/linux/types.h b/include/linux/types.h index 608050dbca6a..93166b0b0617 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -224,6 +224,12 @@ struct ustat { char f_fpack[6]; }; +struct kcov_common_handle_id { +#ifdef CONFIG_KCOV + u64 val; +#endif +}; + /** * struct callback_head - callback structure for use with RCU and task_work * @next: next update requests in a list diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 8a264662b242..eddbbb65ccc4 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -84,7 +84,7 @@ * the 6 functions (copy_{to,from}_user(), __copy_{to,from}_user_inatomic()) * that are used instead. Out of those, __... ones are inlined. Plain * copy_{to,from}_user() might or might not be inlined. If you want them - * inlined, have asm/uaccess.h define INLINE_COPY_{TO,FROM}_USER. + * inlined, have asm/uaccess.h define INLINE_COPY_USER. * * NOTE: only copy_from_user() zero-pads the destination in case of short copy. * Neither __copy_from_user() nor __copy_from_user_inatomic() zero anything @@ -157,7 +157,7 @@ __copy_to_user(void __user *to, const void *from, unsigned long n) } /* - * Architectures that #define INLINE_COPY_TO_USER use this function + * Architectures that #define INLINE_COPY_USER use this function * directly in the normal copy_to/from_user(), the other ones go * through an extern _copy_to/from_user(), which expands the same code * here. @@ -190,10 +190,6 @@ fail: memset(to + (n - res), 0, res); return res; } -#ifndef INLINE_COPY_FROM_USER -extern __must_check unsigned long -_copy_from_user(void *, const void __user *, unsigned long); -#endif static inline __must_check unsigned long _inline_copy_to_user(void __user *to, const void *from, unsigned long n) @@ -207,7 +203,13 @@ _inline_copy_to_user(void __user *to, const void *from, unsigned long n) } return n; } -#ifndef INLINE_COPY_TO_USER +#ifdef INLINE_COPY_USER +# define _copy_to_user _inline_copy_to_user +# define _copy_from_user _inline_copy_from_user +#else +extern __must_check unsigned long +_copy_from_user(void *, const void __user *, unsigned long); + extern __must_check unsigned long _copy_to_user(void __user *, const void *, unsigned long); #endif @@ -217,11 +219,7 @@ copy_from_user(void *to, const void __user *from, unsigned long n) { if (!check_copy_size(to, n, false)) return n; -#ifdef INLINE_COPY_FROM_USER - return _inline_copy_from_user(to, from, n); -#else return _copy_from_user(to, from, n); -#endif } static __always_inline unsigned long __must_check @@ -229,12 +227,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n) { if (!check_copy_size(from, n, true)) return n; - -#ifdef INLINE_COPY_TO_USER - return _inline_copy_to_user(to, from, n); -#else return _copy_to_user(to, from, n); -#endif } #ifndef copy_mc_to_kernel diff --git a/include/linux/usb/uvc.h b/include/linux/usb/uvc.h index 05bfebab42b6..99b070ab860f 100644 --- a/include/linux/usb/uvc.h +++ b/include/linux/usb/uvc.h @@ -43,6 +43,16 @@ #define UVC_GUID_MSXU_1_5 \ {0xdc, 0x95, 0x3f, 0x0f, 0x32, 0x26, 0x4e, 0x4c, \ 0x92, 0xc9, 0xa0, 0x47, 0x82, 0xf4, 0x3b, 0xc8} +#define UVC_GUID_LOGITECH_MOTOR_CONTROL_V1 \ + {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ + 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56 } +#define UVC_GUID_LOGITECH_PERIPHERAL \ + {0x21, 0x2d, 0xe5, 0xff, 0x30, 0x80, 0x2c, 0x4e, \ + 0x82, 0xd9, 0xf5, 0x87, 0xd0, 0x05, 0x40, 0xbd } +#define UVC_GUID_LOGITECH_USER_HW_CONTROL_V1 \ + {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ + 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1f } + /* https://learn.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-extensions-1-5#222-extension-unit-controls */ #define UVC_MSXU_CONTROL_FOCUS 0x01 diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h index d2920f98ab86..68edac4dcd78 100644 --- a/include/linux/userfaultfd_k.h +++ b/include/linux/userfaultfd_k.h @@ -23,8 +23,8 @@ /* The set of all possible UFFD-related VM flags. */ #define __VM_UFFD_FLAGS (VM_UFFD_MISSING | VM_UFFD_WP | VM_UFFD_MINOR) -#define __VMA_UFFD_FLAGS mk_vma_flags(VMA_UFFD_MISSING_BIT, VMA_UFFD_WP_BIT, \ - VMA_UFFD_MINOR_BIT) +#define __VMA_UFFD_FLAGS mk_vma_flags_from_masks(VMA_UFFD_MISSING, VMA_UFFD_WP, \ + VMA_UFFD_MINOR) /* * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining @@ -147,26 +147,12 @@ static inline uffd_flags_t uffd_flags_set_mode(uffd_flags_t flags, enum mfill_at /* Flags controlling behavior. These behavior changes are mode-independent. */ #define MFILL_ATOMIC_WP MFILL_ATOMIC_FLAG(0) -extern ssize_t mfill_atomic_copy(struct userfaultfd_ctx *ctx, unsigned long dst_start, - unsigned long src_start, unsigned long len, - uffd_flags_t flags); -extern ssize_t mfill_atomic_zeropage(struct userfaultfd_ctx *ctx, - unsigned long dst_start, - unsigned long len); -extern ssize_t mfill_atomic_continue(struct userfaultfd_ctx *ctx, unsigned long dst_start, - unsigned long len, uffd_flags_t flags); -extern ssize_t mfill_atomic_poison(struct userfaultfd_ctx *ctx, unsigned long start, - unsigned long len, uffd_flags_t flags); -extern int mwriteprotect_range(struct userfaultfd_ctx *ctx, unsigned long start, - unsigned long len, bool enable_wp); extern long uffd_wp_range(struct vm_area_struct *vma, unsigned long start, unsigned long len, bool enable_wp); /* move_pages */ void double_pt_lock(spinlock_t *ptl1, spinlock_t *ptl2); void double_pt_unlock(spinlock_t *ptl1, spinlock_t *ptl2); -ssize_t move_pages(struct userfaultfd_ctx *ctx, unsigned long dst_start, - unsigned long src_start, unsigned long len, __u64 flags); int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pmd_t dst_pmdval, struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, @@ -239,9 +225,6 @@ static inline bool userfaultfd_armed(struct vm_area_struct *vma) return vma->vm_flags & __VM_UFFD_FLAGS; } -bool vma_can_userfault(struct vm_area_struct *vma, vm_flags_t vm_flags, - bool wp_async); - static inline bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma) { struct userfaultfd_ctx *uffd_ctx = vma->vm_userfaultfd_ctx.ctx; @@ -271,25 +254,6 @@ extern void userfaultfd_unmap_complete(struct mm_struct *mm, extern bool userfaultfd_wp_unpopulated(struct vm_area_struct *vma); extern bool userfaultfd_wp_async(struct vm_area_struct *vma); -void userfaultfd_reset_ctx(struct vm_area_struct *vma); - -struct vm_area_struct *userfaultfd_clear_vma(struct vma_iterator *vmi, - struct vm_area_struct *prev, - struct vm_area_struct *vma, - unsigned long start, - unsigned long end); - -int userfaultfd_register_range(struct userfaultfd_ctx *ctx, - struct vm_area_struct *vma, - vm_flags_t vm_flags, - unsigned long start, unsigned long end, - bool wp_async); - -void userfaultfd_release_new(struct userfaultfd_ctx *ctx); - -void userfaultfd_release_all(struct mm_struct *mm, - struct userfaultfd_ctx *ctx); - static inline bool userfaultfd_wp_use_markers(struct vm_area_struct *vma) { /* Only wr-protect mode uses pte markers */ diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index 89165b769e5c..5fc6ce4dd786 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -127,6 +127,7 @@ struct vfio_pci_core_device { bool needs_pm_restore:1; bool pm_intx_masked:1; bool pm_runtime_engaged:1; + bool sriov_active; struct pci_saved_state *pci_saved_state; struct pci_saved_state *pm_save; int ioeventfds_nr; @@ -188,7 +189,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); -int vfio_pci_core_setup_barmap(struct vfio_pci_core_device *vdev, int bar); 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, @@ -234,6 +234,25 @@ static inline bool is_aligned_for_order(struct vm_area_struct *vma, !IS_ALIGNED(pfn, 1 << order))); } +/* + * Returns a BAR's iomap base or an ERR_PTR() if, for example, the + * BAR isn't valid, its resource wasn't acquired, or its iomap + * failed. This shall only be used after vfio_pci_core_enable() + * has set up the BAR maps and before vfio_pci_core_disable() + * tears them down. + */ +static inline void __iomem __must_check * +vfio_pci_core_get_iomap(struct vfio_pci_core_device *vdev, unsigned int bar) +{ + if (WARN_ON_ONCE(bar >= PCI_STD_NUM_BARS)) + return IOMEM_ERR_PTR(-EINVAL); + + if (WARN_ON_ONCE(!vdev->barmap[bar])) + return IOMEM_ERR_PTR(-ENODEV); + + return vdev->barmap[bar]; +} + int vfio_pci_dma_buf_iommufd_map(struct dma_buf_attachment *attachment, struct phys_vec *phys); diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 3bbc4cb6a672..bf089e51970e 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -157,11 +157,13 @@ struct virtio_admin_cmd { * @id: the device type identification (used to match it with a driver). * @config: the configuration ops for this device. * @vringh_config: configuration ops for host vrings. + * @map: the map operations for mapping virtio device memory. * @vqs: the list of virtqueues for this device. * @features: the 64 lower features supported by both driver and device. * @features_array: the full features space supported by both driver and * device. * @priv: private pointer for the driver's use. + * @vmap: the map container with transport- or device-specific metadata. * @debugfs_dir: debugfs directory entry. * @debugfs_filter_features: features to be filtered set by debugfs. */ diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 3b02c0c6b371..d87dc7f77f4e 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -265,7 +265,9 @@ static inline bool is_vm_area_hugepages(const void *addr) * allocated in the vmalloc layer. */ #ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC - return find_vm_area(addr)->page_order > 0; + struct vm_struct *area = find_vm_area(addr); + + return area && area->page_order > 0; #else return false; #endif diff --git a/include/linux/vmpressure.h b/include/linux/vmpressure.h index 6a2f51ebbfd3..faecd5522401 100644 --- a/include/linux/vmpressure.h +++ b/include/linux/vmpressure.h @@ -30,8 +30,8 @@ struct vmpressure { struct mem_cgroup; #ifdef CONFIG_MEMCG -extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, - unsigned long scanned, unsigned long reclaimed); +void vmpressure(gfp_t gfp, int order, struct mem_cgroup *memcg, bool tree, + unsigned long scanned, unsigned long reclaimed); extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio); extern void vmpressure_init(struct vmpressure *vmpr); @@ -44,8 +44,9 @@ extern int vmpressure_register_event(struct mem_cgroup *memcg, extern void vmpressure_unregister_event(struct mem_cgroup *memcg, struct eventfd_ctx *eventfd); #else -static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, - unsigned long scanned, unsigned long reclaimed) {} +static inline void vmpressure(gfp_t gfp, int order, struct mem_cgroup *memcg, + bool tree, unsigned long scanned, + unsigned long reclaimed) {} static inline void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio) {} #endif /* CONFIG_MEMCG */ diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 6177624539b3..a283766a192a 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -409,6 +409,7 @@ enum wq_flags { __WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */ __WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */ __WQ_LEGACY = 1 << 18, /* internal: create*_workqueue() */ + __WQ_DEPRECATED = 1 << 19, /* internal: workqueue is deprecated */ /* BH wq only allows the following flags */ __WQ_BH_ALLOWS = WQ_BH | WQ_HIGHPRI | WQ_PERCPU, |
