diff options
Diffstat (limited to 'include/linux')
484 files changed, 12650 insertions, 4409 deletions
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 10d6c6c11bdf..ddacac812094 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -13,7 +13,7 @@ #include <linux/ioport.h> /* for struct resource */ #include <linux/resource_ext.h> #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/acpi.h> #include <linux/property.h> #include <linux/uuid.h> #include <linux/node.h> @@ -94,6 +94,12 @@ static inline void acpi_preset_companion(struct device *dev, ACPI_COMPANION_SET(dev, acpi_find_child_device(parent, addr, false)); } +static inline void acpi_device_clear_deps(struct device *dev) +{ + if (has_acpi_companion(dev)) + acpi_dev_clear_dependencies(ACPI_COMPANION(dev)); +} + static inline const char *acpi_dev_name(struct acpi_device *adev) { return dev_name(&adev->dev); @@ -315,6 +321,19 @@ static inline int acpi_processor_evaluate_cst(acpi_handle handle, u32 cpu, } #endif +#ifdef CONFIG_ACPI_PROCESSOR_IDLE +int acpi_processor_extract_lpi_info(acpi_handle pr_handle, + struct acpi_processor_power *pr_power, + bool strict); +#else +static inline int acpi_processor_extract_lpi_info(acpi_handle pr_handle, + struct acpi_processor_power *pr_power, + bool strict) +{ + return -ENODEV; +} +#endif + #ifdef CONFIG_ACPI_HOTPLUG_CPU /* Arch dependent functions for cpu hotplug support */ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id, @@ -360,9 +379,10 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi); typedef struct fwnode_handle *(*acpi_gsi_domain_disp_fn)(u32); +typedef acpi_handle (*acpi_gsi_handle_disp_fn)(u32); void acpi_set_irq_model(enum acpi_irq_model_id model, - acpi_gsi_domain_disp_fn fn); + acpi_gsi_domain_disp_fn fn, acpi_gsi_handle_disp_fn gsi_dep_fn); acpi_gsi_domain_disp_fn acpi_get_gsi_dispatcher(void); void acpi_set_gsi_to_irq_fallback(u32 (*)(u32)); @@ -372,6 +392,8 @@ struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags, const struct irq_domain_ops *ops, void *host_data); +u32 acpi_irq_add_auto_dep(acpi_handle handle); + #ifdef CONFIG_X86_IO_APIC extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity); #else @@ -448,6 +470,7 @@ extern char *wmi_get_acpi_device_uid(const char *guid); #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800 extern char acpi_video_backlight_string[]; +extern bool acpi_dev_is_video_device(struct acpi_device *adev); extern long acpi_is_video_device(acpi_handle handle); extern void acpi_osi_setup(char *str); @@ -908,6 +931,8 @@ static inline void acpi_preset_companion(struct device *dev, { } +static inline void acpi_device_clear_deps(struct device *dev) {} + static inline const char *acpi_dev_name(struct acpi_device *adev) { return NULL; diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h index 17bb3374f4ca..931eaa7bbf6a 100644 --- a/include/linux/acpi_iort.h +++ b/include/linux/acpi_iort.h @@ -27,7 +27,8 @@ int iort_register_domain_token(int trans_id, phys_addr_t base, struct fwnode_handle *fw_node); void iort_deregister_domain_token(int trans_id); struct fwnode_handle *iort_find_domain_token(int trans_id); -struct fwnode_handle *iort_iwb_handle(u32 iwb_id); +acpi_handle iort_iwb_handle(u32 iwb_id); +struct fwnode_handle *iort_iwb_handle_fwnode(u32 iwb_id); #ifdef CONFIG_ACPI_IORT u32 iort_msi_map_id(struct device *dev, u32 id); diff --git a/include/linux/acpi_pmtmr.h b/include/linux/acpi_pmtmr.h index 0ded9220d379..cceed294d0b5 100644 --- a/include/linux/acpi_pmtmr.h +++ b/include/linux/acpi_pmtmr.h @@ -27,15 +27,17 @@ static inline u32 acpi_pm_read_early(void) } /** - * Register callback for suspend and resume event + * acpi_pmtmr_register_suspend_resume_callback - Register callback for + * suspend and resume event * - * @cb Callback triggered on suspend and resume - * @data Data passed with the callback + * @cb: Callback triggered on suspend and resume + * @data: Data passed with the callback */ void acpi_pmtmr_register_suspend_resume_callback(void (*cb)(void *data, bool suspend), void *data); /** - * Remove registered callback for suspend and resume event + * acpi_pmtmr_unregister_suspend_resume_callback - Remove registered callback + * for suspend and resume event */ void acpi_pmtmr_unregister_suspend_resume_callback(void); diff --git a/include/linux/alloc_tag.h b/include/linux/alloc_tag.h index 068ba2e77c5d..7f2d80a59792 100644 --- a/include/linux/alloc_tag.h +++ b/include/linux/alloc_tag.h @@ -134,6 +134,8 @@ static inline bool mem_alloc_profiling_enabled(void) &mem_alloc_profiling_key); } +bool mem_alloc_profiling_permanently_disabled(void); + static inline struct alloc_tag_counters alloc_tag_read(struct alloc_tag *tag) { struct alloc_tag_counters v = { 0, 0 }; @@ -163,11 +165,11 @@ static inline void alloc_tag_sub_check(union codetag_ref *ref) { WARN_ONCE(ref && !ref->ct, "alloc_tag was not set\n"); } -void alloc_tag_add_early_pfn(unsigned long pfn, gfp_t gfp_flags); +void alloc_tag_add_early_pfn(unsigned long pfn, unsigned int alloc_flags); #else static inline void alloc_tag_add_check(union codetag_ref *ref, struct alloc_tag *tag) {} static inline void alloc_tag_sub_check(union codetag_ref *ref) {} -static inline void alloc_tag_add_early_pfn(unsigned long pfn, gfp_t gfp_flags) {} +static inline void alloc_tag_add_early_pfn(unsigned long pfn, unsigned int alloc_flags) {} #endif /* Caller should verify both ref and tag to be valid */ @@ -239,6 +241,7 @@ static inline bool alloc_tag_is_inaccurate(struct alloc_tag *tag) #define DEFINE_ALLOC_TAG(_alloc_tag) static inline bool mem_alloc_profiling_enabled(void) { return false; } +static inline bool mem_alloc_profiling_permanently_disabled(void) { return true; } static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag, size_t bytes) {} static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes) {} diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 6c54d5c0d21f..80a74cd2da7e 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -13,7 +13,7 @@ #include <linux/clk.h> #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/amba.h> #include <linux/err.h> #include <linux/resource.h> #include <linux/regulator/consumer.h> diff --git a/include/linux/amd-pmf-io.h b/include/linux/amd-pmf-io.h index 55198d2875cc..271472458516 100644 --- a/include/linux/amd-pmf-io.h +++ b/include/linux/amd-pmf-io.h @@ -19,11 +19,13 @@ * @MT_HPD: Message ID to know the Human presence info from MP2 FW * @MT_ALS: Message ID to know the Ambient light info from MP2 FW * @MT_SRA: Message ID to know the SRA data from MP2 FW + * @MT_OP_MODE: Message ID to know the operating-mode (tablet/laptop) info */ enum sfh_message_type { MT_HPD, MT_ALS, MT_SRA, + MT_OP_MODE, }; /** @@ -44,21 +46,24 @@ enum sfh_hpd_info { * @user_present: Populates the user presence information * @platform_type: Operating modes (clamshell, flat, tent, etc.) * @laptop_placement: Device states (ontable, onlap, outbag) + * @op_mode: Operating-mode field (see enum sfh_dev_mode); used for tablet detection */ struct amd_sfh_info { u32 ambient_light; u8 user_present; u32 platform_type; u32 laptop_placement; + u32 op_mode; }; -enum laptop_placement { - LP_UNKNOWN = 0, - ON_TABLE, - ON_LAP_MOTION, - IN_BAG, - OUT_OF_BAG, - LP_UNDEFINED, +/** + * enum sfh_dev_mode - SFH operating-mode field (sfh_op_mode.mode, bits 0-2) + * @SFH_MODE_LAPTOP: Device is in laptop/clamshell posture + * @SFH_MODE_TABLET: Device is in tablet posture + */ +enum sfh_dev_mode { + SFH_MODE_LAPTOP = 1, + SFH_MODE_TABLET = 3, }; /** @@ -69,6 +74,7 @@ enum laptop_placement { * @mpnpuclk_freq: MPNPU [MHz] * @npu_reads: NPU read bandwidth [MB/sec] * @npu_writes: NPU write bandwidth [MB/sec] + * @npu_temp: NPU temperature [C] */ struct amd_pmf_npu_metrics { u16 npuclk_freq; @@ -77,6 +83,7 @@ struct amd_pmf_npu_metrics { u16 mpnpuclk_freq; u16 npu_reads; u16 npu_writes; + u16 npu_temp; }; int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op); diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h index 17eca3dfc59e..e71d83ee0aef 100644 --- a/include/linux/arm_ffa.h +++ b/include/linux/arm_ffa.h @@ -421,6 +421,13 @@ struct ffa_mem_region { #define FFA_EMAD_HAS_IMPDEF_FIELD(version) ((version) >= FFA_VERSION_1_2) #define FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version) ((version) > FFA_VERSION_1_0) +/* The layout changed from FFA_VERSION_1_0 and the region includes an + * ep_mem_offset. + */ +#define FFA_MEM_REGION_SZ(version) (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET((version)) ?\ + offsetof(struct ffa_mem_region, ep_mem_offset) :\ + sizeof(struct ffa_mem_region)) + static inline u32 ffa_emad_size_get(u32 ffa_version) { u32 sz; @@ -445,7 +452,7 @@ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version) if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version)) offset += offsetof(struct ffa_mem_region, ep_mem_offset); else - offset += sizeof(struct ffa_mem_region); + offset += buf->ep_mem_offset; return offset; } diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h index f652a5028b59..b9dc21c241be 100644 --- a/include/linux/arm_sdei.h +++ b/include/linux/arm_sdei.h @@ -37,6 +37,15 @@ int sdei_event_unregister(u32 event_num); int sdei_event_enable(u32 event_num); int sdei_event_disable(u32 event_num); +/* + * Signal the software-signalled event (event 0) to another PE, NMI-like. + * @mpidr is the target's MPIDR affinity. + */ +int sdei_event_signal(u32 event_num, u64 mpidr); + +/* Was SDEI firmware probed and usable? */ +bool sdei_is_present(void); + /* GHES register/unregister helpers */ int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb, sdei_event_callback *critical_cb); diff --git a/include/linux/ata.h b/include/linux/ata.h index 8fd48bcb2a46..c4fac5f8d480 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -75,6 +75,7 @@ enum { ATA_ID_HW_CONFIG = 93, ATA_ID_SPG = 98, ATA_ID_LBA_CAPACITY_2 = 100, + ATA_ID_MAX_PAGES_PER_DSM = 105, ATA_ID_SECTOR_SIZE = 106, ATA_ID_WWN = 108, ATA_ID_LOGICAL_SECTOR_SIZE = 117, /* and 118 */ @@ -288,6 +289,10 @@ enum { ATA_CMD_SANITIZE_DEVICE = 0xB4, ATA_CMD_ZAC_MGMT_IN = 0x4A, ATA_CMD_ZAC_MGMT_OUT = 0x9F, + ATA_CMD_GET_PHYS_ELEMENT_STATUS = 0x12, + ATA_CMD_REMOVE_ELEMENT_AND_TRUNCATE = 0x7c, + ATA_CMD_RESTORE_ELEMENTS_AND_REBUILD = 0x7d, + ATA_CMD_REMOVE_ELEMENT_AND_MODIFY_ZONES = 0x7e, /* marked obsolete in the ATA/ATAPI-7 spec */ ATA_CMD_RESTORE = 0x10, @@ -762,8 +767,7 @@ static inline bool ata_id_sense_reporting_enabled(const u16 *id) return id[ATA_ID_COMMAND_SET_4] & BIT(6); } -/** - * +/* * Word: 206 - SCT Command Transport * 15:12 - Vendor Specific * 11:6 - Reserved @@ -810,8 +814,9 @@ static inline bool ata_id_sct_supported(const u16 *id) * * The practical impact of this is that ata_id_major_version cannot * reliably report on drives below ATA3. + * + * Returns: major version of ATA drive level or %0 if unknown */ - static inline unsigned int ata_id_major_version(const u16 *id) { unsigned int mver; @@ -928,6 +933,18 @@ static inline bool ata_id_has_trim(const u16 *id) return false; } +static inline u16 ata_id_dsm_max_pages(const u16 *id) +{ + /* + * IDENTIFY DEVICE word 105: MAX PAGES PER DSM COMMAND. Maximum number + * of 512-byte pages of LBA Range Entries the device accepts in a + * single DATA SET MANAGEMENT command. Zero means the device does not + * specify a limit. The field is reserved unless TRIM is supported, so + * callers must gate on ata_id_has_trim(). + */ + return id[ATA_ID_MAX_PAGES_PER_DSM]; +} + static inline bool ata_id_has_zero_after_trim(const u16 *id) { /* DSM supported, deterministic read, and read zero after trim set */ diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index fe21d2f547b5..92c2e20e7416 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -229,9 +229,6 @@ static inline void atm_dev_put(struct atm_dev *dev) int atm_charge(struct atm_vcc *vcc,int truesize); -struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, - gfp_t gfp_flags); -int atm_pcr_goal(const struct atm_trafprm *tp); void vcc_release_async(struct atm_vcc *vcc, int reply); diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h index 4e1ad8ccbcdd..de0ecd0fb05a 100644 --- a/include/linux/auxiliary_bus.h +++ b/include/linux/auxiliary_bus.h @@ -9,7 +9,7 @@ #define _AUXILIARY_BUS_H_ #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/auxiliary.h> /** * DOC: DEVICE_LIFESPAN diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index 5b7d12b40d5e..c2284466e7aa 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -76,8 +76,6 @@ static inline s64 wb_stat_sum(struct bdi_writeback *wb, enum wb_stat_item item) return percpu_counter_sum_positive(&wb->stat[item]); } -extern void wb_writeout_inc(struct bdi_writeback *wb); - /* * maximal error of a stat counter. */ diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 60b94b944e9f..17fc50190014 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -3,7 +3,7 @@ #define LINUX_BCMA_H_ #include <linux/pci.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/bcma.h> #include <linux/bcma/bcma_driver_arm_c9.h> #include <linux/bcma/bcma_driver_chipcommon.h> @@ -486,4 +486,6 @@ extern u32 bcma_core_dma_translation(struct bcma_device *core); extern unsigned int bcma_core_irq(struct bcma_device *core, int num); +extern const struct software_node bcma_gpio_swnode; + #endif /* LINUX_BCMA_H_ */ diff --git a/include/linux/binfmt_misc.h b/include/linux/binfmt_misc.h new file mode 100644 index 000000000000..8045b10dd3e5 --- /dev/null +++ b/include/linux/binfmt_misc.h @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_BINFMT_MISC_H +#define _LINUX_BINFMT_MISC_H + +#include <linux/types.h> + +struct bpf_prog; +struct file; +struct linux_binprm; +struct ucounts; +struct user_namespace; + +#define BINFMT_MISC_OPS_NAME_MAX 16 + +/* Longest name a 'B' entry can bind an interpreter under. */ +#define BINFMT_MISC_INTERP_NAME_MAX 32 + +/* Most interpreters one entry can bind. */ +#define BINFMT_MISC_INTERP_MAX 100 + +/** + * struct binfmt_misc_interp - an interpreter an entry was registered with + * @list: link in the entry's list, in registration order + * @file: the file, opened at registration and never resolved again + * @ucounts: the UCOUNT_BINFMT_MISC_INTERPRETERS charge the binding took + * @path: the path it was registered under, used as the name the interpreter + * runs under; stored after @name in the same allocation + * @name: the name the load program selects it by; empty for the fixed + * interpreter of a static 'F' entry + * + * Owned by the entry and living exactly as long as it does. The list head + * is handed to the handler's load program for the duration of one exec, + * which picks one with bpf_binprm_select_interp(). + */ +struct binfmt_misc_interp { + struct list_head list; + struct file *file; + struct ucounts *ucounts; + const char *path; + char name[]; +}; + +const struct binfmt_misc_interp * +binfmt_misc_find_interp(const struct list_head *interps, const char *name); + +/** + * enum bpf_binprm_flags - per-exec invocation flags a load program can request + * @BPF_BINPRM_PRESERVE_ARGV0: keep the caller's argv[0] (like the 'P' flag) + * @BPF_BINPRM_CREDENTIALS: compute credentials from the binary; implies execfd + * (like the 'C' flag) + * @BPF_BINPRM_EXECFD: pass the binary via AT_EXECFD (like the 'O' flag) + * @BPF_BINPRM_TRANSPARENT: leave argv untouched, the interpreter takes the + * binary from AT_EXECFD (like the 'T' flag); implies + * execfd, excludes preserve-argv0 + * @BPF_BINPRM_LOADER: substitute the interpreter for the binary's PT_INTERP + * and run the binary as a native exec (like the 'L' + * flag); excludes every other flag + * + * Set from a load program with bpf_binprm_set_flags(). Unlike a static entry, + * a bpf handler chooses these per exec rather than once at registration. + */ +enum bpf_binprm_flags { + BPF_BINPRM_PRESERVE_ARGV0 = (1ULL << 0), + BPF_BINPRM_CREDENTIALS = (1ULL << 1), + BPF_BINPRM_EXECFD = (1ULL << 2), + BPF_BINPRM_TRANSPARENT = (1ULL << 3), + BPF_BINPRM_LOADER = (1ULL << 4), +}; + +/** + * struct binfmt_misc_ops - bpf-backed binary type handler + * @match: decide whether the handler applies to @bprm; consulted from the + * entry lookup walk like static magic and extension matching, in + * registration order with first-match-wins semantics; sleepable, + * so it can read the binary to decide, but the verifier rejects + * the interpreter selection kfuncs in it + * @load: select an interpreter for the matched @bprm via + * bpf_binprm_set_interp(), or one the entry bound via + * bpf_binprm_select_interp(), and return zero; a match is + * committed, so a failure fails the exec instead of falling + * through to later entries; -ENOEXEC does not fail the exec but + * moves on to the remaining binary formats + * @name: name that 'B' entries reference the handler by + */ +struct binfmt_misc_ops { + bool (*match)(struct linux_binprm *bprm); + int (*load)(struct linux_binprm *bprm); + char name[BINFMT_MISC_OPS_NAME_MAX]; +}; + +#ifdef CONFIG_BINFMT_MISC_BPF +const struct binfmt_misc_ops *binfmt_misc_get_ops(struct user_namespace *user_ns, + const char *name); +void binfmt_misc_put_ops(const struct binfmt_misc_ops *ops); +bool bpf_prog_is_binfmt_misc_ops(const struct bpf_prog *prog); +#else +static inline const struct binfmt_misc_ops * +binfmt_misc_get_ops(struct user_namespace *user_ns, const char *name) +{ + return NULL; +} + +static inline void binfmt_misc_put_ops(const struct binfmt_misc_ops *ops) +{ +} + +static inline bool bpf_prog_is_binfmt_misc_ops(const struct bpf_prog *prog) +{ + return false; +} +#endif /* CONFIG_BINFMT_MISC_BPF */ + +#endif /* _LINUX_BINFMT_MISC_H */ diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 2c77e383e737..f686a37f7a0a 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -12,6 +12,16 @@ struct coredump_params; #define CORENAME_MAX_SIZE 128 +/* Interpreter selection staged by a bpf binfmt_misc handler. */ +struct binfmt_misc_bpf { + /* interpreters the matched entry bound, selectable by name */ + const struct list_head *bpf_interps; + const char *bpf_interp; /* interpreter selected by a bpf handler */ + struct file *bpf_interp_file; /* the bound interpreter it selected */ + const char *bpf_interp_arg; /* interpreter argument from a bpf handler */ + u64 bpf_flags; /* enum bpf_binprm_flags from a bpf handler */ +}; + /* * This structure is used to hold the arguments that are used when loading binaries. */ @@ -55,6 +65,7 @@ struct linux_binprm { is_check:1; struct file *executable; /* Executable to pass to the interpreter */ struct file *interpreter; + struct file *loader; struct file *file; struct cred *cred; /* new credentials */ int unsafe; /* how unsafe this exec is (mask of LSM_UNSAFE_*) */ @@ -65,6 +76,7 @@ struct linux_binprm { of the time same as filename, but could be different for binfmt_{misc,script} */ const char *fdpath; /* generated filename for execveat */ + struct binfmt_misc_bpf; /* bpf handler interpreter selection */ unsigned interp_flags; int execfd; /* File descriptor of the executable */ unsigned long exec; @@ -85,6 +97,28 @@ struct linux_binprm { #define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3 #define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT) +/* binfmt_misc dispatched to the interpreter transparently */ +#define BINPRM_FLAGS_TRANSPARENT_INTERP_BIT 4 +#define BINPRM_FLAGS_TRANSPARENT_INTERP (1 << BINPRM_FLAGS_TRANSPARENT_INTERP_BIT) + +/** + * bprm_at_flags - the AT_FLAGS this invocation implies + * @bprm: binary that is being executed + * + * Tell the program on the receiving end which dispatch contract it got. + * + * Return: the AT_FLAGS value for this exec + */ +static inline unsigned long bprm_at_flags(const struct linux_binprm *bprm) +{ + /* Transparency preserves the whole argv, argv[0] included. */ + if (bprm->interp_flags & BINPRM_FLAGS_TRANSPARENT_INTERP) + return AT_FLAGS_TRANSPARENT_INTERP; + if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0) + return AT_FLAGS_PRESERVE_ARGV0; + return 0; +} + /* * This structure defines the functions that are used to load the binary formats that * linux accepts. @@ -101,8 +135,8 @@ struct linux_binfmt { #if IS_ENABLED(CONFIG_BINFMT_MISC) struct binfmt_misc { - struct list_head entries; - rwlock_t entries_lock; + struct hlist_head entries; + spinlock_t entries_lock; bool enabled; } __randomize_layout; @@ -129,6 +163,8 @@ extern int begin_new_exec(struct linux_binprm * bprm); extern void setup_new_exec(struct linux_binprm * bprm); extern void finalize_exec(struct linux_binprm *bprm); extern void would_dump(struct linux_binprm *, struct file *); +struct file *bprm_open_interpreter(struct linux_binprm *bprm, const char *path); +void bprm_drop_loader(struct linux_binprm *bprm); extern int suid_dumpable; diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h index c3dda32fd803..0ea2a8bf7efb 100644 --- a/include/linux/bio-integrity.h +++ b/include/linux/bio-integrity.h @@ -17,6 +17,9 @@ enum bip_flags { BIP_MEMPOOL = 1 << 15, /* buffer backed by mempool */ }; +/* flags that require generate/verify action. */ +#define BIP_CHECK_FLAGS (BIP_CHECK_GUARD | BIP_CHECK_REFTAG | BIP_CHECK_APPTAG) + struct bio_integrity_payload { struct bvec_iter bip_iter; diff --git a/include/linux/bio.h b/include/linux/bio.h index 8f33f717b14f..bb3235497e67 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -368,6 +368,45 @@ static inline struct bio *bio_alloc(struct block_device *bdev, void submit_bio(struct bio *bio); +/** + * bio_in_atomic - check if the current context is unsafe for bio completion + * + * Return: %true in atomic contexts (e.g. hard/soft IRQ, preempt-disabled); + * %false when a bio can be safely completed in the current context. + */ +static inline bool bio_in_atomic(void) +{ + if (IS_ENABLED(CONFIG_PREEMPTION) && rcu_preempt_depth()) + return true; + if (!IS_ENABLED(CONFIG_PREEMPT_COUNT)) + return true; + return !preemptible(); +} + +void __bio_complete_in_task(struct bio *bio); + +/** + * bio_complete_in_task - ensure a bio is completed in preemptible task context + * @bio: bio to complete + * + * If called from non-task context, offload the bio completion to a worker + * thread and return %true. Else return %false and do nothing. + * + * Uses BIO_COMPLETE_IN_TASK as a sentinel: if set, the bio was already + * deferred and we are running in the worker — return %false so the + * callback proceeds instead of re-deferring. + */ +static inline bool bio_complete_in_task(struct bio *bio) +{ + if (bio_flagged(bio, BIO_COMPLETE_IN_TASK)) + return false; + if (!bio_in_atomic()) + return false; + bio_set_flag(bio, BIO_COMPLETE_IN_TASK); + __bio_complete_in_task(bio); + return true; +} + extern void bio_endio(struct bio *); /** @@ -477,9 +516,9 @@ int bdev_rw_virt(struct block_device *bdev, sector_t sector, void *data, size_t len, enum req_op op); int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter, - unsigned len_align_mask); + unsigned mem_align_mask, unsigned len_align_mask); -void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter); +bool bio_iov_iter_set(struct bio *bio, const struct iov_iter *iter); void __bio_release_pages(struct bio *bio, bool mark_dirty); extern void bio_set_pages_dirty(struct bio *bio); extern void bio_check_pages_dirty(struct bio *bio); diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index b007d54a9036..7df1573a409c 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -2,7 +2,7 @@ #ifndef __LINUX_BITMAP_H #define __LINUX_BITMAP_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/align.h> #include <linux/bitops.h> @@ -209,6 +209,9 @@ unsigned long bitmap_find_next_zero_area_off(unsigned long *map, * The @align_mask should be one less than a power of 2; the effect is that * the bit offset of all zero areas this function finds is multiples of that * power of 2. A @align_mask of 0 means no alignment is required. + * + * Return: The bit offset of the found area or a value >= @size + * if no area is found. */ static __always_inline unsigned long bitmap_find_next_zero_area(unsigned long *map, @@ -697,14 +700,6 @@ void bitmap_gather(unsigned long *dst, const unsigned long *src, __assign_bit(n++, dst, test_bit(bit, src)); } -static __always_inline -void bitmap_next_set_region(unsigned long *bitmap, unsigned int *rs, - unsigned int *re, unsigned int end) -{ - *rs = find_next_bit(bitmap, end, *rs); - *re = find_next_zero_bit(bitmap, end, *rs + 1); -} - /** * bitmap_release_region - release allocated bitmap region * @bitmap: array of unsigned longs corresponding to the bitmap @@ -894,6 +889,6 @@ void bitmap_write(unsigned long *map, unsigned long value, #define bitmap_set_value8(map, value, start) \ bitmap_write(map, value, start, BITS_PER_BYTE) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __LINUX_BITMAP_H */ diff --git a/include/linux/bits.h b/include/linux/bits.h index a40cc861b3a7..b7509f15718e 100644 --- a/include/linux/bits.h +++ b/include/linux/bits.h @@ -17,7 +17,7 @@ * position @h. For example * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. */ -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) /* * Missing asm support @@ -75,7 +75,7 @@ #define BIT_U32(nr) BIT_TYPE(u32, nr) #define BIT_U64(nr) BIT_TYPE(u64, nr) -#else /* defined(__ASSEMBLY__) */ +#else /* defined(__ASSEMBLER__) */ /* * BUILD_BUG_ON_ZERO is not available in h files included from asm files, @@ -84,6 +84,6 @@ #define GENMASK(h, l) __GENMASK(h, l) #define GENMASK_ULL(h, l) __GENMASK_ULL(h, l) -#endif /* !defined(__ASSEMBLY__) */ +#endif /* !defined(__ASSEMBLER__) */ #endif /* __LINUX_BITS_H */ diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h index dd5841a42c33..58abde49f8c5 100644 --- a/include/linux/blk-cgroup.h +++ b/include/linux/blk-cgroup.h @@ -14,6 +14,8 @@ * Nauman Rafique <nauman@google.com> */ +#include <linux/atomic.h> +#include <linux/compiler.h> #include <linux/types.h> struct bio; @@ -24,10 +26,29 @@ struct gendisk; #ifdef CONFIG_BLK_CGROUP extern struct cgroup_subsys_state * const blkcg_root_css; +extern atomic_t blkcg_nr_congested; void blkcg_schedule_throttle(struct gendisk *disk, bool use_memdelay); void blkcg_maybe_throttle_current(void); -bool blk_cgroup_congested(void); +bool __blk_cgroup_congested(void); + +/** + * blk_cgroup_congested - is the current task in a throttled blkcg? + * + * Called from mm hot paths where the answer is almost always false, so keep + * that case to a load and a branch and only walk the hierarchy out of line + * when something in the system really is throttled. + * + * Return: %true if the current task's blkcg or any of its ancestors is + * throttled, %false otherwise. + */ +static inline bool blk_cgroup_congested(void) +{ + if (likely(!atomic_read(&blkcg_nr_congested))) + return false; + return __blk_cgroup_congested(); +} + void blkcg_pin_online(struct cgroup_subsys_state *blkcg_css); void blkcg_unpin_online(struct cgroup_subsys_state *blkcg_css); struct list_head *blkcg_get_cgwb_list(struct cgroup_subsys_state *css); diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index f7c3cb4a342f..938ff536838c 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -68,6 +68,15 @@ enum blk_crypto_key_type { */ #define BLK_CRYPTO_SW_SECRET_SIZE 32 +/* Flags for blk_crypto_config::flags: */ + +/* + * If set, inline encryption hardware will be used if available. + * If unset, CPU-based encryption will always be used (requires + * CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) + */ +#define BLK_CRYPTO_CFG_ALLOW_HW (1 << 0) + /** * struct blk_crypto_config - an inline encryption key's crypto configuration * @crypto_mode: encryption algorithm this key is for @@ -77,12 +86,14 @@ enum blk_crypto_key_type { * filesystem block size or the disk sector size. * @dun_bytes: the maximum number of bytes of DUN used when using this key * @key_type: the type of this key -- either raw or hardware-wrapped + * @flags: BLK_CRYPTO_CFG_* flags */ struct blk_crypto_config { enum blk_crypto_mode_num crypto_mode; unsigned int data_unit_size; unsigned int dun_bytes; enum blk_crypto_key_type key_type; + int flags; }; /** @@ -150,7 +161,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, enum blk_crypto_key_type key_type, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, - unsigned int data_unit_size); + unsigned int data_unit_size, int flags); int blk_crypto_start_using_key(struct block_device *bdev, const struct blk_crypto_key *key); @@ -160,8 +171,6 @@ void blk_crypto_evict_key(struct block_device *bdev, bool blk_crypto_config_supported_natively(struct block_device *bdev, const struct blk_crypto_config *cfg); -bool blk_crypto_config_supported(struct block_device *bdev, - const struct blk_crypto_config *cfg); int blk_crypto_derive_sw_secret(struct block_device *bdev, const u8 *eph_key, size_t eph_key_size, diff --git a/include/linux/blk_plug.h b/include/linux/blk_plug.h new file mode 100644 index 000000000000..2ac1265662ad --- /dev/null +++ b/include/linux/blk_plug.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_BLK_PLUG_H +#define _LINUX_BLK_PLUG_H + +#include <linux/sched.h> + +struct blk_plug_cb; +typedef void (*blk_plug_cb_fn)(struct blk_plug_cb *cb, bool from_schedule); + +struct rq_list { + struct request *head; + struct request *tail; +}; + +#ifdef CONFIG_BLOCK +/* + * blk_plug permits building a queue of related requests by holding the I/O + * fragments for a short period. This allows merging of sequential requests + * into single larger request. As the requests are moved from a per-task list to + * the device's request_queue in a batch, this results in improved scalability + * as the lock contention for request_queue lock is reduced. + * + * It is ok not to disable preemption when adding the request to the plug list + * or when attempting a merge. For details, please see schedule() where + * blk_flush_plug() is called. + */ +struct blk_plug { + struct rq_list mq_list; /* blk-mq requests */ + + /* if ios_left is > 1, we can batch tag/rq allocations */ + struct rq_list cached_rqs; + u64 cur_ktime; + unsigned short nr_ios; + + unsigned short rq_count; + + bool multiple_queues; + bool has_elevator; + + struct list_head cb_list; /* md requires an unplug callback */ +}; + +void blk_start_plug(struct blk_plug *); +void blk_start_plug_nr_ios(struct blk_plug *, unsigned short); +void blk_finish_plug(struct blk_plug *); + +void __blk_flush_plug(struct blk_plug *plug, bool from_schedule); +static inline void blk_flush_plug(struct blk_plug *plug, bool async) +{ + if (plug) + __blk_flush_plug(plug, async); +} + +static __always_inline void blk_plug_invalidate_ts(void) +{ + if (unlikely(current->flags & PF_BLOCK_TS)) { + current->plug->cur_ktime = 0; + current->flags &= ~PF_BLOCK_TS; + } +} + +struct blk_plug_cb { + struct list_head list; + blk_plug_cb_fn callback; + void *data; +}; + +struct blk_plug_cb *blk_check_plugged(blk_plug_cb_fn unplug, void *data, + int size); +#else /* CONFIG_BLOCK */ +struct blk_plug { +}; + +static inline void blk_start_plug(struct blk_plug *plug) +{ +} + +static inline void blk_start_plug_nr_ios(struct blk_plug *plug, + unsigned short nr_ios) +{ +} + +static inline void blk_finish_plug(struct blk_plug *plug) +{ +} + +static inline void blk_flush_plug(struct blk_plug *plug, bool async) +{ +} + +static inline void blk_plug_invalidate_ts(void) +{ +} +#endif /* CONFIG_BLOCK */ +#endif /* _LINUX_BLK_PLUG_H */ diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 8808ee76e73c..98e21b4cbf32 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -66,7 +66,7 @@ struct block_device { int bd_holders; struct kobject *bd_holder_dir; - atomic_t bd_fsfreeze_count; /* number of freeze requests */ + atomic_t bd_fsfreeze_count; /* >0 freeze requests, <0 freeze deniers */ struct mutex bd_fsfreeze_mutex; /* serialize freeze/thaw */ struct partition_meta_info *bd_meta_info; @@ -322,6 +322,7 @@ enum { BIO_REMAPPED, BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write plugging */ BIO_EMULATES_ZONE_APPEND, /* bio emulates a zone append operation */ + BIO_COMPLETE_IN_TASK, /* complete bi_end_io() in task context */ BIO_FLAG_LAST }; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9213a5716f95..4f7905c3412b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -7,6 +7,7 @@ #include <linux/types.h> #include <linux/blk_types.h> +#include <linux/blk_plug.h> #include <linux/device.h> #include <linux/list.h> #include <linux/llist.h> @@ -21,7 +22,6 @@ #include <linux/rcupdate.h> #include <linux/percpu-refcount.h> #include <linux/blkzoned.h> -#include <linux/sched.h> #include <linux/sbitmap.h> #include <linux/uuid.h> #include <linux/xarray.h> @@ -126,8 +126,6 @@ struct blk_integrity { unsigned char pi_tuple_size; }; -typedef unsigned int __bitwise blk_mode_t; - /* open for reading */ #define BLK_OPEN_READ ((__force blk_mode_t)(1 << 0)) /* open for writing */ @@ -1169,94 +1167,10 @@ extern void blk_put_queue(struct request_queue *); void blk_mark_disk_dead(struct gendisk *disk); -struct rq_list { - struct request *head; - struct request *tail; -}; - #ifdef CONFIG_BLOCK -/* - * blk_plug permits building a queue of related requests by holding the I/O - * fragments for a short period. This allows merging of sequential requests - * into single larger request. As the requests are moved from a per-task list to - * the device's request_queue in a batch, this results in improved scalability - * as the lock contention for request_queue lock is reduced. - * - * It is ok not to disable preemption when adding the request to the plug list - * or when attempting a merge. For details, please see schedule() where - * blk_flush_plug() is called. - */ -struct blk_plug { - struct rq_list mq_list; /* blk-mq requests */ - - /* if ios_left is > 1, we can batch tag/rq allocations */ - struct rq_list cached_rqs; - u64 cur_ktime; - unsigned short nr_ios; - - unsigned short rq_count; - - bool multiple_queues; - bool has_elevator; - - struct list_head cb_list; /* md requires an unplug callback */ -}; - -struct blk_plug_cb; -typedef void (*blk_plug_cb_fn)(struct blk_plug_cb *, bool); -struct blk_plug_cb { - struct list_head list; - blk_plug_cb_fn callback; - void *data; -}; -extern struct blk_plug_cb *blk_check_plugged(blk_plug_cb_fn unplug, - void *data, int size); -extern void blk_start_plug(struct blk_plug *); -extern void blk_start_plug_nr_ios(struct blk_plug *, unsigned short); -extern void blk_finish_plug(struct blk_plug *); - -void __blk_flush_plug(struct blk_plug *plug, bool from_schedule); -static inline void blk_flush_plug(struct blk_plug *plug, bool async) -{ - if (plug) - __blk_flush_plug(plug, async); -} - -static __always_inline void blk_plug_invalidate_ts(void) -{ - if (unlikely(current->flags & PF_BLOCK_TS)) { - current->plug->cur_ktime = 0; - current->flags &= ~PF_BLOCK_TS; - } -} - int blkdev_issue_flush(struct block_device *bdev); long nr_blockdev_pages(void); #else /* CONFIG_BLOCK */ -struct blk_plug { -}; - -static inline void blk_start_plug_nr_ios(struct blk_plug *plug, - unsigned short nr_ios) -{ -} - -static inline void blk_start_plug(struct blk_plug *plug) -{ -} - -static inline void blk_finish_plug(struct blk_plug *plug) -{ -} - -static inline void blk_flush_plug(struct blk_plug *plug, bool async) -{ -} - -static inline void blk_plug_invalidate_ts(void) -{ -} - static inline int blkdev_issue_flush(struct block_device *bdev) { return 0; @@ -1771,13 +1685,6 @@ struct blk_holder_ops { }; /* - * For filesystems using @fs_holder_ops, the @holder argument passed to - * helpers used to open and claim block devices via - * bd_prepare_to_claim() must point to a superblock. - */ -extern const struct blk_holder_ops fs_holder_ops; - -/* * Return the correct open flags for blkdev_get_by_* for super block flags * as stored in sb->s_flags. */ @@ -1837,7 +1744,10 @@ static inline int early_lookup_bdev(const char *pathname, dev_t *dev) int bdev_freeze(struct block_device *bdev); int bdev_thaw(struct block_device *bdev); +int bdev_deny_freeze(struct block_device *bdev); +void bdev_allow_freeze(struct block_device *bdev); void bdev_fput(struct file *bdev_file); +void bdev_yield_claim(struct file *bdev_file); struct io_comp_batch { struct rq_list req_list; diff --git a/include/linux/bnge/hsi.h b/include/linux/bnge/hsi.h index 8ea13d5407ee..1f7bd96415a5 100644 --- a/include/linux/bnge/hsi.h +++ b/include/linux/bnge/hsi.h @@ -8317,8 +8317,7 @@ struct hwrm_ring_alloc_output { __le16 req_type; __le16 seq_id; __le16 resp_len; - __le16 ring_id; - __le16 logical_ring_id; + __le32 ring_id; u8 push_buffer_index; #define RING_ALLOC_RESP_PUSH_BUFFER_INDEX_PING_BUFFER 0x0UL #define RING_ALLOC_RESP_PUSH_BUFFER_INDEX_PONG_BUFFER 0x1UL @@ -8345,10 +8344,10 @@ struct hwrm_ring_free_input { u8 flags; #define RING_FREE_REQ_FLAGS_VIRTIO_RING_VALID 0x1UL #define RING_FREE_REQ_FLAGS_LAST RING_FREE_REQ_FLAGS_VIRTIO_RING_VALID - __le16 ring_id; + __le16 unused_1; __le32 prod_idx; __le32 opaque; - __le32 unused_1; + __le32 ring_id; }; /* hwrm_ring_free_output (size:128b/16B) */ diff --git a/include/linux/bnxt/hsi.h b/include/linux/bnxt/hsi.h index 74a6bf278d88..2f17dbd02185 100644 --- a/include/linux/bnxt/hsi.h +++ b/include/linux/bnxt/hsi.h @@ -191,6 +191,8 @@ struct cmd_nums { #define HWRM_PORT_EVENTS_LOG 0x67UL #define HWRM_VNIC_RSS_COS_LB_CTX_ALLOC 0x70UL #define HWRM_VNIC_RSS_COS_LB_CTX_FREE 0x71UL + #define HWRM_SCH_GRP_CFG 0x73UL + #define HWRM_SCH_GRP_QCFG 0x74UL #define HWRM_QUEUE_MPLS_QCAPS 0x80UL #define HWRM_QUEUE_MPLSTC2PRI_QCFG 0x81UL #define HWRM_QUEUE_MPLSTC2PRI_CFG 0x82UL @@ -4911,6 +4913,29 @@ struct hwrm_port_phy_qcfg_output { u8 valid; }; +/* hwrm_port_events_log_input (size:256b/32B) */ +struct hwrm_port_events_log_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 host_dest_addr; + __le32 host_dest_addr_len; + u8 unused_0[4]; +}; + +/* hwrm_port_events_log_output (size:128b/16B) */ +struct hwrm_port_events_log_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 data_len; + u8 unused_0[5]; + u8 valid; +}; + /* hwrm_port_mac_cfg_input (size:448b/56B) */ struct hwrm_port_mac_cfg_input { __le16 req_type; @@ -5418,6 +5443,40 @@ struct port_stats_ecn { __le64 mark_cnt_cos7; }; +/* port_stats_ext_pfc_adv (size:1536b/192B) */ +struct port_stats_ext_pfc_adv { + __le64 pfc_min_duration_time[8]; + __le64 pfc_max_duration_time[8]; + __le64 pfc_weighted_duration_time[8]; +}; + +/* hwrm_port_qstats_ext_pfc_adv_input (size:320b/40B) */ +struct hwrm_port_qstats_ext_pfc_adv_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 port_id; + __le16 pfc_adv_stat_size; + u8 flags; + #define PORT_QSTATS_EXT_PFC_ADV_REQ_FLAGS_COUNTER_MASK 0x1UL + u8 unused_0[3]; + __le64 tx_pfc_adv_stat_host_addr; + __le64 rx_pfc_adv_stat_host_addr; +}; + +/* hwrm_port_qstats_ext_pfc_adv_output (size:128b/16B) */ +struct hwrm_port_qstats_ext_pfc_adv_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 pfc_adv_stat_size; + u8 unused_0[5]; + u8 valid; +}; + /* hwrm_port_clr_stats_input (size:192b/24B) */ struct hwrm_port_clr_stats_input { __le16 req_type; @@ -6095,6 +6154,61 @@ struct hwrm_port_led_qcaps_output { u8 valid; }; +/* hwrm_port_prbs_test_input (size:384b/48B) */ +struct hwrm_port_prbs_test_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 resp_data_addr; + __le16 data_len; + __le16 flags; + #define PORT_PRBS_TEST_REQ_FLAGS_INTERNAL 0x1UL + __le32 unused_1; + __le16 port_id; + __le16 poly; + #define PORT_PRBS_TEST_REQ_POLY_PRBS7 0x0UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS9 0x1UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS11 0x2UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS15 0x3UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS23 0x4UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS31 0x5UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS58 0x6UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS49 0x7UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS10 0x8UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS20 0x9UL + #define PORT_PRBS_TEST_REQ_POLY_PRBS13 0xaUL + #define PORT_PRBS_TEST_REQ_POLY_INVALID 0xffUL + #define PORT_PRBS_TEST_REQ_POLY_LAST PORT_PRBS_TEST_REQ_POLY_INVALID + __le16 prbs_config; + #define PORT_PRBS_TEST_REQ_PRBS_CONFIG_START_STOP 0x1UL + #define PORT_PRBS_TEST_REQ_PRBS_CONFIG_TX_LANE_MAP_VALID 0x2UL + #define PORT_PRBS_TEST_REQ_PRBS_CONFIG_RX_LANE_MAP_VALID 0x4UL + #define PORT_PRBS_TEST_REQ_PRBS_CONFIG_FEC_STAT_T0_T7 0x8UL + #define PORT_PRBS_TEST_REQ_PRBS_CONFIG_FEC_STAT_T8_T15 0x10UL + #define PORT_PRBS_TEST_REQ_PRBS_CONFIG_T_CODE 0x20UL + __le16 timeout; + __le32 tx_lane_map; + __le32 rx_lane_map; +}; + +/* hwrm_port_prbs_test_output (size:128b/16B) */ +struct hwrm_port_prbs_test_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 total_data_len; + u8 ber_format; + #define PORT_PRBS_TEST_RESP_BER_FORMAT_PRBS 0x0UL + #define PORT_PRBS_TEST_RESP_BER_FORMAT_FEC 0x1UL + #define PORT_PRBS_TEST_RESP_BER_FORMAT_LAST PORT_PRBS_TEST_RESP_BER_FORMAT_FEC + u8 unused_0; + u8 unused_1[3]; + u8 valid; +}; + /* hwrm_port_phy_fdrstat_input (size:192b/24B) */ struct hwrm_port_phy_fdrstat_input { __le16 req_type; @@ -6147,6 +6261,54 @@ struct hwrm_port_phy_fdrstat_cmd_err { u8 unused_0[7]; }; +/* hwrm_port_dsc_dump_input (size:320b/40B) */ +struct hwrm_port_dsc_dump_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 resp_data_addr; + __le16 data_len; + __le16 unused_0; + __le32 data_offset; + __le16 port_id; + __le16 diag_level; + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_LANE 0x0UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_CORE 0x1UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_EVENT 0x2UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_EYE 0x3UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_REG_CORE 0x4UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_REG_LANE 0x5UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_UC_CORE 0x6UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_UC_LANE 0x7UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_LANE_DEBUG 0x8UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_BER_VERT 0x9UL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_BER_HORZ 0xaUL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_EVENT_SAFE 0xbUL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_TIMESTAMP 0xcUL + #define PORT_DSC_DUMP_REQ_DIAG_LEVEL_LAST PORT_DSC_DUMP_REQ_DIAG_LEVEL_SRDS_DIAG_TIMESTAMP + __le16 lane_number; + __le16 dsc_dump_config; + #define PORT_DSC_DUMP_REQ_DSC_DUMP_CONFIG_START_RETRIEVE 0x1UL + #define PORT_DSC_DUMP_REQ_DSC_DUMP_CONFIG_BIG_BUFFER 0x2UL + #define PORT_DSC_DUMP_REQ_DSC_DUMP_CONFIG_DEFER_CLOSE 0x4UL +}; + +/* hwrm_port_dsc_dump_output (size:128b/16B) */ +struct hwrm_port_dsc_dump_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 total_data_len; + __le16 total_data_len_high; + u8 unused_1[2]; + u8 flags; + #define PORT_DSC_DUMP_RESP_FLAGS_BIG_BUFFER 0x1UL + u8 valid; +}; + /* hwrm_port_mac_qcaps_input (size:192b/24B) */ struct hwrm_port_mac_qcaps_input { __le16 req_type; @@ -9559,6 +9721,62 @@ struct hwrm_stat_generic_qstats_output { u8 valid; }; +/* hwrm_stat_query_roce_stats_input (size:256b/32B) */ +struct hwrm_stat_query_roce_stats_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 roce_stat_size; + u8 flags; + #define STAT_QUERY_ROCE_STATS_REQ_FLAGS_PORT_AGGREGATED 0x1UL + u8 port_id; + u8 unused_0[4]; + __le64 roce_stat_host_addr; +}; + +/* hwrm_stat_query_roce_stats_output (size:128b/16B) */ +struct hwrm_stat_query_roce_stats_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 roce_stat_size; + u8 flags; + #define STAT_QUERY_ROCE_STATS_RESP_FLAGS_PORT_AGGREGATED 0x1UL + u8 unused_0[4]; + u8 valid; +}; + +/* hwrm_stat_query_roce_stats_ext_input (size:256b/32B) */ +struct hwrm_stat_query_roce_stats_ext_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 roce_stat_size; + u8 flags; + #define STAT_QUERY_ROCE_STATS_EXT_REQ_FLAGS_PORT_AGGREGATED 0x1UL + u8 port_id; + u8 unused_0[4]; + __le64 roce_stat_host_addr; +}; + +/* hwrm_stat_query_roce_stats_ext_output (size:128b/16B) */ +struct hwrm_stat_query_roce_stats_ext_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 roce_stat_size; + u8 flags; + #define STAT_QUERY_ROCE_STATS_EXT_RESP_FLAGS_PORT_AGGREGATED 0x1UL + u8 unused_0[4]; + u8 valid; +}; + /* generic_sw_hw_stats (size:1472b/184B) */ struct generic_sw_hw_stats { __le64 pcie_statistics_tx_tlp; @@ -10207,6 +10425,57 @@ struct hwrm_dbg_read_direct_output { u8 valid; }; +/* hwrm_dbg_read_indirect_input (size:640b/80B) */ +struct hwrm_dbg_read_indirect_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 host_dest_addr; + __le32 host_dest_addr_len; + u8 indirect_access_type; + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_TE_MGMT_FILTERS_L2 0x0UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_TE_MGMT_FILTERS_L3L4 0x1UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_RE_MGMT_FILTERS_L2 0x2UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_RE_MGMT_FILTERS_L3L4 0x3UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_STAT_CTXS 0x4UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_TX_L2_TCAM 0x5UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_RX_L2_TCAM 0x6UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_TX_IPV6_SUBNET_TCAM 0x7UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_RX_IPV6_SUBNET_TCAM 0x8UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_TX_SRC_PROPERTIES_TCAM 0x9UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_RX_SRC_PROPERTIES_TCAM 0xaUL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_VEB_LOOKUP_TCAM 0xbUL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_TX_PROFILE_LOOKUP_TCAM 0xcUL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_RX_PROFILE_LOOKUP_TCAM 0xdUL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_TX_LOOKUP_TCAM 0xeUL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CFA_RX_LOOKUP_TCAM 0xfUL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_MHB 0x10UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_PCIE_GBL 0x11UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_MULTI_HOST_SOC 0x12UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_PCIE_PRIVATE 0x13UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_HOST_DMA 0x14UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_SOC_ELOG 0x15UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_CTX 0x16UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_STATS 0x17UL + #define DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_LAST DBG_READ_INDIRECT_REQ_INDIRECT_ACCESS_TYPE_STATS + u8 unused_0[3]; + __le32 start_index; + __le32 num_of_entries; + __le32 opaque[10]; +}; + +/* hwrm_dbg_read_indirect_output (size:128b/16B) */ +struct hwrm_dbg_read_indirect_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + u8 unused_0[7]; + u8 valid; +}; + /* hwrm_dbg_qcaps_input (size:192b/24B) */ struct hwrm_dbg_qcaps_input { __le16 req_type; @@ -10518,6 +10787,154 @@ struct hwrm_dbg_log_buffer_flush_output { u8 valid; }; +/* hwrm_dbg_serdes_test_input (size:320b/40B) */ +struct hwrm_dbg_serdes_test_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 resp_data_addr; + __le32 resp_data_offset; + __le16 data_len; + u8 flags; + #define DBG_SERDES_TEST_REQ_FLAGS_UNUSED_TEST_MASK 0x7UL + #define DBG_SERDES_TEST_REQ_FLAGS_UNUSED_TEST_SFT 0 + #define DBG_SERDES_TEST_REQ_FLAGS_EYE_PROJECTION 0x8UL + #define DBG_SERDES_TEST_REQ_FLAGS_PCIE_SERDES_TEST 0x10UL + #define DBG_SERDES_TEST_REQ_FLAGS_ETHERNET_SERDES_TEST 0x20UL + u8 options; + #define DBG_SERDES_TEST_REQ_OPTIONS_LANE_NO_MASK 0xfUL + #define DBG_SERDES_TEST_REQ_OPTIONS_LANE_NO_SFT 0 + #define DBG_SERDES_TEST_REQ_OPTIONS_DIRECTION 0x10UL + #define DBG_SERDES_TEST_REQ_OPTIONS_DIRECTION_HORIZONTAL (0x0UL << 4) + #define DBG_SERDES_TEST_REQ_OPTIONS_DIRECTION_VERTICAL (0x1UL << 4) + #define DBG_SERDES_TEST_REQ_OPTIONS_DIRECTION_LAST DBG_SERDES_TEST_REQ_OPTIONS_DIRECTION_VERTICAL + #define DBG_SERDES_TEST_REQ_OPTIONS_PROJ_TYPE 0x20UL + #define DBG_SERDES_TEST_REQ_OPTIONS_PROJ_TYPE_LEFT_TOP (0x0UL << 5) + #define DBG_SERDES_TEST_REQ_OPTIONS_PROJ_TYPE_RIGHT_BOTTOM (0x1UL << 5) + #define DBG_SERDES_TEST_REQ_OPTIONS_PROJ_TYPE_LAST DBG_SERDES_TEST_REQ_OPTIONS_PROJ_TYPE_RIGHT_BOTTOM + #define DBG_SERDES_TEST_REQ_OPTIONS_RSVD_MASK 0xc0UL + #define DBG_SERDES_TEST_REQ_OPTIONS_RSVD_SFT 6 + u8 targetBER; + #define DBG_SERDES_TEST_REQ_TARGETBER_BER_1E8 0x0UL + #define DBG_SERDES_TEST_REQ_TARGETBER_BER_1E9 0x1UL + #define DBG_SERDES_TEST_REQ_TARGETBER_BER_1E10 0x2UL + #define DBG_SERDES_TEST_REQ_TARGETBER_BER_1E11 0x3UL + #define DBG_SERDES_TEST_REQ_TARGETBER_BER_1E12 0x4UL + #define DBG_SERDES_TEST_REQ_TARGETBER_LAST DBG_SERDES_TEST_REQ_TARGETBER_BER_1E12 + u8 action; + #define DBG_SERDES_TEST_REQ_ACTION_SYNCHRONOUS 0x0UL + #define DBG_SERDES_TEST_REQ_ACTION_START 0x1UL + #define DBG_SERDES_TEST_REQ_ACTION_PROGRESS 0x2UL + #define DBG_SERDES_TEST_REQ_ACTION_STOP 0x3UL + #define DBG_SERDES_TEST_REQ_ACTION_LAST DBG_SERDES_TEST_REQ_ACTION_STOP + u8 unused[6]; +}; + +/* hwrm_dbg_serdes_test_output (size:192b/24B) */ +struct hwrm_dbg_serdes_test_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 total_data_len; + __le16 copied_data_len; + __le16 progress_percent; + __le16 timeout; + u8 flags; + #define DBG_SERDES_TEST_RESP_FLAGS_BIT_COUNT_TYPE 0x1UL + #define DBG_SERDES_TEST_RESP_FLAGS_BIT_COUNT_TYPE_BIT_COUNT_TOTAL (0x0UL << 0) + #define DBG_SERDES_TEST_RESP_FLAGS_BIT_COUNT_TYPE_BIT_COUNT_POW2 (0x1UL << 0) + #define DBG_SERDES_TEST_RESP_FLAGS_BIT_COUNT_TYPE_LAST DBG_SERDES_TEST_RESP_FLAGS_BIT_COUNT_TYPE_BIT_COUNT_POW2 + #define DBG_SERDES_TEST_RESP_FLAGS_RSVD_MASK 0xfeUL + #define DBG_SERDES_TEST_RESP_FLAGS_RSVD_SFT 1 + u8 unused_0; + __le16 hdr_size; + u8 unused_1[3]; + u8 valid; +}; + +/* hwrm_dbg_ptrace_input (size:320b/40B) */ +struct hwrm_dbg_ptrace_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le32 pdi_cmd_buf_addr[2]; + __le32 pdi_resp_buf_addr[2]; + __le32 pdi_req_buf_len; + __le16 seq_no; + __le16 flags; + #define DBG_PTRACE_REQ_FLAGS_SELECT_IN 0x1UL + #define DBG_PTRACE_REQ_FLAGS_SELECT_OUT 0x2UL + #define DBG_PTRACE_REQ_FLAGS_GLOBAL_START 0x4UL + #define DBG_PTRACE_REQ_FLAGS_GLOBAL_STOP 0x8UL +}; + +/* hwrm_dbg_ptrace_output (size:128b/16B) */ +struct hwrm_dbg_ptrace_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 flags; + #define DBG_PTRACE_RESP_FLAGS_MORE 0x1UL + __le16 data_len; + u8 unused_0[3]; + u8 valid; +}; + +/* hwrm_dbg_token_cfg_input (size:256b/32B) */ +struct hwrm_dbg_token_cfg_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + u8 flags; + #define DBG_TOKEN_CFG_REQ_FLAGS_ENABLE 0x1UL + u8 unused_0[3]; + __le32 dbg_token_len; + __le64 host_src_addr; +}; + +/* hwrm_dbg_token_cfg_output (size:128b/16B) */ +struct hwrm_dbg_token_cfg_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + u8 unused_0[7]; + u8 valid; +}; + +/* hwrm_nvm_raw_write_blk_input (size:320b/40B) */ +struct hwrm_nvm_raw_write_blk_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 host_src_addr; + __le32 dest_addr; + __le32 len; + u8 flags; + #define NVM_RAW_WRITE_BLK_REQ_FLAGS_SECURITY_SOC_NVM 0x1UL + u8 unused_0[7]; +}; + +/* hwrm_nvm_raw_write_blk_output (size:128b/16B) */ +struct hwrm_nvm_raw_write_blk_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + u8 unused_0[7]; + u8 valid; +}; + /* hwrm_nvm_read_input (size:320b/40B) */ struct hwrm_nvm_read_input { __le16 req_type; @@ -10543,6 +10960,31 @@ struct hwrm_nvm_read_output { u8 valid; }; +/* hwrm_nvm_raw_dump_input (size:320b/40B) */ +struct hwrm_nvm_raw_dump_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 host_dest_addr; + __le32 offset; + __le32 len; + u8 flags; + #define NVM_RAW_DUMP_REQ_FLAGS_SECURITY_SOC_NVM 0x1UL + u8 unused_0[7]; +}; + +/* hwrm_nvm_raw_dump_output (size:128b/16B) */ +struct hwrm_nvm_raw_dump_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + u8 unused_0[7]; + u8 valid; +}; + /* hwrm_nvm_get_dir_entries_input (size:192b/24B) */ struct hwrm_nvm_get_dir_entries_input { __le16 req_type; @@ -11166,6 +11608,149 @@ struct hwrm_selftest_irq_output { u8 valid; }; +/* hwrm_selftest_retrieve_serdes_data_input (size:320b/40B) */ +struct hwrm_selftest_retrieve_serdes_data_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le64 resp_data_addr; + __le32 resp_data_offset; + __le16 data_len; + u8 flags; + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_UNUSED_TEST_MASK 0x7UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_UNUSED_TEST_SFT 0 + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_EYE_PROJECTION 0x8UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_PCIE_SERDES_TEST 0x10UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_FLAGS_ETHERNET_SERDES_TEST 0x20UL + u8 options; + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_PCIE_LANE_NO_MASK 0xfUL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_PCIE_LANE_NO_SFT 0 + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_DIRECTION 0x10UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_DIRECTION_HORIZONTAL (0x0UL << 4) + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_DIRECTION_VERTICAL (0x1UL << 4) + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_DIRECTION_LAST SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_DIRECTION_VERTICAL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_PROJ_TYPE 0x20UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_PROJ_TYPE_LEFT_TOP (0x0UL << 5) + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_PROJ_TYPE_RIGHT_BOTTOM (0x1UL << 5) + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_PROJ_TYPE_LAST SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_PROJ_TYPE_RIGHT_BOTTOM + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_RSVD_MASK 0xc0UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_OPTIONS_RSVD_SFT 6 + u8 targetBER; + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_TARGETBER_BER_1E8 0x0UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_TARGETBER_BER_1E9 0x1UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_TARGETBER_BER_1E10 0x2UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_TARGETBER_BER_1E11 0x3UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_TARGETBER_BER_1E12 0x4UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_TARGETBER_LAST SELFTEST_RETRIEVE_SERDES_DATA_REQ_TARGETBER_BER_1E12 + u8 action; + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_ACTION_SYNCHRONOUS 0x0UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_ACTION_START 0x1UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_ACTION_PROGRESS 0x2UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_ACTION_STOP 0x3UL + #define SELFTEST_RETRIEVE_SERDES_DATA_REQ_ACTION_LAST SELFTEST_RETRIEVE_SERDES_DATA_REQ_ACTION_STOP + u8 unused[6]; +}; + +/* hwrm_selftest_retrieve_serdes_data_output (size:192b/24B) */ +struct hwrm_selftest_retrieve_serdes_data_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 total_data_len; + __le16 copied_data_len; + __le16 progress_percent; + __le16 timeout; + u8 flags; + #define SELFTEST_RETRIEVE_SERDES_DATA_RESP_FLAGS_BIT_COUNT_TYPE 0x1UL + #define SELFTEST_RETRIEVE_SERDES_DATA_RESP_FLAGS_BIT_COUNT_TYPE_BIT_COUNT_TOTAL (0x0UL << 0) + #define SELFTEST_RETRIEVE_SERDES_DATA_RESP_FLAGS_BIT_COUNT_TYPE_BIT_COUNT_POW2 (0x1UL << 0) + #define SELFTEST_RETRIEVE_SERDES_DATA_RESP_FLAGS_BIT_COUNT_TYPE_LAST SELFTEST_RETRIEVE_SERDES_DATA_RESP_FLAGS_BIT_COUNT_TYPE_BIT_COUNT_POW2 + #define SELFTEST_RETRIEVE_SERDES_DATA_RESP_FLAGS_RSVD_MASK 0xfeUL + #define SELFTEST_RETRIEVE_SERDES_DATA_RESP_FLAGS_RSVD_SFT 1 + u8 unused_0; + __le16 hdr_size; + u8 unused_1[3]; + u8 valid; +}; + +/* hwrm_sch_grp_cfg_input (size:704b/88B) */ +struct hwrm_sch_grp_cfg_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 sch_grp_id; + __le16 num_fids; + __le32 enables; + #define SCH_GRP_CFG_REQ_ENABLES_QUEUE_ID0_VALID 0x1UL + #define SCH_GRP_CFG_REQ_ENABLES_QUEUE_ID1_VALID 0x2UL + #define SCH_GRP_CFG_REQ_ENABLES_QUEUE_ID2_VALID 0x4UL + #define SCH_GRP_CFG_REQ_ENABLES_QUEUEID3_VALID 0x8UL + #define SCH_GRP_CFG_REQ_ENABLES_QUEUE_ID4_VALID 0x10UL + #define SCH_GRP_CFG_REQ_ENABLES_QUEUE_ID5_VALID 0x20UL + #define SCH_GRP_CFG_REQ_ENABLES_QUEUE_ID6_VALID 0x40UL + #define SCH_GRP_CFG_REQ_ENABLES_QUEUE_ID7_VALID 0x80UL + #define SCH_GRP_CFG_REQ_ENABLES_MAX_BW 0x100UL + #define SCH_GRP_CFG_REQ_ENABLES_FID_MAP 0x200UL + __le64 fid_table_addr; + __le32 max_bw; + u8 unused_0[4]; + u8 queue_id[8]; + u8 queue_tsa_assign[8]; + #define SCH_GRP_CFG_REQ_QUEUE_TSA_ASSIGN_SP 0x0UL + #define SCH_GRP_CFG_REQ_QUEUE_TSA_ASSIGN_ETS 0x1UL + #define SCH_GRP_CFG_REQ_QUEUE_TSA_ASSIGN_LAST SCH_GRP_CFG_REQ_QUEUE_TSA_ASSIGN_ETS + __le32 queue_min_bw_percent[8]; +}; + +/* hwrm_sch_grp_cfg_output (size:128b/16B) */ +struct hwrm_sch_grp_cfg_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + u8 unused_0[7]; + u8 valid; +}; + +/* hwrm_sch_grp_qcfg_input (size:256b/32B) */ +struct hwrm_sch_grp_qcfg_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 sch_grp_id; + __le16 fid_table_len; + u8 unused_0[4]; + __le64 fid_table_addr; +}; + +/* hwrm_sch_grp_qcfg_output (size:576b/72B) */ +struct hwrm_sch_grp_qcfg_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le32 max_bw; + u8 unused_0[2]; + __le16 num_fids; + u8 queue_id[8]; + #define SCH_GRP_QCFG_RESP_QUEUE_ID_INVALID_QUEUE_ID 0xffUL + #define SCH_GRP_QCFG_RESP_QUEUE_ID_LAST SCH_GRP_QCFG_RESP_QUEUE_ID_INVALID_QUEUE_ID + u8 queue_tsa_assign[8]; + #define SCH_GRP_QCFG_RESP_QUEUE_TSA_ASSIGN_SP 0x0UL + #define SCH_GRP_QCFG_RESP_QUEUE_TSA_ASSIGN_ETS 0x1UL + #define SCH_GRP_QCFG_RESP_QUEUE_TSA_ASSIGN_LAST SCH_GRP_QCFG_RESP_QUEUE_TSA_ASSIGN_ETS + __le32 queue_min_bw_percent[8]; + u8 unused_1[7]; + u8 valid; +}; + /* dbc_dbc (size:64b/8B) */ struct dbc_dbc { __le32 index; diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h index 1c7f3b74ffcf..deda507500da 100644 --- a/include/linux/bootconfig.h +++ b/include/linux/bootconfig.h @@ -308,4 +308,18 @@ static inline const char *xbc_get_embedded_bootconfig(size_t *size) } #endif +/* Bootconfig opt-in detection, shared by setup_arch() and setup_boot_config() */ +#ifdef CONFIG_BOOT_CONFIG +bool __init bootconfig_cmdline_requested(const char *boot_cmdline, int *end_offset); +#endif + +/* Build-time-rendered bootconfig cmdline prepended in setup_arch() */ +#ifdef CONFIG_CMDLINE_FROM_BOOTCONFIG +void __init xbc_prepend_embedded_cmdline(char *dst, size_t size); +bool __init xbc_embedded_cmdline_applied(void); +#else +static inline void xbc_prepend_embedded_cmdline(char *dst, size_t size) { } +static inline bool xbc_embedded_cmdline_applied(void) { return false; } +#endif + #endif diff --git a/include/linux/bootmem_info.h b/include/linux/bootmem_info.h deleted file mode 100644 index f724340755e5..000000000000 --- a/include/linux/bootmem_info.h +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __LINUX_BOOTMEM_INFO_H -#define __LINUX_BOOTMEM_INFO_H - -#include <linux/mm.h> -#include <linux/kmemleak.h> - -/* - * Types for free bootmem stored in the low bits of page->private. - */ -enum bootmem_type { - MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE = 1, - SECTION_INFO = MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE, - MIX_SECTION_INFO, - NODE_INFO, - MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE = NODE_INFO, -}; - -#ifdef CONFIG_HAVE_BOOTMEM_INFO_NODE -void __init register_page_bootmem_info_node(struct pglist_data *pgdat); -void register_page_bootmem_memmap(unsigned long section_nr, struct page *map, - unsigned long nr_pages); - -void get_page_bootmem(unsigned long info, struct page *page, - enum bootmem_type type); -void put_page_bootmem(struct page *page); - -static inline enum bootmem_type bootmem_type(const struct page *page) -{ - return (unsigned long)page->private & 0xf; -} - -static inline unsigned long bootmem_info(const struct page *page) -{ - return (unsigned long)page->private >> 4; -} - -/* - * Any memory allocated via the memblock allocator and not via the - * buddy will be marked reserved already in the memmap. For those - * pages, we can call this function to free it to buddy allocator. - */ -static inline void free_bootmem_page(struct page *page) -{ - enum bootmem_type type = bootmem_type(page); - - VM_BUG_ON_PAGE(page_ref_count(page) != 2, page); - - if (type == SECTION_INFO || type == MIX_SECTION_INFO) - put_page_bootmem(page); - else - VM_BUG_ON_PAGE(1, page); -} -#else -static inline void register_page_bootmem_info_node(struct pglist_data *pgdat) -{ -} - -static inline void register_page_bootmem_memmap(unsigned long section_nr, - struct page *map, unsigned long nr_pages) -{ -} - -static inline void put_page_bootmem(struct page *page) -{ -} - -static inline enum bootmem_type bootmem_type(const struct page *page) -{ - return SECTION_INFO; -} - -static inline unsigned long bootmem_info(const struct page *page) -{ - return 0; -} - -static inline void get_page_bootmem(unsigned long info, struct page *page, - enum bootmem_type type) -{ -} - -static inline void free_bootmem_page(struct page *page) -{ - free_reserved_page(page); -} -#endif - -#endif /* __LINUX_BOOTMEM_INFO_H */ diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 7719f6528445..ffa5626411ac 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -145,6 +145,7 @@ struct bpf_map_ops { int (*map_direct_value_meta)(const struct bpf_map *map, u64 imm, u32 *off); int (*map_mmap)(struct bpf_map *map, struct vm_area_struct *vma); + vm_fault_t (*map_mmap_fault)(struct bpf_map *map, struct vm_fault *vmf); __poll_t (*map_poll)(struct bpf_map *map, struct file *filp, struct poll_table_struct *pts); unsigned long (*map_get_unmapped_area)(struct file *filep, unsigned long addr, @@ -299,7 +300,6 @@ 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 @@ -570,7 +570,7 @@ static inline void bpf_obj_memcpy(struct btf_record *rec, if (IS_ERR_OR_NULL(rec)) { if (long_memcpy) - bpf_long_memcpy(dst, src, round_up(size, 8)); + bpf_long_memcpy(dst, src, size); else memcpy(dst, src, size); return; @@ -593,7 +593,7 @@ static inline void copy_map_value(struct bpf_map *map, void *dst, void *src) static inline void copy_map_value_long(struct bpf_map *map, void *dst, void *src) { - bpf_obj_memcpy(map->record, dst, src, map->value_size, true); + bpf_obj_memcpy(map->record, dst, src, round_up(map->value_size, 8), true); } static inline void bpf_obj_swap_uptrs(const struct btf_record *rec, void *dst, void *src) @@ -889,8 +889,8 @@ enum bpf_arg_type { ARG_PTR_TO_MEM, /* pointer to valid memory (stack, packet, map value) */ ARG_PTR_TO_ARENA, - ARG_CONST_SIZE, /* number of bytes accessed from memory */ - ARG_CONST_SIZE_OR_ZERO, /* number of bytes accessed from memory or 0 */ + ARG_MEM_SIZE, /* number of bytes accessed from memory */ + ARG_MEM_SIZE_OR_ZERO, /* number of bytes accessed from memory or 0 */ ARG_PTR_TO_CTX, /* pointer to context */ ARG_ANYTHING, /* any (initialized) argument is ok */ @@ -961,6 +961,21 @@ enum bpf_return_type { }; static_assert(__BPF_RET_TYPE_MAX <= BPF_BASE_TYPE_LIMIT); +/* 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 + +/* The maximum number of arguments passed through registers + * a single function may have. + */ +#define MAX_BPF_FUNC_REG_ARGS 5 + /* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs * to in-kernel helper functions and for adjusting imm32 field in BPF_CALL * instructions after verifying @@ -985,7 +1000,7 @@ struct bpf_func_proto { enum bpf_arg_type arg4_type; enum bpf_arg_type arg5_type; }; - enum bpf_arg_type arg_type[5]; + enum bpf_arg_type arg_type[MAX_BPF_FUNC_ARGS]; }; union { struct { @@ -995,7 +1010,7 @@ struct bpf_func_proto { u32 *arg4_btf_id; u32 *arg5_btf_id; }; - u32 *arg_btf_id[5]; + u32 *arg_btf_id[MAX_BPF_FUNC_ARGS]; struct { size_t arg1_size; size_t arg2_size; @@ -1003,7 +1018,7 @@ struct bpf_func_proto { size_t arg4_size; size_t arg5_size; }; - size_t arg_size[5]; + size_t arg_size[MAX_BPF_FUNC_ARGS]; }; int *ret_btf_id; /* return value btf_id */ bool (*allowed)(const struct bpf_prog *prog); @@ -1118,21 +1133,6 @@ static inline bool bpf_pseudo_func(const struct bpf_insn *insn) return bpf_is_ldimm64(insn) && insn->src_reg == BPF_PSEUDO_FUNC; } -/* Given a BPF_ATOMIC instruction @atomic_insn, return true if it is an - * atomic load or store, and false if it is a read-modify-write instruction. - */ -static inline bool -bpf_atomic_is_load_store(const struct bpf_insn *atomic_insn) -{ - switch (atomic_insn->imm) { - case BPF_LOAD_ACQ: - case BPF_STORE_REL: - return true; - default: - return false; - } -} - struct bpf_prog_ops { int (*test_run)(struct bpf_prog *prog, const union bpf_attr *kattr, union bpf_attr __user *uattr); @@ -1193,27 +1193,15 @@ struct bpf_prog_offload { u32 jited_len; }; -/* 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 - -/* The maximum number of arguments passed through registers - * a single function may have. - */ -#define MAX_BPF_FUNC_REG_ARGS 5 - -/* The argument is a structure or a union. */ -#define BTF_FMODEL_STRUCT_ARG BIT(0) - /* The argument is signed. */ #define BTF_FMODEL_SIGNED_ARG BIT(1) +/* The argument is an arena pointer. */ +#define BTF_FMODEL_ARENA_ARG BIT(2) + +/* The argument is nullable. */ +#define BTF_FMODEL_NULLABLE_ARG BIT(3) + struct btf_func_model { u8 ret_size; u8 ret_flags; @@ -1287,6 +1275,15 @@ struct bpf_tramp_nodes { int nr_nodes; }; +/* + * The arena base against which a struct_ops trampoline converts the + * arguments marked with BTF_FMODEL_ARENA_ARG while saving them into the BPF + * ctx, ctx[arg] = (u32)(kaddr - kern_vm_start). Zero when the trampoline + * converts nothing. + */ +u64 bpf_tramp_arena_base(const struct btf_func_model *m, + struct bpf_tramp_nodes *tnodes, u32 flags); + struct bpf_tramp_run_ctx; /* Different use cases for BPF trampoline: @@ -1522,8 +1519,9 @@ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_func 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); +void bpf_trampoline_multi_detach(struct bpf_prog *prog, + struct bpf_tracing_multi_link *link); +void bpf_trampoline_set_flags(struct bpf_trampoline *tr, u32 flags); /* * When the architecture supports STATIC_CALL replace the bpf_dispatcher_fn @@ -1642,11 +1640,11 @@ static inline int bpf_trampoline_multi_attach(struct bpf_prog *prog, u32 *ids, { return -ENOTSUPP; } -static inline int bpf_trampoline_multi_detach(struct bpf_prog *prog, - struct bpf_tracing_multi_link *link) +static inline void bpf_trampoline_multi_detach(struct bpf_prog *prog, + struct bpf_tracing_multi_link *link) { - return -ENOTSUPP; } +static inline void bpf_trampoline_set_flags(struct bpf_trampoline *tr, u32 flags) {} #endif struct bpf_func_info_aux { @@ -1865,8 +1863,9 @@ struct bpf_prog_aux { struct bpf_prog { u16 pages; /* Number of allocated pages */ - u16 jited:1, /* Is our filter JIT'ed? */ + u32 jited:1, /* Is our filter JIT'ed? */ jit_requested:1,/* archs need to JIT the prog */ + jit_required:1, /* program strictly requires JIT compiler */ gpl_compatible:1, /* Is filter GPL compatible? */ cb_access:1, /* Is control block accessed? */ dst_needed:1, /* Do we need dst entry? */ @@ -2196,6 +2195,12 @@ static inline bool is_tracing_multi(enum bpf_attach_type type) type == BPF_TRACE_FSESSION_MULTI; } +static inline bool is_struct_ops_tramp(const struct bpf_tramp_nodes *fentry_nodes) +{ + return fentry_nodes->nr_nodes == 1 && + fentry_nodes->nodes[0]->link->type == BPF_LINK_TYPE_STRUCT_OPS; +} + #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 @@ -3146,7 +3151,7 @@ int btf_struct_access(struct bpf_verifier_log *log, bool btf_struct_ids_match(struct bpf_verifier_log *log, const struct btf *btf, u32 id, int off, const struct btf *need_btf, u32 need_type_id, - bool strict); + bool strict, bool walk_flex_arrays); int btf_distill_func_proto(struct bpf_verifier_log *log, struct btf *btf, @@ -3170,7 +3175,6 @@ const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog); void bpf_task_storage_free(struct task_struct *task); void bpf_cgrp_storage_free(struct cgroup *cgroup); -bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog); const struct btf_func_model * bpf_jit_find_kfunc_model(const struct bpf_prog *prog, const struct bpf_insn *insn); @@ -3509,11 +3513,6 @@ static inline void bpf_task_storage_free(struct task_struct *task) { } -static inline bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog) -{ - return false; -} - static inline const struct btf_func_model * bpf_jit_find_kfunc_model(const struct bpf_prog *prog, const struct bpf_insn *insn) @@ -4148,8 +4147,16 @@ static inline bool bpf_is_subprog(const struct bpf_prog *prog) } const struct bpf_line_info *bpf_find_linfo(const struct bpf_prog *prog, u32 insn_off); -void bpf_get_linfo_file_line(struct btf *btf, const struct bpf_line_info *linfo, - const char **filep, const char **linep, int *nump); +struct bpf_linfo_source { + const char *file; + const char *line; + u32 file_name_off; + int line_num; + int line_col; +}; + +void bpf_get_linfo_source(struct btf *btf, const struct bpf_line_info *linfo, + struct bpf_linfo_source *src); int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char **filep, const char **linep, int *nump); struct bpf_prog *bpf_prog_find_from_stack(void); @@ -4169,7 +4176,7 @@ bpf_prog_update_insn_ptrs(struct bpf_prog *prog, u32 *offsets, void *image) } #endif -static inline bool bpf_map_supports_cpu_flags(enum bpf_map_type map_type) +static inline bool bpf_map_is_percpu_map(enum bpf_map_type map_type) { switch (map_type) { case BPF_MAP_TYPE_PERCPU_ARRAY: @@ -4196,7 +4203,7 @@ static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 all return -EINVAL; if (flags & (BPF_F_CPU | BPF_F_ALL_CPUS)) { - if (!bpf_map_supports_cpu_flags(map->map_type)) + if (!bpf_map_is_percpu_map(map->map_type)) return -EINVAL; if ((flags & BPF_F_CPU) && (flags & BPF_F_ALL_CPUS)) return -EINVAL; diff --git a/include/linux/bpf_ksock.h b/include/linux/bpf_ksock.h new file mode 100644 index 000000000000..cb387fb75e43 --- /dev/null +++ b/include/linux/bpf_ksock.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2026 Isovalent */ + +#ifndef _BPF_KSOCK_H +#define _BPF_KSOCK_H + +#include <linux/types.h> +#include <linux/in.h> +#include <linux/in6.h> + +/** + * struct bpf_ksock_create_opts - BPF kernel socket creation parameters + * @family: Address family: AF_INET or AF_INET6. + * @type: Socket type: only SOCK_DGRAM supported for now. + * @protocol: Protocol number (e.g. IPPROTO_UDP), or 0 for the default protocol + * of the given type. + * @reserved: Must be zero. Reserved for future use. + */ +struct bpf_ksock_create_opts { + __u8 family; + __u8 type; + __u8 protocol; + __u8 reserved; +}; + +/** + * union bpf_ksock_addr - IPv4 or IPv6 socket address + * @sin: IPv4 socket address. + * @sin6: IPv6 socket address. + */ +union bpf_ksock_addr { + struct sockaddr_in sin; + struct sockaddr_in6 sin6; +}; + +#endif /* _BPF_KSOCK_H */ diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h index 143775a27a2a..dda272d78f01 100644 --- a/include/linux/bpf_lsm.h +++ b/include/linux/bpf_lsm.h @@ -14,6 +14,8 @@ #ifdef CONFIG_BPF_LSM +extern bool bpf_lsm_initialized __ro_after_init; + #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ RET bpf_lsm_##NAME(__VA_ARGS__); #include <linux/lsm_hook_defs.h> @@ -56,6 +58,8 @@ bool bpf_lsm_hook_returns_errno(u32 btf_id); #else /* !CONFIG_BPF_LSM */ +#define bpf_lsm_initialized false + static inline bool bpf_lsm_is_sleepable_hook(u32 btf_id) { return false; diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 39a851e690ec..5fad59fdab0d 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -15,7 +15,7 @@ * ensures that umax_value + (int)off + (int)size cannot overflow a u64. */ #define BPF_MAX_VAR_OFF (1 << 29) -/* Maximum variable size permitted for ARG_CONST_SIZE[_OR_ZERO]. This ensures +/* Maximum variable size permitted for ARG_MEM_SIZE[_OR_ZERO]. This ensures * that converting umax_value to int cannot overflow. */ #define BPF_MAX_VAR_SIZ (1 << 29) @@ -162,11 +162,6 @@ struct bpf_reg_state { * pointing to bpf_func_state. */ u32 frameno; - /* Tracks subreg definition. The stored value is the insn_idx of the - * writing insn. This is safe because subreg_def is used before any insn - * patching which only happens after main verification finished. - */ - s32 subreg_def; /* if (!precise && SCALAR_VALUE) min/max/tnum don't affect safety */ bool precise; }; @@ -359,6 +354,11 @@ struct bpf_func_state { * 0 = main function, 1 = first callee. */ u32 frameno; + /* + * Unique diagnostic identity for this function invocation. Frame depth is + * reused after returns, while this ID is preserved across state clones. + */ + u32 diag_frame_id; /* subprog number == index within subprog_info * zero == main subprog */ @@ -385,6 +385,8 @@ struct bpf_func_state { * | number of simulations is tracked in frame N */ u32 callback_depth; + /* Instructions processed in this frame and callees on the current path. */ + u32 insns_subtotal; /* The following fields should be last. See copy_func_state() */ /* The state of the stack. Each element of the array describes BPF_REG_SIZE @@ -803,7 +805,8 @@ 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; + u32 insns_total; + u32 insns_self; /* offsets in range [stack_depth .. fastcall_stack_off) * are used for bpf_fastcall spills and fills. */ @@ -835,6 +838,7 @@ static inline u16 bpf_in_stack_arg_cnt(const struct bpf_subprog_info *sub) return 0; } +struct bpf_diag; struct bpf_verifier_env; struct backtrack_state { @@ -898,6 +902,14 @@ struct bpf_scc_info { struct bpf_liveness; +struct bpf_fd_array { + union { + struct bpf_map *map; + struct btf *btf; + unsigned long val; + }; +}; + /* single container for all structs * one verifier_env per bpf_check() call */ @@ -939,9 +951,12 @@ struct bpf_verifier_env { bool bypass_spec_v4; bool seen_direct_write; bool seen_exception; + bool signature; + u32 insn_aux_data_len; struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ const struct bpf_line_info *prev_linfo; struct bpf_verifier_log log; + struct bpf_diag *diag; struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 2]; /* max + 2 for the fake and exception subprogs */ /* subprog indices sorted in topological order: leaves first, callers last */ int subprog_topo_order[BPF_MAX_SUBPROGS + 2]; @@ -989,7 +1004,19 @@ struct bpf_verifier_env { u32 free_list_size; u32 explored_states_size; u32 num_backedges; - bpfptr_t fd_array; + /* + * The program's fd_array comes in two shapes, told apart by whether + * the caller passed fd_array_cnt. They are mutually exclusive: + * - continuous (fd_array_cnt given): ->fd_array holds every entry + * resolved to its object up front, indexed by fd_array position, + * with ->fd_array_cnt slots; ->fd_array_raw is unused. + * - sparse (no fd_array_cnt): ->fd_array is NULL, and entries are + * read from ->fd_array_raw (the caller's fd_array) and resolved + * on the spot at each reference. + */ + struct bpf_fd_array *fd_array; + u32 fd_array_cnt; + bpfptr_t fd_array_raw; /* bit mask to keep track of whether a register has been accessed * since the last time the function state was printed @@ -1156,8 +1183,8 @@ static inline void bpf_trampoline_unpack_key(u64 key, u32 *obj_id, u32 *btf_id) *btf_id = key & 0x7FFFFFFF; } -int bpf_check_btf_info_early(struct bpf_verifier_env *env, - const union bpf_attr *attr, bpfptr_t uattr); +int bpf_prepare_btf_info(struct bpf_verifier_env *env, + const union bpf_attr *attr, bpfptr_t uattr); int bpf_check_btf_info(struct bpf_verifier_env *env, const union bpf_attr *attr, bpfptr_t uattr); @@ -1243,6 +1270,11 @@ static inline void bpf_bt_set_frame_slot(struct backtrack_state *bt, u32 frame, bt->stack_masks[frame] |= 1ull << slot; } +static inline void bpf_bt_set_frame_slot_mask(struct backtrack_state *bt, u32 frame, u64 mask) +{ + bt->stack_masks[frame] |= mask; +} + static inline void bt_set_frame_stack_arg_slot(struct backtrack_state *bt, u32 frame, u32 slot) { bt->stack_arg_masks[frame] |= 1 << slot; @@ -1276,7 +1308,37 @@ static inline u32 type_flag(u32 type) return type & ~BPF_BASE_TYPE_MASK; } -/* only use after check_attach_btf_id() */ +static inline bool bpf_is_ptr_to_mem_or_btf_id(enum bpf_reg_type type) +{ + switch (base_type(type)) { + case PTR_TO_MEM: + case PTR_TO_BTF_ID: + return true; + default: + return false; + } +} + +static inline bool bpf_may_fault_on_deref(enum bpf_reg_type type) +{ + /* + * The pointer types which must not be dereferenced without fault + * protection, that is, the ones bpf_convert_ctx_accesses() has to + * turn a BPF_LDX into a BPF_PROBE_MEM one for. + */ + return type == PTR_TO_BTF_ID || (type_flag(type) & PTR_UNTRUSTED); +} + +static inline bool bpf_prog_has_arena_ctx_arg(const struct bpf_prog *prog) +{ + int i; + + for (i = 0; i < prog->aux->ctx_arg_info_size; i++) + if (base_type(prog->aux->ctx_arg_info[i].reg_type) == PTR_TO_ARENA) + return true; + return false; +} + static inline enum bpf_prog_type resolve_prog_type(const struct bpf_prog *prog) { return (prog->type == BPF_PROG_TYPE_EXT && prog->aux->saved_dst_prog_type) ? @@ -1315,6 +1377,18 @@ static inline bool type_is_non_owning_ref(u32 type) return type_is_ptr_alloc_obj(type) && type_flag(type) & NON_OWN_REF; } +static inline bool type_is_map_ptr(enum bpf_reg_type type) +{ + switch (base_type(type)) { + case CONST_PTR_TO_MAP: + case PTR_TO_MAP_KEY: + case PTR_TO_MAP_VALUE: + return true; + default: + return false; + } +} + static inline bool type_is_pkt_pointer(enum bpf_reg_type type) { type = base_type(type); @@ -1399,8 +1473,10 @@ void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_verifie void print_insn_state(struct bpf_verifier_env *env, const struct bpf_verifier_state *vstate, u32 frameno); u32 bpf_vlog_alignment(u32 pos); +const char *bpf_disasm_kfunc_name(void *data, const struct bpf_insn *insn); struct bpf_subprog_info *bpf_find_containing_subprog(struct bpf_verifier_env *env, int off); +const char *bpf_subprog_name(const struct bpf_verifier_env *env, int subprog); int bpf_jmp_offset(struct bpf_insn *insn); struct bpf_iarray *bpf_insn_successors(struct bpf_verifier_env *env, u32 idx); void bpf_fmt_stack_mask(char *buf, ssize_t buf_sz, u64 stack_mask); @@ -1438,23 +1514,46 @@ struct ref_obj_desc { u8 cnt; }; -struct bpf_kfunc_call_arg_meta { - /* In parameters */ +/* + * A memory argument a call fills in. The verifier allows the stack to be uninitialized if + * the range is a known constant. Stack slots are marked as STACK_MISC by check_mem_access(). + */ +struct arg_raw_mem_desc { + u8 regno; + int size; +}; + +/* Size of PTR_TO_MEM returned, taken from a constant allocation-size argument */ +struct ret_mem_desc { + u32 size; + bool found; +}; + +/* A constant scalar argument; Populated by process_const_arg() */ +struct arg_constant_desc { + u64 value; + bool found; +}; + +struct bpf_call_arg_meta { + /* Common */ struct btf *btf; u32 func_id; - u32 kfunc_flags; - const struct btf_type *func_proto; - const char *func_name; - /* Out parameters */ + const struct bpf_func_proto *fn; u8 release_regno; - bool r0_rdonly; u32 ret_btf_id; - u64 r0_size; u32 subprogno; - struct { - u64 value; - bool found; - } arg_constant; + struct bpf_map_desc map; + struct bpf_dynptr_desc dynptr; + struct ref_obj_desc ref_obj; + struct ret_mem_desc ret_mem; + + /* Only set by kfunc */ + bool r0_rdonly; + u32 kfunc_flags; + const struct btf_type *func_proto; + const char *func_name; + struct arg_constant_desc arg_constant; /* arg_{btf,btf_id,owning_ref} are used by kfunc-specific handling, * generally to pass info about user-defined local kptr types to later @@ -1481,28 +1580,31 @@ struct bpf_kfunc_call_arg_meta { u8 spi; u8 frameno; } iter; - struct bpf_map_desc map; - struct bpf_dynptr_desc dynptr; - struct ref_obj_desc ref_obj; - u64 mem_size; + + /* Only set by helper */ + u64 msize_max_value; + s64 const_map_key; + struct btf *ret_btf; + struct btf_field *kptr_field; + struct arg_raw_mem_desc arg_raw_mem; }; int bpf_get_helper_proto(struct bpf_verifier_env *env, int func_id, const struct bpf_func_proto **ptr); int bpf_fetch_kfunc_arg_meta(struct bpf_verifier_env *env, s32 func_id, - s16 offset, struct bpf_kfunc_call_arg_meta *meta); + s16 offset, struct bpf_call_arg_meta *meta); bool bpf_is_async_callback_calling_insn(struct bpf_insn *insn); bool bpf_is_sync_callback_calling_insn(struct bpf_insn *insn); -static inline bool bpf_is_iter_next_kfunc(struct bpf_kfunc_call_arg_meta *meta) +static inline bool bpf_is_iter_next_kfunc(struct bpf_call_arg_meta *meta) { return meta->kfunc_flags & KF_ITER_NEXT; } -static inline bool bpf_is_kfunc_sleepable(struct bpf_kfunc_call_arg_meta *meta) +static inline bool bpf_is_kfunc_sleepable(struct bpf_call_arg_meta *meta) { return meta->kfunc_flags & KF_SLEEPABLE; } -bool bpf_is_kfunc_pkt_changing(struct bpf_kfunc_call_arg_meta *meta); +bool bpf_is_kfunc_pkt_changing(struct bpf_call_arg_meta *meta); struct bpf_iarray *bpf_iarray_realloc(struct bpf_iarray *old, size_t n_elem); int bpf_copy_insn_array_uniq(struct bpf_map *map, u32 start, u32 end, u32 *off); bool bpf_insn_is_cond_jump(u8 code); @@ -1566,6 +1668,7 @@ enum bpf_reg_arg_type { struct bpf_kfunc_desc { struct btf_func_model func_model; + struct bpf_func_proto proto; u32 func_id; s32 imm; u16 offset; @@ -1573,17 +1676,18 @@ struct bpf_kfunc_desc { }; struct bpf_kfunc_desc_tab { + u32 nr_descs; /* Sorted by func_id (BTF ID) and offset (fd_array offset) during * verification. JITs do lookups by bpf_insn, where func_id may not be * available, therefore at the end of verification do_misc_fixups() * sorts this by imm and offset. + * + * Grown one entry at a time by bpf_add_kfunc_call(). */ - struct bpf_kfunc_desc descs[MAX_KFUNC_DESCS]; - u32 nr_descs; + struct bpf_kfunc_desc descs[]; }; /* Functions exported from verifier.c, used by fixups.c */ -bool bpf_is_reg64(struct bpf_insn *insn, u32 regno, struct bpf_reg_state *reg, enum bpf_reg_arg_type t); void bpf_clear_insn_aux_data(struct bpf_verifier_env *env, int start, int len); void bpf_mark_subprog_exc_cb(struct bpf_verifier_env *env, int subprog); bool bpf_allow_tail_call_in_subprogs(struct bpf_verifier_env *env); @@ -1607,5 +1711,6 @@ int bpf_convert_ctx_accesses(struct bpf_verifier_env *env); int bpf_jit_subprogs(struct bpf_verifier_env *env); int bpf_fixup_call_args(struct bpf_verifier_env *env); int bpf_do_misc_fixups(struct bpf_verifier_env *env); +int bpf_insn_def32(struct bpf_prog *prog, struct bpf_insn *insn); #endif /* _LINUX_BPF_VERIFIER_H */ diff --git a/include/linux/btf.h b/include/linux/btf.h index 240401d9b25b..89d5a5c4f117 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -79,6 +79,7 @@ #define KF_ARENA_ARG1 (1 << 14) /* kfunc takes an arena pointer as its first argument */ #define KF_ARENA_ARG2 (1 << 15) /* kfunc takes an arena pointer as its second argument */ #define KF_IMPLICIT_ARGS (1 << 16) /* kfunc has implicit arguments supplied by the verifier */ +#define KF_SPINLOCK_SAFE (1 << 17) /* kfunc is allowed inside bpf_spin_lock-ed region */ /* * Tag marking a kernel function as a kfunc. This is meant to minimize the @@ -213,6 +214,7 @@ int btf_type_seq_show_flags(const struct btf *btf, u32 type_id, void *obj, */ int btf_type_snprintf_show(const struct btf *btf, u32 type_id, void *obj, char *buf, int len, u64 flags); +int btf_type_name_to_buf(const struct btf *btf, u32 type_id, char *buf, int len); int btf_get_fd_by_id(u32 id); u32 btf_obj_id(const struct btf *btf); @@ -235,6 +237,8 @@ int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec); bool btf_type_is_void(const struct btf_type *t); s32 btf_find_by_name_kind(const struct btf *btf, const char *name, u8 kind); s32 bpf_find_btf_id(const char *name, u32 kind, struct btf **btf_p); +struct btf *btf_get_module_btf(const struct module *module); +__u32 btf_relocate_id(const struct btf *btf, __u32 id); const struct btf_type *btf_type_skip_modifiers(const struct btf *btf, u32 id, u32 *res_id); const struct btf_type *btf_type_resolve_ptr(const struct btf *btf, @@ -578,6 +582,7 @@ const char *btf_str_by_offset(const struct btf *btf, u32 offset); struct btf *btf_parse_vmlinux(void); struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog); u32 *btf_kfunc_flags(const struct btf *btf, u32 kfunc_btf_id, const struct bpf_prog *prog); +int btf_kfunc_check_flag(const struct btf *btf, u32 kfunc_btf_id, u32 flag); bool btf_kfunc_is_allowed(const struct btf *btf, u32 kfunc_btf_id, const struct bpf_prog *prog); u32 *btf_kfunc_is_modify_return(const struct btf *btf, u32 kfunc_btf_id, const struct bpf_prog *prog); diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 8b23bc9a244c..fd2c7115c054 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -210,10 +210,6 @@ void bh_end_async_write(struct bio *bio); /* Things to do with metadata buffers list */ void mmb_mark_buffer_dirty(struct buffer_head *bh, struct mapping_metadata_bhs *mmb); -int mmb_fsync_noflush(struct file *file, struct mapping_metadata_bhs *mmb, - loff_t start, loff_t end, bool datasync); -int mmb_fsync(struct file *file, struct mapping_metadata_bhs *mmb, - loff_t start, loff_t end, bool datasync); void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len); static inline void clean_bdev_bh_alias(struct buffer_head *bh) diff --git a/include/linux/bvec.h b/include/linux/bvec.h index 92837e2743f1..fc566ee1c1ff 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h @@ -110,7 +110,7 @@ struct bvec_iter { /* * Current offset in the bvec entry pointed to by `bi_idx`. */ - unsigned int bi_bvec_done; + unsigned int bi_offset; } __packed __aligned(4); struct bvec_iter_all { @@ -135,14 +135,14 @@ mp_bvec_iter_page(const struct bio_vec *bvecs, const struct bvec_iter iter) static __always_inline unsigned int mp_bvec_iter_len(const struct bio_vec *bvecs, const struct bvec_iter iter) { - return min(__bvec_iter_bvec(bvecs, iter)->bv_len - iter.bi_bvec_done, + return min(__bvec_iter_bvec(bvecs, iter)->bv_len - iter.bi_offset, iter.bi_size); } static __always_inline unsigned int mp_bvec_iter_offset(const struct bio_vec *bvecs, const struct bvec_iter iter) { - return __bvec_iter_bvec(bvecs, iter)->bv_offset + iter.bi_bvec_done; + return __bvec_iter_bvec(bvecs, iter)->bv_offset + iter.bi_offset; } static __always_inline unsigned int @@ -204,7 +204,7 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv, } iter->bi_size -= bytes; - bytes += iter->bi_bvec_done; + bytes += iter->bi_offset; while (bytes && bytes >= bv[idx].bv_len) { bytes -= bv[idx].bv_len; @@ -212,7 +212,7 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv, } iter->bi_idx = idx; - iter->bi_bvec_done = bytes; + iter->bi_offset = bytes; return true; } @@ -223,13 +223,13 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv, static inline void bvec_iter_advance_single(const struct bio_vec *bv, struct bvec_iter *iter, unsigned int bytes) { - unsigned int done = iter->bi_bvec_done + bytes; + unsigned int done = iter->bi_offset + bytes; if (done == bv[iter->bi_idx].bv_len) { done = 0; iter->bi_idx++; } - iter->bi_bvec_done = done; + iter->bi_offset = done; iter->bi_size -= bytes; } diff --git a/include/linux/can/dev/peak_canfd.h b/include/linux/can/dev/peak_canfd.h index d3788a3d0942..056e0efa649f 100644 --- a/include/linux/can/dev/peak_canfd.h +++ b/include/linux/can/dev/peak_canfd.h @@ -3,7 +3,7 @@ * CAN driver for PEAK System micro-CAN based adapters * * Copyright (C) 2003-2025 PEAK System-Technik GmbH - * Author: Stéphane Grosjean <stephane.grosjean@hms-networks.com> + * Author: Stéphane Grosjean <s.grosjean@peak-system.fr> */ #ifndef PUCAN_H #define PUCAN_H diff --git a/include/linux/capability.h b/include/linux/capability.h index 37db92b3d6f8..f8532d92fcad 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -145,6 +145,7 @@ extern bool has_capability_noaudit(struct task_struct *t, int cap); extern bool has_ns_capability_noaudit(struct task_struct *t, struct user_namespace *ns, int cap); extern bool capable(int cap); +bool capable_noaudit(int cap); extern bool ns_capable(struct user_namespace *ns, int cap); extern bool ns_capable_noaudit(struct user_namespace *ns, int cap); extern bool ns_capable_setid(struct user_namespace *ns, int cap); @@ -167,6 +168,10 @@ static inline bool capable(int cap) { return true; } +static inline bool capable_noaudit(int cap) +{ + return true; +} static inline bool ns_capable(struct user_namespace *ns, int cap) { return true; diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h index f54770f110bc..715b026ad95b 100644 --- a/include/linux/cdx/cdx_bus.h +++ b/include/linux/cdx/cdx_bus.h @@ -11,7 +11,7 @@ #include <linux/device.h> #include <linux/list.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/cdx.h> #include <linux/msi.h> #define MAX_CDX_DEV_RESOURCES 4 diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 63e0e2aa1ce9..691e1bdece49 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -313,8 +313,6 @@ int ceph_wait_for_latest_osdmap(struct ceph_client *client, /* pagevec.c */ extern void ceph_release_page_vector(struct page **pages, int num_pages); -extern void ceph_put_page_vector(struct page **pages, int num_pages, - bool dirty); extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); extern void ceph_copy_from_page_vector(struct page **pages, void *data, diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index de2cd6238c2a..3754d697854b 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -527,7 +527,10 @@ struct cgroup { int nr_threaded_children; /* # of live threaded child cgroups */ - /* sequence number for cgroup.kill, serialized by css_set_lock. */ + /* + * Sequence number for cgroup.kill. Incremented with both cgroup_mutex + * and css_set_lock held. Readers hold either one. + */ unsigned int kill_seq; struct kernfs_node *kn; /* cgroup kernfs entry */ @@ -896,7 +899,7 @@ static inline void cgroup_threadgroup_change_begin(struct task_struct *tsk) * cgroup_threadgroup_change_end - threadgroup exclusion for cgroups * @tsk: target task * - * Counterpart of cgroup_threadcgroup_change_begin(). + * Counterpart of cgroup_threadgroup_change_begin(). */ static inline void cgroup_threadgroup_change_end(struct task_struct *tsk) { diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index f2aa46a4f871..5dfa915a630e 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -82,12 +82,38 @@ enum cgroup_lifetime_events { CGROUP_LIFETIME_OFFLINE, }; +/* + * Events on cgroup_task_notifier, data is struct cgroup_task_migrate_ctx. + * MIGRATING fires per task before the migration commits and an error return + * from the chain fails the migration, in which case tasks that were already + * notified receive MIGRATE_CANCELED. MIGRATED fires per task after the + * migration is committed and can't fail. Only migrations that change a task's + * dfl cgroup are reported. + */ +enum cgroup_task_events { + CGROUP_TASK_MIGRATING, + CGROUP_TASK_MIGRATED, + CGROUP_TASK_MIGRATE_CANCELED, +}; + +/* + * @src_dcgrp and @dst_dcgrp are @task's dfl cgroups before and after the + * migration. @src_dcgrp is NULL for CGROUP_TASK_MIGRATED as per-task sources + * are not tracked past the commit point. + */ +struct cgroup_task_migrate_ctx { + struct task_struct *task; + struct cgroup *src_dcgrp; + struct cgroup *dst_dcgrp; +}; + extern struct file_system_type cgroup_fs_type; extern struct cgroup_root cgrp_dfl_root; extern struct css_set init_css_set; extern struct mutex cgroup_mutex; extern spinlock_t css_set_lock; extern struct blocking_notifier_head cgroup_lifetime_notifier; +extern struct blocking_notifier_head cgroup_task_notifier; #define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys; #include <linux/cgroup_subsys.h> @@ -480,7 +506,7 @@ static inline void cgroup_unlock(void) rcu_read_lock_sched_held() || \ lockdep_is_held(&cgroup_mutex) || \ lockdep_is_held(&css_set_lock) || \ - ((task)->flags & PF_EXITING) || (__c)) + (data_race((task)->flags) & PF_EXITING) || (__c)) #else #define task_css_set_check(task, __c) \ rcu_dereference((task)->cgroups) @@ -624,6 +650,27 @@ static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp, } /** + * cgroup_common_ancestor - find common ancestor of two cgroups + * @a: first cgroup to find common ancestor of + * @b: second cgroup to find common ancestor of + * + * Find the first cgroup that is an ancestor of both @a and @b, if it exists + * and return a pointer to it. If such a cgroup doesn't exist, return NULL. + * + * This function is safe to call as long as both @a and @b are accessible. + */ +static inline struct cgroup *cgroup_common_ancestor(struct cgroup *a, + struct cgroup *b) +{ + int level; + + for (level = min(a->level, b->level); level >= 0; level--) + if (a->ancestors[level] == b->ancestors[level]) + return a->ancestors[level]; + return NULL; +} + +/** * task_under_cgroup_hierarchy - test task's membership of cgroup ancestry * @task: the task to be tested * @ancestor: possible ancestor of @task's cgroup diff --git a/include/linux/cgroup_dmem.h b/include/linux/cgroup_dmem.h index dd4869f1d736..c6cad9501770 100644 --- a/include/linux/cgroup_dmem.h +++ b/include/linux/cgroup_dmem.h @@ -14,8 +14,40 @@ struct dmem_cgroup_pool_state; /* Opaque definition of a cgroup region, used internally */ struct dmem_cgroup_region; +/** + * struct dmem_cgroup_ops - Operations for a dmem cgroup region. + * @reclaim: Optional callback invoked when dmem.max is set below the current + * usage of a pool. The driver should attempt to free at least + * @target_bytes from @pool. May be called multiple times if usage + * remains above the limit after returning. + * + * Return: 0 if some progress was made (even if less than + * @target_bytes was freed), -ENOSPC if no progress could be made + * (the caller will retry up to a bounded number of times), or + * another negative error code if a fatal error occurred (stops + * further reclaim attempts immediately). + */ +struct dmem_cgroup_ops { + int (*reclaim)(struct dmem_cgroup_pool_state *pool, + u64 target_bytes, void *priv); +}; + +/** + * struct dmem_cgroup_init - Initialization parameters for a dmem cgroup region. + * @size: Size of the region in bytes. + * @ops: Optional operations for this region. May be NULL. + * @reclaim_priv: Opaque pointer passed to @ops->reclaim. May be NULL. + */ +struct dmem_cgroup_init { + u64 size; + const struct dmem_cgroup_ops *ops; + void *reclaim_priv; +}; + #if IS_ENABLED(CONFIG_CGROUP_DMEM) -struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *name_fmt, ...) __printf(2,3); +struct dmem_cgroup_region * +dmem_cgroup_register_region(const struct dmem_cgroup_init *init, + const char *name_fmt, ...) __printf(2, 3); void dmem_cgroup_unregister_region(struct dmem_cgroup_region *region); int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size, struct dmem_cgroup_pool_state **ret_pool, @@ -24,11 +56,17 @@ void dmem_cgroup_uncharge(struct dmem_cgroup_pool_state *pool, u64 size); bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool, struct dmem_cgroup_pool_state *test_pool, bool ignore_low, bool *ret_hit_low); +bool dmem_cgroup_below_min(struct dmem_cgroup_pool_state *root, + struct dmem_cgroup_pool_state *test); +bool dmem_cgroup_below_low(struct dmem_cgroup_pool_state *root, + struct dmem_cgroup_pool_state *test); +struct dmem_cgroup_pool_state *dmem_cgroup_get_common_ancestor(struct dmem_cgroup_pool_state *a, + struct dmem_cgroup_pool_state *b); void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool); #else -static inline __printf(2,3) struct dmem_cgroup_region * -dmem_cgroup_register_region(u64 size, const char *name_fmt, ...) +static inline __printf(2, 3) struct dmem_cgroup_region * +dmem_cgroup_register_region(const struct dmem_cgroup_init *init, const char *name_fmt, ...) { return NULL; } @@ -59,6 +97,25 @@ bool dmem_cgroup_state_evict_valuable(struct dmem_cgroup_pool_state *limit_pool, return true; } +static inline bool dmem_cgroup_below_min(struct dmem_cgroup_pool_state *root, + struct dmem_cgroup_pool_state *test) +{ + return false; +} + +static inline bool dmem_cgroup_below_low(struct dmem_cgroup_pool_state *root, + struct dmem_cgroup_pool_state *test) +{ + return false; +} + +static inline +struct dmem_cgroup_pool_state *dmem_cgroup_get_common_ancestor(struct dmem_cgroup_pool_state *a, + struct dmem_cgroup_pool_state *b) +{ + return NULL; +} + static inline void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool) { } diff --git a/include/linux/cgroup_rdma.h b/include/linux/cgroup_rdma.h index 404e746552ca..9a5c9ee728e7 100644 --- a/include/linux/cgroup_rdma.h +++ b/include/linux/cgroup_rdma.h @@ -34,6 +34,7 @@ struct rdmacg_device { struct list_head dev_node; struct list_head rpools; char *name; + u32 index; }; /* diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index b01a38fef8cf..dc8e161f9c2c 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -6,31 +6,44 @@ #ifndef __LINUX_CLK_PROVIDER_H #define __LINUX_CLK_PROVIDER_H +#include <dt-bindings/clock/clock.h> #include <linux/of.h> #include <linux/of_clk.h> -/* - * flags used across common struct clk. these flags should only affect the - * top-level framework. custom flags for dealing with hardware specifics - * belong in struct clk_foo +/** + * DOC: clk framework flags * - * Please update clk_flags[] in drivers/clk/clk.c when making changes here! + * Flags used across common struct clk. These flags should only affect the + * top-level framework. Custom flags for dealing with hardware specifics + * belong in struct clk_foo. + * + * * CLK_SET_RATE_GATE - must be gated across rate change + * * CLK_SET_PARENT_GATE - must be gated across re-parent + * * CLK_SET_RATE_PARENT - propagate rate change up one level + * * CLK_IGNORE_UNUSED - do not gate even if unused + * * CLK_GET_RATE_NOCACHE - do not use the cached clk rate + * * CLK_SET_RATE_NO_REPARENT - don't re-parent on rate change + * * CLK_GET_ACCURACY_NOCACHE - do not use the cached clk accuracy + * * CLK_RECALC_NEW_RATES - recalc rates after notifications + * * CLK_SET_RATE_UNGATE - clock needs to run to set rate + * * CLK_IS_CRITICAL - do not gate, ever + * * CLK_OPS_PARENT_ENABLE - parents need enable during gate/ungate, set rate and re-parent + * * CLK_DUTY_CYCLE_PARENT - duty cycle call may be forwarded to the parent clock */ -#define CLK_SET_RATE_GATE BIT(0) /* must be gated across rate change */ -#define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */ -#define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ -#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ +/* Please update clk_flags[] in drivers/clk/clk.c when making changes here! */ +#define CLK_SET_RATE_GATE BIT(0) +#define CLK_SET_PARENT_GATE BIT(1) +#define CLK_SET_RATE_PARENT BIT(2) +#define CLK_IGNORE_UNUSED BIT(3) /* unused */ /* unused */ -#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ -#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ -#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ -#define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */ -#define CLK_SET_RATE_UNGATE BIT(10) /* clock needs to run to set rate */ -#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ -/* parents need enable during gate/ungate, set rate and re-parent */ +#define CLK_GET_RATE_NOCACHE BIT(6) +#define CLK_SET_RATE_NO_REPARENT BIT(7) +#define CLK_GET_ACCURACY_NOCACHE BIT(8) +#define CLK_RECALC_NEW_RATES BIT(9) +#define CLK_SET_RATE_UNGATE BIT(10) +#define CLK_IS_CRITICAL BIT(11) #define CLK_OPS_PARENT_ENABLE BIT(12) -/* duty cycle call may be forwarded to the parent clock */ #define CLK_DUTY_CYCLE_PARENT BIT(13) struct clk; @@ -84,6 +97,26 @@ struct clk_duty { unsigned int den; }; +enum clk_ssc_method { + CLK_SPREAD_NO = CLK_SSC_NO_SPREAD, + CLK_SPREAD_CENTER = CLK_SSC_CENTER_SPREAD, + CLK_SPREAD_UP = CLK_SSC_UP_SPREAD, + CLK_SPREAD_DOWN = CLK_SSC_DOWN_SPREAD, +}; + +/** + * struct clk_spread_spectrum - Structure encoding spread spectrum of a clock + * + * @modfreq_hz: Modulation frequency + * @spread_bp: Modulation percent in permyriad + * @method: Modulation method + */ +struct clk_spread_spectrum { + u32 modfreq_hz; + u32 spread_bp; + enum clk_ssc_method method; +}; + /** * struct clk_ops - Callback operations for hardware clocks; these are to * be provided by the clock implementation, and will be called by drivers @@ -174,6 +207,12 @@ struct clk_duty { * separately via calls to .set_parent and .set_rate. * Returns 0 on success, -EERROR otherwise. * + * @set_spread_spectrum: Optional callback used to configure the spread + * spectrum modulation frequency, percentage, and method + * to reduce EMI by spreading the clock frequency over a + * wider range. + * Returns 0 on success, -EERROR otherwise. + * * @recalc_accuracy: Recalculate the accuracy of this clock. The clock accuracy * is expressed in ppb (parts per billion). The parent accuracy is * an input parameter. @@ -249,6 +288,8 @@ struct clk_ops { int (*set_rate_and_parent)(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate, u8 index); + int (*set_spread_spectrum)(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf); unsigned long (*recalc_accuracy)(struct clk_hw *hw, unsigned long parent_accuracy); int (*get_phase)(struct clk_hw *hw); @@ -1152,13 +1193,16 @@ struct clk_fixed_factor { #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw) extern const struct clk_ops clk_fixed_factor_ops; +struct clk_hw * +__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, + const char *name, const char *parent_name, + const struct clk_hw *parent_hw, const struct clk_parent_data *pdata, + unsigned long flags, unsigned int mult, unsigned int div, + unsigned long acc, unsigned int fixflags, bool devm); struct clk *clk_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned int mult, unsigned int div); void clk_unregister_fixed_factor(struct clk *clk); -struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned int mult, unsigned int div); struct clk_hw *clk_hw_register_fixed_factor_fwname(struct device *dev, struct device_node *np, const char *name, const char *fw_name, unsigned long flags, unsigned int mult, unsigned int div); @@ -1170,9 +1214,6 @@ struct clk_hw *clk_hw_register_fixed_factor_index(struct device *dev, const char *name, unsigned int index, unsigned long flags, unsigned int mult, unsigned int div); void clk_hw_unregister_fixed_factor(struct clk_hw *hw); -struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev, - const char *name, const char *parent_name, unsigned long flags, - unsigned int mult, unsigned int div); struct clk_hw *devm_clk_hw_register_fixed_factor_fwname(struct device *dev, struct device_node *np, const char *name, const char *fw_name, unsigned long flags, unsigned int mult, unsigned int div); @@ -1184,13 +1225,45 @@ struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev, const char *name, unsigned int index, unsigned long flags, unsigned int mult, unsigned int div); -struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev, - const char *name, const struct clk_hw *parent_hw, - unsigned long flags, unsigned int mult, unsigned int div); - -struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev, - const char *name, const struct clk_hw *parent_hw, - unsigned long flags, unsigned int mult, unsigned int div); +#define clk_hw_register_fixed_factor(dev, name, parent_name, \ + flags, mult, div) \ + __clk_hw_register_fixed_factor((dev), NULL, (name), (parent_name), \ + NULL, NULL, (flags), (mult), (div), \ + 0, 0, false) +#define clk_hw_register_fixed_factor_pdata(dev, np, name, pdata, \ + flags, mult, div, acc, fixflags) \ + __clk_hw_register_fixed_factor((dev), (np), (name), NULL, NULL, \ + (pdata), (flags), (mult), (div), \ + (acc), (fixflags), false) +#define devm_clk_hw_register_fixed_factor(dev, name, parent_name, flags, \ + mult, div) \ + __clk_hw_register_fixed_factor((dev), NULL, (name), (parent_name), \ + NULL, NULL, (flags), (mult), (div), 0, \ + 0, true) +/** + * devm_clk_hw_register_fixed_factor_parent_hw - Register a fixed factor clock with + * pointer to parent clock + * @dev: device that is registering this clock + * @name: name of this clock + * @parent_hw: pointer to parent clk + * @flags: fixed factor flags + * @mult: multiplier + * @div: divider + * + * Return: Pointer to fixed factor clk_hw structure that was registered or + * an error pointer. + */ +#define devm_clk_hw_register_fixed_factor_parent_hw(dev, name, parent_hw, \ + flags, mult, div) \ + __clk_hw_register_fixed_factor((dev), NULL, (name), NULL, \ + (parent_hw), NULL, (flags), (mult), \ + (div), 0, 0, true) + +#define clk_hw_register_fixed_factor_parent_hw(dev, name, parent_hw, flags, \ + mult, div) \ + __clk_hw_register_fixed_factor((dev), NULL, (name), NULL, \ + (parent_hw), NULL, (flags), (mult), \ + (div), 0, 0, false) /** * struct clk_fractional_divider - adjustable fractional divider clock * @@ -1431,11 +1504,14 @@ int clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long flags); int clk_hw_determine_rate_no_reparent(struct clk_hw *hw, struct clk_rate_request *req); +int clk_determine_rate_noop(struct clk_hw *hw, struct clk_rate_request *req); void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent); void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate, unsigned long *max_rate); void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate, unsigned long max_rate); +int clk_hw_set_spread_spectrum(struct clk_hw *hw, + const struct clk_spread_spectrum *ss_conf); static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src) { diff --git a/include/linux/clk.h b/include/linux/clk.h index 998ba3f261da..db9cf184fd99 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -503,6 +503,22 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks, struct clk_bulk_data *clks); /** + * devm_clk_bulk_get_enable - Get and enable bulk clocks (managed) + * @dev: device for clock "consumer" + * @num_clks: the number of clk_bulk_data + * @clks: pointer to the clk_bulk_data table of consumer + * + * Behaves the same as devm_clk_bulk_get() but also prepares and enables the + * clocks in one operation with management. The clks will automatically be + * disabled, unprepared and freed when the device is unbound. + * + * Return: 0 if all clocks specified in clk_bulk_data table are obtained and + * enabled successfully. Otherwise returns valid IS_ERR() condition containing + * errno. + */ +int __must_check devm_clk_bulk_get_enable(struct device *dev, int num_clks, + struct clk_bulk_data *clks); +/** * devm_clk_bulk_get_optional_enable - Get and enable optional bulk clocks (managed) * @dev: device for clock "consumer" * @num_clks: the number of clk_bulk_data @@ -951,8 +967,8 @@ int clk_set_parent(struct clk *clk, struct clk *parent); * clk_get_parent - get the parent clock source for this clock * @clk: clock source * - * Returns struct clk corresponding to parent clock source, or - * valid IS_ERR() condition containing errno. + * Returns struct clk corresponding to parent clock source, or NULL + * if clk is NULL. */ struct clk *clk_get_parent(struct clk *clk); @@ -1052,6 +1068,13 @@ static inline int __must_check devm_clk_bulk_get_optional(struct device *dev, return 0; } +static inline int __must_check devm_clk_bulk_get_enable(struct device *dev, + int num_clks, + struct clk_bulk_data *clks) +{ + return 0; +} + static inline int __must_check devm_clk_bulk_get_optional_enable(struct device *dev, int num_clks, struct clk_bulk_data *clks) diff --git a/include/linux/clk/qcom.h b/include/linux/clk/qcom.h new file mode 100644 index 000000000000..11ac2d42ff9e --- /dev/null +++ b/include/linux/clk/qcom.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2026, Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __LINUX_CLK_QCOM_H +#define __LINUX_CLK_QCOM_H + +#include <linux/clk-provider.h> +#include <linux/errno.h> +#include <linux/kconfig.h> +#include <linux/regmap.h> +#include <linux/types.h> + +struct device; +struct platform_device; +struct regulator_bulk_data; + +/** + * struct qcom_clk_ref_desc - descriptor for a clkref_en gate clock + * @name: clock name exposed to the common clock framework + * @offset: clkref_en register offset from the block base + * @regulator_names: optional supply names enabled while preparing the clock + * @num_regulators: number of entries in @regulator_names + */ +struct qcom_clk_ref_desc { + const char *name; + u32 offset; + const char * const *regulator_names; + unsigned int num_regulators; +}; + +/** + * struct qcom_clk_ref - per-clock data for a clkref_en gate clock + * @hw: common clock framework hardware clock handle + * @regmap: register map backing the clkref_en register + * @desc: clock descriptor copied at registration time + * @regulators: optional bulk regulator handles for @desc.regulator_names + */ +struct qcom_clk_ref { + struct clk_hw hw; + struct regmap *regmap; + struct qcom_clk_ref_desc desc; + struct regulator_bulk_data *regulators; +}; + +#if IS_ENABLED(CONFIG_COMMON_CLK_QCOM) + +int qcom_clk_ref_probe(struct platform_device *pdev, + const struct regmap_config *config, + const struct qcom_clk_ref_desc * const *descs, + size_t num_clk_refs); + +#else + +static inline int +qcom_clk_ref_probe(struct platform_device *pdev, + const struct regmap_config *config, + const struct qcom_clk_ref_desc * const *descs, + size_t num_clk_refs) +{ + return -EOPNOTSUPP; +} + +#endif + +#endif diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h index 0949400f44de..c9495558cd5c 100644 --- a/include/linux/clk/renesas.h +++ b/include/linux/clk/renesas.h @@ -53,6 +53,9 @@ static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { } * various parameters used to configure a PLL. These limits ensure * the PLL operates within valid and stable ranges. * + * @input_fref: Reference input frequency to the PLL (in Hz). If set + * to 0, a default value of 24MHz is used. + * * @fout: Output frequency range (in MHz) * @fout.min: Minimum allowed output frequency * @fout.max: Maximum allowed output frequency @@ -78,6 +81,8 @@ static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { } * @k.max: Maximum delta-sigma value */ struct rzv2h_pll_limits { + u32 input_fref; + struct { u32 min; u32 max; @@ -184,28 +189,31 @@ struct rzv2h_pll_div_pars { .k = { .min = -32768, .max = 32767 }, \ } \ -#ifdef CONFIG_CLK_RZV2H -bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_pars *pars, u64 freq_millihz); +#ifdef CONFIG_CLK_RZV2H_CPG_LIB +bool rzv2h_cpg_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, u64 freq_millihz); -bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_div_pars *pars, - const u8 *table, u8 table_size, u64 freq_millihz); +bool rzv2h_cpg_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, u64 freq_millihz); #else -static inline bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_pars *pars, - u64 freq_millihz) +static inline bool rzv2h_cpg_get_pll_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_pars *pars, + u64 freq_millihz) { return false; } -static inline bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, - struct rzv2h_pll_div_pars *pars, - const u8 *table, u8 table_size, - u64 freq_millihz) +static inline bool rzv2h_cpg_get_pll_divs_pars(const struct rzv2h_pll_limits *limits, + struct rzv2h_pll_div_pars *pars, + const u8 *table, u8 table_size, + u64 freq_millihz) { return false; } #endif +#define rzv2h_get_pll_pars rzv2h_cpg_get_pll_pars +#define rzv2h_get_pll_divs_pars rzv2h_cpg_get_pll_divs_pars + #endif diff --git a/include/linux/codetag.h b/include/linux/codetag.h index ddae7484ca45..a25a085c2df1 100644 --- a/include/linux/codetag.h +++ b/include/linux/codetag.h @@ -77,6 +77,8 @@ struct codetag_iterator { void codetag_lock_module_list(struct codetag_type *cttype); bool codetag_trylock_module_list(struct codetag_type *cttype); void codetag_unlock_module_list(struct codetag_type *cttype); +unsigned long codetag_get_content_id(struct codetag_type *cttype); +unsigned int codetag_get_count(struct codetag_type *cttype); struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype); struct codetag *codetag_next_ct(struct codetag_iterator *iter); diff --git a/include/linux/compaction.h b/include/linux/compaction.h index f29ef0653546..66a2f70e9e01 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h @@ -58,6 +58,7 @@ enum compact_result { }; struct alloc_context; /* in mm/internal.h */ +struct capture_control; /* in mm/internal.h */ /* * Number of free order-0 pages that should be available above given watermark @@ -92,7 +93,7 @@ extern int fragmentation_index(struct zone *zone, unsigned int order); extern enum compact_result try_to_compact_pages(gfp_t gfp_mask, unsigned int order, unsigned int alloc_flags, const struct alloc_context *ac, enum compact_priority prio, - struct page **page); + struct capture_control *capc); extern void reset_isolation_suitable(pg_data_t *pgdat); extern bool compaction_suitable(struct zone *zone, int order, unsigned long watermark, int highest_zoneidx); diff --git a/include/linux/container_of.h b/include/linux/container_of.h index 1f6ebf27d962..28db38e9ee3e 100644 --- a/include/linux/container_of.h +++ b/include/linux/container_of.h @@ -17,11 +17,10 @@ * Do not use container_of() in new code. */ #define container_of(ptr, type, member) ({ \ - void *__mptr = (void *)(ptr); \ - static_assert(__same_type(*(ptr), ((type *)0)->member) || \ + static_assert(__same_type(*(ptr), typeof_member(type, member)) || \ __same_type(*(ptr), void), \ "pointer type mismatch in container_of()"); \ - ((type *)(__mptr - offsetof(type, member))); }) + (type *)((void *)(ptr) - offsetof(type, member)); }) /** * container_of_const - cast a member of a structure out to the containing diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index ae9d1ce4f49c..35ce665edfd8 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -379,6 +379,7 @@ struct cpufreq_driver { void (*adjust_perf)(struct cpufreq_policy *policy, unsigned long min_perf, unsigned long target_perf, + unsigned long max_perf, unsigned long capacity); /* @@ -624,6 +625,7 @@ unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy, void cpufreq_driver_adjust_perf(struct cpufreq_policy *policy, unsigned long min_perf, unsigned long target_perf, + unsigned long max_perf, unsigned long capacity); bool cpufreq_driver_has_adjust_perf(void); int cpufreq_driver_target(struct cpufreq_policy *policy, diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 0fb3a2a62eb0..feb32949aeea 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -180,7 +180,6 @@ enum cpuhp_state { CPUHP_AP_DUMMY_TIMER_STARTING, CPUHP_AP_ARM_XEN_STARTING, CPUHP_AP_ARM_XEN_RUNSTATE_STARTING, - CPUHP_AP_ARM_CORESIGHT_CTI_STARTING, CPUHP_AP_ARM64_ISNDEP_STARTING, CPUHP_AP_SMPCFD_DYING, CPUHP_AP_HRTIMERS_DYING, diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index d3cda0544954..4c8bb6953107 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -13,7 +13,6 @@ #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> @@ -1316,24 +1315,6 @@ static __always_inline bool cpu_dying(unsigned int cpu) #endif /* NR_CPUS > BITS_PER_LONG */ /** - * cpumap_print_to_pagebuf - copies the cpumask into the buffer either - * as comma-separated list of cpus or hex values of cpumask - * @list: indicates whether the cpumap must be list - * @mask: the cpumask to copy - * @buf: the buffer to copy into - * - * Return: the length of the (null-terminated) @buf string, zero if - * nothing is copied. - */ -static __always_inline ssize_t -cpumap_print_to_pagebuf(bool list, char *buf, const struct cpumask *mask) -{ - /* 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)); -} - -/** * cpumap_print_bitmask_to_buf - copies the cpumask into the buffer as * hex values of cpumask * diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index 65d76a38974b..914983387e95 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -80,10 +80,11 @@ extern void lockdep_assert_cpuset_lock_held(void); extern void cpuset_cpus_allowed_locked(struct task_struct *p, struct cpumask *mask); extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); extern bool cpuset_cpus_allowed_fallback(struct task_struct *p); +extern int cpuset_num_cpus(struct cgroup *cgroup); extern nodemask_t cpuset_mems_allowed(struct task_struct *p); #define cpuset_current_mems_allowed (current->mems_allowed) void cpuset_init_current_mems_allowed(void); -int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask); +int cpuset_nodemask_valid_mems_allowed(const nodemask_t *nodemask); extern bool cpuset_current_node_allowed(int node, gfp_t gfp_mask); @@ -216,6 +217,11 @@ static inline bool cpuset_cpus_allowed_fallback(struct task_struct *p) return false; } +static inline int cpuset_num_cpus(struct cgroup *cgroup) +{ + return num_online_cpus(); +} + static inline nodemask_t cpuset_mems_allowed(struct task_struct *p) { return node_possible_map; @@ -224,7 +230,7 @@ static inline nodemask_t cpuset_mems_allowed(struct task_struct *p) #define cpuset_current_mems_allowed (node_states[N_MEMORY]) static inline void cpuset_init_current_mems_allowed(void) {} -static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask) +static inline int cpuset_nodemask_valid_mems_allowed(const nodemask_t *nodemask) { return 1; } @@ -273,6 +279,7 @@ static inline void dl_rebuild_rd_accounting(void) static inline void rebuild_sched_domains(void) { + guard(cpus_read_lock)(); partition_sched_domains(1, NULL, NULL); } diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index c1dee3f971a9..bc087124cd78 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -59,6 +59,9 @@ extern int crash_exclude_mem_range(struct crash_mem *mem, unsigned long long mend); extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, void **addr, unsigned long *sz); +extern int crash_prepare_headers(int need_kernel_map, void **addr, + unsigned long *sz, unsigned long *nr_mem_ranges); +extern int crash_exclude_core_ranges(struct crash_mem **cmem); struct kimage; struct kexec_segment; @@ -76,6 +79,12 @@ int kexec_should_crash(struct task_struct *p); int kexec_crash_loaded(void); void crash_save_cpu(struct pt_regs *regs, int cpu); extern int kimage_crash_copy_vmcoreinfo(struct kimage *image); +extern unsigned int arch_get_system_nr_ranges(void); +extern int arch_crash_populate_cmem(struct crash_mem *cmem); +extern int arch_crash_exclude_ranges(struct crash_mem *cmem); +extern int arch_crash_exclude_mem_range(struct crash_mem **mem, + unsigned long long mstart, + unsigned long long mend); #else /* !CONFIG_CRASH_DUMP*/ struct pt_regs; diff --git a/include/linux/crash_reserve.h b/include/linux/crash_reserve.h index f0dc03d94ca2..30864d90d7f5 100644 --- a/include/linux/crash_reserve.h +++ b/include/linux/crash_reserve.h @@ -14,9 +14,11 @@ extern struct resource crashk_res; extern struct resource crashk_low_res; extern struct range crashk_cma_ranges[]; + +#define CRASHK_CMA_RANGES_MAX 4 #if defined(CONFIG_CMA) && defined(CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION) #define CRASHKERNEL_CMA -#define CRASHKERNEL_CMA_RANGES_MAX 4 +#define CRASHKERNEL_CMA_RANGES_MAX (CRASHK_CMA_RANGES_MAX) extern int crashk_cma_cnt; #else #define crashk_cma_cnt 0 diff --git a/include/linux/cred.h b/include/linux/cred.h index c6676265a985..6ef1750c93e2 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -371,7 +371,6 @@ DEFINE_FREE(put_cred, struct cred *, if (!IS_ERR_OR_NULL(_T)) put_cred(_T)) }) #define task_uid(task) (task_cred_xxx((task), uid)) -#define task_euid(task) (task_cred_xxx((task), euid)) #define task_ucounts(task) (task_cred_xxx((task), ucounts)) #define current_cred_xxx(xxx) \ diff --git a/include/linux/damon.h b/include/linux/damon.h index 6f7edb3590ef..0c8b7ddef9ab 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -1,8 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * DAMON api - * - * Author: SeongJae Park <sj@kernel.org> */ #ifndef _DAMON_H_ @@ -47,13 +45,11 @@ struct damon_size_range { * @ar: The address range of the region. * @sampling_addr: Address of the sample for the next access check. * @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. * - * For any use case, @ar should be non-zero positive size. + * For any use case, @ar should be non-zero positive size. damon_set_regions() + * does the validation. * * @nr_accesses is reset to zero for every &damon_attrs->aggr_interval and be * increased for every &damon_attrs->sample_interval if an access to the region @@ -61,13 +57,6 @@ struct damon_size_range { * not be done with direct access but with the helper function, * damon_update_region_access_rate(). * - * @nr_accesses_bp is another representation of @nr_accesses in basis point - * (1 in 10,000) that updated for every &damon_attrs->sample_interval in a - * manner similar to moving sum. By the algorithm, this value becomes - * @nr_accesses * 10000 for every &struct damon_attrs->aggr_interval. This can - * be used when the aggregation interval is too huge and therefore cannot wait - * for it before getting the access monitoring results. - * * @age is initially zero, increased for each aggregation interval, and reset * to zero again if the access frequency is significantly changed. If two * regions are merged into a new region, both @nr_accesses and @age of the new @@ -77,21 +66,19 @@ struct damon_region { struct damon_addr_range ar; 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; -/* private: Internal value for age calculation. */ +/* private: internal use only. */ + /* List head for siblings. */ + struct list_head list; + /* for age calculation. */ unsigned int last_nr_accesses; + unsigned char last_probe_hits[DAMON_MAX_PROBES]; }; /** * struct damon_target - Represents a monitoring target. * @pid: The PID of the virtual address space to monitor. - * @nr_regions: Number of monitoring target regions of this target. - * @regions_list: Head of the monitoring target regions of this target. - * @list: List head for siblings. * @obsolete: Whether the commit destination target is obsolete. * * Each monitoring context could have multiple targets. For example, a context @@ -105,10 +92,14 @@ struct damon_region { */ struct damon_target { struct pid *pid; + bool obsolete; +/* private: */ + /* Number of monitoring target regions of this target. */ unsigned int nr_regions; + /* Head of the monitoring target regions of this target. */ struct list_head regions_list; + /* List head for siblings. */ struct list_head list; - bool obsolete; }; /** @@ -184,10 +175,8 @@ enum damos_quota_goal_metric { * @metric: Metric to be used for representing the goal. * @target_value: Target value of @metric to achieve with the tuning. * @current_value: Current value of @metric. - * @last_psi_total: Last measured total PSI * @nid: Node id. * @memcg_id: Memcg id. - * @list: List head for siblings. * * Data structure for getting the current score of the quota tuning goal. The * score is calculated by how close @current_value and @target_value are. Then @@ -210,12 +199,17 @@ struct damos_quota_goal { unsigned long current_value; /* metric-dependent fields */ union { - u64 last_psi_total; struct { int nid; u64 memcg_id; }; +/* private: */ + /* Last measured total PSI */ + u64 last_psi_total; + }; +/* private: */ + /* List head for siblings. */ struct list_head list; }; @@ -234,7 +228,6 @@ enum damos_quota_goal_tuner { * @reset_interval: Charge reset interval in milliseconds. * @ms: Maximum milliseconds that the scheme can use. * @sz: Maximum bytes of memory that the action can be applied. - * @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. @@ -261,7 +254,7 @@ enum damos_quota_goal_tuner { * the scheme's action. DAMON then compares it against &sz and uses smaller * one as the effective quota. * - * If @goals is not empty, DAMON calculates yet another size quota based on the + * If goals is not empty, DAMON calculates yet another size quota based on the * goals using its internal feedback loop algorithm, for every @reset_interval. * Then, if the new size quota is smaller than the effective quota, it uses the * new size quota as the effective quota. @@ -282,7 +275,7 @@ struct damos_quota { unsigned long reset_interval; unsigned long ms; unsigned long sz; - struct list_head goals; + enum damos_quota_goal_tuner goal_tuner; unsigned long esz; @@ -294,6 +287,8 @@ struct damos_quota { unsigned int weight_age; /* private: */ + /* Head of quota tuning goals (&damos_quota_goal) list. */ + struct list_head goals; /* For throughput estimation */ unsigned long total_charged_sz; unsigned long total_charged_ns; @@ -403,16 +398,15 @@ struct damos_stat { * @DAMOS_FILTER_TYPE_TARGET: Data Access Monitoring target. * @NR_DAMOS_FILTER_TYPES: Number of filter types. * - * The anon pages type and memcg type filters are handled by underlying - * &struct damon_operations as a part of scheme action trying, and therefore - * accounted as 'tried'. In contrast, other types are handled by core layer - * before trying of the action and therefore not accounted as 'tried'. + * All types except &DAMOS_FILTER_TYPE_ADDR and &DAMOS_FILTER_TYPE_TARGET + * are handled by the underlying &struct damon_operations as a part of scheme + * action trying, and therefore accounted as 'tried'. In contrast, + * &DAMOS_FILTER_TYPE_ADDR and &DAMOS_FILTER_TYPE_TARGET filters are handled + * by the core layer before trying of the action, and therefore not accounted + * as 'tried'. * - * The support of the filters that handled by &struct damon_operations depend - * on the running &struct damon_operations. - * &enum DAMON_OPS_PADDR supports both anon pages type and memcg type filters, - * while &enum DAMON_OPS_VADDR and &enum DAMON_OPS_FVADDR don't support any of - * the two types. + * Support for the operations-handled filters depends on the running + * &struct damon_operations. */ enum damos_filter_type { DAMOS_FILTER_TYPE_ANON, @@ -437,7 +431,6 @@ enum damos_filter_type { * &damon_ctx->adaptive_targets if @type is * DAMOS_FILTER_TYPE_TARGET. * @sz_range: Size range if @type is DAMOS_FILTER_TYPE_HUGEPAGE_SIZE. - * @list: List head for siblings. * * Before applying the &damos->action to a memory region, DAMOS checks if each * byte of the region matches to this given condition and avoid applying the @@ -455,6 +448,8 @@ struct damos_filter { int target_idx; struct damon_size_range sz_range; }; +/* private: */ + /* List head for siblings. */ struct list_head list; }; @@ -526,12 +521,8 @@ struct damos_migrate_dests { * @wmarks: Watermarks for automated (in)activation of this scheme. * @migrate_dests: Destination nodes if @action is "migrate_{hot,cold}". * @target_nid: Destination node if @action is "migrate_{hot,cold}". - * @core_filters: Additional set of &struct damos_filter for &action. - * @ops_filters: ops layer handling &struct damos_filter objects list. - * @last_applied: Last @action applied ops-managing entity. * @stat: Statistics of this scheme. * @max_nr_snapshots: Upper limit of nr_snapshots stat. - * @list: List head for siblings. * * For each @apply_interval_us, DAMON finds regions which fit in the * &pattern and applies &action to those. To avoid consuming too much @@ -553,16 +544,7 @@ struct damos_migrate_dests { * * Before applying the &action to a memory region, &struct damon_operations * implementation could check pages of the region and skip &action to respect - * &core_filters - * - * The minimum entity that @action can be applied depends on the underlying - * &struct damon_operations. Since it may not be aligned with the core layer - * abstract, namely &struct damon_region, &struct damon_operations could apply - * @action to same entity multiple times. Large folios that underlying on - * multiple &struct damon region objects could be such examples. The &struct - * damon_operations can use @last_applied to avoid that. DAMOS core logic - * unsets @last_applied when each regions walking for applying the scheme is - * finished. + * &struct damos_filter. * * After applying the &action to each region, &stat is updated. * @@ -573,6 +555,16 @@ struct damos { struct damos_access_pattern pattern; enum damos_action action; unsigned long apply_interval_us; + struct damos_quota quota; + struct damos_watermarks wmarks; + union { + struct { + int target_nid; + struct damos_migrate_dests migrate_dests; + }; + }; + struct damos_stat stat; + unsigned long max_nr_snapshots; /* private: internal use only */ /* * number of sample intervals that should be passed before applying @@ -589,20 +581,25 @@ struct damos { /* whether to reject core/ops filters umatched regions */ bool core_filters_default_reject; bool ops_filters_default_reject; -/* public: */ - struct damos_quota quota; - struct damos_watermarks wmarks; - union { - struct { - int target_nid; - struct damos_migrate_dests migrate_dests; - }; - }; + /* Additional set of &struct damos_filter for &action. */ struct list_head core_filters; + /* ops layer handling &struct damos_filter objects list. */ struct list_head ops_filters; + /* + * Last @action applied ops-managing entity. + * + * The minimum entity that @action can be applied depends on the + * underlying &struct damon_operations. Since it may not be aligned + * with the core layer abstract, namely &struct damon_region, &struct + * damon_operations could apply @action to same entity multiple times. + * Large folios that underlying on multiple &struct damon region + * objects could be such examples. The &struct damon_operations can + * use @last_applied to avoid that. DAMOS core logic unsets + * @last_applied when each regions walking for applying the scheme is + * finished. + */ void *last_applied; - struct damos_stat stat; - unsigned long max_nr_snapshots; + /* List head for siblings. */ struct list_head list; }; @@ -658,7 +655,10 @@ enum damon_ops_id { * 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. + * accordingly update the probe hits counter of the region. It should also + * set &damon_region->sampling_addr of each region if ``set_samples`` is true. + * It should also return maximum probe hits weighted sum of regions if + * ``return_max_wsum`` is true. * @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 @@ -676,7 +676,8 @@ 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); + unsigned int (*apply_probes)(struct damon_ctx *context, + bool set_samples, bool return_max_wsum); int (*get_scheme_score)(struct damon_ctx *context, struct damon_region *r, struct damos *scheme); unsigned long (*apply_scheme)(struct damon_ctx *context, @@ -756,7 +757,6 @@ enum damon_filter_type { * @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; @@ -765,17 +765,22 @@ struct damon_filter { union { u64 memcg_id; }; +/* private: */ + /* Siblings list. */ 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. + * @weight: Relative priority of the attribute for this probe. */ struct damon_probe { + unsigned int weight; +/* private: */ + /* Filters for assessing if a given region is for this probe. */ struct list_head filters; + /* Siblings list. */ struct list_head list; }; @@ -842,12 +847,9 @@ struct damon_attrs { * thread other than the kdamond should be made using safe DAMON APIs, * including damon_call() and damos_walk(). * - * @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. */ struct damon_ctx { struct damon_attrs attrs; @@ -896,16 +898,21 @@ struct damon_ctx { struct mutex kdamond_lock; /* public: */ - struct damon_operations ops; - struct list_head probes; unsigned long addr_unit; unsigned long min_region_sz; bool pause; +/* private: */ + /* Set of monitoring operations for given use cases. */ + struct damon_operations ops; + /* Head of monitoring targets (&damon_target) list. */ struct list_head adaptive_targets; + /* Head of probes (&damon_probe) list. */ + struct list_head probes; + /* Head of schemes (&damos) list. */ struct list_head schemes; - /* Per-ctx PRNG state for damon_rand(); kdamond is the sole consumer. */ + /* @rnd_state: Per-ctx PRNG state for damon_rand(). */ struct rnd_state rnd_state; }; @@ -1012,11 +1019,16 @@ 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); +unsigned int damon_nr_accesses_mvsum(struct damon_region *r, + struct damon_ctx *ctx); +unsigned char damon_probe_hits_mvsum(int probe_idx, struct damon_region *r, + struct damon_ctx *ctx); +unsigned int damon_probe_hits_wsum(struct damon_region *r, bool last, + struct damon_ctx *ctx); 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, - struct damon_attrs *attrs); +void damon_update_region_access_rate(struct damon_region *r, bool accessed); struct damos_filter *damos_new_filter(enum damos_filter_type type, bool matching, bool allow); @@ -1063,17 +1075,23 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx) return ctx->ops.id == DAMON_OPS_VADDR || ctx->ops.id == DAMON_OPS_FVADDR; } -static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs) +/* Returns number of samples per aggregation interval */ +static inline unsigned int damon_nr_samples_per_aggr( + const struct damon_attrs *attrs) { - /* {aggr,sample}_interval are unsigned long, hence could overflow */ - return min(attrs->aggr_interval / attrs->sample_interval, + unsigned long sample_interval; + unsigned long nr_samples; + + sample_interval = attrs->sample_interval ? : 1; + nr_samples = min(attrs->aggr_interval / sample_interval, (unsigned long)UINT_MAX); + return nr_samples ? : 1; } bool damon_initialized(void); int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive); -int damon_stop(struct damon_ctx **ctxs, int nr_ctxs); +void damon_stop(struct damon_ctx **ctxs, int nr_ctxs); bool damon_is_running(struct damon_ctx *ctx); int damon_kdamond_pid(struct damon_ctx *ctx); diff --git a/include/linux/delay.h b/include/linux/delay.h index 68b2a69dd24d..82409e55b6ae 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -17,6 +17,8 @@ extern unsigned long loops_per_jiffy; #include <asm/delay.h> +bool delay_read_timer(unsigned long *t); + /* * Using udelay() for intervals greater than a few milliseconds can * risk overflow for high loops_per_jiffy (high bogomips) machines. The diff --git a/include/linux/designware_i2c.h b/include/linux/designware_i2c.h new file mode 100644 index 000000000000..53f37f18a722 --- /dev/null +++ b/include/linux/designware_i2c.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Synopsys DesignWare I2C register definitions + * + * Copyright (C) 2026, Intel Corporation + */ + +#ifndef __LINUX_DESIGNWARE_I2C_H +#define __LINUX_DESIGNWARE_I2C_H + +#include <linux/bits.h> + +/* + * Registers offset + */ +#define DW_IC_CON 0x00 +#define DW_IC_TAR 0x04 +#define DW_IC_SAR 0x08 +#define DW_IC_DATA_CMD 0x10 +#define DW_IC_SS_SCL_HCNT 0x14 +#define DW_IC_SS_SCL_LCNT 0x18 +#define DW_IC_FS_SCL_HCNT 0x1c +#define DW_IC_FS_SCL_LCNT 0x20 +#define DW_IC_HS_SCL_HCNT 0x24 +#define DW_IC_HS_SCL_LCNT 0x28 +#define DW_IC_INTR_STAT 0x2c +#define DW_IC_INTR_MASK 0x30 +#define DW_IC_RAW_INTR_STAT 0x34 +#define DW_IC_RX_TL 0x38 +#define DW_IC_TX_TL 0x3c +#define DW_IC_CLR_INTR 0x40 +#define DW_IC_CLR_RX_UNDER 0x44 +#define DW_IC_CLR_RX_OVER 0x48 +#define DW_IC_CLR_TX_OVER 0x4c +#define DW_IC_CLR_RD_REQ 0x50 +#define DW_IC_CLR_TX_ABRT 0x54 +#define DW_IC_CLR_RX_DONE 0x58 +#define DW_IC_CLR_ACTIVITY 0x5c +#define DW_IC_CLR_STOP_DET 0x60 +#define DW_IC_CLR_START_DET 0x64 +#define DW_IC_CLR_GEN_CALL 0x68 +#define DW_IC_ENABLE 0x6c +#define DW_IC_STATUS 0x70 +#define DW_IC_TXFLR 0x74 +#define DW_IC_RXFLR 0x78 +#define DW_IC_SDA_HOLD 0x7c +#define DW_IC_TX_ABRT_SOURCE 0x80 +#define DW_IC_ENABLE_STATUS 0x9c +#define DW_IC_CLR_RESTART_DET 0xa8 +#define DW_IC_SMBUS_INTR_STAT 0xc8 +#define DW_IC_SMBUS_INTR_MASK 0xcc +#define DW_IC_CLR_SMBUS_INTR 0xd4 +#define DW_IC_COMP_PARAM_1 0xf4 +#define DW_IC_COMP_VERSION 0xf8 +#define DW_IC_COMP_TYPE 0xfc + +/* DW_IC_CON bits */ +#define DW_IC_CON_MASTER BIT(0) +#define DW_IC_CON_SPEED_STD (1 << 1) +#define DW_IC_CON_SPEED_FAST (2 << 1) +#define DW_IC_CON_SPEED_HIGH (3 << 1) +#define DW_IC_CON_SPEED_MASK GENMASK(2, 1) +#define DW_IC_CON_10BITADDR_SLAVE BIT(3) +#define DW_IC_CON_10BITADDR_MASTER BIT(4) +#define DW_IC_CON_RESTART_EN BIT(5) +#define DW_IC_CON_SLAVE_DISABLE BIT(6) +#define DW_IC_CON_STOP_DET_IFADDRESSED BIT(7) +#define DW_IC_CON_TX_EMPTY_CTRL BIT(8) +#define DW_IC_CON_RX_FIFO_FULL_HLD_CTRL BIT(9) +#define DW_IC_CON_BUS_CLEAR_CTRL BIT(11) + +/* DW_IC_DATA_CMD bits */ +#define DW_IC_DATA_CMD_DAT GENMASK(7, 0) +#define DW_IC_DATA_CMD_FIRST_DATA_BYTE BIT(11) + +/* DW_IC_INTR_* bits */ +#define DW_IC_INTR_RX_UNDER BIT(0) +#define DW_IC_INTR_RX_OVER BIT(1) +#define DW_IC_INTR_RX_FULL BIT(2) +#define DW_IC_INTR_TX_OVER BIT(3) +#define DW_IC_INTR_TX_EMPTY BIT(4) +#define DW_IC_INTR_RD_REQ BIT(5) +#define DW_IC_INTR_TX_ABRT BIT(6) +#define DW_IC_INTR_RX_DONE BIT(7) +#define DW_IC_INTR_ACTIVITY BIT(8) +#define DW_IC_INTR_STOP_DET BIT(9) +#define DW_IC_INTR_START_DET BIT(10) +#define DW_IC_INTR_GEN_CALL BIT(11) +#define DW_IC_INTR_RESTART_DET BIT(12) +#define DW_IC_INTR_MST_ON_HOLD BIT(13) + +/* DW_IC_ENABLE bits */ +#define DW_IC_ENABLE_ENABLE BIT(0) +#define DW_IC_ENABLE_ABORT BIT(1) + +/* DW_IC_STATUS bits */ +#define DW_IC_STATUS_ACTIVITY BIT(0) +#define DW_IC_STATUS_TFE BIT(2) +#define DW_IC_STATUS_RFNE BIT(3) +#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) +#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) +#define DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY BIT(7) + +/* DW_IC_SMBUS_INTR_* bits */ +#define DW_IC_SMBUS_INTR_ALERT BIT(10) + +#endif /* __LINUX_DESIGNWARE_I2C_H */ diff --git a/include/linux/device-id/acpi.h b/include/linux/device-id/acpi.h new file mode 100644 index 000000000000..65800cefddca --- /dev/null +++ b/include/linux/device-id/acpi.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_ACPI_H +#define LINUX_DEVICE_ID_ACPI_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define ACPI_ID_LEN 16 + +struct acpi_device_id { + __u8 id[ACPI_ID_LEN]; + kernel_ulong_t driver_data; + __u32 cls; + __u32 cls_msk; +}; + +/** + * ACPI_DEVICE_CLASS - macro used to describe an ACPI device with + * the PCI-defined class-code information + * + * @_cls : the class, subclass, prog-if triple for this device + * @_msk : the class mask for this device + * + * This macro is used to create a struct acpi_device_id that matches a + * specific PCI class. The .id and .driver_data fields will be left + * initialized with the default value. + */ +#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk), + +#endif /* ifndef LINUX_DEVICE_ID_ACPI_H */ diff --git a/include/linux/device-id/amba.h b/include/linux/device-id/amba.h new file mode 100644 index 000000000000..114d66a784ac --- /dev/null +++ b/include/linux/device-id/amba.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_AMBA_H +#define LINUX_DEVICE_ID_AMBA_H + +/** + * struct amba_id - identifies a device on an AMBA bus + * @id: The significant bits if the hardware device ID + * @mask: Bitmask specifying which bits of the id field are significant when + * matching. A driver binds to a device when ((hardware device ID) & mask) + * == id. + * @data: Private data used by the driver. + */ +struct amba_id { + unsigned int id; + unsigned int mask; + void *data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_AMBA_H */ diff --git a/include/linux/device-id/ap.h b/include/linux/device-id/ap.h new file mode 100644 index 000000000000..0992333a34db --- /dev/null +++ b/include/linux/device-id/ap.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_AP_H +#define LINUX_DEVICE_ID_AP_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define AP_DEVICE_ID_MATCH_CARD_TYPE 0x01 +#define AP_DEVICE_ID_MATCH_QUEUE_TYPE 0x02 + +/* s390 AP bus devices */ +struct ap_device_id { + __u16 match_flags; /* which fields to match against */ + __u8 dev_type; /* device type */ + kernel_ulong_t driver_info; +}; + +#endif /* ifndef LINUX_DEVICE_ID_AP_H */ diff --git a/include/linux/device-id/apr.h b/include/linux/device-id/apr.h new file mode 100644 index 000000000000..f282608ea018 --- /dev/null +++ b/include/linux/device-id/apr.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_APR_H +#define LINUX_DEVICE_ID_APR_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define APR_NAME_SIZE 32 +#define APR_MODULE_PREFIX "apr:" + +struct apr_device_id { + char name[APR_NAME_SIZE]; + __u32 domain_id; + __u32 svc_id; + __u32 svc_version; + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_APR_H */ diff --git a/include/linux/device-id/auxiliary.h b/include/linux/device-id/auxiliary.h new file mode 100644 index 000000000000..9d512dfb23dd --- /dev/null +++ b/include/linux/device-id/auxiliary.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_AUXILIARY_H +#define LINUX_DEVICE_ID_AUXILIARY_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +#define AUXILIARY_NAME_SIZE 40 +#define AUXILIARY_MODULE_PREFIX "auxiliary:" + +struct auxiliary_device_id { + char name[AUXILIARY_NAME_SIZE]; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_AUXILIARY_H */ diff --git a/include/linux/device-id/bcma.h b/include/linux/device-id/bcma.h new file mode 100644 index 000000000000..3e6b973dc4ae --- /dev/null +++ b/include/linux/device-id/bcma.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_BCMA_H +#define LINUX_DEVICE_ID_BCMA_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define BCMA_CORE(_manuf, _id, _rev, _class) \ + { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, } + +#define BCMA_ANY_MANUF 0xFFFF +#define BCMA_ANY_ID 0xFFFF +#define BCMA_ANY_REV 0xFF +#define BCMA_ANY_CLASS 0xFF + +/* Broadcom's specific AMBA core, see drivers/bcma/ */ +struct bcma_device_id { + __u16 manuf; + __u16 id; + __u8 rev; + __u8 class; +} __attribute__((packed,aligned(2))); + +#endif /* ifndef LINUX_DEVICE_ID_BCMA_H */ diff --git a/include/linux/device-id/ccw.h b/include/linux/device-id/ccw.h new file mode 100644 index 000000000000..6b7086aa5ca8 --- /dev/null +++ b/include/linux/device-id/ccw.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_CCW_H +#define LINUX_DEVICE_ID_CCW_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define CCW_DEVICE_ID_MATCH_CU_TYPE 0x01 +#define CCW_DEVICE_ID_MATCH_CU_MODEL 0x02 +#define CCW_DEVICE_ID_MATCH_DEVICE_TYPE 0x04 +#define CCW_DEVICE_ID_MATCH_DEVICE_MODEL 0x08 + +/* s390 CCW devices */ +struct ccw_device_id { + __u16 match_flags; /* which fields to match against */ + + __u16 cu_type; /* control unit type */ + __u16 dev_type; /* device type */ + __u8 cu_model; /* control unit model */ + __u8 dev_model; /* device model */ + + kernel_ulong_t driver_info; +}; + +#endif /* ifndef LINUX_DEVICE_ID_CCW_H */ diff --git a/include/linux/device-id/cdx.h b/include/linux/device-id/cdx.h new file mode 100644 index 000000000000..c6cb2b5cab5a --- /dev/null +++ b/include/linux/device-id/cdx.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_CDX_H +#define LINUX_DEVICE_ID_CDX_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define CDX_ANY_ID (0xFFFF) + +enum { + CDX_ID_F_VFIO_DRIVER_OVERRIDE = 1, +}; + +/** + * struct cdx_device_id - CDX device identifier + * @vendor: Vendor ID + * @device: Device ID + * @subvendor: Subsystem vendor ID (or CDX_ANY_ID) + * @subdevice: Subsystem device ID (or CDX_ANY_ID) + * @class: Device class + * Most drivers do not need to specify class/class_mask + * as vendor/device is normally sufficient. + * @class_mask: Limit which sub-fields of the class field are compared. + * @override_only: Match only when dev->driver_override is this driver. + * + * Type of entries in the "device Id" table for CDX devices supported by + * a CDX device driver. + */ +struct cdx_device_id { + __u16 vendor; + __u16 device; + __u16 subvendor; + __u16 subdevice; + __u32 class; + __u32 class_mask; + __u32 override_only; +}; + +#endif /* ifndef LINUX_DEVICE_ID_CDX_H */ diff --git a/include/linux/device-id/coreboot.h b/include/linux/device-id/coreboot.h new file mode 100644 index 000000000000..ff459879781e --- /dev/null +++ b/include/linux/device-id/coreboot.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_COREBOOT_H +#define LINUX_DEVICE_ID_COREBOOT_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/** + * struct coreboot_device_id - Identifies a coreboot table entry + * @tag: tag ID + * @driver_data: driver specific data + */ +struct coreboot_device_id { + __u32 tag; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_COREBOOT_H */ diff --git a/include/linux/device-id/css.h b/include/linux/device-id/css.h new file mode 100644 index 000000000000..67435bb22618 --- /dev/null +++ b/include/linux/device-id/css.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_CSS_H +#define LINUX_DEVICE_ID_CSS_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* s390 css bus devices (subchannels) */ +struct css_device_id { + __u8 match_flags; + __u8 type; /* subchannel type */ + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_CSS_H */ diff --git a/include/linux/device-id/dfl.h b/include/linux/device-id/dfl.h new file mode 100644 index 000000000000..bd0c9dbafeeb --- /dev/null +++ b/include/linux/device-id/dfl.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_DFL_H +#define LINUX_DEVICE_ID_DFL_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* + * DFL (Device Feature List) + * + * DFL defines a linked list of feature headers within the device MMIO space to + * provide an extensible way of adding features. Software can walk through these + * predefined data structures to enumerate features. It is now used in the FPGA. + * See Documentation/fpga/dfl.rst for more information. + * + * The dfl bus type is introduced to match the individual feature devices (dfl + * devices) for specific dfl drivers. + */ + +/** + * struct dfl_device_id - dfl device identifier + * @type: DFL FIU type of the device. See enum dfl_id_type. + * @feature_id: feature identifier local to its DFL FIU type. + * @driver_data: driver specific data. + */ +struct dfl_device_id { + __u16 type; + __u16 feature_id; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_DFL_H */ diff --git a/include/linux/device-id/dmi.h b/include/linux/device-id/dmi.h new file mode 100644 index 000000000000..fdc4adbad133 --- /dev/null +++ b/include/linux/device-id/dmi.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_DMI_H +#define LINUX_DEVICE_ID_DMI_H + +#define DMI_MATCH(a, b) { .slot = a, .substr = b } +#define DMI_EXACT_MATCH(a, b) { .slot = a, .substr = b, .exact_match = 1 } + +/* dmi */ +enum dmi_field { + DMI_NONE, + DMI_BIOS_VENDOR, + DMI_BIOS_VERSION, + DMI_BIOS_DATE, + DMI_BIOS_RELEASE, + DMI_EC_FIRMWARE_RELEASE, + DMI_SYS_VENDOR, + DMI_PRODUCT_NAME, + DMI_PRODUCT_VERSION, + DMI_PRODUCT_SERIAL, + DMI_PRODUCT_UUID, + DMI_PRODUCT_SKU, + DMI_PRODUCT_FAMILY, + DMI_BOARD_VENDOR, + DMI_BOARD_NAME, + DMI_BOARD_VERSION, + DMI_BOARD_SERIAL, + DMI_BOARD_ASSET_TAG, + DMI_CHASSIS_VENDOR, + DMI_CHASSIS_TYPE, + DMI_CHASSIS_VERSION, + DMI_CHASSIS_SERIAL, + DMI_CHASSIS_ASSET_TAG, + DMI_STRING_MAX, + DMI_OEM_STRING, /* special case - will not be in dmi_ident */ +}; + +struct dmi_strmatch { + unsigned char slot:7; + unsigned char exact_match:1; + char substr[79]; +}; + +struct dmi_system_id { + int (*callback)(const struct dmi_system_id *); + const char *ident; + struct dmi_strmatch matches[4]; + void *driver_data; +}; + +/* + * struct dmi_device_id appears during expansion of + * "MODULE_DEVICE_TABLE(dmi, x)". Compiler doesn't look inside it + * but this is enough for gcc 3.4.6 to error out: + * error: storage size of '__mod_dmi_device_table' isn't known + */ +#define dmi_device_id dmi_system_id + +#endif /* ifndef LINUX_DEVICE_ID_DMI_H */ diff --git a/include/linux/device-id/eisa.h b/include/linux/device-id/eisa.h new file mode 100644 index 000000000000..1eeae6247524 --- /dev/null +++ b/include/linux/device-id/eisa.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_EISA_H +#define LINUX_DEVICE_ID_EISA_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +/* EISA */ + +#define EISA_SIG_LEN 8 + +/* The EISA signature, in ASCII form, null terminated */ +struct eisa_device_id { + char sig[EISA_SIG_LEN]; + kernel_ulong_t driver_data; +}; + +#define EISA_DEVICE_MODALIAS_FMT "eisa:s%s" + +#endif /* ifndef LINUX_DEVICE_ID_EISA_H */ diff --git a/include/linux/device-id/fsl_mc.h b/include/linux/device-id/fsl_mc.h new file mode 100644 index 000000000000..0cfa94923670 --- /dev/null +++ b/include/linux/device-id/fsl_mc.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_FSL_MC_H +#define LINUX_DEVICE_ID_FSL_MC_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +/** + * struct fsl_mc_device_id - MC object device identifier + * @vendor: vendor ID + * @obj_type: MC object type + * + * Type of entries in the "device Id" table for MC object devices supported by + * a MC object device driver. The last entry of the table has vendor set to 0x0 + */ +struct fsl_mc_device_id { + __u16 vendor; + const char obj_type[16]; +}; + +#endif /* ifndef LINUX_DEVICE_ID_FSL_MC_H */ diff --git a/include/linux/device-id/hda.h b/include/linux/device-id/hda.h new file mode 100644 index 000000000000..42542580f955 --- /dev/null +++ b/include/linux/device-id/hda.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_HDA_H +#define LINUX_DEVICE_ID_HDA_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +struct hda_device_id { + __u32 vendor_id; + __u32 rev_id; + __u8 api_version; + const char *name; + unsigned long driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_HDA_H */ diff --git a/include/linux/device-id/hid.h b/include/linux/device-id/hid.h new file mode 100644 index 000000000000..e865fc64bf94 --- /dev/null +++ b/include/linux/device-id/hid.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_HID_H +#define LINUX_DEVICE_ID_HID_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define HID_ANY_ID (~0) +#define HID_BUS_ANY 0xffff +#define HID_GROUP_ANY 0x0000 + +struct hid_device_id { + __u16 bus; + __u16 group; + __u32 vendor; + __u32 product; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_HID_H */ diff --git a/include/linux/device-id/hv_vmbus.h b/include/linux/device-id/hv_vmbus.h new file mode 100644 index 000000000000..a7682c05619f --- /dev/null +++ b/include/linux/device-id/hv_vmbus.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_HV_VMBUS_H +#define LINUX_DEVICE_ID_HV_VMBUS_H + +#ifdef __KERNEL__ +#include <linux/uuid.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* + * For Hyper-V devices we use the device guid as the id. + */ +struct hv_vmbus_device_id { + guid_t guid; + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_HV_VMBUS_H */ diff --git a/include/linux/device-id/i2c.h b/include/linux/device-id/i2c.h new file mode 100644 index 000000000000..21f9b581e7a9 --- /dev/null +++ b/include/linux/device-id/i2c.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_I2C_H +#define LINUX_DEVICE_ID_I2C_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +/* i2c */ + +#define I2C_NAME_SIZE 20 +#define I2C_MODULE_PREFIX "i2c:" + +struct i2c_device_id { + char name[I2C_NAME_SIZE]; + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_I2C_H */ diff --git a/include/linux/device-id/i3c.h b/include/linux/device-id/i3c.h new file mode 100644 index 000000000000..5d8222c9f908 --- /dev/null +++ b/include/linux/device-id/i3c.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_I3C_H +#define LINUX_DEVICE_ID_I3C_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +/* i3c */ + +#define I3C_MATCH_DCR 0x1 +#define I3C_MATCH_MANUF 0x2 +#define I3C_MATCH_PART 0x4 +#define I3C_MATCH_EXTRA_INFO 0x8 + +struct i3c_device_id { + __u8 match_flags; + __u8 dcr; + __u16 manuf_id; + __u16 part_id; + __u16 extra_info; + + const void *data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_I3C_H */ diff --git a/include/linux/device-id/ieee1394.h b/include/linux/device-id/ieee1394.h new file mode 100644 index 000000000000..63023964724a --- /dev/null +++ b/include/linux/device-id/ieee1394.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_IEEE1394_H +#define LINUX_DEVICE_ID_IEEE1394_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define IEEE1394_MATCH_VENDOR_ID 0x0001 +#define IEEE1394_MATCH_MODEL_ID 0x0002 +#define IEEE1394_MATCH_SPECIFIER_ID 0x0004 +#define IEEE1394_MATCH_VERSION 0x0008 + +struct ieee1394_device_id { + __u32 match_flags; + __u32 vendor_id; + __u32 model_id; + __u32 specifier_id; + __u32 version; + union { + kernel_ulong_t driver_data; + const void *driver_data_ptr; + }; +}; + +#endif /* ifndef LINUX_DEVICE_ID_IEEE1394_H */ diff --git a/include/linux/device-id/input.h b/include/linux/device-id/input.h new file mode 100644 index 000000000000..66d7e78d32c0 --- /dev/null +++ b/include/linux/device-id/input.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_INPUT_H +#define LINUX_DEVICE_ID_INPUT_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* Input */ +#define INPUT_DEVICE_ID_EV_MAX 0x1f +#define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71 +#define INPUT_DEVICE_ID_KEY_MAX 0x2ff +#define INPUT_DEVICE_ID_REL_MAX 0x0f +#define INPUT_DEVICE_ID_ABS_MAX 0x3f +#define INPUT_DEVICE_ID_MSC_MAX 0x07 +#define INPUT_DEVICE_ID_LED_MAX 0x0f +#define INPUT_DEVICE_ID_SND_MAX 0x07 +#define INPUT_DEVICE_ID_FF_MAX 0x7f +#define INPUT_DEVICE_ID_SW_MAX 0x11 +#define INPUT_DEVICE_ID_PROP_MAX 0x1f + +#define INPUT_DEVICE_ID_MATCH_BUS 1 +#define INPUT_DEVICE_ID_MATCH_VENDOR 2 +#define INPUT_DEVICE_ID_MATCH_PRODUCT 4 +#define INPUT_DEVICE_ID_MATCH_VERSION 8 + +#define INPUT_DEVICE_ID_MATCH_EVBIT 0x0010 +#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x0020 +#define INPUT_DEVICE_ID_MATCH_RELBIT 0x0040 +#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x0080 +#define INPUT_DEVICE_ID_MATCH_MSCIT 0x0100 +#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x0200 +#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400 +#define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800 +#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 +#define INPUT_DEVICE_ID_MATCH_PROPBIT 0x2000 + +struct input_device_id { + + kernel_ulong_t flags; + + __u16 bustype; + __u16 vendor; + __u16 product; + __u16 version; + + kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t propbit[INPUT_DEVICE_ID_PROP_MAX / BITS_PER_LONG + 1]; + + kernel_ulong_t driver_info; +}; + +#endif /* ifndef LINUX_DEVICE_ID_INPUT_H */ diff --git a/include/linux/device-id/ipack.h b/include/linux/device-id/ipack.h new file mode 100644 index 000000000000..7f9b425e1e30 --- /dev/null +++ b/include/linux/device-id/ipack.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_IPACK_H +#define LINUX_DEVICE_ID_IPACK_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define IPACK_ANY_FORMAT 0xff +#define IPACK_ANY_ID (~0) +struct ipack_device_id { + __u8 format; /* Format version or IPACK_ANY_ID */ + __u32 vendor; /* Vendor ID or IPACK_ANY_ID */ + __u32 device; /* Device ID or IPACK_ANY_ID */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_IPACK_H */ diff --git a/include/linux/device-id/isapnp.h b/include/linux/device-id/isapnp.h new file mode 100644 index 000000000000..ba659c32650a --- /dev/null +++ b/include/linux/device-id/isapnp.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_ISAPNP_H +#define LINUX_DEVICE_ID_ISAPNP_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +#define ISAPNP_ANY_ID 0xffff +struct isapnp_device_id { + unsigned short card_vendor, card_device; + unsigned short vendor, function; + kernel_ulong_t driver_data; /* data private to the driver */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_ISAPNP_H */ diff --git a/include/linux/device-id/ishtp.h b/include/linux/device-id/ishtp.h new file mode 100644 index 000000000000..c66f144b4cb6 --- /dev/null +++ b/include/linux/device-id/ishtp.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_ISHTP_H +#define LINUX_DEVICE_ID_ISHTP_H + +#ifdef __KERNEL__ +#include <linux/uuid.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* ISHTP (Integrated Sensor Hub Transport Protocol) */ + +#define ISHTP_MODULE_PREFIX "ishtp:" + +/** + * struct ishtp_device_id - ISHTP device identifier + * @guid: GUID of the device. + * @driver_data: pointer to driver specific data + */ +struct ishtp_device_id { + guid_t guid; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_ISHTP_H */ diff --git a/include/linux/device-id/mcb.h b/include/linux/device-id/mcb.h new file mode 100644 index 000000000000..a5daec32c21c --- /dev/null +++ b/include/linux/device-id/mcb.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_MCB_H +#define LINUX_DEVICE_ID_MCB_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +struct mcb_device_id { + __u16 device; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_MCB_H */ diff --git a/include/linux/device-id/mdio.h b/include/linux/device-id/mdio.h new file mode 100644 index 000000000000..e6cda2d91ddb --- /dev/null +++ b/include/linux/device-id/mdio.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_MDIO_H +#define LINUX_DEVICE_ID_MDIO_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define MDIO_MODULE_PREFIX "mdio:" + +#define MDIO_ID_FMT "%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u" +#define MDIO_ID_ARGS(_id) \ + ((_id)>>31) & 1, ((_id)>>30) & 1, ((_id)>>29) & 1, ((_id)>>28) & 1, \ + ((_id)>>27) & 1, ((_id)>>26) & 1, ((_id)>>25) & 1, ((_id)>>24) & 1, \ + ((_id)>>23) & 1, ((_id)>>22) & 1, ((_id)>>21) & 1, ((_id)>>20) & 1, \ + ((_id)>>19) & 1, ((_id)>>18) & 1, ((_id)>>17) & 1, ((_id)>>16) & 1, \ + ((_id)>>15) & 1, ((_id)>>14) & 1, ((_id)>>13) & 1, ((_id)>>12) & 1, \ + ((_id)>>11) & 1, ((_id)>>10) & 1, ((_id)>>9) & 1, ((_id)>>8) & 1, \ + ((_id)>>7) & 1, ((_id)>>6) & 1, ((_id)>>5) & 1, ((_id)>>4) & 1, \ + ((_id)>>3) & 1, ((_id)>>2) & 1, ((_id)>>1) & 1, (_id) & 1 + +/** + * struct mdio_device_id - identifies PHY devices on an MDIO/MII bus + * @phy_id: The result of + * (mdio_read(&MII_PHYSID1) << 16 | mdio_read(&MII_PHYSID2)) & @phy_id_mask + * for this PHY type + * @phy_id_mask: Defines the significant bits of @phy_id. A value of 0 + * is used to terminate an array of struct mdio_device_id. + */ +struct mdio_device_id { + __u32 phy_id; + __u32 phy_id_mask; +}; + +#endif /* ifndef LINUX_DEVICE_ID_MDIO_H */ diff --git a/include/linux/device-id/mei_cl.h b/include/linux/device-id/mei_cl.h new file mode 100644 index 000000000000..aeeb95da4b29 --- /dev/null +++ b/include/linux/device-id/mei_cl.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_MEI_CL_H +#define LINUX_DEVICE_ID_MEI_CL_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#include <linux/mei_uuid.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define MEI_CL_MODULE_PREFIX "mei:" +#define MEI_CL_NAME_SIZE 32 +#define MEI_CL_VERSION_ANY 0xff + +/** + * struct mei_cl_device_id - MEI client device identifier + * @name: helper name + * @uuid: client uuid + * @version: client protocol version + * @driver_info: information used by the driver. + * + * identifies mei client device by uuid and name + */ +struct mei_cl_device_id { + char name[MEI_CL_NAME_SIZE]; + uuid_le uuid; + __u8 version; + kernel_ulong_t driver_info; +}; + +#endif /* ifndef LINUX_DEVICE_ID_MEI_CL_H */ diff --git a/include/linux/device-id/mhi.h b/include/linux/device-id/mhi.h new file mode 100644 index 000000000000..30a27a71a57f --- /dev/null +++ b/include/linux/device-id/mhi.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_MHI_H +#define LINUX_DEVICE_ID_MHI_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +#define MHI_DEVICE_MODALIAS_FMT "mhi:%s" +#define MHI_NAME_SIZE 32 + +#define MHI_EP_DEVICE_MODALIAS_FMT "mhi_ep:%s" + +/** + * struct mhi_device_id - MHI device identification + * @chan: MHI channel name + * @driver_data: driver data; + */ +struct mhi_device_id { + const char chan[MHI_NAME_SIZE]; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_MHI_H */ diff --git a/include/linux/device-id/mips_cdmm.h b/include/linux/device-id/mips_cdmm.h new file mode 100644 index 000000000000..e1623884103a --- /dev/null +++ b/include/linux/device-id/mips_cdmm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_MIPS_CDMM_H +#define LINUX_DEVICE_ID_MIPS_CDMM_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +/** + * struct mips_cdmm_device_id - identifies devices in MIPS CDMM bus + * @type: Device type identifier. + */ +struct mips_cdmm_device_id { + __u8 type; +}; + +#endif /* ifndef LINUX_DEVICE_ID_MIPS_CDMM_H */ diff --git a/include/linux/device-id/of.h b/include/linux/device-id/of.h new file mode 100644 index 000000000000..28ea360f8f9a --- /dev/null +++ b/include/linux/device-id/of.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_OF_H +#define LINUX_DEVICE_ID_OF_H + +/* + * Struct used for matching a device + */ +struct of_device_id { + char name[32]; + char type[32]; + char compatible[128]; + const void *data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_OF_H */ diff --git a/include/linux/device-id/parisc.h b/include/linux/device-id/parisc.h new file mode 100644 index 000000000000..2974eb26a8be --- /dev/null +++ b/include/linux/device-id/parisc.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_PARISC_H +#define LINUX_DEVICE_ID_PARISC_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define PA_HWTYPE_ANY_ID 0xff +#define PA_HVERSION_REV_ANY_ID 0xff +#define PA_HVERSION_ANY_ID 0xffff +#define PA_SVERSION_ANY_ID 0xffffffff + +struct parisc_device_id { + __u8 hw_type; /* 5 bits used */ + __u8 hversion_rev; /* 4 bits */ + __u16 hversion; /* 12 bits */ + __u32 sversion; /* 20 bits */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_PARISC_H */ diff --git a/include/linux/device-id/pci.h b/include/linux/device-id/pci.h new file mode 100644 index 000000000000..4a635d531cd6 --- /dev/null +++ b/include/linux/device-id/pci.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_PCI_H +#define LINUX_DEVICE_ID_PCI_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define PCI_ANY_ID (~0) + +enum { + PCI_ID_F_VFIO_DRIVER_OVERRIDE = 1, +}; + +/** + * struct pci_device_id - PCI device ID structure + * @vendor: Vendor ID to match (or PCI_ANY_ID) + * @device: Device ID to match (or PCI_ANY_ID) + * @subvendor: Subsystem vendor ID to match (or PCI_ANY_ID) + * @subdevice: Subsystem device ID to match (or PCI_ANY_ID) + * @class: Device class, subclass, and "interface" to match. + * See Appendix D of the PCI Local Bus Spec or + * include/linux/pci_ids.h for a full list of classes. + * Most drivers do not need to specify class/class_mask + * as vendor/device is normally sufficient. + * @class_mask: Limit which sub-fields of the class field are compared. + * See drivers/scsi/sym53c8xx_2/ for example of usage. + * @driver_data: Data private to the driver. + * Most drivers don't need to use driver_data field. + * Best practice is to use driver_data as an index + * into a static list of equivalent device types, + * instead of using it as a pointer. + * @override_only: Match only when dev->driver_override is this driver. + */ +struct pci_device_id { + __u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/ + __u32 subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ + __u32 class, class_mask; /* (class,subclass,prog-if) triplet */ + kernel_ulong_t driver_data; /* Data private to the driver */ + __u32 override_only; +}; + +/* pci_epf */ + +#define PCI_EPF_NAME_SIZE 20 +#define PCI_EPF_MODULE_PREFIX "pci_epf:" + +struct pci_epf_device_id { + char name[PCI_EPF_NAME_SIZE]; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_PCI_H */ diff --git a/include/linux/device-id/pcmcia.h b/include/linux/device-id/pcmcia.h new file mode 100644 index 000000000000..c0d809be2338 --- /dev/null +++ b/include/linux/device-id/pcmcia.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_PCMCIA_H +#define LINUX_DEVICE_ID_PCMCIA_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* PCMCIA */ + +#define PCMCIA_DEV_ID_MATCH_MANF_ID 0x0001 +#define PCMCIA_DEV_ID_MATCH_CARD_ID 0x0002 +#define PCMCIA_DEV_ID_MATCH_FUNC_ID 0x0004 +#define PCMCIA_DEV_ID_MATCH_FUNCTION 0x0008 +#define PCMCIA_DEV_ID_MATCH_PROD_ID1 0x0010 +#define PCMCIA_DEV_ID_MATCH_PROD_ID2 0x0020 +#define PCMCIA_DEV_ID_MATCH_PROD_ID3 0x0040 +#define PCMCIA_DEV_ID_MATCH_PROD_ID4 0x0080 +#define PCMCIA_DEV_ID_MATCH_DEVICE_NO 0x0100 +#define PCMCIA_DEV_ID_MATCH_FAKE_CIS 0x0200 +#define PCMCIA_DEV_ID_MATCH_ANONYMOUS 0x0400 + +struct pcmcia_device_id { + __u16 match_flags; + + __u16 manf_id; + __u16 card_id; + + __u8 func_id; + + /* for real multi-function devices */ + __u8 function; + + /* for pseudo multi-function devices */ + __u8 device_no; + + __u32 prod_id_hash[4]; + + /* not matched against in kernelspace */ + const char * prod_id[4]; + + /* not matched against */ + kernel_ulong_t driver_info; + char * cisfile; +}; + +#endif /* ifndef LINUX_DEVICE_ID_PCMCIA_H */ diff --git a/include/linux/device-id/platform.h b/include/linux/device-id/platform.h new file mode 100644 index 000000000000..d6beeb4a2574 --- /dev/null +++ b/include/linux/device-id/platform.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_PLATFORM_H +#define LINUX_DEVICE_ID_PLATFORM_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +#define PLATFORM_NAME_SIZE 24 +#define PLATFORM_MODULE_PREFIX "platform:" + +struct platform_device_id { + char name[PLATFORM_NAME_SIZE]; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_PLATFORM_H */ diff --git a/include/linux/device-id/pnp.h b/include/linux/device-id/pnp.h new file mode 100644 index 000000000000..325f17216df8 --- /dev/null +++ b/include/linux/device-id/pnp.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_PNP_H +#define LINUX_DEVICE_ID_PNP_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define PNP_ID_LEN 8 +#define PNP_MAX_DEVICES 8 + +struct pnp_device_id { + __u8 id[PNP_ID_LEN]; + kernel_ulong_t driver_data; +}; + +struct pnp_card_device_id { + __u8 id[PNP_ID_LEN]; + kernel_ulong_t driver_data; + struct { + __u8 id[PNP_ID_LEN]; + } devs[PNP_MAX_DEVICES]; +}; + +#endif /* ifndef LINUX_DEVICE_ID_PNP_H */ diff --git a/include/linux/device-id/rio.h b/include/linux/device-id/rio.h new file mode 100644 index 000000000000..31addf69ad1f --- /dev/null +++ b/include/linux/device-id/rio.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_RIO_H +#define LINUX_DEVICE_ID_RIO_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +/* RapidIO */ + +#define RIO_ANY_ID 0xffff + +/** + * struct rio_device_id - RIO device identifier + * @did: RapidIO device ID + * @vid: RapidIO vendor ID + * @asm_did: RapidIO assembly device ID + * @asm_vid: RapidIO assembly vendor ID + * + * Identifies a RapidIO device based on both the device/vendor IDs and + * the assembly device/vendor IDs. + */ +struct rio_device_id { + __u16 did, vid; + __u16 asm_did, asm_vid; +}; + +#endif /* ifndef LINUX_DEVICE_ID_RIO_H */ diff --git a/include/linux/device-id/rpmsg.h b/include/linux/device-id/rpmsg.h new file mode 100644 index 000000000000..dd53e7b7dc4f --- /dev/null +++ b/include/linux/device-id/rpmsg.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_RPMSG_H +#define LINUX_DEVICE_ID_RPMSG_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +/* rpmsg */ + +#define RPMSG_NAME_SIZE 32 +#define RPMSG_DEVICE_MODALIAS_FMT "rpmsg:%s" + +struct rpmsg_device_id { + char name[RPMSG_NAME_SIZE]; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_RPMSG_H */ diff --git a/include/linux/device-id/sdio.h b/include/linux/device-id/sdio.h new file mode 100644 index 000000000000..609d60a10cd3 --- /dev/null +++ b/include/linux/device-id/sdio.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_SDIO_H +#define LINUX_DEVICE_ID_SDIO_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* SDIO */ + +#define SDIO_ANY_ID (~0) + +struct sdio_device_id { + __u8 class; /* Standard interface or SDIO_ANY_ID */ + __u16 vendor; /* Vendor or SDIO_ANY_ID */ + __u16 device; /* Device ID or SDIO_ANY_ID */ + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_SDIO_H */ diff --git a/include/linux/device-id/sdw.h b/include/linux/device-id/sdw.h new file mode 100644 index 000000000000..dbed7fde1ace --- /dev/null +++ b/include/linux/device-id/sdw.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_SDW_H +#define LINUX_DEVICE_ID_SDW_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +struct sdw_device_id { + __u16 mfg_id; + __u16 part_id; + __u8 sdw_version; + __u8 class_id; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_SDW_H */ diff --git a/include/linux/device-id/serio.h b/include/linux/device-id/serio.h new file mode 100644 index 000000000000..b4c02adf220c --- /dev/null +++ b/include/linux/device-id/serio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_SERIO_H +#define LINUX_DEVICE_ID_SERIO_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define SERIO_ANY 0xff + +struct serio_device_id { + __u8 type; + __u8 extra; + __u8 id; + __u8 proto; +}; + +#endif /* ifndef LINUX_DEVICE_ID_SERIO_H */ diff --git a/include/linux/device-id/slim.h b/include/linux/device-id/slim.h new file mode 100644 index 000000000000..54f8abe09e18 --- /dev/null +++ b/include/linux/device-id/slim.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_SLIM_H +#define LINUX_DEVICE_ID_SLIM_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* SLIMbus */ + +#define SLIMBUS_NAME_SIZE 32 +#define SLIMBUS_MODULE_PREFIX "slim:" + +struct slim_device_id { + __u16 manf_id, prod_code; + __u16 dev_index, instance; + + /* Data private to the driver */ + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_SLIM_H */ diff --git a/include/linux/device-id/spi.h b/include/linux/device-id/spi.h new file mode 100644 index 000000000000..7a77d0d6672b --- /dev/null +++ b/include/linux/device-id/spi.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_SPI_H +#define LINUX_DEVICE_ID_SPI_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +/* spi */ + +#define SPI_NAME_SIZE 32 +#define SPI_MODULE_PREFIX "spi:" + +struct spi_device_id { + char name[SPI_NAME_SIZE]; + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_SPI_H */ diff --git a/include/linux/device-id/spmi.h b/include/linux/device-id/spmi.h new file mode 100644 index 000000000000..a821c42cfc9a --- /dev/null +++ b/include/linux/device-id/spmi.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_SPMI_H +#define LINUX_DEVICE_ID_SPMI_H + +#ifdef __KERNEL__ +typedef unsigned long kernel_ulong_t; +#endif + +#define SPMI_NAME_SIZE 32 +#define SPMI_MODULE_PREFIX "spmi:" + +struct spmi_device_id { + char name[SPMI_NAME_SIZE]; + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + +#endif /* ifndef LINUX_DEVICE_ID_SPMI_H */ diff --git a/include/linux/device-id/ssam.h b/include/linux/device-id/ssam.h new file mode 100644 index 000000000000..550cca115a55 --- /dev/null +++ b/include/linux/device-id/ssam.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_SSAM_H +#define LINUX_DEVICE_ID_SSAM_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* Surface System Aggregator Module */ + +#define SSAM_MATCH_TARGET 0x1 +#define SSAM_MATCH_INSTANCE 0x2 +#define SSAM_MATCH_FUNCTION 0x4 + +struct ssam_device_id { + __u8 match_flags; + + __u8 domain; + __u8 category; + __u8 target; + __u8 instance; + __u8 function; + + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_SSAM_H */ diff --git a/include/linux/device-id/ssb.h b/include/linux/device-id/ssb.h new file mode 100644 index 000000000000..678d40828299 --- /dev/null +++ b/include/linux/device-id/ssb.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_SSB_H +#define LINUX_DEVICE_ID_SSB_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define SSB_ANY_VENDOR 0xFFFF +#define SSB_ANY_ID 0xFFFF +#define SSB_ANY_REV 0xFF + +/* SSB core, see drivers/ssb/ */ +struct ssb_device_id { + __u16 vendor; + __u16 coreid; + __u8 revision; + __u8 __pad; +} __attribute__((packed, aligned(2))); + +#define SSB_DEVICE(_vendor, _coreid, _revision) \ + { .vendor = _vendor, .coreid = _coreid, .revision = _revision } + +#endif /* ifndef LINUX_DEVICE_ID_SSB_H */ diff --git a/include/linux/device-id/tb.h b/include/linux/device-id/tb.h new file mode 100644 index 000000000000..4c62edff8bb7 --- /dev/null +++ b/include/linux/device-id/tb.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_TB_H +#define LINUX_DEVICE_ID_TB_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define TBSVC_MATCH_PROTOCOL_KEY 0x0001 +#define TBSVC_MATCH_PROTOCOL_ID 0x0002 +#define TBSVC_MATCH_PROTOCOL_VERSION 0x0004 +#define TBSVC_MATCH_PROTOCOL_REVISION 0x0008 + +/** + * struct tb_service_id - Thunderbolt service identifiers + * @match_flags: Flags used to match the structure + * @protocol_key: Protocol key the service supports + * @protocol_id: Protocol id the service supports + * @protocol_version: Version of the protocol + * @protocol_revision: Revision of the protocol software + * @driver_data: Driver specific data + * + * Thunderbolt XDomain services are exposed as devices where each device + * carries the protocol information the service supports. Thunderbolt + * XDomain service drivers match against that information. + */ +struct tb_service_id { + __u32 match_flags; + char protocol_key[8 + 1]; + __u32 protocol_id; + __u32 protocol_version; + __u32 protocol_revision; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_TB_H */ diff --git a/include/linux/device-id/tee_client.h b/include/linux/device-id/tee_client.h new file mode 100644 index 000000000000..ed81f4228185 --- /dev/null +++ b/include/linux/device-id/tee_client.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_TEE_CLIENT_H +#define LINUX_DEVICE_ID_TEE_CLIENT_H + +#ifdef __KERNEL__ +#include <linux/uuid.h> +#endif + +/** + * struct tee_client_device_id - tee based device identifier + * @uuid: For TEE based client devices we use the device uuid as + * the identifier. + */ +struct tee_client_device_id { + uuid_t uuid; +}; + +#endif /* ifndef LINUX_DEVICE_ID_TEE_CLIENT_H */ diff --git a/include/linux/device-id/typec.h b/include/linux/device-id/typec.h new file mode 100644 index 000000000000..dc234733408b --- /dev/null +++ b/include/linux/device-id/typec.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_TYPEC_H +#define LINUX_DEVICE_ID_TYPEC_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* USB Type-C Alternate Modes */ + +#define TYPEC_ANY_MODE 0x7 + +/** + * struct typec_device_id - USB Type-C alternate mode identifiers + * @svid: Standard or Vendor ID + * @mode: Mode index + * @driver_data: Driver specific data + */ +struct typec_device_id { + __u16 svid; + __u8 mode; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_TYPEC_H */ diff --git a/include/linux/device-id/ulpi.h b/include/linux/device-id/ulpi.h new file mode 100644 index 000000000000..b5105b4cfacc --- /dev/null +++ b/include/linux/device-id/ulpi.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_ULPI_H +#define LINUX_DEVICE_ID_ULPI_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +struct ulpi_device_id { + __u16 vendor; + __u16 product; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_ULPI_H */ diff --git a/include/linux/device-id/usb.h b/include/linux/device-id/usb.h new file mode 100644 index 000000000000..a7ce5f6e1106 --- /dev/null +++ b/include/linux/device-id/usb.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_USB_H +#define LINUX_DEVICE_ID_USB_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* + * Device table entry for "new style" table-driven USB drivers. + * User mode code can read these tables to choose which modules to load. + * Declare the table as a MODULE_DEVICE_TABLE. + * + * A probe() parameter will point to a matching entry from this table. + * Use the driver_info field for each match to hold information tied + * to that match: device quirks, etc. + * + * Terminate the driver's table with an all-zeroes entry. + * Use the flag values to control which fields are compared. + */ + +/** + * struct usb_device_id - identifies USB devices for probing and hotplugging + * @match_flags: Bit mask controlling which of the other fields are used to + * match against new devices. Any field except for driver_info may be + * used, although some only make sense in conjunction with other fields. + * This is usually set by a USB_DEVICE_*() macro, which sets all + * other fields in this structure except for driver_info. + * @idVendor: USB vendor ID for a device; numbers are assigned + * by the USB forum to its members. + * @idProduct: Vendor-assigned product ID. + * @bcdDevice_lo: Low end of range of vendor-assigned product version numbers. + * This is also used to identify individual product versions, for + * a range consisting of a single device. + * @bcdDevice_hi: High end of version number range. The range of product + * versions is inclusive. + * @bDeviceClass: Class of device; numbers are assigned + * by the USB forum. Products may choose to implement classes, + * or be vendor-specific. Device classes specify behavior of all + * the interfaces on a device. + * @bDeviceSubClass: Subclass of device; associated with bDeviceClass. + * @bDeviceProtocol: Protocol of device; associated with bDeviceClass. + * @bInterfaceClass: Class of interface; numbers are assigned + * by the USB forum. Products may choose to implement classes, + * or be vendor-specific. Interface classes specify behavior only + * of a given interface; other interfaces may support other classes. + * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass. + * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass. + * @bInterfaceNumber: Number of interface; composite devices may use + * fixed interface numbers to differentiate between vendor-specific + * interfaces. + * @driver_info: Holds information used by the driver. Usually it holds + * a pointer to a descriptor understood by the driver, or perhaps + * device flags. + * + * In most cases, drivers will create a table of device IDs by using + * USB_DEVICE(), or similar macros designed for that purpose. + * They will then export it to userspace using MODULE_DEVICE_TABLE(), + * and provide it to the USB core through their usb_driver structure. + * + * See the usb_match_id() function for information about how matches are + * performed. Briefly, you will normally use one of several macros to help + * construct these entries. Each entry you provide will either identify + * one or more specific products, or will identify a class of products + * which have agreed to behave the same. You should put the more specific + * matches towards the beginning of your table, so that driver_info can + * record quirks of specific products. + */ +struct usb_device_id { + /* which fields to match against? */ + __u16 match_flags; + + /* Used for product specific matches; range is inclusive */ + __u16 idVendor; + __u16 idProduct; + __u16 bcdDevice_lo; + __u16 bcdDevice_hi; + + /* Used for device class matches */ + __u8 bDeviceClass; + __u8 bDeviceSubClass; + __u8 bDeviceProtocol; + + /* Used for interface class matches */ + __u8 bInterfaceClass; + __u8 bInterfaceSubClass; + __u8 bInterfaceProtocol; + + /* Used for vendor-specific interface matches */ + __u8 bInterfaceNumber; + + /* not matched against */ + kernel_ulong_t driver_info + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + +/* Some useful macros to use to create struct usb_device_id */ +#define USB_DEVICE_ID_MATCH_VENDOR 0x0001 +#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 +#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 +#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 +#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 +#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 +#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 +#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 +#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 +#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 +#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400 + +#endif /* ifndef LINUX_DEVICE_ID_USB_H */ diff --git a/include/linux/device-id/vchiq.h b/include/linux/device-id/vchiq.h new file mode 100644 index 000000000000..16b1b874c02d --- /dev/null +++ b/include/linux/device-id/vchiq.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_VCHIQ_H +#define LINUX_DEVICE_ID_VCHIQ_H + +struct vchiq_device_id { + char name[32]; +}; + +#endif /* ifndef LINUX_DEVICE_ID_VCHIQ_H */ diff --git a/include/linux/device-id/vio.h b/include/linux/device-id/vio.h new file mode 100644 index 000000000000..8ed7ea9cec07 --- /dev/null +++ b/include/linux/device-id/vio.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_VIO_H +#define LINUX_DEVICE_ID_VIO_H + +/* VIO */ +struct vio_device_id { + char type[32]; + char compat[32]; +}; + +#endif /* ifndef LINUX_DEVICE_ID_VIO_H */ diff --git a/include/linux/device-id/virtio.h b/include/linux/device-id/virtio.h new file mode 100644 index 000000000000..9648a42d4f26 --- /dev/null +++ b/include/linux/device-id/virtio.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_VIRTIO_H +#define LINUX_DEVICE_ID_VIRTIO_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define VIRTIO_DEV_ANY_ID 0xffffffff + +struct virtio_device_id { + __u32 device; + __u32 vendor; +}; + +#endif /* ifndef LINUX_DEVICE_ID_VIRTIO_H */ diff --git a/include/linux/device-id/wmi.h b/include/linux/device-id/wmi.h new file mode 100644 index 000000000000..9f55c83c5203 --- /dev/null +++ b/include/linux/device-id/wmi.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_WMI_H +#define LINUX_DEVICE_ID_WMI_H + +/* WMI */ + +#define WMI_MODULE_PREFIX "wmi:" + +/** + * struct wmi_device_id - WMI device identifier + * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba + * @context: pointer to driver specific data + */ +struct wmi_device_id { + const char guid_string[UUID_STRING_LEN+1]; + const void *context; +}; + +#endif /* ifndef LINUX_DEVICE_ID_WMI_H */ diff --git a/include/linux/device-id/x86_cpu.h b/include/linux/device-id/x86_cpu.h new file mode 100644 index 000000000000..f44e5253ccca --- /dev/null +++ b/include/linux/device-id/x86_cpu.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_X86_CPU_H +#define LINUX_DEVICE_ID_X86_CPU_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +/* Wild cards for x86_cpu_id::vendor, family, model and feature */ +#define X86_VENDOR_ANY 0xffff +#define X86_FAMILY_ANY 0 +#define X86_MODEL_ANY 0 +#define X86_STEPPING_ANY 0 +#define X86_STEP_MIN 0 +#define X86_STEP_MAX 0xf +#define X86_PLATFORM_ANY 0x0 +#define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */ +#define X86_CPU_TYPE_ANY 0 + +/* + * Match x86 CPUs for CPU specific drivers. + * See documentation of "x86_match_cpu" for details. + */ + +/* + * MODULE_DEVICE_TABLE expects this struct to be called x86cpu_device_id. + * Although gcc seems to ignore this error, clang fails without this define. + */ +#define x86cpu_device_id x86_cpu_id +struct x86_cpu_id { + __u16 vendor; + __u16 family; + __u16 model; + __u16 steppings; + __u16 feature; /* bit index */ + /* Solely for kernel-internal use: DO NOT EXPORT to userspace! */ + __u16 flags; + __u8 platform_mask; + __u8 type; + kernel_ulong_t driver_data; +}; + +#endif /* ifndef LINUX_DEVICE_ID_X86_CPU_H */ diff --git a/include/linux/device-id/zorro.h b/include/linux/device-id/zorro.h new file mode 100644 index 000000000000..26827b9b90b6 --- /dev/null +++ b/include/linux/device-id/zorro.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef LINUX_DEVICE_ID_ZORRO_H +#define LINUX_DEVICE_ID_ZORRO_H + +#ifdef __KERNEL__ +#include <linux/types.h> +typedef unsigned long kernel_ulong_t; +#endif + +#define ZORRO_WILDCARD (0xffffffff) /* not official */ + +#define ZORRO_DEVICE_MODALIAS_FMT "zorro:i%08X" + +struct zorro_device_id { + __u32 id; /* Device ID or ZORRO_WILDCARD */ + union { + /* Data private to the driver */ + kernel_ulong_t driver_data; + const void *driver_data_ptr; + }; +}; + +#endif /* ifndef LINUX_DEVICE_ID_ZORRO_H */ diff --git a/include/linux/device.h b/include/linux/device.h index 7b2baffdd2f5..aee79fd6b32b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -99,7 +99,9 @@ struct device_type { * struct device_attribute - Interface for exporting device attributes. * @attr: sysfs attribute definition. * @show: Show handler. + * @show_const: Show handler (read-only). * @store: Store handler. + * @store_const: Store handler (read-only). */ struct device_attribute { struct attribute attr; diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index 38048e74d10a..768a1334c0a1 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -19,6 +19,8 @@ #include <linux/pm.h> #include <linux/device/bus.h> #include <linux/module.h> +#include <linux/device-id/acpi.h> +#include <linux/device-id/of.h> /** * enum probe_type - device driver probe type to try diff --git a/include/linux/dfl.h b/include/linux/dfl.h index 1f02db0c1897..f28e70652080 100644 --- a/include/linux/dfl.h +++ b/include/linux/dfl.h @@ -9,7 +9,7 @@ #define __LINUX_DFL_H #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/dfl.h> /** * enum dfl_id_type - define the DFL FIU types diff --git a/include/linux/dibs.h b/include/linux/dibs.h index c75607f8a5cf..d3e0777f25ae 100644 --- a/include/linux/dibs.h +++ b/include/linux/dibs.h @@ -439,7 +439,7 @@ static inline void *dibs_get_priv(struct dibs_dev *dev, /** * dibs_dev_alloc() - allocate and reference device structure * - * The following fields will be valid upon successful return: dev + * The following fields will be valid upon successful return: dev, lock * NOTE: Use put_device(dibs_get_dev(@dibs)) to give up your reference instead * of freeing @dibs @dev directly once you have successfully called this * function. diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h index 7b2968612b7e..674683894064 100644 --- a/include/linux/dm-io.h +++ b/include/linux/dm-io.h @@ -27,7 +27,7 @@ struct page_list { struct page *page; }; -typedef void (*io_notify_fn)(unsigned int long error, void *context); +typedef void (*io_notify_fn)(unsigned long int error, unsigned long int unsup, void *context); enum dm_io_mem_type { DM_IO_PAGE_LIST,/* Page list */ @@ -80,8 +80,8 @@ void dm_io_client_destroy(struct dm_io_client *client); * error occurred doing io to the corresponding region. */ int dm_io(struct dm_io_request *io_req, unsigned int num_regions, - struct dm_io_region *region, unsigned int long *sync_error_bits, - unsigned short ioprio); + struct dm_io_region *region, unsigned long int *sync_error_bits, + unsigned long int *sync_unsup_bits, unsigned short ioprio); #endif /* __KERNEL__ */ #endif /* _LINUX_DM_IO_H */ diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h index c249912456f9..daa31a1adf7b 100644 --- a/include/linux/dma-direct.h +++ b/include/linux/dma-direct.h @@ -77,6 +77,10 @@ static inline dma_addr_t dma_range_map_max(const struct bus_dma_region *map) #ifndef phys_to_dma_unencrypted #define phys_to_dma_unencrypted phys_to_dma #endif + +#ifndef phys_to_dma_encrypted +#define phys_to_dma_encrypted phys_to_dma +#endif #else static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) { @@ -90,6 +94,12 @@ static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev, { return dma_addr_unencrypted(__phys_to_dma(dev, paddr)); } + +static inline dma_addr_t phys_to_dma_encrypted(struct device *dev, + phys_addr_t paddr) +{ + return dma_addr_encrypted(__phys_to_dma(dev, paddr)); +} /* * If memory encryption is supported, phys_to_dma will set the memory encryption * bit in the DMA address, and dma_to_phys will clear it. @@ -125,12 +135,20 @@ static inline bool force_dma_unencrypted(struct device *dev) #endif /* CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED */ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size, - bool is_ram) + bool is_ram, unsigned long attrs) { dma_addr_t end = addr + size - 1; if (addr == DMA_MAPPING_ERROR) return false; + /* + * The DMA address was derived from encrypted RAM, but this device + * requires unencrypted DMA addresses. Treat it as not DMA-capable + * so the caller can fall back to a suitable SWIOTLB pool. + */ + if (!(attrs & DMA_ATTR_CC_SHARED) && force_dma_unencrypted(dev)) + return false; + if (is_ram && !IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) && min(addr, end) < phys_to_dma(dev, PFN_PHYS(min_low_pfn))) return false; diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h index 62df222fe0f1..7bfacdf79de2 100644 --- a/include/linux/dma-fence-unwrap.h +++ b/include/linux/dma-fence-unwrap.h @@ -8,6 +8,8 @@ #ifndef __LINUX_DMA_FENCE_UNWRAP_H #define __LINUX_DMA_FENCE_UNWRAP_H +#include <linux/types.h> + struct dma_fence; /** @@ -48,11 +50,11 @@ struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor); for (fence = dma_fence_unwrap_first(head, cursor); fence; \ fence = dma_fence_unwrap_next(cursor)) -struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, +struct dma_fence *__dma_fence_unwrap_merge(size_t num_fences, struct dma_fence **fences, struct dma_fence_unwrap *cursors); -int dma_fence_dedup_array(struct dma_fence **array, int num_fences); +size_t dma_fence_dedup_array(struct dma_fence **array, size_t num_fences); /** * dma_fence_unwrap_merge - unwrap and merge fences diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index b52ab692b22e..158cd609f103 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -448,7 +448,7 @@ int dma_fence_add_callback(struct dma_fence *fence, dma_fence_func_t func); bool dma_fence_remove_callback(struct dma_fence *fence, struct dma_fence_cb *cb); -void dma_fence_enable_sw_signaling(struct dma_fence *fence); +void dma_fence_enable_signaling(struct dma_fence *fence); /** * DOC: Safe external access to driver provided object members @@ -534,7 +534,7 @@ dma_fence_is_signaled_locked(struct dma_fence *fence) * Returns true if the fence was already signaled, false if not. Since this * function doesn't enable signaling, it is not guaranteed to ever return * true if dma_fence_add_callback(), dma_fence_wait() or - * dma_fence_enable_sw_signaling() haven't been called before. + * dma_fence_enable_signaling() haven't been called before. * * It's recommended for seqno fences to call dma_fence_signal when the * operation is complete, it makes it possible to prevent issues from diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h index bcb5b5428aea..8fae2b7deb20 100644 --- a/include/linux/dma-map-ops.h +++ b/include/linux/dma-map-ops.h @@ -212,9 +212,10 @@ void *dma_common_pages_remap(struct page **pages, size_t size, pgprot_t prot, void dma_common_free_remap(void *cpu_addr, size_t size); struct page *dma_alloc_from_pool(struct device *dev, size_t size, - void **cpu_addr, gfp_t flags, + void **cpu_addr, gfp_t flags, unsigned long attrs, bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t)); bool dma_free_from_pool(struct device *dev, void *start, size_t size); +bool dma_free_from_pool_page(struct device *dev, struct page *page, size_t size); int dma_direct_set_offset(struct device *dev, phys_addr_t cpu_start, dma_addr_t dma_start, u64 size); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index cc0823a99cfd..a3e880649fa4 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -104,6 +104,14 @@ #define DMA_ATTR_CC_SHARED (1UL << 13) /* + * __DMA_ATTR_ALLOC_CC_SHARED: Internal DMA-mapping attribute used by + * allocation paths that create shared (decrypted) backing pages for + * confidential computing guests. Drivers must not pass this attribute to + * dma_alloc_attrs(). + */ +#define __DMA_ATTR_ALLOC_CC_SHARED (1UL << 14) + +/* * A dma_addr_t can hold any valid DMA or bus address for the platform. It can * be given to a device to use as a DMA source or target. It is specific to a * given device and there may be a translation between the CPU physical address diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h index 1fafd5b0e315..3c8e2ef9dee0 100644 --- a/include/linux/dma/edma.h +++ b/include/linux/dma/edma.h @@ -14,6 +14,8 @@ #define EDMA_MAX_WR_CH 8 #define EDMA_MAX_RD_CH 8 +#define HDMA_MAX_WR_CH 64 +#define HDMA_MAX_RD_CH 64 struct dw_edma; @@ -55,9 +57,48 @@ enum dw_edma_map_format { /** * enum dw_edma_chip_flags - Flags specific to an eDMA chip * @DW_EDMA_CHIP_LOCAL: eDMA is used locally by an endpoint + * @DW_EDMA_CHIP_PARTIAL: Only channels described by this instance are + * owned by this driver. Controller-wide state + * must be preserved, and layouts with shared + * direction-wide registers must only be shared at + * direction granularity. Layouts with per-channel + * registers may be shared at channel granularity. */ enum dw_edma_chip_flags { DW_EDMA_CHIP_LOCAL = BIT(0), + DW_EDMA_CHIP_PARTIAL = BIT(1), +}; + +/** + * enum dw_edma_ch_irq_mode - per-channel interrupt routing control + * @DW_EDMA_CH_IRQ_LOCAL: local interrupt only (edma_int[]) + * @DW_EDMA_CH_IRQ_REMOTE: remote interrupt only (IMWr/MSI), without + * delivering local edma_int[]. + * + * DesignWare EP eDMA can signal interrupts locally through the edma_int[] + * bus, and remotely using posted memory writes (IMWr) that may be + * interpreted as MSI/MSI-X by the RC. + * + * For the v0 eDMA linked-list programming path, DMA_*_INT_MASK gates the local + * edma_int[] assertion, while there is no dedicated per-channel mask for IMWr + * generation. To request a remote-only interrupt, Synopsys recommends setting + * both LIE and RIE, and masking the local interrupt in DMA_*_INT_MASK. See the + * DesignWare endpoint databook 6.30a, Linked List Mode interrupt handling + * ("Software Programming of an Endpoint's LIE and RIE Bits for Linked List + * Transfers", Attention). + * + * A local (DW_EDMA_CHIP_LOCAL) instance never issues transfers on a + * remote-routed channel: REMOTE routing on such an instance denotes a channel + * handed over to and driven by the remote side, and the recipe above is + * applied by the driving instance. + * + * HDMA linked-list watermark interrupts have the same LWIE/RWIE guidance. HDMA + * non-linked-list mode has dedicated local and remote stop/abort interrupt + * enables. + */ +enum dw_edma_ch_irq_mode { + DW_EDMA_CH_IRQ_LOCAL = 0, + DW_EDMA_CH_IRQ_REMOTE, }; /** @@ -76,6 +117,7 @@ enum dw_edma_chip_flags { * @db_irq: Virtual IRQ dedicated to interrupt emulation * @db_offset: Offset from DMA register base * @mf: DMA register map format + * @func_no: PCI endpoint function number used by DMA TLPs * @dw: struct dw_edma that is filled by dw_edma_probe() */ struct dw_edma_chip { @@ -89,18 +131,19 @@ struct dw_edma_chip { u16 ll_wr_cnt; u16 ll_rd_cnt; /* link list address */ - struct dw_edma_region ll_region_wr[EDMA_MAX_WR_CH]; - struct dw_edma_region ll_region_rd[EDMA_MAX_RD_CH]; + struct dw_edma_region ll_region_wr[HDMA_MAX_WR_CH]; + struct dw_edma_region ll_region_rd[HDMA_MAX_RD_CH]; /* data region */ - struct dw_edma_region dt_region_wr[EDMA_MAX_WR_CH]; - struct dw_edma_region dt_region_rd[EDMA_MAX_RD_CH]; + struct dw_edma_region dt_region_wr[HDMA_MAX_WR_CH]; + struct dw_edma_region dt_region_rd[HDMA_MAX_RD_CH]; /* interrupt emulation */ int db_irq; resource_size_t db_offset; enum dw_edma_map_format mf; + u8 func_no; struct dw_edma *dw; bool cfg_non_ll; diff --git a/include/linux/dma/qcom_bam_dma.h b/include/linux/dma/qcom_bam_dma.h index 68fc0e643b1b..d9d07a9ab313 100644 --- a/include/linux/dma/qcom_bam_dma.h +++ b/include/linux/dma/qcom_bam_dma.h @@ -13,9 +13,12 @@ * supported by BAM DMA Engine. * * @cmd_and_addr - upper 8 bits command and lower 24 bits register address. - * @data - for write command: content to be written into peripheral register. - * for read command: dest addr to write peripheral register value. - * @mask - register mask. + * @data - For write command: content to be written into peripheral register. + * For read command: lower 32 bits of destination address. + * @mask - For write command: register write mask. + * For read command on BAM v1.6.0+: upper 4 bits of destination address. + * For read command on BAM < v1.6.0: ignored by hardware. + * Setting to 0 ensures 32-bit addressing compatibility. * @reserved - for future usage. * */ @@ -42,6 +45,10 @@ enum bam_command_type { * @addr: target address * @cmd: BAM command * @data: actual data for write and dest addr for read in le32 + * + * For BAM v1.6.0+, the mask field behavior depends on command type: + * - Write commands: mask = write mask (typically 0xffffffff) + * - Read commands: mask = upper 4 bits of destination address (0 for 32-bit) */ static inline void bam_prep_ce_le32(struct bam_cmd_element *bam_ce, u32 addr, @@ -50,7 +57,11 @@ bam_prep_ce_le32(struct bam_cmd_element *bam_ce, u32 addr, bam_ce->cmd_and_addr = cpu_to_le32((addr & 0xffffff) | ((cmd & 0xff) << 24)); bam_ce->data = data; - bam_ce->mask = cpu_to_le32(0xffffffff); + if (cmd == BAM_READ_COMMAND) + bam_ce->mask = cpu_to_le32(0x0); /* 32-bit addressing */ + else + bam_ce->mask = cpu_to_le32(0xffffffff); /* Write mask */ + bam_ce->reserved = 0; } /* @@ -60,7 +71,7 @@ bam_prep_ce_le32(struct bam_cmd_element *bam_ce, u32 addr, * @bam_ce: BAM command element * @addr: target address * @cmd: BAM command - * @data: actual data for write and dest addr for read + * @data: actual data for write and destination address for read */ static inline void bam_prep_ce(struct bam_cmd_element *bam_ce, u32 addr, diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index b3d251c9734e..fe33a20abc61 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -322,6 +322,8 @@ struct dma_router { * @slave: ptr to the device using this channel * @cookie: last cookie value returned to client * @completed_cookie: last completed cookie for this channel + * @lock: protect between config and prepare transfer when driver have not + * implemented callback device_prep_config_sg(). * @chan_id: channel ID for sysfs * @dev: class device for sysfs * @name: backlink name for sysfs @@ -341,6 +343,12 @@ struct dma_chan { dma_cookie_t cookie; dma_cookie_t completed_cookie; + /* + * protect between config and prepare transfer because *_prep() may be + * called from complete callback, which is in GFP_NOSLEEP context. + */ + spinlock_t lock; + /* sysfs */ int chan_id; struct dma_chan_dev *dev; @@ -623,7 +631,7 @@ struct dma_async_tx_descriptor { void *callback_param; struct dmaengine_unmap_data *unmap; enum dma_desc_metadata_mode desc_metadata_mode; - struct dma_descriptor_metadata_ops *metadata_ops; + const struct dma_descriptor_metadata_ops *metadata_ops; #ifdef CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH struct dma_async_tx_descriptor *next; struct dma_async_tx_descriptor *parent; @@ -835,6 +843,7 @@ struct dma_filter { * where the address and size of each segment is located in one entry of * the dma_vec array. * @device_prep_slave_sg: prepares a slave dma operation + * @device_prep_config_sg: prepares a slave DMA operation with dma_slave_config * @device_prep_dma_cyclic: prepare a cyclic dma operation suitable for audio. * The function takes a buffer of size buf_len. The callback function will * be called after period_len bytes have been transferred. @@ -934,6 +943,10 @@ struct dma_device { struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, unsigned long flags, void *context); + struct dma_async_tx_descriptor *(*device_prep_config_sg)( + struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_transfer_direction direction, + unsigned long flags, struct dma_slave_config *config); struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)( struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, size_t period_len, enum dma_transfer_direction direction, @@ -974,22 +987,44 @@ static inline bool is_slave_direction(enum dma_transfer_direction direction) (direction == DMA_DEV_TO_DEV); } -static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single( - struct dma_chan *chan, dma_addr_t buf, size_t len, - enum dma_transfer_direction dir, unsigned long flags) +static inline struct dma_async_tx_descriptor * +dmaengine_prep_config_single(struct dma_chan *chan, dma_addr_t buf, size_t len, + enum dma_transfer_direction dir, + unsigned long flags, + struct dma_slave_config *config) { struct scatterlist sg; + + if (!chan || !chan->device) + return NULL; + sg_init_table(&sg, 1); sg_dma_address(&sg) = buf; sg_dma_len(&sg) = len; - if (!chan || !chan->device || !chan->device->device_prep_slave_sg) + if (chan->device->device_prep_config_sg) + return chan->device->device_prep_config_sg(chan, &sg, 1, dir, + flags, config); + + if (config) + if (dmaengine_slave_config(chan, config)) + return NULL; + + if (!chan->device->device_prep_slave_sg) return NULL; return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags, NULL); } +static inline struct dma_async_tx_descriptor * +dmaengine_prep_slave_single(struct dma_chan *chan, dma_addr_t buf, size_t len, + enum dma_transfer_direction dir, + unsigned long flags) +{ + return dmaengine_prep_config_single(chan, buf, len, dir, flags, NULL); +} + /** * dmaengine_prep_peripheral_dma_vec() - Prepare a DMA scatter-gather descriptor * @chan: The channel to be used for this descriptor @@ -1010,17 +1045,115 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_peripheral_dma_vec( dir, flags); } -static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg( - struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, - enum dma_transfer_direction dir, unsigned long flags) +static inline struct dma_async_tx_descriptor * +dmaengine_prep_config_sg(struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_transfer_direction dir, + unsigned long flags, struct dma_slave_config *config) { - if (!chan || !chan->device || !chan->device->device_prep_slave_sg) + if (!chan || !chan->device) + return NULL; + + if (chan->device->device_prep_config_sg) + return chan->device->device_prep_config_sg(chan, sgl, sg_len, + dir, flags, config); + + if (config) + if (dmaengine_slave_config(chan, config)) + return NULL; + + if (!chan->device->device_prep_slave_sg) return NULL; return chan->device->device_prep_slave_sg(chan, sgl, sg_len, dir, flags, NULL); } +static inline struct dma_async_tx_descriptor * +dmaengine_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_transfer_direction dir, + unsigned long flags) +{ + return dmaengine_prep_config_sg(chan, sgl, sg_len, dir, flags, NULL); +} + +/** + * dmaengine_prep_config_sg_safe - prepare a scatter-gather DMA transfer + * with atomic slave configuration update + * @chan: DMA channel + * @sgl: scatterlist for the transfer + * @sg_len: number of entries in @sgl + * @dir: DMA transfer direction + * @flags: transfer preparation flags + * @config: DMA slave configuration for this transfer + * + * Prepare a DMA scatter-gather transfer together with a corresponding slave + * configuration update in a re-entrant and race-safe manner. + * + * DMA engine drivers may implement the optional + * device_prep_config_sg() callback to perform both the slave configuration + * and descriptor preparation atomically. In this case, the operation is + * fully handled by the DMA engine driver. + * + * If the DMA engine driver does not implement device_prep_config_sg(), falls + * back to calling dmaengine_slave_config() followed by dmaengine_prep_slave_sg(). + * The fallback path is protected by a per-channel spinlock to ensure that + * concurrent callers cannot interleave configuration and descriptor preparation + * on the same DMA channel. + * + * Return: Pointer to a prepared DMA async transaction descriptor on success, + * or %NULL if the transfer could not be prepared. + */ +static inline struct dma_async_tx_descriptor * +dmaengine_prep_config_sg_safe(struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, + enum dma_transfer_direction dir, + unsigned long flags, + struct dma_slave_config *config) +{ + struct dma_async_tx_descriptor *tx; + unsigned long spinlock_flags; + + if (!chan || !chan->device) + return NULL; + + if (!chan->device->device_prep_config_sg) + spin_lock_irqsave(&chan->lock, spinlock_flags); + + tx = dmaengine_prep_config_sg(chan, sgl, sg_len, dir, flags, config); + + if (!chan->device->device_prep_config_sg) + spin_unlock_irqrestore(&chan->lock, spinlock_flags); + + return tx; +} + +/** + * dmaengine_prep_config_single_safe - prepare a single-buffer DMA transfer + * with atomic slave configuration update + * @chan: DMA channel + * @buf: DMA buffer address + * @len: length of the transfer in bytes + * @dir: DMA transfer direction + * @flags: transfer preparation flags + * @config: DMA slave configuration for this transfer + * + * Detail see dmaengine_prep_config_sg_safe(). + */ +static inline struct dma_async_tx_descriptor * +dmaengine_prep_config_single_safe(struct dma_chan *chan, dma_addr_t buf, + size_t len, enum dma_transfer_direction dir, + unsigned long flags, + struct dma_slave_config *config) +{ + struct scatterlist sg; + + sg_init_table(&sg, 1); + sg_dma_address(&sg) = buf; + sg_dma_len(&sg) = len; + + return dmaengine_prep_config_sg_safe(chan, &sg, 1, dir, flags, config); +} + #ifdef CONFIG_RAPIDIO_DMA_ENGINE struct rio_dma_ext; static inline struct dma_async_tx_descriptor *dmaengine_prep_rio_sg( diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 692b2b445761..63e35df2cef4 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -24,6 +24,7 @@ struct acpi_dmar_header; #define DMAR_INTR_REMAP 0x1 #define DMAR_X2APIC_OPT_OUT 0x2 #define DMAR_PLATFORM_OPT_IN 0x4 +#define DMAR_REMAP_OPT_OUT 0x8 struct intel_iommu; diff --git a/include/linux/dmi.h b/include/linux/dmi.h index c8700e6a694d..fbb62f7c3111 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -4,7 +4,7 @@ #include <linux/list.h> #include <linux/kobject.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/dmi.h> /* enum dmi_field is in mod_devicetable.h */ diff --git a/include/linux/efi.h b/include/linux/efi.h index ccbc35479684..aa15ff88539b 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -705,7 +705,7 @@ efi_guidcmp (efi_guid_t left, efi_guid_t right) } static inline char * -efi_guid_to_str(efi_guid_t *guid, char *out) +efi_guid_to_str(const efi_guid_t *guid, char *out) { sprintf(out, "%pUl", guid->b); return out; @@ -1212,8 +1212,8 @@ efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *), /* * efi_runtime_service() function identifiers. - * "NONE" is used by efi_recover_from_page_fault() to check if the page - * fault happened while executing an efi runtime service. + * "NONE" is used by efi_crash_gracefully_on_page_fault() to check if the + * page fault happened while executing an efi runtime service. */ enum efi_rts_ids { EFI_NONE, @@ -1256,6 +1256,8 @@ extern struct efi_runtime_work efi_rts_work; /* Workqueue to queue EFI Runtime Services */ extern struct workqueue_struct *efi_rts_wq; +void __noreturn efi_rts_park_worker(void); + struct linux_efi_memreserve { int size; // allocated size of the array atomic_t count; // number of entries used diff --git a/include/linux/efs_vh.h b/include/linux/efs_vh.h deleted file mode 100644 index 206c5270f7b8..000000000000 --- a/include/linux/efs_vh.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * efs_vh.h - * - * Copyright (c) 1999 Al Smith - * - * Portions derived from IRIX header files (c) 1985 MIPS Computer Systems, Inc. - */ - -#ifndef __EFS_VH_H__ -#define __EFS_VH_H__ - -#define VHMAGIC 0xbe5a941 /* volume header magic number */ -#define NPARTAB 16 /* 16 unix partitions */ -#define NVDIR 15 /* max of 15 directory entries */ -#define BFNAMESIZE 16 /* max 16 chars in boot file name */ -#define VDNAMESIZE 8 - -struct volume_directory { - char vd_name[VDNAMESIZE]; /* name */ - __be32 vd_lbn; /* logical block number */ - __be32 vd_nbytes; /* file length in bytes */ -}; - -struct partition_table { /* one per logical partition */ - __be32 pt_nblks; /* # of logical blks in partition */ - __be32 pt_firstlbn; /* first lbn of partition */ - __be32 pt_type; /* use of partition */ -}; - -struct volume_header { - __be32 vh_magic; /* identifies volume header */ - __be16 vh_rootpt; /* root partition number */ - __be16 vh_swappt; /* swap partition number */ - char vh_bootfile[BFNAMESIZE]; /* name of file to boot */ - char pad[48]; /* device param space */ - struct volume_directory vh_vd[NVDIR]; /* other vol hdr contents */ - struct partition_table vh_pt[NPARTAB]; /* device partition layout */ - __be32 vh_csum; /* volume header checksum */ - __be32 vh_fill; /* fill out to 512 bytes */ -}; - -/* partition type sysv is used for EFS format CD-ROM partitions */ -#define SGI_SYSV 0x05 -#define SGI_EFS 0x07 -#define IS_EFS(x) (((x) == SGI_EFS) || ((x) == SGI_SYSV)) - -struct pt_types { - int pt_type; - char *pt_name; -}; - -#endif /* __EFS_VH_H__ */ - diff --git a/include/linux/eisa.h b/include/linux/eisa.h index cf55630b595b..52a97dc4c85a 100644 --- a/include/linux/eisa.h +++ b/include/linux/eisa.h @@ -4,7 +4,7 @@ #include <linux/ioport.h> #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/eisa.h> #define EISA_MAX_SLOTS 8 diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h index 416a3352261f..6574b7183c01 100644 --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h @@ -6,9 +6,11 @@ #include <linux/irq-entry-common.h> #include <linux/livepatch.h> #include <linux/ptrace.h> +#include <linux/randomize_kstack.h> #include <linux/resume_user_mode.h> #include <linux/seccomp.h> #include <linux/sched.h> +#include <linux/syscall_user_dispatch.h> #include <asm/entry-common.h> #include <asm/syscall.h> @@ -18,7 +20,7 @@ #endif /* - * SYSCALL_WORK flags handled in syscall_enter_from_user_mode() + * SYSCALL_WORK flags handled in syscall_enter_from_user_mode_work() */ #define SYSCALL_WORK_ENTER (SYSCALL_WORK_SECCOMP | \ SYSCALL_WORK_SYSCALL_TRACEPOINT | \ @@ -37,42 +39,32 @@ SYSCALL_WORK_SYSCALL_EXIT_TRAP) /** - * arch_ptrace_report_syscall_entry - Architecture specific ptrace_report_syscall_entry() wrapper + * arch_ptrace_report_syscall_permit_entry - Architecture specific wrapper for + * ptrace_report_syscall_permit_entry() * @regs: Pointer to the register state at syscall entry * - * Invoked from syscall_trace_enter() to wrap ptrace_report_syscall_entry(). + * Invoked from syscall_trace_enter() to wrap ptrace_report_syscall_permit_entry(). * - * This allows architecture specific ptrace_report_syscall_entry() + * This allows architecture specific ptrace_report_syscall_permit_entry() * implementations. If not defined by the architecture this falls back to - * to ptrace_report_syscall_entry(). + * to ptrace_report_syscall_permit_entry(). */ -static __always_inline int arch_ptrace_report_syscall_entry(struct pt_regs *regs); +static __always_inline bool arch_ptrace_report_syscall_permit_entry(struct pt_regs *regs); -#ifndef arch_ptrace_report_syscall_entry -static __always_inline int arch_ptrace_report_syscall_entry(struct pt_regs *regs) +#ifndef arch_ptrace_report_syscall_permit_entry +static __always_inline bool arch_ptrace_report_syscall_permit_entry(struct pt_regs *regs) { - return ptrace_report_syscall_entry(regs); + return ptrace_report_syscall_permit_entry(regs); } #endif -bool syscall_user_dispatch(struct pt_regs *regs); -long trace_syscall_enter(struct pt_regs *regs, long syscall); +void trace_syscall_enter(struct pt_regs *regs); void trace_syscall_exit(struct pt_regs *regs, long ret); +void syscall_enter_audit(struct pt_regs *regs); -static inline void syscall_enter_audit(struct pt_regs *regs, long syscall) +static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned long work, + long syscall) { - if (unlikely(audit_context())) { - unsigned long args[6]; - - syscall_get_arguments(current, regs, args); - audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]); - } -} - -static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned long work) -{ - long syscall, ret = 0; - /* * Handle Syscall User Dispatch. This must comes first, since * the ABI here can be something that doesn't make sense for @@ -80,7 +72,7 @@ static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned l */ if (work & SYSCALL_WORK_SYSCALL_USER_DISPATCH) { if (syscall_user_dispatch(regs)) - return -1L; + return false; } /* @@ -89,31 +81,31 @@ static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned l * through hrtimer_interrupt(). */ if (work & SYSCALL_WORK_SYSCALL_RSEQ_SLICE) - rseq_syscall_enter_work(syscall_get_nr(current, regs)); + rseq_syscall_enter_work(syscall); /* Handle ptrace */ if (work & (SYSCALL_WORK_SYSCALL_TRACE | SYSCALL_WORK_SYSCALL_EMU)) { - ret = arch_ptrace_report_syscall_entry(regs); - if (ret || (work & SYSCALL_WORK_SYSCALL_EMU)) - return -1L; + if (!arch_ptrace_report_syscall_permit_entry(regs) || + (work & SYSCALL_WORK_SYSCALL_EMU)) + return false; + + /* ptrace might have changed work flags */ + work = READ_ONCE(current_thread_info()->syscall_work); } /* Do seccomp after ptrace, to catch any tracer changes. */ if (work & SYSCALL_WORK_SECCOMP) { - ret = __secure_computing(); - if (ret == -1L) - return ret; + if (!__seccomp_permit_syscall()) + return false; } - /* Either of the above might have changed the syscall number */ - syscall = syscall_get_nr(current, regs); - if (unlikely(work & SYSCALL_WORK_SYSCALL_TRACEPOINT)) - syscall = trace_syscall_enter(regs, syscall); + trace_syscall_enter(regs); - syscall_enter_audit(regs, syscall); + if (unlikely(audit_context())) + syscall_enter_audit(regs); - return ret ? : syscall; + return true; } /** @@ -122,36 +114,63 @@ static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned l * @regs: Pointer to currents pt_regs * @syscall: The syscall number * - * Invoked from architecture specific syscall entry code with interrupts - * enabled after invoking enter_from_user_mode(), enabling interrupts and - * extra architecture specific work. + * Invoked from architecture specific syscall entry code with interrupts enabled + * after invoking enter_from_user_mode(), enabling interrupts and extra + * architecture specific work with the syscall return value preset to -ENOSYS. * - * Returns: The original or a modified syscall number + * Returns: True if the syscall should be invoked, False otherwise. * - * If the returned syscall number is -1 then the syscall should be - * skipped. In this case the caller may invoke syscall_set_error() or - * syscall_set_return_value() first. If neither of those are called and -1 - * is returned, then the syscall will fail with ENOSYS. + * If the return value is false, the caller must skip the syscall and leave the + * syscall return value unmodified as it might have been set by one of the entry + * work functions. * * It handles the following work items: * * 1) syscall_work flag dependent invocations of - * ptrace_report_syscall_entry(), __secure_computing(), trace_sys_enter() + * ptrace_report_syscall_permit_entry(), __seccomp_permit_syscall(), trace_sys_enter() * 2) Invocation of audit_syscall_entry() */ -static __always_inline long syscall_enter_from_user_mode_work(struct pt_regs *regs, long syscall) +static __always_inline bool syscall_enter_from_user_mode_work(struct pt_regs *regs, long *syscall) { unsigned long work = READ_ONCE(current_thread_info()->syscall_work); - if (work & SYSCALL_WORK_ENTER) - syscall = syscall_trace_enter(regs, work); + if (!(work & SYSCALL_WORK_ENTER)) + return true; + + if (unlikely(!syscall_trace_enter(regs, work, *syscall))) + return false; - return syscall; + /* Reread the syscall number as it might have been modified */ + *syscall = syscall_get_nr(current, regs); + + return true; } /** - * syscall_enter_from_user_mode - Establish state and check and handle work - * before invoking a syscall + * enter_from_user_mode_randomize_stack - Establish state and add stack randomization + * before invoking syscall_enter_from_user_mode_work() + * @regs: Pointer to currents pt_regs + * + * Invoked from architecture specific syscall entry code with interrupts + * disabled. The calling code has to be non-instrumentable. When the function + * returns all state is correct, interrupts are still disabled and the + * subsequent functions can be instrumented. + * + * Implemented as a macro so that the stack randomization is effective + * throughout the function in which it is invoked. An inline would only make it + * effective in the scope of the inline function. + */ +#define enter_from_user_mode_randomize_stack(regs) \ +do { \ + enter_from_user_mode(regs); \ + instrumentation_begin(); \ + add_random_kstack_offset_irqsoff(); \ + instrumentation_end(); \ +} while (0) + +/** + * syscall_enter_from_user_mode_randomize_stack - Establish state and check and handle work + * before invoking a syscall * @regs: Pointer to currents pt_regs * @syscall: The syscall number * @@ -160,31 +179,32 @@ static __always_inline long syscall_enter_from_user_mode_work(struct pt_regs *re * function returns all state is correct, interrupts are enabled and the * subsequent functions can be instrumented. * - * This is the combination of enter_from_user_mode() and + * This is the combination of enter_from_user_mode_randomize_stack() and * syscall_enter_from_user_mode_work() to be used when there is no * architecture specific work to be done between the two. * * Returns: The original or a modified syscall number. See * syscall_enter_from_user_mode_work() for further explanation. + * + * Implemented as a macro to make stack randomization effective in the calling + * scope. */ -static __always_inline long syscall_enter_from_user_mode(struct pt_regs *regs, long syscall) -{ - long ret; - - enter_from_user_mode(regs); - - instrumentation_begin(); - local_irq_enable(); - ret = syscall_enter_from_user_mode_work(regs, syscall); - instrumentation_end(); - - return ret; -} +#define syscall_enter_from_user_mode_randomize_stack(regs, syscall) \ +({ \ + enter_from_user_mode_randomize_stack(regs); \ + \ + instrumentation_begin(); \ + local_irq_enable(); \ + long _ret = syscall_enter_from_user_mode_work(regs, syscall); \ + instrumentation_end(); \ + \ + _ret; \ +}) /* - * If SYSCALL_EMU is set, then the only reason to report is when - * SINGLESTEP is set (i.e. PTRACE_SYSEMU_SINGLESTEP). This syscall - * instruction has been already reported in syscall_enter_from_user_mode(). + * If SYSCALL_EMU is set, then the only reason to report is when SINGLESTEP is + * set (i.e. PTRACE_SYSEMU_SINGLESTEP). This syscall instruction has been + * already reported in syscall_enter_from_user_mode_work(). */ static __always_inline bool report_single_step(unsigned long work) { @@ -232,10 +252,8 @@ static __always_inline void syscall_exit_work(struct pt_regs *regs, unsigned lon * of these syscalls is unknown. */ if (work & SYSCALL_WORK_SYSCALL_USER_DISPATCH) { - if (unlikely(current->syscall_dispatch.on_dispatch)) { - current->syscall_dispatch.on_dispatch = false; + if (syscall_user_dispatch_clear_on_dispatch()) return; - } } audit_syscall_exit(regs); diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 5d491a98265e..12683b5d125e 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -562,6 +562,7 @@ struct ethtool_fec_hist { u64 per_lane[ETHTOOL_MAX_LANES]; } values[ETHTOOL_FEC_HIST_MAX]; const struct ethtool_fec_hist_range *ranges; + struct ethtool_fec_hist_range ranges_buf[ETHTOOL_FEC_HIST_MAX]; }; /** * struct ethtool_fec_stats - statistics for IEEE 802.3 FEC diff --git a/include/linux/ethtool_netlink.h b/include/linux/ethtool_netlink.h index 39254b2726c0..15881f34ef66 100644 --- a/include/linux/ethtool_netlink.h +++ b/include/linux/ethtool_netlink.h @@ -7,9 +7,6 @@ #include <linux/ethtool.h> #include <linux/netdevice.h> -#define __ETHTOOL_LINK_MODE_MASK_NWORDS \ - DIV_ROUND_UP(__ETHTOOL_LINK_MODE_MASK_NBITS, 32) - #define ETHTOOL_PAUSE_STAT_CNT (__ETHTOOL_A_PAUSE_STAT_CNT - \ ETHTOOL_A_PAUSE_STAT_TX_FRAMES) diff --git a/include/linux/execmem.h b/include/linux/execmem.h index 7de229134e30..1bd34925d1aa 100644 --- a/include/linux/execmem.h +++ b/include/linux/execmem.h @@ -89,7 +89,7 @@ static inline int execmem_restore_rox(void *ptr, size_t size) { return 0; } * @end: address space end (inclusive) * @fallback_start: start of the secondary address space range for fallback * allocations on architectures that require it - * @fallback_end: start of the secondary address space (inclusive) + * @fallback_end: end of the secondary address space (inclusive) * @pgprot: permissions for memory in this address space * @alignment: alignment required for text allocations * @flags: options for memory allocations for this range diff --git a/include/linux/filter.h b/include/linux/filter.h index 67d337ede91b..4a9bc6a848f2 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -21,6 +21,7 @@ #include <linux/if_vlan.h> #include <linux/vmalloc.h> #include <linux/sockptr.h> +#include <linux/static_call.h> #include <linux/u64_stats_sync.h> #include <net/sch_generic.h> @@ -382,6 +383,61 @@ static inline bool insn_is_cast_user(const struct bpf_insn *insn) /* Legacy alias */ #define BPF_STX_XADD(SIZE, DST, SRC, OFF) BPF_ATOMIC_OP(SIZE, BPF_ADD, DST, SRC, OFF) +/* + * Given a BPF_ATOMIC instruction @atomic_insn, return true if it is an + * atomic load or store, and false if it is a read-modify-write instruction. + */ +static inline bool +bpf_atomic_is_load_store(const struct bpf_insn *atomic_insn) +{ + switch (atomic_insn->imm) { + case BPF_LOAD_ACQ: + case BPF_STORE_REL: + return true; + default: + return false; + } +} + +/* + * A load-acquire is the only BPF_STX class instruction that reads into + * dst_reg from src_reg + off16, i.e. it has the operand roles of a BPF_LDX. + * Unlike bpf_atomic_is_load_store(), @insn is not assumed to be a BPF_ATOMIC + * instruction here, so that callers which walk all instruction classes can + * use this directly. + */ +static inline bool bpf_atomic_is_load_acq(const struct bpf_insn *insn) +{ + return BPF_CLASS(insn->code) == BPF_STX && + (BPF_MODE(insn->code) == BPF_ATOMIC || + BPF_MODE(insn->code) == BPF_PROBE_ATOMIC) && + insn->imm == BPF_LOAD_ACQ; +} + +/* + * Given an instruction @insn, return the number of the BPF register that a + * BPF_ATOMIC reads the value at its memory operand into, or -1 if there is + * no such register. That is the register a BPF_PROBE_ATOMIC has to clear when + * the access faults. Like bpf_atomic_is_load_acq(), @insn is not assumed to + * be a BPF_ATOMIC here. + */ +static inline int bpf_atomic_load_reg(const struct bpf_insn *insn) +{ + if (BPF_CLASS(insn->code) != BPF_STX || + (BPF_MODE(insn->code) != BPF_ATOMIC && + BPF_MODE(insn->code) != BPF_PROBE_ATOMIC)) + return -1; + + switch (insn->imm) { + case BPF_LOAD_ACQ: + return insn->dst_reg; + case BPF_CMPXCHG: + return BPF_REG_0; + default: + return (insn->imm & BPF_FETCH) ? insn->src_reg : -1; + } +} + /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ #define BPF_ST_MEM(SIZE, DST, OFF, IMM) \ @@ -1182,6 +1238,7 @@ 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_arena_args(void); bool bpf_jit_supports_far_kfunc_call(void); bool bpf_jit_supports_exceptions(void); bool bpf_jit_supports_ptr_xchg(void); @@ -1210,25 +1267,12 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, #ifdef CONFIG_BPF_SYSCALL struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off, const struct bpf_insn *patch, u32 len); -struct bpf_insn_aux_data *bpf_dup_insn_aux_data(struct bpf_verifier_env *env); -void bpf_restore_insn_aux_data(struct bpf_verifier_env *env, - struct bpf_insn_aux_data *orig_insn_aux); #else static inline struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off, const struct bpf_insn *patch, u32 len) { return ERR_PTR(-ENOTSUPP); } - -static inline struct bpf_insn_aux_data *bpf_dup_insn_aux_data(struct bpf_verifier_env *env) -{ - return NULL; -} - -static inline void bpf_restore_insn_aux_data(struct bpf_verifier_env *env, - struct bpf_insn_aux_data *orig_insn_aux) -{ -} #endif /* CONFIG_BPF_SYSCALL */ int bpf_remove_insns(struct bpf_prog *prog, u32 off, u32 cnt); @@ -1314,6 +1358,15 @@ extern long bpf_jit_limit_max; typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size); +/* + * Flush the indirect branch predictors before reusing JIT memory, so that + * indirect jumps into a newly written program don't reuse predictions left + * behind by an old program that occupied the same space. + */ +void bpf_arch_pred_flush(void); +DECLARE_STATIC_CALL(bpf_arch_pred_flush, bpf_arch_pred_flush); +DECLARE_STATIC_KEY_FALSE(bpf_pred_flush_enabled); + void bpf_jit_fill_hole_with_zero(void *area, unsigned int size); struct bpf_binary_header * @@ -1323,12 +1376,13 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, void bpf_jit_binary_free(struct bpf_binary_header *hdr); u64 bpf_jit_alloc_exec_limit(void); void *bpf_jit_alloc_exec(unsigned long size); +void *bpf_jit_alloc_exec_rw(unsigned long size); void bpf_jit_free_exec(void *addr); void bpf_jit_free(struct bpf_prog *fp); struct bpf_binary_header * bpf_jit_binary_pack_hdr(const struct bpf_prog *fp); -void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns); +void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool was_classic); void bpf_prog_pack_free(void *ptr, u32 size); static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp) @@ -1342,7 +1396,8 @@ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **ro_image, unsigned int alignment, struct bpf_binary_header **rw_hdr, u8 **rw_image, - bpf_jit_fill_hole_t bpf_fill_ill_insns); + bpf_jit_fill_hole_t bpf_fill_ill_insns, + bool was_classic); int bpf_jit_binary_pack_finalize(struct bpf_binary_header *ro_header, struct bpf_binary_header *rw_header); void bpf_jit_binary_pack_free(struct bpf_binary_header *ro_header, diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 986d712e4d94..fd35a6570cd8 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -14,6 +14,7 @@ #include <linux/timer.h> #include <linux/types.h> #include <linux/workqueue.h> +#include <linux/device-id/ieee1394.h> #include <linux/atomic.h> #include <asm/byteorder.h> @@ -271,8 +272,6 @@ static inline void fw_unit_put(struct fw_unit *unit) #define fw_parent_device(unit) fw_device(unit->device.parent) -struct ieee1394_device_id; - struct fw_driver { struct device_driver driver; int (*probe)(struct fw_unit *unit, const struct ieee1394_device_id *id); diff --git a/include/linux/firmware/intel/stratix10-smc.h b/include/linux/firmware/intel/stratix10-smc.h index 9116512169dc..366309260121 100644 --- a/include/linux/firmware/intel/stratix10-smc.h +++ b/include/linux/firmware/intel/stratix10-smc.h @@ -67,6 +67,9 @@ * INTEL_SIP_SMC_STATUS_REJECTED: * Secure monitor software reject the service client's request. * + * INTEL_SIP_SMC_STATUS_NO_RESPONSE: + * Secure monitor software has no response for the request yet. + * * INTEL_SIP_SMC_STATUS_ERROR: * There is error during the process of service request. * @@ -77,6 +80,7 @@ #define INTEL_SIP_SMC_STATUS_OK 0x0 #define INTEL_SIP_SMC_STATUS_BUSY 0x1 #define INTEL_SIP_SMC_STATUS_REJECTED 0x2 +#define INTEL_SIP_SMC_STATUS_NO_RESPONSE 0x3 #define INTEL_SIP_SMC_STATUS_ERROR 0x4 #define INTEL_SIP_SMC_RSU_ERROR 0x7 @@ -430,6 +434,29 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS) /** + * Request INTEL_SIP_SMC_RSU_GET_DEVICE_INFO + * + * Sync call used by service driver at EL1 to query QSPI device info from FW + * + * Call register usage: + * a0 INTEL_SIP_SMC_RSU_GET_DEVICE_INFO + * a1-7 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK + * a1 erasesize0 | size0 + * a2 erasesize1 | size1 + * a3 erasesize2 | size2 + * a4 erasesize3 | size3 + * Or + * + * a0 INTEL_SIP_SMC_RSU_ERROR + */ +#define INTEL_SIP_SMC_FUNCID_RSU_GET_DEVICE_INFO 22 +#define INTEL_SIP_SMC_RSU_GET_DEVICE_INFO \ + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_GET_DEVICE_INFO) + +/** * Request INTEL_SIP_SMC_SERVICE_COMPLETED * Sync call to check if the secure world have completed service request * or not. @@ -493,7 +520,7 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) * a3 not used */ #define INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD 60 - #define INTEL_SIP_SMC_MBOX_SEND_CMD \ +#define INTEL_SIP_SMC_MBOX_SEND_CMD \ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD) /** @@ -606,7 +633,7 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) /** * Request INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE - * Sync call to send a signed certificate + * Async call to send a signed certificate * * Call register usage: * a0 INTEL_SIP_SMC_FCS_SEND_CERTIFICATE @@ -615,7 +642,7 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) * a3-a7 not used * * Return status: - * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_FCS_REJECTED + * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REJECTED * a1-a3 not used */ #define INTEL_SIP_SMC_FUNCID_FCS_SEND_CERTIFICATE 93 @@ -631,9 +658,11 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) * a1-a7 not used * * Return status: - * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FCS_ERROR or - * INTEL_SIP_SMC_FCS_REJECTED - * a1-a3 not used + * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_ERROR or + * INTEL_SIP_SMC_STATUS_REJECTED + * a1 mailbox error if a0 is INTEL_SIP_SMC_STATUS_ERROR + * a2 physical address for the structure of fuse and key hashes + * a3 the size of structure * */ #define INTEL_SIP_SMC_FUNCID_FCS_GET_PROVISION_DATA 94 @@ -696,6 +725,44 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_POLL) /** + * Request INTEL_SIP_SMC_ASYNC_HWMON_READTEMP + * Async call to request temperature + * + * Call register usage: + * a0 INTEL_SIP_SMC_ASYNC_HWMON_READTEMP + * a1 transaction job id + * a2 Temperature Channel + * a3-a17 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_REJECTED + * or INTEL_SIP_SMC_STATUS_BUSY + * a1-a17 not used + */ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_HWMON_READTEMP 0xE8 +#define INTEL_SIP_SMC_ASYNC_HWMON_READTEMP \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_HWMON_READTEMP) + +/** + * Request INTEL_SIP_SMC_ASYNC_HWMON_READVOLT + * Async call to request voltage + * + * Call register usage: + * a0 INTEL_SIP_SMC_ASYNC_HWMON_READVOLT + * a1 transaction job id + * a2 Voltage Channel + * a3-a17 not used + * + * Return status + * a0 INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_REJECTED + * or INTEL_SIP_SMC_STATUS_BUSY + * a1-a17 not used + */ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_HWMON_READVOLT 0xE9 +#define INTEL_SIP_SMC_ASYNC_HWMON_READVOLT \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_HWMON_READVOLT) + +/** * Request INTEL_SIP_SMC_ASYNC_RSU_GET_SPT * Async call to get RSU SPT from SDM. * Call register usage: diff --git a/include/linux/firmware/intel/stratix10-svc-client.h b/include/linux/firmware/intel/stratix10-svc-client.h index 3edd93502bf8..af13dacdf5ac 100644 --- a/include/linux/firmware/intel/stratix10-svc-client.h +++ b/include/linux/firmware/intel/stratix10-svc-client.h @@ -128,6 +128,10 @@ struct stratix10_svc_chan; * @COMMAND_RSU_DCMF_STATUS: query firmware for the DCMF status * return status is SVC_STATUS_OK or SVC_STATUS_ERROR * + * @COMMAND_RSU_GET_DEVICE_INFO: query firmware for QSPI device info; + * return status is SVC_STATUS_OK, SVC_STATUS_ERROR, or SVC_STATUS_NO_SUPPORT + * (unsupported command / firmware compatibility path in the service layer). + * * @COMMAND_RSU_GET_SPT_TABLE: query firmware for SPT table * return status is SVC_STATUS_OK or SVC_STATUS_ERROR * @@ -174,6 +178,7 @@ enum stratix10_svc_command_code { COMMAND_RSU_MAX_RETRY, COMMAND_RSU_DCMF_VERSION, COMMAND_RSU_DCMF_STATUS, + COMMAND_RSU_GET_DEVICE_INFO, COMMAND_FIRMWARE_VERSION, COMMAND_RSU_GET_SPT_TABLE, /* for FCS */ @@ -224,7 +229,12 @@ struct stratix10_svc_command_config_type { /** * struct stratix10_svc_cb_data - callback data structure from service layer * @status: the status of sent command - * @kaddr1: address of 1st completed data block + * @kaddr1: address of 1st completed data block, or command-specific payload. + * For COMMAND_RSU_GET_DEVICE_INFO on SVC_STATUS_OK or SVC_STATUS_ERROR, + * points to struct arm_smccc_1_2_regs filled by the SMC/HVC return + * registers (a0 status, a1-a4 packed device words per + * INTEL_SIP_SMC_RSU_GET_DEVICE_INFO). On SVC_STATUS_NO_SUPPORT (older + * firmware that does not handle this command), kaddr1 is NULL. * @kaddr2: address of 2nd completed data block * @kaddr3: address of 3rd completed data block */ diff --git a/include/linux/firmware/qcom/qcom_pas.h b/include/linux/firmware/qcom/qcom_pas.h new file mode 100644 index 000000000000..fb2ec3be6a16 --- /dev/null +++ b/include/linux/firmware/qcom/qcom_pas.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (C) 2015 Linaro Ltd. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __QCOM_PAS_H +#define __QCOM_PAS_H + +#include <linux/device.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/types.h> + +struct qcom_pas_context { + struct device *dev; + u32 pas_id; + phys_addr_t mem_phys; + size_t mem_size; + void *ptr; + dma_addr_t phys; + ssize_t size; + bool use_tzmem; +}; + +static inline void __iomem *qcom_pas_ctx_map(struct qcom_pas_context *ctx) +{ + void __iomem *ptr = ioremap_wc(ctx->mem_phys, ctx->mem_size); + + if (!ptr) + dev_err(ctx->dev, "unable to map memory region: %pa+%zx\n", + &ctx->mem_phys, ctx->mem_size); + return ptr; +} + +bool qcom_pas_is_available(void); +struct qcom_pas_context *devm_qcom_pas_context_alloc(struct device *dev, + u32 pas_id, + phys_addr_t mem_phys, + size_t mem_size); +int qcom_pas_init_image(u32 pas_id, const void *metadata, size_t size, + struct qcom_pas_context *ctx); +struct resource_table *qcom_pas_get_rsc_table(struct qcom_pas_context *ctx, + void *input_rt, size_t input_rt_size, + size_t *output_rt_size); +int qcom_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size); +int qcom_pas_auth_and_reset(u32 pas_id); +int qcom_pas_prepare_and_auth_reset(struct qcom_pas_context *ctx); +int qcom_pas_set_remote_state(u32 state, u32 pas_id); +int qcom_pas_shutdown(u32 pas_id); +bool qcom_pas_supported(u32 pas_id); +void qcom_pas_metadata_release(struct qcom_pas_context *ctx); + +#endif /* __QCOM_PAS_H */ diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index 7e27b0f7bf7e..f4b3df614c77 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -3,7 +3,7 @@ * Xilinx Zynq MPSoC Firmware layer * * Copyright (C) 2014-2021 Xilinx - * Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc. + * Copyright (C) 2022 - 2026 Advanced Micro Devices, Inc. * * Michal Simek <michal.simek@amd.com> * Davorin Mista <davorin.mista@aggios.com> @@ -50,6 +50,7 @@ /* PM API versions */ #define PM_API_VERSION_1 1 #define PM_API_VERSION_2 2 +#define PM_API_VERSION_3 3 #define PM_PINCTRL_PARAM_SET_VERSION 2 @@ -66,6 +67,7 @@ #define FIRMWARE_VERSION_MASK 0xFFFFU /* ATF only commands */ +#define TF_A_CLEAR_PM_STATE 0xa05 #define TF_A_PM_REGISTER_SGI 0xa04 #define PM_GET_TRUSTZONE_VERSION 0xa03 #define PM_SET_SUSPEND_MODE 0xa02 @@ -144,6 +146,12 @@ #define XPM_EVENT_ERROR_MASK_NOC_NCR BIT(13) #define XPM_EVENT_ERROR_MASK_NOC_CR BIT(12) +/* Node ID for all peripheral devices */ +#define PM_DEV_ALL_PERIPH 0x18224FFFU + +/* Node ID for all notifier callbacks */ +#define PM_ALL_NOTIFIERS 0xFFFFFFFFU + enum pm_module_id { PM_MODULE_ID = 0x0, XPM_MODULE_ID = 0x2, @@ -644,6 +652,8 @@ 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_start_rpu(const u32 node, const u64 bootaddr); +int zynqmp_pm_stop_rpu(const u32 node); 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); @@ -960,6 +970,16 @@ static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const statu return -ENODEV; } +static inline int zynqmp_pm_start_rpu(const u32 node, const u64 bootaddr) +{ + return -ENODEV; +} + +static inline int zynqmp_pm_stop_rpu(const u32 node) +{ + 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/fixp-arith.h b/include/linux/fixp-arith.h index e485fb0c1201..4d4f4a7d4749 100644 --- a/include/linux/fixp-arith.h +++ b/include/linux/fixp-arith.h @@ -40,7 +40,7 @@ static const s32 sin_table[] = { }; /** - * __fixp_sin32() returns the sin of an angle in degrees + * __fixp_sin32() - returns the sin of an angle in degrees * * @degrees: angle, in degrees, from 0 to 360. * @@ -64,7 +64,7 @@ static inline s32 __fixp_sin32(int degrees) } /** - * fixp_sin32() returns the sin of an angle in degrees + * fixp_sin32() - returns the sin of an angle in degrees * * @degrees: angle, in degrees. The angle can be positive or negative * diff --git a/include/linux/font.h b/include/linux/font.h index 6845f02d739a..5e1cf9830084 100644 --- a/include/linux/font.h +++ b/include/linux/font.h @@ -49,6 +49,8 @@ static inline unsigned int font_glyph_pitch(unsigned int width) * scanlines, which is usually the glyph's height in scanlines. Fonts * coming from user space can sometimes have a different vertical pitch * with empty scanlines between two adjacent glyphs. + * + * Returns: the number of bytes per glyph */ static inline unsigned int font_glyph_size(unsigned int width, unsigned int vpitch) { @@ -60,7 +62,7 @@ static inline unsigned int font_glyph_size(unsigned int width, unsigned int vpit */ /** - * font_data_t - Raw font data + * typedef font_data_t - Raw font data * * Values of type font_data_t store a pointer to raw font data. The format * is monochrome. Each bit sets a pixel of a stored glyph. Font data does @@ -101,6 +103,9 @@ font_data_t *font_data_import(const struct console_font *font, unsigned int vpit void font_data_get(font_data_t *fd); bool font_data_put(font_data_t *fd); unsigned int font_data_size(font_data_t *fd); +const unsigned char *font_data_glyph_buf(font_data_t *fd, + unsigned int width, unsigned int vpitch, + unsigned int c); bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs); int font_data_export(font_data_t *fd, struct console_font *font, unsigned int vpitch); diff --git a/include/linux/fs.h b/include/linux/fs.h index d10897b3a1e3..f9d1e05e8ae6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -438,7 +438,6 @@ struct address_space_operations { int (*swap_activate)(struct swap_info_struct *sis, struct file *file, sector_t *span); void (*swap_deactivate)(struct file *file); - int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter); }; extern const struct address_space_operations empty_aops; @@ -740,7 +739,8 @@ enum inode_state_flags_enum { I_CREATING = (1U << 15), I_DONTCACHE = (1U << 16), I_SYNC_QUEUED = (1U << 17), - I_PINNING_NETFS_WB = (1U << 18) + I_PINNING_NETFS_WB = (1U << 18), + I_METADATA_WRITEBACK = (1U << 19), }; #define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC) @@ -1598,12 +1598,12 @@ struct timespec64 inode_set_ctime_deleg(struct inode *inode, static inline time64_t inode_get_atime_sec(const struct inode *inode) { - return inode->i_atime_sec; + return READ_ONCE(inode->i_atime_sec); } static inline long inode_get_atime_nsec(const struct inode *inode) { - return inode->i_atime_nsec; + return READ_ONCE(inode->i_atime_nsec); } static inline struct timespec64 inode_get_atime(const struct inode *inode) @@ -1617,8 +1617,8 @@ static inline struct timespec64 inode_get_atime(const struct inode *inode) static inline struct timespec64 inode_set_atime_to_ts(struct inode *inode, struct timespec64 ts) { - inode->i_atime_sec = ts.tv_sec; - inode->i_atime_nsec = ts.tv_nsec; + WRITE_ONCE(inode->i_atime_sec, ts.tv_sec); + WRITE_ONCE(inode->i_atime_nsec, ts.tv_nsec); return ts; } @@ -1633,12 +1633,12 @@ static inline struct timespec64 inode_set_atime(struct inode *inode, static inline time64_t inode_get_mtime_sec(const struct inode *inode) { - return inode->i_mtime_sec; + return READ_ONCE(inode->i_mtime_sec); } static inline long inode_get_mtime_nsec(const struct inode *inode) { - return inode->i_mtime_nsec; + return READ_ONCE(inode->i_mtime_nsec); } static inline struct timespec64 inode_get_mtime(const struct inode *inode) @@ -1651,8 +1651,8 @@ static inline struct timespec64 inode_get_mtime(const struct inode *inode) static inline struct timespec64 inode_set_mtime_to_ts(struct inode *inode, struct timespec64 ts) { - inode->i_mtime_sec = ts.tv_sec; - inode->i_mtime_nsec = ts.tv_nsec; + WRITE_ONCE(inode->i_mtime_sec, ts.tv_sec); + WRITE_ONCE(inode->i_mtime_nsec, ts.tv_nsec); return ts; } @@ -1677,12 +1677,12 @@ static inline struct timespec64 inode_set_mtime(struct inode *inode, static inline time64_t inode_get_ctime_sec(const struct inode *inode) { - return inode->i_ctime_sec; + return READ_ONCE(inode->i_ctime_sec); } static inline long inode_get_ctime_nsec(const struct inode *inode) { - return inode->i_ctime_nsec & ~I_CTIME_QUERIED; + return READ_ONCE(inode->i_ctime_nsec) & ~I_CTIME_QUERIED; } static inline struct timespec64 inode_get_ctime(const struct inode *inode) @@ -1916,8 +1916,6 @@ struct dir_context { struct io_uring_cmd; struct offset_ctx; -typedef unsigned int __bitwise fop_flags_t; - struct file_operations { struct module *owner; fop_flags_t fop_flags; @@ -2002,7 +2000,7 @@ struct inode_operations { int (*readlink) (struct dentry *, char __user *,int); int (*create) (struct mnt_idmap *, struct inode *,struct dentry *, - umode_t, bool); + umode_t); int (*link) (struct dentry *,struct inode *,struct dentry *); int (*unlink) (struct inode *,struct dentry *); int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *, @@ -2213,6 +2211,13 @@ static inline void mark_inode_dirty_sync(struct inode *inode) __mark_inode_dirty(inode, I_DIRTY_SYNC); } +static inline void set_inode_metadata_writeback(struct inode *inode) +{ + spin_lock(&inode->i_lock); + inode_state_set(inode, I_METADATA_WRITEBACK); + spin_unlock(&inode->i_lock); +} + /* * returns the refcount on the inode. it can change arbitrarily. */ @@ -2413,6 +2418,21 @@ static inline void super_set_sysfs_name_generic(struct super_block *sb, const ch extern void ihold(struct inode * inode); extern void iput(struct inode *); void iput_not_last(struct inode *); + +/** + * iput_if_not_last - drop an inode reference only if it is not the last one + * @inode: inode to put + * + * Returns true if the reference was dropped, false if this was the last + * reference and the caller must arrange for final iput() in a safe context. + */ +static inline bool __must_check iput_if_not_last(struct inode *inode) +{ + VFS_BUG_ON_INODE(inode_state_read_once(inode) & (I_FREEING | I_CLEAR), inode); + VFS_BUG_ON_INODE(icount_read_once(inode) < 1, inode); + return atomic_add_unless(&inode->i_count, -1, 1); +} + int inode_update_time(struct inode *inode, enum fs_update_time type, unsigned int flags); int generic_update_time(struct inode *inode, enum fs_update_time type, @@ -2444,6 +2464,11 @@ static inline struct mnt_idmap *file_mnt_idmap(const struct file *file) return mnt_idmap(file->f_path.mnt); } +static inline bool file_owner_or_capable(const struct file *file) +{ + return inode_owner_or_capable(file_mnt_idmap(file), file_inode(file)); +} + /** * is_idmapped_mnt - check whether a mount is mapped * @mnt: the mount to check diff --git a/include/linux/fs/super.h b/include/linux/fs/super.h index 405612678115..733d439f01ed 100644 --- a/include/linux/fs/super.h +++ b/include/linux/fs/super.h @@ -237,4 +237,12 @@ int thaw_super(struct super_block *super, enum freeze_holder who, int sb_init_dio_done_wq(struct super_block *sb); +struct file; +struct file *fs_bdev_file_open_by_dev(dev_t dev, blk_mode_t mode, void *holder, + struct super_block *sb); +struct file *fs_bdev_file_open_by_path(const char *path, blk_mode_t mode, + void *holder, struct super_block *sb); +void fs_bdev_unregister(struct file *bdev_file, struct super_block *sb); +void fs_bdev_file_release(struct file *bdev_file, struct super_block *sb); + #endif /* _LINUX_FS_SUPER_H */ diff --git a/include/linux/fs/super_types.h b/include/linux/fs/super_types.h index ef7941e9dc79..ecd96aeb1cee 100644 --- a/include/linux/fs/super_types.h +++ b/include/linux/fs/super_types.h @@ -30,6 +30,7 @@ struct mount; struct mtd_info; struct quotactl_ops; struct shrinker; +struct super_dev; struct unicode_map; struct user_namespace; struct workqueue_struct; @@ -86,6 +87,8 @@ struct super_operations { void (*free_inode)(struct inode *inode); void (*dirty_inode)(struct inode *inode, int flags); int (*write_inode)(struct inode *inode, struct writeback_control *wbc); + int (*sync_inode_metadata)(struct inode *inode, + struct writeback_control *wbc); int (*drop_inode)(struct inode *inode); void (*evict_inode)(struct inode *inode); void (*put_super)(struct super_block *sb); @@ -132,6 +135,7 @@ struct super_operations { struct super_block { struct list_head s_list; /* Keep this first */ dev_t s_dev; /* search index; _not_ kdev_t */ + struct super_dev *s_super_dev; /* sget_fc()'s device table claim */ unsigned char s_blocksize_bits; unsigned long s_blocksize; loff_t s_maxbytes; /* Max file size */ @@ -145,7 +149,7 @@ struct super_block { unsigned long s_magic; struct dentry *s_root; struct rw_semaphore s_umount; - int s_count; + refcount_t s_passive; atomic_t s_active; #ifdef CONFIG_SECURITY void *s_security; @@ -300,7 +304,7 @@ struct super_block { #define SB_NODIRATIME BIT(11) /* Do not update directory access times */ #define SB_SILENT BIT(15) #define SB_POSIXACL BIT(16) /* Supports POSIX ACLs */ -#define SB_INLINECRYPT BIT(17) /* Use blk-crypto for encrypted files */ +#define SB_INLINECRYPT BIT(17) /* Use inline crypto hardware if available */ #define SB_KERNMOUNT BIT(22) /* this is a kern_mount call */ #define SB_I_VERSION BIT(23) /* Update inode I_version field */ #define SB_LAZYTIME BIT(25) /* Update the on-disk [acm]times lazily */ diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index 0070764b790a..97eef8d3863d 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -6,6 +6,7 @@ #include <linux/path.h> #include <linux/spinlock.h> #include <linux/seqlock.h> +#include <linux/vfsdebug.h> struct fs_struct { int users; @@ -16,6 +17,7 @@ struct fs_struct { } __randomize_layout; extern struct kmem_cache *fs_cachep; +extern struct fs_struct *userspace_init_fs; extern void exit_fs(struct task_struct *); extern void set_fs_root(struct fs_struct *, const struct path *); @@ -40,6 +42,8 @@ static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) read_sequnlock_excl(&fs->seq); } +struct fs_struct *switch_fs_struct(struct fs_struct *new_fs); + extern bool current_chrooted(void); static inline int current_umask(void) @@ -47,4 +51,34 @@ static inline int current_umask(void) return current->fs->umask; } +/* + * Temporarily use userspace_init_fs for path resolution in kthreads. + * Callers should use scoped_with_init_fs() which automatically + * restores the original fs_struct at scope exit. + */ +static inline struct fs_struct *__override_init_fs(void) +{ + struct fs_struct *old_fs; + + old_fs = current->fs; + WRITE_ONCE(current->fs, userspace_init_fs); + return old_fs; +} + +static inline void __revert_init_fs(struct fs_struct *old_fs) +{ + VFS_WARN_ON_ONCE(current->fs != userspace_init_fs); + WRITE_ONCE(current->fs, old_fs); +} + +DEFINE_CLASS(__override_init_fs, + struct fs_struct *, + __revert_init_fs(_T), + __override_init_fs(), void) + +#define scoped_with_init_fs() \ + scoped_class(__override_init_fs, __UNIQUE_ID(label)) + +void __init init_userspace_fs(void); + #endif /* _LINUX_FS_STRUCT_H */ diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 54712ec61ffb..28f2108e29f3 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -57,6 +57,9 @@ struct fscrypt_name { /* Maximum value for the third parameter of fscrypt_operations.set_context(). */ #define FSCRYPT_SET_CONTEXT_MAX_SIZE 40 +/* Maximum supported number of block devices per filesystem */ +#define FSCRYPT_MAX_DEVICES 8 + #ifdef CONFIG_FS_ENCRYPTION /* Crypto operations for filesystems */ @@ -69,14 +72,15 @@ struct fscrypt_operations { ptrdiff_t inode_info_offs; /* - * If set, then fs/crypto/ will allocate a global bounce page pool the - * first time an encryption key is set up for a file. The bounce page - * pool is required by the following functions: - * - * - fscrypt_encrypt_pagecache_blocks() - * - fscrypt_zeroout_range() for files not using inline crypto - * - * If the filesystem doesn't use those, it doesn't need to set this. + * Set to 1 if the filesystem is block-based. This causes fs/crypto/ to + * set up the key for regular files as a blk_crypto_key. The filesystem + * then uses fscrypt_set_bio_crypt_ctx() and similar functions. + */ + unsigned int is_block_based : 1; + + /* + * Set to 1 if the filesystem uses fscrypt_encrypt_pagecache_blocks(). + * This enables the allocation of the bounce page pool it requires. */ unsigned int needs_bounce_pages : 1; @@ -181,21 +185,20 @@ struct fscrypt_operations { bool (*has_stable_inodes)(struct super_block *sb); /* - * Return an array of pointers to the block devices to which the - * filesystem may write encrypted file contents, NULL if the filesystem - * only has a single such block device, or an ERR_PTR() on error. + * Retrieve the list of block devices to which the filesystem may write + * encrypted file contents. * - * On successful non-NULL return, *num_devs is set to the number of - * devices in the returned array. The caller must free the returned - * array using kfree(). + * This writes the block_device pointers to @devs and returns the count + * (between 1 and FSCRYPT_MAX_DEVICES inclusively). * * If the filesystem can use multiple block devices (other than block * devices that aren't used for encrypted file contents, such as * external journal devices), and wants to support inline encryption, * then it must implement this function. Otherwise it's not needed. */ - struct block_device **(*get_devices)(struct super_block *sb, - unsigned int *num_devs); + unsigned int (*get_devices)( + struct super_block *sb, + struct block_device *devs[FSCRYPT_MAX_DEVICES]); }; int fscrypt_d_revalidate(struct inode *dir, const struct qstr *name, @@ -342,7 +345,6 @@ static inline void fscrypt_prepare_dentry(struct dentry *dentry, } /* crypto.c */ -void fscrypt_enqueue_decrypt_work(struct work_struct *); struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio, size_t len, size_t offs, gfp_t gfp_flags); @@ -350,8 +352,6 @@ int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num); -int fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len, - size_t offs); int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num); @@ -448,11 +448,6 @@ bool fscrypt_match_name(const struct fscrypt_name *fname, const u8 *de_name, u32 de_name_len); u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name); -/* bio.c */ -bool fscrypt_decrypt_bio(struct bio *bio); -int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, - sector_t sector, u64 len); - /* hooks.c */ int fscrypt_file_open(struct inode *inode, struct file *filp); int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, @@ -509,9 +504,6 @@ static inline void fscrypt_prepare_dentry(struct dentry *dentry, } /* crypto.c */ -static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work) -{ -} static inline struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio, size_t len, size_t offs, gfp_t gfp_flags) @@ -527,12 +519,6 @@ static inline int fscrypt_encrypt_block_inplace(const struct inode *inode, return -EOPNOTSUPP; } -static inline int fscrypt_decrypt_pagecache_blocks(struct folio *folio, - size_t len, size_t offs) -{ - return -EOPNOTSUPP; -} - static inline int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, @@ -749,18 +735,6 @@ static inline int fscrypt_d_revalidate(struct inode *dir, const struct qstr *nam return 1; } -/* bio.c */ -static inline bool fscrypt_decrypt_bio(struct bio *bio) -{ - return true; -} - -static inline int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, - sector_t sector, u64 len) -{ - return -EOPNOTSUPP; -} - /* hooks.c */ static inline int fscrypt_file_open(struct inode *inode, struct file *filp) @@ -860,28 +834,21 @@ static inline void fscrypt_set_ops(struct super_block *sb, #endif /* !CONFIG_FS_ENCRYPTION */ -/* inline_crypt.c */ +/* block.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT -bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode); - void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, loff_t pos, gfp_t gfp_mask); bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, loff_t pos); -bool fscrypt_dio_supported(struct inode *inode); - u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks); +int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, + sector_t sector, u64 len); #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ -static inline bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode) -{ - return false; -} - static inline void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, loff_t pos, gfp_t gfp_mask) { } @@ -893,47 +860,18 @@ static inline bool fscrypt_mergeable_bio(struct bio *bio, return true; } -static inline bool fscrypt_dio_supported(struct inode *inode) -{ - return !fscrypt_needs_contents_encryption(inode); -} - static inline u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks) { return nr_blocks; } -#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ -/** - * fscrypt_inode_uses_inline_crypto() - test whether an inode uses inline - * encryption - * @inode: an inode. If encrypted, its key must be set up. - * - * Return: true if the inode requires file contents encryption and if the - * encryption should be done in the block layer via blk-crypto rather - * than in the filesystem layer. - */ -static inline bool fscrypt_inode_uses_inline_crypto(const struct inode *inode) -{ - return fscrypt_needs_contents_encryption(inode) && - __fscrypt_inode_uses_inline_crypto(inode); -} - -/** - * fscrypt_inode_uses_fs_layer_crypto() - test whether an inode uses fs-layer - * encryption - * @inode: an inode. If encrypted, its key must be set up. - * - * Return: true if the inode requires file contents encryption and if the - * encryption should be done in the filesystem layer rather than in the - * block layer via blk-crypto. - */ -static inline bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode) +static inline int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, + sector_t sector, u64 len) { - return fscrypt_needs_contents_encryption(inode) && - !__fscrypt_inode_uses_inline_crypto(inode); + return -EOPNOTSUPP; } +#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ /** * fscrypt_has_encryption_key() - check whether an inode has had its key set up @@ -1121,15 +1059,4 @@ static inline int fscrypt_encrypt_symlink(struct inode *inode, return 0; } -/* If *pagep is a bounce page, free it and set *pagep to the pagecache page */ -static inline void fscrypt_finalize_bounce_page(struct page **pagep) -{ - struct page *page = *pagep; - - if (fscrypt_is_bounce_page(page)) { - *pagep = fscrypt_pagecache_page(page); - fscrypt_free_bounce_page(page); - } -} - #endif /* _LINUX_FSCRYPT_H */ diff --git a/include/linux/fsl/guts.h b/include/linux/fsl/guts.h index fdb55ca47a4f..8d5ffb985fee 100644 --- a/include/linux/fsl/guts.h +++ b/include/linux/fsl/guts.h @@ -13,6 +13,7 @@ #include <linux/types.h> #include <linux/io.h> +#include <soc/fsl/phy-fsl-lynx.h> /* * Global Utility Registers. @@ -91,9 +92,15 @@ struct ccsr_guts { u32 iovselsr; /* 0x.00c0 - I/O voltage select status register Called 'elbcvselcr' on 86xx SOCs */ u8 res0c4[0x100 - 0xc4]; - u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers - There are 16 registers */ - u8 res140[0x224 - 0x140]; + /* 0x.0100 - read-only Reset Configuration Word Status registers in + * CCSR, or write-only Reset Configuration Word Control registers in + * DCSR. In both cases there are 32 registers. + */ + union { + u32 rcwsr[32]; + u32 rcwcr[32]; + }; + u8 res180[0x224 - 0x180]; u32 iodelay1; /* 0x.0224 - IO delay control register 1 */ u32 iodelay2; /* 0x.0228 - IO delay control register 2 */ u8 res22c[0x604 - 0x22c]; @@ -131,6 +138,11 @@ struct ccsr_guts { u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */ } __attribute__ ((packed)); +int fsl_guts_lane_validate(int serdes_idx, int lane, + enum lynx_lane_mode lane_mode); +int fsl_guts_lane_set_mode(int serdes_idx, int lane, + enum lynx_lane_mode lane_mode); + /* Alternate function signal multiplex control */ #define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x)) diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index 9f671e87c80c..c25f0f7e6dd4 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -11,7 +11,7 @@ #define _FSL_MC_H_ #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/fsl_mc.h> #include <linux/interrupt.h> #include <uapi/linux/fsl_mc.h> diff --git a/include/linux/fsl/ntmp.h b/include/linux/fsl/ntmp.h index d3b6c476b91a..764ef2892608 100644 --- a/include/linux/fsl/ntmp.h +++ b/include/linux/fsl/ntmp.h @@ -75,8 +75,10 @@ struct ntmp_user { /* NTMP table bitmaps for resource management */ u32 ett_bitmap_size; u32 ect_bitmap_size; + u16 maft_num_entries; unsigned long *ett_gid_bitmap; /* only valid for switch */ unsigned long *ect_gid_bitmap; /* only valid for switch */ + unsigned long *maft_eid_bitmap; /* only valid for ENETC */ }; struct maft_entry_data { diff --git a/include/linux/futex.h b/include/linux/futex.h index 51f4ccdc9092..18ed18d5cbc1 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -71,8 +71,8 @@ static inline void futex_init_task(struct task_struct *tsk) } void futex_exit_recursive(struct task_struct *tsk); -void futex_exit_release(struct task_struct *tsk); -void futex_exec_release(struct task_struct *tsk); +void futex_exit_exec_release(struct task_struct *tsk); +void futex_exec_done(struct task_struct *tsk); long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, u32 __user *uaddr2, u32 val2, u32 val3); @@ -89,8 +89,8 @@ static inline int futex_hash_free(struct mm_struct *mm) { return 0; } #else /* CONFIG_FUTEX */ static inline void futex_init_task(struct task_struct *tsk) { } static inline void futex_exit_recursive(struct task_struct *tsk) { } -static inline void futex_exit_release(struct task_struct *tsk) { } -static inline void futex_exec_release(struct task_struct *tsk) { } +static inline void futex_exit_exec_release(struct task_struct *tsk) { } +static inline void futex_exec_done(struct task_struct *tsk) { } static inline long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, u32 __user *uaddr2, u32 val2, u32 val3) { diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 4e86e6990d28..a9dcaf7e7076 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -117,6 +117,8 @@ struct fwnode_reference_args { * @put: Put a reference to an fwnode. * @device_is_available: Return true if the device is available. * @device_get_match_data: Return the device driver match data. + * @device_dma_supported: Return true if DMA is supported. + * @device_get_dma_attr: Return the device DMA attribute. * @property_present: Return true if a property is present. * @property_read_bool: Return a boolean property value. * @property_read_int_array: Read an array of integer properties. Return zero on @@ -134,6 +136,8 @@ struct fwnode_reference_args { * endpoint node. * @graph_get_port_parent: Return the parent node of a port node. * @graph_parse_endpoint: Parse endpoint for port and endpoint id. + * @iomap: Map the I/O memory of a given index for a fwnode. + * @irq_get: Get the IRQ of a given index for a fwnode. * @add_links: Create fwnode links to all the suppliers of the fwnode. Return * zero on success, a negative error code otherwise. */ diff --git a/include/linux/gfp.h b/include/linux/gfp.h index cdf95a9f0b87..872bc53f32ec 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -17,28 +17,6 @@ struct mempolicy; #define __default_gfp(a,b,...) b #define default_gfp(...) __default_gfp(,##__VA_ARGS__,GFP_KERNEL) -/* Convert GFP flags to their corresponding migrate type */ -#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE) -#define GFP_MOVABLE_SHIFT 3 - -static inline int gfp_migratetype(const gfp_t gfp_flags) -{ - VM_WARN_ON((gfp_flags & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK); - BUILD_BUG_ON((1UL << GFP_MOVABLE_SHIFT) != ___GFP_MOVABLE); - BUILD_BUG_ON((___GFP_MOVABLE >> GFP_MOVABLE_SHIFT) != MIGRATE_MOVABLE); - BUILD_BUG_ON((___GFP_RECLAIMABLE >> GFP_MOVABLE_SHIFT) != MIGRATE_RECLAIMABLE); - BUILD_BUG_ON(((___GFP_MOVABLE | ___GFP_RECLAIMABLE) >> - GFP_MOVABLE_SHIFT) != MIGRATE_HIGHATOMIC); - - if (unlikely(page_group_by_mobility_disabled)) - return MIGRATE_UNMOVABLE; - - /* Group based on mobility */ - return (__force unsigned long)(gfp_flags & GFP_MOVABLE_MASK) >> GFP_MOVABLE_SHIFT; -} -#undef GFP_MOVABLE_MASK -#undef GFP_MOVABLE_SHIFT - static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) { return !!(gfp_flags & __GFP_DIRECT_RECLAIM); @@ -226,10 +204,6 @@ static inline void arch_free_page(struct page *page, int order) { } static inline void arch_alloc_page(struct page *page, int order) { } #endif -struct page *__alloc_pages_noprof(gfp_t gfp, unsigned int order, int preferred_nid, - nodemask_t *nodemask); -#define __alloc_pages(...) alloc_hooks(__alloc_pages_noprof(__VA_ARGS__)) - struct folio *__folio_alloc_noprof(gfp_t gfp, unsigned int order, int preferred_nid, nodemask_t *nodemask); #define __folio_alloc(...) alloc_hooks(__folio_alloc_noprof(__VA_ARGS__)) @@ -278,25 +252,9 @@ static inline void warn_if_node_offline(int this_node, gfp_t gfp_mask) dump_stack(); } -/* - * Allocate pages, preferring the node given as nid. The node must be valid and - * online. For more general interface, see alloc_pages_node(). - */ -static inline struct page * -__alloc_pages_node_noprof(int nid, gfp_t gfp_mask, unsigned int order) -{ - VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES); - warn_if_node_offline(nid, gfp_mask); - - return __alloc_pages_noprof(gfp_mask, order, nid, NULL); -} - -#define __alloc_pages_node(...) alloc_hooks(__alloc_pages_node_noprof(__VA_ARGS__)) - static inline struct folio *__folio_alloc_node_noprof(gfp_t gfp, unsigned int order, int nid) { - VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES); warn_if_node_offline(nid, gfp); return __folio_alloc_noprof(gfp, order, nid, NULL); @@ -309,14 +267,7 @@ struct folio *__folio_alloc_node_noprof(gfp_t gfp, unsigned int order, int nid) * prefer the current CPU's closest node. Otherwise node must be valid and * online. */ -static inline struct page *alloc_pages_node_noprof(int nid, gfp_t gfp_mask, - unsigned int order) -{ - if (nid == NUMA_NO_NODE) - nid = numa_mem_id(); - - return __alloc_pages_node_noprof(nid, gfp_mask, order); -} +struct page *alloc_pages_node_noprof(int nid, gfp_t gfp_mask, unsigned int order); #define alloc_pages_node(...) alloc_hooks(alloc_pages_node_noprof(__VA_ARGS__)) @@ -395,10 +346,6 @@ extern void free_pages(unsigned long addr, unsigned int order); #define __free_page(page) __free_pages((page), 0) #define free_page(addr) free_pages((addr), 0) -void page_alloc_init_cpuhp(void); -bool decay_pcp_high(struct zone *zone, struct per_cpu_pages *pcp); -void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp); -void drain_all_pages(struct zone *zone); void drain_local_pages(struct zone *zone); void page_alloc_init_late(void); diff --git a/include/linux/gfp_types.h b/include/linux/gfp_types.h index 54ca0c88bab6..190191411009 100644 --- a/include/linux/gfp_types.h +++ b/include/linux/gfp_types.h @@ -55,7 +55,6 @@ enum { #ifdef CONFIG_LOCKDEP ___GFP_NOLOCKDEP_BIT, #endif - ___GFP_NO_OBJ_EXT_BIT, ___GFP_LAST_BIT }; @@ -96,7 +95,6 @@ enum { #else #define ___GFP_NOLOCKDEP 0 #endif -#define ___GFP_NO_OBJ_EXT BIT(___GFP_NO_OBJ_EXT_BIT) /* * Physical address zone modifiers (see linux/mmzone.h - low four bits) @@ -136,18 +134,14 @@ enum { * %__GFP_THISNODE forces the allocation to be satisfied from the requested * node with no fallbacks or placement policy enforcements. * - * %__GFP_ACCOUNT causes the allocation to be accounted to kmemcg. - * - * %__GFP_NO_OBJ_EXT causes slab allocation to have no object extension. - * mark_obj_codetag_empty() should be called upon freeing for objects allocated - * with this flag to indicate that their NULL tags are expected and normal. + * %__GFP_ACCOUNT causes the allocation to be accounted to the active + * cgroup context. */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) #define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL) #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE) #define __GFP_ACCOUNT ((__force gfp_t)___GFP_ACCOUNT) -#define __GFP_NO_OBJ_EXT ((__force gfp_t)___GFP_NO_OBJ_EXT) /** * DOC: Watermark modifiers @@ -320,7 +314,7 @@ enum { * %ZONE_NORMAL or a lower zone for direct access but can direct reclaim. * * %GFP_KERNEL_ACCOUNT is the same as GFP_KERNEL, except the allocation is - * accounted to kmemcg. + * accounted to the active cgroup context. * * %GFP_NOWAIT is for kernel allocations that should not stall for direct * reclaim, start physical IO or use any filesystem callback. It is very diff --git a/include/linux/glob.h b/include/linux/glob.h index 861327b33e41..91595e750936 100644 --- a/include/linux/glob.h +++ b/include/linux/glob.h @@ -6,5 +6,6 @@ #include <linux/compiler.h> /* For __pure */ bool __pure glob_match(char const *pat, char const *str); +bool __pure glob_match_len(char const *pat, char const *str, size_t len); #endif /* _LINUX_GLOB_H */ diff --git a/include/linux/goldfish.h b/include/linux/goldfish.h index bcc17f95b906..98a4719c6776 100644 --- a/include/linux/goldfish.h +++ b/include/linux/goldfish.h @@ -2,8 +2,6 @@ #ifndef __LINUX_GOLDFISH_H #define __LINUX_GOLDFISH_H -#include <linux/kernel.h> -#include <linux/types.h> #include <linux/io.h> /* Helpers for Goldfish virtual platform */ @@ -15,26 +13,4 @@ #define gf_iowrite32 iowrite32 #endif -static inline void gf_write_ptr(const void *ptr, void __iomem *portl, - void __iomem *porth) -{ - const unsigned long addr = (unsigned long)ptr; - - gf_iowrite32(lower_32_bits(addr), portl); -#ifdef CONFIG_64BIT - gf_iowrite32(upper_32_bits(addr), porth); -#endif -} - -static inline void gf_write_dma_addr(const dma_addr_t addr, - void __iomem *portl, - void __iomem *porth) -{ - gf_iowrite32(lower_32_bits(addr), portl); -#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT - gf_iowrite32(upper_32_bits(addr), porth); -#endif -} - - #endif /* __LINUX_GOLDFISH_H */ diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index 5eb88f5d0630..1a141056716f 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -54,7 +54,7 @@ static struct gpiod_lookup_table _name = { \ .dev_id = _dev_id, \ .table = { \ GPIO_LOOKUP(_key, _chip_hwnum, _con_id, _flags), \ - {}, \ + { } \ }, \ } diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h index 06255756710d..6f52c140e50d 100644 --- a/include/linux/gpio/regmap.h +++ b/include/linux/gpio/regmap.h @@ -3,6 +3,8 @@ #ifndef _LINUX_GPIO_REGMAP_H #define _LINUX_GPIO_REGMAP_H +#include <linux/types.h> + struct device; struct fwnode_handle; struct gpio_regmap; @@ -14,6 +16,32 @@ struct regmap; #define GPIO_REGMAP_ADDR(addr) ((addr) ? : GPIO_REGMAP_ADDR_ZERO) /** + * enum gpio_regmap_operation - Operation type for gpio_regmap callbacks + * + * Traditionally, the operation type was inferred from the base register. + * However, that approach does not always work — for example, when all control + * bits of a single GPIO reside in the same register. This enum allows the + * callbacks (reg_mask_xlate and value_xlate) to explicitly distinguish between + * operation types. The user is free to choose which method to use. + * + * Read operation: + * @GPIO_REGMAP_GET_OP: Indicates a read operation to get the current GPIO value. + * + * Write operation: + * @GPIO_REGMAP_SET_OP: Indicates a write operation to set the GPIO output value. + * + * Direction operations: + * @GPIO_REGMAP_GET_DIR_OP: Indicates a read operation to get the GPIO direction. + * @GPIO_REGMAP_SET_DIR_OP: Indicates a write operation to set the GPIO direction. + */ +enum gpio_regmap_operation { + GPIO_REGMAP_GET_OP, + GPIO_REGMAP_SET_OP, + GPIO_REGMAP_GET_DIR_OP, + GPIO_REGMAP_SET_DIR_OP, +}; + +/** * struct gpio_regmap_config - Description of a generic regmap gpio_chip. * @parent: The parent device * @regmap: The regmap used to access the registers @@ -34,10 +62,6 @@ struct regmap; * @ngpio_per_reg: (Optional) Number of GPIOs per register * @irq_domain: (Optional) IRQ domain if the controller is * interrupt-capable - * @reg_mask_xlate: (Optional) Translates base address and GPIO - * offset to a register/bitmask pair. If not - * given the default gpio_regmap_simple_xlate() - * is used. * @fixed_direction_mask: * (Optional) Bitmap representing the GPIO lines that * make use of the @fixed_direction_output list to @@ -48,16 +72,28 @@ struct regmap; * (Optional) Bitmap representing the fixed direction of * the GPIO lines. Useful when there are GPIO lines with a * fixed direction mixed together in the same register. - * @drvdata: (Optional) Pointer to driver specific data which is - * not used by gpio-remap but is provided "as is" to the - * driver callback(s). - * @init_valid_mask: (Optional) Routine to initialize @valid_mask, to be used - * if not all GPIOs are valid. * @regmap_irq_chip: (Optional) Pointer on an regmap_irq_chip structure. If * set, a regmap-irq device will be created and the IRQ * domain will be set accordingly. * @regmap_irq_line: (Optional) The IRQ the device uses to signal interrupts. * @regmap_irq_flags: (Optional) The IRQF_ flags to use for the interrupt. + * @reg_mask_xlate: (Optional) Translates base address and GPIO + * offset to a register/bitmask pair. If not + * given the default gpio_regmap_simple_xlate() + * is used. + * @init_valid_mask: (Optional) Routine to initialize @valid_mask, to be used + * if not all GPIOs are valid. + * @value_xlate: (Optional) Routine to translate the register value and + * mask before writing. This allows driver-specific logic + * to append additional bits (like write-enable masks) + * dynamically based on the current operation + * (GPIO_REGMAP_SET_OP and GPIO_REGMAP_SET_DIR_OP). + * @set_config: (Optional) Callback for setting GPIO configuration such + * as debounce, drive strength, or other hardware specific + * settings. + * @drvdata: (Optional) Pointer to driver specific data which is + * not used by gpio-remap but is provided "as is" to the + * driver callback(s). * * The ->reg_mask_xlate translates a given base address and GPIO offset to * register and mask pair. The base address is one of the given register @@ -104,14 +140,21 @@ struct gpio_regmap_config { unsigned long regmap_irq_flags; #endif - int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base, - unsigned int offset, unsigned int *reg, - unsigned int *mask); + int (*reg_mask_xlate)(struct gpio_regmap *gpio, enum gpio_regmap_operation, + unsigned int base, unsigned int offset, + unsigned int *reg, unsigned int *mask); int (*init_valid_mask)(struct gpio_chip *gc, unsigned long *valid_mask, unsigned int ngpios); + int (*value_xlate)(struct gpio_regmap *gpio, enum gpio_regmap_operation, + unsigned int base, unsigned int offset, unsigned int reg, + unsigned int *mask, unsigned int *val); + + int (*set_config)(struct gpio_regmap *gpio, struct gpio_chip *chip, + unsigned int offset, unsigned long config); + void *drvdata; }; @@ -121,4 +164,10 @@ struct gpio_regmap *devm_gpio_regmap_register(struct device *dev, const struct gpio_regmap_config *config); void *gpio_regmap_get_drvdata(struct gpio_regmap *gpio); +int gpio_regmap_reqres_irq(struct gpio_regmap *gpio, unsigned int offset); +void gpio_regmap_relres_irq(struct gpio_regmap *gpio, unsigned int offset); + +void gpio_regmap_enable_irq(struct gpio_regmap *gpio, irq_hw_number_t hwirq); +void gpio_regmap_disable_irq(struct gpio_regmap *gpio, irq_hw_number_t hwirq); + #endif /* _LINUX_GPIO_REGMAP_H */ diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 80fa930b04c6..e8d6dc290efb 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -25,7 +25,9 @@ struct device; */ struct gpio_keys_button { unsigned int code; +#ifdef CONFIG_GPIOLIB_LEGACY int gpio; +#endif int active_low; const char *desc; unsigned int type; diff --git a/include/linux/gpu_buddy.h b/include/linux/gpu_buddy.h index 71941a039648..2c36124bb696 100644 --- a/include/linux/gpu_buddy.h +++ b/include/linux/gpu_buddy.h @@ -173,6 +173,21 @@ struct gpu_buddy { * that fits in the remaining space. */ struct gpu_buddy_block **roots; + /* + * Per-order free block scoreboard: free_scoreboard[order] holds the + * number of blocks of that order currently in the free state. + * Incremented in mark_free(), decremented wherever rbtree_remove() is + * called on a free block. + */ + u64 *free_scoreboard; + /* + * Per-order used block scoreboard: used_scoreboard[order] holds the + * number of blocks of that order currently in the allocated state. + * Incremented in mark_allocated(), decremented in mark_free() (guarded + * by gpu_buddy_block_is_allocated()) and in __gpu_buddy_free() when an + * allocated block is consumed directly during buddy coalescing. + */ + u64 *used_scoreboard; /* public: */ unsigned int n_roots; unsigned int max_order; @@ -272,6 +287,8 @@ void gpu_buddy_reset_clear(struct gpu_buddy *mm, bool is_clear); void gpu_buddy_free_block(struct gpu_buddy *mm, struct gpu_buddy_block *block); +struct gpu_buddy_block *gpu_buddy_allocated_addr_to_block(struct gpu_buddy *mm, u64 addr); + void gpu_buddy_free_list(struct gpu_buddy *mm, struct list_head *objects, unsigned int flags); diff --git a/include/linux/greybus/greybus_id.h b/include/linux/greybus/greybus_id.h index f4c8440093e4..72f330a35569 100644 --- a/include/linux/greybus/greybus_id.h +++ b/include/linux/greybus/greybus_id.h @@ -1,14 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* FIXME - * move this to include/linux/mod_devicetable.h when merging + * move this to include/linux/device-id/greybus.h when merging */ #ifndef __LINUX_GREYBUS_ID_H #define __LINUX_GREYBUS_ID_H #include <linux/types.h> -#include <linux/mod_devicetable.h> - struct greybus_bundle_id { __u16 match_flags; diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index d57cab4d4c06..73b48dd9f135 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -92,6 +92,37 @@ void irq_exit_rcu(void); #define arch_nmi_exit() do { } while (0) #endif +#ifdef CONFIG_HAS_SEPARATE_PREEMPT_RESCHED_BITS +static __always_inline void __preempt_count_nmi_enter(void) +{ + __preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET); +} + +static __always_inline void __preempt_count_nmi_exit(void) +{ + __preempt_count_sub(NMI_OFFSET + HARDIRQ_OFFSET); +} +#else +DECLARE_PER_CPU(unsigned int, nmi_nesting); + +#define __preempt_count_nmi_enter() \ + do { \ + __preempt_count_add(HARDIRQ_OFFSET); \ + /* Maximum NMI nesting is 15. */ \ + BUG_ON(__this_cpu_read(nmi_nesting) >= 15); \ + __this_cpu_inc(nmi_nesting); \ + preempt_count_set(preempt_count() | NMI_MASK); \ + } while (0) + +#define __preempt_count_nmi_exit() \ + do { \ + __preempt_count_sub(HARDIRQ_OFFSET); \ + if (!__this_cpu_dec_return(nmi_nesting)) \ + preempt_count_set(preempt_count() & ~NMI_MASK); \ + } while (0) + +#endif + /* * NMI vs Tracing * -------------- @@ -102,21 +133,20 @@ void irq_exit_rcu(void); */ /* - * nmi_enter() can nest up to 15 times; see NMI_BITS. + * nmi_enter() can nest - nesting is tracked in a per-CPU counter. */ #define __nmi_enter() \ do { \ lockdep_off(); \ arch_nmi_enter(); \ - BUG_ON(in_nmi() == NMI_MASK); \ - __preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET); \ + __preempt_count_nmi_enter(); \ } while (0) #define nmi_enter() \ do { \ __nmi_enter(); \ lockdep_hardirq_enter(); \ - ct_nmi_enter(); \ + ct_nmi_enter(); \ instrumentation_begin(); \ ftrace_nmi_enter(); \ instrumentation_end(); \ @@ -125,7 +155,7 @@ void irq_exit_rcu(void); #define __nmi_exit() \ do { \ BUG_ON(!in_nmi()); \ - __preempt_count_sub(NMI_OFFSET + HARDIRQ_OFFSET); \ + __preempt_count_nmi_exit(); \ arch_nmi_exit(); \ lockdep_on(); \ } while (0) diff --git a/include/linux/hfs_common.h b/include/linux/hfs_common.h index 45fb4c9ff9f5..d6a615e74b26 100644 --- a/include/linux/hfs_common.h +++ b/include/linux/hfs_common.h @@ -510,14 +510,21 @@ struct hfs_btree_header_rec { b-tree but not in extents b-tree (hfsplus). */ +/* HFS BTree misc info */ +#define HFS_TREE_HEAD 0 +#define HFS_BTREE_HDR_MAP_REC_INDEX 2 /* Map (bitmap) record in Header node */ +#define HFS_BTREE_MAP_NODE_REC_INDEX 0 /* Map record in Map Node */ + /* HFS+ BTree misc info */ -#define HFSPLUS_TREE_HEAD 0 +#define HFSPLUS_TREE_HEAD HFS_TREE_HEAD #define HFSPLUS_NODE_MXSZ 32768 #define HFSPLUS_NODE_MINSZ 512 #define HFSPLUS_ATTR_TREE_NODE_SIZE 8192 #define HFSPLUS_BTREE_HDR_NODE_RECS_COUNT 3 -#define HFSPLUS_BTREE_HDR_MAP_REC_INDEX 2 /* Map (bitmap) record in Header node */ -#define HFSPLUS_BTREE_MAP_NODE_REC_INDEX 0 /* Map record in Map Node */ +/* Map (bitmap) record in Header node */ +#define HFSPLUS_BTREE_HDR_MAP_REC_INDEX HFS_BTREE_HDR_MAP_REC_INDEX +/* Map record in Map Node */ +#define HFSPLUS_BTREE_MAP_NODE_REC_INDEX HFS_BTREE_MAP_NODE_REC_INDEX #define HFSPLUS_BTREE_HDR_USER_BYTES 128 #define HFSPLUS_BTREE_MAP_NODE_RECS_COUNT 2 #define HFSPLUS_BTREE_MAP_NODE_RESERVED_BYTES 2 diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h index e71056553108..ab5cc8db3fbb 100644 --- a/include/linux/hid-sensor-hub.h +++ b/include/linux/hid-sensor-hub.h @@ -43,6 +43,8 @@ struct hid_sensor_hub_attribute_info { * @attr_usage_id: Usage Id of a field, e.g. X-axis for a gyro. * @raw_size: Response size for a read request. * @raw_data: Place holder for received response. + * @index: Current write index into raw_data for multi-byte reads. + * @max_raw_size: Total buffer size for multi-byte reads; 0 for single-value reads. */ struct sensor_hub_pending { bool status; @@ -51,6 +53,8 @@ struct sensor_hub_pending { u32 attr_usage_id; int raw_size; u8 *raw_data; + u32 index; + u32 max_raw_size; }; /** @@ -184,6 +188,27 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, ); /** + * sensor_hub_input_attr_read_values() - Synchronous multi-byte read request + * @hsdev: Hub device instance. + * @usage_id: Attribute usage id of parent physical device as per spec + * @attr_usage_id: Attribute usage id as per spec + * @report_id: Report id to look for + * @flag: Synchronous or asynchronous read + * @buffer_size: Size of the buffer in bytes + * @buffer: Buffer to store the read data + * + * Issues a synchronous or asynchronous read request for an input attribute, + * accumulating data into the provided buffer until it is full. + * Return: 0 on success, -ETIMEDOUT if the device did not respond, or a + * negative error code. + */ +int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev, + u32 usage_id, u32 attr_usage_id, + u32 report_id, + enum sensor_hub_read_flags flag, + u32 buffer_size, u8 *buffer); + +/** * sensor_hub_set_feature() - Feature set request * @hsdev: Hub device instance. * @report_id: Report id to look for diff --git a/include/linux/hid.h b/include/linux/hid.h index 47dc0bc89fa4..8d17b741638c 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -18,7 +18,7 @@ #include <linux/types.h> #include <linux/slab.h> #include <linux/list.h> -#include <linux/mod_devicetable.h> /* hid_device_id */ +#include <linux/device-id/hid.h> #include <linux/timer.h> #include <linux/workqueue.h> #include <linux/input.h> @@ -642,6 +642,7 @@ enum hid_battery_status { * @max: maximum battery value from HID descriptor * @report_type: HID report type (input/feature) * @report_id: HID report ID for this battery + * @report_offset: bit offset of the capacity field within its report * @charge_status: current charging status * @status: battery reporting status * @capacity: current battery capacity (0-100) @@ -657,6 +658,7 @@ struct hid_battery { __s32 max; __s32 report_type; __s32 report_id; + __s32 report_offset; __s32 charge_status; enum hid_battery_status status; __s32 capacity; @@ -1021,7 +1023,7 @@ extern void hid_unregister_driver(struct hid_driver *); extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); -extern int hidinput_connect(struct hid_device *hid, unsigned int force); +extern int hidinput_connect(struct hid_device *hid, unsigned int connect_mask); extern void hidinput_disconnect(struct hid_device *); void hidinput_reset_resume(struct hid_device *hid); diff --git a/include/linux/hmm.h b/include/linux/hmm.h index db75ffc949a7..6f04e3932f5b 100644 --- a/include/linux/hmm.h +++ b/include/linux/hmm.h @@ -123,6 +123,8 @@ struct hmm_range { * Please see Documentation/mm/hmm.rst for how to use the range API. */ int hmm_range_fault(struct hmm_range *range); +int hmm_range_fault_unlocked_timeout(struct hmm_range *range, + unsigned long timeout); /* * HMM_RANGE_DEFAULT_TIMEOUT - default timeout (ms) when waiting for a range diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 6862dea0acc5..29072d89e5cb 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -12,7 +12,6 @@ #ifndef _LINUX_HRTIMER_H #define _LINUX_HRTIMER_H -#include <linux/hrtimer_defs.h> #include <linux/hrtimer_rearm.h> #include <linux/hrtimer_types.h> #include <linux/init.h> @@ -287,37 +286,8 @@ static inline bool hrtimer_is_queued(struct hrtimer *timer) return READ_ONCE(timer->is_queued); } -/* - * Helper function to check, whether the timer is running the callback - * function - */ -static inline int hrtimer_callback_running(struct hrtimer *timer) -{ - return timer->base->running == timer; -} - -/** - * hrtimer_update_function - Update the timer's callback function - * @timer: Timer to update - * @function: New callback function - * - * Only safe to call if the timer is not enqueued. Can be called in the callback function if the - * timer is not enqueued at the same time (see the comments above HRTIMER_STATE_ENQUEUED). - */ -static inline void hrtimer_update_function(struct hrtimer *timer, - enum hrtimer_restart (*function)(struct hrtimer *)) -{ -#ifdef CONFIG_PROVE_LOCKING - guard(raw_spinlock_irqsave)(&timer->base->cpu_base->lock); - - if (WARN_ON_ONCE(hrtimer_is_queued(timer))) - return; - - if (WARN_ON_ONCE(!function)) - return; -#endif - ACCESS_PRIVATE(timer, function) = function; -} +void hrtimer_update_function(struct hrtimer *timer, + enum hrtimer_restart (*function)(struct hrtimer *)); /* Forward a hrtimer so it expires after now: */ extern u64 diff --git a/include/linux/hrtimer_defs.h b/include/linux/hrtimer_bases.h index 52ed9e46ff13..d4c83ec5c0f8 100644 --- a/include/linux/hrtimer_defs.h +++ b/include/linux/hrtimer_bases.h @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _LINUX_HRTIMER_DEFS_H -#define _LINUX_HRTIMER_DEFS_H +#ifndef _LINUX_HRTIMER_BASES_H +#define _LINUX_HRTIMER_BASES_H +#include <linux/hrtimer.h> #include <linux/ktime.h> #include <linux/timerqueue.h> #include <linux/seqlock.h> @@ -83,7 +84,7 @@ struct hrtimer_cpu_base { raw_spinlock_t lock; unsigned int cpu; unsigned int active_bases; - unsigned int clock_was_set_seq; + u32 clock_was_set_seq; bool hres_active; bool deferred_rearm; bool deferred_needs_update; @@ -110,4 +111,13 @@ struct hrtimer_cpu_base { } ____cacheline_aligned; +/* + * Helper function to check, whether the timer is running the callback + * function + */ +static inline int hrtimer_callback_running(struct hrtimer *timer) +{ + return timer->base->running == timer; +} + #endif diff --git a/include/linux/hrtimer_rearm.h b/include/linux/hrtimer_rearm.h index a6f2e5d5e1c7..17a81826bd9a 100644 --- a/include/linux/hrtimer_rearm.h +++ b/include/linux/hrtimer_rearm.h @@ -2,7 +2,12 @@ #ifndef _LINUX_HRTIMER_REARM_H #define _LINUX_HRTIMER_REARM_H +#include <linux/types.h> + #ifdef CONFIG_HRTIMER_REARM_DEFERRED +#include <linux/irqflags.h> +#include <linux/lockdep.h> +#include <linux/preempt.h> #include <linux/thread_info.h> void __hrtimer_rearm_deferred(void); diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index ad20f7f8c179..c745f7ad2298 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -230,6 +230,7 @@ static inline bool thp_vma_suitable_order(struct vm_area_struct *vma, /* Don't have to check pgoff for anonymous vma */ if (!vma_is_anonymous(vma)) { + /* vma_start_pgoff() in mm.h so not available. */ if (!IS_ALIGNED((vma->vm_start >> PAGE_SHIFT) - vma->vm_pgoff, hpage_size >> PAGE_SHIFT)) return false; @@ -390,9 +391,9 @@ static inline bool thp_disabled_by_hw(void) unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, +unsigned long thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, - vm_flags_t vm_flags); + vma_flags_t vma_flags); enum split_type { SPLIT_TYPE_UNIFORM, @@ -471,6 +472,24 @@ void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, void __split_huge_pud(struct vm_area_struct *vma, pud_t *pud, unsigned long address); +/** + * pud_is_huge() - Is this PUD either a huge PUD entry or a software leaf entry? + * @pud: The PUD to check. + * + * This is similar to pmd_is_huge(), but it checks at the PUD level. + * + * Returns: true if this PUD is huge, false otherwise. + */ +static inline bool pud_is_huge(pud_t pud) +{ + if (pud_present(pud)) + return pud_trans_huge(pud); + else if (!pud_none(pud)) + return true; + + return false; +} + #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD int change_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma, pud_t *pudp, unsigned long addr, pgprot_t newprot, @@ -529,6 +548,8 @@ static inline bool folio_test_pmd_mappable(struct folio *folio) vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf); +vm_fault_t do_huge_pmd_uffd_rwp(struct vm_fault *vmf); + vm_fault_t do_huge_pmd_device_private(struct vm_fault *vmf); extern struct folio *huge_zero_folio; @@ -567,7 +588,7 @@ static inline struct folio *get_persistent_huge_zero_folio(void) static inline bool thp_migration_supported(void) { - return IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION); + return IS_ENABLED(CONFIG_ARCH_HAS_PMD_SOFTLEAVES); } void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address, @@ -614,18 +635,13 @@ static inline unsigned long thp_vma_allowable_orders(struct vm_area_struct *vma, #define thp_get_unmapped_area NULL static inline unsigned long -thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, - unsigned long flags, vm_flags_t vm_flags) +thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags, vma_flags_t vma_flags) { return 0; } -static inline bool -can_split_folio(struct folio *folio, int caller_pins, int *pextra_pins) -{ - return false; -} static inline int split_huge_page_to_list_to_order(struct page *page, struct list_head *list, unsigned int new_order) @@ -723,6 +739,11 @@ static inline spinlock_t *pud_trans_huge_lock(pud_t *pud, return NULL; } +static inline vm_fault_t do_huge_pmd_uffd_rwp(struct vm_fault *vmf) +{ + return 0; +} + static inline vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf) { return 0; @@ -790,22 +811,21 @@ static inline bool pmd_is_huge(pmd_t pmd) { return false; } -#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -static inline bool is_pmd_order(unsigned int order) +static inline bool pud_is_huge(pud_t pud) { - return order == HPAGE_PMD_ORDER; + return false; } +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -static inline int split_folio_to_list_to_order(struct folio *folio, - struct list_head *list, int new_order) +static inline bool is_pmd_order(unsigned int order) { - return split_huge_page_to_list_to_order(&folio->page, list, new_order); + return order == HPAGE_PMD_ORDER; } static inline int split_folio_to_order(struct folio *folio, int new_order) { - return split_folio_to_list_to_order(folio, NULL, new_order); + return split_huge_page_to_list_to_order(&folio->page, NULL, new_order); } /** diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 2abaf99321e9..16c4c4caa126 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -2,6 +2,7 @@ #ifndef _LINUX_HUGETLB_H #define _LINUX_HUGETLB_H +#include <linux/mempolicy.h> #include <linux/mm.h> #include <linux/mm_types.h> #include <linux/mmdebug.h> @@ -154,7 +155,8 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, bool folio_isolate_hugetlb(struct folio *folio, struct list_head *list); int get_hwpoison_hugetlb_folio(struct folio *folio, bool *hugetlb, bool unpoison); void folio_putback_hugetlb(struct folio *folio); -void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, int reason); +void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, + enum migrate_reason reason); void hugetlb_fix_reserve_counts(struct inode *inode); extern struct mutex *hugetlb_fault_mutex_table; u32 hugetlb_fault_mutex_hash(struct address_space *mapping, pgoff_t idx); @@ -171,6 +173,7 @@ extern int movable_gigantic_pages __read_mostly; extern int sysctl_hugetlb_shm_group __read_mostly; extern struct list_head huge_boot_pages[MAX_NUMNODES]; +void hugetlb_bootmem_struct_page_init(void); void hugetlb_bootmem_alloc(void); extern nodemask_t hugetlb_bootmem_nodes; void hugetlb_bootmem_set_nodes(void); @@ -424,7 +427,7 @@ static inline void folio_putback_hugetlb(struct folio *folio) } static inline void move_hugetlb_state(struct folio *old_folio, - struct folio *new_folio, int reason) + struct folio *new_folio, enum migrate_reason reason) { } @@ -673,24 +676,30 @@ struct hstate { char name[HSTATE_NAME_LEN]; }; -struct cma; - -struct huge_bootmem_page { - struct list_head list; - struct hstate *hstate; - unsigned long flags; - struct cma *cma; -}; - #define HUGE_BOOTMEM_HVO 0x0001 #define HUGE_BOOTMEM_ZONES_VALID 0x0002 #define HUGE_BOOTMEM_CMA 0x0004 -bool hugetlb_bootmem_page_zones_valid(int nid, struct huge_bootmem_page *m); - int isolate_or_dissolve_huge_folio(struct folio *folio, struct list_head *list); int replace_free_hugepage_folios(unsigned long start_pfn, unsigned long end_pfn); void wait_for_freed_hugetlb_folios(void); + +struct mempolicy_interpreted { + int nid; + nodemask_t *nodemask; + enum mempolicy_mode mode; +}; + +enum hugetlb_alloc_flag { + HUGETLB_ALLOC_CHARGE_CGROUP_RSVD_BIT = 0, + HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS_BIT, +}; + +#define HUGETLB_ALLOC_CHARG_CGROUP_RSVD BIT(HUGETLB_ALLOC_CHARGE_CGROUP_RSVD_BIT) +#define HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS BIT(HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS_BIT) + +struct folio *hugetlb_alloc_folio(struct hstate *h, + struct mempolicy_interpreted *mpoli, u8 alloc_flags); struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, unsigned long addr, bool cow_from_owner); struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid, @@ -705,8 +714,8 @@ void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma, unsigned long address, struct folio *folio); /* arch callback */ -int __init __alloc_bootmem_huge_page(struct hstate *h, int nid); -int __init alloc_bootmem_huge_page(struct hstate *h, int nid); +void *__init __alloc_bootmem_huge_page(struct hstate *h, int nid); +void *__init arch_alloc_bootmem_huge_page(struct hstate *h, int nid); bool __init hugetlb_node_alloc_supported(void); void __init hugetlb_add_hstate(unsigned order); @@ -792,8 +801,7 @@ static inline pgoff_t hugetlb_linear_page_index(struct vm_area_struct *vma, { struct hstate *h = hstate_vma(vma); - return ((address - vma->vm_start) >> huge_page_shift(h)) + - (vma->vm_pgoff >> huge_page_order(h)); + return linear_page_index(vma, address) >> huge_page_order(h); } static inline bool order_is_gigantic(unsigned int order) @@ -956,7 +964,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask) return modified_mask; } -static inline bool htlb_allow_alloc_fallback(int reason) +static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason) { bool allowed_fallback = false; @@ -1137,9 +1145,9 @@ alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid, return NULL; } -static inline int __alloc_bootmem_huge_page(struct hstate *h) +static inline void *__alloc_bootmem_huge_page(struct hstate *h, int nid) { - return 0; + return NULL; } static inline struct hstate *hstate_file(struct file *f) @@ -1238,7 +1246,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask) return 0; } -static inline bool htlb_allow_alloc_fallback(int reason) +static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason) { return false; } @@ -1261,6 +1269,9 @@ static inline void hugetlb_count_sub(long l, struct mm_struct *mm) { } +pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep); +unsigned long huge_pte_dirty(pte_t pte); + static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { @@ -1293,6 +1304,10 @@ static inline bool hugetlbfs_pagecache_present( static inline void hugetlb_bootmem_alloc(void) { } + +static inline void hugetlb_bootmem_struct_page_init(void) +{ +} #endif /* CONFIG_HUGETLB_PAGE */ static inline spinlock_t *huge_pte_lock(struct hstate *h, diff --git a/include/linux/hugetlb_cgroup.h b/include/linux/hugetlb_cgroup.h index e5d64b8b59c2..16d72c8c71f6 100644 --- a/include/linux/hugetlb_cgroup.h +++ b/include/linux/hugetlb_cgroup.h @@ -267,5 +267,5 @@ static inline void hugetlb_cgroup_migrate(struct folio *old_folio, { } -#endif /* CONFIG_MEM_RES_CTLR_HUGETLB */ +#endif /* CONFIG_CGROUP_HUGETLB */ #endif diff --git a/include/linux/hwmon-sysfs.h b/include/linux/hwmon-sysfs.h index d896713359cd..ee5b33185b2d 100644 --- a/include/linux/hwmon-sysfs.h +++ b/include/linux/hwmon-sysfs.h @@ -15,10 +15,10 @@ struct sensor_device_attribute{ int index; }; #define to_sensor_dev_attr(_dev_attr) \ - container_of(_dev_attr, struct sensor_device_attribute, dev_attr) + container_of_const(_dev_attr, struct sensor_device_attribute, dev_attr) -#define SENSOR_ATTR(_name, _mode, _show, _store, _index) \ - { .dev_attr = __ATTR(_name, _mode, _show, _store), \ +#define SENSOR_ATTR(_name, _mode, _show, _store, _index) \ + { .dev_attr = __DEVICE_ATTR(_name, _mode, _show, _store), \ .index = _index } #define SENSOR_ATTR_RO(_name, _func, _index) \ @@ -49,11 +49,11 @@ struct sensor_device_attribute_2 { u8 nr; }; #define to_sensor_dev_attr_2(_dev_attr) \ - container_of(_dev_attr, struct sensor_device_attribute_2, dev_attr) + container_of_const(_dev_attr, struct sensor_device_attribute_2, dev_attr) -#define SENSOR_ATTR_2(_name, _mode, _show, _store, _nr, _index) \ - { .dev_attr = __ATTR(_name, _mode, _show, _store), \ - .index = _index, \ +#define SENSOR_ATTR_2(_name, _mode, _show, _store, _nr, _index) \ + { .dev_attr = __DEVICE_ATTR(_name, _mode, _show, _store), \ + .index = _index, \ .nr = _nr } #define SENSOR_ATTR_2_RO(_name, _func, _nr, _index) \ diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index 77a6f2bffcba..dd713e193d0c 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h @@ -480,8 +480,7 @@ hwmon_device_register_with_info(struct device *dev, const struct attribute_group **extra_groups); struct device * hwmon_device_register_for_thermal(struct device *dev, const char *name, - void *drvdata, - const struct attribute_group **extra_groups); + void *drvdata); struct device * devm_hwmon_device_register_with_info(struct device *dev, const char *name, void *drvdata, diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 9de2c8d6037a..9e109d91aa14 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -21,7 +21,7 @@ #include <linux/timer.h> #include <linux/completion.h> #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/hv_vmbus.h> #include <linux/interrupt.h> #include <linux/reciprocal_div.h> #include <hyperv/hvhdk.h> @@ -70,7 +70,8 @@ */ enum hv_gpadl_type { HV_GPADL_BUFFER, - HV_GPADL_RING + HV_GPADL_RING, + HV_GPADL_BUFFER_DECRYPTED }; /* Single-page buffer */ @@ -260,9 +261,8 @@ static inline u32 hv_get_avail_to_write_percent( * 5 . 2 (Windows Server 2019, RS5) * 5 . 3 (Windows Server 2022) * - * The WS2008 and WIN7 versions are listed here for - * completeness but are no longer supported in the - * Linux kernel. + * The WS2008, WIN7, WIN8, and WIN8_1 versions are listed here for + * completeness but are no longer supported in the Linux kernel. */ #define VMBUS_MAKE_VERSION(MAJ, MIN) ((((u32)MAJ) << 16) | (MIN)) @@ -1205,9 +1205,21 @@ extern int vmbus_establish_gpadl(struct vmbus_channel *channel, u32 size, struct vmbus_gpadl *gpadl); +extern int vmbus_establish_gpadl_caller_decrypted(struct vmbus_channel *channel, + void *kbuffer, + u32 size, + struct vmbus_gpadl *gpadl); + extern int vmbus_teardown_gpadl(struct vmbus_channel *channel, struct vmbus_gpadl *gpadl); +extern void *vmbus_alloc_buffer(struct vmbus_channel *channel, + u32 size, + struct page ***chunks_out, + u32 *chunk_cnt_out); + +extern void vmbus_free_buffer(void *addr, struct page **chunks, u32 chunk_cnt); + void vmbus_reset_channel_cb(struct vmbus_channel *channel); extern int vmbus_recvpacket(struct vmbus_channel *channel, diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h index 7fd5575a368f..c4c43aec1e67 100644 --- a/include/linux/i2c-algo-bit.h +++ b/include/linux/i2c-algo-bit.h @@ -34,6 +34,7 @@ struct i2c_algo_bit_data { maximum 50 us for SMBus */ int timeout; /* in jiffies */ bool can_do_atomic; /* callbacks don't sleep, we can be atomic */ + bool skip_bit_test; /* override bit_test module parameter */ }; int i2c_bit_add_bus(struct i2c_adapter *); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 20fd41b51d5c..14ab4d3055af 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -12,7 +12,7 @@ #include <linux/acpi.h> /* for acpi_handle */ #include <linux/bits.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/i2c.h> #include <linux/device.h> /* for struct device */ #include <linux/sched.h> /* for completion */ #include <linux/mutex.h> diff --git a/include/linux/i3c/ccc.h b/include/linux/i3c/ccc.h index ad59a4ae60d1..c6947dcb0f57 100644 --- a/include/linux/i3c/ccc.h +++ b/include/linux/i3c/ccc.h @@ -12,6 +12,8 @@ #include <linux/i3c/device.h> /* I3C CCC (Common Command Codes) related definitions */ +#define I3C_CCC_RETRIES 1 + #define I3C_CCC_DIRECT BIT(7) #define I3C_CCC_ID(id, broadcast) \ @@ -32,6 +34,7 @@ #define I3C_CCC_DEFSLVS I3C_CCC_ID(0x8, true) #define I3C_CCC_ENTTM I3C_CCC_ID(0xb, true) #define I3C_CCC_ENTHDR(x) I3C_CCC_ID(0x20 + (x), true) +#define I3C_CCC_SETAASA I3C_CCC_ID(0x29, true) /* Unicast-only commands */ #define I3C_CCC_SETDASA I3C_CCC_ID(0x7, false) @@ -343,11 +346,15 @@ struct i3c_ccc_getxtime { /** * struct i3c_ccc_cmd_payload - CCC payload * - * @len: payload length + * @len: requested payload length + * @actual_len: number of bytes received on a GET CCC (filled by the driver) + * @optional_bytes: GET CCCs may return up to this many fewer bytes than @len * @data: payload data. This buffer must be DMA-able */ struct i3c_ccc_cmd_payload { u16 len; + u16 actual_len; + u16 optional_bytes; void *data; }; @@ -372,12 +379,15 @@ struct i3c_ccc_cmd_dest { * @ndests: number of destinations. Should always be one for broadcast commands * @dests: array of destinations and associated payload for this CCC. Most of * the time, only one destination is provided + * @retries: number of times to retry a failed Direct GET CCC (see + * &I3C_CCC_RETRIES) * @err: I3C error code */ struct i3c_ccc_cmd { u8 rnw; u8 id; unsigned int ndests; + unsigned int retries; struct i3c_ccc_cmd_dest *dests; enum i3c_error_code err; }; diff --git a/include/linux/i3c/device.h b/include/linux/i3c/device.h index 971d53349b6f..0f065b883ee0 100644 --- a/include/linux/i3c/device.h +++ b/include/linux/i3c/device.h @@ -12,7 +12,7 @@ #include <linux/device.h> #include <linux/i2c.h> #include <linux/kconfig.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/i3c.h> #include <linux/module.h> /** diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h index 4d2a68793324..f7ceec2b4477 100644 --- a/include/linux/i3c/master.h +++ b/include/linux/i3c/master.h @@ -174,10 +174,19 @@ struct i3c_device_ibi_info { * assigned a dynamic address by the master. Will be used during * bus initialization to assign it a specific dynamic address * before starting DAA (Dynamic Address Assignment) + * @static_addr_method: Bitmap describing which methods of Dynamic Address + * Assignment from a Static Address are supported by this I3C Target. + * A value of 1 in a bit position indicates that the I3C target + * supports that method, and a value of 0 indicates that the I3C + * target does not support that method. + * Bit 0: SETDASA + * Bit 1: SETAASA + * All other bits are reserved. * @pid: I3C Provisioned ID exposed by the device. This is a unique identifier * that may be used to attach boardinfo to i3c_dev_desc when the device * does not have a static address - * @of_node: optional DT node in case the device has been described in the DT + * @fwnode: Firmware node (DT or ACPI) in case the device has been + * described in firmware * * This structure is used to attach board-level information to an I3C device. * Not all I3C devices connected on the bus will have a boardinfo. It's only @@ -188,8 +197,9 @@ struct i3c_dev_boardinfo { struct list_head node; u8 init_dyn_addr; u8 static_addr; + u8 static_addr_method; u64 pid; - struct device_node *of_node; + struct fwnode_handle *fwnode; }; /** @@ -228,6 +238,8 @@ struct i3c_dev_desc { * every time the I3C device is rediscovered with a different dynamic * address assigned * @bus: I3C bus this device is attached to + * @node: unregistered device list node, only for use by + * i3c_master_register_new_i3c_devs(), it is not protected by a lock * * I3C device object exposed to I3C device drivers. The takes care of linking * this object to the relevant &struct_i3c_dev_desc one. @@ -238,6 +250,7 @@ struct i3c_device { struct device dev; struct i3c_dev_desc *desc; struct i3c_bus *bus; + struct list_head node; }; /* @@ -259,6 +272,7 @@ struct i3c_device { #define I3C_BUS_THIGH_MIXED_MAX_NS 41 #define I3C_BUS_TIDLE_MIN_NS 200000 #define I3C_BUS_TLOW_OD_MIN_NS 200 +#define I3C_BUS_THIGH_INIT_OD_MIN_NS 200 /** * enum i3c_bus_mode - I3C bus mode @@ -511,11 +525,17 @@ struct i3c_master_controller_ops { * @hotjoin: true if the master support hotjoin * @rpm_allowed: true if Runtime PM allowed * @rpm_ibi_allowed: true if IBI and Hot-Join allowed while runtime suspended + * @ibi_wakeup: IBI can wakeup the system * @shutting_down: set to true when master begins shutdown or unregister * @boardinfo.i3c: list of I3C boardinfo objects * @boardinfo.i2c: list of I2C boardinfo objects * @boardinfo: board-level information attached to devices connected on the bus * @bus: I3C bus exposed by this master + * @addr_method: Bitmap describing which methods of Address Assignment required + * to be run for discovering all the devices on the bus. + * Bit 0: SETDASA + * Bit 1: SETAASA + * All other bits are reserved. * @wq: freezable workqueue which can be used by master * drivers if they need to postpone operations that need to take place * in a thread context. Typical examples are Hot Join processing which @@ -545,12 +565,14 @@ struct i3c_master_controller { unsigned int hotjoin: 1; unsigned int rpm_allowed: 1; unsigned int rpm_ibi_allowed: 1; + unsigned int ibi_wakeup: 1; bool shutting_down; struct { struct list_head i3c; struct list_head i2c; } boardinfo; struct i3c_bus bus; + u8 addr_method; struct workqueue_struct *wq; struct work_struct hj_work; struct work_struct reg_work; @@ -744,6 +766,7 @@ void i3c_generic_ibi_recycle_slot(struct i3c_generic_ibi_pool *pool, struct i3c_ibi_slot *slot); void i3c_master_queue_ibi(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot); +bool i3c_master_has_wakeup_enabled_devs(struct i3c_master_controller *master); struct i3c_ibi_slot *i3c_master_get_free_ibi_slot(struct i3c_dev_desc *dev); diff --git a/include/linux/ieee80211-eht.h b/include/linux/ieee80211-eht.h index 18f9c662cf4c..b62297a978e7 100644 --- a/include/linux/ieee80211-eht.h +++ b/include/linux/ieee80211-eht.h @@ -481,6 +481,7 @@ struct ieee80211_multi_link_elem { #define IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP 0x0100 #define IEEE80211_MLC_BASIC_PRES_MLD_ID 0x0200 #define IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP 0x0400 +#define IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD 0x0800 #define IEEE80211_MED_SYNC_DELAY_DURATION 0x00ff #define IEEE80211_MED_SYNC_DELAY_SYNC_OFDM_ED_THRESH 0x0f00 @@ -810,6 +811,49 @@ static inline u16 ieee80211_mle_get_ext_mld_capa_op(const u8 *data) } /** + * ieee80211_mle_get_enh_crit_upd_info - returns the enhanced critical + * updates information + * @data: pointer to the multi-link element + * Return: the enhanced critical updates information field, or %NULL + * + * The element is assumed to be of the correct type (BASIC) and big enough, + * this must be checked using ieee80211_mle_type_ok(). + */ +static inline const struct ieee80211_enh_crit_upd * +ieee80211_mle_get_enh_crit_upd_info(const u8 *data) +{ + const struct ieee80211_multi_link_elem *mle = (const void *)data; + u16 control = le16_to_cpu(mle->control); + const u8 *common = mle->variable; + + /* + * common points now at the beginning of + * ieee80211_mle_basic_common_info + */ + common += sizeof(struct ieee80211_mle_basic_common_info); + + if (!(control & IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD)) + return NULL; + + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) + common += 2; + if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) + common += 2; + if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) + common += 2; + if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP) + common += 2; + + return (const void *)common; +} + +/** * ieee80211_mle_get_mld_id - returns the MLD ID * @data: pointer to the multi-link element * Return: The MLD ID in the given multi-link element, or 0 if not present @@ -857,7 +901,7 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) const struct ieee80211_multi_link_elem *mle = (const void *)data; u8 fixed = sizeof(*mle); u8 common = 0; - bool check_common_len = false; + u8 common_len; u16 control; if (!data || len < fixed) @@ -868,7 +912,6 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { case IEEE80211_ML_CONTROL_TYPE_BASIC: common += sizeof(struct ieee80211_mle_basic_common_info); - check_common_len = true; if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) common += 1; if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) @@ -883,14 +926,16 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) common += 1; if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP) common += 2; + if (control & IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD) + common += 1; break; case IEEE80211_ML_CONTROL_TYPE_PREQ: common += sizeof(struct ieee80211_mle_preq_common_info); if (control & IEEE80211_MLC_PREQ_PRES_MLD_ID) common += 1; - check_common_len = true; break; case IEEE80211_ML_CONTROL_TYPE_RECONF: + common += 1; if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR) common += ETH_ALEN; if (control & IEEE80211_MLC_RECONF_PRES_EML_CAPA) @@ -902,7 +947,6 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) break; case IEEE80211_ML_CONTROL_TYPE_TDLS: common += sizeof(struct ieee80211_mle_tdls_common_info); - check_common_len = true; break; case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: common = ETH_ALEN + 1; @@ -915,11 +959,9 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) if (len < fixed + common) return false; - if (!check_common_len) - return true; + common_len = mle->variable[0]; - /* if present, common length is the first octet there */ - return mle->variable[0] >= common; + return common_len >= common && common_len <= len - fixed; } /** @@ -959,6 +1001,8 @@ enum ieee80211_mle_subelems { #define IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT 0x0200 #define IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE 0x0400 #define IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT 0x0800 +#define IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT 0x1000 +#define IEEE80211_MLE_STA_CONTROL_AP_CONDUCTED_TX_PWR_PRESENT 0x2000 struct ieee80211_mle_per_sta_profile { __le16 control; @@ -1004,6 +1048,12 @@ static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data, if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT) info_len += 1; + if (control & IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT) + info_len += 1; + + if (control & IEEE80211_MLE_STA_CONTROL_AP_CONDUCTED_TX_PWR_PRESENT) + info_len += 1; + return prof->sta_info_len >= info_len && fixed + prof->sta_info_len - 1 <= len; } @@ -1044,6 +1094,44 @@ ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta return *pos; } +/** + * ieee80211_mle_basic_sta_prof_enh_crit_upd - get per-STA profile enhanced + * critical updates field + * @prof: the per-STA profile, having been checked with + * ieee80211_mle_basic_sta_prof_size_ok() for the correct length + * + * Return: The enhanced critical updates field if present, %NULL otherwise. + */ +static inline const struct ieee80211_enh_crit_upd * +ieee80211_mle_basic_sta_prof_enh_crit_upd(const struct ieee80211_mle_per_sta_profile *prof) +{ + u16 control = le16_to_cpu(prof->control); + const u8 *pos = prof->variable; + + if (!(control & IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT)) + return NULL; + + if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT) + pos += 6; + if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) + pos += 2; + if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) + pos += 8; + if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) + pos += 2; + if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && + control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { + if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) + pos += 2; + else + pos += 1; + } + if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT) + pos += 1; + + return (const void *)pos; +} + #define IEEE80211_MLE_STA_RECONF_CONTROL_LINK_ID 0x000f #define IEEE80211_MLE_STA_RECONF_CONTROL_COMPLETE_PROFILE 0x0010 #define IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 diff --git a/include/linux/ieee80211-uhr.h b/include/linux/ieee80211-uhr.h index 597c9e559261..665d4b3a5b41 100644 --- a/include/linux/ieee80211-uhr.h +++ b/include/linux/ieee80211-uhr.h @@ -17,6 +17,11 @@ #define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0004 #define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0008 #define IEEE80211_UHR_OPER_PARAMS_DBE_BW 0x0070 +#define IEEE80211_UHR_OPER_PARAMS_DUO_PRES 0x0080 +#define IEEE80211_UHR_OPER_PARAMS_DPS_PRES 0x0100 +#define IEEE80211_UHR_OPER_PARAMS_NPCA_PRES 0x0200 +#define IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES 0x0400 +#define IEEE80211_UHR_OPER_PARAMS_DBE_PRES 0x0800 struct ieee80211_uhr_operation { __le16 params; @@ -265,8 +270,7 @@ struct ieee80211_uhr_p_edca_info { __le16 params; } __packed; -static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, - bool beacon) +static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len) { const struct ieee80211_uhr_operation *oper = (const void *)data; u8 needed = sizeof(*oper); @@ -274,19 +278,15 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, if (len < needed) return false; - /* nothing else present in beacons */ - if (beacon) - return true; - /* DPS Operation Parameters (fixed 4 bytes) */ - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) { needed += sizeof(struct ieee80211_uhr_dps_info); if (len < needed) return false; } /* NPCA Operation Parameters (fixed 4 bytes + optional 2 bytes) */ - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)) { const struct ieee80211_uhr_npca_info *npca = (const void *)(data + needed); @@ -303,14 +303,14 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, } /* P-EDCA Operation Parameters (fixed 3 bytes) */ - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES)) { needed += sizeof(struct ieee80211_uhr_p_edca_info); if (len < needed) return false; } /* DBE Operation Parameters (fixed 1 byte + optional 2 bytes) */ - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_PRES)) { const struct ieee80211_uhr_dbe_info *dbe = (const void *)(data + needed); @@ -329,19 +329,19 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len, return len >= needed; } -/* - * Note: cannot call this on the element coming from a beacon, - * must ensure ieee80211_uhr_oper_size_ok(..., false) first - */ +/* Note: must ensure ieee80211_uhr_oper_size_ok(...) first */ static inline const struct ieee80211_uhr_npca_info * ieee80211_uhr_npca_info(const struct ieee80211_uhr_operation *oper) { const u8 *pos = oper->variable; + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES))) + return NULL; + if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA))) return NULL; - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_ENA)) + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) pos += sizeof(struct ieee80211_uhr_dps_info); return (const void *)pos; @@ -360,22 +360,22 @@ 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 - */ +/* Note: must ensure ieee80211_uhr_oper_size_ok(...) 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_PRES))) + return NULL; + 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)) + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES)) pos += sizeof(struct ieee80211_uhr_dps_info); - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)) { + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_PRES)) { const struct ieee80211_uhr_npca_info *npca = (const void *)pos; pos += sizeof(*npca); @@ -383,7 +383,7 @@ ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper) pos += sizeof(npca->dis_subch_bmap[0]); } - if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA)) + if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES)) pos += sizeof(struct ieee80211_uhr_p_edca_info); return (const void *)pos; diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index d40484451e9a..26e674038865 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -557,6 +557,17 @@ static inline bool ieee80211_is_reassoc_resp(__le16 fc) } /** + * ieee80211_is_assoc - check if (Re)association request/response frame + * @fc: frame control bytes in little-endian byteorder + * Return: whether or not the frame is an (re)association request or response + */ +static inline bool ieee80211_is_assoc(__le16 fc) +{ + return ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc) || + ieee80211_is_assoc_resp(fc) || ieee80211_is_reassoc_resp(fc); +} + +/** * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ * @fc: frame control bytes in little-endian byteorder * Return: whether or not the frame is a probe request @@ -2616,6 +2627,7 @@ static inline int ieee80211_get_tdls_action(struct sk_buff *skb) /* convert frequencies */ #define MHZ_TO_KHZ(freq) ((freq) * 1000) #define KHZ_TO_MHZ(freq) ((freq) / 1000) +#define KHZ_TO_HZ(x) ((x) * 1000) #define PR_KHZ(f) KHZ_TO_MHZ(f), f % 1000 #define KHZ_F "%d.%03d" diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index 5f3e206c7a73..eeb9ed3c5a23 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); +/* Callers must hold the consumer_lock of the ring of file */ void tun_wake_queue(struct file *file, int consumed); static inline bool tun_is_xdp_frame(void *ptr) diff --git a/include/linux/iio/adc/qcom-adc5-gen3-common.h b/include/linux/iio/adc/qcom-adc5-gen3-common.h index 6303eaa6640b..39cbfcbdb101 100644 --- a/include/linux/iio/adc/qcom-adc5-gen3-common.h +++ b/include/linux/iio/adc/qcom-adc5-gen3-common.h @@ -205,7 +205,5 @@ int adc5_gen3_get_scaled_reading(struct device *dev, int adc5_gen3_therm_code_to_temp(struct device *dev, struct adc5_channel_common_prop *common_props, u16 code, int *val); -void adc5_gen3_register_tm_event_notifier(struct device *dev, - void (*handler)(struct auxiliary_device *)); #endif /* QCOM_ADC5_GEN3_COMMON_H */ diff --git a/include/linux/iio/common/inv_sensors_timestamp.h b/include/linux/iio/common/inv_sensors_timestamp.h index 8d506f1e9df2..4f08204ede3b 100644 --- a/include/linux/iio/common/inv_sensors_timestamp.h +++ b/include/linux/iio/common/inv_sensors_timestamp.h @@ -13,9 +13,9 @@ * @init_period: chip initial period at reset in ns */ struct inv_sensors_timestamp_chip { - uint32_t clock_period; - uint32_t jitter; - uint32_t init_period; + u32 clock_period; + u32 jitter; + u32 init_period; }; /** @@ -24,8 +24,8 @@ struct inv_sensors_timestamp_chip { * @up: interval upper bound */ struct inv_sensors_timestamp_interval { - int64_t lo; - int64_t up; + s64 lo; + s64 up; }; /** @@ -35,9 +35,9 @@ struct inv_sensors_timestamp_interval { * @values: table of all measured values, use for computing the mean */ struct inv_sensors_timestamp_acc { - uint32_t val; + u32 val; size_t idx; - uint32_t values[32]; + u32 values[32]; }; /** @@ -46,6 +46,8 @@ struct inv_sensors_timestamp_acc { * @min_period: minimal acceptable clock period * @max_period: maximal acceptable clock period * @it: interrupts interval timestamps + * @delta: interval timestamps between several interrupts + * @delta_counter: number of data samples in the delta interval * @timestamp: store last timestamp for computing next data timestamp * @mult: current internal period multiplier * @new_mult: new set internal period multiplier (not yet effective) @@ -54,13 +56,15 @@ struct inv_sensors_timestamp_acc { */ struct inv_sensors_timestamp { struct inv_sensors_timestamp_chip chip; - uint32_t min_period; - uint32_t max_period; + u32 min_period; + u32 max_period; struct inv_sensors_timestamp_interval it; - int64_t timestamp; - uint32_t mult; - uint32_t new_mult; - uint32_t period; + struct inv_sensors_timestamp_interval delta; + u32 delta_counter; + s64 timestamp; + u32 mult; + u32 new_mult; + u32 period; struct inv_sensors_timestamp_acc chip_period; }; @@ -68,19 +72,19 @@ void inv_sensors_timestamp_init(struct inv_sensors_timestamp *ts, const struct inv_sensors_timestamp_chip *chip); int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts, - uint32_t period, bool fifo); + u32 period, bool fifo); void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts, - size_t sample_nb, int64_t timestamp); + size_t sample_nb, s64 timestamp); -static inline int64_t inv_sensors_timestamp_pop(struct inv_sensors_timestamp *ts) +static inline s64 inv_sensors_timestamp_pop(struct inv_sensors_timestamp *ts) { ts->timestamp += ts->period; return ts->timestamp; } void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts, - uint32_t fifo_period, size_t fifo_nb, + u32 fifo_period, size_t fifo_nb, unsigned int fifo_no); static inline void inv_sensors_timestamp_reset(struct inv_sensors_timestamp *ts) @@ -88,6 +92,8 @@ static inline void inv_sensors_timestamp_reset(struct inv_sensors_timestamp *ts) const struct inv_sensors_timestamp_interval interval_init = {0LL, 0LL}; ts->it = interval_init; + ts->delta = interval_init; + ts->delta_counter = 0; ts->timestamp = 0; } diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 4e3099defc1d..d8944c9e5e90 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -7,6 +7,9 @@ #ifndef _IIO_TYPES_H_ #define _IIO_TYPES_H_ +#include <linux/types.h> +#include <linux/wordpart.h> + #include <uapi/linux/iio/types.h> enum iio_event_info { @@ -34,6 +37,24 @@ enum iio_event_info { #define IIO_VAL_FRACTIONAL_LOG2 11 #define IIO_VAL_CHAR 12 +#define IIO_VAL_DECIMAL64_BASE 32 +#define IIO_VAL_DECIMAL64_MILLI (IIO_VAL_DECIMAL64_BASE + 3) +#define IIO_VAL_DECIMAL64_MICRO (IIO_VAL_DECIMAL64_BASE + 6) +#define IIO_VAL_DECIMAL64_NANO (IIO_VAL_DECIMAL64_BASE + 9) +#define IIO_VAL_DECIMAL64_PICO (IIO_VAL_DECIMAL64_BASE + 12) +#define IIO_VAL_DECIMAL64_FEMTO (IIO_VAL_DECIMAL64_BASE + 15) + +static inline s64 iio_val_s64_compose(s32 val0, s32 val1) +{ + return (s64)(((u64)val1 << 32) | (u32)val0); +} + +static inline void iio_val_s64_decompose(s64 dec64, s32 *val0, s32 *val1) +{ + *val0 = lower_32_bits(dec64); + *val1 = upper_32_bits(dec64); +} + enum iio_available_type { IIO_AVAIL_LIST, IIO_AVAIL_RANGE, diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index dccbeb25f701..6032eea2539a 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -293,6 +293,11 @@ static inline void in_dev_put(struct in_device *idev) #define __in_dev_put(idev) refcount_dec(&(idev)->refcnt) #define in_dev_hold(idev) refcount_inc(&(idev)->refcnt) +static inline bool in_dev_hold_safe(struct in_device *idev) +{ + return refcount_inc_not_zero(&idev->refcnt); +} + #endif /* __KERNEL__ */ static __inline__ __be32 inet_make_mask(int logmask) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index a6cb241ea00c..61536be773f5 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -24,6 +24,7 @@ extern struct files_struct init_files; extern struct fs_struct init_fs; +extern struct fs_struct *userspace_init_fs; extern struct nsproxy init_nsproxy; #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE diff --git a/include/linux/input.h b/include/linux/input.h index 3022bb730898..3381608127f7 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -19,7 +19,7 @@ #include <linux/device.h> #include <linux/fs.h> #include <linux/timer.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/input.h> struct input_dev_poller; @@ -117,7 +117,8 @@ enum input_clock_type { * user opens device and dev->close() is called when the very * last user closes the device * @going_away: marks devices that are in a middle of unregistering and - * causes input_open_device*() fail with -ENODEV. + * causes input_open_device() and input_inhibit/uninhibit_device() + * to fail with -ENODEV. * @dev: driver model's view of this device * @h_list: list of input handles associated with the device. When * accessing the list dev->mutex must be held @@ -128,11 +129,14 @@ enum input_clock_type { * @devres_managed: indicates that devices is managed with devres framework * and needs not be explicitly unregistered or freed. * @timestamp: storage for a timestamp set by input_set_timestamp called - * by a driver + * by a driver * @inhibited: indicates that the input device is inhibited. If that is - * the case then input core ignores any events generated by the device. - * Device's close() is called when it is being inhibited and its open() - * is called when it is being uninhibited. + * the case then input core ignores any events generated by the device. + * Device's close() is called when it is being inhibited and its open() + * is called when it is being uninhibited. + * @ready: indicates that the device has been successfully opened and is + * prepared to process events (like LEDs or sounds) sent from the + * input core. */ struct input_dev { const char *name; @@ -209,6 +213,7 @@ struct input_dev { ktime_t timestamp[INPUT_CLK_MAX]; bool inhibited; + bool ready; }; #define to_input_dev(d) container_of(d, struct input_dev, dev) @@ -284,8 +289,9 @@ struct input_handle; * @connect: called when attaching a handler to an input device * @disconnect: disconnects a handler from input device * @start: starts handler for given handle. This function is called by - * input core right after connect() method and also when a process - * that "grabbed" a device releases it + * input core when device is open and ready to process events, + * and also when device is uninhibited or when a process that "grabbed" + * a device releases it * @passive_observer: set to %true by drivers only interested in observing * data stream from devices if there are other users present. Such * drivers will not result in starting underlying hardware device diff --git a/include/linux/input/elan-i2c-ids.h b/include/linux/input/elan-i2c-ids.h index 51cca17ee94c..874bf0ab500c 100644 --- a/include/linux/input/elan-i2c-ids.h +++ b/include/linux/input/elan-i2c-ids.h @@ -18,7 +18,7 @@ #ifndef __ELAN_I2C_IDS_H #define __ELAN_I2C_IDS_H -#include <linux/mod_devicetable.h> +#include <linux/device-id/acpi.h> static const struct acpi_device_id elan_acpi_id[] = { { "ELAN0000", 0 }, diff --git a/include/linux/intel-ish-client-if.h b/include/linux/intel-ish-client-if.h index 2cd4f65aaa37..a07d952a2b29 100644 --- a/include/linux/intel-ish-client-if.h +++ b/include/linux/intel-ish-client-if.h @@ -9,7 +9,7 @@ #define _INTEL_ISH_CLIENT_IF_H_ #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/ishtp.h> struct ishtp_cl_device; struct ishtp_device; diff --git a/include/linux/interrupt_rc.h b/include/linux/interrupt_rc.h new file mode 100644 index 000000000000..b9a7f05ecf42 --- /dev/null +++ b/include/linux/interrupt_rc.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_INTERRUPT_RC_H +#define __LINUX_INTERRUPT_RC_H + +/* + * include/linux/interrupt_rc.h - refcounted local processor interrupt + * management. + * + * Since the implementation of this API currently depends on + * local_irq_save()/local_irq_restore(), we split this into its own header to + * make it easier to include without hitting circular header dependencies. + */ + +#include <linux/irqflags.h> +#include <linux/preempt.h> +#include <linux/processor.h> +#include <linux/smp.h> + +#ifndef MODULE +/* Per-CPU interrupt disabling state for local_interrupt_{disable,enable}(). */ +DECLARE_PER_CPU(unsigned long, local_interrupt_disable_state); + +static __always_inline void __local_interrupt_disable(void) +{ + unsigned long flags; + + local_irq_save(flags); + raw_cpu_write(local_interrupt_disable_state, flags); +} + +static __always_inline void __local_interrupt_enable(void) +{ + unsigned long flags = raw_cpu_read(local_interrupt_disable_state); + + local_irq_restore(flags); +} + +#ifndef INSTANTIATE_EXPORTED_INTERRUPT_DISABLE +static __always_inline void _local_interrupt_disable(void) +{ + __local_interrupt_disable(); +} + +static __always_inline void _local_interrupt_enable(void) +{ + __local_interrupt_enable(); +} +#else +extern void _local_interrupt_disable(void); +extern void _local_interrupt_enable(void); +#endif + +#else /* !MODULE */ +extern void _local_interrupt_disable(void); +extern void _local_interrupt_enable(void); +#endif /* !MODULE */ + +static inline void local_interrupt_disable(void) +{ + int new_count; + + WARN_ON_ONCE(in_nmi()); + + new_count = hardirq_disable_enter(); + + /* Interrupts can happen here, but it's OK, see __irq_exit_rcu(). */ + + if ((new_count & HARDIRQ_DISABLE_MASK) == HARDIRQ_DISABLE_OFFSET) + _local_interrupt_disable(); +} + +static inline void local_interrupt_enable(void) +{ + int new_count; + + new_count = hardirq_disable_exit(); + + if ((new_count & HARDIRQ_DISABLE_MASK) == 0) + _local_interrupt_enable(); +} + +#endif /* !__LINUX_INTERRUPT_RC_H */ diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h index 331dcbefe72f..42801f0b6456 100644 --- a/include/linux/io_uring/cmd.h +++ b/include/linux/io_uring/cmd.h @@ -91,6 +91,15 @@ struct io_br_sel io_uring_cmd_buffer_select(struct io_uring_cmd *ioucmd, bool io_uring_mshot_cmd_post_cqe(struct io_uring_cmd *ioucmd, struct io_br_sel *sel, unsigned int issue_flags); +int io_buffer_register_request(struct io_uring_cmd *cmd, struct request *rq, + void (*release)(void *), unsigned int index, + unsigned int issue_flags); +int io_buffer_register_bvec(struct io_uring_cmd *cmd, const struct bio_vec *bvs, + unsigned int nr_bvecs, void (*release)(void *), + void *priv, u8 dir, unsigned int index, + unsigned int issue_flags); +int io_buffer_unregister(struct io_uring_cmd *cmd, unsigned int index, + unsigned int issue_flags); #else static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, @@ -133,6 +142,29 @@ static inline bool io_uring_mshot_cmd_post_cqe(struct io_uring_cmd *ioucmd, { return true; } +static inline int io_buffer_register_request(struct io_uring_cmd *cmd, + struct request *rq, + void (*release)(void *), + unsigned int index, + unsigned int issue_flags) +{ + return -EOPNOTSUPP; +} +static inline int io_buffer_register_bvec(struct io_uring_cmd *cmd, + const struct bio_vec *bvs, + unsigned int nr_bvecs, + void (*release)(void *), void *priv, + u8 dir, unsigned int index, + unsigned int issue_flags) +{ + return -EOPNOTSUPP; +} +static inline int io_buffer_unregister(struct io_uring_cmd *cmd, + unsigned int index, + unsigned int issue_flags) +{ + return -EOPNOTSUPP; +} #endif static inline struct io_uring_cmd *io_uring_cmd_from_tw(struct io_tw_req tw_req) @@ -182,10 +214,4 @@ static inline void io_uring_cmd_done32(struct io_uring_cmd *ioucmd, s32 ret, return __io_uring_cmd_done(ioucmd, ret, res2, issue_flags, true); } -int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq, - void (*release)(void *), unsigned int index, - unsigned int issue_flags); -int io_buffer_unregister_bvec(struct io_uring_cmd *cmd, unsigned int index, - unsigned int issue_flags); - #endif /* _LINUX_IO_URING_CMD_H */ diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index 87151a5b62c1..39629ee77b91 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -1,11 +1,12 @@ #ifndef IO_URING_TYPES_H #define IO_URING_TYPES_H -#include <linux/blkdev.h> +#include <linux/blk_plug.h> #include <linux/hashtable.h> #include <linux/task_work.h> #include <linux/bitmap.h> #include <linux/llist.h> +#include <linux/uio.h> #include <uapi/linux/io_uring.h> struct iou_loop_params; @@ -20,6 +21,14 @@ enum { * It's also ignored unless IORING_SETUP_DEFER_TASKRUN is set. */ IOU_F_TWQ_LAZY_WAKE = 1, + + /* + * Set when task_work is queued from a waitqueue wakeup handler, where + * an arbitrary provider waitqueue lock is held. Signaling the CQ ring + * eventfd inline from there can recurse back into that lock through + * epoll, so the eventfd signal must be deferred. + */ + IOU_F_TWQ_IN_WAKE = 2, }; enum io_uring_cmd_flags { @@ -44,6 +53,11 @@ enum io_uring_cmd_flags { IO_URING_F_COMPAT = (1 << 12), }; +enum { + IO_BUF_DEST = 1 << ITER_DEST, + IO_BUF_SOURCE = 1 << ITER_SOURCE, +}; + struct iou_loop_params; struct io_wq_work_node { @@ -534,6 +548,8 @@ struct io_ring_ctx { struct io_mapped_region ring_region; /* used for optimised request parameter and wait argument passing */ struct io_mapped_region param_region; + + struct kcov_common_handle_id kcov_handle; }; /* diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 3582ed1fe236..bc7ae6327dbf 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -10,6 +10,7 @@ #include <linux/mm_types.h> #include <linux/blkdev.h> #include <linux/folio_batch.h> +#include <linux/pagemap.h> struct address_space; struct fiemap_extent_info; @@ -212,24 +213,36 @@ struct iomap_write_ops { #define IOMAP_ATOMIC (1 << 9) /* torn-write protection */ #define IOMAP_DONTCACHE (1 << 10) -struct iomap_ops { - /* - * Return the existing mapping at pos, or reserve space starting at - * pos for up to length, as long as we can do it as a single mapping. - * The actual length is returned in iomap->length. - */ - int (*iomap_begin)(struct inode *inode, loff_t pos, loff_t length, - unsigned flags, struct iomap *iomap, - struct iomap *srcmap); +/* + * Return the existing mapping at pos, or reserve space starting at pos for up + * to length, as long as we can do it as a single mapping. + * The actual length is returned in iomap->length. + */ +typedef int (*iomap_iter_begin_fn)(struct inode *inode, loff_t pos, + loff_t length, unsigned flags, struct iomap *iomap, + struct iomap *srcmap); - /* - * Commit and/or unreserve space previous allocated using iomap_begin. - * Written indicates the length of the successful write operation which - * needs to be commited, while the rest needs to be unreserved. - * Written might be zero if no data was written. - */ - int (*iomap_end)(struct inode *inode, loff_t pos, loff_t length, - ssize_t written, unsigned flags, struct iomap *iomap); +/* + * Commit and/or unreserve space previously allocated by iomap_iter_begin_fn. + * Written indicates the length of the successful write operation which needs + * to be committed, while the rest needs to be unreserved. + * Written might be zero if no data was written. + */ +typedef int (*iomap_iter_end_fn)(struct inode *inode, loff_t pos, loff_t length, + ssize_t written, unsigned flags, struct iomap *iomap); + +/* + * Produce the next mapping (finishing the previous one if needed). + * Return 1 to continue iterating, 0 if the range is fully consumed, or a + * negative error on failure. + */ +typedef int (*iomap_iter_next_fn)(const struct iomap_iter *iter, + struct iomap *iomap, struct iomap *srcmap); + +struct iomap_ops { + iomap_iter_begin_fn iomap_begin; + iomap_iter_end_fn iomap_end; + iomap_iter_next_fn iomap_next; }; /** @@ -317,6 +330,71 @@ static inline const struct iomap *iomap_iter_srcmap(const struct iomap_iter *i) return &i->iomap; } +int iomap_iter_continue(const struct iomap_iter *iter, struct iomap *iomap, + struct iomap *srcmap, int ret); + +/** + * iomap_iter_next - finish the previous mapping and produce the next one + * @iter: iteration structure + * @iomap: mapping to finish and then repopulate + * @srcmap: source mapping to finish and then repopulate + * @begin: callback that produces a mapping for the current position + * @end: optional callback that finishes the previous mapping, or NULL + * + * Inline helper that implements the common body of an ->iomap_next() + * callback: it finishes the previous mapping via @end (if present), decides + * via iomap_iter_continue() whether to keep going, and obtains the next + * mapping via @begin. + * + * This helper is marked __always_inline so that when a caller passes + * compile-time-constant @begin and @end callbacks, the compiler can call them + * directly, avoiding the indirect-call overhead. + * + * Returns 1 to continue iterating, 0 once the range is fully consumed, or a + * negative errno on error. + */ +static __always_inline int iomap_iter_next(const struct iomap_iter *iter, + struct iomap *iomap, struct iomap *srcmap, + iomap_iter_begin_fn begin, iomap_iter_end_fn end) +{ + int ret = 0; + + if (iomap->length) { + if (end) { + /* + * Calculate how far the iter was advanced and the + * original length bytes for end(). + */ + ssize_t advanced = iter->pos - iter->iter_start_pos; + loff_t len; + + len = iomap_length_trim(iter, iter->iter_start_pos, + iter->len + advanced); + + ret = end(iter->inode, iter->iter_start_pos, len, + advanced, iter->flags, iomap); + } + ret = iomap_iter_continue(iter, iomap, srcmap, ret); + if (ret <= 0) + return ret; + } + + ret = begin(iter->inode, iter->pos, iter->len, iter->flags, iomap, + srcmap); + + return ret < 0 ? ret : 1; +} + +#define DEFINE_IOMAP_ITER_NEXT_END(name, begin_fn, end_fn) \ +int name(const struct iomap_iter *iter, struct iomap *iomap, \ + struct iomap *srcmap) \ +{ \ + return iomap_iter_next(iter, iomap, srcmap, begin_fn, end_fn); \ +} + +#define DEFINE_IOMAP_ITER_NEXT(name, begin_fn) \ + DEFINE_IOMAP_ITER_NEXT_END(name, begin_fn, NULL) + /* * Return the file offset for the first unchanged block after a short write. * @@ -365,6 +443,7 @@ struct folio *iomap_get_folio(struct iomap_iter *iter, loff_t pos, size_t len); bool iomap_release_folio(struct folio *folio, gfp_t gfp_flags); void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len); bool iomap_dirty_folio(struct address_space *mapping, struct folio *folio); +void iomap_folio_mark_uptodate(struct folio *folio); int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len, const struct iomap_ops *ops, const struct iomap_write_ops *write_ops); @@ -404,16 +483,13 @@ sector_t iomap_bmap(struct address_space *mapping, sector_t bno, #define IOMAP_IOEND_BOUNDARY (1U << 2) /* is direct I/O */ #define IOMAP_IOEND_DIRECT (1U << 3) -/* is DONTCACHE I/O */ -#define IOMAP_IOEND_DONTCACHE (1U << 4) /* * Flags that if set on either ioend prevent the merge of two ioends. * (IOMAP_IOEND_BOUNDARY also prevents merges, but only one-way) */ #define IOMAP_IOEND_NOMERGE_FLAGS \ - (IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT | \ - IOMAP_IOEND_DONTCACHE) + (IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT) /* * Structure for writeback I/O completions. @@ -606,6 +682,71 @@ struct iomap_dio *__iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, ssize_t iomap_dio_complete(struct iomap_dio *dio); void iomap_dio_bio_end_io(struct bio *bio); +/* + * Fast path for small, block-aligned direct I/Os that map to a single + * contiguous on-disk extent. + * + * @iter must describe a non-empty READ no larger than the inode block size: + * writes, zero-length I/O, and larger requests need the generic iomap direct + * I/O path. + * + * Does not support iomap_dio_ops, dio_flags, done_before or private data. + * The range must also stay within i_size and encrypted inodes must use the + * generic iomap direct I/O path. + * + * -ENOTBLK indicates the generic path must be used by the caller instead. + * Any other errno is a real result and is propagated as-is, in particular + * -EAGAIN for IOCB_NOWAIT must reach the caller. + * + * The caller can only provide an iomap begin handler, and the iterator + * is never advanced. + */ +ssize_t __iomap_dio_read_simple(struct kiocb *iocb, struct iov_iter *iter, + struct iomap_iter *iomi); +static __always_inline ssize_t iomap_dio_read_simple(struct kiocb *iocb, + struct iov_iter *iter, iomap_iter_begin_fn begin) +{ + struct iomap_iter iomi = { + .inode = file_inode(iocb->ki_filp), + .pos = iocb->ki_pos, + .len = iov_iter_count(iter), + .flags = IOMAP_DIRECT, + }; + ssize_t ret; + + if (!iomi.len) + return 0; + + /* + * Simple dio is an optimization for small IO. Filter out large IO + * early as it's the most common case to fail for typical direct IO + * workloads. + */ + if (iomi.len > iomi.inode->i_sb->s_blocksize) + return -ENOTBLK; + if (iocb->ki_pos + iomi.len > i_size_read(iomi.inode)) + return -ENOTBLK; + if (IS_ENCRYPTED(iomi.inode)) + return -ENOTBLK; + + ret = kiocb_write_and_wait(iocb, iomi.len); + if (ret) + return ret; + + if (iocb->ki_flags & IOCB_NOWAIT) + iomi.flags |= IOMAP_NOWAIT; + + inode_dio_begin(iomi.inode); + ret = begin(iomi.inode, iomi.pos, iomi.len, iomi.flags, &iomi.iomap, + &iomi.srcmap); + if (ret) { + inode_dio_end(iomi.inode); + return ret; + } + + return __iomap_dio_read_simple(iocb, iter, &iomi); +} + #ifdef CONFIG_SWAP struct file; struct swap_info_struct; @@ -622,6 +763,8 @@ extern struct bio_set iomap_ioend_bioset; #ifdef CONFIG_BLOCK int iomap_bio_read_folio_range(const struct iomap_iter *iter, struct iomap_read_folio_ctx *ctx, size_t plen); +void iomap_bio_submit_read_endio(const struct iomap_iter *iter, + struct iomap_read_folio_ctx *ctx, bio_end_io_t end_io); extern const struct iomap_read_ops iomap_bio_read_ops; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d20aa6f6863a..ac43b8b93f14 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -1704,6 +1704,7 @@ void iopf_free_group(struct iopf_group *group); int iommu_report_device_fault(struct device *dev, struct iopf_fault *evt); void iopf_group_response(struct iopf_group *group, enum iommu_page_response_code status); +void iopf_group_dequeue(struct iopf_group *group); #else static inline int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev) @@ -1749,5 +1750,9 @@ static inline void iopf_group_response(struct iopf_group *group, enum iommu_page_response_code status) { } + +static inline void iopf_group_dequeue(struct iopf_group *group) +{ +} #endif /* CONFIG_IOMMU_IOPF */ #endif /* __LINUX_IOMMU_H */ diff --git a/include/linux/ipack.h b/include/linux/ipack.h index 455f6c2a1903..7edbf9267338 100644 --- a/include/linux/ipack.h +++ b/include/linux/ipack.h @@ -6,7 +6,7 @@ * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com> */ -#include <linux/mod_devicetable.h> +#include <linux/device-id/ipack.h> #include <linux/device.h> #include <linux/interrupt.h> diff --git a/include/linux/irq-entry-common.h b/include/linux/irq-entry-common.h index 1fabf0f5ea8e..0bb6c03481fa 100644 --- a/include/linux/irq-entry-common.h +++ b/include/linux/irq-entry-common.h @@ -49,9 +49,9 @@ * Defaults to an empty implementation. Can be replaced by architecture * specific code. * - * Invoked from syscall_enter_from_user_mode() in the non-instrumentable - * section. Use __always_inline so the compiler cannot push it out of line - * and make it instrumentable. + * Invoked from enter_from_user_mode() in the non-instrumentable section. Use + * __always_inline so the compiler cannot push it out of line and make it + * instrumentable. */ static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs); diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm-gic-v5.h index f78787e654f4..2c2fb39f049c 100644 --- a/include/linux/irqchip/arm-gic-v5.h +++ b/include/linux/irqchip/arm-gic-v5.h @@ -6,6 +6,7 @@ #define __LINUX_IRQCHIP_ARM_GIC_V5_H #include <linux/iopoll.h> +#include <linux/ioport.h> #include <asm/cacheflush.h> #include <asm/smp.h> @@ -324,6 +325,7 @@ struct gicv5_irs_chip_data { struct list_head entry; struct fwnode_handle *fwnode; void __iomem *irs_base; + struct resource res; u32 flags; u32 spi_min; u32 spi_range; diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 8080db17c1b1..779d6023c5c2 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -146,7 +146,7 @@ extern struct irq_desc irq_desc[NR_IRQS]; static inline unsigned int irq_desc_kstat_cpu(struct irq_desc *desc, unsigned int cpu) { - return desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 0; + return per_cpu(desc->kstat_irqs->cnt, cpu); } static inline struct irq_desc *irq_data_to_desc(struct irq_data *data) diff --git a/include/linux/isapnp.h b/include/linux/isapnp.h index dba18c95844b..8f5a85ca6c1f 100644 --- a/include/linux/isapnp.h +++ b/include/linux/isapnp.h @@ -28,7 +28,7 @@ */ #ifdef __KERNEL__ -#include <linux/mod_devicetable.h> +#include <linux/device-id/isapnp.h> #define DEVICE_COUNT_COMPATIBLE 4 diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index b68561187e90..1b42fe47c26b 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -510,11 +510,12 @@ struct jbd2_journal_handle int h_err; /* Flags [no locking] */ - unsigned int h_sync: 1; - unsigned int h_reserved: 1; - unsigned int h_aborted: 1; - unsigned int h_type: 8; - unsigned int h_line_no: 16; + unsigned char h_sync: 1; + unsigned char h_reserved: 1; + unsigned char h_aborted: 1; + unsigned char h_invalid: 1; + unsigned char h_type; + unsigned short h_line_no; unsigned long h_start_jiffies; unsigned int h_requested_credits; diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index b9c7b0ebf7b9..c95350a10987 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -71,7 +71,7 @@ * Additional babbling in: Documentation/staging/static-keys.rst */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/types.h> #include <linux/compiler.h> @@ -100,12 +100,12 @@ struct static_key { #endif /* CONFIG_JUMP_LABEL */ }; -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #ifdef CONFIG_JUMP_LABEL #include <asm/jump_label.h> -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #ifdef CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE struct jump_entry { @@ -180,7 +180,7 @@ static inline int jump_entry_size(struct jump_entry *entry) #endif #endif -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ enum jump_label_type { JUMP_LABEL_NOP = 0, @@ -524,6 +524,6 @@ extern bool ____wrong_branch_error(void); #define static_branch_enable_cpuslocked(x) static_key_enable_cpuslocked(&(x)->key) #define static_branch_disable_cpuslocked(x) static_key_disable_cpuslocked(&(x)->key) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _LINUX_JUMP_LABEL_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e5570a16cbb1..24414c79e59a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -72,7 +72,7 @@ extern int dynamic_might_resched(void); #ifdef CONFIG_DEBUG_ATOMIC_SLEEP extern void __might_resched(const char *file, int line, unsigned int offsets); extern void __might_sleep(const char *file, int line); -extern void __cant_sleep(const char *file, int line, int preempt_offset); +extern void __cant_sleep(const char *file, int line); extern void __cant_migrate(const char *file, int line); /** @@ -95,7 +95,7 @@ extern void __cant_migrate(const char *file, int line); * this macro will print a stack trace if it is executed with preemption enabled */ # define cant_sleep() \ - do { __cant_sleep(__FILE__, __LINE__, 0); } while (0) + do { __cant_sleep(__FILE__, __LINE__); } while (0) # define sched_annotate_sleep() (current->task_state_change = 0) /** diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 8a22bc9b8c6c..0af8ae4fdd08 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -13,7 +13,7 @@ #define IND_SOURCE (1 << IND_SOURCE_BIT) #define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) #include <linux/vmcore_info.h> #include <linux/crash_reserve.h> diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 8968c56d2d73..46de86dc343e 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -5,11 +5,8 @@ #include <linux/err.h> #include <linux/errno.h> #include <linux/types.h> - -struct kho_scratch { - phys_addr_t addr; - phys_addr_t size; -}; +#include <linux/mm.h> +#include <asm-generic/kexec_handover.h> struct kho_vmalloc; @@ -37,9 +34,20 @@ void kho_remove_subtree(void *blob); int kho_retrieve_subtree(const char *name, phys_addr_t *phys, size_t *size); void kho_memory_init(void); +void kho_memory_init_early(void); void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys, u64 scratch_len); + +bool kho_scratch_overlap(phys_addr_t phys, size_t size); + +static inline enum migratetype kho_scratch_migratetype(unsigned long pfn, + enum migratetype mt) +{ + if (kho_scratch_overlap(PFN_PHYS(pfn), pageblock_nr_pages << PAGE_SHIFT)) + return MIGRATE_CMA; + return mt; +} #else static inline bool kho_is_enabled(void) { @@ -112,10 +120,23 @@ static inline int kho_retrieve_subtree(const char *name, phys_addr_t *phys, static inline void kho_memory_init(void) { } +static inline void kho_memory_init_early(void) { } + static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys, u64 scratch_len) { } + +static inline bool kho_scratch_overlap(phys_addr_t phys, size_t size) +{ + return false; +} + +static inline enum migratetype kho_scratch_migratetype(unsigned long pfn, + enum migratetype mt) +{ + return mt; +} #endif /* CONFIG_KEXEC_HANDOVER */ #endif /* LINUX_KEXEC_HANDOVER_H */ diff --git a/include/linux/kho/abi/kexec_handover.h b/include/linux/kho/abi/kexec_handover.h index 5e2eb8519bda..2f4fb9c63942 100644 --- a/include/linux/kho/abi/kexec_handover.h +++ b/include/linux/kho/abi/kexec_handover.h @@ -257,11 +257,8 @@ struct kho_vmalloc { * memory. These constants govern the indexing, sizing, and depth of the tree. */ enum kho_radix_consts { - /* - * The bit position of the order bit (and also the length of the - * shifted physical address) for an order-0 page. - */ - KHO_ORDER_0_LOG2 = 64 - PAGE_SHIFT, + /* Need to store the PFN, plus one bit for order. */ + KHO_RADIX_KEY_WIDTH = 64 - PAGE_SHIFT + 1, /* Size of the table in kho_radix_node, in log2 */ KHO_TABLE_SIZE_LOG2 = const_ilog2(PAGE_SIZE / sizeof(phys_addr_t)), @@ -274,7 +271,7 @@ enum kho_radix_consts { * and 1 bitmap level. */ KHO_TREE_MAX_DEPTH = - DIV_ROUND_UP(KHO_ORDER_0_LOG2 - KHO_BITMAP_SIZE_LOG2 + 1, + DIV_ROUND_UP(KHO_RADIX_KEY_WIDTH - KHO_BITMAP_SIZE_LOG2, KHO_TABLE_SIZE_LOG2) + 1, }; diff --git a/include/linux/kho_radix_tree.h b/include/linux/kho_radix_tree.h index 84e918b96e53..fcd69639721b 100644 --- a/include/linux/kho_radix_tree.h +++ b/include/linux/kho_radix_tree.h @@ -11,15 +11,19 @@ /** * DOC: Kexec Handover Radix Tree * - * This is a radix tree implementation for tracking physical memory pages - * across kexec transitions. It was developed for the KHO mechanism but is - * designed for broader use by any subsystem that needs to preserve pages. + * This is a radix tree implementation for tracking numeric keys across kexec + * transitions. It was developed for the KHO preserved memory map but is + * designed for broader use by any subsystem that needs to track keys. + * Conceptually speaking, the data structure is similar to a set. It tracks the + * presence or absence of numeric keys. * * The radix tree is a multi-level tree where leaf nodes are bitmaps - * representing individual pages. To allow pages of different sizes (orders) + * representing individual keys. + * + * For the KHO preserved memory map, to allow pages of different sizes (orders) * to be stored efficiently in a single tree, it uses a unique key encoding - * scheme. Each key is an unsigned long that combines a page's physical - * address and its order. + * scheme. Each key is an unsigned long that combines a page's physical address + * and its order. * * Client code is responsible for allocating the root node of the tree, * initializing the mutex lock, and managing its lifecycle. It must use the @@ -34,37 +38,53 @@ struct kho_radix_tree { struct mutex lock; /* protects the tree's structure and root pointer */ }; -typedef int (*kho_radix_tree_walk_callback_t)(phys_addr_t phys, - unsigned int order); +/** + * struct kho_radix_walk_cb - Callbacks for KHO radix tree walk. + * @leaf: Called on each present key in the radix tree. + * @node: Called on each node of the radix tree itself. Receives the + * physical address of the page containing the node. + * + * For each callback, a return value of 0 continues the walk and a non-zero + * return value is directly returned to the caller. + */ +struct kho_radix_walk_cb { + int (*leaf)(unsigned long key, void *data); + int (*node)(phys_addr_t phys, void *data); +}; #ifdef CONFIG_KEXEC_HANDOVER -int kho_radix_add_page(struct kho_radix_tree *tree, unsigned long pfn, - unsigned int order); - -void kho_radix_del_page(struct kho_radix_tree *tree, unsigned long pfn, - unsigned int order); - +int kho_radix_add_key(struct kho_radix_tree *tree, unsigned long key); +void kho_radix_del_key(struct kho_radix_tree *tree, unsigned long key); int kho_radix_walk_tree(struct kho_radix_tree *tree, - kho_radix_tree_walk_callback_t cb); + const struct kho_radix_walk_cb *cb, void *data); +int kho_radix_init_tree(struct kho_radix_tree *tree, struct kho_radix_node *root); +void kho_radix_destroy_tree(struct kho_radix_tree *tree); #else /* #ifdef CONFIG_KEXEC_HANDOVER */ -static inline int kho_radix_add_page(struct kho_radix_tree *tree, long pfn, - unsigned int order) +static inline int kho_radix_add_key(struct kho_radix_tree *tree, unsigned long key) { return -EOPNOTSUPP; } -static inline void kho_radix_del_page(struct kho_radix_tree *tree, - unsigned long pfn, unsigned int order) { } +static inline void kho_radix_del_key(struct kho_radix_tree *tree, + unsigned long key) { } static inline int kho_radix_walk_tree(struct kho_radix_tree *tree, - kho_radix_tree_walk_callback_t cb) + const struct kho_radix_walk_cb *cb, void *data) { return -EOPNOTSUPP; } +static inline int kho_radix_init_tree(struct kho_radix_tree *tree, + struct kho_radix_node *root) +{ + return 0; +} + +static inline void kho_radix_destroy_tree(struct kho_radix_tree *tree) { } + #endif /* #ifdef CONFIG_KEXEC_HANDOVER */ #endif /* _LINUX_KHO_RADIX_TREE_H */ diff --git a/include/linux/kobject.h b/include/linux/kobject.h index bcb5d4e32001..55e37a5d405e 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -138,12 +138,79 @@ struct kset_uevent_ops { struct kobj_attribute { struct attribute attr; - ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, - char *buf); - ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count); + __SYSFS_FUNCTION_ALTERNATIVE( + ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf); + ssize_t (*show_const)(struct kobject *kobj, const struct kobj_attribute *attr, + char *buf); + ); + __SYSFS_FUNCTION_ALTERNATIVE( + ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); + ssize_t (*store_const)(struct kobject *kobj, const struct kobj_attribute *attr, + const char *buf, size_t count); + ); }; +typedef ssize_t __kobj_show_handler_const(struct kobject *kobj, const struct kobj_attribute *attr, + char *buf); +typedef ssize_t __kobj_store_handler_const(struct kobject *kobj, const struct kobj_attribute *attr, + const char *buf, size_t count); + +#ifdef CONFIG_CFI + +#define __KOBJ_ATTR_SHOW_STORE(_show, _store) \ + .show = _Generic(_show, \ + __kobj_show_handler_const * : NULL, \ + default : _show \ + ), \ + .show_const = _Generic(_show, \ + __kobj_show_handler_const * : _show, \ + default : NULL \ + ), \ + .store = _Generic(_store, \ + __kobj_store_handler_const * : NULL, \ + default : _store \ + ), \ + .store_const = _Generic(_store, \ + __kobj_store_handler_const * : _store, \ + default : NULL \ + ), + +#else + +#define __KOBJ_ATTR_SHOW_STORE(_show, _store) \ + .show = _Generic(_show, \ + __kobj_show_handler_const * : (void *)_show, \ + default : _show \ + ), \ + .store = _Generic(_store, \ + __kobj_store_handler_const * : (void *)_store, \ + default : _store \ + ), \ + +#endif + +#define __KOBJ_ATTR(_name, _mode, _show, _store) { \ + .attr = { .name = __stringify(_name), \ + .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \ + __KOBJ_ATTR_SHOW_STORE(_show, _store) \ +} + +#define __KOBJ_ATTR_RO_MODE(_name, _mode) \ + __KOBJ_ATTR(_name, _mode, _name##_show, NULL) + +#define __KOBJ_ATTR_RO(_name) \ + __KOBJ_ATTR_RO_MODE(_name, 0444) + +#define __KOBJ_ATTR_RW_MODE(_name, _mode) \ + __KOBJ_ATTR(_name, _mode, _name##_show, _name##_store) + +#define __KOBJ_ATTR_WO(_name) \ + __KOBJ_ATTR(_name, 0200, NULL, _name##_store) + +#define __KOBJ_ATTR_RW(_name) \ + __KOBJ_ATTR(_name, 0644, _name##_show, _name##_store) + extern const struct sysfs_ops kobj_sysfs_ops; struct sock; diff --git a/include/linux/kstrtox.h b/include/linux/kstrtox.h index 6c9282866770..b41b9736886f 100644 --- a/include/linux/kstrtox.h +++ b/include/linux/kstrtox.h @@ -97,6 +97,9 @@ int __must_check kstrtou8(const char *s, unsigned int base, u8 *res); int __must_check kstrtos8(const char *s, unsigned int base, s8 *res); int __must_check kstrtobool(const char *s, bool *res); +int __must_check kstrtoudec64(const char *s, unsigned int scale, u64 *res); +int __must_check kstrtodec64(const char *s, unsigned int scale, s64 *res); + int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res); int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res); int __must_check kstrtoul_from_user(const char __user *s, size_t count, unsigned int base, unsigned long *res); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ab8cfaec82d3..03bfc92864b6 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -791,6 +791,7 @@ struct kvm { /* The current active memslot set for each address space */ struct kvm_memslots __rcu *memslots[KVM_MAX_NR_ADDRESS_SPACES]; struct xarray vcpu_array; + DECLARE_BITMAP(vcpu_ids, KVM_MAX_VCPU_IDS); /* * Protected by slots_lock, but can be read outside if an * incorrect answer is acceptable. @@ -989,6 +990,13 @@ static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx) lockdep_is_held(&kvm->slots_lock)); } +static inline void kvm_lockdep_assert_vcpu_is_locked_or_unreachable(struct kvm_vcpu *vcpu) +{ + lockdep_assert_once(lockdep_is_held(&vcpu->mutex) || + vcpu->vcpu_idx < 0 || + !refcount_read(&vcpu->kvm->users_count)); +} + static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) { int num_vcpus = atomic_read(&kvm->online_vcpus); @@ -1413,6 +1421,25 @@ static inline void kvm_vcpu_map_mark_dirty(struct kvm_vcpu *vcpu, kvm_vcpu_mark_page_dirty(vcpu, map->gfn); } +typedef struct { + struct kvm_vcpu *vcpu; + struct kvm_host_map map; + int ret; +} kvm_vcpu_local_map_t; + +#define DEFINE_VCPU_MAP_CLASS(ro) \ +DEFINE_CLASS(kvm_vcpu_map_local##ro, kvm_vcpu_local_map_t, \ + if (!_T.ret) kvm_vcpu_unmap(_T.vcpu, &_T.map), \ + ({ \ + kvm_vcpu_local_map_t m = { .vcpu = vcpu }; \ + \ + m.ret = kvm_vcpu_map##ro(vcpu, gfn, &m.map); \ + \ + m; \ + }), struct kvm_vcpu *vcpu, gfn_t gfn); +DEFINE_VCPU_MAP_CLASS(); +DEFINE_VCPU_MAP_CLASS(_readonly); + unsigned long kvm_vcpu_gfn_to_hva(struct kvm_vcpu *vcpu, gfn_t gfn); unsigned long kvm_vcpu_gfn_to_hva_prot(struct kvm_vcpu *vcpu, gfn_t gfn, bool *writable); int kvm_vcpu_read_guest_page(struct kvm_vcpu *vcpu, gfn_t gfn, void *data, int offset, @@ -2572,8 +2599,9 @@ static inline int kvm_gmem_get_pfn(struct kvm *kvm, } #endif /* CONFIG_KVM_GUEST_MEMFD */ -#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_PREPARE -int kvm_arch_gmem_prepare(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, int max_order); +#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT +int kvm_arch_gmem_make_private(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, + kvm_pfn_t nr_pages); #endif #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_POPULATE @@ -2606,8 +2634,12 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, kvm_gmem_populate_cb post_populate, void *opaque); #endif +#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_RECLAIM +void kvm_arch_gmem_reclaim(kvm_pfn_t pfn, kvm_pfn_t nr_pages); +#endif + #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE -void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end); +void kvm_arch_gmem_invalidate_range(struct kvm *kvm, struct kvm_gfn_range *range); #endif #ifdef CONFIG_KVM_GENERIC_PRE_FAULT_MEMORY diff --git a/include/linux/landlock.h b/include/linux/landlock.h new file mode 100644 index 000000000000..004cbd0b9298 --- /dev/null +++ b/include/linux/landlock.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Landlock - Public types and definitions + * + * Copyright © 2016-2026 Mickaël Salaün <mic@digikod.net> + * Copyright © 2026 Cloudflare, Inc. + */ + +#ifndef _LINUX_LANDLOCK_H +#define _LINUX_LANDLOCK_H + +#include <linux/types.h> +#include <uapi/linux/landlock.h> + +/* + * Access-right and scope names, shared between the audit records (get_blocker() + * in security/landlock/audit.c) and the trace events + * (include/trace/events/landlock.h). A consumer defines + * _LANDLOCK_NAME_ENTRY(mask, name) before expanding a list and undefines it + * afterwards: audit maps each entry to a "[bit] = name" slot for O(1) lookup, + * the trace events map it to a __print_flags() { mask, name } pair. The bit + * value lives only in the LANDLOCK_* UAPI constant each entry references. + * Names are unprefixed; audit prepends the "fs."/"net."/"scope." category. + */ +#define _LANDLOCK_ACCESS_FS_NAMES \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_EXECUTE, "execute"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_WRITE_FILE, "write_file"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_READ_FILE, "read_file"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_READ_DIR, "read_dir"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_REMOVE_DIR, "remove_dir"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_REMOVE_FILE, "remove_file"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_MAKE_CHAR, "make_char"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_MAKE_DIR, "make_dir"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_MAKE_REG, "make_reg"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_MAKE_SOCK, "make_sock"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_MAKE_FIFO, "make_fifo"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_MAKE_BLOCK, "make_block"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_MAKE_SYM, "make_sym"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_REFER, "refer"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_TRUNCATE, "truncate"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_IOCTL_DEV, "ioctl_dev"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_RESOLVE_UNIX, "resolve_unix") + +#define _LANDLOCK_ACCESS_NET_NAMES \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_BIND_TCP, "bind_tcp"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_CONNECT_TCP, "connect_tcp"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_BIND_UDP, "bind_udp"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP, \ + "connect_send_udp") + +#define _LANDLOCK_SCOPE_NAMES \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, \ + "abstract_unix_socket"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_SCOPE_SIGNAL, "signal") + +#endif /* _LINUX_LANDLOCK_H */ diff --git a/include/linux/leafops.h b/include/linux/leafops.h index 992cd8bd8ed0..4c1476ae3234 100644 --- a/include/linux/leafops.h +++ b/include/linux/leafops.h @@ -81,7 +81,7 @@ static inline pte_t softleaf_to_pte(softleaf_t entry) return swp_entry_to_pte(entry); } -#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +#ifdef CONFIG_ARCH_HAS_PMD_SOFTLEAVES /** * softleaf_from_pmd() - Obtain a leaf entry from a PMD entry. * @pmd: PMD entry. @@ -100,14 +100,29 @@ static inline softleaf_t softleaf_from_pmd(pmd_t pmd) if (pmd_swp_soft_dirty(pmd)) pmd = pmd_swp_clear_soft_dirty(pmd); - if (pmd_swp_uffd_wp(pmd)) - pmd = pmd_swp_clear_uffd_wp(pmd); + if (pmd_swp_uffd(pmd)) + pmd = pmd_swp_clear_uffd(pmd); arch_entry = __pmd_to_swp_entry(pmd); /* Temporary until swp_entry_t eliminated. */ return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry)); } +/** + * softleaf_to_pmd() - Obtain a PMD entry from a leaf entry. + * @entry: Leaf entry. + * + * This generates an architecture-specific PMD entry that can be utilised to + * encode the metadata the leaf entry encodes. + * + * Returns: Architecture-specific PMD entry encoding leaf entry. + */ +static inline pmd_t softleaf_to_pmd(softleaf_t entry) +{ + /* Temporary until swp_entry_t eliminated. */ + return swp_entry_to_pmd(entry); +} + #else static inline softleaf_t softleaf_from_pmd(pmd_t pmd) @@ -115,6 +130,11 @@ static inline softleaf_t softleaf_from_pmd(pmd_t pmd) return softleaf_mk_none(); } +static inline pmd_t softleaf_to_pmd(softleaf_t entry) +{ + return __pmd(0); +} + #endif /** @@ -567,7 +587,7 @@ static inline bool pte_is_uffd_marker(pte_t pte) return false; } -#if defined(CONFIG_ZONE_DEVICE) && defined(CONFIG_ARCH_ENABLE_THP_MIGRATION) +#if defined(CONFIG_ZONE_DEVICE) && defined(CONFIG_ARCH_HAS_PMD_SOFTLEAVES) /** * pmd_is_device_private_entry() - Check if PMD contains a device private swap @@ -586,14 +606,14 @@ static inline bool pmd_is_device_private_entry(pmd_t pmd) return softleaf_is_device_private(softleaf_from_pmd(pmd)); } -#else /* CONFIG_ZONE_DEVICE && CONFIG_ARCH_ENABLE_THP_MIGRATION */ +#else /* CONFIG_ZONE_DEVICE && CONFIG_ARCH_HAS_PMD_SOFTLEAVES */ static inline bool pmd_is_device_private_entry(pmd_t pmd) { return false; } -#endif /* CONFIG_ZONE_DEVICE && CONFIG_ARCH_ENABLE_THP_MIGRATION */ +#endif /* CONFIG_ZONE_DEVICE && CONFIG_ARCH_HAS_PMD_SOFTLEAVES */ /** * pmd_is_migration_entry() - Does this PMD entry encode a migration entry? diff --git a/include/linux/leds.h b/include/linux/leds.h index b16b803cc1ac..a515f075c29a 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -607,6 +607,10 @@ enum led_trigger_netdev_modes { TRIGGER_NETDEV_LINK_2500, TRIGGER_NETDEV_LINK_5000, TRIGGER_NETDEV_LINK_10000, + TRIGGER_NETDEV_LINK_25000, + TRIGGER_NETDEV_LINK_40000, + TRIGGER_NETDEV_LINK_50000, + TRIGGER_NETDEV_LINK_100000, TRIGGER_NETDEV_HALF_DUPLEX, TRIGGER_NETDEV_FULL_DUPLEX, TRIGGER_NETDEV_TX, @@ -676,8 +680,10 @@ typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state, struct gpio_led { const char *name; const char *default_trigger; +#ifdef CONFIG_GPIOLIB_LEGACY unsigned gpio; unsigned active_low : 1; +#endif unsigned retain_state_suspended : 1; unsigned panic_indicator : 1; unsigned default_state : 2; diff --git a/include/linux/libata.h b/include/linux/libata.h index 96e626d6a7ca..313e96173b19 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -121,6 +121,55 @@ enum { ATA_QUIRK_NO_FUA = BIT_ULL(__ATA_QUIRK_NO_FUA), }; +/* + * struct ata_device flags + */ +enum { + ATA_DFLAG_LBA = (1UL << 0), /* device supports LBA */ + ATA_DFLAG_LBA48 = (1UL << 1), /* device supports LBA48 */ + ATA_DFLAG_CDB_INTR = (1UL << 2), /* device asserts INTRQ when ready for CDB */ + ATA_DFLAG_NCQ = (1UL << 3), /* device supports NCQ */ + ATA_DFLAG_FLUSH_EXT = (1UL << 4), /* do FLUSH_EXT instead of FLUSH */ + ATA_DFLAG_ACPI_PENDING = (1UL << 5), /* ACPI resume action pending */ + ATA_DFLAG_ACPI_FAILED = (1UL << 6), /* ACPI on devcfg has failed */ + ATA_DFLAG_AN = (1UL << 7), /* AN configured */ + ATA_DFLAG_TRUSTED = (1UL << 8), /* device supports trusted send/recv */ + ATA_DFLAG_FUA = (1UL << 9), /* device supports FUA */ + ATA_DFLAG_DMADIR = (1UL << 10), /* device requires DMADIR */ + ATA_DFLAG_NCQ_SEND_RECV = (1UL << 11), /* device supports NCQ SEND and RECV */ + ATA_DFLAG_NCQ_PRIO = (1UL << 12), /* device supports NCQ priority */ + ATA_DFLAG_CDL = (1UL << 13), /* supports cmd duration limits */ + ATA_DFLAG_DEPOP = (1UL << 14), /* supports depopulation capability */ + ATA_DFLAG_DEPOP_RESTORE = (1UL << 15), /* supports depopulation restoration */ + ATA_DFLAG_DEPOP_MODIFY = (1UL << 16), /* supports zoned depopulation */ + ATA_DFLAG_CFG_MASK = (1UL << 17) - 1, + + ATA_DFLAG_PIO = (1UL << 17), /* device limited to PIO mode */ + ATA_DFLAG_NCQ_OFF = (1UL << 18), /* device limited to non-NCQ mode */ + ATA_DFLAG_SLEEPING = (1UL << 19), /* device is sleeping */ + ATA_DFLAG_DUBIOUS_XFER = (1UL << 20), /* data transfer not verified */ + ATA_DFLAG_NO_UNLOAD = (1UL << 21), /* device doesn't support unload */ + ATA_DFLAG_UNLOCK_HPA = (1UL << 22), /* unlock HPA */ + ATA_DFLAG_INIT_MASK = (1UL << 23) - 1, + + ATA_DFLAG_NCQ_PRIO_ENABLED = (1UL << 23), /* Priority cmds sent to dev */ + ATA_DFLAG_CDL_ENABLED = (1UL << 24), /* cmd duration limits is enabled */ + ATA_DFLAG_RESUMING = (1UL << 25), /* Device is resuming */ + ATA_DFLAG_DETACH = (1UL << 26), + ATA_DFLAG_DETACHED = (1UL << 27), + ATA_DFLAG_DA = (1UL << 28), /* device supports Device Attention */ + ATA_DFLAG_DEVSLP = (1UL << 29), /* device supports Device Sleep */ + ATA_DFLAG_ACPI_DISABLED = (1UL << 30), /* ACPI for the device is disabled */ + ATA_DFLAG_D_SENSE = (1UL << 31), /* Descriptor sense requested */ + + ATA_DFLAG_FEATURES_MASK = (ATA_DFLAG_TRUSTED | ATA_DFLAG_DA | \ + ATA_DFLAG_DEVSLP | ATA_DFLAG_NCQ_SEND_RECV | \ + ATA_DFLAG_NCQ_PRIO | ATA_DFLAG_FUA | \ + ATA_DFLAG_CDL | ATA_DFLAG_DEPOP | \ + ATA_DFLAG_DEPOP_RESTORE | + ATA_DFLAG_DEPOP_MODIFY) +}; + enum { /* various global constants */ LIBATA_MAX_PRD = ATA_MAX_PRD / 2, @@ -146,46 +195,7 @@ enum { ATA_TFLAG_FUA = (1 << 5), /* enable FUA */ ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */ - /* struct ata_device stuff */ - ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */ - ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ - ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */ - ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */ - ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */ - ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */ - ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */ - ATA_DFLAG_AN = (1 << 7), /* AN configured */ - ATA_DFLAG_TRUSTED = (1 << 8), /* device supports trusted send/recv */ - ATA_DFLAG_FUA = (1 << 9), /* device supports FUA */ - ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */ - ATA_DFLAG_NCQ_SEND_RECV = (1 << 11), /* device supports NCQ SEND and RECV */ - ATA_DFLAG_NCQ_PRIO = (1 << 12), /* device supports NCQ priority */ - ATA_DFLAG_CDL = (1 << 13), /* supports cmd duration limits */ - ATA_DFLAG_CFG_MASK = (1 << 14) - 1, - - ATA_DFLAG_PIO = (1 << 14), /* device limited to PIO mode */ - ATA_DFLAG_NCQ_OFF = (1 << 15), /* device limited to non-NCQ mode */ - ATA_DFLAG_SLEEPING = (1 << 16), /* device is sleeping */ - ATA_DFLAG_DUBIOUS_XFER = (1 << 17), /* data transfer not verified */ - ATA_DFLAG_NO_UNLOAD = (1 << 18), /* device doesn't support unload */ - ATA_DFLAG_UNLOCK_HPA = (1 << 19), /* unlock HPA */ - ATA_DFLAG_INIT_MASK = (1 << 20) - 1, - - ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 20), /* Priority cmds sent to dev */ - ATA_DFLAG_CDL_ENABLED = (1 << 21), /* cmd duration limits is enabled */ - ATA_DFLAG_RESUMING = (1 << 22), /* Device is resuming */ - ATA_DFLAG_DETACH = (1 << 24), - ATA_DFLAG_DETACHED = (1 << 25), - ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */ - ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */ - ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */ - ATA_DFLAG_D_SENSE = (1 << 29), /* Descriptor sense requested */ - - ATA_DFLAG_FEATURES_MASK = (ATA_DFLAG_TRUSTED | ATA_DFLAG_DA | \ - ATA_DFLAG_DEVSLP | ATA_DFLAG_NCQ_SEND_RECV | \ - ATA_DFLAG_NCQ_PRIO | ATA_DFLAG_FUA | \ - ATA_DFLAG_CDL), - + /* sturct ata_device class. */ ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ ATA_DEV_ATA_UNSUP = 2, /* ATA device (unsupported) */ @@ -425,7 +435,7 @@ enum { /* This should match the actual table size of * ata_eh_cmd_timeout_table in libata-eh.c. */ - ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 8, + ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 9, /* User visible DMA mask for DMA control. DO NOT renumber. */ ATA_DMA_MASK_ATA = (1 << 0), /* DMA on ATA Disk */ @@ -1153,6 +1163,9 @@ extern int ata_scsi_ioctl(struct scsi_device *dev, unsigned int cmd, #endif extern enum scsi_qc_status ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd); +enum scsi_timeout_action ata_scsi_retry_deferred_qc(struct ata_port *ap, + struct scsi_cmnd *scmd); +enum scsi_timeout_action ata_scsi_eh_timed_out(struct scsi_cmnd *cmd); #if IS_REACHABLE(CONFIG_ATA) bool ata_scsi_dma_need_drain(struct request *rq); #else @@ -1418,9 +1431,6 @@ extern int ata_port_freeze(struct ata_port *ap); extern void ata_eh_freeze_port(struct ata_port *ap); 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) __must_hold(&ap->host->eh_mutex); extern void ata_std_sched_eh(struct ata_port *ap); @@ -1464,6 +1474,7 @@ extern const struct attribute_group *ata_common_sdev_groups[]; .ioctl = ata_scsi_ioctl, \ ATA_SCSI_COMPAT_IOCTL \ .queuecommand = ata_scsi_queuecmd, \ + .eh_timed_out = ata_scsi_eh_timed_out, \ .dma_need_drain = ata_scsi_dma_need_drain, \ .this_id = ATA_SHT_THIS_ID, \ .emulated = ATA_SHT_EMULATED, \ diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 28f086c4a187..d929d83abf3b 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -126,6 +126,15 @@ struct nd_mapping_desc { struct bio; struct resource; struct nd_region; + +/* + * Provider flush callback return values: + * 0: flush completed synchronously + * <0: flush failed + * >0: flush completion was queued and @bio will be completed later + */ +#define NVDIMM_FLUSH_ASYNC 1 + struct nd_region_desc { struct resource *res; struct nd_mapping_desc *mapping; diff --git a/include/linux/list.h b/include/linux/list.h index 09d979976b3b..77fb62f79928 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -34,6 +34,14 @@ struct list_head name = LIST_HEAD_INIT(name) /** + * LIST_HEAD_GUARDED - define a &struct list_head annotated with __guarded_by() + * @name: name of the list_head + * @lock: lock protecting the list + */ +#define LIST_HEAD_GUARDED(name, lock) \ + __guarded_by(&(lock)) LIST_HEAD(name) + +/** * INIT_LIST_HEAD - Initialize a list_head structure * @list: list_head structure to be initialized. * @@ -150,10 +158,13 @@ static inline bool __list_del_entry_valid(struct list_head *entry) * * This is only for internal list manipulation where we know * the prev/next entries already! + * + * Must be inlined to ensure it can be safely called + * with initdata arguments. */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) +static __always_inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) { if (!__list_add_valid(new, prev, next)) return; @@ -171,8 +182,12 @@ static inline void __list_add(struct list_head *new, * * Insert a new entry after the specified head. * This is good for implementing stacks. + * + * Must be inlined to ensure it can be safely called + * with initdata arguments. */ -static inline void list_add(struct list_head *new, struct list_head *head) +static __always_inline void list_add(struct list_head *new, + struct list_head *head) { __list_add(new, head, head->next); } @@ -436,6 +451,7 @@ static inline void list_del_init_careful(struct list_head *entry) * if another CPU could re-list_add() it. */ static inline int list_empty_careful(const struct list_head *head) + __context_unsafe(/* intentional lockless access to @head */) { struct list_head *next = smp_load_acquire(&head->next); return list_is_head(next, head) && (next == READ_ONCE(head->prev)); diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index 88722e5caf02..63ea5417de84 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -173,7 +173,9 @@ struct liveupdate_flb_ops { * @lock: A mutex that protects all fields within this structure, providing * the synchronization service for the FLB's ops. * @finished: True once the FLB's finish() callback has run. - * @retrieved: True once the FLB's retrieve() callback has run. + * @retrieve_status: Status code indicating whether retrieve() has been + * attempted. 0 means not attempted, 1 means successful, + * and negative value means it failed with that error code. */ struct luo_flb_private_state { refcount_t count; @@ -181,7 +183,7 @@ struct luo_flb_private_state { void *obj; struct mutex lock; bool finished; - bool retrieved; + int retrieve_status; }; /* @@ -243,6 +245,7 @@ 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); +void liveupdate_flb_put_outgoing(struct liveupdate_flb *flb); #else /* CONFIG_LIVEUPDATE */ @@ -292,5 +295,9 @@ static inline int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, return -EOPNOTSUPP; } +static inline void liveupdate_flb_put_outgoing(struct liveupdate_flb *flb) +{ +} + #endif /* CONFIG_LIVEUPDATE */ #endif /* _LINUX_LIVEUPDATE_H */ diff --git a/include/linux/llist.h b/include/linux/llist.h index 8846b7709669..413249764f7b 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h @@ -66,7 +66,7 @@ struct llist_node { /** * init_llist_head - initialize lock-less list head - * @head: the head for your lock-less list + * @list: the head for your lock-less list */ static inline void init_llist_head(struct llist_head *list) { diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h index b614e0deea72..db8207d4059f 100644 --- a/include/linux/lockd/bind.h +++ b/include/linux/lockd/bind.h @@ -16,17 +16,23 @@ struct svc_rqst; struct rpc_task; struct rpc_clnt; struct super_block; +struct module; -/* - * This is the set of functions for lockd->nfsd communication +/** + * struct nlmsvc_binding - lockd -> nfsd callback table + * @owner: module that provides this binding. + * @fopen: open a file by NFS file handle on behalf of an NLM request. + * @fclose: close a file that was previously opened via @fopen. + * Implementations MUST be semantically equivalent to fput(). */ struct nlmsvc_binding { + struct module *owner; int (*fopen)(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp, int flags); void (*fclose)(struct file *filp); }; -extern const struct nlmsvc_binding *nlmsvc_ops; +extern const struct nlmsvc_binding __rcu *nlmsvc_ops; /* * Similar to nfs_client_initdata, but without the NFS-specific diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 621566345406..a6451ecbbe9a 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -273,6 +273,9 @@ extern struct pin_cookie lock_pin_lock(struct lockdep_map *lock); extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie); extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); +extern u32 lock_sequence(struct lockdep_map *lock); +#define lockdep_sequence(lock) lock_sequence(&(lock)->dep_map) + #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) #define lockdep_assert(cond) \ diff --git a/include/linux/lockdep_types.h b/include/linux/lockdep_types.h index eae115a26488..55c4b152fedf 100644 --- a/include/linux/lockdep_types.h +++ b/include/linux/lockdep_types.h @@ -253,7 +253,8 @@ struct held_lock { unsigned int hardirqs_off:1; unsigned int sync:1; unsigned int references:11; /* 32 bits */ - unsigned int pin_count; + unsigned int pin_count:24; + unsigned int seq_count:8; }; #else /* !CONFIG_LOCKDEP */ diff --git a/include/linux/lockref.h b/include/linux/lockref.h index 6ded24cdb4a8..ddfb7d3b8cec 100644 --- a/include/linux/lockref.h +++ b/include/linux/lockref.h @@ -34,6 +34,8 @@ struct lockref { }; }; +#define __LOCKREF_DEAD_VAL -128 + /** * lockref_init - Initialize a lockref * @lockref: pointer to lockref structure @@ -55,9 +57,15 @@ void lockref_mark_dead(struct lockref *lockref); bool lockref_get_not_dead(struct lockref *lockref); /* Must be called under spinlock for reliable results */ -static inline bool __lockref_is_dead(const struct lockref *l) +static inline bool lockref_is_dead(const struct lockref *l) +{ + return (READ_ONCE(l->count) == __LOCKREF_DEAD_VAL); +} + +static inline bool lockref_is_dead_or_zero(const struct lockref *l) { - return ((int)l->count < 0); + int count = READ_ONCE(l->count); + return (count == __LOCKREF_DEAD_VAL || count == 0); } #endif /* __LINUX_LOCKREF_H */ diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index b4f8cad53ddb..c4488c4a6d8a 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -167,6 +167,7 @@ enum lsm_order { * @initcall_fs: LSM callback for fs_initcall setup, optional * @initcall_device: LSM callback for device_initcall() setup, optional * @initcall_late: LSM callback for late_initcall() setup, optional + * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional */ struct lsm_info { const struct lsm_id *id; @@ -182,6 +183,7 @@ struct lsm_info { int (*initcall_fs)(void); int (*initcall_device)(void); int (*initcall_late)(void); + int (*initcall_late_sync)(void); }; #define DEFINE_LSM(lsm) \ diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h index 4a5631906aff..e595ae5cd0ee 100644 --- a/include/linux/maple_tree.h +++ b/include/linux/maple_tree.h @@ -11,7 +11,6 @@ #include <linux/kernel.h> #include <linux/rcupdate.h> #include <linux/spinlock.h> -/* #define CONFIG_MAPLE_RCU_DISABLED */ /* * Allocated nodes are mutable until they have been inserted into the tree, @@ -29,13 +28,11 @@ #define MAPLE_NODE_SLOTS 31 /* 256 bytes including ->parent */ #define MAPLE_RANGE64_SLOTS 16 /* 256 bytes */ #define MAPLE_ARANGE64_SLOTS 10 /* 240 bytes */ -#define MAPLE_ALLOC_SLOTS (MAPLE_NODE_SLOTS - 1) #else /* 32bit sizes */ #define MAPLE_NODE_SLOTS 63 /* 256 bytes including ->parent */ #define MAPLE_RANGE64_SLOTS 32 /* 256 bytes */ #define MAPLE_ARANGE64_SLOTS 21 /* 240 bytes */ -#define MAPLE_ALLOC_SLOTS (MAPLE_NODE_SLOTS - 2) #endif /* defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64) */ #define MAPLE_NODE_MASK 255UL @@ -485,6 +482,12 @@ struct ma_state { unsigned char mas_flags; unsigned char end; /* The end of the node */ enum store_type store_type; /* The type of store needed for this operation */ +#ifdef CONFIG_LOCKDEP + u32 ld_seq; +#ifdef CONFIG_RCU_STRICT_GRACE_PERIOD + unsigned long rcu_gp; +#endif /* CONFIG_RCU_STRICT_GRACE_PERIOD */ +#endif /* CONFIG_LOCKDEP */ }; struct ma_wr_state { @@ -567,12 +570,14 @@ int mas_alloc_cyclic(struct ma_state *mas, unsigned long *startp, unsigned long *next, gfp_t gfp); bool mas_nomem(struct ma_state *mas, gfp_t gfp); +bool mas_nomem_nofail(struct ma_state *mas, unsigned long index, + unsigned long last); void mas_pause(struct ma_state *mas); void maple_tree_init(void); void mas_destroy(struct ma_state *mas); void *mas_prev(struct ma_state *mas, unsigned long min); -void *mas_prev_range(struct ma_state *mas, unsigned long max); +void *mas_prev_range(struct ma_state *mas, unsigned long min); void *mas_next(struct ma_state *mas, unsigned long max); void *mas_next_range(struct ma_state *mas, unsigned long max); @@ -864,9 +869,6 @@ static inline void mt_init(struct maple_tree *mt) static inline bool mt_in_rcu(struct maple_tree *mt) { -#ifdef CONFIG_MAPLE_RCU_DISABLED - return false; -#endif return mt->ma_flags & MT_FLAGS_USE_RCU; } diff --git a/include/linux/math64.h b/include/linux/math64.h index cc305206d89f..99189410d4bb 100644 --- a/include/linux/math64.h +++ b/include/linux/math64.h @@ -58,6 +58,20 @@ static inline u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) } /** + * div64_s64_rem - signed 64bit divide with 64bit divisor and remainder + * @dividend: signed 64bit dividend + * @divisor: signed 64bit divisor + * @remainder: pointer to signed 64bit remainder + * + * Return: sets ``*remainder``, then returns dividend / divisor + */ +static inline s64 div64_s64_rem(s64 dividend, s64 divisor, s64 *remainder) +{ + *remainder = dividend % divisor; + return dividend / divisor; +} + +/** * div64_u64 - unsigned 64bit divide with 64bit divisor * @dividend: unsigned 64bit dividend * @divisor: unsigned 64bit divisor @@ -102,6 +116,10 @@ extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder); extern u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder); #endif +#ifndef div64_s64_rem +extern s64 div64_s64_rem(s64 dividend, s64 divisor, s64 *remainder); +#endif + #ifndef div64_u64 extern u64 div64_u64(u64 dividend, u64 divisor); #endif diff --git a/include/linux/mcb.h b/include/linux/mcb.h index 4ab2691f51a6..874118765d0f 100644 --- a/include/linux/mcb.h +++ b/include/linux/mcb.h @@ -8,7 +8,7 @@ #ifndef _LINUX_MCB_H #define _LINUX_MCB_H -#include <linux/mod_devicetable.h> +#include <linux/device-id/mcb.h> #include <linux/device.h> #include <linux/irqreturn.h> diff --git a/include/linux/mdio.h b/include/linux/mdio.h index f4f9d9609448..a7d9e3ae362a 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -8,7 +8,6 @@ #include <uapi/linux/mdio.h> #include <linux/bitfield.h> -#include <linux/mod_devicetable.h> struct gpio_desc; struct mii_bus; @@ -87,6 +86,11 @@ static inline void *mdiodev_get_drvdata(struct mdio_device *mdio) return dev_get_drvdata(&mdio->dev); } +static inline bool mdiodev_has_reset(struct mdio_device *mdio) +{ + return (mdio->reset_gpio || mdio->reset_ctrl); +} + void mdio_device_free(struct mdio_device *mdiodev); struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr); int mdio_device_register(struct mdio_device *mdiodev); diff --git a/include/linux/mei_cl_bus.h b/include/linux/mei_cl_bus.h index 5bdbd9e1d460..d5d29451eabf 100644 --- a/include/linux/mei_cl_bus.h +++ b/include/linux/mei_cl_bus.h @@ -7,7 +7,7 @@ #include <linux/device.h> #include <linux/uuid.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/mei_cl.h> struct mei_cl_device; struct mei_device; diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 5afcd99aa8c1..d62db9e776cf 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -51,6 +51,7 @@ extern unsigned long long max_possible_pfn; * memory reservations yet, so we get scratch memory from the previous * kernel that we know is good to use. It is the only memory that * allocations may happen from in this phase. + * @MEMBLOCK_RSRV_HUGETLB: memory is reserved for hugetlb pages */ enum memblock_flags { MEMBLOCK_NONE = 0x0, /* No special request */ @@ -61,6 +62,7 @@ enum memblock_flags { MEMBLOCK_RSRV_NOINIT = 0x10, /* don't initialize struct pages */ MEMBLOCK_RSRV_KERN = 0x20, /* memory reserved for kernel use */ MEMBLOCK_KHO_SCRATCH = 0x40, /* scratch memory for kexec handover */ + MEMBLOCK_RSRV_HUGETLB = 0x80, /* memory reserved for hugetlb pages */ }; /** @@ -420,6 +422,7 @@ void *memblock_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align, void *memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid); +void *memblock_alloc_hugetlb(phys_addr_t size, int nid, bool exact_nid); static __always_inline void *memblock_alloc(phys_addr_t size, phys_addr_t align) { @@ -484,6 +487,7 @@ static inline __init_memblock bool memblock_bottom_up(void) phys_addr_t memblock_phys_mem_size(void); phys_addr_t memblock_reserved_size(void); phys_addr_t memblock_reserved_kern_size(phys_addr_t limit, int nid); +phys_addr_t memblock_reserved_hugetlb_size(phys_addr_t limit, int nid); unsigned long memblock_estimated_nr_free_pages(void); phys_addr_t memblock_start_of_DRAM(void); phys_addr_t memblock_end_of_DRAM(void); @@ -613,28 +617,9 @@ 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); -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 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 e1f46a0016fc..7d1c0ce189a8 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -239,8 +239,6 @@ struct mem_cgroup { */ bool oom_group; - int swappiness; - /* memory.events and memory.events.local */ struct cgroup_file events_file; struct cgroup_file events_local_file; @@ -270,10 +268,15 @@ struct mem_cgroup { #endif int kmemcg_id; - struct memcg_vmstats_percpu __percpu *vmstats_percpu; - #ifdef CONFIG_CGROUP_WRITEBACK struct list_head cgwb_list; +#endif + + /* Keep the hot per-CPU stats pointer away from memory event counters. */ + struct memcg_vmstats_percpu __percpu *vmstats_percpu + ____cacheline_aligned_in_smp; + +#ifdef CONFIG_CGROUP_WRITEBACK struct wb_domain cgwb_domain; struct memcg_cgwb_frn cgwb_frn[MEMCG_CGWB_FRN_CNT]; #endif @@ -318,6 +321,8 @@ struct mem_cgroup { /* List of events which userspace want to receive */ struct list_head event_list; spinlock_t event_list_lock; + + int swappiness; #endif /* CONFIG_MEMCG_V1 */ struct mem_cgroup_per_node *nodeinfo[]; @@ -520,6 +525,22 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg) return (memcg == root_mem_cgroup); } +/** + * mem_cgroup_shrink_is_root - is this a global or root-memcg shrink invocation? + * @sc: shrink_control describing the current shrinker call + * + * Returns true when @sc represents a global reclaim shrink (sc->memcg == NULL) + * or a root-memcg shrink, i.e. not a per-memcg iteration of + * shrink_slab_memcg(). Filesystems whose ->nr_cached_objects()/ + * ->free_cached_objects() implementations operate on filesystem-global state + * and do not honour sc->memcg can use this to early-return 0 in per-memcg + * contexts. + */ +static inline bool mem_cgroup_shrink_is_root(struct shrink_control *sc) +{ + return !sc->memcg || mem_cgroup_is_root(sc->memcg); +} + static inline bool obj_cgroup_is_root(const struct obj_cgroup *objcg) { return objcg->is_root; @@ -931,6 +952,8 @@ unsigned long memcg_page_state_output(struct mem_cgroup *memcg, int item); bool memcg_stat_item_valid(int idx); bool memcg_vm_event_item_valid(enum vm_event_item idx); unsigned long lruvec_page_state(struct lruvec *lruvec, enum node_stat_item idx); +unsigned long lruvec_page_state_monotonic(struct lruvec *lruvec, + enum node_stat_item idx); unsigned long lruvec_page_state_local(struct lruvec *lruvec, enum node_stat_item idx); @@ -1071,6 +1094,11 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg) return true; } +static inline bool mem_cgroup_shrink_is_root(struct shrink_control *sc) +{ + return true; +} + static inline bool obj_cgroup_is_root(const struct obj_cgroup *objcg) { return true; @@ -1378,6 +1406,12 @@ static inline unsigned long lruvec_page_state(struct lruvec *lruvec, return node_page_state(lruvec_pgdat(lruvec), idx); } +static inline unsigned long lruvec_page_state_monotonic(struct lruvec *lruvec, + enum node_stat_item idx) +{ + return node_page_state_monotonic(lruvec_pgdat(lruvec), idx); +} + static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec, enum node_stat_item idx) { @@ -1440,19 +1474,6 @@ static inline void mem_cgroup_flush_workqueue(void) { } static inline int mem_cgroup_init(void) { return 0; } #endif /* CONFIG_MEMCG */ -/* - * Extended information for slab objects stored as an array in page->memcg_data - * if MEMCG_DATA_OBJEXTS is set. - */ -struct slabobj_ext { -#ifdef CONFIG_MEMCG - struct obj_cgroup *objcg; -#endif -#ifdef CONFIG_MEM_ALLOC_PROFILING - union codetag_ref ref; -#endif -} __aligned(8); - static inline struct lruvec *parent_lruvec(struct lruvec *lruvec) { struct mem_cgroup *memcg; @@ -1472,6 +1493,31 @@ static inline void lruvec_lock_irq(struct lruvec *lruvec) spin_lock_irq(&lruvec->lru_lock); } +static inline struct lruvec *lruvec_live_lock_irq(struct lruvec *lruvec) +{ +#ifdef CONFIG_MEMCG + struct pglist_data *pgdat = lruvec_pgdat(lruvec); + struct mem_cgroup *memcg = lruvec_memcg(lruvec); + + rcu_read_lock(); + + /* + * The memcg can be NULL when the memory controller is disabled. + * Otherwise, the caller keeps the memcg owning @lruvec alive. + */ + while (unlikely(memcg && css_is_dying(&memcg->css))) { + memcg = parent_mem_cgroup(memcg); + lruvec = mem_cgroup_lruvec(memcg, pgdat); + } + + spin_lock_irq(&lruvec->lru_lock); +#else + lruvec_lock_irq(lruvec); +#endif + + return lruvec; +} + static inline void lruvec_unlock(struct lruvec *lruvec) { spin_unlock(&lruvec->lru_lock); diff --git a/include/linux/memfd.h b/include/linux/memfd.h index b4fda09dab9f..c159e40e3f34 100644 --- a/include/linux/memfd.h +++ b/include/linux/memfd.h @@ -14,9 +14,9 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx); * to sealing, or 0 otherwise. * * We also update VMA flags if appropriate by manipulating the VMA flags pointed - * to by vm_flags_ptr. + * to by vma_flags_ptr. */ -int memfd_check_seals_mmap(struct file *file, vm_flags_t *vm_flags_ptr); +int memfd_check_seals_mmap(struct file *file, vma_flags_t *vma_flags_ptr); struct file *memfd_alloc_file(const char *name, unsigned int flags); int memfd_get_seals(struct file *file); int memfd_add_seals(struct file *file, unsigned int seals); @@ -30,7 +30,7 @@ static inline struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx) return ERR_PTR(-EINVAL); } static inline int memfd_check_seals_mmap(struct file *file, - vm_flags_t *vm_flags_ptr) + vma_flags_t *vma_flags_ptr) { return 0; } diff --git a/include/linux/memory.h b/include/linux/memory.h index 463dc02f6cff..1783299073e4 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -20,6 +20,7 @@ #include <linux/compiler.h> #include <linux/mutex.h> #include <linux/memory_hotplug.h> +#include <linux/range.h> #define MIN_MEMORY_BLOCK_SIZE (1UL << SECTION_SIZE_BITS) @@ -100,6 +101,32 @@ int arch_get_memory_phys_device(unsigned long start_pfn); unsigned long memory_block_size_bytes(void); int set_memory_block_size_order(unsigned int order); +/** + * memory_block_aligned_range - align a physical address range to memory blocks + * @range: the input range to align + * + * Aligns the start address up and the end address down to memory block + * boundaries. This is required for memory hotplug operations which must + * operate on memory-block aligned ranges. + * + * Returns the aligned range. Callers should check that the returned + * range is valid (aligned.start < aligned.end) before using it. + */ +static inline struct range memory_block_aligned_range(const struct range *range) +{ + struct range aligned; + + aligned.start = ALIGN(range->start, memory_block_size_bytes()); + aligned.end = ALIGN_DOWN(range->end + 1, memory_block_size_bytes()); + /* No whole block fits (e.g. range below the first boundary): empty. */ + if (aligned.end <= aligned.start) + aligned.start = aligned.end; + else + aligned.end -= 1; + + return aligned; +} + struct memory_notify { unsigned long start_pfn; unsigned long nr_pages; diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 7c9d66729c60..b39605d30896 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -127,6 +127,7 @@ extern int arch_add_memory(int nid, u64 start, u64 size, extern u64 max_mem_size; extern int mhp_online_type_from_str(const char *str); +const char *mhp_online_type_to_str(int online_type); /* If movable_node boot option specified */ extern bool movable_node_enabled; @@ -267,6 +268,8 @@ extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages, extern int remove_memory(u64 start, u64 size); extern void __remove_memory(u64 start, u64 size); extern int offline_and_remove_memory(u64 start, u64 size); +int offline_and_remove_memory_ranges(const struct range *ranges, + unsigned int nr_ranges); #else static inline void try_offline_node(int nid) {} @@ -283,17 +286,26 @@ static inline int remove_memory(u64 start, u64 size) } static inline void __remove_memory(u64 start, u64 size) {} + +static inline int offline_and_remove_memory_ranges(const struct range *ranges, + unsigned int nr_ranges) +{ + return -EBUSY; +} #endif /* CONFIG_MEMORY_HOTREMOVE */ #ifdef CONFIG_MEMORY_HOTPLUG /* Default online_type (MMOP_*) when new memory blocks are added. */ extern enum mmop mhp_get_default_online_type(void); extern void mhp_set_default_online_type(enum mmop online_type); -extern void __ref free_area_init_core_hotplug(struct pglist_data *pgdat); +int __ref free_area_init_core_hotplug(struct pglist_data *pgdat); extern int __add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags); extern int add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags); extern int add_memory_resource(int nid, struct resource *resource, mhp_t mhp_flags); +int __add_memory_driver_managed(int nid, u64 start, u64 size, + const char *resource_name, mhp_t mhp_flags, + enum mmop online_type); extern int add_memory_driver_managed(int nid, u64 start, u64 size, const char *resource_name, mhp_t mhp_flags); @@ -316,6 +328,8 @@ extern struct zone *zone_for_pfn_range(enum mmop online_type, extern int arch_create_linear_mapping(int nid, u64 start, u64 size, struct mhp_params *params); void arch_remove_linear_mapping(u64 start, u64 size); +#else +static inline enum mmop mhp_get_default_online_type(void) { return MMOP_OFFLINE; } #endif /* CONFIG_MEMORY_HOTPLUG */ #endif /* __LINUX_MEMORY_HOTPLUG_H */ diff --git a/include/linux/mfd/88pm886.h b/include/linux/mfd/88pm886.h index 38892ba7b8a4..2c24dd3032ab 100644 --- a/include/linux/mfd/88pm886.h +++ b/include/linux/mfd/88pm886.h @@ -11,6 +11,7 @@ #define PM886_PAGE_OFFSET_REGULATORS 1 #define PM886_PAGE_OFFSET_GPADC 2 +#define PM886_PAGE_OFFSET_BATTERY 3 #define PM886_REG_ID 0x00 @@ -128,9 +129,13 @@ #define PM886_GPADC_BIAS_LEVELS 16 #define PM886_GPADC_INDEX_TO_BIAS_uA(i) (1 + (i) * 5) +/* Battery block register definitions */ +#define PM886_REG_CLS_CONFIG1 0x71 + struct pm886_chip { struct i2c_client *client; unsigned int chip_id; struct regmap *regmap; + struct regmap *regmap_battery; }; #endif /* __MFD_88PM886_H */ diff --git a/include/linux/mfd/bq257xx.h b/include/linux/mfd/bq257xx.h index 4ec72eb920f2..379ef4ee8291 100644 --- a/include/linux/mfd/bq257xx.h +++ b/include/linux/mfd/bq257xx.h @@ -200,6 +200,20 @@ #define BQ25792_REG0A_TRECHG_MASK GENMASK(5, 4) #define BQ25792_REG0A_VRECHG_MASK GENMASK(3, 0) +#define BQ25792_CELL_1S 0 +#define BQ25792_CELL_2S 1 +#define BQ25792_CELL_3S 2 +#define BQ25792_CELL_4S 3 + +#define BQ25792_TRECHG_64MS 0 +#define BQ25792_TRECHG_256MS 1 +#define BQ25792_TRECHG_1024MS 2 +#define BQ25792_TRECHG_2048MS 3 + +#define BQ25792_VRECHG_MIN_UV 50000 +#define BQ25792_VRECHG_STEP_UV 50000 +#define BQ25792_VRECHG_MAX_UV 800000 + /* VOTG regulation */ #define BQ25792_REG0B_VOTG_MASK GENMASK(10, 0) diff --git a/include/linux/mfd/cs42l43.h b/include/linux/mfd/cs42l43.h index ff0f7e365a19..8e993fb535e6 100644 --- a/include/linux/mfd/cs42l43.h +++ b/include/linux/mfd/cs42l43.h @@ -86,7 +86,6 @@ struct cs42l43 { struct regmap_irq_chip_data *irq_data; struct work_struct boot_work; - struct completion device_attach; struct completion device_detach; struct completion firmware_download; int firmware_error; @@ -96,7 +95,6 @@ struct cs42l43 { struct mutex pll_lock; bool sdw_pll_active; - bool attached; bool hw_lock; long variant_id; }; diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index a62de3d155ed..c939c9a1170a 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h @@ -12,6 +12,9 @@ #include <linux/interrupt.h> #include <linux/bitops.h> +#include <linux/err.h> + +#include <dt-bindings/mfd/dbx500-prcmu.h> /* For clock identifiers */ /* * Registers @@ -24,6 +27,38 @@ #define DB8500_PRCM_DSI_SW_RESET_DSI1_SW_RESETN BIT(1) #define DB8500_PRCM_DSI_SW_RESET_DSI2_SW_RESETN BIT(2) +/* Offset for the firmware version within the TCPM */ +#define DB8500_PRCMU_FW_VERSION_OFFSET 0xA4 + +#define DB8500_PRCMU_LEGACY_OFFSET 0xDD4 + +/* + * CLKOUT sources + */ +#define PRCMU_CLKSRC_CLK38M 0x00 +#define PRCMU_CLKSRC_ACLK 0x01 +#define PRCMU_CLKSRC_SYSCLK 0x02 +#define PRCMU_CLKSRC_LCDCLK 0x03 +#define PRCMU_CLKSRC_SDMMCCLK 0x04 +#define PRCMU_CLKSRC_TVCLK 0x05 +#define PRCMU_CLKSRC_TIMCLK 0x06 +#define PRCMU_CLKSRC_CLK009 0x07 +/* These are only valid for CLKOUT1: */ +#define PRCMU_CLKSRC_SIAMMDSPCLK 0x40 +#define PRCMU_CLKSRC_I2CCLK 0x41 +#define PRCMU_CLKSRC_MSP02CLK 0x42 +#define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43 +#define PRCMU_CLKSRC_HSIRXCLK 0x44 +#define PRCMU_CLKSRC_HSITXCLK 0x45 +#define PRCMU_CLKSRC_ARMCLKFIX 0x46 +#define PRCMU_CLKSRC_HDMICLK 0x47 + +/* + * Definitions for controlling ESRAM0 in deep sleep. + */ +#define ESRAM0_DEEP_SLEEP_STATE_OFF 1 +#define ESRAM0_DEEP_SLEEP_STATE_RET 2 + /* This portion previously known as <mach/prcmu-fw-defs_v1.h> */ /** @@ -451,10 +486,173 @@ enum prcmu_power_status { PRCMU_ARMPENDINGIT_ER = 0x93, }; +/* PRCMU Wakeup defines */ +enum prcmu_wakeup_index { + PRCMU_WAKEUP_INDEX_RTC, + PRCMU_WAKEUP_INDEX_RTT0, + PRCMU_WAKEUP_INDEX_RTT1, + PRCMU_WAKEUP_INDEX_HSI0, + PRCMU_WAKEUP_INDEX_HSI1, + PRCMU_WAKEUP_INDEX_USB, + PRCMU_WAKEUP_INDEX_ABB, + PRCMU_WAKEUP_INDEX_ABB_FIFO, + PRCMU_WAKEUP_INDEX_ARM, + PRCMU_WAKEUP_INDEX_CD_IRQ, + NUM_PRCMU_WAKEUP_INDICES +}; + +#define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name)) + +/** + * enum prcmu_wdog_id - PRCMU watchdog IDs + * @PRCMU_WDOG_ALL: use all timers + * @PRCMU_WDOG_CPU1: use first CPU timer only + * @PRCMU_WDOG_CPU2: use second CPU timer conly + */ +enum prcmu_wdog_id { + PRCMU_WDOG_ALL = 0x00, + PRCMU_WDOG_CPU1 = 0x01, + PRCMU_WDOG_CPU2 = 0x02, +}; + +/** + * enum ape_opp - APE OPP states definition + * @APE_OPP_INIT: + * @APE_NO_CHANGE: The APE operating point is unchanged + * @APE_100_OPP: The new APE operating point is ape100opp + * @APE_50_OPP: 50% + * @APE_50_PARTLY_25_OPP: 50%, except some clocks at 25%. + */ +enum ape_opp { + APE_OPP_INIT = 0x00, + APE_NO_CHANGE = 0x01, + APE_100_OPP = 0x02, + APE_50_OPP = 0x03, + APE_50_PARTLY_25_OPP = 0xFF, +}; + +/** + * enum arm_opp - ARM OPP states definition + * @ARM_OPP_INIT: + * @ARM_NO_CHANGE: The ARM operating point is unchanged + * @ARM_100_OPP: The new ARM operating point is arm100opp + * @ARM_50_OPP: The new ARM operating point is arm50opp + * @ARM_MAX_OPP: Operating point is "max" (more than 100) + * @ARM_MAX_FREQ100OPP: Set max opp if available, else 100 + * @ARM_EXTCLK: The new ARM operating point is armExtClk + */ +enum arm_opp { + ARM_OPP_INIT = 0x00, + ARM_NO_CHANGE = 0x01, + ARM_100_OPP = 0x02, + ARM_50_OPP = 0x03, + ARM_MAX_OPP = 0x04, + ARM_MAX_FREQ100OPP = 0x05, + ARM_EXTCLK = 0x07 +}; + +/** + * enum ddr_opp - DDR OPP states definition + * @DDR_100_OPP: The new DDR operating point is ddr100opp + * @DDR_50_OPP: The new DDR operating point is ddr50opp + * @DDR_25_OPP: The new DDR operating point is ddr25opp + */ +enum ddr_opp { + DDR_100_OPP = 0x00, + DDR_50_OPP = 0x01, + DDR_25_OPP = 0x02, +}; + +/** + * enum ddr_pwrst - DDR power states definition + * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged + * @DDR_PWR_STATE_ON: + * @DDR_PWR_STATE_OFFLOWLAT: + * @DDR_PWR_STATE_OFFHIGHLAT: + */ +enum ddr_pwrst { + DDR_PWR_STATE_UNCHANGED = 0x00, + DDR_PWR_STATE_ON = 0x01, + DDR_PWR_STATE_OFFLOWLAT = 0x02, + DDR_PWR_STATE_OFFHIGHLAT = 0x03 +}; + /* * Definitions for autonomous power management configuration. */ +/* EPOD (power domain) IDs */ + +/* + * DB8500 EPODs + * - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP + * - EPOD_ID_SVAPIPE: power domain for SVA pipe + * - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP + * - EPOD_ID_SIAPIPE: power domain for SIA pipe + * - EPOD_ID_SGA: power domain for SGA + * - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE + * - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2 + * - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4 + * - NUM_EPOD_ID: number of power domains + * + * TODO: These should be prefixed. + */ +#define EPOD_ID_SVAMMDSP 0 +#define EPOD_ID_SVAPIPE 1 +#define EPOD_ID_SIAMMDSP 2 +#define EPOD_ID_SIAPIPE 3 +#define EPOD_ID_SGA 4 +#define EPOD_ID_B2R2_MCDE 5 +#define EPOD_ID_ESRAM12 6 +#define EPOD_ID_ESRAM34 7 +#define NUM_EPOD_ID 8 + +/* + * state definition for EPOD (power domain) + * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged + * - EPOD_STATE_OFF: The EPOD is switched off + * - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in + * retention + * - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off + * - EPOD_STATE_ON: Same as above, but with clock enabled + */ +#define EPOD_STATE_NO_CHANGE 0x00 +#define EPOD_STATE_OFF 0x01 +#define EPOD_STATE_RAMRET 0x02 +#define EPOD_STATE_ON_CLK_OFF 0x03 +#define EPOD_STATE_ON 0x04 + +#define PRCMU_FW_PROJECT_U8500 2 +#define PRCMU_FW_PROJECT_U8400 3 +#define PRCMU_FW_PROJECT_U9500 4 /* Customer specific */ +#define PRCMU_FW_PROJECT_U8500_MBB 5 +#define PRCMU_FW_PROJECT_U8500_C1 6 +#define PRCMU_FW_PROJECT_U8500_C2 7 +#define PRCMU_FW_PROJECT_U8500_C3 8 +#define PRCMU_FW_PROJECT_U8500_C4 9 +#define PRCMU_FW_PROJECT_U9500_MBL 10 +#define PRCMU_FW_PROJECT_U8500_SSG1 11 /* Samsung specific */ +#define PRCMU_FW_PROJECT_U8500_MBL2 12 /* Customer specific */ +#define PRCMU_FW_PROJECT_U8520 13 +#define PRCMU_FW_PROJECT_U8420 14 +#define PRCMU_FW_PROJECT_U8500_SSG2 15 /* Samsung specific */ +#define PRCMU_FW_PROJECT_U8420_SYSCLK 17 +#define PRCMU_FW_PROJECT_A9420 20 +/* [32..63] 9540 and derivatives */ +#define PRCMU_FW_PROJECT_U9540 32 +/* [64..95] 8540 and derivatives */ +#define PRCMU_FW_PROJECT_L8540 64 +/* [96..126] 8580 and derivatives */ +#define PRCMU_FW_PROJECT_L8580 96 + +#define PRCMU_FW_PROJECT_NAME_LEN 20 + +/* PRCMU QoS APE OPP class */ +#define PRCMU_QOS_APE_OPP 1 +#define PRCMU_QOS_DDR_OPP 2 +#define PRCMU_QOS_ARM_OPP 3 +#define PRCMU_QOS_DEFAULT_VALUE -1 + #define PRCMU_AUTO_PM_OFF 0 #define PRCMU_AUTO_PM_ON 1 @@ -469,6 +667,14 @@ enum prcmu_auto_pm_policy { PRCMU_AUTO_PM_POLICY_DSP_CLK_OFF_HWP_CLK_OFF, }; +struct prcmu_fw_version { + u32 project; /* Notice, project shifted with 8 on ux540 */ + u8 api_version; + u8 func_version; + u8 errata; + char project_name[PRCMU_FW_PROJECT_NAME_LEN]; +}; + /** * struct prcmu_auto_pm_config - Autonomous power management configuration. * @sia_auto_pm_enable: SIA autonomous pm enable. (PRCMU_AUTO_PM_{OFF,ON}) @@ -501,6 +707,9 @@ void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, bool prcmu_is_auto_pm_enabled(void); int prcmu_config_clkout(u8 clkout, u8 source, u8 div); +unsigned long prcmu_clock_rate(u8 clock); +long prcmu_round_clock_rate(u8 clock, unsigned long rate); +int prcmu_set_clock_rate(u8 clock, unsigned long rate); int prcmu_set_clock_divider(u8 clock, u8 divider); int db8500_prcmu_config_hotdog(u8 threshold); int db8500_prcmu_config_hotmon(u8 low, u8 high); @@ -508,6 +717,8 @@ int db8500_prcmu_start_temp_sense(u16 cycles32k); int db8500_prcmu_stop_temp_sense(void); int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); +int prcmu_abb_write_masked(u8 slave, u8 reg, u8 *value, + u8 *mask, u8 size); int prcmu_ac_wake_req(void); void prcmu_ac_sleep_req(void); @@ -610,6 +821,21 @@ static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div) return 0; } +static inline unsigned long prcmu_clock_rate(u8 clock) +{ + return 0; +} + +static inline long prcmu_round_clock_rate(u8 clock, unsigned long rate) +{ + return 0; +} + +static inline int prcmu_set_clock_rate(u8 clock, unsigned long rate) +{ + return 0; +} + static inline int prcmu_set_clock_divider(u8 clock, u8 divider) { return 0; @@ -637,12 +863,18 @@ static inline int db8500_prcmu_stop_temp_sense(void) static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) { - return -ENOSYS; + return -EINVAL; } static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) { - return -ENOSYS; + return -EINVAL; +} + +static inline int prcmu_abb_write_masked(u8 slave, u8 reg, + u8 *value, u8 *mask, u8 size) +{ + return -EINVAL; } static inline int prcmu_ac_wake_req(void) @@ -745,4 +977,20 @@ static inline void db8500_prcmu_write_masked(unsigned int reg, u32 mask, #endif /* !CONFIG_MFD_DB8500_PRCMU */ +static inline int prcmu_qos_add_requirement(int prcmu_qos_class, + char *name, s32 value) +{ + return 0; +} + +static inline int prcmu_qos_update_requirement(int prcmu_qos_class, + char *name, s32 new_value) +{ + return 0; +} + +static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name) +{ +} + #endif /* __MFD_DB8500_PRCMU_H */ diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h deleted file mode 100644 index 828362b7860c..000000000000 --- a/include/linux/mfd/dbx500-prcmu.h +++ /dev/null @@ -1,575 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) ST Ericsson SA 2011 - * - * STE Ux500 PRCMU API - */ -#ifndef __MACH_PRCMU_H -#define __MACH_PRCMU_H - -#include <linux/interrupt.h> -#include <linux/notifier.h> -#include <linux/err.h> - -#include <dt-bindings/mfd/dbx500-prcmu.h> /* For clock identifiers */ - -/* Offset for the firmware version within the TCPM */ -#define DB8500_PRCMU_FW_VERSION_OFFSET 0xA4 -#define DBX540_PRCMU_FW_VERSION_OFFSET 0xA8 - -/* PRCMU Wakeup defines */ -enum prcmu_wakeup_index { - PRCMU_WAKEUP_INDEX_RTC, - PRCMU_WAKEUP_INDEX_RTT0, - PRCMU_WAKEUP_INDEX_RTT1, - PRCMU_WAKEUP_INDEX_HSI0, - PRCMU_WAKEUP_INDEX_HSI1, - PRCMU_WAKEUP_INDEX_USB, - PRCMU_WAKEUP_INDEX_ABB, - PRCMU_WAKEUP_INDEX_ABB_FIFO, - PRCMU_WAKEUP_INDEX_ARM, - PRCMU_WAKEUP_INDEX_CD_IRQ, - NUM_PRCMU_WAKEUP_INDICES -}; -#define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name)) - -/* EPOD (power domain) IDs */ - -/* - * DB8500 EPODs - * - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP - * - EPOD_ID_SVAPIPE: power domain for SVA pipe - * - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP - * - EPOD_ID_SIAPIPE: power domain for SIA pipe - * - EPOD_ID_SGA: power domain for SGA - * - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE - * - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2 - * - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4 - * - NUM_EPOD_ID: number of power domains - * - * TODO: These should be prefixed. - */ -#define EPOD_ID_SVAMMDSP 0 -#define EPOD_ID_SVAPIPE 1 -#define EPOD_ID_SIAMMDSP 2 -#define EPOD_ID_SIAPIPE 3 -#define EPOD_ID_SGA 4 -#define EPOD_ID_B2R2_MCDE 5 -#define EPOD_ID_ESRAM12 6 -#define EPOD_ID_ESRAM34 7 -#define NUM_EPOD_ID 8 - -/* - * state definition for EPOD (power domain) - * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged - * - EPOD_STATE_OFF: The EPOD is switched off - * - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in - * retention - * - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off - * - EPOD_STATE_ON: Same as above, but with clock enabled - */ -#define EPOD_STATE_NO_CHANGE 0x00 -#define EPOD_STATE_OFF 0x01 -#define EPOD_STATE_RAMRET 0x02 -#define EPOD_STATE_ON_CLK_OFF 0x03 -#define EPOD_STATE_ON 0x04 - -/* - * CLKOUT sources - */ -#define PRCMU_CLKSRC_CLK38M 0x00 -#define PRCMU_CLKSRC_ACLK 0x01 -#define PRCMU_CLKSRC_SYSCLK 0x02 -#define PRCMU_CLKSRC_LCDCLK 0x03 -#define PRCMU_CLKSRC_SDMMCCLK 0x04 -#define PRCMU_CLKSRC_TVCLK 0x05 -#define PRCMU_CLKSRC_TIMCLK 0x06 -#define PRCMU_CLKSRC_CLK009 0x07 -/* These are only valid for CLKOUT1: */ -#define PRCMU_CLKSRC_SIAMMDSPCLK 0x40 -#define PRCMU_CLKSRC_I2CCLK 0x41 -#define PRCMU_CLKSRC_MSP02CLK 0x42 -#define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43 -#define PRCMU_CLKSRC_HSIRXCLK 0x44 -#define PRCMU_CLKSRC_HSITXCLK 0x45 -#define PRCMU_CLKSRC_ARMCLKFIX 0x46 -#define PRCMU_CLKSRC_HDMICLK 0x47 - -/** - * enum prcmu_wdog_id - PRCMU watchdog IDs - * @PRCMU_WDOG_ALL: use all timers - * @PRCMU_WDOG_CPU1: use first CPU timer only - * @PRCMU_WDOG_CPU2: use second CPU timer conly - */ -enum prcmu_wdog_id { - PRCMU_WDOG_ALL = 0x00, - PRCMU_WDOG_CPU1 = 0x01, - PRCMU_WDOG_CPU2 = 0x02, -}; - -/** - * enum ape_opp - APE OPP states definition - * @APE_OPP_INIT: - * @APE_NO_CHANGE: The APE operating point is unchanged - * @APE_100_OPP: The new APE operating point is ape100opp - * @APE_50_OPP: 50% - * @APE_50_PARTLY_25_OPP: 50%, except some clocks at 25%. - */ -enum ape_opp { - APE_OPP_INIT = 0x00, - APE_NO_CHANGE = 0x01, - APE_100_OPP = 0x02, - APE_50_OPP = 0x03, - APE_50_PARTLY_25_OPP = 0xFF, -}; - -/** - * enum arm_opp - ARM OPP states definition - * @ARM_OPP_INIT: - * @ARM_NO_CHANGE: The ARM operating point is unchanged - * @ARM_100_OPP: The new ARM operating point is arm100opp - * @ARM_50_OPP: The new ARM operating point is arm50opp - * @ARM_MAX_OPP: Operating point is "max" (more than 100) - * @ARM_MAX_FREQ100OPP: Set max opp if available, else 100 - * @ARM_EXTCLK: The new ARM operating point is armExtClk - */ -enum arm_opp { - ARM_OPP_INIT = 0x00, - ARM_NO_CHANGE = 0x01, - ARM_100_OPP = 0x02, - ARM_50_OPP = 0x03, - ARM_MAX_OPP = 0x04, - ARM_MAX_FREQ100OPP = 0x05, - ARM_EXTCLK = 0x07 -}; - -/** - * enum ddr_opp - DDR OPP states definition - * @DDR_100_OPP: The new DDR operating point is ddr100opp - * @DDR_50_OPP: The new DDR operating point is ddr50opp - * @DDR_25_OPP: The new DDR operating point is ddr25opp - */ -enum ddr_opp { - DDR_100_OPP = 0x00, - DDR_50_OPP = 0x01, - DDR_25_OPP = 0x02, -}; - -/* - * Definitions for controlling ESRAM0 in deep sleep. - */ -#define ESRAM0_DEEP_SLEEP_STATE_OFF 1 -#define ESRAM0_DEEP_SLEEP_STATE_RET 2 - -/** - * enum ddr_pwrst - DDR power states definition - * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged - * @DDR_PWR_STATE_ON: - * @DDR_PWR_STATE_OFFLOWLAT: - * @DDR_PWR_STATE_OFFHIGHLAT: - */ -enum ddr_pwrst { - DDR_PWR_STATE_UNCHANGED = 0x00, - DDR_PWR_STATE_ON = 0x01, - DDR_PWR_STATE_OFFLOWLAT = 0x02, - DDR_PWR_STATE_OFFHIGHLAT = 0x03 -}; - -#define DB8500_PRCMU_LEGACY_OFFSET 0xDD4 - -#define PRCMU_FW_PROJECT_U8500 2 -#define PRCMU_FW_PROJECT_U8400 3 -#define PRCMU_FW_PROJECT_U9500 4 /* Customer specific */ -#define PRCMU_FW_PROJECT_U8500_MBB 5 -#define PRCMU_FW_PROJECT_U8500_C1 6 -#define PRCMU_FW_PROJECT_U8500_C2 7 -#define PRCMU_FW_PROJECT_U8500_C3 8 -#define PRCMU_FW_PROJECT_U8500_C4 9 -#define PRCMU_FW_PROJECT_U9500_MBL 10 -#define PRCMU_FW_PROJECT_U8500_SSG1 11 /* Samsung specific */ -#define PRCMU_FW_PROJECT_U8500_MBL2 12 /* Customer specific */ -#define PRCMU_FW_PROJECT_U8520 13 -#define PRCMU_FW_PROJECT_U8420 14 -#define PRCMU_FW_PROJECT_U8500_SSG2 15 /* Samsung specific */ -#define PRCMU_FW_PROJECT_U8420_SYSCLK 17 -#define PRCMU_FW_PROJECT_A9420 20 -/* [32..63] 9540 and derivatives */ -#define PRCMU_FW_PROJECT_U9540 32 -/* [64..95] 8540 and derivatives */ -#define PRCMU_FW_PROJECT_L8540 64 -/* [96..126] 8580 and derivatives */ -#define PRCMU_FW_PROJECT_L8580 96 - -#define PRCMU_FW_PROJECT_NAME_LEN 20 -struct prcmu_fw_version { - u32 project; /* Notice, project shifted with 8 on ux540 */ - u8 api_version; - u8 func_version; - u8 errata; - char project_name[PRCMU_FW_PROJECT_NAME_LEN]; -}; - -#include <linux/mfd/db8500-prcmu.h> - -#if defined(CONFIG_UX500_SOC_DB8500) - -static inline void __init prcmu_early_init(void) -{ - db8500_prcmu_early_init(); -} - -static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, - bool keep_ap_pll) -{ - return db8500_prcmu_set_power_state(state, keep_ulp_clk, - keep_ap_pll); -} - -static inline u8 prcmu_get_power_state_result(void) -{ - return db8500_prcmu_get_power_state_result(); -} - -static inline int prcmu_set_epod(u16 epod_id, u8 epod_state) -{ - return db8500_prcmu_set_epod(epod_id, epod_state); -} - -static inline void prcmu_enable_wakeups(u32 wakeups) -{ - db8500_prcmu_enable_wakeups(wakeups); -} - -static inline void prcmu_disable_wakeups(void) -{ - prcmu_enable_wakeups(0); -} - -static inline void prcmu_config_abb_event_readout(u32 abb_events) -{ - db8500_prcmu_config_abb_event_readout(abb_events); -} - -static inline void prcmu_get_abb_event_buffer(void __iomem **buf) -{ - db8500_prcmu_get_abb_event_buffer(buf); -} - -int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); -int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); -int prcmu_abb_write_masked(u8 slave, u8 reg, u8 *value, u8 *mask, u8 size); - -int prcmu_config_clkout(u8 clkout, u8 source, u8 div); - -static inline int prcmu_request_clock(u8 clock, bool enable) -{ - return db8500_prcmu_request_clock(clock, enable); -} - -unsigned long prcmu_clock_rate(u8 clock); -long prcmu_round_clock_rate(u8 clock, unsigned long rate); -int prcmu_set_clock_rate(u8 clock, unsigned long rate); - -static inline int prcmu_get_ddr_opp(void) -{ - return db8500_prcmu_get_ddr_opp(); -} - -static inline int prcmu_set_arm_opp(u8 opp) -{ - return db8500_prcmu_set_arm_opp(opp); -} - -static inline int prcmu_get_arm_opp(void) -{ - return db8500_prcmu_get_arm_opp(); -} - -static inline int prcmu_set_ape_opp(u8 opp) -{ - return db8500_prcmu_set_ape_opp(opp); -} - -static inline int prcmu_get_ape_opp(void) -{ - return db8500_prcmu_get_ape_opp(); -} - -static inline int prcmu_request_ape_opp_100_voltage(bool enable) -{ - return db8500_prcmu_request_ape_opp_100_voltage(enable); -} - -static inline void prcmu_system_reset(u16 reset_code) -{ - db8500_prcmu_system_reset(reset_code); -} - -static inline u16 prcmu_get_reset_code(void) -{ - return db8500_prcmu_get_reset_code(); -} - -int prcmu_ac_wake_req(void); -void prcmu_ac_sleep_req(void); -static inline void prcmu_modem_reset(void) -{ - db8500_prcmu_modem_reset(); -} - -static inline bool prcmu_is_ac_wake_requested(void) -{ - return db8500_prcmu_is_ac_wake_requested(); -} - -static inline int prcmu_config_esram0_deep_sleep(u8 state) -{ - return db8500_prcmu_config_esram0_deep_sleep(state); -} - -static inline int prcmu_config_hotdog(u8 threshold) -{ - return db8500_prcmu_config_hotdog(threshold); -} - -static inline int prcmu_config_hotmon(u8 low, u8 high) -{ - return db8500_prcmu_config_hotmon(low, high); -} - -static inline int prcmu_start_temp_sense(u16 cycles32k) -{ - return db8500_prcmu_start_temp_sense(cycles32k); -} - -static inline int prcmu_stop_temp_sense(void) -{ - return db8500_prcmu_stop_temp_sense(); -} - -static inline u32 prcmu_read(unsigned int reg) -{ - return db8500_prcmu_read(reg); -} - -static inline void prcmu_write(unsigned int reg, u32 value) -{ - db8500_prcmu_write(reg, value); -} - -static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) -{ - db8500_prcmu_write_masked(reg, mask, value); -} - -static inline int prcmu_enable_a9wdog(u8 id) -{ - return db8500_prcmu_enable_a9wdog(id); -} - -static inline int prcmu_disable_a9wdog(u8 id) -{ - return db8500_prcmu_disable_a9wdog(id); -} - -static inline int prcmu_kick_a9wdog(u8 id) -{ - return db8500_prcmu_kick_a9wdog(id); -} - -static inline int prcmu_load_a9wdog(u8 id, u32 timeout) -{ - return db8500_prcmu_load_a9wdog(id, timeout); -} - -static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off) -{ - return db8500_prcmu_config_a9wdog(num, sleep_auto_off); -} -#else - -static inline void prcmu_early_init(void) {} - -static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, - bool keep_ap_pll) -{ - return 0; -} - -static inline int prcmu_set_epod(u16 epod_id, u8 epod_state) -{ - return 0; -} - -static inline void prcmu_enable_wakeups(u32 wakeups) {} - -static inline void prcmu_disable_wakeups(void) {} - -static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) -{ - return -ENOSYS; -} - -static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) -{ - return -ENOSYS; -} - -static inline int prcmu_abb_write_masked(u8 slave, u8 reg, u8 *value, u8 *mask, - u8 size) -{ - return -ENOSYS; -} - -static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div) -{ - return 0; -} - -static inline int prcmu_request_clock(u8 clock, bool enable) -{ - return 0; -} - -static inline long prcmu_round_clock_rate(u8 clock, unsigned long rate) -{ - return 0; -} - -static inline int prcmu_set_clock_rate(u8 clock, unsigned long rate) -{ - return 0; -} - -static inline unsigned long prcmu_clock_rate(u8 clock) -{ - return 0; -} - -static inline int prcmu_set_ape_opp(u8 opp) -{ - return 0; -} - -static inline int prcmu_get_ape_opp(void) -{ - return APE_100_OPP; -} - -static inline int prcmu_request_ape_opp_100_voltage(bool enable) -{ - return 0; -} - -static inline int prcmu_set_arm_opp(u8 opp) -{ - return 0; -} - -static inline int prcmu_get_arm_opp(void) -{ - return ARM_100_OPP; -} - -static inline int prcmu_get_ddr_opp(void) -{ - return DDR_100_OPP; -} - -static inline void prcmu_system_reset(u16 reset_code) {} - -static inline u16 prcmu_get_reset_code(void) -{ - return 0; -} - -static inline int prcmu_ac_wake_req(void) -{ - return 0; -} - -static inline void prcmu_ac_sleep_req(void) {} - -static inline void prcmu_modem_reset(void) {} - -static inline bool prcmu_is_ac_wake_requested(void) -{ - return false; -} - -static inline int prcmu_config_esram0_deep_sleep(u8 state) -{ - return 0; -} - -static inline void prcmu_config_abb_event_readout(u32 abb_events) {} - -static inline void prcmu_get_abb_event_buffer(void __iomem **buf) -{ - *buf = NULL; -} - -static inline int prcmu_config_hotdog(u8 threshold) -{ - return 0; -} - -static inline int prcmu_config_hotmon(u8 low, u8 high) -{ - return 0; -} - -static inline int prcmu_start_temp_sense(u16 cycles32k) -{ - return 0; -} - -static inline int prcmu_stop_temp_sense(void) -{ - return 0; -} - -static inline u32 prcmu_read(unsigned int reg) -{ - return 0; -} - -static inline void prcmu_write(unsigned int reg, u32 value) {} - -static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} - -#endif - -static inline void prcmu_set(unsigned int reg, u32 bits) -{ - prcmu_write_masked(reg, bits, bits); -} - -static inline void prcmu_clear(unsigned int reg, u32 bits) -{ - prcmu_write_masked(reg, bits, 0); -} - -/* PRCMU QoS APE OPP class */ -#define PRCMU_QOS_APE_OPP 1 -#define PRCMU_QOS_DDR_OPP 2 -#define PRCMU_QOS_ARM_OPP 3 -#define PRCMU_QOS_DEFAULT_VALUE -1 - -static inline int prcmu_qos_add_requirement(int prcmu_qos_class, - char *name, s32 value) -{ - return 0; -} - -static inline int prcmu_qos_update_requirement(int prcmu_qos_class, - char *name, s32 new_value) -{ - return 0; -} - -static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name) -{ -} - -#endif /* __MACH_PRCMU_H */ diff --git a/include/linux/mfd/lp3943.h b/include/linux/mfd/lp3943.h index 402f01078fcc..5d2d172d3598 100644 --- a/include/linux/mfd/lp3943.h +++ b/include/linux/mfd/lp3943.h @@ -10,7 +10,7 @@ #ifndef __MFD_LP3943_H__ #define __MFD_LP3943_H__ -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/regmap.h> /* Registers */ diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h index dd51a37fa37f..5957e15b568e 100644 --- a/include/linux/mfd/max14577-private.h +++ b/include/linux/mfd/max14577-private.h @@ -350,6 +350,9 @@ enum max77836_pmic_reg { #define MAX77836_CNFG1_LDO_PWRMD_SHIFT 6 #define MAX77836_CNFG1_LDO_TV_SHIFT 0 #define MAX77836_CNFG1_LDO_PWRMD_MASK (0x3 << MAX77836_CNFG1_LDO_PWRMD_SHIFT) +#define MAX77836_CNFG1_LDO_PWRMD_OFF (0x0 << MAX77836_CNFG1_LDO_PWRMD_SHIFT) +#define MAX77836_CNFG1_LDO_PWRMD_LPM (0x1 << MAX77836_CNFG1_LDO_PWRMD_SHIFT) +#define MAX77836_CNFG1_LDO_PWRMD_NORMAL (0x3 << MAX77836_CNFG1_LDO_PWRMD_SHIFT) #define MAX77836_CNFG1_LDO_TV_MASK (0x3f << MAX77836_CNFG1_LDO_TV_SHIFT) /* LDO1/LDO2 CONFIG2 register */ diff --git a/include/linux/mfd/si476x-core.h b/include/linux/mfd/si476x-core.h index e913b2cdf77d..d9e3a322134c 100644 --- a/include/linux/mfd/si476x-core.h +++ b/include/linux/mfd/si476x-core.h @@ -14,6 +14,7 @@ #include <linux/kfifo.h> #include <linux/atomic.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/regmap.h> #include <linux/mutex.h> @@ -104,7 +105,7 @@ enum si476x_power_state { * @power_state: Current power state of the device. * @supplies: Structure containing handles to all power supplies used * by the device (NULL ones are ignored). - * @gpio_reset: GPIO pin connectet to the RSTB pin of the chip. + * @reset: GPIO connected to the RSTB pin of the chip. * @pinmux: Chip's configurable pins configuration. * @diversity_mode: Chips role when functioning in diversity mode. * @is_alive: Chip is initialized and active. @@ -142,7 +143,7 @@ struct si476x_core { struct regulator_bulk_data supplies[4]; - int gpio_reset; + struct gpio_desc *reset; struct si476x_pinmux pinmux; enum si476x_phase_diversity_mode diversity_mode; diff --git a/include/linux/mfd/si476x-platform.h b/include/linux/mfd/si476x-platform.h index cb99e16ca947..f9e1f6b27277 100644 --- a/include/linux/mfd/si476x-platform.h +++ b/include/linux/mfd/si476x-platform.h @@ -246,8 +246,6 @@ enum si476x_phase_diversity_mode { * Platform dependent definition */ struct si476x_platform_data { - int gpio_reset; /* < 0 if not used */ - struct si476x_power_up_args power_up_parameters; enum si476x_phase_diversity_mode diversity_mode; diff --git a/include/linux/mfd/ti-lmu.h b/include/linux/mfd/ti-lmu.h index 0bc0e8199798..2089ec5124e8 100644 --- a/include/linux/mfd/ti-lmu.h +++ b/include/linux/mfd/ti-lmu.h @@ -10,7 +10,6 @@ #ifndef __MFD_TI_LMU_H__ #define __MFD_TI_LMU_H__ -#include <linux/gpio.h> #include <linux/notifier.h> #include <linux/regmap.h> #include <linux/gpio/consumer.h> diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index f67ef0a4e041..3813fc9c2b55 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -12,7 +12,7 @@ #ifndef __LINUX_MFD_TPS65910_H #define __LINUX_MFD_TPS65910_H -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/regmap.h> /* TPS chip id list */ diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h index ede237384723..66ecad4667c9 100644 --- a/include/linux/mfd/ucb1x00.h +++ b/include/linux/mfd/ucb1x00.h @@ -9,7 +9,7 @@ #include <linux/device.h> #include <linux/mfd/mcp.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/gpio/driver.h> #include <linux/mutex.h> @@ -103,6 +103,9 @@ #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) #define UCB_MODE_AUD_OFF_CAN (1 << 13) +struct software_node; +extern const struct software_node ucb1x00_gpiochip_node; + enum ucb1x00_reset { UCB_RST_PROBE, UCB_RST_RESUME, diff --git a/include/linux/mfd/viperboard.h b/include/linux/mfd/viperboard.h index 0557667fe544..5761ebdc81b3 100644 --- a/include/linux/mfd/viperboard.h +++ b/include/linux/mfd/viperboard.h @@ -47,7 +47,7 @@ struct vprbrd_i2c_write_hdr { u8 cmd; - u16 addr; + __le16 addr; u8 len1; u8 len2; u8 last; @@ -57,15 +57,15 @@ struct vprbrd_i2c_write_hdr { struct vprbrd_i2c_read_hdr { u8 cmd; - u16 addr; + __le16 addr; u8 len0; u8 len1; u8 len2; u8 len3; u8 len4; u8 len5; - u16 tf1; /* transfer 1 length */ - u16 tf2; /* transfer 2 length */ + __le16 tf1; /* transfer 1 length */ + __le16 tf2; /* transfer 2 length */ } __packed; struct vprbrd_i2c_status { @@ -89,7 +89,7 @@ struct vprbrd_i2c_addr_msg { u8 cmd; u8 addr; u8 unknown1; - u16 len; + __le16 len; u8 unknown2; u8 unknown3; } __packed; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index fb3ba639f4f8..8616bacd8675 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -14,6 +14,7 @@ #include <linux/spinlock.h> #include <linux/wait.h> #include <linux/workqueue.h> +#include <linux/device-id/mhi.h> #define MHI_MAX_OEM_PK_HASH_SEGMENTS 16 @@ -116,8 +117,8 @@ struct image_info { /** * struct mhi_link_info - BW requirement - * target_link_speed - Link speed as defined by TLS bits in LinkControl reg - * target_link_width - Link width as defined by NLW bits in LinkStatus reg + * @target_link_speed: Link speed as defined by TLS bits in LinkControl reg + * @target_link_width: Link width as defined by NLW bits in LinkStatus reg */ struct mhi_link_info { unsigned int target_link_speed; @@ -172,6 +173,7 @@ enum mhi_state { MHI_STATE_M3_FAST = 0x6, MHI_STATE_BHI = 0x7, MHI_STATE_SYS_ERR = 0xFF, + /* private: */ MHI_STATE_MAX, }; @@ -226,12 +228,12 @@ enum mhi_db_brst_mode { * @type: Channel type * @ee_mask: Execution Environment mask for this channel * @pollcfg: Polling configuration for burst mode. 0 is default. milliseconds - for UL channels, multiple of 8 ring elements for DL channels + * for UL channels, multiple of 8 ring elements for DL channels * @doorbell: Doorbell mode * @lpm_notify: The channel master requires low power mode notifications * @offload_channel: The client manages the channel completely * @doorbell_mode_switch: Channel switches to doorbell mode on M0 transition - * @wake-capable: Channel capable of waking up the system + * @wake_capable: Channel capable of waking up the system */ struct mhi_channel_config { char *name; @@ -349,7 +351,9 @@ struct mhi_controller_config { * @dev_state: MHI device state * @dev_wake: Device wakeup count * @pending_pkts: Pending packets for the controller - * @M0, M2, M3: Counters to track number of device MHI state changes + * @M0: Counter to track number of device MHI state changes + * @M2: Counter to track number of device MHI state changes + * @M3: Counter to track number of device MHI state changes * @transition_list: List of MHI state transitions * @transition_lock: Lock for protecting MHI state transition list * @wlock: Lock for protecting device wakeup @@ -374,6 +378,7 @@ struct mhi_controller_config { * @bounce_buf: Use of bounce buffer * @fbc_download: MHI host needs to do complete image transfer (optional) * @wake_set: Device wakeup set flag + * @no_m3: Device doesn't support M3 state * @irq_flags: irq flags passed to request_irq (optional) * @mru: the default MRU for the MHI device * @@ -459,6 +464,7 @@ struct mhi_controller { bool bounce_buf; bool fbc_download; bool wake_set; + bool no_m3; unsigned long irq_flags; u32 mru; }; @@ -506,6 +512,7 @@ struct mhi_result { /** * struct mhi_driver - Structure representing a MHI client driver + * @id_table: table of MHI channel names that a driver supports * @probe: CB function for client driver probe function * @remove: CB function for client driver remove function * @ul_xfer_cb: CB function for UL data transfer @@ -537,6 +544,7 @@ struct mhi_controller *mhi_alloc_controller(void); /** * mhi_free_controller - Free the MHI Controller structure + * @mhi_cntrl: MHI controller to free * Free the mhi_controller structure which was previously allocated */ void mhi_free_controller(struct mhi_controller *mhi_cntrl); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 7b40fc8cbe77..f6383a57a872 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -107,6 +107,7 @@ struct mhi_ep_buf_info { * @write_sync: CB function for writing to host memory synchronously * @read_async: CB function for reading from host memory asynchronously * @write_async: CB function for writing to host memory asynchronously + * @flush_async: CB function for flushing asynchronous read/writes * @mhi_state: MHI Endpoint state * @max_chan: Maximum channels supported by the endpoint controller * @mru: MRU (Maximum Receive Unit) value of the endpoint controller @@ -164,6 +165,7 @@ struct mhi_ep_cntrl { int (*write_sync)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info); int (*read_async)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info); int (*write_async)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info); + void (*flush_async)(struct mhi_ep_cntrl *mhi_cntrl); enum mhi_state mhi_state; diff --git a/include/linux/migrate.h b/include/linux/migrate.h index d5af2b7f577b..78424b3824c2 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -57,8 +57,9 @@ void putback_movable_pages(struct list_head *l); int migrate_folio(struct address_space *mapping, struct folio *dst, struct folio *src, enum migrate_mode mode); int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free, - unsigned long private, enum migrate_mode mode, int reason, - unsigned int *ret_succeeded); + unsigned long private, enum migrate_mode mode, + enum migrate_reason reason, + unsigned int *ret_succeeded); struct folio *alloc_migration_target(struct folio *src, unsigned long private); bool isolate_movable_ops_page(struct page *page, isolate_mode_t mode); bool isolate_folio_to_list(struct folio *folio, struct list_head *list); @@ -77,7 +78,8 @@ int set_movable_ops(const struct movable_operations *ops, enum pagetype type); static inline void putback_movable_pages(struct list_head *l) {} static inline int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free, unsigned long private, - enum migrate_mode mode, int reason, unsigned int *ret_succeeded) + enum migrate_mode mode, enum migrate_reason reason, + unsigned int *ret_succeeded) { return -ENOSYS; } static inline struct folio *alloc_migration_target(struct folio *src, unsigned long private) diff --git a/include/linux/migrate_mode.h b/include/linux/migrate_mode.h index 265c4328b36a..05102d4d2490 100644 --- a/include/linux/migrate_mode.h +++ b/include/linux/migrate_mode.h @@ -25,6 +25,7 @@ enum migrate_reason { MR_LONGTERM_PIN, MR_DEMOTION, MR_DAMON, + MR_NEVER, /* page has never been migrated */ MR_TYPES }; diff --git a/include/linux/misc/tsi.h b/include/linux/misc/tsi.h new file mode 100644 index 000000000000..5273c44688f0 --- /dev/null +++ b/include/linux/misc/tsi.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD SBTSI shared data structure and auxiliary bus definitions. + * + * Copyright (C) 2026 Advanced Micro Devices, Inc. + */ + +#ifndef _LINUX_MISC_TSI_H_ +#define _LINUX_MISC_TSI_H_ + +#include <linux/cleanup.h> +#include <linux/i2c.h> +#include <linux/i3c/device.h> +#include <linux/kref.h> +#include <linux/miscdevice.h> +#include <linux/mutex.h> +#include <linux/types.h> + +/** + * struct sbtsi_data - driver private data for an AMD SB-TSI device + * @client: underlying I2C client + * @i3cdev: underlying I3C device (when using I3C bus) + * @sbtsi_misc_dev: miscdevice exposing ioctl interface at /dev/sbtsi-<addr> + * @lock: mutex protecting concurrent access to the device + * @kref: reference count; keeps @sbtsi_data alive while misc fds are open + * @dev_addr: I2C/I3C device address, used as the auxiliary device instance id + * and name the misc device node + * @ext_range_mode: sensor uses extended temperature range + * @read_order: if set, decimal part must be read before integer part + * @is_i3c: true when the device is accessed over I3C + * @detached: set on driver unbind; open/ioctl return -ENODEV afterward + */ +struct sbtsi_data { + union { + struct i2c_client *client; + struct i3c_device *i3cdev; + }; + struct miscdevice sbtsi_misc_dev; + struct mutex lock; /* protects concurrent access to the device */ + struct kref kref; + u8 dev_addr; + bool ext_range_mode; + bool read_order; + bool is_i3c; + bool detached; +}; + +DEFINE_GUARD(sbtsi, struct sbtsi_data *, mutex_lock(&_T->lock), + mutex_unlock(&_T->lock)) + +/* + * Name of the auxiliary device published on the auxiliary bus by the core + * driver. The full device name is "amd-sbtsi.temp-sensor.<id>". where + * <id> is the auxiliary device instance id. + */ +#define AMD_SBTSI_ADEV "amd-sbtsi" +#define AMD_SBTSI_AUX_HWMON "temp-sensor" + +/** + * sbtsi_xfer - Perform a register read or write transfer on an AMD SB-TSI device. + * + * @data: Pointer to the sbtsi_data structure containing the device context + * @reg: Register address to access. + * @val: Pointer to the value to read into or write from. + * @is_read: If true, performs a read transfer and stores the result in @val. + * If false, performs a write transfer using the value in @val. + * + * Returns 0 on success, or a negative error code on failure. + */ +int sbtsi_xfer(struct sbtsi_data *data, u8 reg, u8 *val, bool is_read); + +#endif /* _LINUX_MISC_TSI_H_ */ diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index 07a25f264292..8cb321a9fb3d 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -1171,6 +1171,7 @@ enum { MLX5_MATCH_MISC_PARAMETERS_3 = 1 << 4, MLX5_MATCH_MISC_PARAMETERS_4 = 1 << 5, MLX5_MATCH_MISC_PARAMETERS_5 = 1 << 6, + MLX5_MATCH_MISC_PARAMETERS_6 = 1 << 7, }; enum { diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index b1871c0821d0..83d0a83bbfbc 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -548,6 +548,7 @@ struct mlx5_debugfs_entries { struct dentry *cq_debugfs; struct dentry *cmdif_debugfs; struct dentry *frag_buf_dma_pools_debugfs; + struct dentry *db_dma_pools_debugfs; struct dentry *pages_debugfs; struct dentry *lag_debugfs; }; @@ -569,6 +570,7 @@ enum mlx5_page_mgt_mode { }; struct mlx5_frag_buf_node_pools; +struct mlx5_dma_pool; struct mlx5_ft_pool; struct mlx5_priv { /* IRQ table valid only for real pci devices PF or VF */ @@ -598,10 +600,8 @@ struct mlx5_priv { struct mutex alloc_mutex; int numa_node; - struct mutex pgdir_mutex; - struct list_head pgdir_list; - struct mlx5_frag_buf_node_pools **frag_buf_node_pools; + struct mlx5_dma_pool **db_node_pools; /* end: alloc stuff */ struct mlx5_adev **adev; @@ -806,7 +806,7 @@ struct mlx5_core_dev { struct mlx5_db { __be32 *db; union { - struct mlx5_db_pgdir *pgdir; + struct mlx5_dma_pool_page *pool_page; struct mlx5_ib_user_db_page *user_page; } u; dma_addr_t dma; diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 695c86ee6d7a..12b9a81e5621 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -508,7 +508,8 @@ struct mlx5_ifc_flow_table_prop_layout_bits { u8 reformat_l2_to_l3_audp_tunnel[0x1]; u8 reformat_l3_audp_tunnel_to_l2[0x1]; u8 ignore_flow_level_rtc_valid[0x1]; - u8 reserved_at_70[0x8]; + u8 reserved_at_70[0x7]; + u8 reformat_del_psp_transport[0x1]; u8 log_max_ft_num[0x8]; u8 reserved_at_80[0x10]; @@ -798,6 +799,15 @@ struct mlx5_ifc_fte_match_set_misc5_bits { u8 reserved_at_100[0x100]; }; +struct mlx5_ifc_fte_match_set_misc6_bits { + u8 reserved_at_0[0x1a]; + u8 psp_version[0x4]; + u8 reserved_at_1e[0x2]; + + u8 reserved_at_20[0x1e0]; +}; + + struct mlx5_ifc_cmd_pas_bits { u8 pa_h[0x20]; @@ -1042,20 +1052,6 @@ struct mlx5_ifc_wqe_based_flow_table_cap_bits { u8 reserved_at_1c1[0x1f]; }; -struct mlx5_ifc_esw_cap_bits { - u8 reserved_at_0[0x1d]; - u8 merged_eswitch[0x1]; - u8 reserved_at_1e[0x2]; - - u8 reserved_at_20[0x40]; - - u8 esw_manager_vport_number_valid[0x1]; - u8 reserved_at_61[0xf]; - u8 esw_manager_vport_number[0x10]; - - u8 reserved_at_80[0x780]; -}; - enum { MLX5_COUNTER_SOURCE_ESWITCH = 0x0, MLX5_COUNTER_FLOW_ESWITCH = 0x1, @@ -1096,7 +1092,11 @@ struct mlx5_ifc_e_switch_cap_bits { u8 log_max_esw_sf[0x5]; u8 esw_sf_base_id[0x10]; - u8 reserved_at_60[0x7a0]; + u8 esw_manager_vport_number_valid[0x1]; + u8 reserved_at_61[0xf]; + u8 esw_manager_vport_number[0x10]; + + u8 reserved_at_80[0x780]; }; @@ -2005,7 +2005,8 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 log_max_stride_sz_rq[0x5]; u8 reserved_at_3a8[0x3]; u8 log_min_stride_sz_rq[0x5]; - u8 reserved_at_3b0[0x3]; + u8 reserved_at_3b0[0x2]; + u8 qp_latency_sensitive_disable[0x1]; u8 log_max_stride_sz_sq[0x5]; u8 reserved_at_3b8[0x3]; u8 log_min_stride_sz_sq[0x5]; @@ -2352,7 +2353,7 @@ struct mlx5_ifc_fte_match_param_bits { struct mlx5_ifc_fte_match_set_misc5_bits misc_parameters_5; - u8 reserved_at_e00[0x200]; + struct mlx5_ifc_fte_match_set_misc6_bits misc_parameters_6; }; enum { @@ -3859,7 +3860,6 @@ union mlx5_ifc_hca_cap_union_bits { struct mlx5_ifc_flow_table_nic_cap_bits flow_table_nic_cap; struct mlx5_ifc_flow_table_eswitch_cap_bits flow_table_eswitch_cap; struct mlx5_ifc_wqe_based_flow_table_cap_bits wqe_based_flow_table_cap; - struct mlx5_ifc_esw_cap_bits esw_cap; struct mlx5_ifc_e_switch_cap_bits e_switch_cap; struct mlx5_ifc_port_selection_cap_bits port_selection_cap; struct mlx5_ifc_qos_cap_bits qos_cap; @@ -6999,6 +6999,7 @@ enum { MLX5_QUERY_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS_3 = 0x4, MLX5_QUERY_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS_4 = 0x5, MLX5_QUERY_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS_5 = 0x6, + MLX5_QUERY_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS_6 = 0x7, }; struct mlx5_ifc_query_flow_group_out_bits { @@ -7260,6 +7261,7 @@ enum mlx5_reformat_ctx_type { MLX5_REFORMAT_TYPE_REMOVE_HDR = 0x10, MLX5_REFORMAT_TYPE_ADD_MACSEC = 0x11, MLX5_REFORMAT_TYPE_DEL_MACSEC = 0x12, + MLX5_REFORMAT_TYPE_REMOVE_PSP_TRANSPORT = 0x16, }; struct mlx5_ifc_alloc_packet_reformat_context_in_bits { @@ -7383,6 +7385,7 @@ enum { MLX5_ACTION_IN_FIELD_OUT_EMD_47_32 = 0x6F, MLX5_ACTION_IN_FIELD_OUT_EMD_31_0 = 0x70, MLX5_ACTION_IN_FIELD_PSP_SYNDROME = 0x71, + MLX5_ACTION_IN_FIELD_PSP_HEADER_1 = 0x78, }; struct mlx5_ifc_alloc_modify_header_context_out_bits { @@ -12215,18 +12218,7 @@ struct mlx5_ifc_mcia_reg_bits { u8 reserved_at_60[0x20]; - u8 dword_0[0x20]; - u8 dword_1[0x20]; - u8 dword_2[0x20]; - u8 dword_3[0x20]; - u8 dword_4[0x20]; - u8 dword_5[0x20]; - u8 dword_6[0x20]; - u8 dword_7[0x20]; - u8 dword_8[0x20]; - u8 dword_9[0x20]; - u8 dword_10[0x20]; - u8 dword_11[0x20]; + u8 dwords[0x400]; }; struct mlx5_ifc_dcbx_param_bits { diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h index ee34d3ed335f..57c6b5bacedb 100644 --- a/include/linux/mlx5/vport.h +++ b/include/linux/mlx5/vport.h @@ -61,7 +61,8 @@ u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport); int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport, u8 other_vport, u8 state); int mlx5_query_vport_max_tx_speed(struct mlx5_core_dev *mdev, u8 op_mod, - u16 vport, u8 other_vport, u32 *max_tx_speed); + u16 vport, u8 other_vport, + u32 *max_tx_speed, u8 *state); int mlx5_modify_vport_max_tx_speed(struct mlx5_core_dev *mdev, u8 opmod, u16 vport, u8 other_vport, u16 max_tx_speed); int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, @@ -78,7 +79,8 @@ int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu); int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu); int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev, u64 *system_image_guid); -int mlx5_query_nic_vport_sd_group(struct mlx5_core_dev *mdev, u8 *sd_group); +int mlx5_query_nic_vport_sd_group(struct mlx5_core_dev *mdev, u8 *sd_group, + u8 *sd_group_size); int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u16 vport, bool other_vport, u64 *node_guid); int mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev *mdev, diff --git a/include/linux/mm.h b/include/linux/mm.h index 485df9c2dbdd..dd09c438fa23 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -37,6 +37,7 @@ #include <linux/bitmap.h> #include <linux/bitops.h> #include <linux/iommu-debug-pagealloc.h> +#include <linux/kcsan-checks.h> struct mempolicy; struct anon_vma; @@ -353,6 +354,7 @@ enum { #endif DECLARE_VMA_BIT(UFFD_MINOR, 41), DECLARE_VMA_BIT(SEALED, 42), + DECLARE_VMA_BIT(UFFD_RWP, 43), /* Flags that reuse flags above. */ DECLARE_VMA_BIT_ALIAS(PKEY_BIT0, HIGH_ARCH_0), DECLARE_VMA_BIT_ALIAS(PKEY_BIT1, HIGH_ARCH_1), @@ -440,8 +442,10 @@ enum { #define VM_STACK INIT_VM_FLAG(STACK) #ifdef CONFIG_STACK_GROWSUP #define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY) +#define VMA_STACK_EARLY mk_vma_flags(VMA_STACK_EARLY_BIT) #else #define VM_STACK_EARLY VM_NONE +#define VMA_STACK_EARLY EMPTY_VMA_FLAGS #endif #ifdef CONFIG_ARCH_HAS_PKEYS #define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT) @@ -463,15 +467,18 @@ enum { #if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_ARM64_GCS) || \ defined(CONFIG_RISCV_USER_CFI) #define VM_SHADOW_STACK INIT_VM_FLAG(SHADOW_STACK) +#define VMA_SHADOW_STACK mk_vma_flags(VMA_SHADOW_STACK_BIT) #define VMA_STARTGAP_FLAGS mk_vma_flags(VMA_GROWSDOWN_BIT, VMA_SHADOW_STACK_BIT) #else #define VM_SHADOW_STACK VM_NONE +#define VMA_SHADOW_STACK EMPTY_VMA_FLAGS #define VMA_STARTGAP_FLAGS mk_vma_flags(VMA_GROWSDOWN_BIT) #endif #if defined(CONFIG_PPC64) #define VM_SAO INIT_VM_FLAG(SAO) #elif defined(CONFIG_PARISC) #define VM_GROWSUP INIT_VM_FLAG(GROWSUP) +#define VMA_GROWSUP mk_vma_flags(VMA_GROWSUP_BIT) #elif defined(CONFIG_SPARC64) #define VM_SPARC_ADI INIT_VM_FLAG(SPARC_ADI) #define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR) @@ -483,6 +490,7 @@ enum { #endif #ifndef VM_GROWSUP #define VM_GROWSUP VM_NONE +#define VMA_GROWSUP EMPTY_VMA_FLAGS #endif #ifdef CONFIG_ARM64_MTE #define VM_MTE INIT_VM_FLAG(MTE) @@ -496,12 +504,17 @@ enum { #else #define VM_UFFD_MINOR VM_NONE #endif +#ifdef CONFIG_USERFAULTFD_RWP +#define VM_UFFD_RWP INIT_VM_FLAG(UFFD_RWP) +#else +#define VM_UFFD_RWP 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. + * vma_flags_t masks for the userfaultfd VMA flags. The two high-bit modes are + * gated on the same configs as their VM_* flags above -- both of which imply + * 64BIT -- 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) @@ -510,6 +523,11 @@ enum { #else #define VMA_UFFD_MINOR EMPTY_VMA_FLAGS #endif +#ifdef CONFIG_USERFAULTFD_RWP +#define VMA_UFFD_RWP mk_vma_flags(VMA_UFFD_RWP_BIT) +#else +#define VMA_UFFD_RWP EMPTY_VMA_FLAGS +#endif #ifdef CONFIG_64BIT #define VM_ALLOW_ANY_UNCACHED INIT_VM_FLAG(ALLOW_ANY_UNCACHED) @@ -528,6 +546,8 @@ enum { /* Bits set in the VMA until the stack is in its final location */ #define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY) +#define VMA_STACK_INCOMPLETE_SETUP append_vma_flags( \ + VMA_STACK_EARLY, VMA_RAND_READ_BIT, VMA_SEQ_READ_BIT) #define TASK_EXEC_BIT ((current->personality & READ_IMPLIES_EXEC) ? \ VMA_EXEC_BIT : VMA_READ_BIT) @@ -648,29 +668,32 @@ enum { * reconsistuted upon page fault, so necessitate page table copying upon fork. * * Note that these flags should be compared with the DESTINATION VMA not the - * source, as VM_UFFD_WP may not be propagated to destination, while all other - * flags will be. + * source: VM_UFFD_WP and VM_UFFD_RWP may be cleared on the destination + * (dup_userfaultfd() -> userfaultfd_reset_ctx() when the parent context did + * not negotiate UFFD_FEATURE_EVENT_FORK), while all other flags propagate. * * VM_PFNMAP / VM_MIXEDMAP - These contain kernel-mapped data which cannot be * reasonably reconstructed on page fault. * * VM_UFFD_WP - Encodes metadata about an installed uffd - * write protect handler, which cannot be - * reconstructed on page fault. + * VM_UFFD_RWP write- or read-write-protect handler, which + * cannot be reconstructed on page fault. * - * We always copy pgtables when dst_vma has uffd-wp - * enabled even if it's file-backed - * (e.g. shmem). Because when uffd-wp is enabled, - * pgtable contains uffd-wp protection information, - * that's something we can't retrieve from page cache, - * and skip copying will lose those info. + * We always copy pgtables when dst_vma has the + * uffd PTE bit in use even if it's file-backed + * (e.g. shmem). Because when the uffd bit is + * in use, the pgtable contains the protection + * information, that's something we can't + * retrieve from page cache, and skip copying + * will lose those info. * * VM_MAYBE_GUARD - Could contain page guard region markers which * by design are a property of the page tables * only and thus cannot be reconstructed on page * fault. */ -#define VM_COPY_ON_FORK (VM_PFNMAP | VM_MIXEDMAP | VM_UFFD_WP | VM_MAYBE_GUARD) +#define VM_COPY_ON_FORK (VM_PFNMAP | VM_MIXEDMAP | VM_UFFD_WP | VM_UFFD_RWP | \ + VM_MAYBE_GUARD) /* * mapping from the currently active vm_flags protection bits (the @@ -1533,7 +1556,7 @@ 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) +static inline bool vma_is_anonymous(const struct vm_area_struct *vma) { return !vma->vm_ops; } @@ -1563,11 +1586,24 @@ static inline bool vma_is_initial_stack(const struct vm_area_struct *vma) vma->vm_end >= vma->vm_mm->start_stack; } -static inline bool vma_is_temporary_stack(const struct vm_area_struct *vma) +static inline bool vma_flags_can_grow(const vma_flags_t *flags) { - int maybe_stack = vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP); + if (vma_flags_test_single_mask(flags, VMA_GROWSUP)) + return true; + if (vma_flags_test(flags, VMA_GROWSDOWN_BIT)) + return true; - if (!maybe_stack) + return false; +} + +static inline bool vma_can_grow(const struct vm_area_struct *vma) +{ + return vma_flags_can_grow(&vma->flags); +} + +static inline bool vma_is_temporary_stack(const struct vm_area_struct *vma) +{ + if (!vma_can_grow(vma)) return false; if ((vma->vm_flags & VM_STACK_INCOMPLETE_SETUP) == @@ -2235,17 +2271,76 @@ void unpin_user_pages(struct page **pages, unsigned long npages); void unpin_user_folio(struct folio *folio, unsigned long npages); void unpin_folios(struct folio **folios, unsigned long nfolios); -static inline bool is_cow_mapping(vm_flags_t flags) +/** + * vma_flags_is_cow_mapping() - Do these VMA flags imply a CoW mapping? + * @flags: The VMA flags to check. + * + * Mappings which could be CoW'd (subject to Copy-On-Write faults) are + * described as CoW mappings. + * + * All mappings backed by anonymous folios (all anonymous mappings and most + * MAP_PRIVATE-file backed ranges) are CoW mappings. + * + * All other mappings (including all MAP_SHARED mappings) are non-CoW. + * + * The criteria are !VMA_SHARED_BIT, VMA_MAYWRITE_BIT. + * + * VMA_MAYWRITE_BIT is checked instead of VMA_WRITE_BIT to account for both + * future mprotect() calls which can render a read-only mapping writable, and + * GUP with FOLL_FORCE (e.g. ptrace) which can CoW a read-only mapping. + * + * - No anonymous mapping can ever clear VMA_MAYWRITE_BIT. + * + * - Writes to anonymous mappings do not immediately result in CoW faults but + * may do so after the process is forked or if a read is followed by a + * write. + * + * - Writes to MAP_PRIVATE file-backed mappings result in CoW faults and may + * do so again after fork. + * + * - MAP_SHARED mappings of a file opened read-only are transformed into + * VMA_MAYSHARE_BIT, !VMA_SHARED_BIT, !VMA_MAYWRITE_BIT mappings, so remain + * non-CoW. + * + * - Drivers may clear VMA_MAYWRITE_BIT but do so at mmap() time and cannot + * mark themselves anonymous. Having cleared this flag it is not valid for + * them to leave the VMA_WRITE_BIT flag set. + * + * As a consequence, the anonymous reverse mapping only tracks CoW mappings. + * + * Returns: true if the flags indicate a CoW mapping, otherwise false. + */ +static inline bool vma_flags_is_cow_mapping(const vma_flags_t *flags) +{ + return vma_flags_test(flags, VMA_MAYWRITE_BIT) && + !vma_flags_test(flags, VMA_SHARED_BIT); +} + +/** + * vma_is_cow_mapping() - Is this VMA a CoW mapping? + * @vma: The VMA to check. + * + * See vma_flags_is_cow_mapping() for details. + * + * Returns: true if the VMA is a CoW mapping, otherwise false. + */ +static inline bool vma_is_cow_mapping(const struct vm_area_struct *vma) { - return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; + return vma_flags_is_cow_mapping(&vma->flags); } +/** + * vma_desc_is_cow_mapping() - Is this VMA descriptor a CoW mapping? + * @desc: The VMA descriptor to check. + * + * See vma_flags_is_cow_mapping() for details. + * + * Returns: true if the VMA descriptor describes a CoW mapping, otherwise + * false. + */ static inline bool vma_desc_is_cow_mapping(struct vm_area_desc *desc) { - const vma_flags_t *flags = &desc->vma_flags; - - return vma_flags_test(flags, VMA_MAYWRITE_BIT) && - !vma_flags_test(flags, VMA_SHARED_BIT); + return vma_flags_is_cow_mapping(&desc->vma_flags); } #ifndef CONFIG_MMU @@ -2286,22 +2381,30 @@ static inline int page_zone_id(struct page *page) } #ifdef NODE_NOT_IN_PAGE_FLAGS -int memdesc_nid(memdesc_flags_t mdf); +int memdesc_nid(const memdesc_flags_t *mdf); #else -static inline int memdesc_nid(memdesc_flags_t mdf) +#ifdef CONFIG_NUMA +static inline int memdesc_nid(const memdesc_flags_t *mdf) +{ + ASSERT_EXCLUSIVE_BITS(mdf->f, NODES_MASK << NODES_PGSHIFT); + return (mdf->f >> NODES_PGSHIFT) & NODES_MASK; +} +#else +static inline int memdesc_nid(const memdesc_flags_t *mdf) { - return (mdf.f >> NODES_PGSHIFT) & NODES_MASK; + return 0; } #endif +#endif static inline int page_to_nid(const struct page *page) { - return memdesc_nid(PF_POISONED_CHECK(page)->flags); + return memdesc_nid(&(PF_POISONED_CHECK(page)->flags)); } static inline int folio_nid(const struct folio *folio) { - return memdesc_nid(folio->flags); + return memdesc_nid(&folio->flags); } #ifdef CONFIG_NUMA_BALANCING @@ -2541,12 +2644,13 @@ static inline void set_page_section(struct page *page, unsigned long section) page->flags.f |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT; } -static inline unsigned long memdesc_section(memdesc_flags_t mdf) +static inline unsigned long memdesc_section(const memdesc_flags_t *mdf) { - return (mdf.f >> SECTIONS_PGSHIFT) & SECTIONS_MASK; + ASSERT_EXCLUSIVE_BITS(mdf->f, SECTIONS_MASK << SECTIONS_PGSHIFT); + return (mdf->f >> SECTIONS_PGSHIFT) & SECTIONS_MASK; } #else /* !SECTION_IN_PAGE_FLAGS */ -static inline unsigned long memdesc_section(memdesc_flags_t mdf) +static inline unsigned long memdesc_section(const memdesc_flags_t *mdf) { return 0; } @@ -3317,6 +3421,11 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen); #define MM_CP_UFFD_WP_RESOLVE (1UL << 3) /* Resolve wp */ #define MM_CP_UFFD_WP_ALL (MM_CP_UFFD_WP | \ MM_CP_UFFD_WP_RESOLVE) +/* Whether this change is for uffd RWP */ +#define MM_CP_UFFD_RWP (1UL << 4) /* do rwp */ +#define MM_CP_UFFD_RWP_RESOLVE (1UL << 5) /* resolve rwp */ +#define MM_CP_UFFD_RWP_ALL (MM_CP_UFFD_RWP | \ + MM_CP_UFFD_RWP_RESOLVE) bool can_change_pte_writable(struct vm_area_struct *vma, unsigned long addr, pte_t pte); @@ -3967,8 +4076,12 @@ extern unsigned long free_reserved_area(void *start, void *end, extern void adjust_managed_page_count(struct page *page, long count); -/* Free the reserved page into the buddy system, so it gets managed. */ -void free_reserved_page(struct page *page); +void free_reserved_pages(struct page *page, unsigned int order); + +static inline void free_reserved_page(struct page *page) +{ + free_reserved_pages(page, 0); +} static inline void mark_page_reserved(struct page *page) { @@ -4042,7 +4155,7 @@ extern int __meminit early_pfn_to_nid(unsigned long pfn); extern void mem_init(void); extern void __init mmap_init(void); -extern void __show_mem(unsigned int flags, nodemask_t *nodemask, int max_zone_idx); +extern void __show_mem(unsigned int flags, const nodemask_t *nodemask, int max_zone_idx); static inline void show_mem(void) { __show_mem(0, NULL, MAX_NR_ZONES - 1); @@ -4052,7 +4165,7 @@ extern void si_meminfo(struct sysinfo * val); extern void si_meminfo_node(struct sysinfo *val, int nid); extern __printf(3, 4) -void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...); +void warn_alloc(gfp_t gfp_mask, const nodemask_t *nodemask, const char *fmt, ...); extern void setup_per_cpu_pageset(void); @@ -4061,44 +4174,46 @@ extern atomic_long_t mmap_pages_allocated; extern int nommu_shrink_inode_mappings(struct inode *, size_t, size_t); /* interval_tree.c */ -void vma_interval_tree_insert(struct vm_area_struct *node, - struct rb_root_cached *root); -void vma_interval_tree_insert_after(struct vm_area_struct *node, +void mapping_rmap_tree_insert(struct vm_area_struct *vma, + struct address_space *mapping); +void mapping_rmap_tree_insert_after(struct vm_area_struct *vma, struct vm_area_struct *prev, - struct rb_root_cached *root); -void vma_interval_tree_remove(struct vm_area_struct *node, - struct rb_root_cached *root); -struct vm_area_struct *vma_interval_tree_subtree_search(struct vm_area_struct *node, - unsigned long start, unsigned long last); -struct vm_area_struct *vma_interval_tree_iter_first(struct rb_root_cached *root, - unsigned long start, unsigned long last); -struct vm_area_struct *vma_interval_tree_iter_next(struct vm_area_struct *node, - unsigned long start, unsigned long last); - -#define vma_interval_tree_foreach(vma, root, start, last) \ - for (vma = vma_interval_tree_iter_first(root, start, last); \ - vma; vma = vma_interval_tree_iter_next(vma, start, last)) - -void anon_vma_interval_tree_insert(struct anon_vma_chain *node, - struct rb_root_cached *root); -void anon_vma_interval_tree_remove(struct anon_vma_chain *node, - struct rb_root_cached *root); + struct address_space *mapping); +void mapping_rmap_tree_remove(struct vm_area_struct *vma, + struct address_space *mapping); +struct vm_area_struct * +mapping_rmap_tree_iter_first(struct address_space *mapping, + pgoff_t pgoff_start, pgoff_t pgoff_last); +struct vm_area_struct * +mapping_rmap_tree_iter_next(struct vm_area_struct *vma, + pgoff_t pgoff_start, pgoff_t pgoff_last); + +#define mapping_rmap_tree_foreach(vma, mapping, pgoff_start, pgoff_last) \ + for (vma = mapping_rmap_tree_iter_first(mapping, pgoff_start, \ + pgoff_last); \ + vma; vma = mapping_rmap_tree_iter_next(vma, pgoff_start, \ + pgoff_last)) + +void anon_rmap_tree_insert(struct anon_vma_chain *avc, + struct anon_vma *anon_vma); +void anon_rmap_tree_remove(struct anon_vma_chain *avc, + struct anon_vma *anon_vma); +struct anon_vma_chain * +anon_rmap_tree_iter_first(struct anon_vma *anon_vma, + pgoff_t pgoff_start, pgoff_t pgoff_last); struct anon_vma_chain * -anon_vma_interval_tree_iter_first(struct rb_root_cached *root, - unsigned long start, unsigned long last); -struct anon_vma_chain *anon_vma_interval_tree_iter_next( - struct anon_vma_chain *node, unsigned long start, unsigned long last); +anon_rmap_tree_iter_next(struct anon_vma_chain *avc, + pgoff_t pgoff_start, pgoff_t pgoff_last); #ifdef CONFIG_DEBUG_VM_RB -void anon_vma_interval_tree_verify(struct anon_vma_chain *node); +void anon_rmap_tree_verify(struct anon_vma_chain *avc); #endif -#define anon_vma_interval_tree_foreach(avc, root, start, last) \ - for (avc = anon_vma_interval_tree_iter_first(root, start, last); \ - avc; avc = anon_vma_interval_tree_iter_next(avc, start, last)) +#define anon_rmap_tree_foreach(avc, anon_vma, pgoff_start, pgoff_last) \ + for (avc = anon_rmap_tree_iter_first(anon_vma, pgoff_start, pgoff_last); \ + avc; avc = anon_rmap_tree_iter_next(avc, pgoff_start, pgoff_last)) /* mmap.c */ extern int __vm_enough_memory(const struct mm_struct *mm, long pages, int cap_sys_admin); -extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *); extern void exit_mmap(struct mm_struct *); bool mmap_read_lock_maybe_expand(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, bool write); @@ -4139,18 +4254,20 @@ unsigned long randomize_page(unsigned long start, unsigned long range); unsigned long __get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, - unsigned long pgoff, unsigned long flags, vm_flags_t vm_flags); + unsigned long pgoff, unsigned long flags, + vma_flags_t vma_flags); static inline unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { - return __get_unmapped_area(file, addr, len, pgoff, flags, 0); + return __get_unmapped_area(file, addr, len, pgoff, flags, + EMPTY_VMA_FLAGS); } -extern unsigned long do_mmap(struct file *file, unsigned long addr, +unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, - vm_flags_t vm_flags, unsigned long pgoff, unsigned long *populate, + vma_flags_t vma_flags, unsigned long pgoff, unsigned long *populate, struct list_head *uf); extern int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm, unsigned long start, size_t len, struct list_head *uf, @@ -4278,9 +4395,120 @@ static inline unsigned long vma_pages(const struct vm_area_struct *vma) return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; } -static inline unsigned long vma_last_pgoff(struct vm_area_struct *vma) +/** + * vma_start_pgoff() - Get the page offset of the start of @vma + * @vma: The VMA whose page offset is required. + * + * If the VMA is file-backed, this is the page offset into the file. + * + * If @vma is anonymous, this is the virtual page offset of the start of the + * VMA - if unfaulted, then vma->vm_start >> PAGE_SHIFT, if faulted then the + * virtual page offset at the time of first fault. + * + * If @vma is a MAP_PRIVATE file-backed mapping, then this returns the + * page offset within the file. + * + * Edge cases: nommu does not abide by these, MAP_PRIVATE-/dev/zero satisfies + * vma_is_anonymous() but has file-backed page offset, and MAP_PRIVATE-pfnmap + * regions have their page offset set to the first PFN in the range. + * + * Returns: The page offset of the start of @vma. + */ +static inline pgoff_t vma_start_pgoff(const struct vm_area_struct *vma) +{ + return vma->vm_pgoff; +} + +/** + * vma_end_pgoff() - Get the page offset of the exclusive end of @vma + * @vma: The VMA whose end page offset is required. + * + * This returns the exclusive end page offset of @vma, which is useful for + * expressing page offset ranges. + * + * See the description of vma_start_pgoff() for a description of VMA page + * offsets. + * + * Returns: The exclusive end page offset of @vma. + */ +static inline pgoff_t vma_end_pgoff(const struct vm_area_struct *vma) +{ + return vma_start_pgoff(vma) + vma_pages(vma); +} + +/** + * vma_last_pgoff() - Get the page offset of the last page in @vma + * @vma: The VMA whose last page offset is required. + * + * This returns the last page offset contained within @vma. + * + * See the description of vma_start_pgoff() for a description of VMA page + * offsets. + * + * Returns: The last page offset of @vma. + */ +static inline pgoff_t vma_last_pgoff(const struct vm_area_struct *vma) { - return vma->vm_pgoff + vma_pages(vma) - 1; + return vma_end_pgoff(vma) - 1; +} + +/** + * vma_start_anon_pgoff() - Get the anonymous page offset of the start of @vma + * @vma: The VMA whose anonymous page offset is required. + * + * If unfaulted, then this is vma->vm_start >> PAGE_SHIFT, if faulted then the + * anonymous page offset at the time of first fault. + * + * If the VMA is anonymous, this returns the same value as vma_start_pgoff(). + * + * This value is used for tracking MAP_PRIVATE file-backed mappings by their + * anonymous page offset. + * + * Returns: The anonymous page offset of the start of @vma. + */ +static inline pgoff_t vma_start_anon_pgoff(const struct vm_area_struct *vma) +{ + pgoff_t pgoff = 0; + +#ifdef CONFIG_64BIT + pgoff += vma->__vm_anon_pgoff_hi; + pgoff <<= 32; +#endif + pgoff += vma->__vm_anon_pgoff_lo; + return pgoff; +} + +/** + * vma_end_anon_pgoff() - Get the anonymous page offset of the exclusive end of + * @vma. + * @vma: The VMA whose end anonymous page offset is required. + * + * This returns the anonymous exclusive end page offset of @vma, which is useful + * for expressing page offset ranges. + * + * See the description of vma_start_anon_pgoff() for a description of VMA + * anonymous page offsets. + * + * Returns: The exclusive end anonymous page offset of @vma. + */ +static inline pgoff_t vma_end_anon_pgoff(const struct vm_area_struct *vma) +{ + return vma_start_anon_pgoff(vma) + vma_pages(vma); +} + +/** + * vma_last_anon_pgoff() - Get the anonymous page offset of the last page in + * @vma. + * @vma: The VMA whose last anonymous page offset is required. + * + * See the description of vma_start_anon_pgoff() for a description of VMA + * anonymous page offsets. + * + * Returns: The last anonymous page offset of @vma. + */ +static inline pgoff_t vma_last_anon_pgoff(const struct vm_area_struct *vma) +{ + return vma_end_anon_pgoff(vma) - 1; } static inline unsigned long vma_desc_size(const struct vm_area_desc *desc) @@ -4497,26 +4725,35 @@ static inline bool range_in_vma_desc(const struct vm_area_desc *desc, #ifdef CONFIG_MMU pgprot_t vm_get_page_prot(vm_flags_t vm_flags); -static inline pgprot_t vma_get_page_prot(vma_flags_t vma_flags) +static inline pgprot_t vma_flags_to_page_prot(vma_flags_t vma_flags) { const vm_flags_t vm_flags = vma_flags_to_legacy(vma_flags); return vm_get_page_prot(vm_flags); } +static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma) +{ + return vma_flags_to_page_prot(vma->flags); +} + void vma_set_page_prot(struct vm_area_struct *vma); #else static inline pgprot_t vm_get_page_prot(vm_flags_t vm_flags) { return __pgprot(0); } -static inline pgprot_t vma_get_page_prot(vma_flags_t vma_flags) +static inline pgprot_t vma_flags_to_page_prot(vma_flags_t vma_flags) +{ + return __pgprot(0); +} +static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma) { return __pgprot(0); } static inline void vma_set_page_prot(struct vm_area_struct *vma) { - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + vma->vm_page_prot = vma_get_page_prot(vma); } #endif @@ -4625,12 +4862,26 @@ static inline int vm_fault_to_errno(vm_fault_t vm_fault, int foll_flags) /* * Indicates whether GUP can follow a PROT_NONE mapped page, or whether - * a (NUMA hinting) fault is required. + * a (NUMA hinting or userfaultfd RWP) fault is required. */ static inline bool gup_can_follow_protnone(const struct vm_area_struct *vma, unsigned int flags) { /* + * VM_UFFD_RWP uses protnone as an access-tracking marker, not for + * NUMA hinting. GUP must always take a fault so the access is + * delivered to userfaultfd, regardless of FOLL_HONOR_NUMA_FAULT. + * + * Only do so while the VMA is accessible. If it has been made + * inaccessible (e.g. mprotect(PROT_NONE)), fall through to the guard + * below: forcing a fault there would loop, as handle_mm_fault() makes + * no progress on protnone in an inaccessible VMA, and the access is + * denied regardless of RWP anyway. + */ + if (vma_test_single_mask(vma, VMA_UFFD_RWP) && vma_is_accessible(vma)) + return false; + + /* * If callers don't want to honor NUMA hinting faults, no need to * determine if we would actually have to trigger a NUMA hinting fault. */ @@ -5158,13 +5409,9 @@ int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t * int reserve_mem_release_by_name(const char *name); #ifdef CONFIG_64BIT -int do_mseal(unsigned long start, size_t len_in, unsigned long flags); +void mseal_mmap_page_zero(void); #else -static inline int do_mseal(unsigned long start, size_t len_in, unsigned long flags) -{ - /* noop on 32 bit */ - return 0; -} +static inline void mseal_mmap_page_zero(void) {} #endif /* diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index a8430a7ae054..621c8653d8f7 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -566,59 +566,6 @@ static inline pte_marker copy_pte_marker( return dstm; } -/* - * If this pte is wr-protected by uffd-wp in any form, arm the special pte to - * replace a none pte. NOTE! This should only be called when *pte is already - * cleared so we will never accidentally replace something valuable. Meanwhile - * none pte also means we are not demoting the pte so tlb flushed is not needed. - * E.g., when pte cleared the caller should have taken care of the tlb flush. - * - * Must be called with pgtable lock held so that no thread will see the none - * pte, and if they see it, they'll fault and serialize at the pgtable lock. - * - * Returns true if an uffd-wp pte was installed, false otherwise. - */ -static inline bool -pte_install_uffd_wp_if_needed(struct vm_area_struct *vma, unsigned long addr, - pte_t *pte, pte_t pteval) -{ - bool arm_uffd_pte = false; - - if (!uffd_supports_wp_marker()) - return false; - - /* The current status of the pte should be "cleared" before calling */ - WARN_ON_ONCE(!pte_none(ptep_get(pte))); - - /* - * NOTE: userfaultfd_wp_unpopulated() doesn't need this whole - * thing, because when zapping either it means it's dropping the - * page, or in TTU where the present pte will be quickly replaced - * with a swap pte. There's no way of leaking the bit. - */ - if (vma_is_anonymous(vma) || !userfaultfd_wp(vma)) - return false; - - /* A uffd-wp wr-protected normal pte */ - if (unlikely(pte_present(pteval) && pte_uffd_wp(pteval))) - arm_uffd_pte = true; - - /* - * A uffd-wp wr-protected swap pte. Note: this should even cover an - * existing pte marker with uffd-wp bit set. - */ - if (unlikely(pte_swp_uffd_wp_any(pteval))) - arm_uffd_pte = true; - - if (unlikely(arm_uffd_pte)) { - set_pte_at(vma->vm_mm, addr, pte, - make_pte_marker(PTE_MARKER_UFFD_WP)); - return true; - } - - return false; -} - static inline bool vma_has_recency(const struct vm_area_struct *vma) { if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)) @@ -650,7 +597,7 @@ static inline bool vma_has_recency(const struct vm_area_struct *vma) static inline size_t num_pages_contiguous(struct page **pages, size_t nr_pages) { struct page *cur_page = pages[0]; - unsigned long section = memdesc_section(cur_page->flags); + unsigned long section = memdesc_section(&cur_page->flags); size_t i; for (i = 1; i < nr_pages; i++) { @@ -660,7 +607,7 @@ static inline size_t num_pages_contiguous(struct page **pages, size_t nr_pages) * In unproblematic kernel configs, page_to_section() == 0 and * the whole check will get optimized out. */ - if (memdesc_section(cur_page->flags) != section) + if (memdesc_section(&cur_page->flags) != section) break; } diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index b18c2b2e7d2c..6d815f6440c9 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -368,6 +368,8 @@ typedef unsigned short mm_id_t; * dax_associate_entry. * @private: Filesystem per-folio data (see folio_attach_private()). * @swap: Used for swp_entry_t if folio_test_swapcache(). + * @migrate_info: Stores migration state (anon_vma pointer and + * FOLIO_WAS_* markers). * @_mapcount: Do not access this member directly. Use folio_mapcount() to * find out how many times this folio is mapped by userspace. * @_refcount: Do not access this member directly. Use folio_ref_count() @@ -427,6 +429,7 @@ struct folio { union { void *private; swp_entry_t swap; + unsigned long migrate_info; }; atomic_t _mapcount; atomic_t _refcount; @@ -965,6 +968,11 @@ struct vm_area_struct { unsigned int vm_lock_seq; #endif /* + * Low 32-bits of anonymous page offset. + * See vma_start_anon_pgoff() comment for details. + */ + unsigned int __vm_anon_pgoff_lo; + /* * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma * list, after a COW of one of the file pages. A MAP_SHARED vma * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack @@ -1039,6 +1047,13 @@ struct vm_area_struct { struct lockdep_map vmlock_dep_map; #endif #endif +#ifdef CONFIG_64BIT + /* + * High 32-bits of anonymous page offset. + * See vma_start_anon_pgoff() comment for details. + */ + unsigned int __vm_anon_pgoff_hi; +#endif /* * For areas with an address space and backing store, * linkage into the address_space->i_mmap interval tree. @@ -1703,20 +1718,20 @@ enum vm_fault_reason { VM_FAULT_SIGSEGV | VM_FAULT_HWPOISON | \ VM_FAULT_HWPOISON_LARGE | VM_FAULT_FALLBACK) -#define VM_FAULT_RESULT_TRACE \ - { VM_FAULT_OOM, "OOM" }, \ - { VM_FAULT_SIGBUS, "SIGBUS" }, \ - { VM_FAULT_MAJOR, "MAJOR" }, \ - { VM_FAULT_HWPOISON, "HWPOISON" }, \ - { VM_FAULT_HWPOISON_LARGE, "HWPOISON_LARGE" }, \ - { VM_FAULT_SIGSEGV, "SIGSEGV" }, \ - { VM_FAULT_NOPAGE, "NOPAGE" }, \ - { VM_FAULT_LOCKED, "LOCKED" }, \ - { VM_FAULT_RETRY, "RETRY" }, \ - { VM_FAULT_FALLBACK, "FALLBACK" }, \ - { VM_FAULT_DONE_COW, "DONE_COW" }, \ - { VM_FAULT_NEEDDSYNC, "NEEDDSYNC" }, \ - { VM_FAULT_COMPLETED, "COMPLETED" } +#define VM_FAULT_RESULT_TRACE \ + { (__force u32)VM_FAULT_OOM, "OOM" }, \ + { (__force u32)VM_FAULT_SIGBUS, "SIGBUS" }, \ + { (__force u32)VM_FAULT_MAJOR, "MAJOR" }, \ + { (__force u32)VM_FAULT_HWPOISON, "HWPOISON" }, \ + { (__force u32)VM_FAULT_HWPOISON_LARGE, "HWPOISON_LARGE" }, \ + { (__force u32)VM_FAULT_SIGSEGV, "SIGSEGV" }, \ + { (__force u32)VM_FAULT_NOPAGE, "NOPAGE" }, \ + { (__force u32)VM_FAULT_LOCKED, "LOCKED" }, \ + { (__force u32)VM_FAULT_RETRY, "RETRY" }, \ + { (__force u32)VM_FAULT_FALLBACK, "FALLBACK" }, \ + { (__force u32)VM_FAULT_DONE_COW, "DONE_COW" }, \ + { (__force u32)VM_FAULT_NEEDDSYNC, "NEEDDSYNC" }, \ + { (__force u32)VM_FAULT_COMPLETED, "COMPLETED" } struct vm_special_mapping { const char *name; /* The name, e.g. "[vdso]". */ diff --git a/include/linux/mmap_lock.h b/include/linux/mmap_lock.h index 04b8f61ece5d..bec0eab6ef03 100644 --- a/include/linux/mmap_lock.h +++ b/include/linux/mmap_lock.h @@ -506,6 +506,8 @@ static inline __must_check int vma_start_write_killable(struct vm_area_struct *vma) { return 0; } static inline void vma_assert_write_locked(struct vm_area_struct *vma) { mmap_assert_write_locked(vma->vm_mm); } +static inline bool vma_is_attached(struct vm_area_struct *vma) + { return true; } static inline void vma_assert_attached(struct vm_area_struct *vma) {} static inline void vma_assert_detached(struct vm_area_struct *vma) {} static inline void vma_mark_attached(struct vm_area_struct *vma) {} @@ -530,6 +532,12 @@ static inline void vma_assert_stabilised(struct vm_area_struct *vma) #endif /* CONFIG_PER_VMA_LOCK */ +static inline void vma_assert_can_modify(struct vm_area_struct *vma) +{ + if (vma_is_attached(vma)) + vma_assert_write_locked(vma); +} + static inline void mmap_write_lock(struct mm_struct *mm) { __mmap_lock_trace_start_locking(mm, true); @@ -621,6 +629,7 @@ static inline void mmap_read_unlock(struct mm_struct *mm) DEFINE_GUARD(mmap_read_lock, struct mm_struct *, mmap_read_lock(_T), mmap_read_unlock(_T)) +DEFINE_GUARD_COND(mmap_read_lock, _try, mmap_read_trylock(_T)) static inline void mmap_read_unlock_non_owner(struct mm_struct *mm) { diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index 4534bf462aac..5d63a6465b0d 100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -9,7 +9,7 @@ #define LINUX_MMC_SDIO_FUNC_H #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/sdio.h> #include <linux/mmc/pm.h> diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index 0685dd717e85..afae93f6f245 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -117,7 +117,11 @@ #define SDIO_VENDOR_ID_MICROCHIP_WILC 0x0296 #define SDIO_DEVICE_ID_MICROCHIP_WILC1000 0x5347 +#define SDIO_VENDOR_ID_MORSEMICRO 0x325b +#define SDIO_DEVICE_ID_MORSEMICRO_MM8108 0x0809 + #define SDIO_VENDOR_ID_NXP 0x0471 +#define SDIO_DEVICE_ID_NXP_IW61X_BASE 0x0204 #define SDIO_DEVICE_ID_NXP_IW61X 0x0205 #define SDIO_VENDOR_ID_REALTEK 0x024c diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index ca2712187147..94f9c3ff5416 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -2,7 +2,7 @@ #ifndef _LINUX_MMZONE_H #define _LINUX_MMZONE_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #ifndef __GENERATING_BOUNDS_H #include <linux/spinlock.h> @@ -323,6 +323,8 @@ enum node_stat_item { PGSCAN_PROACTIVE, PGSCAN_ANON, PGSCAN_FILE, + PGROTATE_ANON, + PGROTATE_FILE, PGREFILL, #ifdef CONFIG_HUGETLB_PAGE NR_HUGETLB, @@ -755,6 +757,12 @@ void lru_gen_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, #endif /* CONFIG_LRU_GEN */ +struct lru_cost { + unsigned long count; + unsigned long last_rotated; + unsigned long last_io; +}; + struct lruvec { struct list_head lists[NR_LRU_LISTS]; /* per lruvec lru_lock for memcg */ @@ -763,9 +771,12 @@ struct lruvec { * These track the cost of reclaiming one LRU - file or anon - * over the other. As the observed cost of reclaiming one LRU * increases, the reclaim scan balance tips toward the other. + * Updated and decayed at prepare_scan_control() time; cost_lock + * serialises that update. */ - unsigned long anon_cost; - unsigned long file_cost; + struct lru_cost cost[ANON_AND_FILE]; + /* Protects cost[]. */ + spinlock_t cost_lock; /* Non-resident age, driven by LRU movement */ atomic_long_t nonresident_age; /* Refaults at the time of last reclaim cycle */ @@ -1272,31 +1283,33 @@ static inline bool zone_is_empty(const struct zone *zone) #define KASAN_TAG_MASK ((1UL << KASAN_TAG_WIDTH) - 1) #define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1) -static inline enum zone_type memdesc_zonenum(memdesc_flags_t flags) +static inline enum zone_type memdesc_zonenum(const memdesc_flags_t *flags) { - ASSERT_EXCLUSIVE_BITS(flags.f, ZONES_MASK << ZONES_PGSHIFT); - return (flags.f >> ZONES_PGSHIFT) & ZONES_MASK; +#if ZONES_WIDTH != 0 + ASSERT_EXCLUSIVE_BITS(flags->f, ZONES_MASK << ZONES_PGSHIFT); +#endif + return (flags->f >> ZONES_PGSHIFT) & ZONES_MASK; } static inline enum zone_type page_zonenum(const struct page *page) { - return memdesc_zonenum(page->flags); + return memdesc_zonenum(&page->flags); } static inline enum zone_type folio_zonenum(const struct folio *folio) { - return memdesc_zonenum(folio->flags); + return memdesc_zonenum(&folio->flags); } #ifdef CONFIG_ZONE_DEVICE -static inline bool memdesc_is_zone_device(memdesc_flags_t mdf) +static inline bool memdesc_is_zone_device(const memdesc_flags_t *mdf) { return memdesc_zonenum(mdf) == ZONE_DEVICE; } static inline struct dev_pagemap *page_pgmap(const struct page *page) { - VM_WARN_ON_ONCE_PAGE(!memdesc_is_zone_device(page->flags), page); + VM_WARN_ON_ONCE_PAGE(!memdesc_is_zone_device(&page->flags), page); return page_folio(page)->pgmap; } @@ -1311,9 +1324,9 @@ static inline struct dev_pagemap *page_pgmap(const struct page *page) static inline bool zone_device_pages_have_same_pgmap(const struct page *a, const struct page *b) { - if (memdesc_is_zone_device(a->flags) != memdesc_is_zone_device(b->flags)) + if (memdesc_is_zone_device(&a->flags) != memdesc_is_zone_device(&b->flags)) return false; - if (!memdesc_is_zone_device(a->flags)) + if (!memdesc_is_zone_device(&a->flags)) return true; return page_pgmap(a) == page_pgmap(b); } @@ -1321,7 +1334,7 @@ static inline bool zone_device_pages_have_same_pgmap(const struct page *a, extern void memmap_init_zone_device(struct zone *, unsigned long, unsigned long, struct dev_pagemap *); #else -static inline bool memdesc_is_zone_device(memdesc_flags_t mdf) +static inline bool memdesc_is_zone_device(const memdesc_flags_t *mdf) { return false; } @@ -1338,12 +1351,12 @@ static inline struct dev_pagemap *page_pgmap(const struct page *page) static inline bool is_zone_device_page(const struct page *page) { - return memdesc_is_zone_device(page->flags); + return memdesc_is_zone_device(&page->flags); } static inline bool folio_is_zone_device(const struct folio *folio) { - return memdesc_is_zone_device(folio->flags); + return memdesc_is_zone_device(&folio->flags); } static inline bool is_zone_movable_page(const struct page *page) @@ -1815,7 +1828,7 @@ static inline int zonelist_node_idx(const struct zoneref *zoneref) struct zoneref *__next_zones_zonelist(struct zoneref *z, enum zone_type highest_zoneidx, - nodemask_t *nodes); + const nodemask_t *nodes); /** * next_zones_zonelist - Returns the next zone at or below highest_zoneidx within the allowed nodemask using a cursor within a zonelist as a starting point @@ -1834,7 +1847,7 @@ struct zoneref *__next_zones_zonelist(struct zoneref *z, */ static __always_inline struct zoneref *next_zones_zonelist(struct zoneref *z, enum zone_type highest_zoneidx, - nodemask_t *nodes) + const nodemask_t *nodes) { if (likely(!nodes && zonelist_zone_idx(z) <= highest_zoneidx)) return z; @@ -1860,7 +1873,7 @@ static __always_inline struct zoneref *next_zones_zonelist(struct zoneref *z, */ static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist, enum zone_type highest_zoneidx, - nodemask_t *nodes) + const nodemask_t *nodes) { return next_zones_zonelist(zonelist->_zonerefs, highest_zoneidx, nodes); @@ -2056,7 +2069,6 @@ static inline struct mem_section *__nr_to_section(unsigned long nr) #endif return &mem_section[root][nr & SECTION_ROOT_MASK]; } -extern size_t mem_section_usage_size(void); /* * We use the lower bits of the mem_map pointer to store a little bit of @@ -2156,8 +2168,6 @@ static inline int preinited_vmemmap_section(const struct mem_section *section) } void sparse_vmemmap_init_nid_early(int nid); -void sparse_vmemmap_init_nid_late(int nid); - #else static inline int preinited_vmemmap_section(const struct mem_section *section) { @@ -2166,10 +2176,6 @@ static inline int preinited_vmemmap_section(const struct mem_section *section) static inline void sparse_vmemmap_init_nid_early(int nid) { } - -static inline void sparse_vmemmap_init_nid_late(int nid) -{ -} #endif static inline int online_section_nr(unsigned long nr) @@ -2374,7 +2380,6 @@ static inline unsigned long next_present_section_nr(unsigned long section_nr) #else #define sparse_vmemmap_init_nid_early(_nid) do {} while (0) -#define sparse_vmemmap_init_nid_late(_nid) do {} while (0) #define pfn_in_present_section pfn_valid #endif /* CONFIG_SPARSEMEM */ @@ -2389,5 +2394,5 @@ static inline unsigned long next_present_section_nr(unsigned long section_nr) #endif #endif /* !__GENERATING_BOUNDS.H */ -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #endif /* _LINUX_MMZONE_H */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 3b0c9a251a2e..a397213bedac 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -9,706 +9,65 @@ #define LINUX_MOD_DEVICETABLE_H #ifdef __KERNEL__ -#include <linux/mei.h> #include <linux/types.h> -#include <linux/uuid.h> -typedef unsigned long kernel_ulong_t; #endif -#define PCI_ANY_ID (~0) - -enum { - PCI_ID_F_VFIO_DRIVER_OVERRIDE = 1, -}; - -/** - * struct pci_device_id - PCI device ID structure - * @vendor: Vendor ID to match (or PCI_ANY_ID) - * @device: Device ID to match (or PCI_ANY_ID) - * @subvendor: Subsystem vendor ID to match (or PCI_ANY_ID) - * @subdevice: Subsystem device ID to match (or PCI_ANY_ID) - * @class: Device class, subclass, and "interface" to match. - * See Appendix D of the PCI Local Bus Spec or - * include/linux/pci_ids.h for a full list of classes. - * Most drivers do not need to specify class/class_mask - * as vendor/device is normally sufficient. - * @class_mask: Limit which sub-fields of the class field are compared. - * See drivers/scsi/sym53c8xx_2/ for example of usage. - * @driver_data: Data private to the driver. - * Most drivers don't need to use driver_data field. - * Best practice is to use driver_data as an index - * into a static list of equivalent device types, - * instead of using it as a pointer. - * @override_only: Match only when dev->driver_override is this driver. - */ -struct pci_device_id { - __u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/ - __u32 subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ - __u32 class, class_mask; /* (class,subclass,prog-if) triplet */ - kernel_ulong_t driver_data; /* Data private to the driver */ - __u32 override_only; -}; - - -#define IEEE1394_MATCH_VENDOR_ID 0x0001 -#define IEEE1394_MATCH_MODEL_ID 0x0002 -#define IEEE1394_MATCH_SPECIFIER_ID 0x0004 -#define IEEE1394_MATCH_VERSION 0x0008 - -struct ieee1394_device_id { - __u32 match_flags; - __u32 vendor_id; - __u32 model_id; - __u32 specifier_id; - __u32 version; - union { - kernel_ulong_t driver_data; - const void *driver_data_ptr; - }; -}; - - -/* - * Device table entry for "new style" table-driven USB drivers. - * User mode code can read these tables to choose which modules to load. - * Declare the table as a MODULE_DEVICE_TABLE. - * - * A probe() parameter will point to a matching entry from this table. - * Use the driver_info field for each match to hold information tied - * to that match: device quirks, etc. - * - * Terminate the driver's table with an all-zeroes entry. - * Use the flag values to control which fields are compared. - */ - -/** - * struct usb_device_id - identifies USB devices for probing and hotplugging - * @match_flags: Bit mask controlling which of the other fields are used to - * match against new devices. Any field except for driver_info may be - * used, although some only make sense in conjunction with other fields. - * This is usually set by a USB_DEVICE_*() macro, which sets all - * other fields in this structure except for driver_info. - * @idVendor: USB vendor ID for a device; numbers are assigned - * by the USB forum to its members. - * @idProduct: Vendor-assigned product ID. - * @bcdDevice_lo: Low end of range of vendor-assigned product version numbers. - * This is also used to identify individual product versions, for - * a range consisting of a single device. - * @bcdDevice_hi: High end of version number range. The range of product - * versions is inclusive. - * @bDeviceClass: Class of device; numbers are assigned - * by the USB forum. Products may choose to implement classes, - * or be vendor-specific. Device classes specify behavior of all - * the interfaces on a device. - * @bDeviceSubClass: Subclass of device; associated with bDeviceClass. - * @bDeviceProtocol: Protocol of device; associated with bDeviceClass. - * @bInterfaceClass: Class of interface; numbers are assigned - * by the USB forum. Products may choose to implement classes, - * or be vendor-specific. Interface classes specify behavior only - * of a given interface; other interfaces may support other classes. - * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass. - * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass. - * @bInterfaceNumber: Number of interface; composite devices may use - * fixed interface numbers to differentiate between vendor-specific - * interfaces. - * @driver_info: Holds information used by the driver. Usually it holds - * a pointer to a descriptor understood by the driver, or perhaps - * device flags. - * - * In most cases, drivers will create a table of device IDs by using - * USB_DEVICE(), or similar macros designed for that purpose. - * They will then export it to userspace using MODULE_DEVICE_TABLE(), - * and provide it to the USB core through their usb_driver structure. - * - * See the usb_match_id() function for information about how matches are - * performed. Briefly, you will normally use one of several macros to help - * construct these entries. Each entry you provide will either identify - * one or more specific products, or will identify a class of products - * which have agreed to behave the same. You should put the more specific - * matches towards the beginning of your table, so that driver_info can - * record quirks of specific products. - */ -struct usb_device_id { - /* which fields to match against? */ - __u16 match_flags; - - /* Used for product specific matches; range is inclusive */ - __u16 idVendor; - __u16 idProduct; - __u16 bcdDevice_lo; - __u16 bcdDevice_hi; - - /* Used for device class matches */ - __u8 bDeviceClass; - __u8 bDeviceSubClass; - __u8 bDeviceProtocol; - - /* Used for interface class matches */ - __u8 bInterfaceClass; - __u8 bInterfaceSubClass; - __u8 bInterfaceProtocol; - - /* Used for vendor-specific interface matches */ - __u8 bInterfaceNumber; - - /* not matched against */ - kernel_ulong_t driver_info - __attribute__((aligned(sizeof(kernel_ulong_t)))); -}; - -/* Some useful macros to use to create struct usb_device_id */ -#define USB_DEVICE_ID_MATCH_VENDOR 0x0001 -#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 -#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 -#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 -#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 -#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 -#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 -#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 -#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 -#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 -#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400 - -#define HID_ANY_ID (~0) -#define HID_BUS_ANY 0xffff -#define HID_GROUP_ANY 0x0000 - -struct hid_device_id { - __u16 bus; - __u16 group; - __u32 vendor; - __u32 product; - kernel_ulong_t driver_data; -}; - -/* s390 CCW devices */ -struct ccw_device_id { - __u16 match_flags; /* which fields to match against */ - - __u16 cu_type; /* control unit type */ - __u16 dev_type; /* device type */ - __u8 cu_model; /* control unit model */ - __u8 dev_model; /* device model */ - - kernel_ulong_t driver_info; -}; - -#define CCW_DEVICE_ID_MATCH_CU_TYPE 0x01 -#define CCW_DEVICE_ID_MATCH_CU_MODEL 0x02 -#define CCW_DEVICE_ID_MATCH_DEVICE_TYPE 0x04 -#define CCW_DEVICE_ID_MATCH_DEVICE_MODEL 0x08 - -/* s390 AP bus devices */ -struct ap_device_id { - __u16 match_flags; /* which fields to match against */ - __u8 dev_type; /* device type */ - kernel_ulong_t driver_info; -}; - -#define AP_DEVICE_ID_MATCH_CARD_TYPE 0x01 -#define AP_DEVICE_ID_MATCH_QUEUE_TYPE 0x02 - -/* s390 css bus devices (subchannels) */ -struct css_device_id { - __u8 match_flags; - __u8 type; /* subchannel type */ - kernel_ulong_t driver_data; -}; - -#define ACPI_ID_LEN 16 - -struct acpi_device_id { - __u8 id[ACPI_ID_LEN]; - kernel_ulong_t driver_data; - __u32 cls; - __u32 cls_msk; -}; - -/** - * ACPI_DEVICE_CLASS - macro used to describe an ACPI device with - * the PCI-defined class-code information - * - * @_cls : the class, subclass, prog-if triple for this device - * @_msk : the class mask for this device - * - * This macro is used to create a struct acpi_device_id that matches a - * specific PCI class. The .id and .driver_data fields will be left - * initialized with the default value. - */ -#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk), - -#define PNP_ID_LEN 8 -#define PNP_MAX_DEVICES 8 - -struct pnp_device_id { - __u8 id[PNP_ID_LEN]; - kernel_ulong_t driver_data; -}; - -struct pnp_card_device_id { - __u8 id[PNP_ID_LEN]; - kernel_ulong_t driver_data; - struct { - __u8 id[PNP_ID_LEN]; - } devs[PNP_MAX_DEVICES]; -}; - - -#define SERIO_ANY 0xff - -struct serio_device_id { - __u8 type; - __u8 extra; - __u8 id; - __u8 proto; -}; - -struct hda_device_id { - __u32 vendor_id; - __u32 rev_id; - __u8 api_version; - const char *name; - unsigned long driver_data; -}; - -struct sdw_device_id { - __u16 mfg_id; - __u16 part_id; - __u8 sdw_version; - __u8 class_id; - kernel_ulong_t driver_data; -}; - -/* - * Struct used for matching a device - */ -struct of_device_id { - char name[32]; - char type[32]; - char compatible[128]; - const void *data; -}; - -/* VIO */ -struct vio_device_id { - char type[32]; - char compat[32]; -}; - -/* PCMCIA */ - -struct pcmcia_device_id { - __u16 match_flags; - - __u16 manf_id; - __u16 card_id; - - __u8 func_id; - - /* for real multi-function devices */ - __u8 function; - - /* for pseudo multi-function devices */ - __u8 device_no; - - __u32 prod_id_hash[4]; - - /* not matched against in kernelspace */ - const char * prod_id[4]; - - /* not matched against */ - kernel_ulong_t driver_info; - char * cisfile; -}; - -#define PCMCIA_DEV_ID_MATCH_MANF_ID 0x0001 -#define PCMCIA_DEV_ID_MATCH_CARD_ID 0x0002 -#define PCMCIA_DEV_ID_MATCH_FUNC_ID 0x0004 -#define PCMCIA_DEV_ID_MATCH_FUNCTION 0x0008 -#define PCMCIA_DEV_ID_MATCH_PROD_ID1 0x0010 -#define PCMCIA_DEV_ID_MATCH_PROD_ID2 0x0020 -#define PCMCIA_DEV_ID_MATCH_PROD_ID3 0x0040 -#define PCMCIA_DEV_ID_MATCH_PROD_ID4 0x0080 -#define PCMCIA_DEV_ID_MATCH_DEVICE_NO 0x0100 -#define PCMCIA_DEV_ID_MATCH_FAKE_CIS 0x0200 -#define PCMCIA_DEV_ID_MATCH_ANONYMOUS 0x0400 - -/* Input */ -#define INPUT_DEVICE_ID_EV_MAX 0x1f -#define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71 -#define INPUT_DEVICE_ID_KEY_MAX 0x2ff -#define INPUT_DEVICE_ID_REL_MAX 0x0f -#define INPUT_DEVICE_ID_ABS_MAX 0x3f -#define INPUT_DEVICE_ID_MSC_MAX 0x07 -#define INPUT_DEVICE_ID_LED_MAX 0x0f -#define INPUT_DEVICE_ID_SND_MAX 0x07 -#define INPUT_DEVICE_ID_FF_MAX 0x7f -#define INPUT_DEVICE_ID_SW_MAX 0x11 -#define INPUT_DEVICE_ID_PROP_MAX 0x1f - -#define INPUT_DEVICE_ID_MATCH_BUS 1 -#define INPUT_DEVICE_ID_MATCH_VENDOR 2 -#define INPUT_DEVICE_ID_MATCH_PRODUCT 4 -#define INPUT_DEVICE_ID_MATCH_VERSION 8 - -#define INPUT_DEVICE_ID_MATCH_EVBIT 0x0010 -#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x0020 -#define INPUT_DEVICE_ID_MATCH_RELBIT 0x0040 -#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x0080 -#define INPUT_DEVICE_ID_MATCH_MSCIT 0x0100 -#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x0200 -#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400 -#define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800 -#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 -#define INPUT_DEVICE_ID_MATCH_PROPBIT 0x2000 - -struct input_device_id { - - kernel_ulong_t flags; - - __u16 bustype; - __u16 vendor; - __u16 product; - __u16 version; - - kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1]; - kernel_ulong_t propbit[INPUT_DEVICE_ID_PROP_MAX / BITS_PER_LONG + 1]; - - kernel_ulong_t driver_info; -}; - -/* EISA */ - -#define EISA_SIG_LEN 8 - -/* The EISA signature, in ASCII form, null terminated */ -struct eisa_device_id { - char sig[EISA_SIG_LEN]; - kernel_ulong_t driver_data; -}; - -#define EISA_DEVICE_MODALIAS_FMT "eisa:s%s" - -struct parisc_device_id { - __u8 hw_type; /* 5 bits used */ - __u8 hversion_rev; /* 4 bits */ - __u16 hversion; /* 12 bits */ - __u32 sversion; /* 20 bits */ -}; - -#define PA_HWTYPE_ANY_ID 0xff -#define PA_HVERSION_REV_ANY_ID 0xff -#define PA_HVERSION_ANY_ID 0xffff -#define PA_SVERSION_ANY_ID 0xffffffff - -/* SDIO */ - -#define SDIO_ANY_ID (~0) - -struct sdio_device_id { - __u8 class; /* Standard interface or SDIO_ANY_ID */ - __u16 vendor; /* Vendor or SDIO_ANY_ID */ - __u16 device; /* Device ID or SDIO_ANY_ID */ - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -/* SSB core, see drivers/ssb/ */ -struct ssb_device_id { - __u16 vendor; - __u16 coreid; - __u8 revision; - __u8 __pad; -} __attribute__((packed, aligned(2))); -#define SSB_DEVICE(_vendor, _coreid, _revision) \ - { .vendor = _vendor, .coreid = _coreid, .revision = _revision, } - -#define SSB_ANY_VENDOR 0xFFFF -#define SSB_ANY_ID 0xFFFF -#define SSB_ANY_REV 0xFF - -/* Broadcom's specific AMBA core, see drivers/bcma/ */ -struct bcma_device_id { - __u16 manuf; - __u16 id; - __u8 rev; - __u8 class; -} __attribute__((packed,aligned(2))); -#define BCMA_CORE(_manuf, _id, _rev, _class) \ - { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, } - -#define BCMA_ANY_MANUF 0xFFFF -#define BCMA_ANY_ID 0xFFFF -#define BCMA_ANY_REV 0xFF -#define BCMA_ANY_CLASS 0xFF - -struct virtio_device_id { - __u32 device; - __u32 vendor; -}; -#define VIRTIO_DEV_ANY_ID 0xffffffff - -/* - * For Hyper-V devices we use the device guid as the id. - */ -struct hv_vmbus_device_id { - guid_t guid; - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -/* rpmsg */ - -#define RPMSG_NAME_SIZE 32 -#define RPMSG_DEVICE_MODALIAS_FMT "rpmsg:%s" - -struct rpmsg_device_id { - char name[RPMSG_NAME_SIZE]; - kernel_ulong_t driver_data; -}; - -/* i2c */ - -#define I2C_NAME_SIZE 20 -#define I2C_MODULE_PREFIX "i2c:" - -struct i2c_device_id { - char name[I2C_NAME_SIZE]; - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -/* pci_epf */ - -#define PCI_EPF_NAME_SIZE 20 -#define PCI_EPF_MODULE_PREFIX "pci_epf:" - -struct pci_epf_device_id { - char name[PCI_EPF_NAME_SIZE]; - kernel_ulong_t driver_data; -}; - -/* i3c */ - -#define I3C_MATCH_DCR 0x1 -#define I3C_MATCH_MANUF 0x2 -#define I3C_MATCH_PART 0x4 -#define I3C_MATCH_EXTRA_INFO 0x8 - -struct i3c_device_id { - __u8 match_flags; - __u8 dcr; - __u16 manuf_id; - __u16 part_id; - __u16 extra_info; - - const void *data; -}; - -/* spi */ - -#define SPI_NAME_SIZE 32 -#define SPI_MODULE_PREFIX "spi:" - -struct spi_device_id { - char name[SPI_NAME_SIZE]; - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -/* SLIMbus */ - -#define SLIMBUS_NAME_SIZE 32 -#define SLIMBUS_MODULE_PREFIX "slim:" - -struct slim_device_id { - __u16 manf_id, prod_code; - __u16 dev_index, instance; - - /* Data private to the driver */ - kernel_ulong_t driver_data; -}; - -#define APR_NAME_SIZE 32 -#define APR_MODULE_PREFIX "apr:" - -struct apr_device_id { - char name[APR_NAME_SIZE]; - __u32 domain_id; - __u32 svc_id; - __u32 svc_version; - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -#define SPMI_NAME_SIZE 32 -#define SPMI_MODULE_PREFIX "spmi:" - -struct spmi_device_id { - char name[SPMI_NAME_SIZE]; - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -/* dmi */ -enum dmi_field { - DMI_NONE, - DMI_BIOS_VENDOR, - DMI_BIOS_VERSION, - DMI_BIOS_DATE, - DMI_BIOS_RELEASE, - DMI_EC_FIRMWARE_RELEASE, - DMI_SYS_VENDOR, - DMI_PRODUCT_NAME, - DMI_PRODUCT_VERSION, - DMI_PRODUCT_SERIAL, - DMI_PRODUCT_UUID, - DMI_PRODUCT_SKU, - DMI_PRODUCT_FAMILY, - DMI_BOARD_VENDOR, - DMI_BOARD_NAME, - DMI_BOARD_VERSION, - DMI_BOARD_SERIAL, - DMI_BOARD_ASSET_TAG, - DMI_CHASSIS_VENDOR, - DMI_CHASSIS_TYPE, - DMI_CHASSIS_VERSION, - DMI_CHASSIS_SERIAL, - DMI_CHASSIS_ASSET_TAG, - DMI_STRING_MAX, - DMI_OEM_STRING, /* special case - will not be in dmi_ident */ -}; - -struct dmi_strmatch { - unsigned char slot:7; - unsigned char exact_match:1; - char substr[79]; -}; - -struct dmi_system_id { - int (*callback)(const struct dmi_system_id *); - const char *ident; - struct dmi_strmatch matches[4]; - void *driver_data; -}; -/* - * struct dmi_device_id appears during expansion of - * "MODULE_DEVICE_TABLE(dmi, x)". Compiler doesn't look inside it - * but this is enough for gcc 3.4.6 to error out: - * error: storage size of '__mod_dmi_device_table' isn't known - */ -#define dmi_device_id dmi_system_id - -#define DMI_MATCH(a, b) { .slot = a, .substr = b } -#define DMI_EXACT_MATCH(a, b) { .slot = a, .substr = b, .exact_match = 1 } - -#define PLATFORM_NAME_SIZE 24 -#define PLATFORM_MODULE_PREFIX "platform:" - -struct platform_device_id { - char name[PLATFORM_NAME_SIZE]; - kernel_ulong_t driver_data; -}; - -#define MDIO_MODULE_PREFIX "mdio:" - -#define MDIO_ID_FMT "%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u" -#define MDIO_ID_ARGS(_id) \ - ((_id)>>31) & 1, ((_id)>>30) & 1, ((_id)>>29) & 1, ((_id)>>28) & 1, \ - ((_id)>>27) & 1, ((_id)>>26) & 1, ((_id)>>25) & 1, ((_id)>>24) & 1, \ - ((_id)>>23) & 1, ((_id)>>22) & 1, ((_id)>>21) & 1, ((_id)>>20) & 1, \ - ((_id)>>19) & 1, ((_id)>>18) & 1, ((_id)>>17) & 1, ((_id)>>16) & 1, \ - ((_id)>>15) & 1, ((_id)>>14) & 1, ((_id)>>13) & 1, ((_id)>>12) & 1, \ - ((_id)>>11) & 1, ((_id)>>10) & 1, ((_id)>>9) & 1, ((_id)>>8) & 1, \ - ((_id)>>7) & 1, ((_id)>>6) & 1, ((_id)>>5) & 1, ((_id)>>4) & 1, \ - ((_id)>>3) & 1, ((_id)>>2) & 1, ((_id)>>1) & 1, (_id) & 1 - -/** - * struct mdio_device_id - identifies PHY devices on an MDIO/MII bus - * @phy_id: The result of - * (mdio_read(&MII_PHYSID1) << 16 | mdio_read(&MII_PHYSID2)) & @phy_id_mask - * for this PHY type - * @phy_id_mask: Defines the significant bits of @phy_id. A value of 0 - * is used to terminate an array of struct mdio_device_id. - */ -struct mdio_device_id { - __u32 phy_id; - __u32 phy_id_mask; -}; - -struct zorro_device_id { - __u32 id; /* Device ID or ZORRO_WILDCARD */ - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -#define ZORRO_WILDCARD (0xffffffff) /* not official */ - -#define ZORRO_DEVICE_MODALIAS_FMT "zorro:i%08X" - -#define ISAPNP_ANY_ID 0xffff -struct isapnp_device_id { - unsigned short card_vendor, card_device; - unsigned short vendor, function; - kernel_ulong_t driver_data; /* data private to the driver */ -}; - -/** - * struct amba_id - identifies a device on an AMBA bus - * @id: The significant bits if the hardware device ID - * @mask: Bitmask specifying which bits of the id field are significant when - * matching. A driver binds to a device when ((hardware device ID) & mask) - * == id. - * @data: Private data used by the driver. - */ -struct amba_id { - unsigned int id; - unsigned int mask; - void *data; -}; - -/** - * struct mips_cdmm_device_id - identifies devices in MIPS CDMM bus - * @type: Device type identifier. - */ -struct mips_cdmm_device_id { - __u8 type; -}; - -/* - * Match x86 CPUs for CPU specific drivers. - * See documentation of "x86_match_cpu" for details. - */ - -/* - * MODULE_DEVICE_TABLE expects this struct to be called x86cpu_device_id. - * Although gcc seems to ignore this error, clang fails without this define. - */ -#define x86cpu_device_id x86_cpu_id -struct x86_cpu_id { - __u16 vendor; - __u16 family; - __u16 model; - __u16 steppings; - __u16 feature; /* bit index */ - /* Solely for kernel-internal use: DO NOT EXPORT to userspace! */ - __u16 flags; - __u8 platform_mask; - __u8 type; - kernel_ulong_t driver_data; -}; - -/* Wild cards for x86_cpu_id::vendor, family, model and feature */ -#define X86_VENDOR_ANY 0xffff -#define X86_FAMILY_ANY 0 -#define X86_MODEL_ANY 0 -#define X86_STEPPING_ANY 0 -#define X86_STEP_MIN 0 -#define X86_STEP_MAX 0xf -#define X86_PLATFORM_ANY 0x0 -#define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */ -#define X86_CPU_TYPE_ANY 0 +#include "device-id/acpi.h" +#include "device-id/amba.h" +#include "device-id/ap.h" +#include "device-id/apr.h" +#include "device-id/auxiliary.h" +#include "device-id/bcma.h" +#include "device-id/ccw.h" +#include "device-id/cdx.h" +#include "device-id/coreboot.h" +#include "device-id/css.h" +#include "device-id/dfl.h" +#include "device-id/dmi.h" +#include "device-id/eisa.h" +#include "device-id/fsl_mc.h" +#include "device-id/hda.h" +#include "device-id/hid.h" +#include "device-id/hv_vmbus.h" +#include "device-id/i2c.h" +#include "device-id/i3c.h" +#include "device-id/ieee1394.h" +#include "device-id/input.h" +#include "device-id/ipack.h" +#include "device-id/isapnp.h" +#include "device-id/ishtp.h" +#include "device-id/mcb.h" +#include "device-id/mdio.h" +#include "device-id/mei_cl.h" +#include "device-id/mhi.h" +#include "device-id/mips_cdmm.h" +#include "device-id/of.h" +#include "device-id/parisc.h" +#include "device-id/pci.h" +#include "device-id/pcmcia.h" +#include "device-id/platform.h" +#include "device-id/pnp.h" +#include "device-id/rio.h" +#include "device-id/rpmsg.h" +#include "device-id/sdio.h" +#include "device-id/sdw.h" +#include "device-id/serio.h" +#include "device-id/slim.h" +#include "device-id/spi.h" +#include "device-id/spmi.h" +#include "device-id/ssam.h" +#include "device-id/ssb.h" +#include "device-id/tb.h" +#include "device-id/tee_client.h" +#include "device-id/typec.h" +#include "device-id/ulpi.h" +#include "device-id/usb.h" +#include "device-id/vchiq.h" +#include "device-id/vio.h" +#include "device-id/virtio.h" +#include "device-id/wmi.h" +#include "device-id/x86_cpu.h" +#include "device-id/zorro.h" /* * Generic table type for matching CPU features. @@ -719,265 +78,4 @@ struct cpu_feature { __u16 feature; }; -#define IPACK_ANY_FORMAT 0xff -#define IPACK_ANY_ID (~0) -struct ipack_device_id { - __u8 format; /* Format version or IPACK_ANY_ID */ - __u32 vendor; /* Vendor ID or IPACK_ANY_ID */ - __u32 device; /* Device ID or IPACK_ANY_ID */ -}; - -#define MEI_CL_MODULE_PREFIX "mei:" -#define MEI_CL_NAME_SIZE 32 -#define MEI_CL_VERSION_ANY 0xff - -/** - * struct mei_cl_device_id - MEI client device identifier - * @name: helper name - * @uuid: client uuid - * @version: client protocol version - * @driver_info: information used by the driver. - * - * identifies mei client device by uuid and name - */ -struct mei_cl_device_id { - char name[MEI_CL_NAME_SIZE]; - uuid_le uuid; - __u8 version; - kernel_ulong_t driver_info; -}; - -/* RapidIO */ - -#define RIO_ANY_ID 0xffff - -/** - * struct rio_device_id - RIO device identifier - * @did: RapidIO device ID - * @vid: RapidIO vendor ID - * @asm_did: RapidIO assembly device ID - * @asm_vid: RapidIO assembly vendor ID - * - * Identifies a RapidIO device based on both the device/vendor IDs and - * the assembly device/vendor IDs. - */ -struct rio_device_id { - __u16 did, vid; - __u16 asm_did, asm_vid; -}; - -struct mcb_device_id { - __u16 device; - kernel_ulong_t driver_data; -}; - -struct ulpi_device_id { - __u16 vendor; - __u16 product; - kernel_ulong_t driver_data; -}; - -/** - * struct fsl_mc_device_id - MC object device identifier - * @vendor: vendor ID - * @obj_type: MC object type - * - * Type of entries in the "device Id" table for MC object devices supported by - * a MC object device driver. The last entry of the table has vendor set to 0x0 - */ -struct fsl_mc_device_id { - __u16 vendor; - const char obj_type[16]; -}; - -/** - * struct tb_service_id - Thunderbolt service identifiers - * @match_flags: Flags used to match the structure - * @protocol_key: Protocol key the service supports - * @protocol_id: Protocol id the service supports - * @protocol_version: Version of the protocol - * @protocol_revision: Revision of the protocol software - * @driver_data: Driver specific data - * - * Thunderbolt XDomain services are exposed as devices where each device - * carries the protocol information the service supports. Thunderbolt - * XDomain service drivers match against that information. - */ -struct tb_service_id { - __u32 match_flags; - char protocol_key[8 + 1]; - __u32 protocol_id; - __u32 protocol_version; - __u32 protocol_revision; - kernel_ulong_t driver_data; -}; - -#define TBSVC_MATCH_PROTOCOL_KEY 0x0001 -#define TBSVC_MATCH_PROTOCOL_ID 0x0002 -#define TBSVC_MATCH_PROTOCOL_VERSION 0x0004 -#define TBSVC_MATCH_PROTOCOL_REVISION 0x0008 - -/* USB Type-C Alternate Modes */ - -#define TYPEC_ANY_MODE 0x7 - -/** - * struct typec_device_id - USB Type-C alternate mode identifiers - * @svid: Standard or Vendor ID - * @mode: Mode index - * @driver_data: Driver specific data - */ -struct typec_device_id { - __u16 svid; - __u8 mode; - kernel_ulong_t driver_data; -}; - -/** - * struct tee_client_device_id - tee based device identifier - * @uuid: For TEE based client devices we use the device uuid as - * the identifier. - */ -struct tee_client_device_id { - uuid_t uuid; -}; - -/* WMI */ - -#define WMI_MODULE_PREFIX "wmi:" - -/** - * struct wmi_device_id - WMI device identifier - * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba - * @context: pointer to driver specific data - */ -struct wmi_device_id { - const char guid_string[UUID_STRING_LEN+1]; - const void *context; -}; - -#define MHI_DEVICE_MODALIAS_FMT "mhi:%s" -#define MHI_NAME_SIZE 32 - -#define MHI_EP_DEVICE_MODALIAS_FMT "mhi_ep:%s" - -/** - * struct mhi_device_id - MHI device identification - * @chan: MHI channel name - * @driver_data: driver data; - */ -struct mhi_device_id { - const char chan[MHI_NAME_SIZE]; - kernel_ulong_t driver_data; -}; - -#define AUXILIARY_NAME_SIZE 40 -#define AUXILIARY_MODULE_PREFIX "auxiliary:" - -struct auxiliary_device_id { - char name[AUXILIARY_NAME_SIZE]; - kernel_ulong_t driver_data; -}; - -/* Surface System Aggregator Module */ - -#define SSAM_MATCH_TARGET 0x1 -#define SSAM_MATCH_INSTANCE 0x2 -#define SSAM_MATCH_FUNCTION 0x4 - -struct ssam_device_id { - __u8 match_flags; - - __u8 domain; - __u8 category; - __u8 target; - __u8 instance; - __u8 function; - - kernel_ulong_t driver_data; -}; - -/* - * DFL (Device Feature List) - * - * DFL defines a linked list of feature headers within the device MMIO space to - * provide an extensible way of adding features. Software can walk through these - * predefined data structures to enumerate features. It is now used in the FPGA. - * See Documentation/fpga/dfl.rst for more information. - * - * The dfl bus type is introduced to match the individual feature devices (dfl - * devices) for specific dfl drivers. - */ - -/** - * struct dfl_device_id - dfl device identifier - * @type: DFL FIU type of the device. See enum dfl_id_type. - * @feature_id: feature identifier local to its DFL FIU type. - * @driver_data: driver specific data. - */ -struct dfl_device_id { - __u16 type; - __u16 feature_id; - kernel_ulong_t driver_data; -}; - -/* ISHTP (Integrated Sensor Hub Transport Protocol) */ - -#define ISHTP_MODULE_PREFIX "ishtp:" - -/** - * struct ishtp_device_id - ISHTP device identifier - * @guid: GUID of the device. - * @driver_data: pointer to driver specific data - */ -struct ishtp_device_id { - guid_t guid; - kernel_ulong_t driver_data; -}; - -#define CDX_ANY_ID (0xFFFF) - -enum { - CDX_ID_F_VFIO_DRIVER_OVERRIDE = 1, -}; - -/** - * struct cdx_device_id - CDX device identifier - * @vendor: Vendor ID - * @device: Device ID - * @subvendor: Subsystem vendor ID (or CDX_ANY_ID) - * @subdevice: Subsystem device ID (or CDX_ANY_ID) - * @class: Device class - * Most drivers do not need to specify class/class_mask - * as vendor/device is normally sufficient. - * @class_mask: Limit which sub-fields of the class field are compared. - * @override_only: Match only when dev->driver_override is this driver. - * - * Type of entries in the "device Id" table for CDX devices supported by - * a CDX device driver. - */ -struct cdx_device_id { - __u16 vendor; - __u16 device; - __u16 subvendor; - __u16 subdevice; - __u32 class; - __u32 class_mask; - __u32 override_only; -}; - -struct vchiq_device_id { - char name[32]; -}; - -/** - * struct coreboot_device_id - Identifies a coreboot table entry - * @tag: tag ID - * @driver_data: driver specific data - */ -struct coreboot_device_id { - __u32 tag; - kernel_ulong_t driver_data; -}; - #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/include/linux/module.h b/include/linux/module.h index 7566815fabbe..96cc98568eea 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -477,10 +477,6 @@ struct module { struct module_notes_attrs *notes_attrs; #endif - /* The command line arguments (may be mangled). People like - keeping pointers to this stuff */ - char *args; - #ifdef CONFIG_SMP /* Per-cpu data. */ void __percpu *percpu; diff --git a/include/linux/most.h b/include/linux/most.h index 232e01b7f5d2..4aeed08f816e 100644 --- a/include/linux/most.h +++ b/include/linux/most.h @@ -15,7 +15,7 @@ struct module; struct interface_private; /** - * Interface type + * enum most_interface_type - Interface type */ enum most_interface_type { ITYPE_LOOPBACK = 1, @@ -30,7 +30,7 @@ enum most_interface_type { }; /** - * Channel direction. + * enum most_channel_direction - Channel direction. */ enum most_channel_direction { MOST_CH_RX = 1 << 0, @@ -38,7 +38,7 @@ enum most_channel_direction { }; /** - * Channel data type. + * enum most_channel_data_type - Channel data type. */ enum most_channel_data_type { MOST_CH_CONTROL = 1 << 0, @@ -115,6 +115,7 @@ struct most_channel_capability { * @subbuffer_size: size of a subbuffer * @packets_per_xact: number of MOST frames that are packet inside one USB * packet. This is USB specific + * @dbr_size: DBR data buffer size (MediaLB communication only) * * Describes the configuration for a MOST channel. This information is * provided from the MostCore to a HDM (like the Medusa PCIe Interface) as a @@ -189,28 +190,31 @@ struct mbo { }; /** - * Interface instance description. + * struct most_interface - Interface instance description. * * Describes an interface of a MOST device the core driver is bound to. * This structure is allocated and initialized in the HDM. MostCore may not * modify this structure. * * @dev: the actual device + * @driver_dev: struct device for calling snd_card_new() * @mod: module - * @interface Interface type. \sa most_interface_type. - * @description PRELIMINARY. + * @interface: Interface type. \sa most_interface_type. + * @description: PRELIMINARY. * Unique description of the device instance from point of view of the * interface in free text form (ASCII). * It may be a hexadecimal presentation of the memory address for the MediaLB * IP or USB device ID with USB properties for USB interface, etc. - * @num_channels Number of channels and size of the channel_vector. - * @channel_vector Properties of the channels. + * @num_channels: Number of channels and size of the channel_vector. + * @channel_vector: Properties of the channels. * Array index represents channel ID by the driver. - * @configure Callback to change data type for the channel of the + * @dma_alloc: Callback to interface driver to allocation DMA memory. + * @dma_free: Callback to interface driver to free a DMA memory allocation. + * @configure: Callback to change data type for the channel of the * interface instance. May be zero if the instance of the interface is not * configurable. Parameter channel_config describes direction and data * type for the channel, configured by the higher level. The content of - * @enqueue Delivers MBO to the HDM for processing. + * @enqueue: Delivers MBO to the HDM for processing. * After HDM completes Rx- or Tx- operation the processed MBO shall * be returned back to the MostCore using completion routine. * The reason to get the MBO delivered from the MostCore after the channel @@ -218,7 +222,7 @@ struct mbo { * In this case the HDM shall hold MBOs and service the channel as usual. * The HDM must be able to hold at least one MBO for each channel. * The callback returns a negative value on error, otherwise 0. - * @poison_channel Informs HDM about closing the channel. The HDM shall + * @poison_channel: Informs HDM about closing the channel. The HDM shall * cancel all transfers and synchronously or asynchronously return * all enqueued for this channel MBOs using the completion routine. * The callback returns a negative value on error, otherwise 0. @@ -226,7 +230,8 @@ struct mbo { * means of "Message exchange over MDP/MEP" * The call of the function request_netinfo with the parameter on_netinfo as * NULL prohibits use of the previously obtained function pointer. - * @priv Private field used by mostcore to store context information. + * @priv: Private field used by mostcore to store context information. + * @p: &struct interface_private pointer */ struct most_interface { struct device *dev; @@ -255,10 +260,12 @@ struct most_interface { * struct most_component - identifies a loadable component for the mostcore * @list: list_head * @name: component name + * @mod: owning module * @probe_channel: function for core to notify driver about channel connection * @disconnect_channel: callback function to disconnect a certain channel * @rx_completion: completion handler for received packets * @tx_completion: completion handler for transmitted packets + * @cfg_complete: setup completion function called after the device is matched */ struct most_component { struct list_head list; @@ -278,7 +285,7 @@ struct most_component { * most_register_interface - Registers instance of the interface. * @iface: Pointer to the interface instance description. * - * Returns a pointer to the kobject of the generated instance. + * Returns: a pointer to the kobject of the generated instance. * * Note: HDM has to ensure that any reference held on the kobj is * released before deregistering the interface. @@ -286,8 +293,8 @@ struct most_component { int most_register_interface(struct most_interface *iface); /** - * Deregisters instance of the interface. - * @intf_instance Pointer to the interface instance description. + * most_deregister_interface - Deregisters instance of the interface. + * @iface: Pointer to the interface instance description. */ void most_deregister_interface(struct most_interface *iface); void most_submit_mbo(struct mbo *mbo); diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h index 006ca8c978a9..437448995187 100644 --- a/include/linux/mtd/nand-qpic-common.h +++ b/include/linux/mtd/nand-qpic-common.h @@ -443,6 +443,7 @@ struct qcom_nand_controller { * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset * @supports_bam - whether NAND controller is using BAM * @nandc_part_of_qpic - whether NAND controller is part of qpic IP + * @has_onfi_read_op - whether ONFI param page read command is supported * @qpic_version2 - flag to indicate QPIC IP version 2 * @use_codeword_fixup - whether NAND has different layout for boot partitions */ @@ -452,6 +453,7 @@ struct qcom_nandc_props { u32 bam_offset; bool supports_bam; bool nandc_part_of_qpic; + bool has_onfi_read_op; bool qpic_version2; bool use_codeword_fixup; }; diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index ec6efcfeef83..5f4c00ae72a7 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -437,6 +437,7 @@ extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; extern const struct spinand_manufacturer fmsh_spinand_manufacturer; extern const struct spinand_manufacturer foresee_spinand_manufacturer; extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; +extern const struct spinand_manufacturer heyangtek_spinand_manufacturer; extern const struct spinand_manufacturer macronix_spinand_manufacturer; extern const struct spinand_manufacturer micron_spinand_manufacturer; extern const struct spinand_manufacturer paragon_spinand_manufacturer; diff --git a/include/linux/namei.h b/include/linux/namei.h index ebe6e29f7e93..86d657b24fc6 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -97,6 +97,9 @@ struct dentry *start_creating_dentry(struct dentry *parent, struct dentry *start_removing_dentry(struct dentry *parent, struct dentry *child); +struct file *vfs_lookup_open(struct path *parent, struct qstr *last, + int open_flag, umode_t mode); + /* end_creating - finish action started with start_creating * @child: dentry returned by start_creating() or vfs_mkdir() * diff --git a/include/linux/nd.h b/include/linux/nd.h index fa099e295f78..62988000e7a7 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -110,7 +110,7 @@ static inline struct nd_namespace_common *to_ndns(struct device *dev) /** * struct nd_namespace_io - device representation of a persistent memory range - * @dev: namespace device created by the nd region driver + * @common: namespace device core infrastructure created by the nd region driver * @res: struct resource conversion of a NFIT SPA table * @size: cached resource_size(@res) for fast path size checks * @addr: virtual address to access the namespace range @@ -158,8 +158,11 @@ static inline struct nd_namespace_pmem *to_nd_namespace_pmem(const struct device * @offset: namespace-relative starting offset * @buf: buffer to fill * @size: transfer length + * @flags: process (0) or atomic (1) context * * @buf is up-to-date upon return from this routine. + * + * Returns: %0 on success or a negative error code on failure */ static inline int nvdimm_read_bytes(struct nd_namespace_common *ndns, resource_size_t offset, void *buf, size_t size, @@ -174,11 +177,14 @@ static inline int nvdimm_read_bytes(struct nd_namespace_common *ndns, * @offset: namespace-relative starting offset * @buf: buffer to drain * @size: transfer length + * @flags: process (0) or atomic (1) context * * NVDIMM Namepaces disks do not implement sectors internally. Depending on * the @ndns, the contents of @buf may be in cpu cache, platform buffers, * or on backing memory media upon return from this routine. Flushing * to media is handled internal to the @ndns driver, if at all. + * + * Returns: %0 on success or a negative error code on failure */ static inline int nvdimm_write_bytes(struct nd_namespace_common *ndns, resource_size_t offset, void *buf, size_t size, diff --git a/include/linux/net.h b/include/linux/net.h index f268f395ce47..3d82966e2243 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -47,6 +47,29 @@ typedef struct sockopt { int optlen; } sockopt_t; +/* + * Initialize a user-backed sockopt_t from the (optval, optlen) __user pair of + * a getsockopt() callback. Used by transitional __user getsockopt wrappers + * while the proto-layer callbacks are converted to take a sockopt_t; the + * caller writes opt->optlen back to the user optlen after the callback. + */ +static inline int sockopt_init_user(sockopt_t *opt, char __user *optval, + int __user *optlen) +{ + int len; + + if (get_user(len, optlen)) + return -EFAULT; + if (len < 0) + return -EINVAL; + + iov_iter_ubuf(&opt->iter_out, ITER_DEST, optval, len); + iov_iter_ubuf(&opt->iter_in, ITER_SOURCE, optval, len); + opt->optlen = len; + + return 0; +} + struct poll_table_struct; struct pipe_inode_info; struct inode; @@ -285,6 +308,7 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags); struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname); struct socket *sockfd_lookup(int fd, int *err); struct socket *sock_from_file(struct file *file); +int sock_read_xattr(struct socket *sock, const char *name, void *value, size_t size); #define sockfd_put(sock) fput(sock->file) int net_ratelimit(void); diff --git a/include/linux/net/intel/libie/controlq.h b/include/linux/net/intel/libie/controlq.h new file mode 100644 index 000000000000..175227d4eef1 --- /dev/null +++ b/include/linux/net/intel/libie/controlq.h @@ -0,0 +1,436 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 2025 Intel Corporation */ + +#ifndef __LIBIE_CONTROLQ_H +#define __LIBIE_CONTROLQ_H + +#include <linux/dmapool.h> +#include <net/libeth/rx.h> + +#include <linux/net/intel/libie/pci.h> +#include <linux/net/intel/virtchnl2.h> + +/* Default mailbox control queue */ +#define LIBIE_CTLQ_MBX_ID -1 +#define LIBIE_CTLQ_MAX_BUF_LEN SZ_4K + +/** + * enum libie_ctlq_type - control queue type + * @LIBIE_CTLQ_TYPE_TX: basic Tx control queue + * @LIBIE_CTLQ_TYPE_RX: basic Rx control queue + */ +enum libie_ctlq_type { + LIBIE_CTLQ_TYPE_TX = 0, + LIBIE_CTLQ_TYPE_RX = 1, +}; + +/* Opcode used to send controlq message to the control plane */ +#define LIBIE_CTLQ_SEND_MSG_TO_CP 0x801 +#define LIBIE_CTLQ_SEND_MSG_TO_PEER 0x804 + +#define LIBIE_CP_TX_COPYBREAK 128 + +/** + * struct libie_ctlq_ctx - contains controlq info and MMIO region info + * @mmio_info: MMIO region info structure + * @ctlqs: list that stores all the control queues + * @ctlqs_lock: lock for control queue list + */ +struct libie_ctlq_ctx { + struct libie_mmio_info mmio_info; + struct list_head ctlqs; + spinlock_t ctlqs_lock; /* protects the ctlqs list */ +}; + +/** + * struct libie_ctlq_reg - structure representing virtual addresses of the + * controlq registers and masks + * @head: controlq head register address + * @tail: controlq tail register address + * @len: register address to write controlq length and enable bit + * @addr_high: register address to write the upper 32b of ring physical address + * @addr_low: register address to write the lower 32b of ring physical address + * @len_mask: mask to read the controlq length + * @len_ena_mask: mask to write the controlq enable bit + * @head_mask: mask to read the head value + */ +struct libie_ctlq_reg { + void __iomem *head; + void __iomem *tail; + void __iomem *len; + void __iomem *addr_high; + void __iomem *addr_low; + u32 len_mask; + u32 len_ena_mask; + u32 head_mask; +}; + +/** + * struct libie_cp_dma_mem - structure for DMA memory + * @va: virtual address + * @pa: physical address + * @size: memory size + * @direction: memory to device or device to memory + */ +struct libie_cp_dma_mem { + void *va; + dma_addr_t pa; + size_t size; + int direction; +}; + +/** + * struct libie_ctlq_msg - control queue message data + * @flags: refer to 'Flags sub-structure' definitions + * @opcode: infrastructure message opcode + * @data_len: size of the payload + * @func_id: queue id for mailbox selection, 0 for default mailbox (Tx) + * @hw_retval: execution status from the HW (Rx) + * @chnl_opcode: virtchnl message opcode + * @chnl_retval: virtchnl return value + * @param0: indirect message raw parameter0 + * @sw_cookie: used to verify the response of the sent virtchnl message + * @virt_flags: virtchnl capability flags + * @addr_param: additional parameters in place of the address, given no buffer + * @recv_mem: virtual address and size of the buffer that contains + * the indirect response + * @send_mem: physical and virtual address of the DMA buffer, + * used for sending + */ +struct libie_ctlq_msg { + u16 flags; + u16 opcode; + u16 data_len; + union { + u16 func_id; + u16 hw_retval; + }; + u32 chnl_opcode; + u32 chnl_retval; + u32 param0; + u16 sw_cookie; + u16 virt_flags; + u64 addr_param; + union { + struct kvec recv_mem; + struct libie_cp_dma_mem send_mem; + }; +}; + +/** + * struct libie_ctlq_create_info - control queue create information + * @type: control queue type (Rx or Tx) + * @id: queue offset passed as input, -1 for default mailbox + * @reg: registers accessed by control queue + * @len: controlq length + */ +struct libie_ctlq_create_info { + enum libie_ctlq_type type; + int id; + struct libie_ctlq_reg reg; + u16 len; +}; + +/** + * struct libie_ctlq_info - control queue information + * @list: used to add a controlq to the list of queues in libie_ctlq_ctx + * @type: control queue type + * @qid: queue identifier + * @lock: control queue lock + * @ring_mem: descriptor ring DMA memory + * @descs: array of descriptors + * @rx_fqes: array of controlq Rx buffers + * @tx_msg: Tx messages sent to hardware + * @reg: registers used by control queue + * @dev: device that owns this control queue + * @pp: page pool for controlq Rx buffers + * @truesize: size to allocate per buffer + * @next_to_clean: next descriptor to be cleaned + * @next_to_use: next available slot to send buffer (Tx queue) + * @next_to_post: next available slot to post buffers to (Rx queue) + * @ring_len: length of the descriptor ring + */ +struct libie_ctlq_info { + struct list_head list; + enum libie_ctlq_type type; + int qid; + spinlock_t lock; /* for concurrent processing */ + struct libie_cp_dma_mem ring_mem; + struct libie_ctlq_desc *descs; + union { + struct libeth_fqe *rx_fqes; + struct libie_ctlq_msg **tx_msg; + }; + struct libie_ctlq_reg reg; + struct device *dev; + struct page_pool *pp; + u32 truesize; + u32 next_to_clean; + union { + u32 next_to_use; + u32 next_to_post; + }; + u32 ring_len; +}; + +#define LIBIE_CTLQ_MBX_ATQ_LEN GENMASK(9, 0) + +/* libie controlq descriptor qword0 details */ + +/* Flags sub-structure + * |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |14 |15 | + * |DD |CMP|ERR| * RSV * |FTYPE | *RSV* |RD |VFC|BUF| HOST_ID | + */ +#define LIBIE_CTLQ_DESC_FLAG_DD BIT(0) +#define LIBIE_CTLQ_DESC_FLAG_CMP BIT(1) +#define LIBIE_CTLQ_DESC_FLAG_ERR BIT(2) +#define LIBIE_CTLQ_DESC_FLAG_FTYPE_VM BIT(6) +#define LIBIE_CTLQ_DESC_FLAG_FTYPE_PF BIT(7) +#define LIBIE_CTLQ_DESC_FLAG_FTYPE GENMASK(7, 6) +#define LIBIE_CTLQ_DESC_FLAG_RD BIT(10) +#define LIBIE_CTLQ_DESC_FLAG_VFC BIT(11) +#define LIBIE_CTLQ_DESC_FLAG_BUF BIT(12) +#define LIBIE_CTLQ_DESC_FLAG_HOST_ID GENMASK(15, 13) + +#define LIBIE_CTLQ_DESC_FLAGS GENMASK(15, 0) +#define LIBIE_CTLQ_DESC_INFRA_OPCODE GENMASK_ULL(31, 16) +#define LIBIE_CTLQ_DESC_DATA_LEN GENMASK_ULL(47, 32) +#define LIBIE_CTLQ_DESC_HW_RETVAL GENMASK_ULL(63, 48) + +#define LIBIE_CTLQ_DESC_PFID_VFID GENMASK_ULL(63, 48) + +/* libie controlq descriptor qword1 details */ +#define LIBIE_CTLQ_DESC_VIRTCHNL_OPCODE GENMASK(27, 0) +#define LIBIE_CTLQ_DESC_VIRTCHNL_DESC_TYPE GENMASK_ULL(31, 28) +#define LIBIE_CTLQ_DESC_VIRTCHNL_MSG_RET_VAL GENMASK_ULL(63, 32) + +/* libie controlq descriptor qword2 details */ +#define LIBIE_CTLQ_DESC_MSG_PARAM0 GENMASK_ULL(31, 0) +#define LIBIE_CTLQ_DESC_SW_COOKIE GENMASK_ULL(47, 32) +#define LIBIE_CTLQ_DESC_VIRTCHNL_FLAGS GENMASK_ULL(63, 48) + +/* libie controlq descriptor qword3 details */ +#define LIBIE_CTLQ_DESC_DATA_ADDR_HIGH GENMASK_ULL(31, 0) +#define LIBIE_CTLQ_DESC_DATA_ADDR_LOW GENMASK_ULL(63, 32) + +/** + * struct libie_ctlq_desc - control queue descriptor format + * @qword0: flags, message opcode, data length etc + * @qword1: virtchnl opcode, descriptor type and return value + * @qword2: indirect message parameters + * @qword3: indirect message buffer address + */ +struct libie_ctlq_desc { + __le64 qword0; + __le64 qword1; + __le64 qword2; + __le64 qword3; +}; + +/** + * struct libie_ctlq_clean_params - cleaning parameters for Tx messages + * @rel_dma_mem: non-sleeping callback to put the DMA buffer after send + * @rel_ctx: additional context for release callback + * @ctlq: control queue information + * @num_msgs: number of messages to be cleaned + * @force: clean even if DD is not yet set, use only for final cleanup + */ +struct libie_ctlq_clean_params { + void (*rel_dma_mem)(const void *ctx, struct libie_cp_dma_mem *dma_mem); + const void *rel_ctx; + struct libie_ctlq_info *ctlq; + u16 num_msgs; + bool force; +}; + +/** + * libie_ctlq_release_rx_buf - Release Rx buffer for a specific control queue + * @rx_buf: Rx buffer to be freed + * + * Driver uses this function to post back the Rx buffer after the usage. + */ +static inline void libie_ctlq_release_rx_buf(struct kvec *rx_buf) +{ + netmem_ref netmem; + + if (!rx_buf->iov_base) + return; + + netmem = virt_to_netmem(rx_buf->iov_base); + page_pool_put_full_netmem(netmem_get_pp(netmem), netmem, false); +} + +int libie_ctlq_init(struct libie_ctlq_ctx *ctx, + const struct libie_ctlq_create_info *qinfo, u32 numq); +void libie_ctlq_deinit(struct libie_ctlq_ctx *ctx); + +struct libie_ctlq_info *libie_find_ctlq(struct libie_ctlq_ctx *ctx, + enum libie_ctlq_type type, + int id); + +u32 libie_ctlq_send_desc_avail(const struct libie_ctlq_info *ctlq); +void libie_ctlq_send(struct libie_ctlq_info *ctlq, u32 num_q_msg); +u32 libie_ctlq_send_clean(const struct libie_ctlq_clean_params *params); +u32 libie_ctlq_recv(struct libie_ctlq_info *ctlq, struct libie_ctlq_msg *msg, + u32 num_q_msg); + +int libie_ctlq_post_rx_buffs(struct libie_ctlq_info *ctlq); + +/* Only 8 bits are available in descriptor for Xn index */ +#define LIBIE_CTLQ_MAX_XN_ENTRIES 256 +#define LIBIE_CTLQ_XN_COOKIE_M GENMASK(15, 8) +#define LIBIE_CTLQ_XN_INDEX_M GENMASK(7, 0) + +/** + * enum libie_ctlq_xn_state - Transaction state of a virtchnl message + * @LIBIE_CTLQ_XN_IDLE: transaction is available to use + * @LIBIE_CTLQ_XN_WAITING: waiting for transaction to complete + * @LIBIE_CTLQ_XN_COMPLETED_SUCCESS: transaction completed with success + * @LIBIE_CTLQ_XN_COMPLETED_FAILED: transaction completed with failure + * @LIBIE_CTLQ_XN_ASYNC: asynchronous virtchnl message transaction type + * @LIBIE_CTLQ_XN_SHUTDOWN: transaction cannot be used anymore + */ +enum libie_ctlq_xn_state { + LIBIE_CTLQ_XN_IDLE = 0, + LIBIE_CTLQ_XN_WAITING, + LIBIE_CTLQ_XN_COMPLETED_SUCCESS, + LIBIE_CTLQ_XN_COMPLETED_FAILED, + LIBIE_CTLQ_XN_ASYNC, + LIBIE_CTLQ_XN_SHUTDOWN, +}; + +/** + * struct libie_ctlq_xn - structure representing a virtchnl transaction entry + * @resp_cb: non-sleeping callback to handle the response to an async message + * @xn_lock: lock to protect the transaction entry state + * @cmd_completion_event: wait until reply is received or xn is terminated + * @small_dma_mem: DMA memory for copying small send buffers from stack, + * is recycled when response is received or on timeout + * @send_dma_mem: DMA memory of send buffer + * @recv_mem: receive buffer + * @send_ctx: context for callback function + * @timeout_ms: Xn transaction timeout in msecs + * @timestamp: timestamp to record the Xn send + * @tx_msg: control queue Tx message slot to track small DMA usage + * @virtchnl_opcode: virtchnl command opcode used for Xn transaction + * @state: transaction state of a virtchnl message + * @cookie: unique message identifier, incremented every time the slot is used + * @index: index of the transaction entry + */ +struct libie_ctlq_xn { + void (*resp_cb)(void *ctx, struct kvec *mem, int status); + spinlock_t xn_lock; /* protects state */ + struct completion cmd_completion_event; + struct libie_cp_dma_mem small_dma_mem; + struct libie_cp_dma_mem send_dma_mem; + struct kvec recv_mem; + void *send_ctx; + u64 timeout_ms; + ktime_t timestamp; + struct libie_ctlq_msg *tx_msg; + u32 virtchnl_opcode; + enum libie_ctlq_xn_state state; + u8 cookie; + u8 index; +}; + +/** + * struct libie_ctlq_xn_manager - structure representing the array of virtchnl + * transaction entries + * @ctx: pointer to controlq context structure + * @free_xns_bm_lock: lock to protect the free Xn entries bit map + * @free_xns_bm: bitmap that represents the free Xn entries + * @ring: array of Xn entries + * @small_buff_pool: DMA pool for small send buffers + * @can_destroy: completion, triggered by the last released transaction + * @shutdown: shutdown process has been started, no new transactions allowed + */ +struct libie_ctlq_xn_manager { + struct libie_ctlq_ctx *ctx; + spinlock_t free_xns_bm_lock; /* get/check entries */ + DECLARE_BITMAP(free_xns_bm, LIBIE_CTLQ_MAX_XN_ENTRIES); + struct libie_ctlq_xn ring[LIBIE_CTLQ_MAX_XN_ENTRIES]; + struct dma_pool *small_buff_pool; + struct completion can_destroy; + bool shutdown; +}; + +/** + * struct libie_ctlq_xn_send_params - structure representing send Xn entry + * @resp_cb: non-sleeping callback to handle the response to an async message + * @rel_tx_buf: non-sleeping callback for freeing the send buffer + * @xnm: Xn manager to process Xn entries + * @ctlq: send control queue information + * @ctlq_msg: control queue message information + * @send_buf: buffer that carries outgoing message data, buffers larger than + * LIBIE_CP_TX_COPYBREAK bytes will always be consumed + * @recv_mem: receive buffer + * @send_ctx: context for callback function + * @timeout_ms: virtchnl transaction timeout in msecs + * @chnl_opcode: virtchnl message opcode + */ +struct libie_ctlq_xn_send_params { + void (*resp_cb)(void *ctx, struct kvec *mem, int status); + void (*rel_tx_buf)(const void *buf_va); + struct libie_ctlq_xn_manager *xnm; + struct libie_ctlq_info *ctlq; + struct libie_ctlq_msg *ctlq_msg; + struct kvec send_buf; + struct kvec recv_mem; + void *send_ctx; + u64 timeout_ms; + u32 chnl_opcode; +}; + +/** + * libie_cp_can_send_onstack - can a message be sent using a stack variable + * @size: ctlq data buffer size + * + * Return: %true if the message size is small enough for caller to pass + * an on-stack buffer, %false if kmalloc is needed + */ +static inline bool libie_cp_can_send_onstack(u32 size) +{ + return size <= LIBIE_CP_TX_COPYBREAK; +} + +/** + * struct libie_ctlq_xn_recv_params - request to receive xn responses + * @ctlq_msg_handler: handler for Rx messages with no matching xn (mandatory) + * @xnm: Xn manager to process Xn entries + * @ctlq: control queue information + * @budget: maximum number of messages to process + */ +struct libie_ctlq_xn_recv_params { + void (*ctlq_msg_handler)(struct libie_ctlq_ctx *ctx, + struct libie_ctlq_msg *msg); + struct libie_ctlq_xn_manager *xnm; + struct libie_ctlq_info *ctlq; + u32 budget; +}; + +/** + * struct libie_ctlq_xn_init_params - xn transaction manager parameters + * @cctlq_info: control queue information + * @ctx: pointer to controlq context structure + * @xnm: Xn manager to process Xn entries + * @num_qs: number of control queues to be initialized + */ +struct libie_ctlq_xn_init_params { + struct libie_ctlq_create_info *cctlq_info; + struct libie_ctlq_ctx *ctx; + struct libie_ctlq_xn_manager *xnm; + u32 num_qs; +}; + +int libie_ctlq_xn_init(struct libie_ctlq_xn_init_params *params); +void libie_ctlq_xn_deinit(struct libie_ctlq_xn_manager *xnm, + struct libie_ctlq_ctx *ctx); +void libie_ctlq_xn_shutdown(struct libie_ctlq_xn_manager *xnm); +int libie_ctlq_xn_send(struct libie_ctlq_xn_send_params *params); +u32 libie_ctlq_xn_recv(struct libie_ctlq_xn_recv_params *params); +u32 libie_ctlq_xn_send_clean(struct libie_ctlq_info *ctlq, + void (*rel_tx_buf)(const void *buf_va), + bool force); + +#endif /* __LIBIE_CONTROLQ_H */ diff --git a/include/linux/net/intel/libie/pci.h b/include/linux/net/intel/libie/pci.h new file mode 100644 index 000000000000..effd072c55c8 --- /dev/null +++ b/include/linux/net/intel/libie/pci.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 2025 Intel Corporation */ + +#ifndef __LIBIE_PCI_H +#define __LIBIE_PCI_H + +#include <linux/pci.h> + +/** + * struct libie_pci_mmio_region - structure for MMIO region info + * @list: used to add a MMIO region to the list of MMIO regions in + * libie_mmio_info + * @addr: virtual address of MMIO region start + * @offset: start offset of the MMIO region + * @size: size of the MMIO region + * @bar_idx: BAR index to which the MMIO region belongs to + */ +struct libie_pci_mmio_region { + struct list_head list; + void __iomem *addr; + resource_size_t offset; + resource_size_t size; + u16 bar_idx; +}; + +/** + * struct libie_mmio_info - contains list of MMIO regions + * @pdev: PCI device pointer + * @mmio_list: list of MMIO regions + */ +struct libie_mmio_info { + struct pci_dev *pdev; + struct list_head mmio_list; +}; + +#define libie_pci_map_mmio_region(mmio_info, offset, size, ...) \ + __libie_pci_map_mmio_region(mmio_info, offset, size, \ + COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__) + +#define libie_pci_get_mmio_addr(mmio_info, offset, ...) \ + __libie_pci_get_mmio_addr(mmio_info, offset, \ + COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__) + +bool __libie_pci_map_mmio_region(struct libie_mmio_info *mmio_info, + resource_size_t offset, resource_size_t size, + int num_args, ...); +void __iomem *__libie_pci_get_mmio_addr(struct libie_mmio_info *mmio_info, + resource_size_t offset, + int num_args, ...); +void libie_pci_unmap_all_mmio_regions(struct libie_mmio_info *mmio_info); +void libie_pci_unmap_fltr_regs(struct libie_mmio_info *mmio_info, + bool (*fltr)(struct libie_mmio_info *mmio_info, + struct libie_pci_mmio_region *reg)); +int libie_pci_init_dev(struct pci_dev *pdev); + +#endif /* __LIBIE_PCI_H */ diff --git a/include/linux/avf/virtchnl.h b/include/linux/net/intel/virtchnl.h index 11bdab5522fd..11bdab5522fd 100644 --- a/include/linux/avf/virtchnl.h +++ b/include/linux/net/intel/virtchnl.h diff --git a/include/linux/net/intel/virtchnl2.h b/include/linux/net/intel/virtchnl2.h new file mode 100644 index 000000000000..39fea65c075c --- /dev/null +++ b/include/linux/net/intel/virtchnl2.h @@ -0,0 +1,1819 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 2023 Intel Corporation */ + +#ifndef _VIRTCHNL2_H_ +#define _VIRTCHNL2_H_ + +#include <linux/if_ether.h> + +/* All opcodes associated with virtchnl2 are prefixed with virtchnl2 or + * VIRTCHNL2. Any future opcodes, offloads/capabilities, structures, + * and defines must be prefixed with virtchnl2 or VIRTCHNL2 to avoid confusion. + * + * PF/VF uses the virtchnl2 interface defined in this header file to communicate + * with device Control Plane (CP). Driver and the CP may run on different + * platforms with different endianness. To avoid byte order discrepancies, + * all the structures in this header follow little-endian format. + * + * This is an interface definition file where existing enums and their values + * must remain unchanged over time, so we specify explicit values for all enums. + */ + +/* This macro is used to generate compilation errors if a structure + * is not exactly the correct length. + */ +#define VIRTCHNL2_CHECK_STRUCT_LEN(n, X) \ + static_assert((n) == sizeof(struct X)) + +/* New major set of opcodes introduced and so leaving room for + * old misc opcodes to be added in future. Also these opcodes may only + * be used if both the PF and VF have successfully negotiated the + * VIRTCHNL version as 2.0 during VIRTCHNL2_OP_VERSION exchange. + */ +enum virtchnl2_op { + VIRTCHNL2_OP_UNKNOWN = 0, + VIRTCHNL2_OP_VERSION = 1, + VIRTCHNL2_OP_GET_CAPS = 500, + VIRTCHNL2_OP_CREATE_VPORT = 501, + VIRTCHNL2_OP_DESTROY_VPORT = 502, + VIRTCHNL2_OP_ENABLE_VPORT = 503, + VIRTCHNL2_OP_DISABLE_VPORT = 504, + VIRTCHNL2_OP_CONFIG_TX_QUEUES = 505, + VIRTCHNL2_OP_CONFIG_RX_QUEUES = 506, + VIRTCHNL2_OP_ENABLE_QUEUES = 507, + VIRTCHNL2_OP_DISABLE_QUEUES = 508, + VIRTCHNL2_OP_ADD_QUEUES = 509, + VIRTCHNL2_OP_DEL_QUEUES = 510, + VIRTCHNL2_OP_MAP_QUEUE_VECTOR = 511, + VIRTCHNL2_OP_UNMAP_QUEUE_VECTOR = 512, + VIRTCHNL2_OP_GET_RSS_KEY = 513, + VIRTCHNL2_OP_SET_RSS_KEY = 514, + VIRTCHNL2_OP_GET_RSS_LUT = 515, + VIRTCHNL2_OP_SET_RSS_LUT = 516, + VIRTCHNL2_OP_GET_RSS_HASH = 517, + VIRTCHNL2_OP_SET_RSS_HASH = 518, + VIRTCHNL2_OP_SET_SRIOV_VFS = 519, + VIRTCHNL2_OP_ALLOC_VECTORS = 520, + VIRTCHNL2_OP_DEALLOC_VECTORS = 521, + VIRTCHNL2_OP_EVENT = 522, + VIRTCHNL2_OP_GET_STATS = 523, + VIRTCHNL2_OP_RESET_VF = 524, + VIRTCHNL2_OP_GET_EDT_CAPS = 525, + VIRTCHNL2_OP_GET_PTYPE_INFO = 526, + /* Opcode 527 and 528 are reserved for VIRTCHNL2_OP_GET_PTYPE_ID and + * VIRTCHNL2_OP_GET_PTYPE_INFO_RAW. + */ + VIRTCHNL2_OP_RDMA = 529, + /* Opcodes 530 through 533 are reserved. */ + VIRTCHNL2_OP_LOOPBACK = 534, + VIRTCHNL2_OP_ADD_MAC_ADDR = 535, + VIRTCHNL2_OP_DEL_MAC_ADDR = 536, + VIRTCHNL2_OP_CONFIG_PROMISCUOUS_MODE = 537, + + /* TimeSync opcodes */ + VIRTCHNL2_OP_PTP_GET_CAPS = 541, + VIRTCHNL2_OP_PTP_GET_VPORT_TX_TSTAMP = 542, + VIRTCHNL2_OP_PTP_GET_DEV_CLK_TIME = 543, + VIRTCHNL2_OP_PTP_GET_CROSS_TIME = 544, + VIRTCHNL2_OP_PTP_SET_DEV_CLK_TIME = 545, + VIRTCHNL2_OP_PTP_ADJ_DEV_CLK_FINE = 546, + VIRTCHNL2_OP_PTP_ADJ_DEV_CLK_TIME = 547, + VIRTCHNL2_OP_PTP_GET_VPORT_TX_TSTAMP_CAPS = 548, + VIRTCHNL2_OP_GET_LAN_MEMORY_REGIONS = 549, + /* Opcode 550 is reserved */ + VIRTCHNL2_OP_ADD_FLOW_RULE = 551, + VIRTCHNL2_OP_GET_FLOW_RULE = 552, + VIRTCHNL2_OP_DEL_FLOW_RULE = 553, +}; + +/** + * enum virtchnl2_vport_type - Type of virtual port. + * @VIRTCHNL2_VPORT_TYPE_DEFAULT: Default virtual port type. + */ +enum virtchnl2_vport_type { + VIRTCHNL2_VPORT_TYPE_DEFAULT = 0, +}; + +/** + * enum virtchnl2_queue_model - Type of queue model. + * @VIRTCHNL2_QUEUE_MODEL_SINGLE: Single queue model. + * @VIRTCHNL2_QUEUE_MODEL_SPLIT: Split queue model. + * + * In the single queue model, the same transmit descriptor queue is used by + * software to post descriptors to hardware and by hardware to post completed + * descriptors to software. + * Likewise, the same receive descriptor queue is used by hardware to post + * completions to software and by software to post buffers to hardware. + * + * In the split queue model, hardware uses transmit completion queues to post + * descriptor/buffer completions to software, while software uses transmit + * descriptor queues to post descriptors to hardware. + * Likewise, hardware posts descriptor completions to the receive descriptor + * queue, while software uses receive buffer queues to post buffers to hardware. + */ +enum virtchnl2_queue_model { + VIRTCHNL2_QUEUE_MODEL_SINGLE = 0, + VIRTCHNL2_QUEUE_MODEL_SPLIT = 1, +}; + +/* Checksum offload capability flags */ +enum virtchnl2_cap_txrx_csum { + VIRTCHNL2_CAP_TX_CSUM_L3_IPV4 = BIT(0), + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP = BIT(1), + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP = BIT(2), + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP = BIT(3), + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP = BIT(4), + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP = BIT(5), + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP = BIT(6), + VIRTCHNL2_CAP_TX_CSUM_GENERIC = BIT(7), + VIRTCHNL2_CAP_RX_CSUM_L3_IPV4 = BIT(8), + VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP = BIT(9), + VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP = BIT(10), + VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP = BIT(11), + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP = BIT(12), + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP = BIT(13), + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP = BIT(14), + VIRTCHNL2_CAP_RX_CSUM_GENERIC = BIT(15), + VIRTCHNL2_CAP_TX_CSUM_L3_SINGLE_TUNNEL = BIT(16), + VIRTCHNL2_CAP_TX_CSUM_L3_DOUBLE_TUNNEL = BIT(17), + VIRTCHNL2_CAP_RX_CSUM_L3_SINGLE_TUNNEL = BIT(18), + VIRTCHNL2_CAP_RX_CSUM_L3_DOUBLE_TUNNEL = BIT(19), + VIRTCHNL2_CAP_TX_CSUM_L4_SINGLE_TUNNEL = BIT(20), + VIRTCHNL2_CAP_TX_CSUM_L4_DOUBLE_TUNNEL = BIT(21), + VIRTCHNL2_CAP_RX_CSUM_L4_SINGLE_TUNNEL = BIT(22), + VIRTCHNL2_CAP_RX_CSUM_L4_DOUBLE_TUNNEL = BIT(23), +}; + +/* Segmentation offload capability flags */ +enum virtchnl2_cap_seg { + VIRTCHNL2_CAP_SEG_IPV4_TCP = BIT(0), + VIRTCHNL2_CAP_SEG_IPV4_UDP = BIT(1), + VIRTCHNL2_CAP_SEG_IPV4_SCTP = BIT(2), + VIRTCHNL2_CAP_SEG_IPV6_TCP = BIT(3), + VIRTCHNL2_CAP_SEG_IPV6_UDP = BIT(4), + VIRTCHNL2_CAP_SEG_IPV6_SCTP = BIT(5), + VIRTCHNL2_CAP_SEG_GENERIC = BIT(6), + VIRTCHNL2_CAP_SEG_TX_SINGLE_TUNNEL = BIT(7), + VIRTCHNL2_CAP_SEG_TX_DOUBLE_TUNNEL = BIT(8), +}; + +/* Receive Side Scaling and Flow Steering Flow type capability flags */ +enum virtchnl2_flow_types { + VIRTCHNL2_FLOW_IPV4_TCP = BIT(0), + VIRTCHNL2_FLOW_IPV4_UDP = BIT(1), + VIRTCHNL2_FLOW_IPV4_SCTP = BIT(2), + VIRTCHNL2_FLOW_IPV4_OTHER = BIT(3), + VIRTCHNL2_FLOW_IPV6_TCP = BIT(4), + VIRTCHNL2_FLOW_IPV6_UDP = BIT(5), + VIRTCHNL2_FLOW_IPV6_SCTP = BIT(6), + VIRTCHNL2_FLOW_IPV6_OTHER = BIT(7), + VIRTCHNL2_FLOW_IPV4_AH = BIT(8), + VIRTCHNL2_FLOW_IPV4_ESP = BIT(9), + VIRTCHNL2_FLOW_IPV4_AH_ESP = BIT(10), + VIRTCHNL2_FLOW_IPV6_AH = BIT(11), + VIRTCHNL2_FLOW_IPV6_ESP = BIT(12), + VIRTCHNL2_FLOW_IPV6_AH_ESP = BIT(13), +}; + +/* Header split capability flags */ +enum virtchnl2_cap_rx_hsplit_at { + /* for prepended metadata */ + VIRTCHNL2_CAP_RX_HSPLIT_AT_L2 = BIT(0), + /* all VLANs go into header buffer */ + VIRTCHNL2_CAP_RX_HSPLIT_AT_L3 = BIT(1), + VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V4 = BIT(2), + VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V6 = BIT(3), +}; + +/* Receive Side Coalescing offload capability flags */ +enum virtchnl2_cap_rsc { + VIRTCHNL2_CAP_RSC_IPV4_TCP = BIT(0), + VIRTCHNL2_CAP_RSC_IPV4_SCTP = BIT(1), + VIRTCHNL2_CAP_RSC_IPV6_TCP = BIT(2), + VIRTCHNL2_CAP_RSC_IPV6_SCTP = BIT(3), +}; + +/* Other capability flags */ +enum virtchnl2_cap_other { + VIRTCHNL2_CAP_RDMA = BIT_ULL(0), + VIRTCHNL2_CAP_SRIOV = BIT_ULL(1), + VIRTCHNL2_CAP_MACFILTER = BIT_ULL(2), + /* Other capability 3 is available + * Queue based scheduling using split queue model + */ + VIRTCHNL2_CAP_SPLITQ_QSCHED = BIT_ULL(4), + VIRTCHNL2_CAP_CRC = BIT_ULL(5), + VIRTCHNL2_CAP_ADQ = BIT_ULL(6), + VIRTCHNL2_CAP_WB_ON_ITR = BIT_ULL(7), + VIRTCHNL2_CAP_PROMISC = BIT_ULL(8), + VIRTCHNL2_CAP_LINK_SPEED = BIT_ULL(9), + VIRTCHNL2_CAP_INLINE_IPSEC = BIT_ULL(10), + VIRTCHNL2_CAP_LARGE_NUM_QUEUES = BIT_ULL(11), + VIRTCHNL2_CAP_VLAN = BIT_ULL(12), + VIRTCHNL2_CAP_PTP = BIT_ULL(13), + /* EDT: Earliest Departure Time capability used for Timing Wheel */ + VIRTCHNL2_CAP_EDT = BIT_ULL(14), + VIRTCHNL2_CAP_ADV_RSS = BIT_ULL(15), + /* Other capability 16 is available */ + VIRTCHNL2_CAP_RX_FLEX_DESC = BIT_ULL(17), + VIRTCHNL2_CAP_PTYPE = BIT_ULL(18), + VIRTCHNL2_CAP_LOOPBACK = BIT_ULL(19), + /* Other capability 20 is reserved */ + VIRTCHNL2_CAP_FLOW_STEER = BIT_ULL(21), + VIRTCHNL2_CAP_LAN_MEMORY_REGIONS = BIT_ULL(22), + + /* this must be the last capability */ + VIRTCHNL2_CAP_OEM = BIT_ULL(63), +}; + +/** + * enum virtchnl2_action_types - Available actions for sideband flow steering + * @VIRTCHNL2_ACTION_DROP: Drop the packet + * @VIRTCHNL2_ACTION_PASSTHRU: Forward the packet to the next classifier/stage + * @VIRTCHNL2_ACTION_QUEUE: Forward the packet to a receive queue + * @VIRTCHNL2_ACTION_Q_GROUP: Forward the packet to a receive queue group + * @VIRTCHNL2_ACTION_MARK: Mark the packet with specific marker value + * @VIRTCHNL2_ACTION_COUNT: Increment the corresponding counter + */ + +enum virtchnl2_action_types { + VIRTCHNL2_ACTION_DROP = BIT(0), + VIRTCHNL2_ACTION_PASSTHRU = BIT(1), + VIRTCHNL2_ACTION_QUEUE = BIT(2), + VIRTCHNL2_ACTION_Q_GROUP = BIT(3), + VIRTCHNL2_ACTION_MARK = BIT(4), + VIRTCHNL2_ACTION_COUNT = BIT(5), +}; + +/* underlying device type */ +enum virtchl2_device_type { + VIRTCHNL2_MEV_DEVICE = 0, +}; + +/** + * enum virtchnl2_txq_sched_mode - Transmit Queue Scheduling Modes. + * @VIRTCHNL2_TXQ_SCHED_MODE_QUEUE: Queue mode is the legacy mode i.e. inorder + * completions where descriptors and buffers + * are completed at the same time. + * @VIRTCHNL2_TXQ_SCHED_MODE_FLOW: Flow scheduling mode allows for out of order + * packet processing where descriptors are + * cleaned in order, but buffers can be + * completed out of order. + */ +enum virtchnl2_txq_sched_mode { + VIRTCHNL2_TXQ_SCHED_MODE_QUEUE = 0, + VIRTCHNL2_TXQ_SCHED_MODE_FLOW = 1, +}; + +/** + * enum virtchnl2_rxq_flags - Receive Queue Feature flags. + * @VIRTCHNL2_RXQ_RSC: Rx queue RSC flag. + * @VIRTCHNL2_RXQ_HDR_SPLIT: Rx queue header split flag. + * @VIRTCHNL2_RXQ_IMMEDIATE_WRITE_BACK: When set, packet descriptors are flushed + * by hardware immediately after processing + * each packet. + * @VIRTCHNL2_RX_DESC_SIZE_16BYTE: Rx queue 16 byte descriptor size. + * @VIRTCHNL2_RX_DESC_SIZE_32BYTE: Rx queue 32 byte descriptor size. + */ +enum virtchnl2_rxq_flags { + VIRTCHNL2_RXQ_RSC = BIT(0), + VIRTCHNL2_RXQ_HDR_SPLIT = BIT(1), + VIRTCHNL2_RXQ_IMMEDIATE_WRITE_BACK = BIT(2), + VIRTCHNL2_RX_DESC_SIZE_16BYTE = BIT(3), + VIRTCHNL2_RX_DESC_SIZE_32BYTE = BIT(4), +}; + +/* Type of RSS algorithm */ +enum virtchnl2_rss_alg { + VIRTCHNL2_RSS_ALG_TOEPLITZ_ASYMMETRIC = 0, + VIRTCHNL2_RSS_ALG_R_ASYMMETRIC = 1, + VIRTCHNL2_RSS_ALG_TOEPLITZ_SYMMETRIC = 2, + VIRTCHNL2_RSS_ALG_XOR_SYMMETRIC = 3, +}; + +/* Type of event */ +enum virtchnl2_event_codes { + VIRTCHNL2_EVENT_UNKNOWN = 0, + VIRTCHNL2_EVENT_LINK_CHANGE = 1, + /* Event type 2, 3 are reserved */ +}; + +/* Transmit and Receive queue types are valid in legacy as well as split queue + * models. With Split Queue model, 2 additional types are introduced - + * TX_COMPLETION and RX_BUFFER. In split queue model, receive corresponds to + * the queue where hardware posts completions. + */ +enum virtchnl2_queue_type { + VIRTCHNL2_QUEUE_TYPE_TX = 0, + VIRTCHNL2_QUEUE_TYPE_RX = 1, + VIRTCHNL2_QUEUE_TYPE_TX_COMPLETION = 2, + VIRTCHNL2_QUEUE_TYPE_RX_BUFFER = 3, + VIRTCHNL2_QUEUE_TYPE_CONFIG_TX = 4, + VIRTCHNL2_QUEUE_TYPE_CONFIG_RX = 5, + /* Queue types 6, 7, 8, 9 are reserved */ + VIRTCHNL2_QUEUE_TYPE_MBX_TX = 10, + VIRTCHNL2_QUEUE_TYPE_MBX_RX = 11, +}; + +/* Interrupt throttling rate index */ +enum virtchnl2_itr_idx { + VIRTCHNL2_ITR_IDX_0 = 0, + VIRTCHNL2_ITR_IDX_1 = 1, +}; + +/** + * enum virtchnl2_mac_addr_type - MAC address types. + * @VIRTCHNL2_MAC_ADDR_PRIMARY: PF/VF driver should set this type for the + * primary/device unicast MAC address filter for + * VIRTCHNL2_OP_ADD_MAC_ADDR and + * VIRTCHNL2_OP_DEL_MAC_ADDR. This allows for the + * underlying control plane function to accurately + * track the MAC address and for VM/function reset. + * + * @VIRTCHNL2_MAC_ADDR_EXTRA: PF/VF driver should set this type for any extra + * unicast and/or multicast filters that are being + * added/deleted via VIRTCHNL2_OP_ADD_MAC_ADDR or + * VIRTCHNL2_OP_DEL_MAC_ADDR. + */ +enum virtchnl2_mac_addr_type { + VIRTCHNL2_MAC_ADDR_PRIMARY = 1, + VIRTCHNL2_MAC_ADDR_EXTRA = 2, +}; + +/* Flags used for promiscuous mode */ +enum virtchnl2_promisc_flags { + VIRTCHNL2_UNICAST_PROMISC = BIT(0), + VIRTCHNL2_MULTICAST_PROMISC = BIT(1), +}; + +/* Protocol header type within a packet segment. A segment consists of one or + * more protocol headers that make up a logical group of protocol headers. Each + * logical group of protocol headers encapsulates or is encapsulated using/by + * tunneling or encapsulation protocols for network virtualization. + */ +enum virtchnl2_proto_hdr_type { + /* VIRTCHNL2_PROTO_HDR_ANY is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_ANY = 0, + VIRTCHNL2_PROTO_HDR_PRE_MAC = 1, + /* VIRTCHNL2_PROTO_HDR_MAC is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_MAC = 2, + VIRTCHNL2_PROTO_HDR_POST_MAC = 3, + VIRTCHNL2_PROTO_HDR_ETHERTYPE = 4, + VIRTCHNL2_PROTO_HDR_VLAN = 5, + VIRTCHNL2_PROTO_HDR_SVLAN = 6, + VIRTCHNL2_PROTO_HDR_CVLAN = 7, + VIRTCHNL2_PROTO_HDR_MPLS = 8, + VIRTCHNL2_PROTO_HDR_UMPLS = 9, + VIRTCHNL2_PROTO_HDR_MMPLS = 10, + VIRTCHNL2_PROTO_HDR_PTP = 11, + VIRTCHNL2_PROTO_HDR_CTRL = 12, + VIRTCHNL2_PROTO_HDR_LLDP = 13, + VIRTCHNL2_PROTO_HDR_ARP = 14, + VIRTCHNL2_PROTO_HDR_ECP = 15, + VIRTCHNL2_PROTO_HDR_EAPOL = 16, + VIRTCHNL2_PROTO_HDR_PPPOD = 17, + VIRTCHNL2_PROTO_HDR_PPPOE = 18, + /* VIRTCHNL2_PROTO_HDR_IPV4 is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_IPV4 = 19, + /* IPv4 and IPv6 Fragment header types are only associated to + * VIRTCHNL2_PROTO_HDR_IPV4 and VIRTCHNL2_PROTO_HDR_IPV6 respectively, + * cannot be used independently. + */ + /* VIRTCHNL2_PROTO_HDR_IPV4_FRAG is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_IPV4_FRAG = 20, + /* VIRTCHNL2_PROTO_HDR_IPV6 is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_IPV6 = 21, + /* VIRTCHNL2_PROTO_HDR_IPV6_FRAG is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_IPV6_FRAG = 22, + VIRTCHNL2_PROTO_HDR_IPV6_EH = 23, + /* VIRTCHNL2_PROTO_HDR_UDP is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_UDP = 24, + /* VIRTCHNL2_PROTO_HDR_TCP is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_TCP = 25, + /* VIRTCHNL2_PROTO_HDR_SCTP is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_SCTP = 26, + /* VIRTCHNL2_PROTO_HDR_ICMP is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_ICMP = 27, + /* VIRTCHNL2_PROTO_HDR_ICMPV6 is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_ICMPV6 = 28, + VIRTCHNL2_PROTO_HDR_IGMP = 29, + VIRTCHNL2_PROTO_HDR_AH = 30, + VIRTCHNL2_PROTO_HDR_ESP = 31, + VIRTCHNL2_PROTO_HDR_IKE = 32, + VIRTCHNL2_PROTO_HDR_NATT_KEEP = 33, + /* VIRTCHNL2_PROTO_HDR_PAY is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_PAY = 34, + VIRTCHNL2_PROTO_HDR_L2TPV2 = 35, + VIRTCHNL2_PROTO_HDR_L2TPV2_CONTROL = 36, + VIRTCHNL2_PROTO_HDR_L2TPV3 = 37, + VIRTCHNL2_PROTO_HDR_GTP = 38, + VIRTCHNL2_PROTO_HDR_GTP_EH = 39, + VIRTCHNL2_PROTO_HDR_GTPCV2 = 40, + VIRTCHNL2_PROTO_HDR_GTPC_TEID = 41, + VIRTCHNL2_PROTO_HDR_GTPU = 42, + VIRTCHNL2_PROTO_HDR_GTPU_UL = 43, + VIRTCHNL2_PROTO_HDR_GTPU_DL = 44, + VIRTCHNL2_PROTO_HDR_ECPRI = 45, + VIRTCHNL2_PROTO_HDR_VRRP = 46, + VIRTCHNL2_PROTO_HDR_OSPF = 47, + /* VIRTCHNL2_PROTO_HDR_TUN is a mandatory protocol id */ + VIRTCHNL2_PROTO_HDR_TUN = 48, + VIRTCHNL2_PROTO_HDR_GRE = 49, + VIRTCHNL2_PROTO_HDR_NVGRE = 50, + VIRTCHNL2_PROTO_HDR_VXLAN = 51, + VIRTCHNL2_PROTO_HDR_VXLAN_GPE = 52, + VIRTCHNL2_PROTO_HDR_GENEVE = 53, + VIRTCHNL2_PROTO_HDR_NSH = 54, + VIRTCHNL2_PROTO_HDR_QUIC = 55, + VIRTCHNL2_PROTO_HDR_PFCP = 56, + VIRTCHNL2_PROTO_HDR_PFCP_NODE = 57, + VIRTCHNL2_PROTO_HDR_PFCP_SESSION = 58, + VIRTCHNL2_PROTO_HDR_RTP = 59, + VIRTCHNL2_PROTO_HDR_ROCE = 60, + VIRTCHNL2_PROTO_HDR_ROCEV1 = 61, + VIRTCHNL2_PROTO_HDR_ROCEV2 = 62, + /* Protocol ids up to 32767 are reserved. + * 32768 - 65534 are used for user defined protocol ids. + * VIRTCHNL2_PROTO_HDR_NO_PROTO is a mandatory protocol id. + */ + VIRTCHNL2_PROTO_HDR_NO_PROTO = 65535, +}; + +enum virtchl2_version { + VIRTCHNL2_VERSION_MINOR_0 = 0, + VIRTCHNL2_VERSION_MAJOR_2 = 2, +}; + +/** + * struct virtchnl2_edt_caps - Get EDT granularity and time horizon. + * @tstamp_granularity_ns: Timestamp granularity in nanoseconds. + * @time_horizon_ns: Total time window in nanoseconds. + * + * Associated with VIRTCHNL2_OP_GET_EDT_CAPS. + */ +struct virtchnl2_edt_caps { + __le64 tstamp_granularity_ns; + __le64 time_horizon_ns; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_edt_caps); + +/** + * struct virtchnl2_version_info - Version information. + * @major: Major version. + * @minor: Minor version. + * + * PF/VF posts its version number to the CP. CP responds with its version number + * in the same format, along with a return code. + * If there is a major version mismatch, then the PF/VF cannot operate. + * If there is a minor version mismatch, then the PF/VF can operate but should + * add a warning to the system log. + * + * This version opcode MUST always be specified as == 1, regardless of other + * changes in the API. The CP must always respond to this message without + * error regardless of version mismatch. + * + * Associated with VIRTCHNL2_OP_VERSION. + */ +struct virtchnl2_version_info { + __le32 major; + __le32 minor; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_version_info); + +/** + * struct virtchnl2_get_capabilities - Capabilities info. + * @csum_caps: See enum virtchnl2_cap_txrx_csum. + * @seg_caps: See enum virtchnl2_cap_seg. + * @hsplit_caps: See enum virtchnl2_cap_rx_hsplit_at. + * @rsc_caps: See enum virtchnl2_cap_rsc. + * @rss_caps: See enum virtchnl2_flow_types. + * @other_caps: See enum virtchnl2_cap_other. + * @mailbox_dyn_ctl: DYN_CTL register offset and vector id for mailbox + * provided by CP. + * @mailbox_vector_id: Mailbox vector id. + * @num_allocated_vectors: Maximum number of allocated vectors for the device. + * @max_rx_q: Maximum number of supported Rx queues. + * @max_tx_q: Maximum number of supported Tx queues. + * @max_rx_bufq: Maximum number of supported buffer queues. + * @max_tx_complq: Maximum number of supported completion queues. + * @max_sriov_vfs: The PF sends the maximum VFs it is requesting. The CP + * responds with the maximum VFs granted. + * @max_vports: Maximum number of vports that can be supported. + * @default_num_vports: Default number of vports driver should allocate on load. + * @max_tx_hdr_size: Max header length hardware can parse/checksum, in bytes. + * @max_sg_bufs_per_tx_pkt: Max number of scatter gather buffers that can be + * sent per transmit packet without needing to be + * linearized. + * @pad: Padding. + * @reserved: Reserved. + * @device_type: See enum virtchl2_device_type. + * @min_sso_packet_len: Min packet length supported by device for single + * segment offload. + * @max_hdr_buf_per_lso: Max number of header buffers that can be used for + * an LSO. + * @num_rdma_allocated_vectors: Maximum number of allocated RDMA vectors for + * the device. + * @pad1: Padding for future extensions. + * + * Dataplane driver sends this message to CP to negotiate capabilities and + * provides a virtchnl2_get_capabilities structure with its desired + * capabilities, max_sriov_vfs and num_allocated_vectors. + * CP responds with a virtchnl2_get_capabilities structure updated + * with allowed capabilities and the other fields as below. + * If PF sets max_sriov_vfs as 0, CP will respond with max number of VFs + * that can be created by this PF. For any other value 'n', CP responds + * with max_sriov_vfs set to min(n, x) where x is the max number of VFs + * allowed by CP's policy. max_sriov_vfs is not applicable for VFs. + * If dataplane driver sets num_allocated_vectors as 0, CP will respond with 1 + * which is default vector associated with the default mailbox. For any other + * value 'n', CP responds with a value <= n based on the CP's policy of + * max number of vectors for a PF. + * CP will respond with the vector ID of mailbox allocated to the PF in + * mailbox_vector_id and the number of itr index registers in itr_idx_map. + * It also responds with default number of vports that the dataplane driver + * should comeup with in default_num_vports and maximum number of vports that + * can be supported in max_vports. + * + * Associated with VIRTCHNL2_OP_GET_CAPS. + */ +struct virtchnl2_get_capabilities { + __le32 csum_caps; + __le32 seg_caps; + __le32 hsplit_caps; + __le32 rsc_caps; + __le64 rss_caps; + __le64 other_caps; + __le32 mailbox_dyn_ctl; + __le16 mailbox_vector_id; + __le16 num_allocated_vectors; + __le16 max_rx_q; + __le16 max_tx_q; + __le16 max_rx_bufq; + __le16 max_tx_complq; + __le16 max_sriov_vfs; + __le16 max_vports; + __le16 default_num_vports; + __le16 max_tx_hdr_size; + u8 max_sg_bufs_per_tx_pkt; + u8 pad[3]; + u8 reserved[4]; + __le32 device_type; + u8 min_sso_packet_len; + u8 max_hdr_buf_per_lso; + __le16 num_rdma_allocated_vectors; + u8 pad1[8]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(80, virtchnl2_get_capabilities); + +/** + * struct virtchnl2_queue_reg_chunk - Single queue chunk. + * @type: See enum virtchnl2_queue_type. + * @start_queue_id: Start Queue ID. + * @num_queues: Number of queues in the chunk. + * @pad: Padding. + * @qtail_reg_start: Queue tail register offset. + * @qtail_reg_spacing: Queue tail register spacing. + * @pad1: Padding for future extensions. + */ +struct virtchnl2_queue_reg_chunk { + __le32 type; + __le32 start_queue_id; + __le32 num_queues; + __le32 pad; + __le64 qtail_reg_start; + __le32 qtail_reg_spacing; + u8 pad1[4]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(32, virtchnl2_queue_reg_chunk); + +/** + * struct virtchnl2_queue_reg_chunks - Specify several chunks of contiguous + * queues. + * @num_chunks: Number of chunks. + * @pad: Padding. + * @chunks: Chunks of queue info. + */ +struct virtchnl2_queue_reg_chunks { + __le16 num_chunks; + u8 pad[6]; + struct virtchnl2_queue_reg_chunk chunks[] __counted_by_le(num_chunks); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_queue_reg_chunks); + +/** + * enum virtchnl2_vport_flags - Vport flags that indicate vport capabilities. + * @VIRTCHNL2_VPORT_UPLINK_PORT: Representatives of underlying physical ports + * @VIRTCHNL2_VPORT_INLINE_FLOW_STEER: Inline flow steering enabled + * @VIRTCHNL2_VPORT_INLINE_FLOW_STEER_RXQ: Inline flow steering enabled + * with explicit Rx queue action + * @VIRTCHNL2_VPORT_SIDEBAND_FLOW_STEER: Sideband flow steering enabled + * @VIRTCHNL2_VPORT_ENABLE_RDMA: RDMA is enabled for this vport + */ +enum virtchnl2_vport_flags { + VIRTCHNL2_VPORT_UPLINK_PORT = BIT(0), + VIRTCHNL2_VPORT_INLINE_FLOW_STEER = BIT(1), + VIRTCHNL2_VPORT_INLINE_FLOW_STEER_RXQ = BIT(2), + VIRTCHNL2_VPORT_SIDEBAND_FLOW_STEER = BIT(3), + VIRTCHNL2_VPORT_ENABLE_RDMA = BIT(4), +}; + +/** + * struct virtchnl2_create_vport - Create vport config info. + * @vport_type: See enum virtchnl2_vport_type. + * @txq_model: See virtchnl2_queue_model. + * @rxq_model: See virtchnl2_queue_model. + * @num_tx_q: Number of Tx queues. + * @num_tx_complq: Valid only if txq_model is split queue. + * @num_rx_q: Number of Rx queues. + * @num_rx_bufq: Valid only if rxq_model is split queue. + * @default_rx_q: Relative receive queue index to be used as default. + * @vport_index: Used to align PF and CP in case of default multiple vports, + * it is filled by the PF and CP returns the same value, to + * enable the driver to support multiple asynchronous parallel + * CREATE_VPORT requests and associate a response to a specific + * request. + * @max_mtu: Max MTU. CP populates this field on response. + * @vport_id: Vport id. CP populates this field on response. + * @default_mac_addr: Default MAC address. + * @vport_flags: See enum virtchnl2_vport_flags. + * @rx_desc_ids: See VIRTCHNL2_RX_DESC_IDS definitions. + * @tx_desc_ids: See VIRTCHNL2_TX_DESC_IDS definitions. + * @pad1: Padding. + * @inline_flow_caps: Bit mask of supported inline-flow-steering + * flow types (See enum virtchnl2_flow_types) + * @sideband_flow_caps: Bit mask of supported sideband-flow-steering + * flow types (See enum virtchnl2_flow_types) + * @sideband_flow_actions: Bit mask of supported action types + * for sideband flow steering (See enum virtchnl2_action_types) + * @flow_steer_max_rules: Max rules allowed for inline and sideband + * flow steering combined + * @rss_algorithm: RSS algorithm. + * @rss_key_size: RSS key size. + * @rss_lut_size: RSS LUT size. + * @rx_split_pos: See enum virtchnl2_cap_rx_hsplit_at. + * @pad2: Padding. + * @chunks: Chunks of contiguous queues. + * + * PF sends this message to CP to create a vport by filling in required + * fields of virtchnl2_create_vport structure. + * CP responds with the updated virtchnl2_create_vport structure containing the + * necessary fields followed by chunks which in turn will have an array of + * num_chunks entries of virtchnl2_queue_chunk structures. + * + * Associated with VIRTCHNL2_OP_CREATE_VPORT. + */ +struct virtchnl2_create_vport { + __le16 vport_type; + __le16 txq_model; + __le16 rxq_model; + __le16 num_tx_q; + __le16 num_tx_complq; + __le16 num_rx_q; + __le16 num_rx_bufq; + __le16 default_rx_q; + __le16 vport_index; + /* CP populates the following fields on response */ + __le16 max_mtu; + __le32 vport_id; + u8 default_mac_addr[ETH_ALEN]; + __le16 vport_flags; + __le64 rx_desc_ids; + __le64 tx_desc_ids; + u8 pad1[48]; + __le64 inline_flow_caps; + __le64 sideband_flow_caps; + __le32 sideband_flow_actions; + __le32 flow_steer_max_rules; + __le32 rss_algorithm; + __le16 rss_key_size; + __le16 rss_lut_size; + __le32 rx_split_pos; + u8 pad2[20]; + struct virtchnl2_queue_reg_chunks chunks; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(160, virtchnl2_create_vport); + +/** + * struct virtchnl2_vport - Vport ID info. + * @vport_id: Vport id. + * @pad: Padding for future extensions. + * + * PF sends this message to CP to destroy, enable or disable a vport by filling + * in the vport_id in virtchnl2_vport structure. + * CP responds with the status of the requested operation. + * + * Associated with VIRTCHNL2_OP_DESTROY_VPORT, VIRTCHNL2_OP_ENABLE_VPORT, + * VIRTCHNL2_OP_DISABLE_VPORT. + */ +struct virtchnl2_vport { + __le32 vport_id; + u8 pad[4]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_vport); + +/** + * struct virtchnl2_txq_info - Transmit queue config info + * @dma_ring_addr: DMA address. + * @type: See enum virtchnl2_queue_type. + * @queue_id: Queue ID. + * @relative_queue_id: Valid only if queue model is split and type is transmit + * queue. Used in many to one mapping of transmit queues to + * completion queue. + * @model: See enum virtchnl2_queue_model. + * @sched_mode: See enum virtchnl2_txq_sched_mode. + * @qflags: TX queue feature flags. + * @ring_len: Ring length. + * @tx_compl_queue_id: Valid only if queue model is split and type is transmit + * queue. + * @peer_type: Valid only if queue type is VIRTCHNL2_QUEUE_TYPE_MAILBOX_TX + * @peer_rx_queue_id: Valid only if queue type is CONFIG_TX and used to deliver + * messages for the respective CONFIG_TX queue. + * @pad: Padding. + * @egress_pasid: Egress PASID info. + * @egress_hdr_pasid: Egress HDR passid. + * @egress_buf_pasid: Egress buf passid. + * @pad1: Padding for future extensions. + */ +struct virtchnl2_txq_info { + __le64 dma_ring_addr; + __le32 type; + __le32 queue_id; + __le16 relative_queue_id; + __le16 model; + __le16 sched_mode; + __le16 qflags; + __le16 ring_len; + __le16 tx_compl_queue_id; + __le16 peer_type; + __le16 peer_rx_queue_id; + u8 pad[4]; + __le32 egress_pasid; + __le32 egress_hdr_pasid; + __le32 egress_buf_pasid; + u8 pad1[8]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(56, virtchnl2_txq_info); + +/** + * struct virtchnl2_config_tx_queues - TX queue config. + * @vport_id: Vport id. + * @num_qinfo: Number of virtchnl2_txq_info structs. + * @pad: Padding. + * @qinfo: Tx queues config info. + * + * PF sends this message to set up parameters for one or more transmit queues. + * This message contains an array of num_qinfo instances of virtchnl2_txq_info + * structures. CP configures requested queues and returns a status code. If + * num_qinfo specified is greater than the number of queues associated with the + * vport, an error is returned and no queues are configured. + * + * Associated with VIRTCHNL2_OP_CONFIG_TX_QUEUES. + */ +struct virtchnl2_config_tx_queues { + __le32 vport_id; + __le16 num_qinfo; + u8 pad[10]; + struct virtchnl2_txq_info qinfo[] __counted_by_le(num_qinfo); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_config_tx_queues); + +/** + * struct virtchnl2_rxq_info - Receive queue config info. + * @desc_ids: See VIRTCHNL2_RX_DESC_IDS definitions. + * @dma_ring_addr: See VIRTCHNL2_RX_DESC_IDS definitions. + * @type: See enum virtchnl2_queue_type. + * @queue_id: Queue id. + * @model: See enum virtchnl2_queue_model. + * @hdr_buffer_size: Header buffer size. + * @data_buffer_size: Data buffer size. + * @max_pkt_size: Max packet size. + * @ring_len: Ring length. + * @buffer_notif_stride: Buffer notification stride in units of 32-descriptors. + * This field must be a power of 2. + * @pad: Padding. + * @dma_head_wb_addr: Applicable only for receive buffer queues. + * @qflags: Applicable only for receive completion queues. + * See enum virtchnl2_rxq_flags. + * @rx_buffer_low_watermark: Rx buffer low watermark. + * @rx_bufq1_id: Buffer queue index of the first buffer queue associated with + * the Rx queue. Valid only in split queue model. + * @rx_bufq2_id: Buffer queue index of the second buffer queue associated with + * the Rx queue. Valid only in split queue model. + * @bufq2_ena: It indicates if there is a second buffer, rx_bufq2_id is valid + * only if this field is set. + * @pad1: Padding. + * @ingress_pasid: Ingress PASID. + * @ingress_hdr_pasid: Ingress PASID header. + * @ingress_buf_pasid: Ingress PASID buffer. + * @pad2: Padding for future extensions. + */ +struct virtchnl2_rxq_info { + __le64 desc_ids; + __le64 dma_ring_addr; + __le32 type; + __le32 queue_id; + __le16 model; + __le16 hdr_buffer_size; + __le32 data_buffer_size; + __le32 max_pkt_size; + __le16 ring_len; + u8 buffer_notif_stride; + u8 pad; + __le64 dma_head_wb_addr; + __le16 qflags; + __le16 rx_buffer_low_watermark; + __le16 rx_bufq1_id; + __le16 rx_bufq2_id; + u8 bufq2_ena; + u8 pad1[3]; + __le32 ingress_pasid; + __le32 ingress_hdr_pasid; + __le32 ingress_buf_pasid; + u8 pad2[16]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(88, virtchnl2_rxq_info); + +/** + * struct virtchnl2_config_rx_queues - Rx queues config. + * @vport_id: Vport id. + * @num_qinfo: Number of instances. + * @pad: Padding. + * @qinfo: Rx queues config info. + * + * PF sends this message to set up parameters for one or more receive queues. + * This message contains an array of num_qinfo instances of virtchnl2_rxq_info + * structures. CP configures requested queues and returns a status code. + * If the number of queues specified is greater than the number of queues + * associated with the vport, an error is returned and no queues are configured. + * + * Associated with VIRTCHNL2_OP_CONFIG_RX_QUEUES. + */ +struct virtchnl2_config_rx_queues { + __le32 vport_id; + __le16 num_qinfo; + u8 pad[18]; + struct virtchnl2_rxq_info qinfo[] __counted_by_le(num_qinfo); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(24, virtchnl2_config_rx_queues); + +/** + * struct virtchnl2_add_queues - data for VIRTCHNL2_OP_ADD_QUEUES. + * @vport_id: Vport id. + * @num_tx_q: Number of Tx qieues. + * @num_tx_complq: Number of Tx completion queues. + * @num_rx_q: Number of Rx queues. + * @num_rx_bufq: Number of Rx buffer queues. + * @pad: Padding. + * @chunks: Chunks of contiguous queues. + * + * PF sends this message to request additional transmit/receive queues beyond + * the ones that were assigned via CREATE_VPORT request. virtchnl2_add_queues + * structure is used to specify the number of each type of queues. + * CP responds with the same structure with the actual number of queues assigned + * followed by num_chunks of virtchnl2_queue_chunk structures. + * + * Associated with VIRTCHNL2_OP_ADD_QUEUES. + */ +struct virtchnl2_add_queues { + __le32 vport_id; + __le16 num_tx_q; + __le16 num_tx_complq; + __le16 num_rx_q; + __le16 num_rx_bufq; + u8 pad[4]; + struct virtchnl2_queue_reg_chunks chunks; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(24, virtchnl2_add_queues); + +/** + * struct virtchnl2_vector_chunk - Structure to specify a chunk of contiguous + * interrupt vectors. + * @start_vector_id: Start vector id. + * @start_evv_id: Start EVV id. + * @num_vectors: Number of vectors. + * @pad: Padding. + * @dynctl_reg_start: DYN_CTL register offset. + * @dynctl_reg_spacing: register spacing between DYN_CTL registers of 2 + * consecutive vectors. + * @itrn_reg_start: ITRN register offset. + * @itrn_reg_spacing: Register spacing between dynctl registers of 2 + * consecutive vectors. + * @itrn_index_spacing: Register spacing between itrn registers of the same + * vector where n=0..2. + * @pad1: Padding for future extensions. + * + * Register offsets and spacing provided by CP. + * Dynamic control registers are used for enabling/disabling/re-enabling + * interrupts and updating interrupt rates in the hotpath. Any changes + * to interrupt rates in the dynamic control registers will be reflected + * in the interrupt throttling rate registers. + * itrn registers are used to update interrupt rates for specific + * interrupt indices without modifying the state of the interrupt. + */ +struct virtchnl2_vector_chunk { + __le16 start_vector_id; + __le16 start_evv_id; + __le16 num_vectors; + __le16 pad; + __le32 dynctl_reg_start; + __le32 dynctl_reg_spacing; + __le32 itrn_reg_start; + __le32 itrn_reg_spacing; + __le32 itrn_index_spacing; + u8 pad1[4]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(32, virtchnl2_vector_chunk); + +/** + * struct virtchnl2_vector_chunks - chunks of contiguous interrupt vectors. + * @num_vchunks: number of vector chunks. + * @pad: Padding. + * @vchunks: Chunks of contiguous vector info. + * + * PF sends virtchnl2_vector_chunks struct to specify the vectors it is giving + * away. CP performs requested action and returns status. + * + * Associated with VIRTCHNL2_OP_DEALLOC_VECTORS. + */ +struct virtchnl2_vector_chunks { + __le16 num_vchunks; + u8 pad[14]; + struct virtchnl2_vector_chunk vchunks[] __counted_by_le(num_vchunks); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_vector_chunks); + +/** + * struct virtchnl2_alloc_vectors - vector allocation info. + * @num_vectors: Number of vectors. + * @pad: Padding. + * @vchunks: Chunks of contiguous vector info. + * + * PF sends this message to request additional interrupt vectors beyond the + * ones that were assigned via GET_CAPS request. virtchnl2_alloc_vectors + * structure is used to specify the number of vectors requested. CP responds + * with the same structure with the actual number of vectors assigned followed + * by virtchnl2_vector_chunks structure identifying the vector ids. + * + * Associated with VIRTCHNL2_OP_ALLOC_VECTORS. + */ +struct virtchnl2_alloc_vectors { + __le16 num_vectors; + u8 pad[14]; + struct virtchnl2_vector_chunks vchunks; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(32, virtchnl2_alloc_vectors); + +/** + * struct virtchnl2_rss_lut - RSS LUT info. + * @vport_id: Vport id. + * @lut_entries_start: Start of LUT entries. + * @lut_entries: Number of LUT entrties. + * @pad: Padding. + * @lut: RSS lookup table. + * + * PF sends this message to get or set RSS lookup table. Only supported if + * both PF and CP drivers set the VIRTCHNL2_CAP_RSS bit during configuration + * negotiation. + * + * Associated with VIRTCHNL2_OP_GET_RSS_LUT and VIRTCHNL2_OP_SET_RSS_LUT. + */ +struct virtchnl2_rss_lut { + __le32 vport_id; + __le16 lut_entries_start; + __le16 lut_entries; + u8 pad[4]; + __le32 lut[] __counted_by_le(lut_entries); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(12, virtchnl2_rss_lut); + +/** + * struct virtchnl2_rss_hash - RSS hash info. + * @ptype_groups: Packet type groups bitmap. + * @vport_id: Vport id. + * @pad: Padding for future extensions. + * + * PF sends these messages to get and set the hash filter enable bits for RSS. + * By default, the CP sets these to all possible traffic types that the + * hardware supports. The PF can query this value if it wants to change the + * traffic types that are hashed by the hardware. + * Only supported if both PF and CP drivers set the VIRTCHNL2_CAP_RSS bit + * during configuration negotiation. + * + * Associated with VIRTCHNL2_OP_GET_RSS_HASH and VIRTCHNL2_OP_SET_RSS_HASH + */ +struct virtchnl2_rss_hash { + __le64 ptype_groups; + __le32 vport_id; + u8 pad[4]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_rss_hash); + +/** + * struct virtchnl2_sriov_vfs_info - VFs info. + * @num_vfs: Number of VFs. + * @pad: Padding for future extensions. + * + * This message is used to set number of SRIOV VFs to be created. The actual + * allocation of resources for the VFs in terms of vport, queues and interrupts + * is done by CP. When this call completes, the IDPF driver calls + * pci_enable_sriov to let the OS instantiate the SRIOV PCIE devices. + * The number of VFs set to 0 will destroy all the VFs of this function. + * + * Associated with VIRTCHNL2_OP_SET_SRIOV_VFS. + */ +struct virtchnl2_sriov_vfs_info { + __le16 num_vfs; + __le16 pad; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(4, virtchnl2_sriov_vfs_info); + +/** + * struct virtchnl2_ptype - Packet type info. + * @ptype_id_10: 10-bit packet type. + * @ptype_id_8: 8-bit packet type. + * @proto_id_count: Number of protocol ids the packet supports, maximum of 32 + * protocol ids are supported. + * @pad: Padding. + * @proto_id: proto_id_count decides the allocation of protocol id array. + * See enum virtchnl2_proto_hdr_type. + * + * Based on the descriptor type the PF supports, CP fills ptype_id_10 or + * ptype_id_8 for flex and base descriptor respectively. If ptype_id_10 value + * is set to 0xFFFF, PF should consider this ptype as dummy one and it is the + * last ptype. + */ +struct virtchnl2_ptype { + __le16 ptype_id_10; + u8 ptype_id_8; + u8 proto_id_count; + __le16 pad; + __le16 proto_id[] __counted_by(proto_id_count); +} __packed __aligned(2); +VIRTCHNL2_CHECK_STRUCT_LEN(6, virtchnl2_ptype); + +/** + * struct virtchnl2_get_ptype_info - Packet type info. + * @start_ptype_id: Starting ptype ID. + * @num_ptypes: Number of packet types from start_ptype_id. + * @pad: Padding for future extensions. + * + * The total number of supported packet types is based on the descriptor type. + * For the flex descriptor, it is 1024 (10-bit ptype), and for the base + * descriptor, it is 256 (8-bit ptype). Send this message to the CP by + * populating the 'start_ptype_id' and the 'num_ptypes'. CP responds with the + * 'start_ptype_id', 'num_ptypes', and the array of ptype (virtchnl2_ptype) that + * are added at the end of the 'virtchnl2_get_ptype_info' message (Note: There + * is no specific field for the ptypes but are added at the end of the + * ptype info message. PF/VF is expected to extract the ptypes accordingly. + * Reason for doing this is because compiler doesn't allow nested flexible + * array fields). + * + * If all the ptypes don't fit into one mailbox buffer, CP splits the + * ptype info into multiple messages, where each message will have its own + * 'start_ptype_id', 'num_ptypes', and the ptype array itself. When CP is done + * updating all the ptype information extracted from the package (the number of + * ptypes extracted might be less than what PF/VF expects), it will append a + * dummy ptype (which has 'ptype_id_10' of 'struct virtchnl2_ptype' as 0xFFFF) + * to the ptype array. + * + * PF/VF is expected to receive multiple VIRTCHNL2_OP_GET_PTYPE_INFO messages. + * + * Associated with VIRTCHNL2_OP_GET_PTYPE_INFO. + */ +struct virtchnl2_get_ptype_info { + __le16 start_ptype_id; + __le16 num_ptypes; + __le32 pad; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_get_ptype_info); + +/** + * struct virtchnl2_vport_stats - Vport statistics. + * @vport_id: Vport id. + * @pad: Padding. + * @rx_bytes: Received bytes. + * @rx_unicast: Received unicast packets. + * @rx_multicast: Received multicast packets. + * @rx_broadcast: Received broadcast packets. + * @rx_discards: Discarded packets on receive. + * @rx_errors: Receive errors. + * @rx_unknown_protocol: Unlnown protocol. + * @tx_bytes: Transmitted bytes. + * @tx_unicast: Transmitted unicast packets. + * @tx_multicast: Transmitted multicast packets. + * @tx_broadcast: Transmitted broadcast packets. + * @tx_discards: Discarded packets on transmit. + * @tx_errors: Transmit errors. + * @rx_invalid_frame_length: Packets with invalid frame length. + * @rx_overflow_drop: Packets dropped on buffer overflow. + * + * PF/VF sends this message to CP to get the update stats by specifying the + * vport_id. CP responds with stats in struct virtchnl2_vport_stats. + * + * Associated with VIRTCHNL2_OP_GET_STATS. + */ +struct virtchnl2_vport_stats { + __le32 vport_id; + u8 pad[4]; + __le64 rx_bytes; + __le64 rx_unicast; + __le64 rx_multicast; + __le64 rx_broadcast; + __le64 rx_discards; + __le64 rx_errors; + __le64 rx_unknown_protocol; + __le64 tx_bytes; + __le64 tx_unicast; + __le64 tx_multicast; + __le64 tx_broadcast; + __le64 tx_discards; + __le64 tx_errors; + __le64 rx_invalid_frame_length; + __le64 rx_overflow_drop; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(128, virtchnl2_vport_stats); + +/** + * struct virtchnl2_event - Event info. + * @event: Event opcode. See enum virtchnl2_event_codes. + * @link_speed: Link_speed provided in Mbps. + * @vport_id: Vport ID. + * @link_status: Link status. + * @pad: Padding. + * @reserved: Reserved. + * + * CP sends this message to inform the PF/VF driver of events that may affect + * it. No direct response is expected from the driver, though it may generate + * other messages in response to this one. + * + * Associated with VIRTCHNL2_OP_EVENT. + */ +struct virtchnl2_event { + __le32 event; + __le32 link_speed; + __le32 vport_id; + u8 link_status; + u8 pad; + __le16 reserved; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_event); + +/** + * struct virtchnl2_rss_key - RSS key info. + * @vport_id: Vport id. + * @key_len: Length of RSS key. + * @pad: Padding. + * @key_flex: RSS hash key, packed bytes. + * PF/VF sends this message to get or set RSS key. Only supported if both + * PF/VF and CP drivers set the VIRTCHNL2_CAP_RSS bit during configuration + * negotiation. + * + * Associated with VIRTCHNL2_OP_GET_RSS_KEY and VIRTCHNL2_OP_SET_RSS_KEY. + */ +struct virtchnl2_rss_key { + __le32 vport_id; + __le16 key_len; + u8 pad; + u8 key_flex[] __counted_by_le(key_len); +} __packed; +VIRTCHNL2_CHECK_STRUCT_LEN(7, virtchnl2_rss_key); + +/** + * struct virtchnl2_queue_chunk - chunk of contiguous queues + * @type: See enum virtchnl2_queue_type. + * @start_queue_id: Starting queue id. + * @num_queues: Number of queues. + * @pad: Padding for future extensions. + */ +struct virtchnl2_queue_chunk { + __le32 type; + __le32 start_queue_id; + __le32 num_queues; + u8 pad[4]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_queue_chunk); + +/* struct virtchnl2_queue_chunks - chunks of contiguous queues + * @num_chunks: Number of chunks. + * @pad: Padding. + * @chunks: Chunks of contiguous queues info. + */ +struct virtchnl2_queue_chunks { + __le16 num_chunks; + u8 pad[6]; + struct virtchnl2_queue_chunk chunks[] __counted_by_le(num_chunks); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_queue_chunks); + +/** + * struct virtchnl2_del_ena_dis_queues - Enable/disable queues info. + * @vport_id: Vport id. + * @pad: Padding. + * @chunks: Chunks of contiguous queues info. + * + * PF sends these messages to enable, disable or delete queues specified in + * chunks. PF sends virtchnl2_del_ena_dis_queues struct to specify the queues + * to be enabled/disabled/deleted. Also applicable to single queue receive or + * transmit. CP performs requested action and returns status. + * + * Associated with VIRTCHNL2_OP_ENABLE_QUEUES, VIRTCHNL2_OP_DISABLE_QUEUES and + * VIRTCHNL2_OP_DISABLE_QUEUES. + */ +struct virtchnl2_del_ena_dis_queues { + __le32 vport_id; + u8 pad[4]; + struct virtchnl2_queue_chunks chunks; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_del_ena_dis_queues); + +/** + * struct virtchnl2_queue_vector - Queue to vector mapping. + * @queue_id: Queue id. + * @vector_id: Vector id. + * @pad: Padding. + * @itr_idx: See enum virtchnl2_itr_idx. + * @queue_type: See enum virtchnl2_queue_type. + * @pad1: Padding for future extensions. + */ +struct virtchnl2_queue_vector { + __le32 queue_id; + __le16 vector_id; + u8 pad[2]; + __le32 itr_idx; + __le32 queue_type; + u8 pad1[8]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(24, virtchnl2_queue_vector); + +/** + * struct virtchnl2_queue_vector_maps - Map/unmap queues info. + * @vport_id: Vport id. + * @num_qv_maps: Number of queue vector maps. + * @pad: Padding. + * @qv_maps: Queue to vector maps. + * + * PF sends this message to map or unmap queues to vectors and interrupt + * throttling rate index registers. External data buffer contains + * virtchnl2_queue_vector_maps structure that contains num_qv_maps of + * virtchnl2_queue_vector structures. CP maps the requested queue vector maps + * after validating the queue and vector ids and returns a status code. + * + * Associated with VIRTCHNL2_OP_MAP_QUEUE_VECTOR and + * VIRTCHNL2_OP_UNMAP_QUEUE_VECTOR. + */ +struct virtchnl2_queue_vector_maps { + __le32 vport_id; + __le16 num_qv_maps; + u8 pad[10]; + struct virtchnl2_queue_vector qv_maps[] __counted_by_le(num_qv_maps); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_queue_vector_maps); + +/** + * struct virtchnl2_loopback - Loopback info. + * @vport_id: Vport id. + * @enable: Enable/disable. + * @pad: Padding for future extensions. + * + * PF/VF sends this message to transition to/from the loopback state. Setting + * the 'enable' to 1 enables the loopback state and setting 'enable' to 0 + * disables it. CP configures the state to loopback and returns status. + * + * Associated with VIRTCHNL2_OP_LOOPBACK. + */ +struct virtchnl2_loopback { + __le32 vport_id; + u8 enable; + u8 pad[3]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_loopback); + +/* struct virtchnl2_mac_addr - MAC address info. + * @addr: MAC address. + * @type: MAC type. See enum virtchnl2_mac_addr_type. + * @pad: Padding for future extensions. + */ +struct virtchnl2_mac_addr { + u8 addr[ETH_ALEN]; + u8 type; + u8 pad; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_mac_addr); + +/** + * struct virtchnl2_mac_addr_list - List of MAC addresses. + * @vport_id: Vport id. + * @num_mac_addr: Number of MAC addresses. + * @pad: Padding. + * @mac_addr_list: List with MAC address info. + * + * PF/VF driver uses this structure to send list of MAC addresses to be + * added/deleted to the CP where as CP performs the action and returns the + * status. + * + * Associated with VIRTCHNL2_OP_ADD_MAC_ADDR and VIRTCHNL2_OP_DEL_MAC_ADDR. + */ +struct virtchnl2_mac_addr_list { + __le32 vport_id; + __le16 num_mac_addr; + u8 pad[2]; + struct virtchnl2_mac_addr mac_addr_list[] __counted_by_le(num_mac_addr); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_mac_addr_list); + +/** + * struct virtchnl2_promisc_info - Promisc type info. + * @vport_id: Vport id. + * @flags: See enum virtchnl2_promisc_flags. + * @pad: Padding for future extensions. + * + * PF/VF sends vport id and flags to the CP where as CP performs the action + * and returns the status. + * + * Associated with VIRTCHNL2_OP_CONFIG_PROMISCUOUS_MODE. + */ +struct virtchnl2_promisc_info { + __le32 vport_id; + /* See VIRTCHNL2_PROMISC_FLAGS definitions */ + __le16 flags; + u8 pad[2]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_promisc_info); + +/** + * enum virtchnl2_ptp_caps - PTP capabilities + * @VIRTCHNL2_CAP_PTP_GET_DEVICE_CLK_TIME: direct access to get the time of + * device clock + * @VIRTCHNL2_CAP_PTP_GET_DEVICE_CLK_TIME_MB: mailbox access to get the time of + * device clock + * @VIRTCHNL2_CAP_PTP_GET_CROSS_TIME: direct access to cross timestamp + * @VIRTCHNL2_CAP_PTP_GET_CROSS_TIME_MB: mailbox access to cross timestamp + * @VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME: direct access to set the time of + * device clock + * @VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME_MB: mailbox access to set the time of + * device clock + * @VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK: direct access to adjust the time of device + * clock + * @VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK_MB: mailbox access to adjust the time of + * device clock + * @VIRTCHNL2_CAP_PTP_TX_TSTAMPS: direct access to the Tx timestamping + * @VIRTCHNL2_CAP_PTP_TX_TSTAMPS_MB: mailbox access to the Tx timestamping + * + * PF/VF negotiates a set of supported PTP capabilities with the Control Plane. + * There are two access methods - mailbox (_MB) and direct. + * PTP capabilities enables Main Timer operations: get/set/adjust Main Timer, + * cross timestamping and the Tx timestamping. + */ +enum virtchnl2_ptp_caps { + VIRTCHNL2_CAP_PTP_GET_DEVICE_CLK_TIME = BIT(0), + VIRTCHNL2_CAP_PTP_GET_DEVICE_CLK_TIME_MB = BIT(1), + VIRTCHNL2_CAP_PTP_GET_CROSS_TIME = BIT(2), + VIRTCHNL2_CAP_PTP_GET_CROSS_TIME_MB = BIT(3), + VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME = BIT(4), + VIRTCHNL2_CAP_PTP_SET_DEVICE_CLK_TIME_MB = BIT(5), + VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK = BIT(6), + VIRTCHNL2_CAP_PTP_ADJ_DEVICE_CLK_MB = BIT(7), + VIRTCHNL2_CAP_PTP_TX_TSTAMPS = BIT(8), + VIRTCHNL2_CAP_PTP_TX_TSTAMPS_MB = BIT(9), +}; + +/** + * struct virtchnl2_ptp_clk_reg_offsets - Offsets of device and PHY clocks + * registers. + * @dev_clk_ns_l: Device clock low register offset + * @dev_clk_ns_h: Device clock high register offset + * @phy_clk_ns_l: PHY clock low register offset + * @phy_clk_ns_h: PHY clock high register offset + * @cmd_sync_trigger: The command sync trigger register offset + * @pad: Padding for future extensions + */ +struct virtchnl2_ptp_clk_reg_offsets { + __le32 dev_clk_ns_l; + __le32 dev_clk_ns_h; + __le32 phy_clk_ns_l; + __le32 phy_clk_ns_h; + __le32 cmd_sync_trigger; + u8 pad[4]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(24, virtchnl2_ptp_clk_reg_offsets); + +/** + * struct virtchnl2_ptp_cross_time_reg_offsets - Offsets of the device cross + * time registers. + * @sys_time_ns_l: System time low register offset + * @sys_time_ns_h: System time high register offset + * @cmd_sync_trigger: The command sync trigger register offset + * @pad: Padding for future extensions + */ +struct virtchnl2_ptp_cross_time_reg_offsets { + __le32 sys_time_ns_l; + __le32 sys_time_ns_h; + __le32 cmd_sync_trigger; + u8 pad[4]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_cross_time_reg_offsets); + +/** + * struct virtchnl2_ptp_clk_adj_reg_offsets - Offsets of device and PHY clocks + * adjustments registers. + * @dev_clk_cmd_type: Device clock command type register offset + * @dev_clk_incval_l: Device clock increment value low register offset + * @dev_clk_incval_h: Device clock increment value high registers offset + * @dev_clk_shadj_l: Device clock shadow adjust low register offset + * @dev_clk_shadj_h: Device clock shadow adjust high register offset + * @phy_clk_cmd_type: PHY timer command type register offset + * @phy_clk_incval_l: PHY timer increment value low register offset + * @phy_clk_incval_h: PHY timer increment value high register offset + * @phy_clk_shadj_l: PHY timer shadow adjust low register offset + * @phy_clk_shadj_h: PHY timer shadow adjust high register offset + */ +struct virtchnl2_ptp_clk_adj_reg_offsets { + __le32 dev_clk_cmd_type; + __le32 dev_clk_incval_l; + __le32 dev_clk_incval_h; + __le32 dev_clk_shadj_l; + __le32 dev_clk_shadj_h; + __le32 phy_clk_cmd_type; + __le32 phy_clk_incval_l; + __le32 phy_clk_incval_h; + __le32 phy_clk_shadj_l; + __le32 phy_clk_shadj_h; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(40, virtchnl2_ptp_clk_adj_reg_offsets); + +/** + * struct virtchnl2_ptp_tx_tstamp_latch_caps - PTP Tx timestamp latch + * capabilities. + * @tx_latch_reg_offset_l: Tx timestamp latch low register offset + * @tx_latch_reg_offset_h: Tx timestamp latch high register offset + * @index: Latch index provided to the Tx descriptor + * @pad: Padding for future extensions + */ +struct virtchnl2_ptp_tx_tstamp_latch_caps { + __le32 tx_latch_reg_offset_l; + __le32 tx_latch_reg_offset_h; + u8 index; + u8 pad[7]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_tx_tstamp_latch_caps); + +/** + * struct virtchnl2_ptp_get_vport_tx_tstamp_caps - Structure that defines Tx + * tstamp entries. + * @vport_id: Vport number + * @num_latches: Total number of latches + * @tstamp_ns_lo_bit: First bit for nanosecond part of the timestamp + * @tstamp_ns_hi_bit: Last bit for nanosecond part of the timestamp + * @pad: Padding for future tstamp granularity extensions + * @tstamp_latches: Capabilities of Tx timestamp entries + * + * PF/VF sends this message to negotiate the Tx timestamp latches for each + * Vport. + * + * Associated with VIRTCHNL2_OP_PTP_GET_VPORT_TX_TSTAMP_CAPS. + */ +struct virtchnl2_ptp_get_vport_tx_tstamp_caps { + __le32 vport_id; + __le16 num_latches; + u8 tstamp_ns_lo_bit; + u8 tstamp_ns_hi_bit; + u8 pad[8]; + + struct virtchnl2_ptp_tx_tstamp_latch_caps tstamp_latches[] + __counted_by_le(num_latches); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_get_vport_tx_tstamp_caps); + +/** + * struct virtchnl2_ptp_get_caps - Get PTP capabilities + * @caps: PTP capability bitmap. See enum virtchnl2_ptp_caps + * @max_adj: The maximum possible frequency adjustment + * @base_incval: The default timer increment value + * @peer_mbx_q_id: ID of the PTP Device Control daemon queue + * @peer_id: Peer ID for PTP Device Control daemon + * @secondary_mbx: Indicates to the driver that it should create a secondary + * mailbox to inetract with control plane for PTP + * @pad: Padding for future extensions + * @clk_offsets: Main timer and PHY registers offsets + * @cross_time_offsets: Cross time registers offsets + * @clk_adj_offsets: Offsets needed to adjust the PHY and the main timer + * + * PF/VF sends this message to negotiate PTP capabilities. CP updates bitmap + * with supported features and fulfills appropriate structures. + * If HW uses primary MBX for PTP: secondary_mbx is set to false. + * If HW uses secondary MBX for PTP: secondary_mbx is set to true. + * Control plane has 2 MBX and the driver has 1 MBX, send to peer + * driver may be used to send a message using valid ptp_peer_mb_q_id and + * ptp_peer_id. + * If HW does not use send to peer driver: secondary_mbx is no care field and + * peer_mbx_q_id holds invalid value (0xFFFF). + * + * Associated with VIRTCHNL2_OP_PTP_GET_CAPS. + */ +struct virtchnl2_ptp_get_caps { + __le32 caps; + __le32 max_adj; + __le64 base_incval; + __le16 peer_mbx_q_id; + u8 peer_id; + u8 secondary_mbx; + u8 pad[4]; + + struct virtchnl2_ptp_clk_reg_offsets clk_offsets; + struct virtchnl2_ptp_cross_time_reg_offsets cross_time_offsets; + struct virtchnl2_ptp_clk_adj_reg_offsets clk_adj_offsets; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(104, virtchnl2_ptp_get_caps); + +/** + * struct virtchnl2_ptp_tx_tstamp_latch - Structure that describes tx tstamp + * values, index and validity. + * @tstamp: Timestamp value + * @index: Timestamp index from which the value is read + * @valid: Timestamp validity + * @pad: Padding for future extensions + */ +struct virtchnl2_ptp_tx_tstamp_latch { + __le64 tstamp; + u8 index; + u8 valid; + u8 pad[6]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_tx_tstamp_latch); + +/** + * struct virtchnl2_ptp_get_vport_tx_tstamp_latches - Tx timestamp latches + * associated with the vport. + * @vport_id: Number of vport that requests the timestamp + * @num_latches: Number of latches + * @get_devtime_with_txtstmp: Flag to request device time along with Tx timestamp + * @pad: Padding for future extensions + * @device_time: device time if get_devtime_with_txtstmp was set in request + * @tstamp_latches: PTP TX timestamp latch + * + * PF/VF sends this message to receive a specified number of timestamps + * entries. + * + * Associated with VIRTCHNL2_OP_PTP_GET_VPORT_TX_TSTAMP. + */ +struct virtchnl2_ptp_get_vport_tx_tstamp_latches { + __le32 vport_id; + __le16 num_latches; + u8 get_devtime_with_txtstmp; + u8 pad[1]; + __le64 device_time; + + struct virtchnl2_ptp_tx_tstamp_latch tstamp_latches[] + __counted_by_le(num_latches); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_get_vport_tx_tstamp_latches); + +/** + * struct virtchnl2_ptp_get_dev_clk_time - Associated with message + * VIRTCHNL2_OP_PTP_GET_DEV_CLK_TIME. + * @dev_time_ns: Device clock time value in nanoseconds + * @pad: Padding for future extensions + * + * PF/VF sends this message to receive the time from the main timer. + */ +struct virtchnl2_ptp_get_dev_clk_time { + __le64 dev_time_ns; + u8 pad[8]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_get_dev_clk_time); + +/** + * struct virtchnl2_ptp_get_cross_time: Associated with message + * VIRTCHNL2_OP_PTP_GET_CROSS_TIME. + * @sys_time_ns: System counter value expressed in nanoseconds, read + * synchronously with device time + * @dev_time_ns: Device clock time value expressed in nanoseconds + * @pad: Padding for future extensions + * + * PF/VF sends this message to receive the cross time. + */ +struct virtchnl2_ptp_get_cross_time { + __le64 sys_time_ns; + __le64 dev_time_ns; + u8 pad[8]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(24, virtchnl2_ptp_get_cross_time); + +/** + * struct virtchnl2_ptp_set_dev_clk_time: Associated with message + * VIRTCHNL2_OP_PTP_SET_DEV_CLK_TIME. + * @dev_time_ns: Device time value expressed in nanoseconds to set + * @pad: Padding for future extensions + * + * PF/VF sends this message to set the time of the main timer. + */ +struct virtchnl2_ptp_set_dev_clk_time { + __le64 dev_time_ns; + u8 pad[8]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_set_dev_clk_time); + +/** + * struct virtchnl2_ptp_adj_dev_clk_fine: Associated with message + * VIRTCHNL2_OP_PTP_ADJ_DEV_CLK_FINE. + * @incval: Source timer increment value per clock cycle + * + * PF/VF sends this message to adjust the frequency of the main timer by the + * indicated increment value. + */ +struct virtchnl2_ptp_adj_dev_clk_fine { + __le64 incval; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_ptp_adj_dev_clk_fine); + +/** + * struct virtchnl2_ptp_adj_dev_clk_time: Associated with message + * VIRTCHNL2_OP_PTP_ADJ_DEV_CLK_TIME. + * @delta: Offset in nanoseconds to adjust the time by + * + * PF/VF sends this message to adjust the time of the main timer by the delta. + */ +struct virtchnl2_ptp_adj_dev_clk_time { + __le64 delta; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_ptp_adj_dev_clk_time); + +/** + * struct virtchnl2_mem_region - MMIO memory region + * @start_offset: starting offset of the MMIO memory region + * @size: size of the MMIO memory region + */ +struct virtchnl2_mem_region { + __le64 start_offset; + __le64 size; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_mem_region); + +/** + * struct virtchnl2_get_lan_memory_regions - List of LAN MMIO memory regions + * @num_memory_regions: number of memory regions + * @pad: Padding + * @mem_reg: List with memory region info + * + * PF/VF sends this message to learn what LAN MMIO memory regions it should map. + */ +struct virtchnl2_get_lan_memory_regions { + __le16 num_memory_regions; + u8 pad[6]; + struct virtchnl2_mem_region mem_reg[]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_get_lan_memory_regions); + +#define VIRTCHNL2_MAX_NUM_PROTO_HDRS 4 +#define VIRTCHNL2_MAX_SIZE_RAW_PACKET 256 +#define VIRTCHNL2_MAX_NUM_ACTIONS 8 + +/** + * struct virtchnl2_proto_hdr - represent one protocol header + * @hdr_type: See enum virtchnl2_proto_hdr_type + * @pad: padding + * @buffer_spec: binary buffer based on header type. + * @buffer_mask: mask applied on buffer_spec. + * + * Structure to hold protocol headers based on hdr_type + */ +struct virtchnl2_proto_hdr { + __le32 hdr_type; + u8 pad[4]; + u8 buffer_spec[64]; + u8 buffer_mask[64]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(136, virtchnl2_proto_hdr); + +/** + * struct virtchnl2_proto_hdrs - struct to represent match criteria + * @tunnel_level: specify where protocol header(s) start from. + * must be 0 when sending a raw packet request. + * 0 - from the outer layer + * 1 - from the first inner layer + * 2 - from the second inner layer + * @pad: Padding bytes + * @count: total number of protocol headers in proto_hdr. 0 for raw packet. + * @proto_hdr: Array of protocol headers + * @raw: struct holding raw packet buffer when count is 0 + */ +struct virtchnl2_proto_hdrs { + u8 tunnel_level; + u8 pad[3]; + __le32 count; + union { + struct virtchnl2_proto_hdr + proto_hdr[VIRTCHNL2_MAX_NUM_PROTO_HDRS]; + struct { + __le16 pkt_len; + u8 spec[VIRTCHNL2_MAX_SIZE_RAW_PACKET]; + u8 mask[VIRTCHNL2_MAX_SIZE_RAW_PACKET]; + } raw; + }; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(552, virtchnl2_proto_hdrs); + +/** + * struct virtchnl2_rule_action - struct representing single action for a flow + * @action_type: see enum virtchnl2_action_types + * @act_conf: union representing action depending on action_type. + * @act_conf.q_id: queue id to redirect the packets to. + * @act_conf.q_grp_id: queue group id to redirect the packets to. + * @act_conf.ctr_id: used for count action. If input value 0xFFFFFFFF control + * plane assigns a new counter and returns the counter ID to + * the driver. If input value is not 0xFFFFFFFF then it must + * be an existing counter given to the driver for an earlier + * flow. Then this flow will share the counter. + * @act_conf.mark_id: Value used to mark the packets. Used for mark action. + * @act_conf.reserved: Reserved for future use. + */ +struct virtchnl2_rule_action { + __le32 action_type; + union { + __le32 q_id; + __le32 q_grp_id; + __le32 ctr_id; + __le32 mark_id; + u8 reserved[8]; + } act_conf; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(12, virtchnl2_rule_action); + +/** + * struct virtchnl2_rule_action_set - struct representing multiple actions + * @count: number of valid actions in the action set of a rule + * @actions: array of struct virtchnl2_rule_action + */ +struct virtchnl2_rule_action_set { + /* action count must be less than VIRTCHNL2_MAX_NUM_ACTIONS */ + __le32 count; + struct virtchnl2_rule_action actions[VIRTCHNL2_MAX_NUM_ACTIONS]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(100, virtchnl2_rule_action_set); + +/** + * struct virtchnl2_flow_rule - represent one flow steering rule + * @proto_hdrs: array of protocol header buffers representing match criteria + * @action_set: series of actions to be applied for given rule + * @priority: rule priority. + * @pad: padding for future extensions. + */ +struct virtchnl2_flow_rule { + struct virtchnl2_proto_hdrs proto_hdrs; + struct virtchnl2_rule_action_set action_set; + __le32 priority; + u8 pad[8]; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(664, virtchnl2_flow_rule); + +enum virtchnl2_flow_rule_status { + VIRTCHNL2_FLOW_RULE_SUCCESS = 1, + VIRTCHNL2_FLOW_RULE_NORESOURCE = 2, + VIRTCHNL2_FLOW_RULE_EXIST = 3, + VIRTCHNL2_FLOW_RULE_TIMEOUT = 4, + VIRTCHNL2_FLOW_RULE_FLOW_TYPE_NOT_SUPPORTED = 5, + VIRTCHNL2_FLOW_RULE_MATCH_KEY_NOT_SUPPORTED = 6, + VIRTCHNL2_FLOW_RULE_ACTION_NOT_SUPPORTED = 7, + VIRTCHNL2_FLOW_RULE_ACTION_COMBINATION_INVALID = 8, + VIRTCHNL2_FLOW_RULE_ACTION_DATA_INVALID = 9, + VIRTCHNL2_FLOW_RULE_NOT_ADDED = 10, +}; + +/** + * struct virtchnl2_flow_rule_info: structure representing single flow rule + * @rule_id: rule_id associated with the flow_rule. + * @rule_cfg: structure representing rule. + * @status: status of rule programming. See enum virtchnl2_flow_rule_status. + */ +struct virtchnl2_flow_rule_info { + __le32 rule_id; + struct virtchnl2_flow_rule rule_cfg; + __le32 status; +}; +VIRTCHNL2_CHECK_STRUCT_LEN(672, virtchnl2_flow_rule_info); + +/** + * struct virtchnl2_flow_rule_add_del - add/delete a flow steering rule + * @vport_id: vport id for which the rule is to be added or deleted. + * @count: Indicates number of rules to be added or deleted. + * @rule_info: Array of flow rules to be added or deleted. + * + * For VIRTCHNL2_OP_FLOW_RULE_ADD, rule_info contains list of rules to be + * added. If rule_id is 0xFFFFFFFF, then the rule is programmed and not cached. + * + * For VIRTCHNL2_OP_FLOW_RULE_DEL, there are two possibilities. The structure + * can contain either array of rule_ids or array of match keys to be deleted. + * When match keys are used the corresponding rule_ids must be 0xFFFFFFFF. + * + * status member of each rule indicates the result. Maximum of 6 rules can be + * added or deleted using this method. Driver has to retry in case of any + * failure of ADD or DEL opcode. CP doesn't retry in case of failure. + */ +struct virtchnl2_flow_rule_add_del { + __le32 vport_id; + __le32 count; + struct virtchnl2_flow_rule_info rule_info[] __counted_by_le(count); +}; +VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_flow_rule_add_del); + +#endif /* _VIRTCHNL_2_H_ */ diff --git a/include/linux/net/intel/virtchnl2_lan_desc.h b/include/linux/net/intel/virtchnl2_lan_desc.h new file mode 100644 index 000000000000..f1b577f1c452 --- /dev/null +++ b/include/linux/net/intel/virtchnl2_lan_desc.h @@ -0,0 +1,451 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (C) 2023 Intel Corporation */ + +#ifndef _VIRTCHNL2_LAN_DESC_H_ +#define _VIRTCHNL2_LAN_DESC_H_ + +#include <linux/bits.h> + +/* This is an interface definition file where existing enums and their values + * must remain unchanged over time, so we specify explicit values for all enums. + */ + +/* Transmit descriptor ID flags + */ +enum virtchnl2_tx_desc_ids { + VIRTCHNL2_TXDID_DATA = BIT(0), + VIRTCHNL2_TXDID_CTX = BIT(1), + /* TXDID bit 2 is reserved + * TXDID bit 3 is free for future use + * TXDID bit 4 is reserved + */ + VIRTCHNL2_TXDID_FLEX_TSO_CTX = BIT(5), + /* TXDID bit 6 is reserved */ + VIRTCHNL2_TXDID_FLEX_L2TAG1_L2TAG2 = BIT(7), + /* TXDID bits 8 and 9 are free for future use + * TXDID bit 10 is reserved + * TXDID bit 11 is free for future use + */ + VIRTCHNL2_TXDID_FLEX_FLOW_SCHED = BIT(12), + /* TXDID bits 13 and 14 are free for future use */ + VIRTCHNL2_TXDID_DESC_DONE = BIT(15), +}; + +/* Receive descriptor IDs */ +enum virtchnl2_rx_desc_ids { + VIRTCHNL2_RXDID_1_32B_BASE = 1, + /* FLEX_SQ_NIC and FLEX_SPLITQ share desc ids because they can be + * differentiated based on queue model; e.g. single queue model can + * only use FLEX_SQ_NIC and split queue model can only use FLEX_SPLITQ + * for DID 2. + */ + VIRTCHNL2_RXDID_2_FLEX_SPLITQ = 2, + VIRTCHNL2_RXDID_2_FLEX_SQ_NIC = VIRTCHNL2_RXDID_2_FLEX_SPLITQ, + /* 3 through 6 are reserved */ + VIRTCHNL2_RXDID_7_HW_RSVD = 7, + /* 8 through 15 are free */ +}; + +/* Receive descriptor ID bitmasks */ +#define VIRTCHNL2_RXDID_M(bit) BIT_ULL(VIRTCHNL2_RXDID_##bit) + +enum virtchnl2_rx_desc_id_bitmasks { + VIRTCHNL2_RXDID_1_32B_BASE_M = VIRTCHNL2_RXDID_M(1_32B_BASE), + VIRTCHNL2_RXDID_2_FLEX_SPLITQ_M = VIRTCHNL2_RXDID_M(2_FLEX_SPLITQ), + VIRTCHNL2_RXDID_2_FLEX_SQ_NIC_M = VIRTCHNL2_RXDID_M(2_FLEX_SQ_NIC), + VIRTCHNL2_RXDID_7_HW_RSVD_M = VIRTCHNL2_RXDID_M(7_HW_RSVD), +}; + +/* For splitq virtchnl2_rx_flex_desc_adv_nic_3 desc members */ +#define VIRTCHNL2_RX_FLEX_DESC_ADV_RXDID_M GENMASK(3, 0) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_UMBCAST_M GENMASK(7, 6) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_PTYPE_M GENMASK(9, 0) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_RAW_CSUM_INV_S 12 +#define VIRTCHNL2_RX_FLEX_DESC_ADV_RAW_CSUM_INV_M \ + BIT_ULL(VIRTCHNL2_RX_FLEX_DESC_ADV_RAW_CSUM_INV_S) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_FF0_M GENMASK(15, 13) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_LEN_PBUF_M GENMASK(13, 0) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_GEN_S 14 +#define VIRTCHNL2_RX_FLEX_DESC_ADV_GEN_M \ + BIT_ULL(VIRTCHNL2_RX_FLEX_DESC_ADV_GEN_S) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_BUFQ_ID_S 15 +#define VIRTCHNL2_RX_FLEX_DESC_ADV_BUFQ_ID_M \ + BIT_ULL(VIRTCHNL2_RX_FLEX_DESC_ADV_BUFQ_ID_S) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_LEN_HDR_M GENMASK(9, 0) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_RSC_S 10 +#define VIRTCHNL2_RX_FLEX_DESC_ADV_RSC_M \ + BIT_ULL(VIRTCHNL2_RX_FLEX_DESC_ADV_RSC_S) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_SPH_S 11 +#define VIRTCHNL2_RX_FLEX_DESC_ADV_SPH_M \ + BIT_ULL(VIRTCHNL2_RX_FLEX_DESC_ADV_SPH_S) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_FF1_S 12 +#define VIRTCHNL2_RX_FLEX_DESC_ADV_FF1_M GENMASK(14, 12) +#define VIRTCHNL2_RX_FLEX_DESC_ADV_MISS_S 15 +#define VIRTCHNL2_RX_FLEX_DESC_ADV_MISS_M \ + BIT_ULL(VIRTCHNL2_RX_FLEX_DESC_ADV_MISS_S) + +/* Bitmasks for splitq virtchnl2_rx_flex_desc_adv_nic_3 */ +enum virtchl2_rx_flex_desc_adv_status_error_0_qw1_bits { + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_DD_M = BIT(0), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_EOF_M = BIT(1), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_HBO_M = BIT(2), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_L3L4P_M = BIT(3), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_XSUM_IPE_M = BIT(4), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_XSUM_L4E_M = BIT(5), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_XSUM_EIPE_M = BIT(6), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_XSUM_EUDPE_M = BIT(7), +}; + +/* Bitmasks for splitq virtchnl2_rx_flex_desc_adv_nic_3 */ +enum virtchnl2_rx_flex_desc_adv_status_error_0_qw0_bits { + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_LPBK_M = BIT(0), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_IPV6EXADD_M = BIT(1), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_RXE_M = BIT(2), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_CRCP_M = BIT(3), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_RSS_VALID_M = BIT(4), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_L2TAG1P_M = BIT(5), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_XTRMD0_VALID_M = BIT(6), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_XTRMD1_VALID_M = BIT(7), +}; + +/* Bitmasks for splitq virtchnl2_rx_flex_desc_adv_nic_3 */ +enum virtchnl2_rx_flex_desc_adv_status_error_1_bits { + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS1_RSVD_M = GENMASK(1, 0), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS1_ATRAEFAIL_M = BIT(2), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS1_L2TAG2P_M = BIT(3), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS1_XTRMD2_VALID_M = BIT(4), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS1_XTRMD3_VALID_M = BIT(5), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS1_XTRMD4_VALID_M = BIT(6), + VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS1_XTRMD5_VALID_M = BIT(7), +}; + +/* For singleq (flex) virtchnl2_rx_flex_desc fields + * For virtchnl2_rx_flex_desc.ptype_flex_flags0 member + */ +#define VIRTCHNL2_RX_FLEX_DESC_PTYPE_M GENMASK(9, 0) + +/* For virtchnl2_rx_flex_desc.pkt_len member */ +#define VIRTCHNL2_RX_FLEX_DESC_PKT_LEN_M GENMASK(13, 0) + +/* Bitmasks for singleq (flex) virtchnl2_rx_flex_desc */ +enum virtchnl2_rx_flex_desc_status_error_0_bits { + VIRTCHNL2_RX_FLEX_DESC_STATUS0_DD_M = BIT(0), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_EOF_M = BIT(1), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_HBO_M = BIT(2), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_L3L4P_M = BIT(3), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_XSUM_IPE_M = BIT(4), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_XSUM_L4E_M = BIT(5), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_XSUM_EIPE_M = BIT(6), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_XSUM_EUDPE_M = BIT(7), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_LPBK_M = BIT(8), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_IPV6EXADD_M = BIT(9), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_RXE_M = BIT(10), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_CRCP_M = BIT(11), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_RSS_VALID_M = BIT(12), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_L2TAG1P_M = BIT(13), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_XTRMD0_VALID_M = BIT(14), + VIRTCHNL2_RX_FLEX_DESC_STATUS0_XTRMD1_VALID_M = BIT(15), +}; + +/* Bitmasks for singleq (flex) virtchnl2_rx_flex_desc */ +enum virtchnl2_rx_flex_desc_status_error_1_bits { + VIRTCHNL2_RX_FLEX_DESC_STATUS1_CPM_M = GENMASK(3, 0), + VIRTCHNL2_RX_FLEX_DESC_STATUS1_NAT_M = BIT(4), + VIRTCHNL2_RX_FLEX_DESC_STATUS1_CRYPTO_M = BIT(5), + /* [10:6] reserved */ + VIRTCHNL2_RX_FLEX_DESC_STATUS1_L2TAG2P_M = BIT(11), + VIRTCHNL2_RX_FLEX_DESC_STATUS1_XTRMD2_VALID_M = BIT(12), + VIRTCHNL2_RX_FLEX_DESC_STATUS1_XTRMD3_VALID_M = BIT(13), + VIRTCHNL2_RX_FLEX_DESC_STATUS1_XTRMD4_VALID_M = BIT(14), + VIRTCHNL2_RX_FLEX_DESC_STATUS1_XTRMD5_VALID_M = BIT(15), +}; + +/* For virtchnl2_rx_flex_desc.ts_low member */ +#define VIRTCHNL2_RX_FLEX_TSTAMP_VALID BIT(0) + +/* For singleq (non flex) virtchnl2_singleq_base_rx_desc legacy desc members */ +#define VIRTCHNL2_RX_BASE_DESC_QW1_LEN_PBUF_M GENMASK_ULL(51, 38) +#define VIRTCHNL2_RX_BASE_DESC_QW1_PTYPE_M GENMASK_ULL(37, 30) +#define VIRTCHNL2_RX_BASE_DESC_QW1_ERROR_M GENMASK_ULL(26, 19) +#define VIRTCHNL2_RX_BASE_DESC_QW1_STATUS_M GENMASK_ULL(18, 0) + +/* Bitmasks for singleq (base) virtchnl2_rx_base_desc */ +enum virtchnl2_rx_base_desc_status_bits { + VIRTCHNL2_RX_BASE_DESC_STATUS_DD_M = BIT(0), + VIRTCHNL2_RX_BASE_DESC_STATUS_EOF_M = BIT(1), + VIRTCHNL2_RX_BASE_DESC_STATUS_L2TAG1P_M = BIT(2), + VIRTCHNL2_RX_BASE_DESC_STATUS_L3L4P_M = BIT(3), + VIRTCHNL2_RX_BASE_DESC_STATUS_CRCP_M = BIT(4), + VIRTCHNL2_RX_BASE_DESC_STATUS_RSVD_M = GENMASK(7, 5), + VIRTCHNL2_RX_BASE_DESC_STATUS_EXT_UDP_0_M = BIT(8), + VIRTCHNL2_RX_BASE_DESC_STATUS_UMBCAST_M = GENMASK(10, 9), + VIRTCHNL2_RX_BASE_DESC_STATUS_FLM_M = BIT(11), + VIRTCHNL2_RX_BASE_DESC_STATUS_FLTSTAT_M = GENMASK(13, 12), + VIRTCHNL2_RX_BASE_DESC_STATUS_LPBK_M = BIT(14), + VIRTCHNL2_RX_BASE_DESC_STATUS_IPV6EXADD_M = BIT(15), + VIRTCHNL2_RX_BASE_DESC_STATUS_RSVD1_M = GENMASK(17, 16), + VIRTCHNL2_RX_BASE_DESC_STATUS_INT_UDP_0_M = BIT(18), +}; + +/* Bitmasks for singleq (base) virtchnl2_rx_base_desc */ +enum virtchnl2_rx_base_desc_error_bits { + VIRTCHNL2_RX_BASE_DESC_ERROR_RXE_M = BIT(0), + VIRTCHNL2_RX_BASE_DESC_ERROR_ATRAEFAIL_M = BIT(1), + VIRTCHNL2_RX_BASE_DESC_ERROR_HBO_M = BIT(2), + VIRTCHNL2_RX_BASE_DESC_ERROR_L3L4E_M = GENMASK(5, 3), + VIRTCHNL2_RX_BASE_DESC_ERROR_IPE_M = BIT(3), + VIRTCHNL2_RX_BASE_DESC_ERROR_L4E_M = BIT(4), + VIRTCHNL2_RX_BASE_DESC_ERROR_EIPE_M = BIT(5), + VIRTCHNL2_RX_BASE_DESC_ERROR_OVERSIZE_M = BIT(6), + VIRTCHNL2_RX_BASE_DESC_ERROR_PPRS_M = BIT(7), +}; + +/* Bitmasks for singleq (base) virtchnl2_rx_base_desc */ +#define VIRTCHNL2_RX_BASE_DESC_FLTSTAT_RSS_HASH_M GENMASK(13, 12) + +/** + * struct virtchnl2_splitq_rx_buf_desc - SplitQ RX buffer descriptor format + * @qword0: RX buffer struct. + * @qword0.buf_id: Buffer identifier. + * @qword0.rsvd0: Reserved. + * @qword0.rsvd1: Reserved. + * @pkt_addr: Packet buffer address. + * @hdr_addr: Header buffer address. + * @rsvd2: Rerserved. + * + * Receive Descriptors + * SplitQ buffer + * | 16| 0| + * ---------------------------------------------------------------- + * | RSV | Buffer ID | + * ---------------------------------------------------------------- + * | Rx packet buffer address | + * ---------------------------------------------------------------- + * | Rx header buffer address | + * ---------------------------------------------------------------- + * | RSV | + * ---------------------------------------------------------------- + * | 0| + */ +struct virtchnl2_splitq_rx_buf_desc { + struct { + __le16 buf_id; + __le16 rsvd0; + __le32 rsvd1; + } qword0; + __le64 pkt_addr; + __le64 hdr_addr; + __le64 rsvd2; +}; + +/** + * struct virtchnl2_singleq_rx_buf_desc - SingleQ RX buffer descriptor format. + * @pkt_addr: Packet buffer address. + * @hdr_addr: Header buffer address. + * @rsvd1: Reserved. + * @rsvd2: Reserved. + * + * SingleQ buffer + * | 0| + * ---------------------------------------------------------------- + * | Rx packet buffer address | + * ---------------------------------------------------------------- + * | Rx header buffer address | + * ---------------------------------------------------------------- + * | RSV | + * ---------------------------------------------------------------- + * | RSV | + * ---------------------------------------------------------------- + * | 0| + */ +struct virtchnl2_singleq_rx_buf_desc { + __le64 pkt_addr; + __le64 hdr_addr; + __le64 rsvd1; + __le64 rsvd2; +}; + +/** + * struct virtchnl2_singleq_base_rx_desc - RX descriptor writeback format. + * @qword0: First quad word struct. + * @qword0.lo_dword: Lower dual word struct. + * @qword0.lo_dword.mirroring_status: Mirrored packet status. + * @qword0.lo_dword.l2tag1: Stripped L2 tag from the received packet. + * @qword0.hi_dword: High dual word union. + * @qword0.hi_dword.rss: RSS hash. + * @qword0.hi_dword.fd_id: Flow director filter id. + * @qword1: Second quad word struct. + * @qword1.status_error_ptype_len: Status/error/PTYPE/length. + * @qword2: Third quad word struct. + * @qword2.ext_status: Extended status. + * @qword2.rsvd: Reserved. + * @qword2.l2tag2_1: Extracted L2 tag 2 from the packet. + * @qword2.l2tag2_2: Reserved. + * @qword3: Fourth quad word struct. + * @qword3.reserved: Reserved. + * @qword3.fd_id: Flow director filter id. + * + * Profile ID 0x1, SingleQ, base writeback format + */ +struct virtchnl2_singleq_base_rx_desc { + struct { + struct { + __le16 mirroring_status; + __le16 l2tag1; + } lo_dword; + union { + __le32 rss; + __le32 fd_id; + } hi_dword; + } qword0; + struct { + __le64 status_error_ptype_len; + } qword1; + struct { + __le16 ext_status; + __le16 rsvd; + __le16 l2tag2_1; + __le16 l2tag2_2; + } qword2; + struct { + __le32 reserved; + __le32 fd_id; + } qword3; +}; + +/** + * struct virtchnl2_rx_flex_desc_nic - RX descriptor writeback format. + * + * @rxdid: Descriptor builder profile id. + * @mir_id_umb_cast: umb_cast=[7:6], mirror=[5:0] + * @ptype_flex_flags0: ff0=[15:10], ptype=[9:0] + * @pkt_len: Packet length, [15:14] are reserved. + * @hdr_len_sph_flex_flags1: ff1/ext=[15:12], sph=[11], header=[10:0]. + * @status_error0: Status/Error section 0. + * @l2tag1: Stripped L2 tag from the received packet + * @rss_hash: RSS hash. + * @status_error1: Status/Error section 1. + * @flexi_flags2: Flexible flags section 2. + * @ts_low: Lower word of timestamp value. + * @l2tag2_1st: First L2TAG2. + * @l2tag2_2nd: Second L2TAG2. + * @flow_id: Flow id. + * @flex_ts: Timestamp and flexible flow id union. + * @flex_ts.ts_high: Timestamp higher word of the timestamp value. + * @flex_ts.flex.rsvd: Reserved. + * @flex_ts.flex.flow_id_ipv6: IPv6 flow id. + * + * Profile ID 0x2, SingleQ, flex writeback format + */ +struct virtchnl2_rx_flex_desc_nic { + /* Qword 0 */ + u8 rxdid; + u8 mir_id_umb_cast; + __le16 ptype_flex_flags0; + __le16 pkt_len; + __le16 hdr_len_sph_flex_flags1; + /* Qword 1 */ + __le16 status_error0; + __le16 l2tag1; + __le32 rss_hash; + /* Qword 2 */ + __le16 status_error1; + u8 flexi_flags2; + u8 ts_low; + __le16 l2tag2_1st; + __le16 l2tag2_2nd; + /* Qword 3 */ + __le32 flow_id; + union { + struct { + __le16 rsvd; + __le16 flow_id_ipv6; + } flex; + __le32 ts_high; + } flex_ts; +}; + +/** + * struct virtchnl2_rx_flex_desc_adv_nic_3 - RX descriptor writeback format. + * @rxdid_ucast: ucast=[7:6], rsvd=[5:4], profile_id=[3:0]. + * @status_err0_qw0: Status/Error section 0 in quad word 0. + * @ptype_err_fflags0: ff0=[15:12], udp_len_err=[11], ip_hdr_err=[10], + * ptype=[9:0]. + * @pktlen_gen_bufq_id: bufq_id=[15] only in splitq, gen=[14] only in splitq, + * plen=[13:0]. + * @hdrlen_flags: miss_prepend=[15], trunc_mirr=[14], int_udp_0=[13], + * ext_udp0=[12], sph=[11] only in splitq, rsc=[10] + * only in splitq, header=[9:0]. + * @status_err0_qw1: Status/Error section 0 in quad word 1. + * @status_err1: Status/Error section 1. + * @fflags1: Flexible flags section 1. + * @ts_low: Lower word of timestamp value. + * @buf_id: Buffer identifier. Only in splitq mode. + * @misc: Union. + * @misc.raw_cs: Raw checksum. + * @misc.l2tag1: Stripped L2 tag from the received packet + * @misc.rscseglen: + * @hash1: Lower bits of Rx hash value. + * @ff2_mirrid_hash2: Union. + * @ff2_mirrid_hash2.fflags2: Flexible flags section 2. + * @ff2_mirrid_hash2.mirrorid: Mirror id. + * @ff2_mirrid_hash2.rscseglen: RSC segment length. + * @hash3: Upper bits of Rx hash value. + * @l2tag2: Extracted L2 tag 2 from the packet. + * @fmd4: Flexible metadata container 4. + * @l2tag1: Stripped L2 tag from the received packet + * @fmd6: Flexible metadata container 6. + * @ts_high: Timestamp higher word of the timestamp value. + * + * Profile ID 0x2, SplitQ, flex writeback format + * + * Flex-field 0: BufferID + * Flex-field 1: Raw checksum/L2TAG1/RSC Seg Len (determined by HW) + * Flex-field 2: Hash[15:0] + * Flex-flags 2: Hash[23:16] + * Flex-field 3: L2TAG2 + * Flex-field 5: L2TAG1 + * Flex-field 7: Timestamp (upper 32 bits) + */ +struct virtchnl2_rx_flex_desc_adv_nic_3 { + /* Qword 0 */ + u8 rxdid_ucast; + u8 status_err0_qw0; + __le16 ptype_err_fflags0; + __le16 pktlen_gen_bufq_id; + __le16 hdrlen_flags; + /* Qword 1 */ + u8 status_err0_qw1; + u8 status_err1; + u8 fflags1; + u8 ts_low; + __le16 buf_id; + union { + __le16 raw_cs; + __le16 l2tag1; + __le16 rscseglen; + } misc; + /* Qword 2 */ + __le16 hash1; + union { + u8 fflags2; + u8 mirrorid; + u8 hash2; + } ff2_mirrid_hash2; + u8 hash3; + __le16 l2tag2; + __le16 fmd4; + /* Qword 3 */ + __le16 l2tag1; + __le16 fmd6; + __le32 ts_high; +}; + +/* Common union for accessing descriptor format structs */ +union virtchnl2_rx_desc { + struct virtchnl2_singleq_base_rx_desc base_wb; + struct virtchnl2_rx_flex_desc_nic flex_nic_wb; + struct virtchnl2_rx_flex_desc_adv_nic_3 flex_adv_nic_3_wb; +}; + +#endif /* _VIRTCHNL_LAN_DESC_H_ */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9981d637f8b5..87cafc932e9e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -300,9 +300,11 @@ struct hh_cache { * We could use other alignment values, but we must maintain the * relationship HH alignment <= LL alignment. */ -#define LL_RESERVED_SPACE(dev) \ - ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom)) \ +#define LL_RESERVED_SPACE_EX(dev, hlen) \ + ((((hlen) + READ_ONCE((dev)->needed_headroom)) \ & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD) +#define LL_RESERVED_SPACE(dev) \ + LL_RESERVED_SPACE_EX(dev, (dev)->hard_header_len) #define LL_RESERVED_SPACE_EXTRA(dev,extra) \ ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom) + (extra)) \ & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD) @@ -830,8 +832,13 @@ struct xps_dev_maps { #define TC_BITMASK 15 /* HW offloaded queuing disciplines txq count and offset maps */ struct netdev_tc_txq { - u16 count; - u16 offset; + union { + struct { + u16 count; + u16 offset; + }; + u32 combined; + }; }; #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) @@ -892,6 +899,7 @@ struct net_device_path { u8 h_dest[ETH_ALEN]; } encap; struct { + struct dst_entry *dst; union { struct in_addr src_v4; struct in6_addr src_v6; @@ -901,7 +909,7 @@ struct net_device_path { struct in6_addr dst_v6; }; - u8 l3_proto; + u8 inner_proto; } tun; struct { enum { @@ -938,6 +946,7 @@ struct net_device_path_stack { struct net_device_path_ctx { const struct net_device *dev; u8 daddr[ETH_ALEN]; + __be16 ether_type; int num_vlans; struct { @@ -1845,6 +1854,8 @@ enum netdev_reg_state { * @napi_list: List entry used for polling NAPI devices * @unreg_list: List entry when we are unregistering the * device; see the function unregister_netdev + * @unreg_list_net:List entry when we are unregistering the cross-netns + * device; see the function unregister_netdevice_queue_net() * @close_list: List entry used when we are closing the device * @ptype_all: Device-specific packet handlers for all protocols * @ptype_specific: Device-specific, protocol-specific packet handlers @@ -2241,6 +2252,9 @@ struct net_device { struct list_head dev_list; struct list_head napi_list; struct list_head unreg_list; +#ifdef CONFIG_DEBUG_NET_SMALL_RTNL + struct list_head unreg_list_net; +#endif struct list_head close_list; struct list_head ptype_all; @@ -2658,16 +2672,16 @@ static inline bool netif_elide_gro(const struct net_device *dev) static inline int netdev_get_prio_tc_map(const struct net_device *dev, u32 prio) { - return dev->prio_tc_map[prio & TC_BITMASK]; + return READ_ONCE(dev->prio_tc_map[prio & TC_BITMASK]); } static inline int netdev_set_prio_tc_map(struct net_device *dev, u8 prio, u8 tc) { - if (tc >= dev->num_tc) + if (tc >= READ_ONCE(dev->num_tc)) return -EINVAL; - dev->prio_tc_map[prio & TC_BITMASK] = tc & TC_BITMASK; + WRITE_ONCE(dev->prio_tc_map[prio & TC_BITMASK], tc & TC_BITMASK); return 0; } @@ -2677,9 +2691,9 @@ int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset); int netdev_set_num_tc(struct net_device *dev, u8 num_tc); static inline -int netdev_get_num_tc(struct net_device *dev) +int netdev_get_num_tc(const struct net_device *dev) { - return dev->num_tc; + return READ_ONCE(dev->num_tc); } static inline void net_prefetch(void *p) @@ -2706,7 +2720,7 @@ int netdev_bind_sb_channel_queue(struct net_device *dev, int netdev_set_sb_channel(struct net_device *dev, u16 channel); static inline int netdev_get_sb_channel(struct net_device *dev) { - return max_t(int, -dev->num_tc, 0); + return max_t(int, -READ_ONCE(dev->num_tc), 0); } static inline @@ -3420,8 +3434,9 @@ void dev_remove_offload(struct packet_offload *po); int dev_get_iflink(const struct net_device *dev); int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb); -int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, +int dev_fill_forward_path(struct net_device_path_ctx *ctx, struct net_device_path_stack *stack); +void dev_fill_forward_path_release(struct net_device_path_stack *stack); struct net_device *dev_get_by_name(struct net *net, const char *name); struct net_device *dev_get_by_name_rcu(struct net *net, const char *name); struct net_device *__dev_get_by_name(struct net *net, const char *name); @@ -3472,6 +3487,25 @@ static inline void unregister_netdevice(struct net_device *dev) unregister_netdevice_queue(dev, NULL); } +#ifdef CONFIG_DEBUG_NET_SMALL_RTNL +void unregister_netdevice_queue_net(struct net *net, struct net_device *dev, + struct list_head *head); +void unregister_netdevice_many_net(struct net *net); +void unregister_netdevice_queue_many_net(struct net *net, struct list_head *head); +#else +static inline void unregister_netdevice_queue_net(struct net *net, + struct net_device *dev, + struct list_head *head) +{ + unregister_netdevice_queue(dev, head); +} + +static inline void unregister_netdevice_queue_many_net(struct net *net, + struct list_head *head) +{ +} +#endif + int netdev_refcnt_read(const struct net_device *dev); void free_netdev(struct net_device *dev); @@ -3531,11 +3565,6 @@ static inline bool dev_validate_header(const struct net_device *dev, if (len < dev->min_header_len) return false; - if (capable(CAP_SYS_RAWIO)) { - memset(ll_header + len, 0, dev->hard_header_len - len); - return true; - } - if (dev->header_ops && dev->header_ops->validate) return dev->header_ops->validate(ll_header, len); diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index efbbfa770d66..e99afc1414cd 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -93,6 +93,7 @@ enum nf_hook_ops_type { NF_HOOK_OP_NF_TABLES, NF_HOOK_OP_BPF, NF_HOOK_OP_NFT_FT, + NF_HOOK_OP_NAT, }; struct nf_hook_ops { @@ -140,6 +141,12 @@ struct nf_hook_entries { */ }; +struct nf_nat_lookup_hook_priv { + struct nf_hook_entries __rcu *entries; + + struct rcu_head rcu_head; +}; + #ifdef CONFIG_NETFILTER static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e) { diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index b98331572ad2..c46864cc6623 100644 --- a/include/linux/netfilter/ipset/ip_set.h +++ b/include/linux/netfilter/ipset/ip_set.h @@ -244,8 +244,8 @@ extern void ip_set_type_unregister(struct ip_set_type *set_type); /* A generic IP set */ struct ip_set { - /* For call_cru in destroy */ - struct rcu_head rcu; + /* for set destruction */ + struct rcu_work rwork; /* The name of the set */ char name[IPSET_MAXNAMELEN]; /* Lock protecting the set data */ @@ -273,7 +273,7 @@ struct ip_set { /* Number of elements (vs timeout) */ u32 elements; /* Size of the dynamic extensions (vs timeout) */ - size_t ext_size; + atomic64_t ext_size; /* Element data size */ size_t dsize; /* Offsets to extensions in elements */ diff --git a/include/linux/netfilter/nf_conntrack_amanda.h b/include/linux/netfilter/nf_conntrack_amanda.h index 1719987e8fd8..deb560bb79c4 100644 --- a/include/linux/netfilter/nf_conntrack_amanda.h +++ b/include/linux/netfilter/nf_conntrack_amanda.h @@ -9,6 +9,7 @@ typedef unsigned int nf_nat_amanda_hook_fn(struct sk_buff *skb, + struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int protoff, unsigned int matchoff, diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h index 7b62446ccec4..712702183b94 100644 --- a/include/linux/netfilter/nf_conntrack_ftp.h +++ b/include/linux/netfilter/nf_conntrack_ftp.h @@ -28,6 +28,7 @@ struct nf_ct_ftp_master { * connection we should expect. */ typedef unsigned int nf_nat_ftp_hook_fn(struct sk_buff *skb, + struct nf_conn *ct, enum ip_conntrack_info ctinfo, enum nf_ct_ftp_type type, unsigned int protoff, diff --git a/include/linux/netfilter/nf_conntrack_h323.h b/include/linux/netfilter/nf_conntrack_h323.h index 81286c499325..b15f37604cde 100644 --- a/include/linux/netfilter/nf_conntrack_h323.h +++ b/include/linux/netfilter/nf_conntrack_h323.h @@ -9,8 +9,6 @@ #include <net/netfilter/nf_conntrack_expect.h> #include <uapi/linux/netfilter/nf_conntrack_tuple_common.h> -#define RAS_PORT 1719 -#define Q931_PORT 1720 #define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */ /* This structure exists only once per master */ diff --git a/include/linux/netfilter/nf_conntrack_irc.h b/include/linux/netfilter/nf_conntrack_irc.h index ce07250afb4e..c73b3b44a0b7 100644 --- a/include/linux/netfilter/nf_conntrack_irc.h +++ b/include/linux/netfilter/nf_conntrack_irc.h @@ -10,6 +10,7 @@ typedef unsigned int nf_nat_irc_hook_fn(struct sk_buff *skb, + struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int protoff, unsigned int matchoff, diff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h index c3bdb4370938..c0b305ce7c3c 100644 --- a/include/linux/netfilter/nf_conntrack_pptp.h +++ b/include/linux/netfilter/nf_conntrack_pptp.h @@ -50,8 +50,6 @@ struct nf_nat_pptp { __be16 pac_call_id; /* NAT'ed PAC call id */ }; -#define PPTP_CONTROL_PORT 1723 - #define PPTP_PACKET_CONTROL 1 #define PPTP_PACKET_MGMT 2 diff --git a/include/linux/netfilter/nf_conntrack_sane.h b/include/linux/netfilter/nf_conntrack_sane.h index 46c7acd1b4a7..8501035d7335 100644 --- a/include/linux/netfilter/nf_conntrack_sane.h +++ b/include/linux/netfilter/nf_conntrack_sane.h @@ -3,8 +3,6 @@ #define _NF_CONNTRACK_SANE_H /* SANE tracking. */ -#define SANE_PORT 6566 - enum sane_state { SANE_STATE_NORMAL, SANE_STATE_START_REQUESTED, diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h index dbc614dfe0d5..aafa0c04f917 100644 --- a/include/linux/netfilter/nf_conntrack_sip.h +++ b/include/linux/netfilter/nf_conntrack_sip.h @@ -115,7 +115,7 @@ struct nf_nat_sip_hooks { unsigned int *datalen); void (*seq_adjust)(struct sk_buff *skb, - unsigned int protoff, s16 off); + unsigned int protoff, s32 off); unsigned int (*expect)(struct sk_buff *skb, unsigned int protoff, diff --git a/include/linux/netfilter/nf_conntrack_tftp.h b/include/linux/netfilter/nf_conntrack_tftp.h index 90b334bbce3c..802cb7fc19cd 100644 --- a/include/linux/netfilter/nf_conntrack_tftp.h +++ b/include/linux/netfilter/nf_conntrack_tftp.h @@ -2,8 +2,6 @@ #ifndef _NF_CONNTRACK_TFTP_H #define _NF_CONNTRACK_TFTP_H -#define TFTP_PORT 69 - #include <linux/netfilter.h> #include <linux/skbuff.h> #include <linux/types.h> @@ -21,6 +19,7 @@ struct tftphdr { typedef unsigned int nf_nat_tftp_hook_fn(struct sk_buff *skb, + struct nf_conn *ct, enum ip_conntrack_info ctinfo, struct nf_conntrack_expect *exp); diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 243c0f737938..f837a501008c 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -61,14 +61,16 @@ struct netfs_inode { #if IS_ENABLED(CONFIG_FSCACHE) struct fscache_cookie *cache; #endif - struct mutex wb_lock; /* Writeback serialisation */ + struct list_head wb_queue; /* Queue of processes wanting to do writeback */ loff_t _remote_i_size; /* Size of the remote file */ loff_t _zero_point; /* Size after which we assume there's no data * on the server */ + spinlock_t lock; /* Lock covering wb_queue */ atomic_t io_count; /* Number of outstanding reqs */ unsigned long flags; #define NETFS_ICTX_ODIRECT 0 /* The file has DIO in progress */ #define NETFS_ICTX_UNBUFFERED 1 /* I/O should not use the pagecache */ +#define NETFS_ICTX_WB_LOCK 2 /* Writeback serialisation lock */ #define NETFS_ICTX_MODIFIED_ATTR 3 /* Indicate change in mtime/ctime */ #define NETFS_ICTX_SINGLE_NO_UPLOAD 4 /* Monolithic payload, cache but no upload */ }; @@ -189,7 +191,6 @@ struct netfs_io_subrequest { #define NETFS_SREQ_COPY_TO_CACHE 0 /* Set if should copy the data to the cache */ #define NETFS_SREQ_CLEAR_TAIL 1 /* Set if the rest of the read should be cleared */ #define NETFS_SREQ_MADE_PROGRESS 4 /* Set if we transferred at least some data */ -#define NETFS_SREQ_ONDEMAND 5 /* Set if it's from on-demand read mode */ #define NETFS_SREQ_BOUNDARY 6 /* Set if ends on hard boundary (eg. ceph object) */ #define NETFS_SREQ_HIT_EOF 7 /* Set if short due to EOF */ #define NETFS_SREQ_IN_PROGRESS 8 /* Unlocked when the subrequest completes */ @@ -253,6 +254,7 @@ struct netfs_io_request { unsigned long long cleaned_to; /* Position we've cleaned folios to */ unsigned long long abandon_to; /* Position to abandon folios to */ const struct folio *no_unlock_folio; /* Don't unlock this folio after read */ + gfp_t gfp; /* GFP flags to use */ unsigned int direct_bv_count; /* Number of elements in direct_bv[] */ unsigned int debug_id; unsigned int rsize; /* Maximum read size (0 for none) */ @@ -371,14 +373,6 @@ struct netfs_cache_ops { loff_t *_start, size_t *_len, size_t upper_len, loff_t i_size, bool no_space_allocated_yet); - /* Prepare an on-demand read operation, shortening it to a cached/uncached - * boundary as appropriate. - */ - enum netfs_io_source (*prepare_ondemand_read)(struct netfs_cache_resources *cres, - loff_t start, size_t *_len, - loff_t i_size, - unsigned long *_flags, ino_t ino); - /* Query the occupancy of the cache in a region, returning where the * next chunk of data starts and how long it is. */ @@ -462,6 +456,10 @@ int netfs_alloc_folioq_buffer(struct address_space *mapping, size_t *_cur_size, ssize_t size, gfp_t gfp); void netfs_free_folioq_buffer(struct folio_queue *fq); +/* Writeback exclusion API. */ +bool netfs_wb_begin(struct netfs_inode *ictx, bool nowait); +void netfs_wb_end(struct netfs_inode *ictx); + /** * netfs_inode - Get the netfs inode context from the inode * @inode: The inode to query @@ -743,7 +741,8 @@ static inline void netfs_inode_init(struct netfs_inode *ctx, #if IS_ENABLED(CONFIG_FSCACHE) ctx->cache = NULL; #endif - mutex_init(&ctx->wb_lock); + INIT_LIST_HEAD(&ctx->wb_queue); + spin_lock_init(&ctx->lock); /* ->releasepage() drives zero_point */ if (use_zero_point) { ctx->_zero_point = ctx->_remote_i_size; @@ -753,7 +752,7 @@ static inline void netfs_inode_init(struct netfs_inode *ctx, /** * netfs_resize_file - Note that a file got resized - * @ctx: The netfs inode being resized + * @ictx: The netfs inode being resized * @new_i_size: The new file size * @changed_on_server: The change was applied to the server * diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 88f7daa8560e..1c6b1eec5efd 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -21,20 +21,6 @@ union inet_addr { 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; @@ -46,13 +32,6 @@ struct netpoll { char dev_name[IFNAMSIZ]; u8 dev_mac[ETH_ALEN]; const char *name; - - union inet_addr local_ip, remote_ip; - bool ipv6; - u16 local_port, remote_port; - u8 remote_mac[ETH_ALEN]; - struct sk_buff_head skb_pool; - struct work_struct refill_wq; }; #define np_info(np, fmt, ...) \ @@ -84,12 +63,12 @@ static inline void netpoll_poll_enable(struct net_device *dev) { return; } #endif 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); +unsigned int netpoll_get_carrier_timeout(void); #ifdef CONFIG_NETPOLL static inline void *netpoll_poll_lock(struct napi_struct *napi) diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index d87be1f25273..1a3981c26b23 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -171,133 +171,6 @@ Needs to be updated if more operations are defined in future.*/ #define LAST_NFS42_OP OP_REMOVEXATTR #define LAST_NFS4_OP LAST_NFS42_OP -enum nfsstat4 { - NFS4_OK = 0, - NFS4ERR_PERM = 1, - NFS4ERR_NOENT = 2, - NFS4ERR_IO = 5, - NFS4ERR_NXIO = 6, - NFS4ERR_ACCESS = 13, - NFS4ERR_EXIST = 17, - NFS4ERR_XDEV = 18, - /* Unused/reserved 19 */ - NFS4ERR_NOTDIR = 20, - NFS4ERR_ISDIR = 21, - NFS4ERR_INVAL = 22, - NFS4ERR_FBIG = 27, - NFS4ERR_NOSPC = 28, - NFS4ERR_ROFS = 30, - NFS4ERR_MLINK = 31, - NFS4ERR_NAMETOOLONG = 63, - NFS4ERR_NOTEMPTY = 66, - NFS4ERR_DQUOT = 69, - NFS4ERR_STALE = 70, - NFS4ERR_BADHANDLE = 10001, - NFS4ERR_BAD_COOKIE = 10003, - NFS4ERR_NOTSUPP = 10004, - NFS4ERR_TOOSMALL = 10005, - NFS4ERR_SERVERFAULT = 10006, - NFS4ERR_BADTYPE = 10007, - NFS4ERR_DELAY = 10008, - NFS4ERR_SAME = 10009, - NFS4ERR_DENIED = 10010, - NFS4ERR_EXPIRED = 10011, - NFS4ERR_LOCKED = 10012, - NFS4ERR_GRACE = 10013, - NFS4ERR_FHEXPIRED = 10014, - NFS4ERR_SHARE_DENIED = 10015, - NFS4ERR_WRONGSEC = 10016, - NFS4ERR_CLID_INUSE = 10017, - NFS4ERR_RESOURCE = 10018, - NFS4ERR_MOVED = 10019, - NFS4ERR_NOFILEHANDLE = 10020, - NFS4ERR_MINOR_VERS_MISMATCH = 10021, - NFS4ERR_STALE_CLIENTID = 10022, - NFS4ERR_STALE_STATEID = 10023, - NFS4ERR_OLD_STATEID = 10024, - NFS4ERR_BAD_STATEID = 10025, - NFS4ERR_BAD_SEQID = 10026, - NFS4ERR_NOT_SAME = 10027, - NFS4ERR_LOCK_RANGE = 10028, - NFS4ERR_SYMLINK = 10029, - NFS4ERR_RESTOREFH = 10030, - NFS4ERR_LEASE_MOVED = 10031, - NFS4ERR_ATTRNOTSUPP = 10032, - NFS4ERR_NO_GRACE = 10033, - NFS4ERR_RECLAIM_BAD = 10034, - NFS4ERR_RECLAIM_CONFLICT = 10035, - NFS4ERR_BADXDR = 10036, - NFS4ERR_LOCKS_HELD = 10037, - NFS4ERR_OPENMODE = 10038, - NFS4ERR_BADOWNER = 10039, - NFS4ERR_BADCHAR = 10040, - NFS4ERR_BADNAME = 10041, - NFS4ERR_BAD_RANGE = 10042, - NFS4ERR_LOCK_NOTSUPP = 10043, - NFS4ERR_OP_ILLEGAL = 10044, - NFS4ERR_DEADLOCK = 10045, - NFS4ERR_FILE_OPEN = 10046, - NFS4ERR_ADMIN_REVOKED = 10047, - NFS4ERR_CB_PATH_DOWN = 10048, - - /* nfs41 */ - NFS4ERR_BADIOMODE = 10049, - NFS4ERR_BADLAYOUT = 10050, - NFS4ERR_BAD_SESSION_DIGEST = 10051, - NFS4ERR_BADSESSION = 10052, - NFS4ERR_BADSLOT = 10053, - NFS4ERR_COMPLETE_ALREADY = 10054, - NFS4ERR_CONN_NOT_BOUND_TO_SESSION = 10055, - NFS4ERR_DELEG_ALREADY_WANTED = 10056, - NFS4ERR_BACK_CHAN_BUSY = 10057, /* backchan reqs outstanding */ - NFS4ERR_LAYOUTTRYLATER = 10058, - NFS4ERR_LAYOUTUNAVAILABLE = 10059, - NFS4ERR_NOMATCHING_LAYOUT = 10060, - NFS4ERR_RECALLCONFLICT = 10061, - NFS4ERR_UNKNOWN_LAYOUTTYPE = 10062, - NFS4ERR_SEQ_MISORDERED = 10063, /* unexpected seq.id in req */ - NFS4ERR_SEQUENCE_POS = 10064, /* [CB_]SEQ. op not 1st op */ - NFS4ERR_REQ_TOO_BIG = 10065, /* request too big */ - NFS4ERR_REP_TOO_BIG = 10066, /* reply too big */ - NFS4ERR_REP_TOO_BIG_TO_CACHE = 10067, /* rep. not all cached */ - NFS4ERR_RETRY_UNCACHED_REP = 10068, /* retry & rep. uncached */ - NFS4ERR_UNSAFE_COMPOUND = 10069, /* retry/recovery too hard */ - NFS4ERR_TOO_MANY_OPS = 10070, /* too many ops in [CB_]COMP */ - NFS4ERR_OP_NOT_IN_SESSION = 10071, /* op needs [CB_]SEQ. op */ - NFS4ERR_HASH_ALG_UNSUPP = 10072, /* hash alg. not supp. */ - /* Error 10073 is unused. */ - NFS4ERR_CLIENTID_BUSY = 10074, /* clientid has state */ - NFS4ERR_PNFS_IO_HOLE = 10075, /* IO to _SPARSE file hole */ - NFS4ERR_SEQ_FALSE_RETRY = 10076, /* retry not original */ - NFS4ERR_BAD_HIGH_SLOT = 10077, /* sequence arg bad */ - NFS4ERR_DEADSESSION = 10078, /* persistent session dead */ - NFS4ERR_ENCR_ALG_UNSUPP = 10079, /* SSV alg mismatch */ - NFS4ERR_PNFS_NO_LAYOUT = 10080, /* direct I/O with no layout */ - NFS4ERR_NOT_ONLY_OP = 10081, /* bad compound */ - NFS4ERR_WRONG_CRED = 10082, /* permissions:state change */ - NFS4ERR_WRONG_TYPE = 10083, /* current operation mismatch */ - NFS4ERR_DIRDELEG_UNAVAIL = 10084, /* no directory delegation */ - NFS4ERR_REJECT_DELEG = 10085, /* on callback */ - NFS4ERR_RETURNCONFLICT = 10086, /* outstanding layoutreturn */ - NFS4ERR_DELEG_REVOKED = 10087, /* deleg./layout revoked */ - - /* nfs42 */ - NFS4ERR_PARTNER_NOTSUPP = 10088, - NFS4ERR_PARTNER_NO_AUTH = 10089, - NFS4ERR_UNION_NOTSUPP = 10090, - NFS4ERR_OFFLOAD_DENIED = 10091, - NFS4ERR_WRONG_LFS = 10092, - NFS4ERR_BADLABEL = 10093, - NFS4ERR_OFFLOAD_NO_REQS = 10094, - - /* xattr (RFC8276) */ - NFS4ERR_NOXATTR = 10095, - NFS4ERR_XATTR2BIG = 10096, - - /* can be used for internal errors */ - NFS4ERR_FIRST_FREE -}; - /* error codes for internal client use */ #define NFS4ERR_RESET_TO_MDS 12001 #define NFS4ERR_RESET_TO_PNFS 12002 @@ -517,6 +390,14 @@ enum { }; /* + * Symbol name and value are from draft-ietf-nfsv4-uncacheable-files + * Section 7. "XDR for Uncacheable Attribute" + */ +enum { + FATTR4_UNCACHEABLE_FILE_DATA = 87, +}; + +/* * The following internal definitions enable processing the above * attribute bits within 32-bit word boundaries. */ @@ -602,6 +483,7 @@ enum { #define FATTR4_WORD2_ACL_TRUEFORM_SCOPE BIT(FATTR4_ACL_TRUEFORM_SCOPE - 64) #define FATTR4_WORD2_POSIX_DEFAULT_ACL BIT(FATTR4_POSIX_DEFAULT_ACL - 64) #define FATTR4_WORD2_POSIX_ACCESS_ACL BIT(FATTR4_POSIX_ACCESS_ACL - 64) +#define FATTR4_WORD2_UNCACHEABLE_FILE_DATA BIT(FATTR4_UNCACHEABLE_FILE_DATA - 64) /* MDS threshold bitmap bits */ #define THRESHOLD_RD (1UL << 0) diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index ec17e602c979..b85a73ae7919 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -110,6 +110,7 @@ struct nfs_open_context { #define NFS_CONTEXT_UNLOCK (3) #define NFS_CONTEXT_FILE_OPEN (4) #define NFS_CONTEXT_WRITE_SYNC (5) +#define NFS_CONTEXT_O_DIRECT (6) struct nfs4_threshold *mdsthreshold; struct list_head list; @@ -162,6 +163,8 @@ struct nfs_inode { struct timespec64 btime; + bool uncacheable_file_data : 1; + /* * read_cache_jiffies is when we started read-caching this inode. * attrtimeo is for how long the cached information is assumed @@ -319,6 +322,7 @@ struct nfs4_copy_state { #define NFS_INO_INVALID_NLINK BIT(16) /* cached nlinks is invalid */ #define NFS_INO_INVALID_MODE BIT(17) /* cached mode is invalid */ #define NFS_INO_INVALID_BTIME BIT(18) /* cached btime is invalid */ +#define NFS_INO_INVALID_UNCACHEABLE_FILE_DATA BIT(19) /* cached uncacheable_file_data is invalid */ #define NFS_INO_INVALID_ATTR (NFS_INO_INVALID_CHANGE \ | NFS_INO_INVALID_CTIME \ @@ -548,7 +552,6 @@ static inline const struct cred *nfs_file_cred(struct file *file) /* * linux/fs/nfs/direct.c */ -int nfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter); ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter, bool swap); ssize_t nfs_file_direct_write(struct kiocb *iocb, diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 11c5b31cfc7d..7ed8fdb930d6 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -17,6 +17,9 @@ #define NFS_BITMASK_SZ 3 +/* aux_flags in nfs_fattr */ +#define NFS_AUX_UNCACHEABLE_FILE_DATA BIT(0) + struct nfs4_string { unsigned int len; char *data; @@ -68,6 +71,7 @@ struct nfs_fattr { struct timespec64 mtime; struct timespec64 ctime; struct timespec64 btime; + __u32 aux_flags; /* NFSv4 auxiliary flags bitfield */ __u64 change_attr; /* NFSv4 change attribute */ __u64 pre_change_attr;/* pre-op NFSv4 change attribute */ __u64 pre_size; /* pre_op_attr.size */ @@ -108,6 +112,7 @@ struct nfs_fattr { #define NFS_ATTR_FATTR_GROUP_NAME BIT_ULL(24) #define NFS_ATTR_FATTR_V4_SECURITY_LABEL BIT_ULL(25) #define NFS_ATTR_FATTR_BTIME BIT_ULL(26) +#define NFS_ATTR_FATTR_UNCACHEABLE_FILE_DATA BIT_ULL(27) #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ | NFS_ATTR_FATTR_MODE \ @@ -129,7 +134,8 @@ struct nfs_fattr { #define NFS_ATTR_FATTR_V4 (NFS_ATTR_FATTR \ | NFS_ATTR_FATTR_SPACE_USED \ | NFS_ATTR_FATTR_BTIME \ - | NFS_ATTR_FATTR_V4_SECURITY_LABEL) + | NFS_ATTR_FATTR_V4_SECURITY_LABEL \ + | NFS_ATTR_FATTR_UNCACHEABLE_FILE_DATA) /* * Maximal number of supported layout drivers. @@ -354,7 +360,7 @@ struct nfs4_layoutreturn { struct nfs4_xdr_opaque_data ld_private; }; -#define PNFS_LAYOUTSTATS_MAXSIZE 256 +#define PNFS_LAYOUTSTATS_MAXSIZE 384 struct nfs42_layoutstat_args; struct nfs42_layoutstat_devinfo; diff --git a/include/linux/nmi.h b/include/linux/nmi.h index bc1162895f35..af69712df5f4 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -77,9 +77,9 @@ static inline void reset_hung_task_detector(void) { } * detectors are 'suspended' while 'watchdog_thresh' is equal zero. */ #define WATCHDOG_HARDLOCKUP_ENABLED_BIT 0 -#define WATCHDOG_SOFTOCKUP_ENABLED_BIT 1 +#define WATCHDOG_SOFTLOCKUP_ENABLED_BIT 1 #define WATCHDOG_HARDLOCKUP_ENABLED (1 << WATCHDOG_HARDLOCKUP_ENABLED_BIT) -#define WATCHDOG_SOFTOCKUP_ENABLED (1 << WATCHDOG_SOFTOCKUP_ENABLED_BIT) +#define WATCHDOG_SOFTLOCKUP_ENABLED (1 << WATCHDOG_SOFTLOCKUP_ENABLED_BIT) #if defined(CONFIG_HARDLOCKUP_DETECTOR) extern void hardlockup_detector_disable(void); @@ -157,27 +157,29 @@ static inline void touch_nmi_watchdog(void) * to allow calling code to fall back to some other mechanism: */ #ifdef arch_trigger_cpumask_backtrace +void cpumask_backtrace(const cpumask_t *mask, int exclude_cpu); + static inline bool trigger_all_cpu_backtrace(void) { - arch_trigger_cpumask_backtrace(cpu_online_mask, -1); + cpumask_backtrace(cpu_online_mask, -1); return true; } static inline bool trigger_allbutcpu_cpu_backtrace(int exclude_cpu) { - arch_trigger_cpumask_backtrace(cpu_online_mask, exclude_cpu); + cpumask_backtrace(cpu_online_mask, exclude_cpu); return true; } static inline bool trigger_cpumask_backtrace(struct cpumask *mask) { - arch_trigger_cpumask_backtrace(mask, -1); + cpumask_backtrace(mask, -1); return true; } static inline bool trigger_single_cpu_backtrace(int cpu) { - arch_trigger_cpumask_backtrace(cpumask_of(cpu), -1); + cpumask_backtrace(cpumask_of(cpu), -1); return true; } diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index b842aa525546..607373bd83ee 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -95,6 +95,14 @@ extern nodemask_t _unused_nodemask_arg_; +#if MAX_NUMNODES > 1 +extern unsigned int nr_node_ids; +extern unsigned int nr_online_nodes; +#else +#define nr_node_ids 1U +#define nr_online_nodes 1U +#endif + /** * nodemask_pr_args - printf args to output a nodemask * @maskp: nodemask to be printed @@ -105,7 +113,7 @@ extern nodemask_t _unused_nodemask_arg_; __nodemask_pr_bits(maskp) static __always_inline unsigned int __nodemask_pr_numnodes(const nodemask_t *m) { - return m ? MAX_NUMNODES : 0; + return m ? nr_node_ids : 0; } static __always_inline const unsigned long *__nodemask_pr_bits(const nodemask_t *m) { @@ -438,9 +446,6 @@ static __always_inline unsigned int next_memory_node(int nid) return next_node(nid, node_states[N_MEMORY]); } -extern unsigned int nr_node_ids; -extern unsigned int nr_online_nodes; - static __always_inline void node_set_online(int nid) { node_set_state(nid, N_ONLINE); @@ -480,8 +485,6 @@ static __always_inline int num_node_state(enum node_states state) #define first_memory_node 0 #define next_online_node(nid) (MAX_NUMNODES) #define next_memory_node(nid) (MAX_NUMNODES) -#define nr_node_ids 1U -#define nr_online_nodes 1U #define node_set_online(node) node_set_state((node), N_ONLINE) #define node_set_offline(node) node_clear_state((node), N_ONLINE) diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 041f30931a90..91ce434a7e8d 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -2272,14 +2272,14 @@ struct nvme_completion { #define NVME_TERTIARY(ver) ((ver) & 0xff) enum { - NVME_AEN_RESV_LOG_PAGE_AVALIABLE = 0x00, + NVME_AEN_RESV_LOG_PAGE_AVAILABLE = 0x00, }; enum { NVME_PR_LOG_EMPTY_LOG_PAGE = 0x00, NVME_PR_LOG_REGISTRATION_PREEMPTED = 0x01, NVME_PR_LOG_RESERVATION_RELEASED = 0x02, - NVME_PR_LOG_RESERVATOIN_PREEMPTED = 0x03, + NVME_PR_LOG_RESERVATION_PREEMPTED = 0x03, }; enum { diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index f3b13da78aac..6063fe5b7784 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -214,6 +214,12 @@ static inline int nvmem_layout_register(struct nvmem_layout *layout) static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} +static inline int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, + struct device_node *np) +{ + return -EOPNOTSUPP; +} + #endif /* CONFIG_NVMEM */ #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF) diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h index 15f58e3c56c7..27f652d4920b 100644 --- a/include/linux/oa_tc6.h +++ b/include/linux/oa_tc6.h @@ -10,15 +10,86 @@ #include <linux/etherdevice.h> #include <linux/spi/spi.h> +/* OPEN Alliance TC6 registers */ +/* Standard Capabilities Register */ +#define OA_TC6_REG_STDCAP 0x0002 +#define OA_TC6_STDCAP_DIRECT_PHY_REG_ACCESS BIT(8) + +/* Reset Control and Status Register */ +#define OA_TC6_REG_RESET 0x0003 +#define OA_TC6_RESET_SWRESET BIT(0) /* Software Reset */ + +/* Configuration Register #0 */ +#define OA_TC6_REG_CONFIG0 0x0004 +#define OA_TC6_CONFIG0_SYNC BIT(15) +#define OA_TC6_CONFIG0_ZARFE_ENABLE BIT(12) +#define OA_TC6_CONFIG0_PROTE BIT(5) + +/* Configuration Register #2 */ +#define OA_TC6_REG_CONFIG2 0x0006 + +/* Status Register #0 */ +#define OA_TC6_REG_STATUS0 0x0008 +#define OA_TC6_STATUS0_RESETC BIT(6) /* Reset Complete */ +#define OA_TC6_STATUS0_HEADER_ERROR BIT(5) +#define OA_TC6_STATUS0_LOSS_OF_FRAME_ERROR BIT(4) +#define OA_TC6_STATUS0_RX_BUFFER_OVERFLOW_ERROR BIT(3) +#define OA_TC6_STATUS0_TX_PROTOCOL_ERROR BIT(0) + +/* Buffer Status Register */ +#define OA_TC6_REG_BUFFER_STATUS 0x000B +#define OA_TC6_BUFFER_STATUS_TX_CREDITS_AVAILABLE GENMASK(15, 8) +#define OA_TC6_BUFFER_STATUS_RX_CHUNKS_AVAILABLE GENMASK(7, 0) + +/* Interrupt Mask Register #0 */ +#define OA_TC6_REG_INT_MASK0 0x000C +#define OA_TC6_INT_MASK0_HEADER_ERR_MASK BIT(5) +#define OA_TC6_INT_MASK0_LOSS_OF_FRAME_ERR_MASK BIT(4) +#define OA_TC6_INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK BIT(3) +#define OA_TC6_INT_MASK0_TX_PROTOCOL_ERR_MASK BIT(0) +#define OA_TC6_INT_MASK0_ALL_INTERRUPTS (GENMASK(5, 0) | \ + GENMASK(12, 7)) + +/* PHY Clause 22 registers base address and mask */ +#define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00 +#define OA_TC6_PHY_STD_REG_ADDR_MASK 0x1F + +/* Memory map selector (MMS) values as per table 6 in the + * OPEN Alliance specification. + */ +#define OA_TC6_MAC_MMS1 1 +#define OA_TC6_PHY_C45_PCS_MMS2 2 /* MMD 3 */ +#define OA_TC6_PHY_C45_PMA_PMD_MMS3 3 /* MMD 1 */ +#define OA_TC6_PHY_C45_VS_PLCA_MMS4 4 /* MMD 31 */ +#define OA_TC6_PHY_C45_AUTO_NEG_MMS5 5 /* MMD 7 */ +#define OA_TC6_PHY_C45_POWER_UNIT_MMS6 6 /* MMD 13 */ + struct oa_tc6; -struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev); +enum oa_tc6_quirk_flag { + OA_TC6_BROKEN_PHY = BIT(0), +}; + +struct oa_tc6_quirks { + enum oa_tc6_quirk_flag quirk_flags; +}; + +struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev, + struct oa_tc6_quirks *quirks); void oa_tc6_exit(struct oa_tc6 *tc6); int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value); +int oa_tc6_write_register_mms(struct oa_tc6 *tc6, u8 mms, u16 address, + u32 value); int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[], u8 length); int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address, u32 *value); +int oa_tc6_read_register_mms(struct oa_tc6 *tc6, u8 mms, u16 address, + u32 *value); int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address, u32 value[], u8 length); netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb); int oa_tc6_zero_align_receive_frame_enable(struct oa_tc6 *tc6); +int oa_tc6_mdiobus_read_c45(struct mii_bus *bus, int addr, int devnum, + int regnum); +int oa_tc6_mdiobus_write_c45(struct mii_bus *bus, int addr, int devnum, + int regnum, u16 val); diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 9a00e701454c..af2e68e496e5 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -7,7 +7,7 @@ #ifdef CONFIG_OBJTOOL -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define UNWIND_HINT(type, sp_reg, sp_offset, signal) \ "987: \n\t" \ @@ -53,7 +53,7 @@ #define __ASM_BREF(label) label ## b -#else /* __ASSEMBLY__ */ +#else /* __ASSEMBLER__ */ /* * In asm, there are two kinds of code: normal C-type callable functions and @@ -102,11 +102,11 @@ #endif .endm -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #else /* !CONFIG_OBJTOOL */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define UNWIND_HINT(type, sp_reg, sp_offset, signal) "\n\t" #define STACK_FRAME_NON_STANDARD(func) diff --git a/include/linux/objtool_types.h b/include/linux/objtool_types.h index c6def4049b1a..c24e9ea39269 100644 --- a/include/linux/objtool_types.h +++ b/include/linux/objtool_types.h @@ -2,7 +2,7 @@ #ifndef _LINUX_OBJTOOL_TYPES_H #define _LINUX_OBJTOOL_TYPES_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/types.h> @@ -18,7 +18,7 @@ struct unwind_hint { u8 signal; }; -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ /* * UNWIND_HINT_TYPE_UNDEFINED: A blind spot in ORC coverage which can result in diff --git a/include/linux/of.h b/include/linux/of.h index 20e4f752d5b6..b920aac6b975 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -16,7 +16,7 @@ #include <linux/cleanup.h> #include <linux/errno.h> #include <linux/kobject.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/of.h> #include <linux/property.h> #include <linux/list.h> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index 29658c0ee71f..649fe8eafcfa 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h @@ -30,12 +30,18 @@ static inline void of_pci_check_probe_only(void) { } #if IS_ENABLED(CONFIG_OF_IRQ) int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); +void pci_configure_of_wake_gpio(struct pci_dev *dev); +void pci_remove_of_wake_gpio(struct pci_dev *dev); #else static inline int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) { return 0; } + +static inline void pci_configure_of_wake_gpio(struct pci_dev *dev) { } + +static inline void pci_remove_of_wake_gpio(struct pci_dev *dev) { } #endif #endif diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 17471ef8e092..181c438a9b0a 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -6,7 +6,9 @@ * <benh@kernel.crashing.org> */ -#include <linux/mod_devicetable.h> +#include <linux/types.h> +#include <linux/err.h> +#include <linux/device-id/of.h> struct device; struct device_node; diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h index e8b20b29fa68..49da515859f2 100644 --- a/include/linux/of_reserved_mem.h +++ b/include/linux/of_reserved_mem.h @@ -40,6 +40,8 @@ int of_reserved_mem_device_init_by_name(struct device *dev, const char *name); void of_reserved_mem_device_release(struct device *dev); +int devm_of_reserved_mem_device_init(struct device *dev); + struct reserved_mem *of_reserved_mem_lookup(struct device_node *np); int of_reserved_mem_region_to_resource(const struct device_node *np, unsigned int idx, struct resource *res); @@ -68,6 +70,11 @@ static inline int of_reserved_mem_device_init_by_name(struct device *dev, static inline void of_reserved_mem_device_release(struct device *pdev) { } +static inline int devm_of_reserved_mem_device_init(struct device *dev) +{ + return -EOPNOTSUPP; +} + static inline struct reserved_mem *of_reserved_mem_lookup(struct device_node *np) { return NULL; diff --git a/include/linux/oom.h b/include/linux/oom.h index 7b02bc1d0a7e..00da05d227e6 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -30,7 +30,7 @@ struct oom_control { struct zonelist *zonelist; /* Used to determine mempolicy */ - nodemask_t *nodemask; + const nodemask_t *nodemask; /* Memory cgroup in which oom is invoked, or NULL for global oom */ struct mem_cgroup *memcg; diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 7223f6f4e2b4..7a863572adce 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -879,20 +879,6 @@ FOLIO_FLAG_FALSE(partially_mapped) #define PG_head_mask ((1UL << PG_head)) -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -/* - * PageTransCompound returns true for both transparent huge pages - * and hugetlbfs pages, so it should only be called when it's known - * that hugetlbfs pages aren't involved. - */ -static inline int PageTransCompound(const struct page *page) -{ - return PageCompound(page); -} -#else -TESTPAGEFLAG_FALSE(TransCompound, transcompound) -#endif - #if defined(CONFIG_MEMORY_FAILURE) && defined(CONFIG_TRANSPARENT_HUGEPAGE) /* * PageHasHWPoisoned indicates that at least one subpage is hwpoisoned in the diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index 61e876e255e8..79c53ec45dfa 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -55,7 +55,6 @@ struct page_ext { extern bool early_page_ext; extern unsigned long page_ext_size; -extern void pgdat_page_ext_init(struct pglist_data *pgdat); static inline bool early_page_ext_enabled(void) { @@ -120,14 +119,18 @@ struct page_ext_iter { * page_ext_iter_begin() - Prepare for iterating through page extensions. * @iter: page extension iterator. * @pfn: PFN of the page we're interested in. + * @count: maximum number of page extensions to return. * * Must be called with RCU read lock taken. * * Return: NULL if no page_ext exists for this page. */ static inline struct page_ext *page_ext_iter_begin(struct page_ext_iter *iter, - unsigned long pfn) + unsigned long pfn, unsigned long count) { + if (!count) + return NULL; + iter->index = 0; iter->start_pfn = pfn; iter->page_ext = page_ext_lookup(pfn); @@ -138,19 +141,22 @@ static inline struct page_ext *page_ext_iter_begin(struct page_ext_iter *iter, /** * page_ext_iter_next() - Get next page extension * @iter: page extension iterator. + * @count: maximum number of page extensions to return. * * Must be called with RCU read lock taken. * * Return: NULL if no next page_ext exists. */ -static inline struct page_ext *page_ext_iter_next(struct page_ext_iter *iter) +static inline struct page_ext *page_ext_iter_next(struct page_ext_iter *iter, + unsigned long count) { unsigned long pfn; if (WARN_ON_ONCE(!iter->page_ext)) return NULL; - iter->index++; + if (++iter->index >= count) + return NULL; pfn = iter->start_pfn + iter->index; if (page_ext_iter_next_fast_possible(pfn)) @@ -183,9 +189,9 @@ static inline struct page_ext *page_ext_iter_get(const struct page_ext_iter *ite * IMPORTANT: must be called with RCU read lock taken. */ #define for_each_page_ext(__page, __pgcount, __page_ext, __iter) \ - for (__page_ext = page_ext_iter_begin(&__iter, page_to_pfn(__page));\ - __page_ext && __iter.index < __pgcount; \ - __page_ext = page_ext_iter_next(&__iter)) + for (__page_ext = page_ext_iter_begin(&__iter, page_to_pfn(__page), __pgcount); \ + __page_ext; \ + __page_ext = page_ext_iter_next(&__iter, __pgcount)) #else /* !CONFIG_PAGE_EXTENSION */ struct page_ext; @@ -195,10 +201,6 @@ static inline bool early_page_ext_enabled(void) return false; } -static inline void pgdat_page_ext_init(struct pglist_data *pgdat) -{ -} - static inline void page_ext_init(void) { } diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h index 3328357f6dba..8188ddc5c412 100644 --- a/include/linux/page_owner.h +++ b/include/linux/page_owner.h @@ -3,6 +3,7 @@ #define __LINUX_PAGE_OWNER_H #include <linux/jump_label.h> +#include <linux/migrate_mode.h> #ifdef CONFIG_PAGE_OWNER extern struct static_key_false page_owner_inited; @@ -14,7 +15,7 @@ extern void __set_page_owner(struct page *page, extern void __split_page_owner(struct page *page, int old_order, int new_order); extern void __folio_copy_owner(struct folio *newfolio, struct folio *old); -extern void __folio_set_owner_migrate_reason(struct folio *folio, int reason); +void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason); extern void __dump_page_owner(const struct page *page); extern void pagetypeinfo_showmixedcount_print(struct seq_file *m, pg_data_t *pgdat, struct zone *zone); @@ -43,7 +44,7 @@ static inline void folio_copy_owner(struct folio *newfolio, struct folio *old) if (static_branch_unlikely(&page_owner_inited)) __folio_copy_owner(newfolio, old); } -static inline void folio_set_owner_migrate_reason(struct folio *folio, int reason) +static inline void folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason) { if (static_branch_unlikely(&page_owner_inited)) __folio_set_owner_migrate_reason(folio, reason); @@ -68,7 +69,7 @@ static inline void split_page_owner(struct page *page, int old_order, static inline void folio_copy_owner(struct folio *newfolio, struct folio *folio) { } -static inline void folio_set_owner_migrate_reason(struct folio *folio, int reason) +static inline void folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason) { } static inline void dump_page_owner(const struct page *page) diff --git a/include/linux/page_reporting.h b/include/linux/page_reporting.h index 9d4ca5c218a0..272b1274efdc 100644 --- a/include/linux/page_reporting.h +++ b/include/linux/page_reporting.h @@ -5,7 +5,6 @@ #include <linux/mmzone.h> #include <linux/scatterlist.h> -/* This value should always be a power of 2, see page_reporting_cycle() */ #define PAGE_REPORTING_CAPACITY 32 #define PAGE_REPORTING_ORDER_UNSPECIFIED -1 @@ -22,6 +21,9 @@ struct page_reporting_dev_info { /* Minimal order of page reporting */ unsigned int order; + + /* Max pages per report batch; 0 (default) means PAGE_REPORTING_CAPACITY */ + unsigned int capacity; }; /* Tear-down and bring-up for page reporting devices */ diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 2c3718d592d6..0adfa6605653 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -1063,12 +1063,75 @@ static inline pgoff_t folio_pgoff(const struct folio *folio) return folio->index; } +/** + * linear_page_delta() - Determine the relative page offset of @address within + * @vma. + * @vma: The VMA in which @address resides. + * @address: The address whose relative page offset is required. + * + * The result is identical for both file-backed and anonymous mappings and + * simply determines how many pages @address lies from @vma->vm_start. + * + * Returns: The number of pages @address is offset by within @vma. + */ +static inline pgoff_t linear_page_delta(const struct vm_area_struct *vma, + const unsigned long address) +{ + return (address - vma->vm_start) >> PAGE_SHIFT; +} + +/** + * linear_page_index() - Determine the absolute page offset of @address within + * @vma. + * @vma: The VMA in which @address resides. + * @address: The address whose absolute page offset is required. + * + * See the comment for vma_start_pgoff() for a description of what the page + * offset signifies. + * + * Returns: The absolute page offset of @address within @vma. + */ static inline pgoff_t linear_page_index(const struct vm_area_struct *vma, const unsigned long address) { - pgoff_t pgoff; - pgoff = (address - vma->vm_start) >> PAGE_SHIFT; - pgoff += vma->vm_pgoff; + return linear_page_delta(vma, address) + vma_start_pgoff(vma); +} + +static inline pgoff_t __linear_anon_page_index(const struct vm_area_struct *vma, + const unsigned long address) +{ + return linear_page_delta(vma, address) + vma_start_anon_pgoff(vma); +} + +/** + * linear_anon_page_index() - Determine the absolute anonymous page offset of + * @address within @vma. + * @vma: An anonymous or MAP_PRIVATE file-backed VMA in which @address resides. + * @address: The address whose absolute page offset is required. + * + * This returns the anonymous page offset of @address, which is the page offset + * the address possessed at the time the VMA was first faulted. + * + * For anonymous mappings, this returns the same value as linear_page_index(). + * + * For MAP_PRIVATE file-backed mappings, this returns the anonymous page offset + * of @address, which is the page offset the address possessed at the time the + * VMA was first faulted. + * + * It is not valid to call this function for shared file-backed mappings. + * + * Returns: The absolute anonymous page offset of @address within @vma. + */ +static inline pgoff_t linear_anon_page_index(const struct vm_area_struct *vma, + const unsigned long address) +{ + const pgoff_t pgoff = __linear_anon_page_index(vma, address); + + VM_WARN_ON_ONCE(!vma_is_cow_mapping(vma)); + /* Account for MAP_PRIVATE-/dev/zero which is only semi-anonymous. */ + if (vma_is_anonymous(vma) && !vma->vm_file) + VM_WARN_ON_ONCE(pgoff != linear_page_index(vma, address)); + return pgoff; } @@ -1219,7 +1282,7 @@ static inline vm_fault_t folio_lock_or_retry(struct folio *folio, void folio_wait_bit(struct folio *folio, int bit_nr); int folio_wait_bit_killable(struct folio *folio, int bit_nr); -/* +/* * Wait for a folio to be unlocked. * * This must be called with the caller "holding" the folio, diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h index d930651473b4..044f67ced6ff 100644 --- a/include/linux/pci-ecam.h +++ b/include/linux/pci-ecam.h @@ -81,6 +81,9 @@ void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, /* default ECAM ops */ extern const struct pci_ecam_ops pci_generic_ecam_ops; +/* default CAM ops */ +extern const struct pci_ecam_ops pci_generic_cam_ops; + #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) extern const struct pci_ecam_ops pci_32b_ops; /* 32-bit accesses only */ extern const struct pci_ecam_ops pci_32b_read_ops; /* 32-bit read only */ diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index 8a6c64a35890..704e1dc8b30a 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -11,7 +11,7 @@ #include <linux/configfs.h> #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/pci.h> #include <linux/msi.h> #include <linux/pci.h> diff --git a/include/linux/pci.h b/include/linux/pci.h index ebb5b9d76360..d31a8d107b1e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -24,7 +24,7 @@ #define LINUX_PCI_H #include <linux/args.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/pci.h> #include <linux/types.h> #include <linux/sizes.h> @@ -79,14 +79,18 @@ * and, if ARI Forwarding is enabled, functions may appear to be on multiple * devices. */ -#define PCI_SLOT_ALL_DEVICES 0xfe +#define PCI_SLOT_ALL_DEVICES 0xfeff + +/* Used to identify a slot as a placeholder */ +#define PCI_SLOT_PLACEHOLDER 0xffff /* pci_slot represents a physical slot */ struct pci_slot { struct pci_bus *bus; /* Bus this slot is on */ struct list_head list; /* Node in list of slots */ struct hotplug_slot *hotplug; /* Hotplug info (move here) */ - unsigned char number; /* Device nr, or PCI_SLOT_ALL_DEVICES */ + u16 number; /* Device nr, or PCI_SLOT_ALL_DEVICES */ + unsigned int per_func_slot:1; /* Allow per function slot */ struct kobject kobj; }; @@ -587,6 +591,8 @@ struct pci_dev { /* These methods index pci_reset_fn_methods[] */ u8 reset_methods[PCI_NUM_RESET_METHODS]; /* In priority order */ + struct gpio_desc *wake; /* WAKE# GPIO */ + #ifdef CONFIG_PCIE_TPH u16 tph_cap; /* TPH capability offset */ u8 tph_mode; /* TPH mode */ @@ -646,6 +652,7 @@ struct pci_host_bridge { void (*release_fn)(struct pci_host_bridge *); int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev); void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev); + int (*reset_root_port)(struct pci_host_bridge *bridge, struct pci_dev *dev); void *release_data; unsigned int ignore_reset_delay:1; /* For entire hierarchy */ unsigned int no_ext_tags:1; /* No Extended Tags */ @@ -979,6 +986,7 @@ struct module; * function returns zero when the driver chooses to * take "ownership" of the device or an error code * (negative number) otherwise. + * The pci_device_id parameter is only valid during probe. * The probe function always gets called from process * context, so it can sleep. * @remove: The remove() function gets called whenever a device @@ -1783,6 +1791,26 @@ void pci_free_irq_vectors(struct pci_dev *dev); int pci_irq_vector(struct pci_dev *dev, unsigned int nr); const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, int vec); +/** + * pci_irq_type - Get the interrupt type of a PCI device + * @pdev: the PCI device to operate on + * + * Discriminate the interrupt type the PCI core selected for this device + * after a successful pci_alloc_irq_vectors() call. + * + * Return: %PCI_IRQ_MSIX, %PCI_IRQ_MSI, or %PCI_IRQ_INTX. + */ +static inline unsigned int pci_irq_type(struct pci_dev *pdev) +{ + if (pdev->msix_enabled) + return PCI_IRQ_MSIX; + + if (pdev->msi_enabled) + return PCI_IRQ_MSI; + + return PCI_IRQ_INTX; +} + #else static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } static inline void pci_disable_msi(struct pci_dev *dev) { } @@ -1845,6 +1873,11 @@ static inline const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, { return cpu_possible_mask; } + +static inline unsigned int pci_irq_type(struct pci_dev *pdev) +{ + return PCI_IRQ_INTX; +} #endif /** @@ -2255,6 +2288,11 @@ static inline bool pci_suspend_retains_context(struct pci_dev *pdev) { return true; } + +static inline unsigned int pci_irq_type(struct pci_dev *pdev) +{ + return 0; +} #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ @@ -2569,7 +2607,7 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id); int pci_num_vf(struct pci_dev *dev); int pci_vfs_assigned(struct pci_dev *dev); int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); -int pci_sriov_get_totalvfs(struct pci_dev *dev); +unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev); int pci_sriov_configure_simple(struct pci_dev *dev, int nr_virtfn); resource_size_t pci_iov_resource_size(const struct pci_dev *dev, int resno); int pci_iov_vf_bar_set_size(struct pci_dev *dev, int resno, int size); @@ -2622,7 +2660,7 @@ static inline int pci_vfs_assigned(struct pci_dev *dev) { return 0; } static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) { return 0; } -static inline int pci_sriov_get_totalvfs(struct pci_dev *dev) +static inline unsigned int pci_sriov_get_totalvfs(struct pci_dev *dev) { return 0; } #define pci_sriov_configure_simple NULL static inline resource_size_t pci_iov_resource_size(const struct pci_dev *dev, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1c9d40e09107..63774ae2bf71 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2640,6 +2640,12 @@ #define PCI_VENDOR_ID_SUNIX 0x1fd4 #define PCI_DEVICE_ID_SUNIX_1999 0x1999 +#define PCI_VENDOR_ID_SPACEMIT 0x201f +#define PCI_DEVICE_ID_SPACEMIT_K1 0x0001 +#define PCI_DEVICE_ID_SPACEMIT_K3 0x0002 + +#define PCI_VENDOR_ID_PICOHEART 0x20fa + #define PCI_VENDOR_ID_HINT 0x3388 #define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013 @@ -2892,6 +2898,7 @@ #define PCI_DEVICE_ID_INTEL_HDA_ICH8 0x284b #define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 #define PCI_DEVICE_ID_INTEL_VMD_28C0 0x28c0 +#define PCI_DEVICE_ID_INTEL_VMD_28C1 0x28c1 #define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910 #define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912 #define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913 diff --git a/include/linux/pcie-dwc.h b/include/linux/pcie-dwc.h index 8ff778e7aec0..097e806c714c 100644 --- a/include/linux/pcie-dwc.h +++ b/include/linux/pcie-dwc.h @@ -11,6 +11,8 @@ #include <linux/pci_ids.h> +#define PCI_VENDOR_ID_LECARC 0x0720 + struct dwc_pcie_vsec_id { u16 vendor_id; u16 vsec_id; @@ -26,12 +28,16 @@ static const struct dwc_pcie_vsec_id dwc_pcie_rasdes_vsec_ids[] = { .vsec_id = 0x02, .vsec_rev = 0x4 }, { .vendor_id = PCI_VENDOR_ID_AMPERE, .vsec_id = 0x02, .vsec_rev = 0x4 }, + { .vendor_id = PCI_VENDOR_ID_PICOHEART, + .vsec_id = 0x02, .vsec_rev = 0x4 }, { .vendor_id = PCI_VENDOR_ID_QCOM, .vsec_id = 0x02, .vsec_rev = 0x4 }, { .vendor_id = PCI_VENDOR_ID_ROCKCHIP, .vsec_id = 0x02, .vsec_rev = 0x4 }, { .vendor_id = PCI_VENDOR_ID_SAMSUNG, .vsec_id = 0x02, .vsec_rev = 0x4 }, + { .vendor_id = PCI_VENDOR_ID_LECARC, + .vsec_id = 0x02, .vsec_rev = 0x4 }, {} }; diff --git a/include/linux/pds/pds_core_if.h b/include/linux/pds/pds_core_if.h index 17a87c1a55d7..901e1e628f89 100644 --- a/include/linux/pds/pds_core_if.h +++ b/include/linux/pds/pds_core_if.h @@ -40,6 +40,14 @@ enum pds_core_cmd_opcode { PDS_CORE_CMD_FW_DOWNLOAD = 4, PDS_CORE_CMD_FW_CONTROL = 5, + PDS_CORE_CMD_GET_COMPONENT_INFO = 6, + PDS_CORE_CMD_SEND_PKG_DATA = 7, + PDS_CORE_CMD_SEND_COMPONENT_TBL = 8, + PDS_CORE_CMD_SEND_COMPONENT = 9, + PDS_CORE_CMD_FINALIZE_UPDATE = 10, + PDS_CORE_CMD_MATCH_RECORD_DESC = 11, + PDS_CORE_CMD_HOST_MEM = 12, + /* SR/IOV commands */ PDS_CORE_CMD_VF_GETATTR = 60, PDS_CORE_CMD_VF_SETATTR = 61, @@ -100,6 +108,16 @@ struct pds_core_drv_identity { char driver_ver_str[32]; }; +/** + * enum pds_core_dev_capability - Device capabilities + * @PDS_CORE_DEV_CAP_PLDM_FW_UPDATE: Device only supports FW update via PLDM + * @PDS_CORE_DEV_CAP_HOST_MEM: Device supports host memory for fw use + */ +enum pds_core_dev_capability { + PDS_CORE_DEV_CAP_PLDM_FW_UPDATE = BIT(0), + PDS_CORE_DEV_CAP_HOST_MEM = BIT(1), +}; + #define PDS_DEV_TYPE_MAX 16 /** * struct pds_core_dev_identity - Device identity information @@ -119,6 +137,11 @@ struct pds_core_drv_identity { * value in usecs to device units using: * device units = usecs * mult / div * @vif_types: How many of each VIF device type is supported + * @max_fw_slots: Number of firmware components reported by device + * only supported on version >= PDS_CORE_IDENTITY_VERSION_2 + * @rsvd2: Word boundary padding + * @capabilities: Device capabilities + * only supported on version >= PDS_CORE_IDENTITY_VERSION_2 */ struct pds_core_dev_identity { u8 version; @@ -131,9 +154,13 @@ struct pds_core_dev_identity { __le32 intr_coal_mult; __le32 intr_coal_div; __le16 vif_types[PDS_DEV_TYPE_MAX]; + __le16 max_fw_slots; + u8 rsvd2[6]; + __le64 capabilities; }; #define PDS_CORE_IDENTITY_VERSION_1 1 +#define PDS_CORE_IDENTITY_VERSION_2 2 /** * struct pds_core_dev_identify_cmd - Driver/device identify command @@ -275,11 +302,20 @@ enum pds_core_fw_control_oper { PDS_CORE_FW_GET_LIST = 7, }; +/** + * enum pds_core_fw_slot - Firmware slot identifiers + * @PDS_CORE_FW_SLOT_INVALID: Let firmware select slot based on package metadata + * @PDS_CORE_FW_SLOT_A: Primary firmware slot A + * @PDS_CORE_FW_SLOT_B: Primary firmware slot B + * @PDS_CORE_FW_SLOT_GOLD: Gold/recovery firmware slot + * @PDS_CORE_FW_SLOT_MAX: Sentinel value indicating no slot resolved + */ enum pds_core_fw_slot { PDS_CORE_FW_SLOT_INVALID = 0, PDS_CORE_FW_SLOT_A = 1, PDS_CORE_FW_SLOT_B = 2, PDS_CORE_FW_SLOT_GOLD = 3, + PDS_CORE_FW_SLOT_MAX = 0xff, }; /** @@ -446,6 +482,423 @@ struct pds_core_vf_ctrl_comp { u8 status; }; +/** + * struct pds_core_send_pkg_data_cmd - Send package data command + * @opcode: Opcode PDS_CORE_CMD_SEND_PKG_DATA + * @ver: Driver's max support version of this command + * @total_len: Total length of the package data + * @offset: Offset in the package data, non-zero if multiple commands are + * needed for sending the package data + * @data_len: Length of data stored at data_pa + * @data_pa: Data physical address for DMA to device + * + * The package data may be too large to store in a single buffer, so multiple + * PDS_CORE_CMD_SEND_PKG_DATA devcmds may be needed. + */ +struct pds_core_send_pkg_data_cmd { + u8 opcode; + u8 ver; + __le16 total_len; + __le16 offset; + __le16 data_len; + __le64 data_pa; +}; + +/** + * struct pds_core_send_pkg_data_comp - Send package data completion + * @status: Status of the command (enum pds_core_status_code) + * @ver: Device's max supported version of this command + * @rsvd: Word boundary padding + */ +struct pds_core_send_pkg_data_comp { + u8 status; + u8 ver; + u8 rsvd[2]; +}; + +/** + * struct pds_core_component_tbl - Component table details + * @comparison_stamp: Comparison stamp used for component version checks + * @classification: Vendor specific classification info + * @identifier: Component's ID + * @transfer_flag: Part of the component table this request represents + * @version_str_type: The types of strings used + * @version_str_len: Length of @version_str + * @version_str: Component version information + */ +struct pds_core_component_tbl { + __le32 comparison_stamp; + __le16 classification; + __le16 identifier; + u8 transfer_flag; + u8 version_str_type; + u8 version_str_len; + u8 version_str[]; +}; + +/** + * struct pds_core_send_component_tbl_cmd - Send component table command + * @opcode: Opcode PDS_CORE_CMD_SEND_COMPONENT_TBL + * @ver: Driver's max support version of this command + * @slot_id: enum pds_core_fw_slot + * @rsvd: Word boundary padding + * + * Expects to find component table info (struct pds_core_component_tbl) + * in cmd_regs->data. Driver should keep the devcmd interface locked + * while preparing the component table info. + */ +struct pds_core_send_component_tbl_cmd { + u8 opcode; + u8 ver; + u8 slot_id; + u8 rsvd; +}; + +enum pds_core_component_resp_code { + PDS_CORE_COMPONENT_VALID = 0x0, + PDS_CORE_COMPONENT_STAMP_IDENTICAL = 0x1, + PDS_CORE_COMPONENT_STAMP_LOWER = 0x2, + PDS_CORE_COMPONENT_STAMP_OR_VERSION_INVALID = 0x3, + PDS_CORE_COMPONENT_CONFLICT = 0x4, + PDS_CORE_COMPONENT_PREREQS_NOT_MET = 0x5, + PDS_CORE_COMPONENT_NOT_SUPPORTED = 0x6, + PDS_CORE_COMPONENT_FW_TYPE_INVALID = 0xd0, +}; + +/** + * struct pds_core_send_component_tbl_comp - Send component table completion + * @status: Status of the command (enum pds_core_status_code) + * @ver: Device's max supported version of this command + * @completion_code: Component completion code + * @response: Component response + * @response_code: Component response code + * @slot_id: Actual slot_id of the component (enum pds_core_fw_slot) + * @rsvd: Word boundary padding + */ +struct pds_core_send_component_tbl_comp { + u8 status; + u8 ver; + u8 completion_code; + u8 response; + u8 response_code; + u8 slot_id; + u8 rsvd[2]; +}; + +/** + * enum pds_core_send_component_op - PDS_CORE_CMD_SEND_COMPONENT operation + * @PDS_CORE_SEND_COMPONENT_START: Initial operation to start transfer + * @PDS_CORE_SEND_COMPONENT_STATUS: Subsequent calls to check on status + */ +enum pds_core_send_component_op { + PDS_CORE_SEND_COMPONENT_START = 0, + PDS_CORE_SEND_COMPONENT_STATUS = 1, +}; + +#define PDS_CORE_FW_COMPONENT_ID_INVALID 0xFFFF +/** + * struct pds_core_flash_component - Component details + * @comparison_stamp: Comparison stamp used for component version checks + * @image_size: Component image size + * @classification: Vendor specific classification info + * @identifier: Component's ID + * @options: Component options + * @rsvd: Word boundary padding + * @version_str_type: The types of strings used + * @version_str_len: Length of @version_str + * @version_str: Component version information + */ +struct pds_core_flash_component { + __le32 comparison_stamp; + __le32 image_size; + __le16 classification; + __le16 identifier; + __le16 options; + u8 rsvd[3]; + u8 version_str_type; + u8 version_str_len; + u8 version_str[]; +}; + +/** + * struct pds_core_send_component_cmd - Send component command + * @opcode: Opcode PDS_CORE_CMD_SEND_COMPONENT + * @ver: Driver's max supported version of this command + * @slot_id: enum pds_core_fw_slot + * @operation: enum pds_core_send_component_op + * @offset: Offset into the component, non-zero if multiple commands + * are needed for a single component + * @data_len: Length of this part of the component stored at @data_pa + * @rsvd: Word boundary padding + * @data_pa: DMA address of the component + * + * A component may be too large to store in a single buffer, so multiple + * PDS_CORE_CMD_SEND_COMPONENT devcmds may be needed. + * + * Expects to find flash component info (struct pds_core_flash_component) + * in cmd_regs->data. Driver should keep the devcmd interface locked + * while preparing and sending the flash component info. + */ +struct pds_core_send_component_cmd { + u8 opcode; + u8 ver; + u8 slot_id; + u8 operation; + __le32 offset; + __le32 data_len; + u8 rsvd[4]; + __le64 data_pa; +}; + +/** + * struct pds_core_send_component_comp - Send component completion + * @status: Status of the command (enum pds_core_status_code) + * @ver: Device's max supported version of this command + * @completion_code: Completion code + * @compat_response: Compatibility response (0 = Component can be updated) + * @compat_response_code: Compatibility response code + * @rsvd: Word boundary padding + */ +struct pds_core_send_component_comp { + u8 status; + u8 ver; + u8 completion_code; + u8 compat_response; + u8 compat_response_code; + u8 rsvd[3]; +}; + +/** + * enum pds_core_fw_component_type - Firmware component type + * @PDS_CORE_FW_TYPE_UNKNOWN: Unknown component type + * @PDS_CORE_FW_TYPE_MAIN: Main firmware + * @PDS_CORE_FW_TYPE_BOOT: Boot loader + * @PDS_CORE_FW_TYPE_CPLD: CPLD firmware + * @PDS_CORE_FW_TYPE_SECURE: Secure firmware + * @PDS_CORE_FW_TYPE_FPGA: FPGA configuration + * @PDS_CORE_FW_TYPE_SUC_MAIN: System Unit Controller firmware + * @PDS_CORE_FW_TYPE_SUC_BOOT: System Unit Controller bootloader + * @PDS_CORE_FW_TYPE_UBOOT: U-Boot bootloader + * + * Gold/recovery variants are identified by slot_id == PDS_CORE_FW_SLOT_GOLD + * and reported with a ".gold" suffix (e.g., fw.gold). + */ +enum pds_core_fw_component_type { + PDS_CORE_FW_TYPE_UNKNOWN = 0, + PDS_CORE_FW_TYPE_MAIN = 1, + PDS_CORE_FW_TYPE_BOOT = 2, + PDS_CORE_FW_TYPE_CPLD = 3, + PDS_CORE_FW_TYPE_SECURE = 4, + PDS_CORE_FW_TYPE_FPGA = 5, + PDS_CORE_FW_TYPE_SUC_MAIN = 6, + PDS_CORE_FW_TYPE_SUC_BOOT = 7, + PDS_CORE_FW_TYPE_UBOOT = 8, +}; + +/** + * enum pds_core_component_info_flags - Component info flags + * @PDS_CORE_FW_COMPONENT_INFO_F_RUNNING: Component is currently running + * @PDS_CORE_FW_COMPONENT_INFO_F_STARTUP: Component version on next FW boot + * @PDS_CORE_FW_COMPONENT_INFO_F_FIXED: Component is fixed and cannot be updated + * @PDS_CORE_FW_COMPONENT_INFO_F_UPDATE_BY_NAME: Component can be updated + * by name + */ +enum pds_core_component_info_flags { + PDS_CORE_FW_COMPONENT_INFO_F_RUNNING = BIT(0), + PDS_CORE_FW_COMPONENT_INFO_F_STARTUP = BIT(1), + PDS_CORE_FW_COMPONENT_INFO_F_FIXED = BIT(2), + PDS_CORE_FW_COMPONENT_INFO_F_UPDATE_BY_NAME = BIT(3), +}; + +/** + * struct pds_core_fw_component_info - GET_COMPONENT_INFO entry + * @name: Component's name + * @component_type: enum pds_core_fw_component_type + * @rsvd: Word boundary padding + * @flags: enum pds_core_component_info_flags + * @identifier: Component's identifier + * @slot_id: Component's slot identifier + * @version: Component's version + */ +struct pds_core_fw_component_info { +#define PDS_CORE_FW_COMPONENT_NAME_BUFLEN 24 + char name[PDS_CORE_FW_COMPONENT_NAME_BUFLEN]; + u8 component_type; + u8 rsvd[3]; + __le16 flags; + u8 identifier; + u8 slot_id; +#define PDS_CORE_FW_COMPONENT_VER_BUFLEN 32 + char version[PDS_CORE_FW_COMPONENT_VER_BUFLEN]; +}; + +#define PDS_CORE_FW_COMPONENT_LIST_LEN ((PDS_PAGE_SIZE - 8) / \ + sizeof(struct pds_core_fw_component_info)) + +/** + * struct pds_core_component_list_info - GET_COMPONENT_INFO completion data + * @num_components: Number of valid components + * @rsvd: Word boundary padding + * @info: List of valid components + */ +struct pds_core_component_list_info { + u8 num_components; + u8 rsvd[7]; + struct pds_core_fw_component_info info[PDS_CORE_FW_COMPONENT_LIST_LEN]; +}; + +/** + * struct pds_core_get_component_info_cmd - GET_COMPONENT_INFO command + * @opcode: PDS_CORE_CMD_GET_COMPONENT_INFO + * @ver: Driver's max supported version of this command + * @data_len: Length of data at data_pa + * @rsvd: Word boundary padding + * @data_pa: DMA address of data + * + * FW populates struct pds_core_component_list_info pointed to by @data_pa + */ +struct pds_core_get_component_info_cmd { + u8 opcode; + u8 ver; + __le16 data_len; + u8 rsvd[4]; + __le64 data_pa; +}; + +/** + * struct pds_core_get_component_info_comp - GET_COMPONENT_INFO completion + * @status: enum pds_core_status_code + * @ver: Device's max supported version of this command + * @rsvd: Word boundary padding + */ +struct pds_core_get_component_info_comp { + u8 status; + u8 ver; + u8 rsvd[2]; +}; + +/** + * struct pds_core_finalize_update_cmd - FINALIZE_UPDATE command + * @opcode: PDS_CORE_CMD_FINALIZE_UPDATE + * @ver: Driver's max support version of this command + * @rsvd: Word boundary padding + * + * Driver sends at the end of updating all components to finalize the update + */ +struct pds_core_finalize_update_cmd { + u8 opcode; + u8 ver; + u8 rsvd[2]; +}; + +/** + * struct pds_core_finalize_update_comp - FINALIZE_UPDATE completion + * @status: enum pds_core_status_code + * @ver: Device's max supported version of this command + * @rsvd: Word boundary padding + */ +struct pds_core_finalize_update_comp { + u8 status; + u8 ver; + u8 rsvd[2]; +}; + +/** + * struct pds_core_match_record_desc_cmd - MATCH_RECORD_DESC command + * @opcode: PDS_CORE_CMD_MATCH_RECORD_DESC + * @ver: Driver's max supported version of this command + * @type: PLDM Descriptor Identifier Type + * @size: Length of the Descriptor Identifier Value + * @rsvd: Word boundary padding + * + * Expects to find the Descriptor Identifier Data in cmd_regs->data. Driver + * should keep the devcmd interface locked while preparing and sending this + * command. + */ +struct pds_core_match_record_desc_cmd { + u8 opcode; + u8 ver; + __le16 type; + __le16 size; + u8 rsvd[2]; +}; + +/** + * struct pds_core_match_record_desc_comp - MATCH_RECORD_DESC completion + * @status: enum pds_core_status_code + * @ver: Device's max supported version of this command + * @match: Whether or not the Record Descriptor matches the device + * @rsvd: Word boundary padding + * + * When status is PDS_RC_SUCCESS, then @match is valid, otherwise it's + * undefined. + */ +struct pds_core_match_record_desc_comp { + u8 status; + u8 ver; + u8 match; + u8 rsvd; +}; + +/** + * enum pds_core_host_mem_oper - HOST_MEM sub-operations + * @PDS_CORE_HOST_MEM_GET_COUNT: Query number of memory requests + * @PDS_CORE_HOST_MEM_QUERY: Query details of a memory request + * @PDS_CORE_HOST_MEM_ADD: Provide allocated memory to firmware + * @PDS_CORE_HOST_MEM_DEL: Notify firmware of memory deallocation + */ +enum pds_core_host_mem_oper { + PDS_CORE_HOST_MEM_GET_COUNT = 0, + PDS_CORE_HOST_MEM_QUERY = 1, + PDS_CORE_HOST_MEM_ADD = 2, + PDS_CORE_HOST_MEM_DEL = 3, +}; + +/** + * struct pds_core_host_mem_cmd - HOST_MEM command + * @opcode: Opcode PDS_CORE_CMD_HOST_MEM + * @oper: Operation (enum pds_core_host_mem_oper) + * @index: Memory request index (GET_COUNT: max_count, QUERY: index) + * @tag: Tag for this memory request (ADD/DEL) + * @reason: Reason for deletion (DEL only) + * @rsvd: Reserved + * @max_contig: Maximum contiguous memory size (GET_COUNT only) + * @size: Size of memory in bytes (ADD only) + * @buf_pa: DMA address of memory (ADD only) + * + * Unified command for all host memory operations. Fields are reused + * across operations to minimize opcode space usage. + */ +struct pds_core_host_mem_cmd { + u8 opcode; + u8 oper; + __le16 index; + __le16 tag; + u8 reason; + u8 rsvd; + __le32 max_contig; + __le32 size; + __le64 buf_pa; +}; + +/** + * struct pds_core_host_mem_comp - HOST_MEM completion + * @status: Status of the command (enum pds_core_status_code) + * @oper: Operation that was performed + * @count: Number of memory requests (GET_COUNT) + * @size: Size of memory request in bytes (QUERY) + * @tag: Tag for this memory request (QUERY/DEL) + * @rsvd: Reserved + */ +struct pds_core_host_mem_comp { + u8 status; + u8 oper; + __le16 count; + __le32 size; + __le16 tag; + u8 rsvd[6]; +}; + /* * union pds_core_dev_cmd - Overlay of core device command structures */ @@ -462,6 +915,14 @@ union pds_core_dev_cmd { struct pds_core_vf_setattr_cmd vf_setattr; struct pds_core_vf_getattr_cmd vf_getattr; struct pds_core_vf_ctrl_cmd vf_ctrl; + + struct pds_core_get_component_info_cmd get_component_info; + struct pds_core_send_pkg_data_cmd send_pkg_data; + struct pds_core_send_component_tbl_cmd send_component_tbl; + struct pds_core_send_component_cmd send_component; + struct pds_core_finalize_update_cmd finalize_update; + struct pds_core_match_record_desc_cmd match_record_desc; + struct pds_core_host_mem_cmd host_mem; }; /* @@ -480,6 +941,14 @@ union pds_core_dev_comp { struct pds_core_vf_setattr_comp vf_setattr; struct pds_core_vf_getattr_comp vf_getattr; struct pds_core_vf_ctrl_comp vf_ctrl; + + struct pds_core_get_component_info_comp get_component_info; + struct pds_core_send_pkg_data_comp send_pkg_data; + struct pds_core_send_component_tbl_comp send_component_tbl; + struct pds_core_send_component_comp send_component; + struct pds_core_finalize_update_comp finalize_update; + struct pds_core_match_record_desc_comp match_record_desc; + struct pds_core_host_mem_comp host_mem; }; /** diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index 43c854a273c3..dbe3267a0a13 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h @@ -65,13 +65,8 @@ * * Archs which need weak percpu definitions should set * CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU when necessary. - * - * To ensure that the generic code observes the above two - * restrictions, if CONFIG_DEBUG_FORCE_WEAK_PER_CPU is set weak - * definition is used for all cases. */ -#if (defined(CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU) && defined(MODULE)) || \ - defined(CONFIG_DEBUG_FORCE_WEAK_PER_CPU) +#if defined(CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU) && defined(MODULE) /* * __pcpu_scope_* dummy variable is used to enforce scope. It * receives the static modifier when it's used in front of @@ -203,7 +198,7 @@ /* * Accessors and operations. */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ /* * __verify_pcpu_ptr() verifies @ptr is a percpu pointer without evaluating @@ -514,5 +509,5 @@ do { \ #define this_cpu_inc_return(pcp) this_cpu_add_return(pcp, 1) #define this_cpu_dec_return(pcp) this_cpu_add_return(pcp, -1) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _LINUX_PERCPU_DEFS_H */ diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h index d73a1c08c3e3..1e3212e2c827 100644 --- a/include/linux/percpu-refcount.h +++ b/include/linux/percpu-refcount.h @@ -12,8 +12,8 @@ * start shutting down you call percpu_ref_kill() _before_ dropping the initial * refcount. * - * The refcount will have a range of 0 to ((1U << 31) - 1), i.e. one bit less - * than an atomic_t - this is because of the way shutdown works, see + * The refcount will have a range of 0 to LONG_MAX, i.e. one bit less + * than an atomic_long_t - this is because of the way shutdown works, see * percpu_ref_kill()/PERCPU_COUNT_BIAS. * * Before you call percpu_ref_kill(), percpu_ref_put() does not check for the @@ -269,6 +269,7 @@ static inline bool percpu_ref_tryget(struct percpu_ref *ref) /** * percpu_ref_tryget_live_rcu - same as percpu_ref_tryget_live() but the * caller is responsible for taking RCU. + * @ref: percpu_ref to try-get * * This function is safe to call as long as @ref is between init and exit. */ diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 52b37f7bdbf9..02d2c7f45b52 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -119,7 +119,7 @@ struct arm_pmu { /* PMUv3 only */ int pmuver; - bool has_smt; + bool avoid_pmccntr; u64 reg_pmmir; u64 reg_brbidr; #define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40 diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 48d851fbd8ea..5842552294c1 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1791,22 +1791,8 @@ static inline int perf_is_paranoid(void) } extern int perf_allow_kernel(void); - -static inline int perf_allow_cpu(void) -{ - if (sysctl_perf_event_paranoid > 0 && !perfmon_capable()) - return -EACCES; - - return security_perf_event_open(PERF_SECURITY_CPU); -} - -static inline int perf_allow_tracepoint(void) -{ - if (sysctl_perf_event_paranoid > -1 && !perfmon_capable()) - return -EPERM; - - return security_perf_event_open(PERF_SECURITY_TRACEPOINT); -} +extern int perf_allow_cpu(void); +extern int perf_allow_tracepoint(void); extern int perf_exclude_event(struct perf_event *event, struct pt_regs *regs); @@ -2023,6 +2009,19 @@ perf_event_pause(struct perf_event *event, bool reset) { return 0; } static inline int perf_exclude_event(struct perf_event *event, struct pt_regs *regs) { return 0; } +static inline int perf_allow_kernel(void) +{ + return perfmon_capable() ? 0 : -EACCES; +} +static inline int perf_allow_cpu(void) +{ + return perfmon_capable() ? 0 : -EACCES; +} +static inline int perf_allow_tracepoint(void) +{ + return perfmon_capable() ? 0 : -EPERM; +} + #endif /* !CONFIG_PERF_EVENTS */ #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL) diff --git a/include/linux/pfn.h b/include/linux/pfn.h index b90ca0b6c331..cfedf0f61bb3 100644 --- a/include/linux/pfn.h +++ b/include/linux/pfn.h @@ -2,7 +2,7 @@ #ifndef _LINUX_PFN_H_ #define _LINUX_PFN_H_ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/types.h> #endif diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 2981e386da7b..8c093c119e5a 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -8,7 +8,7 @@ #define PMD_ORDER (PMD_SHIFT - PAGE_SHIFT) #define PUD_ORDER (PUD_SHIFT - PAGE_SHIFT) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #ifdef CONFIG_MMU #include <linux/mm_types.h> @@ -988,49 +988,30 @@ static inline void update_mmu_tlb(struct vm_area_struct *vma, update_mmu_tlb_range(vma, address, ptep, 1); } -/* - * Some architectures may be able to avoid expensive synchronization - * primitives when modifications are made to PTE's which are already - * not present, or in the process of an address space destruction. - */ -#ifndef __HAVE_ARCH_PTE_CLEAR_NOT_PRESENT_FULL -static inline void pte_clear_not_present_full(struct mm_struct *mm, - unsigned long address, - pte_t *ptep, - int full) -{ - pte_clear(mm, address, ptep); -} -#endif - -#ifndef clear_not_present_full_ptes /** - * clear_not_present_full_ptes - Clear multiple not present PTEs which are - * consecutive in the pgtable. + * clear_nonpresent_ptes - Clear multiple non-present PTEs which are + * consecutive in the pgtable. * @mm: Address space the ptes represent. * @addr: Address of the first pte. * @ptep: Page table pointer for the first entry. * @nr: Number of entries to clear. - * @full: Whether we are clearing a full mm. - * - * May be overridden by the architecture; otherwise, implemented as a simple - * loop over pte_clear_not_present_full(). * * Context: The caller holds the page table lock. The PTEs are all not present. * The PTEs are all in the same PMD. */ -static inline void clear_not_present_full_ptes(struct mm_struct *mm, - unsigned long addr, pte_t *ptep, unsigned int nr, int full) +static inline void clear_nonpresent_ptes(struct mm_struct *mm, + unsigned long addr, pte_t *ptep, unsigned int nr) { + (void)addr; + for (;;) { - pte_clear_not_present_full(mm, addr, ptep, full); + pte_clear(mm, addr, ptep); if (--nr == 0) break; ptep++; addr += PAGE_SIZE; } } -#endif #ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH extern pte_t ptep_clear_flush(struct vm_area_struct *vma, @@ -1858,7 +1839,7 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) #endif #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY -#ifndef CONFIG_ARCH_ENABLE_THP_MIGRATION +#ifndef CONFIG_ARCH_HAS_PMD_SOFTLEAVES static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd) { return pmd; @@ -2129,18 +2110,26 @@ static inline int pud_trans_unstable(pud_t *pud) return 0; } -#ifndef CONFIG_NUMA_BALANCING +#ifndef CONFIG_ARCH_HAS_PTE_PROTNONE /* - * In an inaccessible (PROT_NONE) VMA, pte_protnone() may indicate "yes". It is - * perfectly valid to indicate "no" in that case, which is why our default - * implementation defaults to "always no". + * In an inaccessible (PROT_NONE) VMA, pte_protnone() may indicate "yes". It + * is perfectly valid to indicate "no" in that case, which is why our + * default implementation defaults to "always no". + * + * In an accessible VMA, pte_protnone() reliably indicates a present + * PROT_NONE page protection. Today the kernel uses such PTEs for two + * purposes: NUMA hinting faults, and userfaultfd RWP tracking on + * VM_UFFD_RWP VMAs. The two are distinguished by the uffd PTE bit and + * the VMA flag; see include/linux/userfaultfd_k.h. * - * In an accessible VMA, however, pte_protnone() reliably indicates PROT_NONE - * page protection due to NUMA hinting. NUMA hinting faults only apply in - * accessible VMAs. + * So, to reliably identify PROT_NONE PTEs that require kernel handling, + * looking at the VMA accessibility (and the uffd bit on RWP VMAs) is + * sufficient. * - * So, to reliably identify PROT_NONE PTEs that require a NUMA hinting fault, - * looking at the VMA accessibility is sufficient. + * Architectures without CONFIG_ARCH_HAS_PTE_PROTNONE get the always-zero + * stubs below; PAGE_NONE references that survive to runtime fire the + * BUILD_BUG() fallback, since callers should have folded such paths to + * dead code via IS_ENABLED(CONFIG_ARCH_HAS_PTE_PROTNONE). */ static inline int pte_protnone(pte_t pte) { @@ -2151,7 +2140,11 @@ static inline int pmd_protnone(pmd_t pmd) { return 0; } -#endif /* CONFIG_NUMA_BALANCING */ + +#ifndef PAGE_NONE +#define PAGE_NONE ({ BUILD_BUG(); (pgprot_t){0}; }) +#endif +#endif /* CONFIG_ARCH_HAS_PTE_PROTNONE */ #endif /* CONFIG_MMU */ @@ -2320,7 +2313,7 @@ static inline const char *pgtable_level_to_str(enum pgtable_level level) } } -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #if !defined(MAX_POSSIBLE_PHYSMEM_BITS) && !defined(CONFIG_64BIT) #ifdef CONFIG_PHYS_ADDR_T_64BIT diff --git a/include/linux/phy.h b/include/linux/phy.h index 199a7aaa341b..5f8d65868e0f 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -23,7 +23,7 @@ #include <linux/module.h> #include <linux/timer.h> #include <linux/workqueue.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/mdio.h> #include <linux/u64_stats_sync.h> #include <linux/irqreturn.h> #include <linux/iopoll.h> @@ -2231,6 +2231,11 @@ static inline void phy_device_reset(struct phy_device *phydev, int value) mdio_device_reset(&phydev->mdio, value); } +static inline bool phy_device_has_reset(struct phy_device *phydev) +{ + return mdiodev_has_reset(&phydev->mdio); +} + #define phydev_err(_phydev, format, args...) \ dev_err(&_phydev->mdio.dev, format, ##args) @@ -2297,6 +2302,9 @@ static inline int genphy_no_config_intr(struct phy_device *phydev) { return 0; } +int genphy_read_mmd_c45(struct phy_device *phydev, int devnum, u16 regnum); +int genphy_write_mmd_c45(struct phy_device *phydev, int devnum, u16 regnum, + u16 val); int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, u16 regnum); int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum, @@ -2309,6 +2317,7 @@ int genphy_c37_read_status(struct phy_device *phydev, bool *changed); /* Clause 45 PHY */ int genphy_c45_restart_aneg(struct phy_device *phydev); int genphy_c45_check_and_restart_aneg(struct phy_device *phydev, bool restart); +int genphy_c45_pma_soft_reset(struct phy_device *phydev); int genphy_c45_aneg_done(struct phy_device *phydev); int genphy_c45_read_link(struct phy_device *phydev); int genphy_c45_read_lpa(struct phy_device *phydev); diff --git a/include/linux/phylink.h b/include/linux/phylink.h index 2bc0db3d52ac..1dda5c7ed5f1 100644 --- a/include/linux/phylink.h +++ b/include/linux/phylink.h @@ -791,6 +791,7 @@ static inline int phylink_get_link_timer_ns(phy_interface_t interface) { switch (interface) { case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_PSGMII: case PHY_INTERFACE_MODE_QSGMII: case PHY_INTERFACE_MODE_USXGMII: case PHY_INTERFACE_MODE_10G_QXGMII: diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 7f6a92ac9704..6402930282e5 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -14,6 +14,9 @@ #define PIPE_BUF_FLAG_LOSS 0x40 /* Message loss happened after this buffer */ #endif +#define PIPE_PREALLOC_MAX 8 /* max pages in prealloc pool */ +#define PIPE_PREALLOC_KEEP 2 /* keep at least this many after trim */ + /** * struct pipe_buffer - a linux kernel pipe buffer * @page: the page containing the data for the pipe buffer @@ -59,6 +62,21 @@ union pipe_index { }; /** + * struct anon_pipe_prealloc - per-pipe page preallocation pool + * @pages: array of cached pages (pool) + * @count: number of pages currently in the pool + * + * Each pipe keeps a small bounded pool of preallocated pages to reduce + * allocation overhead during writes. The pool is bounded at PIPE_PREALLOC_MAX + * and trimmed down to PIPE_PREALLOC_KEEP after a write completes. + */ +struct anon_pipe_prealloc { + struct page *pages[PIPE_PREALLOC_MAX]; + + unsigned int __data_racy count; +}; + +/** * struct pipe_inode_info - a linux kernel pipe * @mutex: mutex protecting the whole thing * @rd_wait: reader wait point in case of empty pipe @@ -68,13 +86,13 @@ union pipe_index { * @max_usage: The maximum number of slots that may be used in the ring * @ring_size: total number of buffers (should be a power of 2) * @nr_accounted: The amount this pipe accounts for in user->pipe_bufs - * @tmp_page: cached released page + * @prealloc: per-pipe page preallocation pool * @readers: number of current readers of this pipe * @writers: number of current writers of this pipe * @files: number of struct file referring this pipe (protected by ->i_lock) * @r_counter: reader counter * @w_counter: writer counter - * @poll_usage: is this pipe used for epoll, which has crazy wakeups? + * @pseudo_edgetrigger: has an EPOLLET consumer, enable per-write wakeups * @fasync_readers: reader side fasync * @fasync_writers: writer side fasync * @bufs: the circular array of pipe buffers @@ -95,11 +113,11 @@ struct pipe_inode_info { unsigned int files; unsigned int r_counter; unsigned int w_counter; - bool poll_usage; + bool pseudo_edgetrigger; #ifdef CONFIG_WATCH_QUEUE bool note_loss; #endif - struct page *tmp_page[2]; + struct anon_pipe_prealloc prealloc; struct fasync_struct *fasync_readers; struct fasync_struct *fasync_writers; struct pipe_buffer *bufs; diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h index 6ed1c4c5ce2e..a1ccecf5e1f8 100644 --- a/include/linux/platform_data/cros_ec_proto.h +++ b/include/linux/platform_data/cros_ec_proto.h @@ -271,6 +271,8 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); +int cros_ec_read_features(struct cros_ec_dev *ec); + bool cros_ec_check_features(struct cros_ec_dev *ec, int feature); int cros_ec_get_sensor_count(struct cros_ec_dev *ec); diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h index 8c2f1f185353..2ddb624b97fd 100644 --- a/include/linux/platform_data/mtd-nand-omap2.h +++ b/include/linux/platform_data/mtd-nand-omap2.h @@ -7,7 +7,6 @@ #define _MTD_NAND_OMAP2_H #include <linux/mtd/partitions.h> -#include <linux/mod_devicetable.h> #define GPMC_BCH_NUM_REMAINDER 8 @@ -63,10 +62,4 @@ struct gpmc_nand_regs { void __iomem *gpmc_bch_result6[GPMC_BCH_NUM_REMAINDER]; }; -static const struct of_device_id omap_nand_ids[] = { - { .compatible = "ti,omap2-nand", }, - { .compatible = "ti,am64-nand", }, - {}, -}; - #endif /* _MTD_NAND_OMAP2_H */ diff --git a/include/linux/platform_data/omap-twl4030.h b/include/linux/platform_data/omap-twl4030.h deleted file mode 100644 index 7fcb55fe21c9..000000000000 --- a/include/linux/platform_data/omap-twl4030.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/** - * omap-twl4030.h - ASoC machine driver for TI SoC based boards with twl4030 - * codec, header. - * - * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com - * All rights reserved. - * - * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> - */ - -#ifndef _OMAP_TWL4030_H_ -#define _OMAP_TWL4030_H_ - -/* To select if only one channel is connected in a stereo port */ -#define OMAP_TWL4030_LEFT (1 << 0) -#define OMAP_TWL4030_RIGHT (1 << 1) - -struct omap_tw4030_pdata { - const char *card_name; - /* Voice port is connected to McBSP3 */ - bool voice_connected; - - /* The driver will parse the connection flags if this flag is set */ - bool custom_routing; - /* Flags to indicate connected audio ports. */ - u8 has_hs; - u8 has_hf; - u8 has_predriv; - u8 has_carkit; - bool has_ear; - - bool has_mainmic; - bool has_submic; - bool has_hsmic; - bool has_carkitmic; - bool has_digimic0; - bool has_digimic1; - u8 has_linein; -}; - -#endif /* _OMAP_TWL4030_H_ */ diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h index c29962d5baac..b5ed8c83ace1 100644 --- a/include/linux/platform_data/x86/asus-wmi.h +++ b/include/linux/platform_data/x86/asus-wmi.h @@ -203,6 +203,7 @@ int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval); int asus_hid_register_listener(struct asus_hid_listener *cdev); void asus_hid_unregister_listener(struct asus_hid_listener *cdev); int asus_hid_event(enum asus_hid_event event); +bool asus_wmi_custom_fan_curve_is_enabled(void); #else static inline void set_ally_mcu_hack(enum asus_ally_mcu_hack status) { @@ -234,6 +235,10 @@ static inline int asus_hid_event(enum asus_hid_event event) { return -ENODEV; } +static inline bool asus_wmi_custom_fan_curve_is_enabled(void) +{ + return false; +} #endif #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */ diff --git a/include/linux/platform_data/x86/int3472.h b/include/linux/platform_data/x86/int3472.h index 93f1e1fe09b4..a73841dfae27 100644 --- a/include/linux/platform_data/x86/int3472.h +++ b/include/linux/platform_data/x86/int3472.h @@ -13,6 +13,7 @@ #include <linux/leds.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> +#include <linux/device-id/dmi.h> #include <linux/types.h> /* FIXME drop this once the I2C_DEV_NAME_FORMAT macro has been added to include/linux/i2c.h */ @@ -72,7 +73,6 @@ container_of(clk, struct int3472_discrete_device, clock) struct acpi_device; -struct dmi_system_id; struct i2c_client; struct platform_device; diff --git a/include/linux/platform_data/x86/soc.h b/include/linux/platform_data/x86/soc.h index f981907a5cb0..a6a6b313dfa7 100644 --- a/include/linux/platform_data/x86/soc.h +++ b/include/linux/platform_data/x86/soc.h @@ -12,7 +12,7 @@ #if IS_ENABLED(CONFIG_X86) -#include <linux/mod_devicetable.h> +#include <linux/device-id/x86_cpu.h> #include <asm/cpu_device_id.h> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 26e6a43358e2..3d5bbcbae730 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -11,6 +11,7 @@ #define _PLATFORM_DEVICE_H_ #include <linux/device.h> +#include <linux/device-id/platform.h> #define PLATFORM_DEVID_NONE (-1) #define PLATFORM_DEVID_AUTO (-2) @@ -18,7 +19,8 @@ struct irq_affinity; struct mfd_cell; struct property_entry; -struct platform_device_id; +struct device_node; +struct fwnode_handle; struct platform_device { const char *name; @@ -262,6 +264,12 @@ extern int platform_device_add_resources(struct platform_device *pdev, unsigned int num); extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size); +void platform_device_set_of_node(struct platform_device *pdev, + struct device_node *np); +void platform_device_set_fwnode(struct platform_device *pdev, + struct fwnode_handle *fwnode); +void platform_device_set_of_node_from_dev(struct platform_device *pdev, + const struct device *dev2); extern int platform_device_add(struct platform_device *pdev); extern void platform_device_del(struct platform_device *pdev); extern void platform_device_put(struct platform_device *pdev); diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 23fe3eaf242d..e0c0d17eb7d8 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -12,7 +12,7 @@ #include <linux/device.h> #include <linux/list.h> #include <linux/errno.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/pnp.h> #include <linux/console.h> #define PNP_NAME_LEN 50 diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 4d3dbcef379e..9a1a0c61361c 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -37,7 +37,7 @@ static inline int clockid_to_fd(const clockid_t clk) return ~(clk >> 3); } -static inline bool clockid_aux_valid(clockid_t id) +static inline bool clockid_is_aux_clock(clockid_t id) { return IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS) && id >= CLOCK_AUX && id <= CLOCK_AUX_LAST; } @@ -47,7 +47,7 @@ static inline bool clockid_aux_valid(clockid_t id) #include <linux/signal_types.h> /** - * cpu_timer - Posix CPU timer representation for k_itimer + * struct cpu_timer - Posix CPU timer representation for k_itimer * @node: timerqueue node to queue in the task/sig * @head: timerqueue head on which this timer is queued * @pid: Pointer to target task PID @@ -174,6 +174,7 @@ static inline void posix_cputimers_init_work(void) { } * @it_sigqueue_seq: The sequence count at the point where the signal was queued * @it_sigev_notify: The notify word of sigevent struct for signal delivery * @it_interval: The interval for periodic timers + * @it_pid_type: The type of the PID * @it_signal: Pointer to the creators signal struct * @it_pid: The pid of the process/task targeted by the signal * @it_process: The task to wakeup on clock_nanosleep (CPU timers) diff --git a/include/linux/posix-timers_types.h b/include/linux/posix-timers_types.h index a4712c1008c9..b40cf352e01d 100644 --- a/include/linux/posix-timers_types.h +++ b/include/linux/posix-timers_types.h @@ -34,7 +34,7 @@ #ifdef CONFIG_POSIX_TIMERS /** - * posix_cputimer_base - Container per posix CPU clock + * struct posix_cputimer_base - Container per posix CPU clock * @nextevt: Earliest-expiration cache * @tqhead: timerqueue head for cpu_timers */ @@ -44,7 +44,7 @@ struct posix_cputimer_base { }; /** - * posix_cputimers - Container for posix CPU timer related data + * struct posix_cputimers - Container for posix CPU timer related data * @bases: Base container for posix CPU clocks * @timers_active: Timers are queued. * @expiry_active: Timer expiry is active. Used for @@ -60,7 +60,7 @@ struct posix_cputimers { }; /** - * posix_cputimers_work - Container for task work based posix CPU timer expiry + * struct posix_cputimers_work - Container for task work based posix CPU timer expiry * @work: The task work to be scheduled * @mutex: Mutex held around expiry in context of this task work * @scheduled: @work has been scheduled already, no further processing diff --git a/include/linux/power/max17042_battery.h b/include/linux/power/max17042_battery.h index 13aeab1597c6..810e068eafd2 100644 --- a/include/linux/power/max17042_battery.h +++ b/include/linux/power/max17042_battery.h @@ -25,6 +25,7 @@ #define MAX17042_CHARACTERIZATION_DATA_SIZE 48 #define MAX17055_MODELCFG_REFRESH_BIT BIT(15) +#define MAX17055_MODELCFG_VCHG_BIT BIT(10) enum max17042_register { MAX17042_STATUS = 0x00, @@ -124,6 +125,7 @@ enum max17055_register { MAX17055_ConvgCfg = 0x49, MAX17055_VFRemCap = 0x4A, + MAX17055_SoftWakeup = 0x60, MAX17055_STATUS2 = 0xB0, MAX17055_POWER = 0xB1, diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 7a5e4c3242a0..e749d2189335 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -83,6 +83,10 @@ enum { POWER_SUPPLY_TECHNOLOGY_LiFe, POWER_SUPPLY_TECHNOLOGY_NiCd, POWER_SUPPLY_TECHNOLOGY_LiMn, + POWER_SUPPLY_TECHNOLOGY_PbAc, + POWER_SUPPLY_TECHNOLOGY_NiZn, + POWER_SUPPLY_TECHNOLOGY_RAM, + POWER_SUPPLY_TECHNOLOGY_ZnAr, }; enum { @@ -281,6 +285,15 @@ struct power_supply_desc { int (*property_is_writeable)(struct power_supply *psy, enum power_supply_property psp); void (*external_power_changed)(struct power_supply *psy); + /* + * Optional registration-time initialization. This runs in sleepable + * process context after driver data and any battery info are available, + * but before the device is added. The callback must not publish changes or + * start asynchronous activity that can access the power supply before + * registration completes. Return 0 on success or a negative errno on + * failure. + */ + int (*init)(struct power_supply *psy); /* * Set if thermal zone should not be created for this power supply. @@ -346,7 +359,8 @@ struct power_supply { #endif #ifdef CONFIG_LEDS_TRIGGERS - struct led_trigger *trig; + struct led_trigger *charging_or_full_trig; + struct led_trigger *online_trig; struct led_trigger *charging_trig; struct led_trigger *full_trig; struct led_trigger *charging_blink_full_solid_trig; @@ -802,15 +816,33 @@ struct power_supply_battery_info { int bti_resistance_tolerance; }; +#if IS_ENABLED(CONFIG_POWER_SUPPLY) extern int power_supply_reg_notifier(struct notifier_block *nb); extern void power_supply_unreg_notifier(struct notifier_block *nb); -#if IS_ENABLED(CONFIG_POWER_SUPPLY) extern struct power_supply *power_supply_get_by_name(const char *name); +extern int __must_check power_supply_get_system_batteries(struct device *dev, + struct power_supply ***psys); +extern void power_supply_put_system_batteries(struct power_supply **psys, int count); extern void power_supply_put(struct power_supply *psy); #else +static inline int power_supply_reg_notifier(struct notifier_block *nb) +{ return -EOPNOTSUPP; } +static inline void power_supply_unreg_notifier(struct notifier_block *nb) {} static inline void power_supply_put(struct power_supply *psy) {} static inline struct power_supply *power_supply_get_by_name(const char *name) { return NULL; } +static inline int __must_check power_supply_get_system_batteries(struct device *dev, + struct power_supply ***psys) +{ + if (psys) + *psys = NULL; + return 0; +} + +static inline void power_supply_put_system_batteries(struct power_supply **psys, + int count) +{ +} #endif extern struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode, const char *property); diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h index 9f088c9023b1..00b840970d56 100644 --- a/include/linux/pps_kernel.h +++ b/include/linux/pps_kernel.h @@ -60,6 +60,7 @@ struct pps_device { struct device dev; struct fasync_struct *async_queue; /* fasync method */ spinlock_t lock; + bool kc_removed; }; /* diff --git a/include/linux/preempt.h b/include/linux/preempt.h index d964f965c8ff..8299657f0f86 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -17,6 +17,9 @@ * * - bits 0-7 are the preemption count (max preemption depth: 256) * - bits 8-15 are the softirq count (max # of softirqs: 256) + * - bits 16-23 are the hardirq disable count (max # of hardirq disable: 256) + * - bits 24-27 are the hardirq count (max # of hardirqs: 16) + * - bit 28 is the NMI flag (no nesting count, tracked separately) * * The hardirq count could in theory be the same as the number of * interrupts in the system, but we run all interrupt handlers with @@ -24,31 +27,56 @@ * there are a few palaeontologic drivers which reenable interrupts in * the handler, so we need more than one bit here. * + * NMI nesting depth is tracked in a separate per-CPU variable + * (nmi_nesting) to save bits in preempt_count. + * * PREEMPT_MASK: 0x000000ff * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x000f0000 - * NMI_MASK: 0x00f00000 + * HARDIRQ_DISABLE_MASK: 0x00ff0000 + * HARDIRQ_MASK: 0x0f000000 + * + * When HAS_SEPARATE_PREEMPT_RESCHED_BITS=y, PREEMPT_NEED_RESCHED is put in a + * separate word and that allows 64bit load-store architectures to 'set' + * PREEMPT_NEED_RESCHED without messing up the otherwise symmetric + * modifications used on preempt_count and still load the whole thing + * (single-copy) atomically, without having to resort to full atomic + * operations. + * + * Because of the above, NMI_MASK bits are different depending on + * HAS_SEPARATE_PREEMPT_RESCHED_BITS: + * + * - HAS_SEPARATE_PREEMPT_RESCHED_BITS=n: + * + * NMI_MASK: 0x10000000 * PREEMPT_NEED_RESCHED: 0x80000000 + * + * - HAS_SEPARATE_PREEMPT_RESCHED_BITS=y: + * NMI_MASK: 0xf0000000 + * (PREEMPT_NEED_RESCHED is in a different word) */ #define PREEMPT_BITS 8 #define SOFTIRQ_BITS 8 +#define HARDIRQ_DISABLE_BITS 8 #define HARDIRQ_BITS 4 -#define NMI_BITS 4 +#define NMI_BITS (1 + 3*IS_ENABLED(CONFIG_HAS_SEPARATE_PREEMPT_RESCHED_BITS)) #define PREEMPT_SHIFT 0 #define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) +#define HARDIRQ_DISABLE_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) +#define HARDIRQ_SHIFT (HARDIRQ_DISABLE_SHIFT + HARDIRQ_DISABLE_BITS) #define NMI_SHIFT (HARDIRQ_SHIFT + HARDIRQ_BITS) #define __IRQ_MASK(x) ((1UL << (x))-1) #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) #define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) +#define HARDIRQ_DISABLE_MASK (__IRQ_MASK(HARDIRQ_DISABLE_BITS) << HARDIRQ_DISABLE_SHIFT) #define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) #define NMI_MASK (__IRQ_MASK(NMI_BITS) << NMI_SHIFT) #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_DISABLE_OFFSET (1UL << HARDIRQ_DISABLE_SHIFT) #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) #define NMI_OFFSET (1UL << NMI_SHIFT) @@ -105,8 +133,8 @@ static __always_inline unsigned char interrupt_context_level(void) * preempt_count() is commonly implemented with READ_ONCE(). */ -#define nmi_count() (preempt_count() & NMI_MASK) -#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define nmi_count() (preempt_count() & NMI_MASK) +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) #ifdef CONFIG_PREEMPT_RT # define softirq_count() (current->softirq_disable_cnt & SOFTIRQ_MASK) # define irq_count() ((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) | softirq_count()) @@ -140,6 +168,10 @@ static __always_inline unsigned char interrupt_context_level(void) #define in_softirq() (softirq_count()) #define in_interrupt() (irq_count()) +#define hardirq_disable_count() ((preempt_count() & HARDIRQ_DISABLE_MASK) >> HARDIRQ_DISABLE_SHIFT) +#define hardirq_disable_enter() __preempt_count_add_return(HARDIRQ_DISABLE_OFFSET) +#define hardirq_disable_exit() __preempt_count_sub_return(HARDIRQ_DISABLE_OFFSET) + /* * The preempt_count offset after preempt_disable(); */ diff --git a/include/linux/property.h b/include/linux/property.h index 14c304db4664..907c790a3f01 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -397,11 +397,13 @@ struct property_entry { union { const void *pointer; union { + /* private: internal representation of @value */ u8 u8_data[sizeof(u64) / sizeof(u8)]; u16 u16_data[sizeof(u64) / sizeof(u16)]; u32 u32_data[sizeof(u64) / sizeof(u32)]; u64 u64_data[sizeof(u64) / sizeof(u64)]; const char *str[sizeof(u64) / sizeof(char *)]; + /* public: */ } value; }; }; diff --git a/include/linux/psi.h b/include/linux/psi.h index e0745873e3f2..7966e3ac03b9 100644 --- a/include/linux/psi.h +++ b/include/linux/psi.h @@ -25,7 +25,9 @@ void psi_memstall_leave(unsigned long *flags); int psi_show(struct seq_file *s, struct psi_group *group, enum psi_res res); struct psi_trigger *psi_trigger_create(struct psi_group *group, char *buf, enum psi_res res, struct file *file, - struct kernfs_open_file *of); + struct kernfs_open_file *of, + bool *need_rtpoll_worker); +int psi_trigger_create_rtpoll_worker(struct psi_group *group); void psi_trigger_destroy(struct psi_trigger *t); __poll_t psi_trigger_poll(void **trigger_ptr, struct file *file, diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h index ce16bbc0b308..03a79786df1d 100644 --- a/include/linux/psp-sev.h +++ b/include/linux/psp-sev.h @@ -129,6 +129,7 @@ enum sev_cmd { SEV_CMD_SNP_LAUNCH_FINISH = 0x0A2, SEV_CMD_SNP_DBG_DECRYPT = 0x0B0, SEV_CMD_SNP_DBG_ENCRYPT = 0x0B1, + SEV_CMD_SNP_VERIFY_MITIGATION = 0x0B2, SEV_CMD_SNP_PAGE_SWAP_OUT = 0x0C0, SEV_CMD_SNP_PAGE_SWAP_IN = 0x0C1, SEV_CMD_SNP_PAGE_MOVE = 0x0C2, @@ -898,10 +899,60 @@ struct snp_feature_info { #define SNP_CIPHER_TEXT_HIDING_SUPPORTED BIT(3) #define SNP_AES_256_XTS_POLICY_SUPPORTED BIT(4) #define SNP_CXL_ALLOW_POLICY_SUPPORTED BIT(5) +#define SNP_VERIFY_MITIGATION_SUPPORTED BIT(13) /* Feature bits in EBX */ #define SNP_SEV_TIO_SUPPORTED BIT(1) +#define SNP_MIT_SUBCMD_REQ_STATUS 0x0 +#define SNP_MIT_SUBCMD_REQ_VERIFY 0x1 + +/** + * struct sev_data_snp_verify_mitigation - SNP_VERIFY_MITIGATION command params + * + * @length: Length of the command buffer read by the PSP + * @subcommand: Mitigation sub-command for the firmware to execute. + * REQ_STATUS: 0x0 - Request status about currently supported and + * verified mitigations + * REQ_VERIFY: 0x1 - Request to initiate verification mitigation + * operation on a specific mitigation + * @rsvd: Reserved + * @vector: Bit specifying the vulnerability mitigation to process + * @dst_paddr_en: Destination paddr enabled + * @src_paddr_en: Source paddr enabled + * @rsvd1: Reserved + * @rsvd2: Reserved + * @src_paddr: Source address for optional input data + * @dst_paddr: Destination address to write the result + * @rsvd3: Reserved + */ +struct sev_data_snp_verify_mitigation { + u32 length; + u16 subcommand; + u16 rsvd; + u64 vector; + u32 dst_paddr_en : 1, + src_paddr_en : 1, + rsvd1 : 30; + u8 rsvd2[4]; + u64 src_paddr; + u64 dst_paddr; + u8 rsvd3[24]; +} __packed; + +/** + * struct sev_data_snp_verify_mitigation_dst - mitigation result vectors + * + * @mit_verified_vector: Bit vector of vulnerability mitigations verified + * @mit_supported_vector: Bit vector of vulnerability mitigations supported + * @mit_failure_status: Status of the verification operation + */ +struct sev_data_snp_verify_mitigation_dst { + u64 mit_verified_vector; /* OUT */ + u64 mit_supported_vector; /* OUT */ + u32 mit_failure_status; /* OUT */ +} __packed; + /** * struct sev_snp_tcb_version_genoa_milan * diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h index c95e891903f0..631c43fde440 100644 --- a/include/linux/ptr_ring.h +++ b/include/linux/ptr_ring.h @@ -96,7 +96,13 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r) return ret; } -/* Note: callers invoking this in a loop must use a compiler barrier, +/* Report whether the next __ptr_ring_produce() has room for one entry: + * 0 means the single slot at r->queue[r->producer] is free, -ENOSPC means + * the ring is full, which is transient, and -EINVAL means r->size is 0, + * which is permanent. A caller that stops producing and waits for space + * must therefore do so only for -ENOSPC. + * + * 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) @@ -117,10 +123,10 @@ static inline int __ptr_ring_check_produce(struct ptr_ring *r) */ static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr) { - int p = __ptr_ring_check_produce(r); + int ret = __ptr_ring_check_produce(r); - if (p) - return p; + if (ret) + return ret; /* 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/ptrace.h b/include/linux/ptrace.h index ef314f7a9ecc..2839d5c8eaa0 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -405,13 +405,13 @@ extern void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oa /* * ptrace report for syscall entry and exit looks identical. */ -static inline int ptrace_report_syscall(unsigned long message) +static inline bool ptrace_report_syscall(unsigned long message) { int ptrace = current->ptrace; int signr; if (!(ptrace & PT_PTRACED)) - return 0; + return true; signr = ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0), message); @@ -424,11 +424,11 @@ static inline int ptrace_report_syscall(unsigned long message) if (signr) send_sig(signr, current, 1); - return fatal_signal_pending(current); + return !fatal_signal_pending(current); } /** - * ptrace_report_syscall_entry - task is about to attempt a system call + * ptrace_report_syscall_permit_entry - task is about to attempt a system call * @regs: user register state of current task * * This will be called if %SYSCALL_WORK_SYSCALL_TRACE or @@ -438,7 +438,7 @@ static inline int ptrace_report_syscall(unsigned long message) * call number and arguments to be tried. It is safe to block here, * preventing the system call from beginning. * - * Returns zero normally, or nonzero if the calling arch code should abort + * Returns True normally, or False if the calling architecture code should abort * the system call. That must prevent normal entry so no system call is * made. If @task ever returns to user mode after this, its register state * is unspecified, but should be something harmless like an %ENOSYS error @@ -447,8 +447,7 @@ static inline int ptrace_report_syscall(unsigned long message) * * Called without locks, just after entering kernel mode. */ -static inline __must_check int ptrace_report_syscall_entry( - struct pt_regs *regs) +static inline __must_check bool ptrace_report_syscall_permit_entry(struct pt_regs *regs) { return ptrace_report_syscall(PTRACE_EVENTMSG_SYSCALL_ENTRY); } diff --git a/include/linux/pwrseq/consumer.h b/include/linux/pwrseq/consumer.h index 3c907c9e1885..16fad5f3e3ab 100644 --- a/include/linux/pwrseq/consumer.h +++ b/include/linux/pwrseq/consumer.h @@ -20,8 +20,8 @@ void pwrseq_put(struct pwrseq_desc *desc); struct pwrseq_desc * __must_check devm_pwrseq_get(struct device *dev, const char *target); -int pwrseq_power_on(struct pwrseq_desc *desc); -int pwrseq_power_off(struct pwrseq_desc *desc); +int pwrseq_enable(struct pwrseq_desc *desc); +int pwrseq_disable(struct pwrseq_desc *desc); struct device *pwrseq_to_device(struct pwrseq_desc *desc); @@ -43,12 +43,12 @@ devm_pwrseq_get(struct device *dev, const char *target) return ERR_PTR(-ENOSYS); } -static inline int pwrseq_power_on(struct pwrseq_desc *desc) +static inline int pwrseq_enable(struct pwrseq_desc *desc) { return -ENOSYS; } -static inline int pwrseq_power_off(struct pwrseq_desc *desc) +static inline int pwrseq_disable(struct pwrseq_desc *desc) { return -ENOSYS; } diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index eae67015ce51..057edc4cbb6e 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -111,7 +111,7 @@ struct radix_tree_iter { }; /** - * Radix-tree synchronization + * DOC: Radix-tree synchronization * * The radix-tree API requires that users provide all synchronisation (with * specific exceptions, noted below). @@ -182,6 +182,7 @@ static inline void *radix_tree_deref_slot(void __rcu **slot) /** * radix_tree_deref_slot_protected - dereference a slot with tree lock held * @slot: slot pointer, returned by radix_tree_lookup_slot + * @treelock: caller must hold this spinlock * * Similar to radix_tree_deref_slot. The caller does not hold the RCU read * lock but it must hold the tree lock to prevent parallel updates. @@ -306,7 +307,7 @@ radix_tree_iter_init(struct radix_tree_iter *iter, unsigned long start) * Also it fills @iter with data about chunk: position in the tree (index), * its end (next_index), and constructs a bit mask for tagged iterating (tags). */ -void __rcu **radix_tree_next_chunk(const struct radix_tree_root *, +void __rcu **radix_tree_next_chunk(const struct radix_tree_root *root, struct radix_tree_iter *iter, unsigned flags); /** diff --git a/include/linux/randomize_kstack.h b/include/linux/randomize_kstack.h index 024fc20e7762..d8b939f50bba 100644 --- a/include/linux/randomize_kstack.h +++ b/include/linux/randomize_kstack.h @@ -77,8 +77,27 @@ static __always_inline u32 get_kstack_offset(void) } \ } while (0) +/** + * add_random_kstack_offset_irqsoff - Increase stack utilization by a random offset. + * + * This should be used in the syscall entry path after user registers have been + * stored to the stack. Interrupts must be still disabled. + */ +#define add_random_kstack_offset_irqsoff() \ +do { \ + lockdep_assert_irqs_disabled(); \ + if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, \ + &randomize_kstack_offset)) { \ + u32 offset = prandom_u32_state(raw_cpu_ptr(&kstack_rnd_state)); \ + u8 *ptr = __kstack_alloca(KSTACK_OFFSET_MAX(offset)); \ + /* Keep allocation even after "ptr" loses scope. */ \ + asm volatile("" :: "r"(ptr) : "memory"); \ + } \ +} while (0) + #else /* CONFIG_RANDOMIZE_KSTACK_OFFSET */ #define add_random_kstack_offset() do { } while (0) +#define add_random_kstack_offset_irqsoff() do { } while (0) #endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */ #endif diff --git a/include/linux/raspberrypi/vchiq_bus.h b/include/linux/raspberrypi/vchiq_bus.h index 9de179b39f85..e52291a3b247 100644 --- a/include/linux/raspberrypi/vchiq_bus.h +++ b/include/linux/raspberrypi/vchiq_bus.h @@ -7,7 +7,7 @@ #define _VCHIQ_DEVICE_H #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/vchiq.h> struct vchiq_drv_mgmt; diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index 48acdc3889dd..b7078b0e1eb2 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h @@ -500,7 +500,7 @@ rb_find_first(const void *key, const struct rb_root *tree, /** * rb_next_match() - find the next @key in @tree * @key: key to match - * @tree: tree to search + * @node: tree to search * @cmp: operator defining node order * * Returns the next node matching @key, or NULL. diff --git a/include/linux/rbtree_latch.h b/include/linux/rbtree_latch.h index 2f630eb8307e..b55a3a01bc8a 100644 --- a/include/linux/rbtree_latch.h +++ b/include/linux/rbtree_latch.h @@ -47,7 +47,7 @@ struct latch_tree_root { }; /** - * latch_tree_ops - operators to define the tree order + * struct latch_tree_ops - operators to define the tree order * @less: used for insertion; provides the (partial) order between two elements. * @comp: used for lookups; provides the order between the search key and an element. * diff --git a/include/linux/rcu_segcblist.h b/include/linux/rcu_segcblist.h index 2fdc2208f1ca..08b63ecf719b 100644 --- a/include/linux/rcu_segcblist.h +++ b/include/linux/rcu_segcblist.h @@ -50,12 +50,14 @@ struct rcu_cblist { * Note that RCU_WAIT_TAIL cannot be empty unless RCU_NEXT_READY_TAIL is also * empty. * - * The ->gp_seq[] array contains the grace-period number at which the - * corresponding segment of callbacks will be ready to invoke. A given - * element of this array is meaningful only when the corresponding segment - * is non-empty, and it is never valid for RCU_DONE_TAIL (whose callbacks - * are already ready to invoke) or for RCU_NEXT_TAIL (whose callbacks have - * not yet been assigned a grace-period number). + * The ->gp_seq[] array contains the grace-period state at which the + * corresponding segment of callbacks will be ready to invoke. This tracks + * both normal and expedited grace periods, allowing callbacks to complete + * when either type of GP finishes. A given element of this array is + * meaningful only when the corresponding segment is non-empty, and it is + * never valid for RCU_DONE_TAIL (whose callbacks are already ready to + * invoke) or for RCU_NEXT_TAIL (whose callbacks have not yet been assigned + * a grace-period state). */ #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ #define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */ @@ -190,7 +192,7 @@ struct rcu_cblist { struct rcu_segcblist { struct rcu_head *head; struct rcu_head **tails[RCU_CBLIST_NSEGS]; - unsigned long gp_seq[RCU_CBLIST_NSEGS]; + struct rcu_gp_seq gp_seq[RCU_CBLIST_NSEGS]; #ifdef CONFIG_RCU_NOCB_CPU atomic_long_t len; #else diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 5e95acc33989..44c07a66edff 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -52,9 +52,18 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func); void rcu_barrier_tasks(void); void synchronize_rcu(void); -struct rcu_gp_oldstate; +/* + * Grace-period sequence snapshot for the polled RCU APIs: ->norm for the + * normal grace period and ->exp for the expedited one. ->exp is unused by + * Tiny RCU, but is present unconditionally so that a single definition + * serves both Tiny RCU and Tree RCU. + */ +struct rcu_gp_seq { + unsigned long norm; + unsigned long exp; +}; unsigned long get_completed_synchronize_rcu(void); -void get_completed_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp); +void get_completed_synchronize_rcu_full(struct rcu_gp_seq *gsp); // Maximum number of unsigned long values corresponding to // not-yet-completed RCU grace periods. @@ -208,15 +217,15 @@ static inline void exit_tasks_rcu_finish(void) { } /** * cond_resched_tasks_rcu_qs - Report potential quiescent states to RCU * - * This macro resembles cond_resched(), except that it is defined to + * This function resembles cond_resched(), except that it is defined to * report potential quiescent states to RCU-tasks even if the cond_resched() * machinery were to be shut off, as some advocate for PREEMPTION kernels. */ -#define cond_resched_tasks_rcu_qs() \ -do { \ - rcu_tasks_qs(current, false); \ - cond_resched(); \ -} while (0) +static inline void cond_resched_tasks_rcu_qs(void) +{ + rcu_tasks_qs(current, false); + cond_resched(); +} /** * rcu_softirq_qs_periodic - Report RCU and RCU-Tasks quiescent states @@ -490,12 +499,12 @@ context_unsafe( \ */ #define unrcu_pointer(p) __unrcu_pointer(p, __UNIQUE_ID(rcu)) -#define __rcu_access_pointer(p, local, space) \ +#define __rcu_access_pointer(p, local, space) context_unsafe( \ ({ \ typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \ rcu_check_sparse(p, space); \ ((typeof(*p) __force __kernel *)(local)); \ -}) +}) ) #define __rcu_dereference_check(p, local, c, space) \ ({ \ /* Dependency order vs. p above. */ \ @@ -1098,19 +1107,22 @@ static inline void rcu_read_unlock_migrate(void) /* * In mm/slab_common.c, no suitable header to include here. */ -void kvfree_call_rcu(struct rcu_head *head, void *ptr); +void kvfree_call_rcu(struct kvfree_rcu_head *head, void *ptr); +void kfree_call_rcu_nolock(struct kvfree_rcu_head *head, void *ptr); /* * The BUILD_BUG_ON() makes sure the rcu_head offset can be handled. See the * comment of kfree_rcu() for details. */ -#define kvfree_rcu_arg_2(ptr, rhf) \ +#define kvfree_rcu_arg_2(ptr, kvrhf) \ do { \ typeof (ptr) ___p = (ptr); \ + struct kvfree_rcu_head *___head; \ \ if (___p) { \ - BUILD_BUG_ON(offsetof(typeof(*(ptr)), rhf) >= 4096); \ - kvfree_call_rcu(&((___p)->rhf), (void *) (___p)); \ + BUILD_BUG_ON(offsetof(typeof(*(ptr)), kvrhf) >= 4096); \ + ___head = (struct kvfree_rcu_head *) &(___p)->kvrhf; \ + kvfree_call_rcu(___head, (void *) (___p)); \ } \ } while (0) @@ -1122,6 +1134,27 @@ do { \ kvfree_call_rcu(NULL, (void *) (___p)); \ } while (0) +/** + * kfree_rcu_nolock() - a version of kfree_rcu() that can be called in any context. + * @ptr: pointer to kfree for double-argument invocations. + * @kvrhf: the name of the struct kvfree_rcu_head within the type of @ptr. + * + * With KVFREE_RCU_BATCHED, kfree_rcu_nolock() tries hard to free objects + * without any deferred processing, but may still defer freeing. + * Large kmalloc and vmalloc objects are always deferred. + * + * kfree_rcu_nolock() supports 2-arg variant only. + */ +#define kfree_rcu_nolock(ptr, kvrhf) \ +do { \ + typeof (ptr) ___p = (ptr); \ + \ + if (___p) { \ + BUILD_BUG_ON(offsetof(typeof(*(ptr)), kvrhf) >= 4096); \ + kfree_call_rcu_nolock(&((___p)->kvrhf), (void *) (___p)); \ + } \ +} while (0) + /* * Place this after a lock-acquisition primitive to guarantee that * an UNLOCK+LOCK pair acts as a full barrier. This guarantee applies diff --git a/include/linux/rcupdate_trace.h b/include/linux/rcupdate_trace.h index cee89e51e45c..273c59a03251 100644 --- a/include/linux/rcupdate_trace.h +++ b/include/linux/rcupdate_trace.h @@ -95,10 +95,13 @@ static inline void rcu_read_unlock_tasks_trace(struct srcu_ctr __percpu *scp) */ static inline void rcu_read_lock_trace(void) { + int n; struct task_struct *t = current; rcu_try_lock_acquire(&rcu_tasks_trace_srcu_struct.dep_map); - if (t->trc_reader_nesting++) { + n = READ_ONCE(t->trc_reader_nesting); + WRITE_ONCE(t->trc_reader_nesting, n + 1); + if (n) { // In case we interrupted a Tasks Trace RCU reader. return; } @@ -119,12 +122,17 @@ static inline void rcu_read_lock_trace(void) */ static inline void rcu_read_unlock_trace(void) { + int n; struct srcu_ctr __percpu *scp; struct task_struct *t = current; - scp = t->trc_reader_scp; - barrier(); // scp before nesting to protect against interrupt handler. - if (!--t->trc_reader_nesting) { + n = READ_ONCE(t->trc_reader_nesting) - 1; + if (n) { + WRITE_ONCE(t->trc_reader_nesting, n); + } else { + scp = t->trc_reader_scp; // Compiler cannot hoist load due to data raciness. + barrier(); // scp before nesting to protect against interrupt handler. + WRITE_ONCE(t->trc_reader_nesting, n); if (!IS_ENABLED(CONFIG_TASKS_TRACE_RCU_NO_MB)) smp_mb(); // Placeholder for more selective ordering __srcu_read_unlock_fast(&rcu_tasks_trace_srcu_struct, scp); @@ -198,10 +206,13 @@ static inline void rcu_tasks_trace_expedite_current(void) srcu_expedite_current(&rcu_tasks_trace_srcu_struct); } +unsigned long rcu_tasks_trace_batches_completed(void); + // Placeholders to enable stepwise transition. void __init rcu_tasks_trace_suppress_unused(void); #else +static inline unsigned long rcu_tasks_trace_batches_completed(void) { return 0; } /* * The BPF JIT forms these addresses even when it doesn't call these * functions, so provide definitions that result in runtime errors. diff --git a/include/linux/rcupdate_wait.h b/include/linux/rcupdate_wait.h index 4c92d4291cce..fa884704a3b7 100644 --- a/include/linux/rcupdate_wait.h +++ b/include/linux/rcupdate_wait.h @@ -18,7 +18,7 @@ struct rcu_synchronize { struct completion completion; /* This is for debugging. */ - struct rcu_gp_oldstate oldstate; + struct rcu_gp_seq oldstate; }; void wakeme_after_rcu(struct rcu_head *head); diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index f519cd680228..e56ded733b1b 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h @@ -14,11 +14,7 @@ #include <asm/param.h> /* for HZ */ -struct rcu_gp_oldstate { - unsigned long rgos_norm; -}; - -// Maximum number of rcu_gp_oldstate values corresponding to +// Maximum number of rcu_gp_seq values corresponding to // not-yet-completed RCU grace periods. #define NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE 2 @@ -26,31 +22,31 @@ struct rcu_gp_oldstate { * Are the two oldstate values the same? See the Tree RCU version for * docbook header. */ -static inline bool same_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp1, - struct rcu_gp_oldstate *rgosp2) +static inline bool same_state_synchronize_rcu_full(struct rcu_gp_seq *rgosp1, + struct rcu_gp_seq *rgosp2) { - return rgosp1->rgos_norm == rgosp2->rgos_norm; + return rgosp1->norm == rgosp2->norm; } unsigned long get_state_synchronize_rcu(void); -static inline void get_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp) +static inline void get_state_synchronize_rcu_full(struct rcu_gp_seq *gsp) { - rgosp->rgos_norm = get_state_synchronize_rcu(); + gsp->norm = get_state_synchronize_rcu(); } unsigned long start_poll_synchronize_rcu(void); -static inline void start_poll_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp) +static inline void start_poll_synchronize_rcu_full(struct rcu_gp_seq *gsp) { - rgosp->rgos_norm = start_poll_synchronize_rcu(); + gsp->norm = start_poll_synchronize_rcu(); } bool poll_state_synchronize_rcu(unsigned long oldstate); -static inline bool poll_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp) +static inline bool poll_state_synchronize_rcu_full(struct rcu_gp_seq *gsp) { - return poll_state_synchronize_rcu(rgosp->rgos_norm); + return poll_state_synchronize_rcu(gsp->norm); } static inline void cond_synchronize_rcu(unsigned long oldstate) @@ -58,9 +54,9 @@ static inline void cond_synchronize_rcu(unsigned long oldstate) might_sleep(); } -static inline void cond_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp) +static inline void cond_synchronize_rcu_full(struct rcu_gp_seq *gsp) { - cond_synchronize_rcu(rgosp->rgos_norm); + cond_synchronize_rcu(gsp->norm); } static inline unsigned long start_poll_synchronize_rcu_expedited(void) @@ -68,9 +64,9 @@ static inline unsigned long start_poll_synchronize_rcu_expedited(void) return start_poll_synchronize_rcu(); } -static inline void start_poll_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp) +static inline void start_poll_synchronize_rcu_expedited_full(struct rcu_gp_seq *gsp) { - rgosp->rgos_norm = start_poll_synchronize_rcu_expedited(); + gsp->norm = start_poll_synchronize_rcu_expedited(); } static inline void cond_synchronize_rcu_expedited(unsigned long oldstate) @@ -78,9 +74,9 @@ static inline void cond_synchronize_rcu_expedited(unsigned long oldstate) cond_synchronize_rcu(oldstate); } -static inline void cond_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp) +static inline void cond_synchronize_rcu_expedited_full(struct rcu_gp_seq *gsp) { - cond_synchronize_rcu_expedited(rgosp->rgos_norm); + cond_synchronize_rcu_expedited(gsp->norm); } extern void rcu_barrier(void); diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 9d2d7bd251d4..16a04202888b 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -38,12 +38,7 @@ void synchronize_rcu_expedited(void); void rcu_barrier(void); void rcu_momentary_eqs(void); -struct rcu_gp_oldstate { - unsigned long rgos_norm; - unsigned long rgos_exp; -}; - -// Maximum number of rcu_gp_oldstate values corresponding to +// Maximum number of rcu_gp_seq values corresponding to // not-yet-completed RCU grace periods. #define NUM_ACTIVE_RCU_POLL_FULL_OLDSTATE 4 @@ -60,29 +55,29 @@ struct rcu_gp_oldstate { * to a list header, allowing those structures to be slightly smaller. * * Note that equality is judged on a bitwise basis, so that an - * @rcu_gp_oldstate structure with an already-completed state in one field + * @rcu_gp_seq structure with an already-completed state in one field * will compare not-equal to a structure with an already-completed state - * in the other field. After all, the @rcu_gp_oldstate structure is opaque + * in the other field. After all, the @rcu_gp_seq structure is opaque * so how did such a situation come to pass in the first place? */ -static inline bool same_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp1, - struct rcu_gp_oldstate *rgosp2) +static inline bool same_state_synchronize_rcu_full(struct rcu_gp_seq *rgosp1, + struct rcu_gp_seq *rgosp2) { - return rgosp1->rgos_norm == rgosp2->rgos_norm && rgosp1->rgos_exp == rgosp2->rgos_exp; + return rgosp1->norm == rgosp2->norm && rgosp1->exp == rgosp2->exp; } unsigned long start_poll_synchronize_rcu_expedited(void); -void start_poll_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp); +void start_poll_synchronize_rcu_expedited_full(struct rcu_gp_seq *gsp); void cond_synchronize_rcu_expedited(unsigned long oldstate); -void cond_synchronize_rcu_expedited_full(struct rcu_gp_oldstate *rgosp); +void cond_synchronize_rcu_expedited_full(struct rcu_gp_seq *gsp); unsigned long get_state_synchronize_rcu(void); -void get_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp); +void get_state_synchronize_rcu_full(struct rcu_gp_seq *gsp); unsigned long start_poll_synchronize_rcu(void); -void start_poll_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp); +void start_poll_synchronize_rcu_full(struct rcu_gp_seq *gsp); bool poll_state_synchronize_rcu(unsigned long oldstate); -bool poll_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp); +bool poll_state_synchronize_rcu_full(struct rcu_gp_seq *gsp); void cond_synchronize_rcu(unsigned long oldstate); -void cond_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp); +void cond_synchronize_rcu_full(struct rcu_gp_seq *gsp); #ifdef CONFIG_PROVE_RCU void rcu_irq_exit_check_preempt(void); diff --git a/include/linux/regmap.h b/include/linux/regmap.h index df44cb30f53b..c8aebd148e08 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -587,7 +587,7 @@ typedef void (*regmap_hw_free_context)(void *context); * must serialise with respect to non-async I/O. * @reg_write: Write a single register value to the given register address. This * write operation has to complete when returning from the function. - * @reg_write_noinc: Write multiple register value to the same register. This + * @reg_noinc_write: Write multiple register values to the same register. This * write operation has to complete when returning from the function. * @reg_update_bits: Update bits operation to be used against volatile * registers, intended for devices supporting some mechanism @@ -596,6 +596,8 @@ typedef void (*regmap_hw_free_context)(void *context); * @read: Read operation. Data is returned in the buffer used to transmit * data. * @reg_read: Read a single register value from a given register address. + * @reg_noinc_read: Read multiple register values from the same register. This + * read operation has to complete when returning from the function. * @free_context: Free context. * @async_alloc: Allocate a regmap_async() structure. * @read_flag_mask: Mask to be set in the top byte of the register when doing @@ -991,7 +993,8 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); /** * regmap_init_sdw_mbq_cfg() - Initialise MBQ SDW register map with config * - * @sdw: Device that will be interacted with + * @dev: &struct device that will be interacted with + * @sdw: Soundwire device that will be interacted with * @config: Configuration for register map * @mbq_config: Properties for the MBQ registers * @@ -1584,6 +1587,7 @@ regmap_fields_force_update_bits(struct regmap_field *field, unsigned int id, * struct regmap_irq_type - IRQ type definitions. * * @type_reg_offset: Offset register for the irq type setting. + * @type_reg_mask: Device interrupt mask * @type_rising_val: Register value to configure RISING type irq. * @type_falling_val: Register value to configure FALLING type irq. * @type_level_low_val: Register value to configure LEVEL_LOW type irq. @@ -1717,6 +1721,8 @@ struct regmap_irq_chip_data; * main status base, [0, num_config_regs[ for any config * register base, and [0, num_regs[ for any other base. * If unspecified then regmap_irq_get_irq_reg_linear() is used. + * @irq_reqres: Callback function to request IRQ resources (may be %NULL) + * @irq_relres: Callback function to release IRQ resources (may be %NULL) * @irq_drv_data: Driver specific IRQ data which is passed as parameter when * driver specific pre/post interrupt handler is called. * @@ -1770,6 +1776,8 @@ struct regmap_irq_chip { void *irq_drv_data); unsigned int (*get_irq_reg)(struct regmap_irq_chip_data *data, unsigned int base, int index); + int (*irq_reqres)(void *irq_drv_data, irq_hw_number_t hwirq); + void (*irq_relres)(void *irq_drv_data, irq_hw_number_t hwirq); void *irq_drv_data; }; diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 7c1546d48008..a44368737b39 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -1,35 +1,8 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ /* - * Remote Processor Framework - * * 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 REMOTEPROC_H @@ -37,6 +10,7 @@ #include <linux/types.h> #include <linux/mutex.h> +#include <linux/spinlock.h> #include <linux/virtio.h> #include <linux/cdev.h> #include <linux/completion.h> @@ -127,10 +101,10 @@ struct rproc_ops { int (*parse_fw)(struct rproc *rproc, const struct firmware *fw); int (*handle_rsc)(struct rproc *rproc, u32 rsc_type, void *rsc, int offset, int avail); - struct resource_table *(*find_loaded_rsc_table)( - struct rproc *rproc, const struct firmware *fw); - struct resource_table *(*get_loaded_rsc_table)( - struct rproc *rproc, size_t *size); + struct resource_table *(*find_loaded_rsc_table)(struct rproc *rproc, + const struct firmware *fw); + struct resource_table *(*get_loaded_rsc_table)(struct rproc *rproc, + size_t *size); int (*load)(struct rproc *rproc, const struct firmware *fw); int (*sanity_check)(struct rproc *rproc, const struct firmware *fw); u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw); @@ -145,7 +119,6 @@ struct rproc_ops { * a message. * @RPROC_RUNNING: device is up and running * @RPROC_CRASHED: device has crashed; need to start recovery - * @RPROC_DELETED: device is deleted * @RPROC_ATTACHED: device has been booted by another entity and the core * has attached to it * @RPROC_DETACHED: device has been booted by another entity and waiting @@ -163,10 +136,9 @@ enum rproc_state { RPROC_SUSPENDED = 1, RPROC_RUNNING = 2, RPROC_CRASHED = 3, - RPROC_DELETED = 4, - RPROC_ATTACHED = 5, - RPROC_DETACHED = 6, - RPROC_LAST = 7, + RPROC_ATTACHED = 4, + RPROC_DETACHED = 5, + RPROC_LAST = 6, }; /** @@ -259,7 +231,10 @@ enum rproc_features { * @subdevs: list of subdevices, to following the running state * @notifyids: idr for dynamically assigning rproc-wide unique notify ids * @index: index of this rproc device + * @attach_work: workqueue for attaching rproc * @crash_handler: workqueue for handling a crash + * @crash_handler_lock: serializes crash handler queueing and deletion + * @deleting: remoteproc deletion has begun * @crash_cnt: crash counter * @recovery_disabled: flag that state if recovery was disabled * @max_notifyid: largest allocated notify id. @@ -271,6 +246,7 @@ enum rproc_features { * @has_iommu: flag to indicate if remote processor is behind an MMU * @auto_boot: flag to indicate if remote processor should be auto-started * @sysfs_read_only: flag to make remoteproc sysfs files read only + * @subdevs_started: flag to indicate if subdevs have started * @dump_segments: list of segments in the firmware * @nb_vdev: number of vdev currently handled by rproc * @elf_class: firmware ELF class @@ -301,7 +277,10 @@ struct rproc { struct list_head subdevs; struct idr notifyids; int index; + struct work_struct attach_work; struct work_struct crash_handler; + spinlock_t crash_handler_lock; + bool deleting; unsigned int crash_cnt; bool recovery_disabled; int max_notifyid; @@ -312,6 +291,7 @@ struct rproc { bool has_iommu; bool auto_boot; bool sysfs_read_only; + bool subdevs_started; struct list_head dump_segments; int nb_vdev; u8 elf_class; @@ -375,7 +355,6 @@ struct rproc_vring { * @index: vdev position versus other vdev declared in resource table */ struct rproc_vdev { - struct rproc_subdev subdev; struct platform_device *pdev; diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index 73ff522448a0..dd09c2ce9a0f 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -54,11 +54,11 @@ enum resctrl_res_level { RDT_RESOURCE_MBA, RDT_RESOURCE_SMBA, RDT_RESOURCE_PERF_PKG, - - /* Must be the last */ - RDT_NUM_RESOURCES, + RDT_RESOURCE_LAST = RDT_RESOURCE_PERF_PKG }; +#define RDT_NUM_RESOURCES (RDT_RESOURCE_LAST + 1) + /** * enum resctrl_conf_type - The type of configuration. * @CDP_NONE: No prioritisation, both code and data are controlled or monitored. @@ -69,9 +69,10 @@ enum resctrl_conf_type { CDP_NONE, CDP_CODE, CDP_DATA, + CDP_LAST = CDP_DATA }; -#define CDP_NUM_TYPES (CDP_DATA + 1) +#define CDP_NUM_TYPES (CDP_LAST + 1) /* * struct pseudo_lock_region - pseudo-lock region information @@ -323,7 +324,7 @@ struct resctrl_mon { * @cdp_capable: Is the CDP feature available on this resource */ struct rdt_resource { - int rid; + enum resctrl_res_level rid; bool alloc_capable; bool mon_capable; enum resctrl_scope ctrl_scope; diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 6816e4c5f3f0..deea02a034c3 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -100,7 +100,8 @@ struct rfkill * __must_check rfkill_alloc(const char *name, int __must_check rfkill_register(struct rfkill *rfkill); /** - * rfkill_pause_polling(struct rfkill *rfkill) + * rfkill_pause_polling - Pause polling + * @rfkill: rfkill struct * * Pause polling -- say transmitter is off for other reasons. * NOTE: not necessary for suspend/resume -- in that case the @@ -110,9 +111,9 @@ int __must_check rfkill_register(struct rfkill *rfkill); void rfkill_pause_polling(struct rfkill *rfkill); /** - * rfkill_resume_polling(struct rfkill *rfkill) + * rfkill_resume_polling - Resume polling + * @rfkill: rfkill struct * - * Resume polling * NOTE: not necessary for suspend/resume -- in that case the * core stops polling anyway */ @@ -325,6 +326,8 @@ static inline enum rfkill_type rfkill_find_type(const char *name) #ifdef CONFIG_RFKILL_LEDS /** * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED. + * @rfkill: rfkill struct + * * This function might return a NULL pointer if registering of the * LED trigger failed. Use this as "default_trigger" for the LED. */ diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 79f83b6eec27..57a2a29bef0e 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h @@ -23,7 +23,6 @@ #include <linux/irq_work.h> #include <linux/jhash.h> #include <linux/list_nulls.h> -#include <linux/workqueue.h> #include <linux/rculist.h> #include <linux/bit_spinlock.h> diff --git a/include/linux/rio.h b/include/linux/rio.h index 2c29f21ba9e5..f42379775ce8 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -16,7 +16,7 @@ #include <linux/errno.h> #include <linux/device.h> #include <linux/rio_regs.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/rio.h> #ifdef CONFIG_RAPIDIO_DMA_ENGINE #include <linux/dmaengine.h> #endif diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 8dc0871e5f00..0b332770abee 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -843,7 +843,7 @@ static inline int folio_try_share_anon_rmap_pmd(struct folio *folio, * Called from mm/vmscan.c to handle paging out */ int folio_referenced(struct folio *, int is_locked, - struct mem_cgroup *memcg, vm_flags_t *vm_flags); + struct mem_cgroup *memcg, vma_flags_t *vma_flags); void try_to_migrate(struct folio *folio, enum ttu_flags flags); void try_to_unmap(struct folio *, enum ttu_flags flags); @@ -864,13 +864,14 @@ struct page *make_device_exclusive(struct mm_struct *mm, unsigned long addr, struct page_vma_mapped_walk { unsigned long pfn; unsigned long nr_pages; - pgoff_t pgoff; + pgoff_t pgoff; /* Only meaningful if nr_pages > 1 and not a KSM walk */ struct vm_area_struct *vma; unsigned long address; pmd_t *pmd; pte_t *pte; spinlock_t *ptl; unsigned int flags; + bool pgoff_is_anon : 1; }; #define DEFINE_FOLIO_VMA_WALK(name, _folio, _vma, _address, _flags) \ @@ -881,6 +882,7 @@ struct page_vma_mapped_walk { .vma = _vma, \ .address = _address, \ .flags = _flags, \ + .pgoff_is_anon = folio_test_anon(_folio), \ } static inline void page_vma_mapped_walk_done(struct page_vma_mapped_walk *pvmw) @@ -975,10 +977,9 @@ struct anon_vma *folio_lock_anon_vma_read(const struct folio *folio, #define anon_vma_prepare(vma) (0) static inline int folio_referenced(struct folio *folio, int is_locked, - struct mem_cgroup *memcg, - vm_flags_t *vm_flags) + struct mem_cgroup *memcg, vma_flags_t *vma_flags) { - *vm_flags = 0; + vma_flags_clear_all(vma_flags); return 0; } diff --git a/include/linux/rolling_buffer.h b/include/linux/rolling_buffer.h index ac15b1ffdd83..9e5dad29669c 100644 --- a/include/linux/rolling_buffer.h +++ b/include/linux/rolling_buffer.h @@ -43,13 +43,13 @@ struct rolling_buffer_snapshot { #define ROLLBUF_MARK_2 BIT(1) int rolling_buffer_init(struct rolling_buffer *roll, unsigned int rreq_id, - unsigned int direction); -int rolling_buffer_make_space(struct rolling_buffer *roll); + unsigned int direction, gfp_t gfp); +int rolling_buffer_make_space(struct rolling_buffer *roll, gfp_t gfp); ssize_t rolling_buffer_load_from_ra(struct rolling_buffer *roll, struct readahead_control *ractl, struct folio_batch *put_batch); ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio, - unsigned int flags); + unsigned int flags, gfp_t gfp); struct folio_queue *rolling_buffer_delete_spent(struct rolling_buffer *roll); void rolling_buffer_clear(struct rolling_buffer *roll); diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index 2e40eb54155e..0171c490339c 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -13,7 +13,7 @@ #include <linux/types.h> #include <linux/device.h> #include <linux/err.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/rpmsg.h> #include <linux/kref.h> #include <linux/mutex.h> #include <linux/poll.h> diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h index c6d6d553d8f1..71b60125310e 100644 --- a/include/linux/rsc_table.h +++ b/include/linux/rsc_table.h @@ -1,35 +1,8 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ /* - * 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 @@ -337,17 +310,22 @@ static inline int rsc_table_for_each_entry(struct resource_table *table, 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); + u32 offset = table->offset[i]; + struct fw_rsc_hdr *hdr; + int avail, rsc_offset; + void *rsc; - if (avail < 0) { + if (offset < sizeof(*table) || offset >= table_sz || + table_sz - offset < sizeof(*hdr)) { dev_err(dev, "rsc table is truncated\n"); return -EINVAL; } + hdr = (void *)table + offset; + avail = table_sz - offset - sizeof(*hdr); + rsc_offset = offset + sizeof(*hdr); + rsc = (void *)hdr + sizeof(*hdr); + ret = cb(hdr->type, rsc, rsc_offset, avail, data); if (ret) return ret; diff --git a/include/linux/rseq_entry.h b/include/linux/rseq_entry.h index ed9da6e41a2a..31ce349ed42c 100644 --- a/include/linux/rseq_entry.h +++ b/include/linux/rseq_entry.h @@ -233,6 +233,7 @@ efault: static __always_inline bool rseq_grant_slice_extension(unsigned long ti_work, unsigned long mask) { if (unlikely(__rseq_grant_slice_extension(ti_work & mask))) { + guard(irq)(); hrtimer_rearm_deferred_tif(ti_work); return true; } diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index ea39dd23a197..95729339e7a5 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -115,6 +115,10 @@ bool rtnl_net_is_locked(struct net *net); bool lockdep_rtnl_net_is_held(struct net *net); +void rtnl_net_queue_work(struct net *net); +void rtnl_net_flush_workqueue(void); +void rtnl_net_work_func(struct work_struct *work); + #define rcu_dereference_rtnl_net(net, p) \ rcu_dereference_check(p, lockdep_rtnl_net_is_held(net)) #define rtnl_net_dereference(net, p) \ @@ -150,6 +154,10 @@ static inline void ASSERT_RTNL_NET(struct net *net) ASSERT_RTNL(); } +static inline void rtnl_net_flush_workqueue(void) +{ +} + #define rcu_dereference_rtnl_net(net, p) \ rcu_dereference_rtnl(p) #define rtnl_net_dereference(net, p) \ diff --git a/include/linux/rtsx_usb.h b/include/linux/rtsx_usb.h index 276b509c03e3..0fc5a74700a8 100644 --- a/include/linux/rtsx_usb.h +++ b/include/linux/rtsx_usb.h @@ -61,6 +61,9 @@ struct rtsx_ucr { struct timer_list sg_timer; struct mutex dev_mutex; + + u16 card_status_cache; + bool card_status_valid; }; /* buffer size */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 373bcc0598d1..8b3d47a325cc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -550,7 +550,6 @@ struct sched_statistics { s64 exec_max; u64 slice_max; - u64 nr_migrations_cold; u64 nr_failed_migrations_affine; u64 nr_failed_migrations_running; u64 nr_failed_migrations_hot; @@ -563,8 +562,6 @@ struct sched_statistics { u64 nr_wakeups_remote; u64 nr_wakeups_affine; u64 nr_wakeups_affine_attempts; - u64 nr_wakeups_passive; - u64 nr_wakeups_idle; #ifdef CONFIG_SCHED_CORE u64 core_forceidle_sum; @@ -575,6 +572,7 @@ struct sched_statistics { struct sched_entity { /* For load-balancing: */ struct load_weight load; + struct load_weight h_load; struct rb_node run_node; u64 deadline; u64 min_vruntime; @@ -823,6 +821,17 @@ struct kmap_ctrl { #endif }; +#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPTION) +struct task_ipi_mask { + union { + cpumask_t *ipi_mask_ptr; + unsigned long ipi_mask_val; + }; +}; +#else +struct task_ipi_mask { }; +#endif + struct task_struct { #ifdef CONFIG_THREAD_INFO_IN_TASK /* @@ -1191,6 +1200,7 @@ struct task_struct { unsigned long last_switch_time; #endif /* Filesystem information: */ + struct fs_struct *real_fs; struct fs_struct *fs; /* Open file information: */ @@ -1288,6 +1298,7 @@ struct task_struct { u64 curr_chain_key; int lockdep_depth; unsigned int lockdep_recursion; + unsigned int lockdep_seq; struct held_lock held_locks[MAX_LOCK_DEPTH]; #endif @@ -1359,6 +1370,7 @@ struct task_struct { struct list_head perf_event_list; struct perf_ctx_data __rcu *perf_ctx_data; #endif + struct task_ipi_mask __private ipi_mask; #ifdef CONFIG_DEBUG_PREEMPT unsigned long preempt_disable_ip; #endif @@ -1543,6 +1555,14 @@ struct task_struct { /* Collect coverage from softirq context: */ unsigned int kcov_softirq; + + /* Temporary storage for preempting remote coverage collection: */ + unsigned int kcov_saved_mode; + unsigned int kcov_saved_size; + void *kcov_saved_area; + struct kcov *kcov_saved_kcov; + int kcov_saved_sequence; + #endif #ifdef CONFIG_MEMCG_V1 @@ -1849,7 +1869,6 @@ static __always_inline bool is_user_task(struct task_struct *task) /* Per-process atomic flags. */ #define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ #define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ -#define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */ #define PFA_SPEC_SSB_DISABLE 3 /* Speculative Store Bypass disabled */ #define PFA_SPEC_SSB_FORCE_DISABLE 4 /* Speculative Store Bypass force disabled*/ #define PFA_SPEC_IB_DISABLE 5 /* Indirect branch speculation restricted */ @@ -1875,10 +1894,6 @@ TASK_PFA_TEST(SPREAD_PAGE, spread_page) TASK_PFA_SET(SPREAD_PAGE, spread_page) TASK_PFA_CLEAR(SPREAD_PAGE, spread_page) -TASK_PFA_TEST(SPREAD_SLAB, spread_slab) -TASK_PFA_SET(SPREAD_SLAB, spread_slab) -TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab) - TASK_PFA_TEST(SPEC_SSB_DISABLE, spec_ssb_disable) TASK_PFA_SET(SPEC_SSB_DISABLE, spec_ssb_disable) TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ssb_disable) diff --git a/include/linux/sched/ext.h b/include/linux/sched/ext.h index 20b2343aa344..582d7cd4a983 100644 --- a/include/linux/sched/ext.h +++ b/include/linux/sched/ext.h @@ -58,6 +58,8 @@ enum scx_dsq_id_flags { SCX_DSQ_GLOBAL = SCX_DSQ_FLAG_BUILTIN | 1, SCX_DSQ_LOCAL = SCX_DSQ_FLAG_BUILTIN | 2, SCX_DSQ_BYPASS = SCX_DSQ_FLAG_BUILTIN | 3, + SCX_DSQ_REJECT = SCX_DSQ_FLAG_BUILTIN | 4, /* internal - see find_dsq_for_dispatch() */ + SCX_DSQ_RESCUE = SCX_DSQ_FLAG_BUILTIN | 5, /* internal - see find_dsq_for_dispatch() */ SCX_DSQ_LOCAL_ON = SCX_DSQ_FLAG_BUILTIN | SCX_DSQ_FLAG_LOCAL_ON, SCX_DSQ_LOCAL_CPU_MASK = 0xffffffffLLU, }; @@ -101,6 +103,7 @@ enum scx_ent_flags { SCX_TASK_DEQD_FOR_SLEEP = 1 << 3, /* last dequeue was for SLEEP */ SCX_TASK_SUB_INIT = 1 << 4, /* task being initialized for a sub sched */ SCX_TASK_IMMED = 1 << 5, /* task is on local DSQ with %SCX_ENQ_IMMED */ + SCX_TASK_PROTECTED = 1 << 6, /* slice and DSQ head position protected */ /* * Bits 8 to 10 are used to carry task state: @@ -124,7 +127,7 @@ enum scx_ent_flags { SCX_TASK_DEAD = 5 << SCX_TASK_STATE_SHIFT, /* - * Bits 12 and 13 are used to carry reenqueue reason. In addition to + * Bits 12 to 14 are used to carry reenqueue reason. In addition to * %SCX_ENQ_REENQ flag, ops.enqueue() can also test for * %SCX_TASK_REENQ_REASON_NONE to distinguish reenqueues. * @@ -132,15 +135,17 @@ enum scx_ent_flags { * KFUNC reenqueued by scx_bpf_dsq_reenq() and friends * IMMED reenqueued due to failed ENQ_IMMED * PREEMPTED preempted while running + * CAP sub-sched cap miss, see p->scx.reenq_reason_* */ SCX_TASK_REENQ_REASON_SHIFT = 12, - SCX_TASK_REENQ_REASON_BITS = 2, + SCX_TASK_REENQ_REASON_BITS = 3, SCX_TASK_REENQ_REASON_MASK = ((1 << SCX_TASK_REENQ_REASON_BITS) - 1) << SCX_TASK_REENQ_REASON_SHIFT, SCX_TASK_REENQ_NONE = 0 << SCX_TASK_REENQ_REASON_SHIFT, SCX_TASK_REENQ_KFUNC = 1 << SCX_TASK_REENQ_REASON_SHIFT, SCX_TASK_REENQ_IMMED = 2 << SCX_TASK_REENQ_REASON_SHIFT, SCX_TASK_REENQ_PREEMPTED = 3 << SCX_TASK_REENQ_REASON_SHIFT, + SCX_TASK_REENQ_CAP = 4 << SCX_TASK_REENQ_REASON_SHIFT, /* iteration cursor, not a task */ SCX_TASK_CURSOR = 1 << 31, @@ -189,22 +194,26 @@ struct sched_ext_entity { atomic_long_t ops_state; u64 ddsp_dsq_id; u64 ddsp_enq_flags; + u64 ddsp_slice; + u64 ddsp_vtime; struct scx_dsq_list_node dsq_list; /* dispatch order */ struct rb_node dsq_priq; /* p->scx.dsq_vtime order */ u32 dsq_seq; u32 dsq_flags; /* protected by DSQ lock */ u32 flags; /* protected by rq lock */ u32 weight; + u32 reenq_cnt; /* reenqueues since last run */ s32 sticky_cpu; s32 holding_cpu; s32 selected_cpu; + s32 runnable_cpu; /* cpu @p is runnable on, -1 if not */ struct task_struct *kf_tasks[2]; /* see SCX_CALL_OP_TASK() */ struct list_head runnable_node; /* rq->scx.runnable_list */ unsigned long runnable_at; -#ifdef CONFIG_SCHED_CORE - u64 core_sched_at; /* see scx_prio_less() */ +#ifdef CONFIG_EXT_SUB_SCHED + unsigned long rescue_at; /* queued on a rescue DSQ at, jiffies */ #endif /* @@ -219,10 +228,11 @@ struct sched_ext_entity { /* BPF scheduler modifiable fields */ /* - * Runtime budget in nsecs. This is usually set through - * scx_bpf_dsq_insert() but can also be modified directly by the BPF - * scheduler. Automatically decreased by SCX as the task executes. On - * depletion, a scheduling event is triggered. + * Runtime budget in nsecs - how long the task may hold its cpu. Owned + * by the task's scheduler. Set it when enqueuing via + * scx_bpf_dsq_insert(), or otherwise via scx_bpf_task_set_slice(). + * Automatically decreased as the task executes. On depletion a + * scheduling event is triggered. * * This value is cleared to zero if the task is preempted by * %SCX_KICK_PREEMPT and shouldn't be used to determine how long the @@ -240,15 +250,31 @@ struct sched_ext_entity { u64 dsq_vtime; /* + * Out-of-band slice request from scx_bpf_task_set_slice() when the + * caller does not hold the rq lock, applied under the rq lock at the + * next slice consideration. One atomic64 packs the pending flag, the + * issuing sch's id, and the requested slice. See scx_slice_oob_consts. + */ + atomic64_t slice_oob; + + /* + * Sub-sched cap rejected reenq context, valid only while + * %SCX_TASK_REENQ_CAP is set. @reenq_reason_caps is the SCX_CAP_* bits + * that were needed but missing. @reenq_reason_cid is the target cid. + */ + u64 reenq_reason_caps; + s32 reenq_reason_cid; + + /* * If set, reject future sched_setscheduler(2) calls updating the policy * to %SCHED_EXT with -%EACCES. * * Can be set from ops.init_task() while the BPF scheduler is being - * loaded (!scx_init_task_args->fork). If set and the task's policy is - * already %SCHED_EXT, the task's policy is rejected and forcefully - * reverted to %SCHED_NORMAL. The number of such events are reported - * through /sys/kernel/debug/sched_ext::nr_rejected. Setting this flag - * during fork is not allowed. + * loaded. If set and the task's policy is already %SCHED_EXT, the + * task's policy is rejected and forcefully reverted to %SCHED_NORMAL. + * The number of such events are reported through + * /sys/kernel/sched_ext/nr_rejected. Setting this flag from any other + * ops.init_task() invocation, such as during fork, fails the scheduler. */ bool disallow; /* reject switching into SCX */ @@ -263,7 +289,7 @@ void sched_ext_dead(struct task_struct *p); void print_scx_info(const char *log_lvl, struct task_struct *p); void scx_softlockup(u32 dur_s); bool scx_hardlockup(int cpu); -bool scx_rcu_cpu_stall(void); +bool scx_rcu_cpu_stall(const struct cpumask *stalled_mask); #else /* !CONFIG_SCHED_CLASS_EXT */ @@ -271,12 +297,27 @@ static inline void sched_ext_dead(struct task_struct *p) {} static inline void print_scx_info(const char *log_lvl, struct task_struct *p) {} static inline void scx_softlockup(u32 dur_s) {} static inline bool scx_hardlockup(int cpu) { return false; } -static inline bool scx_rcu_cpu_stall(void) { return false; } +static inline bool scx_rcu_cpu_stall(const struct cpumask *stalled_mask) { return false; } #endif /* CONFIG_SCHED_CLASS_EXT */ struct scx_task_group { #ifdef CONFIG_EXT_GROUP_SCHED + /* + * The sched this tg is on, NULL if none. SCX_TG_INITED tracks whether + * ops.cgroup_init() succeeded on it. When a child sched exits and its + * tgs move to the parent, a failed init leaves the tg on the parent + * with INITED clear (see scx_cgroup_return_subtree()). + * + * This is tracked separately from cgrp->scx_sched because the tg + * hierarchy can diverge from the cgroup2 hierarchy in both lifetime and + * shape. A tg stays online past its cgroup's removal while the + * cgrp->scx_sched rewrites visit only live cgroups, leaving a removed + * cgroup's pointer stale. The cpu controller can also be mounted on + * cgroup1. + */ + struct scx_sched *sched; + u32 flags; /* SCX_TG_* */ u32 weight; u64 bw_period_us; diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 95d0040df584..d7c6a942aa7e 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -155,10 +155,12 @@ extern struct mm_struct *get_task_mm(struct task_struct *task); * succeeds. */ extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode); -/* Remove the current tasks stale references to the old mm_struct on exit() */ -extern void exit_mm_release(struct task_struct *, struct mm_struct *); -/* Remove the current tasks stale references to the old mm_struct on exec() */ -extern void exec_mm_release(struct task_struct *, struct mm_struct *); + +/* + * Remove the current tasks stale references to the old mm_struct on exit() and + * exec(). Cleans up futexes as well. + */ +extern void mm_exit_exec_release(struct task_struct *, struct mm_struct *); #ifdef CONFIG_MEMCG extern void mm_update_next_owner(struct mm_struct *mm); @@ -193,21 +195,18 @@ unsigned long mm_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -unsigned long mm_get_unmapped_area_vmflags(struct file *filp, - unsigned long addr, - unsigned long len, - unsigned long pgoff, - unsigned long flags, - vm_flags_t vm_flags); +unsigned long mm_get_unmapped_area_vmaflags(struct file *filp, + unsigned long addr, unsigned long len, unsigned long pgoff, + unsigned long flags, vma_flags_t vma_flags); unsigned long generic_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags, vm_flags_t vm_flags); + unsigned long flags, vma_flags_t vma_flags); unsigned long generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, - unsigned long flags, vm_flags_t vm_flags); + unsigned long flags, vma_flags_t vma_flags); #else static inline void arch_pick_mmap_layout(struct mm_struct *mm, const struct rlimit *rlim_stack) {} diff --git a/include/linux/sched/sd_flags.h b/include/linux/sched/sd_flags.h index 42839cfa2778..dc3ec2452ee1 100644 --- a/include/linux/sched/sd_flags.h +++ b/include/linux/sched/sd_flags.h @@ -146,8 +146,7 @@ SD_FLAG(SD_ASYM_PACKING, SDF_NEEDS_GROUPS) /* * Prefer to place tasks in a sibling domain * - * Set up until domains start spanning NUMA nodes. Close to being a SHARED_CHILD - * flag, but cleared below domains with SD_ASYM_CPUCAPACITY. + * Set up until domains start spanning NUMA nodes. * * NEEDS_GROUPS: Load balancing flag. */ diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h index 41ed884cffc9..e0c1ca8c6a18 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -31,6 +31,7 @@ struct kernel_clone_args { u32 io_thread:1; u32 user_worker:1; u32 no_files:1; + u32 umh:1; unsigned long stack; unsigned long stack_size; unsigned long tls; diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 9b959972bf4a..fcb3eb9825e5 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h @@ -22,14 +22,14 @@ #include <linux/atomic.h> #include <asm/seccomp.h> -extern int __secure_computing(void); +extern bool __seccomp_permit_syscall(void); #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER -static inline int secure_computing(void) +static __always_inline bool seccomp_permit_syscall(void) { if (unlikely(test_syscall_work(SECCOMP))) - return __secure_computing(); - return 0; + return __seccomp_permit_syscall(); + return true; } #else extern void secure_computing_strict(int this_syscall); @@ -50,11 +50,11 @@ static inline int seccomp_mode(struct seccomp *s) struct seccomp_data; #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER -static inline int secure_computing(void) { return 0; } +static inline bool seccomp_permit_syscall(void) { return true; } #else static inline void secure_computing_strict(int this_syscall) { return; } #endif -static inline int __secure_computing(void) { return 0; } +static inline bool __seccomp_permit_syscall(void) { return true; } static inline long prctl_get_seccomp(void) { diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 2fb266ea69fa..dc0e8c62d9e0 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -104,7 +104,7 @@ static inline void seq_setwidth(struct seq_file *m, size_t size) } void seq_pad(struct seq_file *m, char c); -char *mangle_path(char *s, const char *p, const char *esc); +char *seq_mangle_path(char *s, const char *p, const char *esc); int seq_open(struct file *, const struct seq_operations *); ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); ssize_t seq_read_iter(struct kiocb *iocb, struct iov_iter *iter); diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index a95b2d143d24..eeb868e93e15 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -150,8 +150,20 @@ struct uart_8250_port { #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS u16 lsr_saved_flags; u16 lsr_save_mask; + + /* + * Track when a console line has been fully written to the + * hardware, i.e. true when the most recent byte written to + * UART_TX by the console was '\n'. + */ + bool console_line_ended; + + /* Allow queuing irq_work for MSR handling */ + bool console_msr_work_allow; + #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA unsigned char msr_saved_flags; + struct irq_work console_msr_work; struct uart_8250_dma *dma; const struct uart_8250_ops *ops; @@ -192,6 +204,7 @@ void serial8250_do_shutdown(struct uart_port *port); void serial8250_do_pm(struct uart_port *port, unsigned int state, unsigned int oldstate); void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl); +void serial8250_do_break_ctl(struct uart_port *port, int break_state); void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, unsigned int quot); int fsl8250_handle_irq(struct uart_port *port); @@ -203,8 +216,8 @@ void serial8250_tx_chars(struct uart_8250_port *up); unsigned int serial8250_modem_status(struct uart_8250_port *up); void serial8250_init_port(struct uart_8250_port *up); void serial8250_set_defaults(struct uart_8250_port *up); -void serial8250_console_write(struct uart_8250_port *up, const char *s, - unsigned int count); +void serial8250_console_write(struct uart_8250_port *up, + struct nbcon_write_context *wctxt, bool in_atomic); int serial8250_console_setup(struct uart_port *port, char *options, bool probe); int serial8250_console_exit(struct uart_port *port); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index bdc214386e4a..904760876ca8 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -437,6 +437,7 @@ enum uart_iotype { UPIO_TSI = SERIAL_IO_TSI, /* Tsi108/109 type IO */ UPIO_MEM32BE = SERIAL_IO_MEM32BE, /* 32b big endian */ UPIO_MEM16 = SERIAL_IO_MEM16, /* 16b little endian */ + UPIO_BUS = SERIAL_IO_BUS, /* Serial bus I/O access (ex: SPI, I2C) */ }; struct uart_port { @@ -459,10 +460,13 @@ struct uart_port { unsigned int baud, unsigned int quot, unsigned int quot_frac); + int (*get_rxtrig)(struct uart_port *port); + int (*set_rxtrig)(struct uart_port *port, unsigned char bytes); int (*startup)(struct uart_port *port); void (*shutdown)(struct uart_port *port); void (*throttle)(struct uart_port *port); void (*unthrottle)(struct uart_port *port); + void (*break_ctl)(struct uart_port *port, int break_state); int (*handle_irq)(struct uart_port *); void (*pm)(struct uart_port *, unsigned int state, unsigned int old); @@ -1338,4 +1342,9 @@ static inline int uart_handle_break(struct uart_port *port) !((cflag) & CLOCAL)) int uart_get_rs485_mode(struct uart_port *port); + +void uart_get_ioinfos(struct uart_port *port, char *buf, size_t size); +bool uart_iotype_mmio(enum uart_iotype iotype); +bool uart_iotype_io(enum uart_iotype iotype); + #endif /* LINUX_SERIAL_CORE_H */ diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h index 102aa33d956c..f54cb6e23f85 100644 --- a/include/linux/serial_s3c.h +++ b/include/linux/serial_s3c.h @@ -269,7 +269,7 @@ #define APPLE_S5L_UTRSTAT_RXTO BIT(9) #define APPLE_S5L_UTRSTAT_ALL_FLAGS GENMASK(9, 3) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/serial_core.h> @@ -294,7 +294,7 @@ struct s3c2410_uartcfg { unsigned long ufcon; /* value of ufcon for port */ }; -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ASM_ARM_REGS_SERIAL_H */ diff --git a/include/linux/serio.h b/include/linux/serio.h index 69a47674af65..98be7084412c 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -13,7 +13,7 @@ #include <linux/spinlock.h> #include <linux/mutex.h> #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/serio.h> #include <uapi/linux/serio.h> extern const struct bus_type serio_bus; diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index e729b9b0e38d..5663dff53186 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -12,8 +12,6 @@ #include <linux/userfaultfd_k.h> #include <linux/bits.h> -struct swap_iocb; - /* inode in-kernel data */ #ifdef CONFIG_TMPFS_QUOTA @@ -123,8 +121,7 @@ static inline bool shmem_mapping(const struct address_space *mapping) void shmem_unlock_mapping(struct address_space *mapping); struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, pgoff_t index, gfp_t gfp_mask); -int shmem_writeout(struct folio *folio, struct swap_iocb **plug, - struct list_head *folio_list); +int shmem_write_folio(struct folio *folio); void shmem_truncate_range(struct inode *inode, loff_t start, uoff_t end); int shmem_unuse(unsigned int type); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 22eda1d54a0e..671c13494566 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3126,6 +3126,30 @@ static inline void skb_set_transport_header(struct sk_buff *skb, skb->transport_header += offset; } +/** + * skb_set_transport_header_careful - conditionally set transport header + * @skb: buffer to alter + * @offset: offset to add to skb->data + * + * Hardened version of skb_set_transport_header(). + * + * Returns: true if the operation was a success. + */ +static inline bool __must_check +skb_set_transport_header_careful(struct sk_buff *skb, const int offset) +{ + long thoff = skb->data - skb->head + offset; + + if (unlikely(thoff != (typeof(skb->transport_header))thoff)) + return false; + + if (unlikely(thoff == (typeof(skb->transport_header))~0U)) + return false; + + skb->transport_header = thoff; + return true; +} + static inline unsigned char *skb_network_header(const struct sk_buff *skb) { return skb->head + skb->network_header; @@ -3573,7 +3597,7 @@ static inline struct page *__dev_alloc_pages_noprof(gfp_t gfp_mask, * 3. If requesting a order 0 page it will not be compound * due to the check to see if order has a value in prep_new_page * 4. __GFP_MEMALLOC is ignored if __GFP_NOMEMALLOC is set due to - * code in gfp_to_alloc_flags that should be enforcing this. + * code in alloc_flags_slowpath() that should be enforcing this. */ gfp_mask |= __GFP_COMP | __GFP_MEMALLOC; @@ -5004,6 +5028,7 @@ static inline unsigned long skb_get_nfct(const struct sk_buff *skb) static inline void skb_set_nfct(struct sk_buff *skb, unsigned long nfct) { #if IS_ENABLED(CONFIG_NF_CONNTRACK) + DEBUG_NET_WARN_ON_ONCE(skb->_nfct & NFCT_PTRMASK); skb->slow_gro |= !!nfct; skb->_nfct = nfct; #endif diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index a8553401b1c9..d5e35f24738d 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -551,20 +551,6 @@ static inline void psock_progs_drop(struct sk_psock_progs *progs) psock_set_prog(&progs->skb_verdict, NULL); } -/* for tcp only, sk is locked */ -static inline ssize_t sk_psock_msg_inq(struct sock *sk) -{ - struct sk_psock *psock; - ssize_t inq = 0; - - psock = sk_psock_get(sk); - if (likely(psock)) { - inq = sk_psock_get_msg_len_nolock(psock); - sk_psock_put(sk, psock); - } - return inq; -} - /* for udp only, sk is not locked */ static inline ssize_t sk_msg_first_len(struct sock *sk) { diff --git a/include/linux/slab.h b/include/linux/slab.h index 51f03f18c9a7..cda126def67a 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -45,6 +45,7 @@ enum _slab_flag_bits { #endif #ifdef CONFIG_MEMCG _SLAB_ACCOUNT, + _SLAB_MAY_ACCOUNT, #endif #ifdef CONFIG_KASAN_GENERIC _SLAB_KASAN, @@ -58,10 +59,13 @@ enum _slab_flag_bits { #endif _SLAB_OBJECT_POISON, _SLAB_CMPXCHG_DOUBLE, +#ifdef CONFIG_SLAB_OBJ_EXT _SLAB_NO_OBJ_EXT, -#if defined(CONFIG_SLAB_OBJ_EXT) && defined(CONFIG_64BIT) +#ifdef CONFIG_64BIT _SLAB_OBJ_EXT_IN_OBJ, #endif +#endif + _SLAB_NO_SHEAVES, _SLAB_FLAGS_LAST_BIT }; @@ -201,8 +205,10 @@ enum _slab_flag_bits { */ #ifdef CONFIG_MEMCG # define SLAB_ACCOUNT __SLAB_FLAG_BIT(_SLAB_ACCOUNT) +# define SLAB_MAY_ACCOUNT __SLAB_FLAG_BIT(_SLAB_MAY_ACCOUNT) #else # define SLAB_ACCOUNT __SLAB_FLAG_UNUSED +# define SLAB_MAY_ACCOUNT __SLAB_FLAG_UNUSED #endif #ifdef CONFIG_KASAN_GENERIC @@ -239,8 +245,14 @@ enum _slab_flag_bits { #endif #define SLAB_TEMPORARY SLAB_RECLAIM_ACCOUNT /* Objects are short-lived */ -/* Slab created using create_boot_cache */ +/* Slab caches without obj_exts array */ +#ifdef CONFIG_SLAB_OBJ_EXT #define SLAB_NO_OBJ_EXT __SLAB_FLAG_BIT(_SLAB_NO_OBJ_EXT) +#else +#define SLAB_NO_OBJ_EXT __SLAB_FLAG_UNUSED +#endif + +#define SLAB_NO_SHEAVES __SLAB_FLAG_BIT(_SLAB_NO_SHEAVES) #if defined(CONFIG_SLAB_OBJ_EXT) && defined(CONFIG_64BIT) #define SLAB_OBJ_EXT_IN_OBJ __SLAB_FLAG_BIT(_SLAB_OBJ_EXT_IN_OBJ) @@ -505,8 +517,12 @@ typedef struct { unsigned long v; } kmalloc_token_t; extern unsigned long random_kmalloc_seed; #define __kmalloc_token(...) ((kmalloc_token_t){ .v = _CODE_LOCATION_ }) #elif defined(CONFIG_KMALLOC_PARTITION_TYPED) +#ifdef __CHECKER__ +#define __kmalloc_token(...) ((kmalloc_token_t){ .v = 0 }) +#else /* !__CHECKER__ */ #define __kmalloc_token(...) ((kmalloc_token_t){ .v = __builtin_infer_alloc_token(__VA_ARGS__) }) -#endif +#endif /* __CHECKER__ */ +#endif /* CONFIG_KMALLOC_PARTITION_TYPED */ #define DECL_TOKEN_PARAM(_token) , kmalloc_token_t (_token) #define _PASS_TOKEN_PARAM(_token) , (_token) #define PASS_TOKEN_PARAM(_token) (_token) @@ -700,6 +716,9 @@ enum kmalloc_cache_type { #ifndef CONFIG_MEMCG KMALLOC_CGROUP = KMALLOC_NORMAL, #endif +#ifndef CONFIG_SLAB_OBJ_EXT + KMALLOC_NO_OBJ_EXT = KMALLOC_NORMAL, +#endif KMALLOC_PARTITION_START = KMALLOC_NORMAL, KMALLOC_PARTITION_END = KMALLOC_PARTITION_START + KMALLOC_PARTITION_CACHES_NR, #ifdef CONFIG_SLUB_TINY @@ -713,6 +732,9 @@ enum kmalloc_cache_type { #ifdef CONFIG_MEMCG KMALLOC_CGROUP, #endif +#ifdef CONFIG_SLAB_OBJ_EXT + KMALLOC_NO_OBJ_EXT, +#endif NR_KMALLOC_TYPES }; @@ -1408,25 +1430,15 @@ extern void kvfree_sensitive(const void *addr, size_t len); unsigned int kmem_cache_size(struct kmem_cache *s); #ifndef CONFIG_KVFREE_RCU_BATCHED -static inline void kvfree_rcu_barrier(void) -{ - rcu_barrier(); -} - -static inline void kvfree_rcu_barrier_on_cache(struct kmem_cache *s) -{ - rcu_barrier(); -} - static inline void kfree_rcu_scheduler_running(void) { } #else +void kfree_rcu_scheduler_running(void); +#endif + void kvfree_rcu_barrier(void); void kvfree_rcu_barrier_on_cache(struct kmem_cache *s); -void kfree_rcu_scheduler_running(void); -#endif - /** * kmalloc_size_roundup - Report allocation bucket size for the given size * diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h index a4608d9a9684..ca6f1da4bdf3 100644 --- a/include/linux/slimbus.h +++ b/include/linux/slimbus.h @@ -8,7 +8,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/completion.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/slim.h> extern const struct bus_type slimbus_bus; diff --git a/include/linux/smp.h b/include/linux/smp.h index 6925d15ccaa7..2dfa7390717a 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -47,8 +47,7 @@ extern void __smp_call_single_queue(int cpu, struct llist_node *node); /* total number of cpus in this system (may exceed NR_CPUS) */ extern unsigned int total_cpus; -int smp_call_function_single(int cpuid, smp_call_func_t func, void *info, - int wait); +int smp_call_function_single(int cpuid, smp_call_func_t func, void *info, bool wait); void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func, void *info, bool wait, const struct cpumask *mask); @@ -239,6 +238,18 @@ static inline int get_boot_cpu_id(void) #endif /* !SMP */ +#if defined(CONFIG_PREEMPTION) && defined(CONFIG_SMP) +int smp_task_ipi_mask_alloc(struct task_struct *task); +void smp_task_ipi_mask_free(struct task_struct *task); +#else +static inline int smp_task_ipi_mask_alloc(struct task_struct *task) +{ + return 0; +} + +static inline void smp_task_ipi_mask_free(struct task_struct *task) { } +#endif + /* * raw_smp_processor_id() - get the current (unstable) CPU id * diff --git a/include/linux/soc/mediatek/mtk_sip_svc.h b/include/linux/soc/mediatek/mtk_sip_svc.h index abe24a73ee19..6c95a29b79fa 100644 --- a/include/linux/soc/mediatek/mtk_sip_svc.h +++ b/include/linux/soc/mediatek/mtk_sip_svc.h @@ -22,6 +22,9 @@ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, MTK_SIP_SMC_CONVENTION, \ ARM_SMCCC_OWNER_SIP, fn_id) +/* Modem related SMC call */ +#define MTK_SIP_KERNEL_CCCI_CONTROL MTK_SIP_SMC_CMD(0x505) + /* DVFSRC SMC calls */ #define MTK_SIP_DVFSRC_VCOREFS_CONTROL MTK_SIP_SMC_CMD(0x506) diff --git a/include/linux/soc/pxa/cpu.h b/include/linux/soc/pxa/cpu.h index 5782450ee45c..c5b275a80854 100644 --- a/include/linux/soc/pxa/cpu.h +++ b/include/linux/soc/pxa/cpu.h @@ -46,14 +46,6 @@ * PXA31x A2 0x69056892 0x2E649013 * PXA32x B1 0x69056825 0x5E642013 * PXA32x B2 0x69056826 0x6E642013 - * - * PXA930 B0 0x69056835 0x5E643013 - * PXA930 B1 0x69056837 0x7E643013 - * PXA930 B2 0x69056838 0x8E643013 - * - * PXA935 A0 0x56056931 0x1E653013 - * PXA935 B0 0x56056936 0x6E653013 - * PXA935 B1 0x56056938 0x8E653013 */ #ifdef CONFIG_PXA25x #define __cpu_is_pxa210(id) \ @@ -126,26 +118,6 @@ #define __cpu_is_pxa320(id) (0) #endif -#ifdef CONFIG_CPU_PXA930 -#define __cpu_is_pxa930(id) \ - ({ \ - unsigned int _id = (id) >> 4 & 0xfff; \ - _id == 0x683; \ - }) -#else -#define __cpu_is_pxa930(id) (0) -#endif - -#ifdef CONFIG_CPU_PXA935 -#define __cpu_is_pxa935(id) \ - ({ \ - unsigned int _id = (id) >> 4 & 0xfff; \ - _id == 0x693; \ - }) -#else -#define __cpu_is_pxa935(id) (0) -#endif - #define cpu_is_pxa210() \ ({ \ __cpu_is_pxa210(read_cpuid_id()); \ @@ -186,18 +158,6 @@ __cpu_is_pxa320(read_cpuid_id()); \ }) -#define cpu_is_pxa930() \ - ({ \ - __cpu_is_pxa930(read_cpuid_id()); \ - }) - -#define cpu_is_pxa935() \ - ({ \ - __cpu_is_pxa935(read_cpuid_id()); \ - }) - - - /* * CPUID Core Generation Bit * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x @@ -217,23 +177,12 @@ ({ \ __cpu_is_pxa300(id) \ || __cpu_is_pxa310(id) \ - || __cpu_is_pxa320(id) \ - || __cpu_is_pxa93x(id); \ + || __cpu_is_pxa320(id); \ }) #else #define __cpu_is_pxa3xx(id) (0) #endif -#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935) -#define __cpu_is_pxa93x(id) \ - ({ \ - __cpu_is_pxa930(id) \ - || __cpu_is_pxa935(id); \ - }) -#else -#define __cpu_is_pxa93x(id) (0) -#endif - #define cpu_is_pxa2xx() \ ({ \ __cpu_is_pxa2xx(read_cpuid_id()); \ @@ -244,9 +193,4 @@ __cpu_is_pxa3xx(read_cpuid_id()); \ }) -#define cpu_is_pxa93x() \ - ({ \ - __cpu_is_pxa93x(read_cpuid_id()); \ - }) - #endif diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h index 58fa1df96347..909e84f84e0c 100644 --- a/include/linux/soc/qcom/apr.h +++ b/include/linux/soc/qcom/apr.h @@ -5,7 +5,7 @@ #include <linux/spinlock.h> #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/apr.h> #include <dt-bindings/soc/qcom,apr.h> #include <dt-bindings/soc/qcom,gpr.h> diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h index c5e6ab85df09..29a53bbc0dd4 100644 --- a/include/linux/soc/qcom/geni-se.h +++ b/include/linux/soc/qcom/geni-se.h @@ -81,13 +81,16 @@ struct geni_se { }; /* Common SE registers */ +#define GENI_GENERAL_CFG 0x10 #define GENI_FORCE_DEFAULT_REG 0x20 #define GENI_OUTPUT_CTRL 0x24 #define SE_GENI_STATUS 0x40 #define GENI_SER_M_CLK_CFG 0x48 #define GENI_SER_S_CLK_CFG 0x4c +#define GENI_CLK_CTRL_RO 0x60 #define GENI_IF_DISABLE_RO 0x64 #define GENI_FW_REVISION_RO 0x68 +#define GENI_FW_MULTILOCK_MSA_RO 0x74 #define SE_GENI_CLK_SEL 0x7c #define SE_GENI_CFG_SEQ_START 0x84 #define SE_GENI_DMA_MODE_EN 0x258 @@ -98,6 +101,8 @@ struct geni_se { #define SE_GENI_M_IRQ_CLEAR 0x618 #define SE_GENI_M_IRQ_EN_SET 0x61c #define SE_GENI_M_IRQ_EN_CLEAR 0x620 +#define M_CMD_ERR_STATUS 0x624 +#define M_FW_ERR_STATUS 0x628 #define SE_GENI_S_CMD0 0x630 #define SE_GENI_S_CMD_CTRL_REG 0x634 #define SE_GENI_S_IRQ_STATUS 0x640 @@ -115,15 +120,43 @@ struct geni_se { #define SE_GENI_IOS 0x908 #define SE_GENI_M_GP_LENGTH 0x910 #define SE_GENI_S_GP_LENGTH 0x914 +/* TX DMA registers */ +#define SE_DMA_TX_PTR_L 0xc30 +#define SE_DMA_TX_PTR_H 0xc34 +#define SE_DMA_TX_ATTR 0xc38 +#define SE_DMA_TX_LEN 0xc3c #define SE_DMA_TX_IRQ_STAT 0xc40 #define SE_DMA_TX_IRQ_CLR 0xc44 +#define SE_DMA_TX_IRQ_EN 0xc48 +#define SE_DMA_TX_IRQ_EN_SET 0xc4c +#define SE_DMA_TX_IRQ_EN_CLR 0xc50 +#define SE_DMA_TX_LEN_IN 0xc54 #define SE_DMA_TX_FSM_RST 0xc58 +#define SE_DMA_TX_MAX_BURST 0xc5c +/* RX DMA registers */ +#define SE_DMA_RX_PTR_L 0xd30 +#define SE_DMA_RX_PTR_H 0xd34 +#define SE_DMA_RX_ATTR 0xd38 +#define SE_DMA_RX_LEN 0xd3c #define SE_DMA_RX_IRQ_STAT 0xd40 #define SE_DMA_RX_IRQ_CLR 0xd44 +#define SE_DMA_RX_IRQ_EN 0xd48 +#define SE_DMA_RX_IRQ_EN_SET 0xd4c +#define SE_DMA_RX_IRQ_EN_CLR 0xd50 #define SE_DMA_RX_LEN_IN 0xd54 #define SE_DMA_RX_FSM_RST 0xd58 +#define SE_DMA_RX_MAX_BURST 0xd5c +/* DMA general / debug registers */ +#define SE_GSI_EVENT_EN 0xe18 +#define SE_IRQ_EN 0xe1c +#define DMA_IF_EN_RO 0xe20 #define SE_HW_PARAM_0 0xe24 #define SE_HW_PARAM_1 0xe28 +#define SE_HW_PARAM_2 0xe2c +#define DMA_GENERAL_CFG 0xe30 +#define SE_DMA_QSB_TRANS_CFG 0xe38 +#define SE_DMA_DEBUG_REG0 0xe40 +#define SE_DMA_IF_EN 0x2004 /* GENI_FORCE_DEFAULT_REG fields */ #define FORCE_DEFAULT BIT(0) @@ -269,6 +302,12 @@ struct geni_se { #define RX_GENI_GP_IRQ_EXT GENMASK(13, 12) #define RX_GENI_CANCEL_IRQ BIT(14) +/* SE_DMA_DEBUG_REG0 fields */ +#define DMA_TX_ACTIVE BIT(0) +#define DMA_RX_ACTIVE BIT(1) +#define DMA_TX_STATE GENMASK(7, 4) +#define DMA_RX_STATE GENMASK(11, 8) + /* SE_HW_PARAM_0 fields */ #define TX_FIFO_WIDTH_MSK GENMASK(29, 24) #define TX_FIFO_WIDTH_SHFT 24 @@ -291,6 +330,9 @@ struct geni_se { #define RX_FIFO_DEPTH_MSK GENMASK(21, 16) #define RX_FIFO_DEPTH_SHFT 16 +/* SE_HW_PARAM_2 fields */ +#define PROG_RAM_DEPTH_MSK GENMASK(10, 0) + #define HW_VER_MAJOR_MASK GENMASK(31, 28) #define HW_VER_MAJOR_SHFT 28 #define HW_VER_MINOR_MASK GENMASK(27, 16) diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h index 82372e0db0a1..74886f772d46 100644 --- a/include/linux/soc/qcom/mdt_loader.h +++ b/include/linux/soc/qcom/mdt_loader.h @@ -10,7 +10,7 @@ struct device; struct firmware; -struct qcom_scm_pas_context; +struct qcom_pas_context; #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER) @@ -20,8 +20,8 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, phys_addr_t mem_phys, size_t mem_size, phys_addr_t *reloc_base); -int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, const struct firmware *fw, - const char *firmware, void *mem_region, phys_addr_t *reloc_base); +int qcom_mdt_pas_load(struct qcom_pas_context *ctx, const struct firmware *fw, + const char *firmware, phys_addr_t *reloc_base); int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, const char *fw_name, void *mem_region, @@ -45,9 +45,9 @@ static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw, return -ENODEV; } -static inline int qcom_mdt_pas_load(struct qcom_scm_pas_context *ctx, +static inline int qcom_mdt_pas_load(struct qcom_pas_context *ctx, const struct firmware *fw, const char *firmware, - void *mem_region, phys_addr_t *reloc_base) + phys_addr_t *reloc_base) { return -ENODEV; } diff --git a/include/linux/soc/qcom/smem.h b/include/linux/soc/qcom/smem.h index f946e3beca21..3249cbd2016b 100644 --- a/include/linux/soc/qcom/smem.h +++ b/include/linux/soc/qcom/smem.h @@ -17,4 +17,6 @@ int qcom_smem_get_feature_code(u32 *code); int qcom_smem_bust_hwspin_lock_by_host(unsigned int host); +int qcom_smem_dram_get_hbb(void); + #endif diff --git a/include/linux/soc/qcom/ubwc.h b/include/linux/soc/qcom/ubwc.h index 83d2c2a7116c..f3a70360b177 100644 --- a/include/linux/soc/qcom/ubwc.h +++ b/include/linux/soc/qcom/ubwc.h @@ -8,25 +8,12 @@ #define __QCOM_UBWC_H__ #include <linux/bits.h> +#include <linux/err.h> #include <linux/printk.h> #include <linux/types.h> struct qcom_ubwc_cfg_data { u32 ubwc_enc_version; - /* Can be read from MDSS_BASE + 0x58 */ - u32 ubwc_dec_version; - - /** - * @ubwc_swizzle: Whether to enable level 1, 2 & 3 bank swizzling. - * - * UBWC 1.0 always enables all three levels. - * UBWC 2.0 removes level 1 bank swizzling, leaving levels 2 & 3. - * UBWC 4.0 adds the optional ability to disable levels 2 & 3. - */ - u32 ubwc_swizzle; -#define UBWC_SWIZZLE_ENABLE_LVL1 BIT(0) -#define UBWC_SWIZZLE_ENABLE_LVL2 BIT(1) -#define UBWC_SWIZZLE_ENABLE_LVL3 BIT(2) /** * @highest_bank_bit: Highest Bank Bit @@ -35,16 +22,10 @@ struct qcom_ubwc_cfg_data { * DDR bank. This should ideally use DRAM type detection. */ int highest_bank_bit; - bool ubwc_bank_spread; - /** - * @macrotile_mode: Macrotile Mode - * - * Whether to use 4-channel macrotiling mode or the newer - * 8-channel macrotiling mode introduced in UBWC 3.1. 0 is - * 4-channel and 1 is 8-channel. - */ - bool macrotile_mode; + unsigned int flags; +#define UBWC_FLAG_DISABLE_SWIZZLE_LVL2 BIT(0) +#define UBWC_FLAG_DISABLE_SWIZZLE_LVL3 BIT(1) }; #define UBWC_1_0 0x10000000 @@ -67,37 +48,62 @@ static inline const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void) static inline bool qcom_ubwc_get_ubwc_mode(const struct qcom_ubwc_cfg_data *cfg) { - bool ret = cfg->ubwc_enc_version == UBWC_1_0; - - if (ret && !(cfg->ubwc_swizzle & UBWC_SWIZZLE_ENABLE_LVL1)) - pr_err("UBWC config discrepancy - level 1 swizzling disabled on UBWC 1.0\n"); - - return ret; + return cfg->ubwc_enc_version == UBWC_1_0; } -/* - * This is the best guess, based on the MDSS driver, which worked so far. - */ static inline bool qcom_ubwc_min_acc_length_64b(const struct qcom_ubwc_cfg_data *cfg) { - return cfg->ubwc_enc_version == UBWC_1_0 && - (cfg->ubwc_dec_version == UBWC_2_0 || - cfg->ubwc_dec_version == UBWC_3_0); + return cfg->ubwc_enc_version == UBWC_1_0; } +/* + * @qcom_ubwc_macrotile_mode: whether to use 4-channel or 8-channel macrotiling + * + * The 8-channel macrotiling mode was introduced in UBWC 3.1. + * + * Returns: false for the 4-channel and true for 8-channel. + */ static inline bool qcom_ubwc_macrotile_mode(const struct qcom_ubwc_cfg_data *cfg) { - return cfg->macrotile_mode; + return cfg->ubwc_enc_version >= UBWC_3_1; } static inline bool qcom_ubwc_bank_spread(const struct qcom_ubwc_cfg_data *cfg) { - return cfg->ubwc_bank_spread; + return true; } +#define UBWC_SWIZZLE_ENABLE_LVL1 BIT(0) +#define UBWC_SWIZZLE_ENABLE_LVL2 BIT(1) +#define UBWC_SWIZZLE_ENABLE_LVL3 BIT(2) + +/** + * @qcom_ubwc_swizzle: Whether to enable level 1, 2 & 3 bank swizzling. + * + * UBWC 1.0 always enables all three levels. + * UBWC 2.0 removes level 1 bank swizzling, leaving levels 2 & 3. + * UBWC 4.0 adds the optional ability to disable levels 2 & 3. + */ static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg) { - return cfg->ubwc_swizzle; + if (cfg->ubwc_enc_version == 0) + return 0; + + if (cfg->ubwc_enc_version == UBWC_1_0) + return UBWC_SWIZZLE_ENABLE_LVL1 | + UBWC_SWIZZLE_ENABLE_LVL2 | + UBWC_SWIZZLE_ENABLE_LVL3; + + u32 ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 | + UBWC_SWIZZLE_ENABLE_LVL3; + + if (cfg->flags & UBWC_FLAG_DISABLE_SWIZZLE_LVL2) + ubwc_swizzle &= ~UBWC_SWIZZLE_ENABLE_LVL2; + + if (cfg->flags & UBWC_FLAG_DISABLE_SWIZZLE_LVL3) + ubwc_swizzle &= ~UBWC_SWIZZLE_ENABLE_LVL3; + + return ubwc_swizzle; } static inline u32 qcom_ubwc_version_tag(const struct qcom_ubwc_cfg_data *cfg) diff --git a/include/linux/socket.h b/include/linux/socket.h index 2a8d7b14f1d1..5a5eb1250103 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -461,6 +461,8 @@ extern struct file *__sys_socket_file(int family, int type, int protocol); extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); extern int __sys_bind_socket(struct socket *sock, struct sockaddr_storage *address, int addrlen); +int connect_socket(struct socket *sock, struct sockaddr_storage *addr, + int addrlen, int flags); extern int __sys_connect_file(struct file *file, struct sockaddr_storage *addr, int addrlen, int file_flags); extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, diff --git a/include/linux/sonet.h b/include/linux/sonet.h deleted file mode 100644 index 2b802b6d12ad..000000000000 --- a/include/linux/sonet.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* sonet.h - SONET/SHD physical layer control */ -#ifndef LINUX_SONET_H -#define LINUX_SONET_H - - -#include <linux/atomic.h> -#include <uapi/linux/sonet.h> - -struct k_sonet_stats { -#define __HANDLE_ITEM(i) atomic_t i - __SONET_ITEMS -#undef __HANDLE_ITEM -}; - -extern void sonet_copy_stats(struct k_sonet_stats *from,struct sonet_stats *to); -extern void sonet_subtract_stats(struct k_sonet_stats *from, - struct sonet_stats *to); - -#endif diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index b484784e2690..707ca6bd1e23 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -13,7 +13,7 @@ #include <linux/irqdomain.h> #include <linux/jiffies.h> #include <linux/lockdep_types.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/sdw.h> #include <linux/mutex.h> #include <linux/types.h> #include <sound/sdca.h> @@ -365,6 +365,10 @@ struct sdw_dpn_prop { * @commit_register_supported: is PCP_Commit register supported * @scp_int1_mask: SCP_INT1_MASK desired settings * @lane_maps: Lane mapping for the slave, only valid if lane_control_support is set + * @bra_block_alignment: If non-zero the length of data in a BRA frame must be + * a multiple of this number of bytes. + * @bra_max_data_per_frame: If non-zero the maximum data payload size (in bytes per + * frame excluding header, CRC, and footer) for this BRA Mode * @clock_reg_supported: the Peripheral implements the clock base and scale * registers introduced with the SoundWire 1.2 specification. SDCA devices * do not need to set this boolean property as the registers are required. @@ -395,6 +399,8 @@ struct sdw_slave_prop { u8 commit_register_supported; u8 scp_int1_mask; u8 lane_maps[SDW_MAX_LANES]; + u32 bra_block_alignment; + u32 bra_max_data_per_frame; bool clock_reg_supported; bool use_domain_irq; }; @@ -837,6 +843,14 @@ struct sdw_defer { */ #define SDW_BPT_MSG_MAX_BYTES (1024 * 1024) +/* + * According to mipi SoundWire DisCo Specification_v2-1, + * this maximum value shall not exceed 470. + * Note that the largest number of bytes accessible by a single BRA operation is limited to 470 + * bytes when using lane 0, but goes up to 502 bytes when using one of the optional extra lanes. + */ +#define SDW_BRA_MAX_BYTES_PER_FRAME 470 + struct sdw_bpt_msg; /** diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index f660bb2e9f85..0cce6b57242a 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -275,6 +275,7 @@ struct spi_mem_dirmap_desc { * @spi: the underlying SPI device * @drvpriv: spi_mem_driver private data * @name: name of the SPI memory device + * @dqs: extra data trobe pin available for high frequency read operations * * Extra information that describe the SPI memory device and may be needed by * the controller to properly handle this device should be placed here. @@ -286,6 +287,7 @@ struct spi_mem { struct spi_device *spi; void *drvpriv; const char *name; + bool dqs; }; /** @@ -461,6 +463,8 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, } #endif /* CONFIG_SPI_MEM */ +void spi_mem_set_dqs(struct spi_mem *mem); +bool spi_mem_has_dqs(struct spi_mem *mem); int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op); void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op); u64 spi_mem_calc_op_duration(struct spi_mem *mem, struct spi_mem_op *op); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index f6ed93eff00b..88d17fce02dc 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -12,7 +12,9 @@ #include <linux/device.h> #include <linux/gpio/consumer.h> #include <linux/kthread.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/acpi.h> +#include <linux/device-id/of.h> +#include <linux/device-id/spi.h> #include <linux/overflow.h> #include <linux/scatterlist.h> #include <linux/slab.h> @@ -177,6 +179,8 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg, * @num_tx_lanes: Number of transmit lanes wired up. * @rx_lane_map: Map of peripheral lanes (index) to controller lanes (value). * @num_rx_lanes: Number of receive lanes wired up. + * @userspace_node: entry on the parent controller's userspace_clients list + * when this device was instantiated via the sysfs new_device interface * * A @spi_device is used to interchange data between an SPI target device * (usually a discrete chip) and CPU memory. @@ -250,6 +254,10 @@ struct spi_device { u8 rx_lane_map[SPI_DEVICE_DATA_LANE_CNT_MAX]; u8 num_rx_lanes; +#if IS_ENABLED(CONFIG_SPI_DYNAMIC) + struct list_head userspace_node; +#endif + /* * Likely need more hooks for more protocol options affecting how * the controller talks to each chip, like: @@ -553,6 +561,11 @@ extern struct spi_device *devm_spi_new_ancillary_device(struct spi_device *spi, * @defer_optimize_message: set to true if controller cannot pre-optimize messages * and needs to defer the optimization step until the message is actually * being transferred + * @userspace_clients: list of SPI devices instantiated from userspace via + * the sysfs new_device interface; protected by @add_lock + * @userspace_registered: true once the new_device/delete_device sysfs + * group has been added by spi_register_controller(); used by + * spi_unregister_controller() to know whether to remove it * * Each SPI controller can communicate with one or more @spi_device * children. These make a small bus, sharing MOSI, MISO and SCK signals @@ -805,6 +818,13 @@ struct spi_controller { bool queue_empty; bool must_async; bool defer_optimize_message; + +#if IS_ENABLED(CONFIG_SPI_DYNAMIC) + /* List of userspace-instantiated devices; protected by @add_lock */ + struct list_head userspace_clients; + /* True after new_device/delete_device sysfs group is created */ + bool userspace_registered; +#endif }; static inline void *spi_controller_get_devdata(struct spi_controller *ctlr) diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 241277cd34cf..3d405cc4c121 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -57,6 +57,7 @@ #include <linux/linkage.h> #include <linux/compiler.h> #include <linux/irqflags.h> +#include <linux/interrupt_rc.h> #include <linux/thread_info.h> #include <linux/stringify.h> #include <linux/bottom_half.h> @@ -273,9 +274,11 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) #endif #define raw_spin_lock_irq(lock) _raw_spin_lock_irq(lock) +#define raw_spin_lock_irq_disable(lock) _raw_spin_lock_irq_disable(lock) #define raw_spin_lock_bh(lock) _raw_spin_lock_bh(lock) #define raw_spin_unlock(lock) _raw_spin_unlock(lock) #define raw_spin_unlock_irq(lock) _raw_spin_unlock_irq(lock) +#define raw_spin_unlock_irq_enable(lock) _raw_spin_unlock_irq_enable(lock) #define raw_spin_unlock_irqrestore(lock, flags) \ do { \ @@ -290,6 +293,8 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) #define raw_spin_trylock_irqsave(lock, flags) _raw_spin_trylock_irqsave(lock, &(flags)) +#define raw_spin_trylock_irq_disable(lock) _raw_spin_trylock_irq_disable(lock) + #ifndef CONFIG_PREEMPT_RT /* Include rwlock functions for !RT */ #include <linux/rwlock.h> @@ -372,6 +377,12 @@ static __always_inline void spin_lock_irq(spinlock_t *lock) raw_spin_lock_irq(&lock->rlock); } +static __always_inline void spin_lock_irq_disable(spinlock_t *lock) + __acquires(lock) __no_context_analysis +{ + raw_spin_lock_irq_disable(&lock->rlock); +} + #define spin_lock_irqsave(lock, flags) \ do { \ raw_spin_lock_irqsave(spinlock_check(lock), flags); \ @@ -402,6 +413,12 @@ static __always_inline void spin_unlock_irq(spinlock_t *lock) raw_spin_unlock_irq(&lock->rlock); } +static __always_inline void spin_unlock_irq_enable(spinlock_t *lock) + __releases(lock) __no_context_analysis +{ + raw_spin_unlock_irq_enable(&lock->rlock); +} + static __always_inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) __releases(lock) __no_context_analysis { @@ -427,6 +444,12 @@ static __always_inline bool _spin_trylock_irqsave(spinlock_t *lock, unsigned lon } #define spin_trylock_irqsave(lock, flags) _spin_trylock_irqsave(lock, &(flags)) +static __always_inline int spin_trylock_irq_disable(spinlock_t *lock) + __cond_acquires(true, lock) __no_context_analysis +{ + return raw_spin_trylock_irq_disable(&lock->rlock); +} + /** * spin_is_locked() - Check whether a spinlock is locked. * @lock: Pointer to the spinlock. diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index bda5e7a390cd..90909d933dab 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h @@ -28,6 +28,8 @@ _raw_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *map) void __lockfunc _raw_spin_lock_bh(raw_spinlock_t *lock) __acquires(lock); void __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock) __acquires(lock); +void __lockfunc _raw_spin_lock_irq_disable(raw_spinlock_t *lock) + __acquires(lock); unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock) __acquires(lock); @@ -39,6 +41,7 @@ int __lockfunc _raw_spin_trylock_bh(raw_spinlock_t *lock) __cond_acquires(true, void __lockfunc _raw_spin_unlock(raw_spinlock_t *lock) __releases(lock); void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) __releases(lock); void __lockfunc _raw_spin_unlock_irq(raw_spinlock_t *lock) __releases(lock); +void __lockfunc _raw_spin_unlock_irq_enable(raw_spinlock_t *lock) __releases(lock); void __lockfunc _raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) __releases(lock); @@ -55,6 +58,11 @@ _raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) #define _raw_spin_lock_irq(lock) __raw_spin_lock_irq(lock) #endif +/* Use the same config as spin_lock_irq() temporarily. */ +#ifdef CONFIG_INLINE_SPIN_LOCK_IRQ +#define _raw_spin_lock_irq_disable(lock) __raw_spin_lock_irq_disable(lock) +#endif + #ifdef CONFIG_INLINE_SPIN_LOCK_IRQSAVE #define _raw_spin_lock_irqsave(lock) __raw_spin_lock_irqsave(lock) #endif @@ -79,6 +87,11 @@ _raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) #define _raw_spin_unlock_irq(lock) __raw_spin_unlock_irq(lock) #endif +/* Use the same config as spin_unlock_irq() temporarily. */ +#ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQ +#define _raw_spin_unlock_irq_enable(lock) __raw_spin_unlock_irq_enable(lock) +#endif + #ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE #define _raw_spin_unlock_irqrestore(lock, flags) __raw_spin_unlock_irqrestore(lock, flags) #endif @@ -105,6 +118,16 @@ static __always_inline bool _raw_spin_trylock_irq(raw_spinlock_t *lock) return false; } +static __always_inline bool _raw_spin_trylock_irq_disable(raw_spinlock_t *lock) + __cond_acquires(true, lock) +{ + local_interrupt_disable(); + if (_raw_spin_trylock(lock)) + return true; + local_interrupt_enable(); + return false; +} + static __always_inline bool _raw_spin_trylock_irqsave(raw_spinlock_t *lock, unsigned long *flags) __cond_acquires(true, lock) { @@ -143,6 +166,15 @@ static inline void __raw_spin_lock_irq(raw_spinlock_t *lock) LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } +static inline void __raw_spin_lock_irq_disable(raw_spinlock_t *lock) + __acquires(lock) __no_context_analysis +{ + local_interrupt_disable(); + preempt_disable(); + spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); +} + static inline void __raw_spin_lock_bh(raw_spinlock_t *lock) __acquires(lock) __no_context_analysis { @@ -188,6 +220,15 @@ static inline void __raw_spin_unlock_irq(raw_spinlock_t *lock) preempt_enable(); } +static inline void __raw_spin_unlock_irq_enable(raw_spinlock_t *lock) + __releases(lock) +{ + spin_release(&lock->dep_map, _RET_IP_); + do_raw_spin_unlock(lock); + local_interrupt_enable(); + preempt_enable(); +} + static inline void __raw_spin_unlock_bh(raw_spinlock_t *lock) __releases(lock) { diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h index a9d5c7c66e03..d03d3065ee04 100644 --- a/include/linux/spinlock_api_up.h +++ b/include/linux/spinlock_api_up.h @@ -42,6 +42,9 @@ #define __LOCK_IRQSAVE(lock, flags, ...) \ do { local_irq_save(flags); __LOCK(lock, ##__VA_ARGS__); } while (0) +#define __LOCK_IRQ_DISABLE(lock, ...) \ + do { local_interrupt_disable(); __LOCK(lock, ##__VA_ARGS__); } while (0) + #define ___UNLOCK_(lock) \ do { __release(lock); (void)(lock); } while (0) @@ -61,6 +64,9 @@ #define __UNLOCK_IRQRESTORE(lock, flags, ...) \ do { local_irq_restore(flags); __UNLOCK(lock, ##__VA_ARGS__); } while (0) +#define __UNLOCK_IRQ_ENABLE(lock, ...) \ + do { __UNLOCK(lock, ##__VA_ARGS__); local_interrupt_enable(); } while (0) + #define _raw_spin_lock(lock) __LOCK(lock) #define _raw_spin_lock_nested(lock, subclass) __LOCK(lock) #define _raw_read_lock(lock) __LOCK(lock, shared) @@ -70,6 +76,7 @@ #define _raw_read_lock_bh(lock) __LOCK_BH(lock, shared) #define _raw_write_lock_bh(lock) __LOCK_BH(lock) #define _raw_spin_lock_irq(lock) __LOCK_IRQ(lock) +#define _raw_spin_lock_irq_disable(lock) __LOCK_IRQ_DISABLE(lock) #define _raw_read_lock_irq(lock) __LOCK_IRQ(lock, shared) #define _raw_write_lock_irq(lock) __LOCK_IRQ(lock) #define _raw_spin_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) @@ -97,6 +104,13 @@ static __always_inline int _raw_spin_trylock_irq(raw_spinlock_t *lock) return 1; } +static __always_inline int _raw_spin_trylock_irq_disable(raw_spinlock_t *lock) + __cond_acquires(true, lock) +{ + __LOCK_IRQ_DISABLE(lock); + return 1; +} + static __always_inline int _raw_spin_trylock_irqsave(raw_spinlock_t *lock, unsigned long *flags) __cond_acquires(true, lock) { @@ -132,6 +146,7 @@ static __always_inline int _raw_write_trylock_irqsave(rwlock_t *lock, unsigned l #define _raw_write_unlock_bh(lock) __UNLOCK_BH(lock) #define _raw_read_unlock_bh(lock) __UNLOCK_BH(lock, shared) #define _raw_spin_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _raw_spin_unlock_irq_enable(lock) __UNLOCK_IRQ_ENABLE(lock) #define _raw_read_unlock_irq(lock) __UNLOCK_IRQ(lock, shared) #define _raw_write_unlock_irq(lock) __UNLOCK_IRQ(lock) #define _raw_spin_unlock_irqrestore(lock, flags) \ diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h index 373618a4243c..560d06384e0c 100644 --- a/include/linux/spinlock_rt.h +++ b/include/linux/spinlock_rt.h @@ -96,6 +96,12 @@ static __always_inline void spin_lock_irq(spinlock_t *lock) rt_spin_lock(lock); } +static __always_inline void spin_lock_irq_disable(spinlock_t *lock) + __acquires(lock) +{ + rt_spin_lock(lock); +} + #define spin_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ @@ -122,6 +128,12 @@ static __always_inline void spin_unlock_irq(spinlock_t *lock) rt_spin_unlock(lock); } +static __always_inline void spin_unlock_irq_enable(spinlock_t *lock) + __releases(lock) +{ + rt_spin_unlock(lock); +} + static __always_inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) __releases(lock) @@ -131,6 +143,12 @@ static __always_inline void spin_unlock_irqrestore(spinlock_t *lock, #define spin_trylock(lock) rt_spin_trylock(lock) +static __always_inline int spin_trylock_irq_disable(spinlock_t *lock) + __cond_acquires(true, lock) +{ + return rt_spin_trylock(lock); +} + #define spin_trylock_bh(lock) rt_spin_trylock_bh(lock) #define spin_trylock_irq(lock) rt_spin_trylock(lock) diff --git a/include/linux/srcu.h b/include/linux/srcu.h index a54ce9e808b9..7d9bc06df98d 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -25,20 +25,19 @@ context_lock_struct(srcu_struct, __reentrant_ctx_lock); #ifdef CONFIG_DEBUG_LOCK_ALLOC -int __init_srcu_struct(struct srcu_struct *ssp, const char *name, struct lock_class_key *key); +int init_srcu_struct_lockdep(struct srcu_struct *ssp, const char *name, + struct lock_class_key *key); +static inline int __init_srcu_struct(struct srcu_struct *ssp, const char *name, + struct lock_class_key *key) +{ + return init_srcu_struct_lockdep(ssp, name, key); +} #ifndef CONFIG_TINY_SRCU int __init_srcu_struct_fast(struct srcu_struct *ssp, const char *name, struct lock_class_key *key); int __init_srcu_struct_fast_updown(struct srcu_struct *ssp, const char *name, struct lock_class_key *key); #endif // #ifndef CONFIG_TINY_SRCU -#define init_srcu_struct(ssp) \ -({ \ - static struct lock_class_key __srcu_key; \ - \ - __init_srcu_struct((ssp), #ssp, &__srcu_key); \ -}) - #define init_srcu_struct_fast(ssp) \ ({ \ static struct lock_class_key __srcu_key; \ @@ -56,7 +55,12 @@ int __init_srcu_struct_fast_updown(struct srcu_struct *ssp, const char *name, #define __SRCU_DEP_MAP_INIT(srcu_name) .dep_map = { .name = #srcu_name }, #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ -int init_srcu_struct(struct srcu_struct *ssp); +int init_srcu_struct_generic(struct srcu_struct *ssp); +static inline int __init_srcu_struct(struct srcu_struct *ssp, const char *name, + struct lock_class_key *key) +{ + return init_srcu_struct_generic(ssp); +} #ifndef CONFIG_TINY_SRCU int init_srcu_struct_fast(struct srcu_struct *ssp); int init_srcu_struct_fast_updown(struct srcu_struct *ssp); @@ -65,6 +69,13 @@ int init_srcu_struct_fast_updown(struct srcu_struct *ssp); #define __SRCU_DEP_MAP_INIT(srcu_name) #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +#define init_srcu_struct(ssp) \ +({ \ + static struct lock_class_key __srcu_key; \ + \ + __init_srcu_struct((ssp), #ssp, &__srcu_key); \ +}) + /* Values for SRCU Tree srcu_data ->srcu_reader_flavor, but also used by rcutorture. */ #define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock(). #define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe(). @@ -638,4 +649,11 @@ DEFINE_LOCK_GUARD_1(srcu_fast_notrace, struct srcu_struct, DECLARE_LOCK_GUARD_1_ATTRS(srcu_fast_notrace, __acquires_shared(_T), __releases_shared(*(struct srcu_struct **)_T)) #define class_srcu_fast_notrace_constructor(_T) WITH_LOCK_GUARD_1_ATTRS(srcu_fast_notrace, _T) +DEFINE_LOCK_GUARD_1(srcu_fast_updown, struct srcu_struct, + _T->scp = srcu_read_lock_fast_updown(_T->lock), + srcu_read_unlock_fast_updown(_T->lock, _T->scp), + struct srcu_ctr __percpu *scp) +DECLARE_LOCK_GUARD_1_ATTRS(srcu_fast_updown, __acquires_shared(_T), __releases_shared(*(struct srcu_struct **)_T)) +#define class_srcu_fast_updown_constructor(_T) WITH_LOCK_GUARD_1_ATTRS(srcu_fast_updown, _T) + #endif diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h index 905b629e8fa3..fbcf13bc12d1 100644 --- a/include/linux/srcutiny.h +++ b/include/linux/srcutiny.h @@ -154,4 +154,17 @@ static inline void srcu_torture_stats_print(struct srcu_struct *ssp, data_race(READ_ONCE(ssp->srcu_idx_max))); } +/** + * srcu_readers_active - returns true if there are readers. and false otherwise. + * @ssp: which srcu_struct to count active readers (holding srcu_read_lock). + * + * Note that this is not an atomic primitive, and can therefore suffer + * severe errors when invoked on an active srcu_struct. That said, it + * can be useful as an error check at cleanup time. + */ +static inline bool srcu_readers_active(struct srcu_struct *ssp) +{ + return READ_ONCE(ssp->srcu_lock_nesting[0]) || READ_ONCE(ssp->srcu_lock_nesting[1]); +} + #endif diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h index fd1a9270cb9a..75e54e4f963f 100644 --- a/include/linux/srcutree.h +++ b/include/linux/srcutree.h @@ -374,4 +374,28 @@ static inline void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flav __srcu_check_read_flavor(ssp, read_flavor); } +/** + * srcu_readers_active - returns true if there are readers. and false otherwise. + * @ssp: which srcu_struct to count active readers (holding srcu_read_lock). + * + * Note that this is not an atomic primitive, and can therefore suffer + * severe errors when invoked on an active srcu_struct. That said, it + * can be useful as an error check at cleanup time. + */ +static inline bool srcu_readers_active(struct srcu_struct *ssp) +{ + int cpu; + unsigned long sum = 0; + + for_each_possible_cpu(cpu) { + struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu); + + sum += atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks); + sum += atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks); + sum -= atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks); + sum -= atomic_long_read(&sdp->srcu_ctrs[1].srcu_unlocks); + } + return sum; +} + #endif diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index e1fb11e0f12c..67cb66f6f5ed 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -8,7 +8,7 @@ #include <linux/spinlock.h> #include <linux/pci.h> #include <linux/gpio/driver.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/ssb.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> @@ -671,4 +671,6 @@ int ssb_pcibios_plat_dev_init(struct pci_dev *dev); int ssb_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); #endif /* CONFIG_SSB_EMBEDDED */ +extern const struct software_node ssb_gpio_swnode; + #endif /* LINUX_SSB_H_ */ diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 97455880ac41..525cf60673fe 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -11,7 +11,7 @@ struct pt_regs; #ifdef CONFIG_ARCH_STACKWALK /** - * stack_trace_consume_fn - Callback for arch_stack_walk() + * typedef stack_trace_consume_fn - Callback for arch_stack_walk() * @cookie: Caller supplied pointer handed back by arch_stack_walk() * @addr: The stack entry address to consume * @@ -48,9 +48,9 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, * @consume_entry * @task: Pointer to a task struct, can be NULL * - * This function returns an error if it detects any unreliable + * Returns: a negative error code if it detects any unreliable * features of the stack. Otherwise it guarantees that the stack - * trace is reliable. + * trace is reliable and returns %0. * * If the task is not 'current', the caller *must* ensure the task is * inactive and its stack is pinned. diff --git a/include/linux/stat.h b/include/linux/stat.h index e3d00e7bb26d..9c5709132862 100644 --- a/include/linux/stat.h +++ b/include/linux/stat.h @@ -41,8 +41,8 @@ struct kstat { u64 ino; dev_t dev; dev_t rdev; - kuid_t uid; - kgid_t gid; + kuid_t uid; /* This is logically a vfsuid_t. */ + kgid_t gid; /* This is logically a vfsgid_t. */ loff_t size; struct timespec64 atime; struct timespec64 mtime; diff --git a/include/linux/static_call_types.h b/include/linux/static_call_types.h index cfb6ddeb292b..ac55bc966a56 100644 --- a/include/linux/static_call_types.h +++ b/include/linux/static_call_types.h @@ -25,7 +25,7 @@ #define STATIC_CALL_SITE_INIT 2UL /* init section */ #define STATIC_CALL_SITE_FLAGS 3UL -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ /* * The static call site table needs to be created by external tooling (objtool @@ -102,6 +102,6 @@ struct static_call_key { #endif /* CONFIG_HAVE_STATIC_CALL */ -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _STATIC_CALL_TYPES_H */ diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h index 01011113d226..84e7fb627ba4 100644 --- a/include/linux/stop_machine.h +++ b/include/linux/stop_machine.h @@ -2,6 +2,7 @@ #ifndef _LINUX_STOP_MACHINE #define _LINUX_STOP_MACHINE +#include <linux/bug.h> #include <linux/cpu.h> #include <linux/cpumask_types.h> #include <linux/smp.h> @@ -31,7 +32,7 @@ struct cpu_stop_work { int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg); int stop_two_cpus(unsigned int cpu1, unsigned int cpu2, cpu_stop_fn_t fn, void *arg); -bool stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, +void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, struct cpu_stop_work *work_buf); void stop_machine_park(int cpu); void stop_machine_unpark(int cpu); @@ -68,19 +69,17 @@ static void stop_one_cpu_nowait_workfn(struct work_struct *work) preempt_enable(); } -static inline bool stop_one_cpu_nowait(unsigned int cpu, +static inline void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, struct cpu_stop_work *work_buf) { - if (cpu == smp_processor_id()) { - INIT_WORK(&work_buf->work, stop_one_cpu_nowait_workfn); - work_buf->fn = fn; - work_buf->arg = arg; - schedule_work(&work_buf->work); - return true; - } - - return false; + if (WARN_ON_ONCE(cpu != smp_processor_id())) + return; + + INIT_WORK(&work_buf->work, stop_one_cpu_nowait_workfn); + work_buf->fn = fn; + work_buf->arg = arg; + schedule_work(&work_buf->work); } static inline void print_stop_info(const char *log_lvl, struct task_struct *task) { } diff --git a/include/linux/sunrpc/bc_xprt.h b/include/linux/sunrpc/bc_xprt.h index 98939cb664cf..59d0cc889beb 100644 --- a/include/linux/sunrpc/bc_xprt.h +++ b/include/linux/sunrpc/bc_xprt.h @@ -32,6 +32,7 @@ int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs); void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs); void xprt_free_bc_rqst(struct rpc_rqst *req); unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt); +void xprt_svc_shutdown_bc(struct rpc_xprt *xprt); void xprt_svc_destroy_nullify_bc(struct rpc_xprt *xprt, struct svc_serv **serv); /* @@ -71,6 +72,10 @@ static inline void xprt_free_bc_request(struct rpc_rqst *req) { } +static inline void xprt_svc_shutdown_bc(struct rpc_xprt *xprt) +{ +} + static inline void xprt_svc_destroy_nullify_bc(struct rpc_xprt *xprt, struct svc_serv **serv) { svc_destroy(serv); diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index f8b406b0a1af..3c2b8c355ab3 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -190,6 +190,7 @@ int rpc_switch_client_transport(struct rpc_clnt *, const struct rpc_timeout *); void rpc_shutdown_client(struct rpc_clnt *); +void rpc_hold_client(struct rpc_clnt *); void rpc_release_client(struct rpc_clnt *); void rpc_task_release_transport(struct rpc_task *); void rpc_task_release_client(struct rpc_task *); diff --git a/include/linux/sunrpc/stats.h b/include/linux/sunrpc/stats.h index 3ce1550d1beb..087ade905e29 100644 --- a/include/linux/sunrpc/stats.h +++ b/include/linux/sunrpc/stats.h @@ -37,9 +37,15 @@ struct svc_stat { rpcbadfmt, rpcbadauth, rpcbadclnt; + + /* Per-version per-procedure call counts (per-cpu, per-netns) */ + unsigned long __percpu **vs_count; }; struct net; +int svc_stat_alloc_counts(struct svc_stat *statp); +void svc_stat_free_counts(struct svc_stat *statp); + #ifdef CONFIG_PROC_FS int rpc_proc_init(struct net *); void rpc_proc_exit(struct net *); diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 4be6204f6630..2db1b9ec5658 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -85,7 +85,6 @@ struct svc_serv { char * sv_name; /* service name */ - unsigned int sv_nrpools; /* number of thread pools */ bool sv_is_pooled; /* is this a pooled service? */ struct svc_pool * sv_pools; /* array of thread pools */ int (*sv_threadfn)(void *data); @@ -408,7 +407,6 @@ struct svc_version { u32 vs_vers; /* version number */ u32 vs_nproc; /* number of procedures */ const struct svc_procedure *vs_proc; /* per-procedure info */ - unsigned long __percpu *vs_count; /* call counts */ u32 vs_xdrsize; /* xdrsize needed for this version */ /* Don't register with rpcbind */ @@ -469,6 +467,7 @@ int svc_set_pool_threads(struct svc_serv *serv, struct svc_pool *pool, unsigned int min_threads, unsigned int max_threads); int svc_set_num_threads(struct svc_serv *serv, unsigned int min_threads, unsigned int nrservs); +unsigned int svc_serv_maxthreads(const struct svc_serv *serv); int svc_pool_stats_open(struct svc_info *si, struct file *file); void svc_process(struct svc_rqst *rqstp); void svc_process_bc(struct rpc_rqst *req, struct svc_rqst *rqstp); @@ -479,6 +478,7 @@ void svc_wake_up(struct svc_serv *); void svc_reserve(struct svc_rqst *rqstp, int space); void svc_pool_wake_idle_thread(struct svc_pool *pool); struct svc_pool *svc_pool_for_cpu(struct svc_serv *serv); +unsigned int svc_serv_nrpools(const struct svc_serv *serv); char * svc_print_addr(struct svc_rqst *, char *, size_t); const char * svc_proc_name(const struct svc_rqst *rqstp); int svc_encode_result_payload(struct svc_rqst *rqstp, diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 5aadb47b3b0e..76aa5ec4ab40 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -77,8 +77,8 @@ struct svcxprt_rdma { struct rdma_cm_id *sc_cm_id; /* RDMA connection id */ struct list_head sc_accept_q; /* Conn. waiting accept */ struct rpcrdma_notification sc_rn; /* removal notification */ - int sc_ord; /* RDMA read limit */ - int sc_max_send_sges; + u32 sc_ord; /* RDMA read limit */ + unsigned int sc_max_send_sges; bool sc_snd_w_inv; /* OK to use Send With Invalidate */ atomic_t sc_sq_avail; /* SQEs ready to be consumed */ diff --git a/include/linux/sunrpc/svc_rdma_pcl.h b/include/linux/sunrpc/svc_rdma_pcl.h index 7516ad0fae80..6346d8cf2587 100644 --- a/include/linux/sunrpc/svc_rdma_pcl.h +++ b/include/linux/sunrpc/svc_rdma_pcl.h @@ -97,7 +97,7 @@ pcl_next_chunk(const struct svc_rdma_pcl *pcl, struct svc_rdma_chunk *chunk) */ #define pcl_for_each_segment(pos, chunk) \ for (pos = &(chunk)->ch_segments[0]; \ - pos <= &(chunk)->ch_segments[(chunk)->ch_segcount - 1]; \ + pos < &(chunk)->ch_segments[(chunk)->ch_segcount]; \ pos++) /** @@ -119,6 +119,8 @@ extern bool pcl_alloc_call(struct svc_rdma_recv_ctxt *rctxt, __be32 *p); extern bool pcl_alloc_read(struct svc_rdma_recv_ctxt *rctxt, __be32 *p); extern bool pcl_alloc_write(struct svc_rdma_recv_ctxt *rctxt, struct svc_rdma_pcl *pcl, __be32 *p); +extern bool pcl_check_read_chunk_positions(struct svc_rdma_recv_ctxt *rctxt, + unsigned int inline_len); extern int pcl_process_nonpayloads(const struct svc_rdma_pcl *pcl, const struct xdr_buf *xdr, int (*actor)(const struct xdr_buf *, diff --git a/include/linux/sunrpc/xdrgen/_builtins.h b/include/linux/sunrpc/xdrgen/_builtins.h index a723fb1da9c8..c9033eb1c829 100644 --- a/include/linux/sunrpc/xdrgen/_builtins.h +++ b/include/linux/sunrpc/xdrgen/_builtins.h @@ -296,4 +296,36 @@ xdrgen_encode_opaque(struct xdr_stream *xdr, opaque val) return true; } +struct svc_rqst; + +/** + * xdrgen_svc_decode_void - Decode a void argument + * @rqstp: RPC transaction context + * @xdr: source XDR data stream + * + * Return values: + * %true: procedure arguments decoded successfully + * %false: decode failed + */ +static inline bool +xdrgen_svc_decode_void(struct svc_rqst *rqstp, struct xdr_stream *xdr) +{ + return xdrgen_decode_void(xdr); +} + +/** + * xdrgen_svc_encode_void - Encode a void result + * @rqstp: RPC transaction context + * @xdr: target XDR data stream + * + * Return values: + * %true: procedure results encoded successfully + * %false: encode failed + */ +static inline bool +xdrgen_svc_encode_void(struct svc_rqst *rqstp, struct xdr_stream *xdr) +{ + return xdrgen_encode_void(xdr); +} + #endif /* _SUNRPC_XDRGEN__BUILTINS_H_ */ diff --git a/include/linux/sunrpc/xdrgen/_defs.h b/include/linux/sunrpc/xdrgen/_defs.h index 20c7270aa64d..8f3776ef3229 100644 --- a/include/linux/sunrpc/xdrgen/_defs.h +++ b/include/linux/sunrpc/xdrgen/_defs.h @@ -25,6 +25,8 @@ typedef struct { #define XDR_void (0) #define XDR_bool (1) +#define XDR_short (1) +#define XDR_unsigned_short (1) #define XDR_int (1) #define XDR_unsigned_int (1) #define XDR_long (1) diff --git a/include/linux/sunrpc/xdrgen/nfs4_1.h b/include/linux/sunrpc/xdrgen/nfs4_1.h index 4ac54bdbd335..bd3289a1d66a 100644 --- a/include/linux/sunrpc/xdrgen/nfs4_1.h +++ b/include/linux/sunrpc/xdrgen/nfs4_1.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */ -/* XDR specification modification time: Thu Jan 8 23:12:07 2026 */ +/* XDR specification modification time: Tue Jun 30 11:57:21 2026 */ #ifndef _LINUX_XDRGEN_NFS4_1_DEF_H #define _LINUX_XDRGEN_NFS4_1_DEF_H @@ -9,15 +9,149 @@ #include <linux/types.h> #include <linux/sunrpc/xdrgen/_defs.h> -typedef s64 int64_t; +typedef s32 int32_t; typedef u32 uint32_t; +typedef s64 int64_t; + +typedef u64 uint64_t; + +enum { NFS4_VERIFIER_SIZE = 8 }; + +enum { NFS4_FHSIZE = 128 }; + +enum nfsstat4 { + NFS4_OK = 0, + NFS4ERR_PERM = 1, + NFS4ERR_NOENT = 2, + NFS4ERR_IO = 5, + NFS4ERR_NXIO = 6, + NFS4ERR_ACCESS = 13, + NFS4ERR_EXIST = 17, + NFS4ERR_XDEV = 18, + NFS4ERR_NOTDIR = 20, + NFS4ERR_ISDIR = 21, + NFS4ERR_INVAL = 22, + NFS4ERR_FBIG = 27, + NFS4ERR_NOSPC = 28, + NFS4ERR_ROFS = 30, + NFS4ERR_MLINK = 31, + NFS4ERR_NAMETOOLONG = 63, + NFS4ERR_NOTEMPTY = 66, + NFS4ERR_DQUOT = 69, + NFS4ERR_STALE = 70, + NFS4ERR_BADHANDLE = 10001, + NFS4ERR_BAD_COOKIE = 10003, + NFS4ERR_NOTSUPP = 10004, + NFS4ERR_TOOSMALL = 10005, + NFS4ERR_SERVERFAULT = 10006, + NFS4ERR_BADTYPE = 10007, + NFS4ERR_DELAY = 10008, + NFS4ERR_SAME = 10009, + NFS4ERR_DENIED = 10010, + NFS4ERR_EXPIRED = 10011, + NFS4ERR_LOCKED = 10012, + NFS4ERR_GRACE = 10013, + NFS4ERR_FHEXPIRED = 10014, + NFS4ERR_SHARE_DENIED = 10015, + NFS4ERR_WRONGSEC = 10016, + NFS4ERR_CLID_INUSE = 10017, + NFS4ERR_RESOURCE = 10018, + NFS4ERR_MOVED = 10019, + NFS4ERR_NOFILEHANDLE = 10020, + NFS4ERR_MINOR_VERS_MISMATCH = 10021, + NFS4ERR_STALE_CLIENTID = 10022, + NFS4ERR_STALE_STATEID = 10023, + NFS4ERR_OLD_STATEID = 10024, + NFS4ERR_BAD_STATEID = 10025, + NFS4ERR_BAD_SEQID = 10026, + NFS4ERR_NOT_SAME = 10027, + NFS4ERR_LOCK_RANGE = 10028, + NFS4ERR_SYMLINK = 10029, + NFS4ERR_RESTOREFH = 10030, + NFS4ERR_LEASE_MOVED = 10031, + NFS4ERR_ATTRNOTSUPP = 10032, + NFS4ERR_NO_GRACE = 10033, + NFS4ERR_RECLAIM_BAD = 10034, + NFS4ERR_RECLAIM_CONFLICT = 10035, + NFS4ERR_BADXDR = 10036, + NFS4ERR_LOCKS_HELD = 10037, + NFS4ERR_OPENMODE = 10038, + NFS4ERR_BADOWNER = 10039, + NFS4ERR_BADCHAR = 10040, + NFS4ERR_BADNAME = 10041, + NFS4ERR_BAD_RANGE = 10042, + NFS4ERR_LOCK_NOTSUPP = 10043, + NFS4ERR_OP_ILLEGAL = 10044, + NFS4ERR_DEADLOCK = 10045, + NFS4ERR_FILE_OPEN = 10046, + NFS4ERR_ADMIN_REVOKED = 10047, + NFS4ERR_CB_PATH_DOWN = 10048, + NFS4ERR_BADIOMODE = 10049, + NFS4ERR_BADLAYOUT = 10050, + NFS4ERR_BAD_SESSION_DIGEST = 10051, + NFS4ERR_BADSESSION = 10052, + NFS4ERR_BADSLOT = 10053, + NFS4ERR_COMPLETE_ALREADY = 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION = 10055, + NFS4ERR_DELEG_ALREADY_WANTED = 10056, + NFS4ERR_BACK_CHAN_BUSY = 10057, + NFS4ERR_LAYOUTTRYLATER = 10058, + NFS4ERR_LAYOUTUNAVAILABLE = 10059, + NFS4ERR_NOMATCHING_LAYOUT = 10060, + NFS4ERR_RECALLCONFLICT = 10061, + NFS4ERR_UNKNOWN_LAYOUTTYPE = 10062, + NFS4ERR_SEQ_MISORDERED = 10063, + NFS4ERR_SEQUENCE_POS = 10064, + NFS4ERR_REQ_TOO_BIG = 10065, + NFS4ERR_REP_TOO_BIG = 10066, + NFS4ERR_REP_TOO_BIG_TO_CACHE = 10067, + NFS4ERR_RETRY_UNCACHED_REP = 10068, + NFS4ERR_UNSAFE_COMPOUND = 10069, + NFS4ERR_TOO_MANY_OPS = 10070, + NFS4ERR_OP_NOT_IN_SESSION = 10071, + NFS4ERR_HASH_ALG_UNSUPP = 10072, + NFS4ERR_CLIENTID_BUSY = 10074, + NFS4ERR_PNFS_IO_HOLE = 10075, + NFS4ERR_SEQ_FALSE_RETRY = 10076, + NFS4ERR_BAD_HIGH_SLOT = 10077, + NFS4ERR_DEADSESSION = 10078, + NFS4ERR_ENCR_ALG_UNSUPP = 10079, + NFS4ERR_PNFS_NO_LAYOUT = 10080, + NFS4ERR_NOT_ONLY_OP = 10081, + NFS4ERR_WRONG_CRED = 10082, + NFS4ERR_WRONG_TYPE = 10083, + NFS4ERR_DIRDELEG_UNAVAIL = 10084, + NFS4ERR_REJECT_DELEG = 10085, + NFS4ERR_RETURNCONFLICT = 10086, + NFS4ERR_DELEG_REVOKED = 10087, + NFS4ERR_PARTNER_NOTSUPP = 10088, + NFS4ERR_PARTNER_NO_AUTH = 10089, + NFS4ERR_UNION_NOTSUPP = 10090, + NFS4ERR_OFFLOAD_DENIED = 10091, + NFS4ERR_WRONG_LFS = 10092, + NFS4ERR_BADLABEL = 10093, + NFS4ERR_OFFLOAD_NO_REQS = 10094, + NFS4ERR_NOXATTR = 10095, + NFS4ERR_XATTR2BIG = 10096, +}; + +typedef enum nfsstat4 nfsstat4; + +typedef opaque attrlist4; + typedef struct { u32 count; uint32_t *element; } bitmap4; +typedef u8 verifier4[NFS4_VERIFIER_SIZE]; + +typedef uint64_t nfs_cookie4; + +typedef opaque nfs_fh4; + typedef opaque utf8string; typedef utf8string utf8str_cis; @@ -26,11 +160,30 @@ typedef utf8string utf8str_cs; typedef utf8string utf8str_mixed; +typedef utf8str_cs component4; + +typedef utf8str_cs linktext4; + +typedef struct { + u32 count; + component4 *element; +} pathname4; + struct nfstime4 { int64_t seconds; uint32_t nseconds; }; +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; + +struct stateid4 { + uint32_t seqid; + u8 other[12]; +}; + typedef bool fattr4_offline; enum { FATTR4_OFFLINE = 83 }; @@ -216,11 +369,109 @@ enum { FATTR4_POSIX_DEFAULT_ACL = 91 }; enum { FATTR4_POSIX_ACCESS_ACL = 92 }; -#define NFS4_int64_t_sz \ - (XDR_hyper) +enum notify_type4 { + NOTIFY4_CHANGE_CHILD_ATTRS = 0, + NOTIFY4_CHANGE_DIR_ATTRS = 1, + NOTIFY4_REMOVE_ENTRY = 2, + NOTIFY4_ADD_ENTRY = 3, + NOTIFY4_RENAME_ENTRY = 4, + NOTIFY4_CHANGE_COOKIE_VERIFIER = 5, + NOTIFY4_GFLAG_EXTEND = 6, + NOTIFY4_AUFLAG_VALID = 7, + NOTIFY4_AUFLAG_USER = 8, + NOTIFY4_AUFLAG_GROUP = 9, + NOTIFY4_AUFLAG_OTHER = 10, + NOTIFY4_CHANGE_AUTH = 11, + NOTIFY4_CFLAG_ORDER = 12, + NOTIFY4_AUFLAG_GANOW = 13, + NOTIFY4_AUFLAG_GALATER = 14, + NOTIFY4_CHANGE_GA = 15, + NOTIFY4_CHANGE_AMASK = 16, +}; + +typedef enum notify_type4 notify_type4; + +struct notify_entry4 { + component4 ne_file; + struct fattr4 ne_attrs; +}; + +struct prev_entry4 { + struct notify_entry4 pe_prev_entry; + nfs_cookie4 pe_prev_entry_cookie; +}; + +struct notify_remove4 { + struct notify_entry4 nrm_old_entry; + nfs_cookie4 nrm_old_entry_cookie; +}; + +struct notify_add4 { + struct { + u32 count; + struct notify_remove4 *element; + } nad_old_entry; + struct notify_entry4 nad_new_entry; + struct { + u32 count; + nfs_cookie4 *element; + } nad_new_entry_cookie; + struct { + u32 count; + struct prev_entry4 *element; + } nad_prev_entry; + bool nad_last_entry; +}; + +struct notify_attr4 { + struct notify_entry4 na_changed_entry; +}; + +struct notify_rename4 { + struct notify_remove4 nrn_old_entry; + struct notify_add4 nrn_new_entry; +}; + +struct notify_verifier4 { + verifier4 nv_old_cookieverf; + verifier4 nv_new_cookieverf; +}; + +typedef opaque notifylist4; + +struct notify4 { + bitmap4 notify_mask; + notifylist4 notify_vals; +}; + +struct CB_NOTIFY4args { + struct stateid4 cna_stateid; + nfs_fh4 cna_fh; + struct { + u32 count; + struct notify4 *element; + } cna_changes; +}; + +struct CB_NOTIFY4res { + nfsstat4 cnr_status; +}; + +#define NFS4_int32_t_sz \ + (XDR_int) #define NFS4_uint32_t_sz \ (XDR_unsigned_int) +#define NFS4_int64_t_sz \ + (XDR_hyper) +#define NFS4_uint64_t_sz \ + (XDR_unsigned_hyper) +#define NFS4_nfsstat4_sz (XDR_int) +#define NFS4_attrlist4_sz (XDR_unsigned_int) #define NFS4_bitmap4_sz (XDR_unsigned_int) +#define NFS4_verifier4_sz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) +#define NFS4_nfs_cookie4_sz \ + (NFS4_uint64_t_sz) +#define NFS4_nfs_fh4_sz (XDR_unsigned_int + XDR_QUADLEN(NFS4_FHSIZE)) #define NFS4_utf8string_sz (XDR_unsigned_int) #define NFS4_utf8str_cis_sz \ (NFS4_utf8string_sz) @@ -228,8 +479,17 @@ enum { FATTR4_POSIX_ACCESS_ACL = 92 }; (NFS4_utf8string_sz) #define NFS4_utf8str_mixed_sz \ (NFS4_utf8string_sz) +#define NFS4_component4_sz \ + (NFS4_utf8str_cs_sz) +#define NFS4_linktext4_sz \ + (NFS4_utf8str_cs_sz) +#define NFS4_pathname4_sz (XDR_unsigned_int) #define NFS4_nfstime4_sz \ (NFS4_int64_t_sz + NFS4_uint32_t_sz) +#define NFS4_fattr4_sz \ + (NFS4_bitmap4_sz + NFS4_attrlist4_sz) +#define NFS4_stateid4_sz \ + (NFS4_uint32_t_sz + XDR_QUADLEN(12)) #define NFS4_fattr4_offline_sz \ (XDR_bool) #define NFS4_open_arguments4_sz \ @@ -259,5 +519,27 @@ enum { FATTR4_POSIX_ACCESS_ACL = 92 }; (NFS4_aclscope4_sz) #define NFS4_fattr4_posix_default_acl_sz (XDR_unsigned_int) #define NFS4_fattr4_posix_access_acl_sz (XDR_unsigned_int) +#define NFS4_notify_type4_sz (XDR_int) +#define NFS4_notify_entry4_sz \ + (NFS4_component4_sz + NFS4_fattr4_sz) +#define NFS4_prev_entry4_sz \ + (NFS4_notify_entry4_sz + NFS4_nfs_cookie4_sz) +#define NFS4_notify_remove4_sz \ + (NFS4_notify_entry4_sz + NFS4_nfs_cookie4_sz) +#define NFS4_notify_add4_sz \ + (XDR_unsigned_int + (1 * (NFS4_notify_remove4_sz)) + NFS4_notify_entry4_sz + XDR_unsigned_int + (1 * (NFS4_nfs_cookie4_sz)) + XDR_unsigned_int + (1 * (NFS4_prev_entry4_sz)) + XDR_bool) +#define NFS4_notify_attr4_sz \ + (NFS4_notify_entry4_sz) +#define NFS4_notify_rename4_sz \ + (NFS4_notify_remove4_sz + NFS4_notify_add4_sz) +#define NFS4_notify_verifier4_sz \ + (NFS4_verifier4_sz + NFS4_verifier4_sz) +#define NFS4_notifylist4_sz (XDR_unsigned_int) +#define NFS4_notify4_sz \ + (NFS4_bitmap4_sz + NFS4_notifylist4_sz) +#define NFS4_CB_NOTIFY4args_sz \ + (NFS4_stateid4_sz + NFS4_nfs_fh4_sz + XDR_unsigned_int) +#define NFS4_CB_NOTIFY4res_sz \ + (NFS4_nfsstat4_sz) #endif /* _LINUX_XDRGEN_NFS4_1_DEF_H */ diff --git a/include/linux/sunrpc/xdrgen/nlm3.h b/include/linux/sunrpc/xdrgen/nlm3.h index 897e7d91807c..0fc627031d8a 100644 --- a/include/linux/sunrpc/xdrgen/nlm3.h +++ b/include/linux/sunrpc/xdrgen/nlm3.h @@ -1,7 +1,7 @@ /* 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 */ +/* XDR specification modification time: Mon Jun 29 20:42:29 2026 */ #ifndef _LINUX_XDRGEN_NLM3_DEF_H #define _LINUX_XDRGEN_NLM3_DEF_H diff --git a/include/linux/sunrpc/xdrgen/nlm4.h b/include/linux/sunrpc/xdrgen/nlm4.h index e95e8f105624..77860a3d1c1e 100644 --- a/include/linux/sunrpc/xdrgen/nlm4.h +++ b/include/linux/sunrpc/xdrgen/nlm4.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Generated by xdrgen. Manual edits will be lost. */ /* XDR specification file: ../../Documentation/sunrpc/xdr/nlm4.x */ -/* XDR specification modification time: Thu Dec 25 13:10:19 2025 */ +/* XDR specification modification time: Mon Jun 29 20:42:29 2026 */ #ifndef _LINUX_XDRGEN_NLM4_DEF_H #define _LINUX_XDRGEN_NLM4_DEF_H diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h index 8cd8c38cf3f3..ed6b271e5a73 100644 --- a/include/linux/surface_aggregator/device.h +++ b/include/linux/surface_aggregator/device.h @@ -14,7 +14,7 @@ #define _LINUX_SURFACE_AGGREGATOR_DEVICE_H #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/ssam.h> #include <linux/property.h> #include <linux/types.h> diff --git a/include/linux/swap.h b/include/linux/swap.h index 8f0f68e245ba..5658a1634b85 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -16,10 +16,6 @@ #include <uapi/linux/mempolicy.h> #include <asm/page.h> -struct notifier_block; - -struct bio; - #define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */ #define SWAP_FLAG_PRIO_MASK 0x7fff #define SWAP_FLAG_DISCARD 0x10000 /* enable discard for swap */ @@ -29,7 +25,6 @@ struct bio; #define SWAP_FLAGS_VALID (SWAP_FLAG_PRIO_MASK | SWAP_FLAG_PREFER | \ SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | \ SWAP_FLAG_DISCARD_PAGES) -#define SWAP_BATCH 64 static inline int current_is_kswapd(void) { @@ -175,7 +170,6 @@ static inline void mm_account_reclaimed_pages(unsigned long pages) struct address_space; struct sysinfo; -struct writeback_control; struct zone; /* @@ -208,7 +202,6 @@ enum { SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */ SWP_BLKDEV = (1 << 6), /* its a block device */ SWP_ACTIVATED = (1 << 7), /* set after swap_activate success */ - SWP_FS_OPS = (1 << 8), /* swapfile operations go through fs */ SWP_AREA_DISCARD = (1 << 9), /* single-time swap area discards */ SWP_PAGE_DISCARD = (1 << 10), /* freed swap page-cluster discards */ SWP_STABLE_WRITES = (1 << 11), /* no overwrite PG_writeback pages */ @@ -282,6 +275,7 @@ struct swap_info_struct { struct work_struct reclaim_work; /* reclaim worker */ struct list_head discard_clusters; /* discard clusters list */ struct plist_node avail_list; /* entry in swap_avail_head */ + const struct swap_ops *ops; }; static inline swp_entry_t page_swap_entry(struct page *page) @@ -293,39 +287,27 @@ static inline swp_entry_t page_swap_entry(struct page *page) return entry; } -/* linux/mm/workingset.c */ -bool workingset_test_recent(void *shadow, bool file, bool *workingset, - bool flush); -void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages); -void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg); -void workingset_refault(struct folio *folio, void *shadow); -void workingset_activation(struct folio *folio); - /* linux/mm/page_alloc.c */ extern unsigned long totalreserve_pages; /* Definition of global_zone_page_state not available yet */ #define nr_free_pages() global_zone_page_state(NR_FREE_PAGES) +/* linux/mm/folio.c */ +void folio_add_lru(struct folio *folio); +void folio_mark_accessed(struct folio *folio); +void lru_add_drain_all(void); -/* linux/mm/swap.c */ -void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file, - unsigned int nr_io, unsigned int nr_rotated); -void lru_note_cost_refault(struct folio *); -void folio_add_lru(struct folio *); -void folio_add_lru_vma(struct folio *, struct vm_area_struct *); -void mark_page_accessed(struct page *); -void folio_mark_accessed(struct folio *); +enum lru_cache_drained { + LRU_CACHE_NOT_DRAINED, + LRU_CACHE_DRAINED, + LRU_CACHE_DRAINED_ALL, +}; +void lru_cache_drain_for_folio(const struct folio *folio, + unsigned int extra_refs, enum lru_cache_drained *drained); -static inline bool folio_may_be_lru_cached(struct folio *folio) -{ - /* - * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting. - * Holding small numbers of low-order mTHP folios in per-CPU LRU cache - * will be sensible, but nobody has implemented and tested that yet. - */ - return !folio_test_large(folio); -} +/* linux/mm/folio-compat.c */ +void mark_page_accessed(struct page *page); extern atomic_t lru_disable_count; @@ -334,45 +316,7 @@ static inline bool lru_cache_disabled(void) return atomic_read(&lru_disable_count); } -static inline void lru_cache_enable(void) -{ - atomic_dec(&lru_disable_count); -} - -extern void lru_cache_disable(void); -extern void lru_add_drain(void); -extern void lru_add_drain_cpu(int cpu); -extern void lru_add_drain_cpu_zone(struct zone *zone); -extern void lru_add_drain_all(void); -void folio_deactivate(struct folio *folio); -void folio_mark_lazyfree(struct folio *folio); -extern void swap_setup(void); - -/* linux/mm/vmscan.c */ -extern unsigned long zone_reclaimable_pages(struct zone *zone); -extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, - gfp_t gfp_mask, nodemask_t *mask); -unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx); - -#define MEMCG_RECLAIM_MAY_SWAP (1 << 1) -#define MEMCG_RECLAIM_PROACTIVE (1 << 2) -#define MIN_SWAPPINESS 0 -#define MAX_SWAPPINESS 200 - -/* Just reclaim from anon folios in proactive memory reclaim */ -#define SWAPPINESS_ANON_ONLY (MAX_SWAPPINESS + 1) - -extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg, - unsigned long nr_pages, - gfp_t gfp_mask, - unsigned int reclaim_options, - int *swappiness); -extern unsigned long mem_cgroup_shrink_node(struct mem_cgroup *mem, - gfp_t gfp_mask, bool noswap, - pg_data_t *pgdat, - unsigned long *nr_scanned); extern unsigned long shrink_all_memory(unsigned long nr_pages); -extern int vm_swappiness; long remove_mapping(struct address_space *mapping, struct folio *folio); #if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) @@ -391,18 +335,12 @@ static inline void reclaim_unregister_node(struct node *node) } #endif /* CONFIG_SYSFS && CONFIG_NUMA */ -#ifdef CONFIG_NUMA -extern int sysctl_min_unmapped_ratio; -extern int sysctl_min_slab_ratio; -#endif - void check_move_unevictable_folios(struct folio_batch *fbatch); extern void __meminit kswapd_run(int nid); extern void __meminit kswapd_stop(int nid); #ifdef CONFIG_SWAP - int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page, unsigned long nr_pages, sector_t start_block); int generic_swapfile_activate(struct swap_info_struct *, struct file *, @@ -442,7 +380,6 @@ extern sector_t swapdev_block(int, pgoff_t); extern int __swap_count(swp_entry_t entry); extern bool swap_entry_swapped(struct swap_info_struct *si, swp_entry_t entry); extern int swp_swapcount(swp_entry_t entry); -struct backing_dev_info; extern struct swap_info_struct *get_swap_device(swp_entry_t entry); sector_t swap_folio_sector(struct folio *folio); @@ -537,25 +474,7 @@ static inline int add_swap_extent(struct swap_info_struct *sis, } #endif /* CONFIG_SWAP */ #ifdef CONFIG_MEMCG -static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg) -{ - /* Cgroup2 doesn't have per-cgroup swappiness */ - if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) - return READ_ONCE(vm_swappiness); - - /* root ? */ - if (mem_cgroup_disabled() || mem_cgroup_is_root(memcg)) - return READ_ONCE(vm_swappiness); - - return READ_ONCE(memcg->swappiness); -} - void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid); -#else -static inline int mem_cgroup_swappiness(struct mem_cgroup *mem) -{ - return READ_ONCE(vm_swappiness); -} #endif #if defined(CONFIG_SWAP) && defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP) diff --git a/include/linux/swap_ops.h b/include/linux/swap_ops.h new file mode 100644 index 000000000000..57ac6c703f68 --- /dev/null +++ b/include/linux/swap_ops.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _MM_SWAP_OPS_H +#define _MM_SWAP_OPS_H + +#include <linux/swap.h> /* for SWAP_CLUSTER_MAX */ + +struct swap_iocb { + union { + struct kiocb iocb; + struct bio bio; + }; + struct bio_vec bvecs[SWAP_CLUSTER_MAX]; + int nr_bvecs; + int len; +}; + +struct swap_io_ctx { + struct swap_iocb *sio; + struct swap_info_struct *sis; +}; + +/* + * SWAP_OPS_F_REQUIRE_NOFS: + * When set, all reclaim operations must operated as GFS_NOFS and not + * just GFP_NOIO, as GFP_NOIO allocations could recourse into the + * file system backing this swap file. + */ +#define SWAP_OPS_F_REQUIRE_NOFS (1U << 0) + +struct swap_ops { + unsigned int flags; + + bool (*can_merge)(struct folio *folio, struct folio *prev_folio, + size_t prev_folio_size, int rw); + void (*submit_write)(struct swap_io_ctx *ctx); + void (*submit_read)(struct swap_io_ctx *ctx); +}; + +void swap_fs_prepare_rw(struct swap_io_ctx *ctx, int rw, struct iov_iter *iter); +bool swap_fs_can_merge(struct folio *folio, struct folio *prev_folio, + size_t prev_folio_size, int rw); +int swap_fs_activate(struct swap_info_struct *sis, const struct swap_ops *ops); + +#endif /* _MM_SWAP_OPS_H */ diff --git a/include/linux/swapops.h b/include/linux/swapops.h index 8cfc966eae48..e7d0d529f3e0 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -5,6 +5,7 @@ #include <linux/radix-tree.h> #include <linux/bug.h> #include <linux/mm_types.h> +#include <linux/swap.h> #ifdef CONFIG_MMU @@ -73,8 +74,8 @@ static inline pte_t pte_swp_clear_flags(pte_t pte) pte = pte_swp_clear_exclusive(pte); if (pte_swp_soft_dirty(pte)) pte = pte_swp_clear_soft_dirty(pte); - if (pte_swp_uffd_wp(pte)) - pte = pte_swp_clear_uffd_wp(pte); + if (pte_swp_uffd(pte)) + pte = pte_swp_clear_uffd(pte); return pte; } @@ -321,12 +322,12 @@ static inline swp_entry_t make_guard_swp_entry(void) struct page_vma_mapped_walk; -#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +#ifdef CONFIG_ARCH_HAS_PMD_SOFTLEAVES extern int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, struct page *page); -extern void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, - struct page *new); +void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, + struct folio *folio); extern void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd); @@ -338,7 +339,7 @@ static inline pmd_t swp_entry_to_pmd(swp_entry_t entry) return __swp_entry_to_pmd(arch_entry); } -#else /* CONFIG_ARCH_ENABLE_THP_MIGRATION */ +#else /* CONFIG_ARCH_HAS_PMD_SOFTLEAVES */ static inline int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, struct page *page) { @@ -346,7 +347,7 @@ static inline int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, } static inline void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, - struct page *new) + struct folio *folio) { BUILD_BUG(); } @@ -358,7 +359,7 @@ static inline pmd_t swp_entry_to_pmd(swp_entry_t entry) return __pmd(0); } -#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */ +#endif /* CONFIG_ARCH_HAS_PMD_SOFTLEAVES */ #endif /* CONFIG_MMU */ #endif /* _LINUX_SWAPOPS_H */ diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 3dae0f592063..2a421241b980 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -15,8 +15,7 @@ struct page; struct scatterlist; #define SWIOTLB_VERBOSE (1 << 0) /* verbose initialization */ -#define SWIOTLB_FORCE (1 << 1) /* force bounce buffering */ -#define SWIOTLB_ANY (1 << 2) /* allow any memory for the buffer */ +#define SWIOTLB_ANY (1 << 1) /* allow any memory for the buffer */ /* * Maximum allowable number of contiguous slabs to map, @@ -32,8 +31,12 @@ struct scatterlist; #define IO_TLB_SHIFT 11 #define IO_TLB_SIZE (1 << IO_TLB_SHIFT) -/* default to 64MB */ -#define IO_TLB_DEFAULT_SIZE (64UL<<20) +/* compile-time default; overridable via CONFIG_SWIOTLB_DEFAULT_SIZE_MB */ +#ifdef CONFIG_SWIOTLB +#define IO_TLB_DEFAULT_SIZE ((unsigned long)CONFIG_SWIOTLB_DEFAULT_SIZE_MB << 20) +#else +#define IO_TLB_DEFAULT_SIZE (64UL << 20) +#endif unsigned long swiotlb_size_or_default(void); void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags, @@ -64,8 +67,9 @@ extern void __init swiotlb_update_mem_attributes(void); * @areas: Array of memory area descriptors. * @slots: Array of slot descriptors. * @node: Member of the IO TLB memory pool list. - * @rcu: RCU head for swiotlb_dyn_free(). + * @dyn_free: RCU work item used to free the pool from process context. * @transient: %true if transient memory pool. + * @cc_shared: %true if the pool memory is shared for confidential computing. */ struct io_tlb_pool { phys_addr_t start; @@ -79,8 +83,9 @@ struct io_tlb_pool { struct io_tlb_slot *slots; #ifdef CONFIG_SWIOTLB_DYNAMIC struct list_head node; - struct rcu_head rcu; + struct rcu_work dyn_free; bool transient; + bool cc_shared; #endif }; @@ -92,16 +97,17 @@ struct io_tlb_pool { * @debugfs: The dentry to debugfs. * @force_bounce: %true if swiotlb bouncing is forced * @for_alloc: %true if the pool is used for memory allocation + * @cc_shared: %true if the pool memory is shared for confidential computing. * @can_grow: %true if more pools can be allocated dynamically. * @phys_limit: Maximum allowed physical address. * @lock: Lock to synchronize changes to the list. * @pools: List of IO TLB memory pool descriptors (if dynamic). * @dyn_alloc: Dynamic IO TLB pool allocation work. * @total_used: The total number of slots in the pool that are currently used - * across all areas. Used only for calculating used_hiwater in - * debugfs. - * @used_hiwater: The high water mark for total_used. Used only for reporting - * in debugfs. + * across all areas. Used only for calculating used_hiwater via boot + * parameter swiotlb=track_hiwater and exposed via debugfs. + * @used_hiwater: The high water mark for total_used. Can be enabled at boot + * time via swiotlb=track_hiwater and exposed via debugfs. * @transient_nslabs: The total number of slots in all transient pools that * are currently used across all areas. */ @@ -111,6 +117,7 @@ struct io_tlb_mem { struct dentry *debugfs; bool force_bounce; bool for_alloc; + bool cc_shared; #ifdef CONFIG_SWIOTLB_DYNAMIC bool can_grow; u64 phys_limit; @@ -238,7 +245,7 @@ static inline phys_addr_t default_swiotlb_limit(void) phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, phys_addr_t phys, size_t mapping_size, unsigned int alloc_aligned_mask, - enum dma_data_direction dir, unsigned long attrs); + enum dma_data_direction dir, unsigned long *attrs); dma_addr_t swiotlb_map(struct device *dev, phys_addr_t phys, size_t size, enum dma_data_direction dir, unsigned long attrs); @@ -282,15 +289,19 @@ static inline void swiotlb_sync_single_for_cpu(struct device *dev, extern void swiotlb_print_info(void); #ifdef CONFIG_DMA_RESTRICTED_POOL -struct page *swiotlb_alloc(struct device *dev, size_t size); +struct page *swiotlb_alloc(struct device *dev, size_t size, + unsigned long attrs); bool swiotlb_free(struct device *dev, struct page *page, size_t size); +void swiotlb_free_from_pool(struct device *dev, + phys_addr_t tlb_addr, struct io_tlb_pool *pool); static inline bool is_swiotlb_for_alloc(struct device *dev) { return dev->dma_io_tlb_mem->for_alloc; } #else -static inline struct page *swiotlb_alloc(struct device *dev, size_t size) +static inline struct page *swiotlb_alloc(struct device *dev, size_t size, + unsigned long attrs) { return NULL; } @@ -299,6 +310,10 @@ static inline bool swiotlb_free(struct device *dev, struct page *page, { return false; } +static inline void swiotlb_free_from_pool(struct device *dev, + phys_addr_t tlb_addr, struct io_tlb_pool *pool) +{ +} static inline bool is_swiotlb_for_alloc(struct device *dev) { return false; diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index f19f5cec18e2..cedabf177f47 100644 --- a/include/linux/sys_soc.h +++ b/include/linux/sys_soc.h @@ -21,19 +21,26 @@ struct soc_device_attribute { /** * soc_device_register - register SoC as a device * @soc_plat_dev_attr: Attributes passed from platform to be attributed to a SoC + * + * Returns: + * - %NULL if the SoC bus is not yet registered; + * - on success, the newly allocated &struct soc_device pointer; + * - on failure, a negative error code as an ERR_PTR(). */ struct soc_device *soc_device_register( struct soc_device_attribute *soc_plat_dev_attr); /** * soc_device_unregister - unregister SoC device - * @dev: SoC device to be unregistered + * @soc_dev: SoC device to be unregistered */ void soc_device_unregister(struct soc_device *soc_dev); /** * soc_device_to_device - helper function to fetch struct device * @soc: Previously registered SoC device container + * + * Returns: &struct device pointer for this @soc */ struct device *soc_device_to_device(struct soc_device *soc); diff --git a/include/linux/syscall_user_dispatch.h b/include/linux/syscall_user_dispatch.h index 3858a6ffdd5c..3dd30f4b2799 100644 --- a/include/linux/syscall_user_dispatch.h +++ b/include/linux/syscall_user_dispatch.h @@ -6,9 +6,23 @@ #define _SYSCALL_USER_DISPATCH_H #include <linux/thread_info.h> +#include <linux/sched.h> #include <linux/syscall_user_dispatch_types.h> -#ifdef CONFIG_GENERIC_ENTRY +struct pt_regs; + +#ifdef CONFIG_SYSCALL_USER_DISPATCH + +bool syscall_user_dispatch(struct pt_regs *regs); + +static __always_inline bool syscall_user_dispatch_clear_on_dispatch(void) +{ + if (likely(!current->syscall_dispatch.on_dispatch)) + return false; + + current->syscall_dispatch.on_dispatch = false; + return true; +} int set_syscall_user_dispatch(unsigned long mode, unsigned long offset, unsigned long len, char __user *selector); @@ -24,6 +38,16 @@ int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long siz #else +static __always_inline bool syscall_user_dispatch(struct pt_regs *regs) +{ + return false; +} + +static __always_inline bool syscall_user_dispatch_clear_on_dispatch(void) +{ + return false; +} + static inline int set_syscall_user_dispatch(unsigned long mode, unsigned long offset, unsigned long len, char __user *selector) { @@ -46,6 +70,6 @@ static inline int syscall_user_dispatch_set_config(struct task_struct *task, return -EINVAL; } -#endif /* CONFIG_GENERIC_ENTRY */ +#endif /* CONFIG_SYSCALL_USER_DISPATCH */ #endif /* _SYSCALL_USER_DISPATCH_H */ diff --git a/include/linux/syscall_user_dispatch_types.h b/include/linux/syscall_user_dispatch_types.h index 3be36b06c7d7..c0bdd4f760d3 100644 --- a/include/linux/syscall_user_dispatch_types.h +++ b/include/linux/syscall_user_dispatch_types.h @@ -4,7 +4,7 @@ #include <linux/types.h> -#ifdef CONFIG_GENERIC_ENTRY +#ifdef CONFIG_SYSCALL_USER_DISPATCH struct syscall_user_dispatch { char __user *selector; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 874d9067a43b..8413b624ad47 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -457,6 +457,7 @@ asmlinkage long sys_faccessat2(int dfd, const char __user *filename, int mode, asmlinkage long sys_chdir(const char __user *filename); asmlinkage long sys_fchdir(unsigned int fd); asmlinkage long sys_chroot(const char __user *filename); +asmlinkage long sys_fchroot(int fd, unsigned int flags); asmlinkage long sys_fchmod(unsigned int fd, umode_t mode); asmlinkage long sys_fchmodat(int dfd, const char __user *filename, umode_t mode); diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 2886fbceb5d6..e5d7226ab6f5 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -59,7 +59,7 @@ extern const int sysctl_vals[]; #define SYSCTL_LONG_ONE ((void *)&sysctl_long_vals[1]) #define SYSCTL_LONG_MAX ((void *)&sysctl_long_vals[2]) -/** +/* * * "dir" originates from read_iter (dir = 0) or write_iter (dir = 1) * in the file_operations struct at proc/proc_sysctl.c. Its value means @@ -74,53 +74,108 @@ extern const int sysctl_vals[]; extern const unsigned long sysctl_long_vals[]; -typedef int proc_handler(const struct ctl_table *ctl, int write, void *buffer, - size_t *lenp, loff_t *ppos); - -int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_dobool(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); +typedef int proc_handler(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); -int proc_dointvec(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_dointvec_minmax(const struct ctl_table *table, int dir, void *buffer, +/* proc_handler functions */ +int proc_dostring(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, + loff_t *ppos); +int proc_dobool(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, + loff_t *ppos); +int proc_dointvec(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, + loff_t *ppos); +int proc_dointvec_minmax(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); +int proc_douintvec(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, + loff_t *ppos); +int proc_douintvec_minmax(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); +int proc_dou8vec_minmax(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); +int proc_doulongvec_minmax(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); +int proc_do_large_bitmap(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, loff_t *ppos); -int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer, +int proc_do_static_key(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos); + +/* + * proc_handler aggregators + * + * Create a proc_handler with a custom converter. Use when the user space + * value is a transformation of the kernel value. Cannot be passed as + * proc_handlers. + * + * Example of creating your custom proc handler: + * int custom_converter(bool *negp, ulong *u_ptr, uint *k_ptr, + * int dir, const struct ctl_table *ctl) {...} + * int custom_proc_handler(const struct ctl_table *ctl, int dir, + * void *buf, size_t *lenp, loff_t *ppos + * { return proc_dointvec_conv(ctl, dir, buf, lenp, ppos, custom_converter); } + */ +int proc_dointvec_conv(const struct ctl_table *ctl, int dir, void *buf, size_t *lenp, loff_t *ppos, int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, - int dir, const struct ctl_table *table)); -int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp, - ulong (*k_ptr_op)(const ulong)); -int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, - ulong (*u_ptr_op)(const ulong)); + int dir, const struct ctl_table *ctl)); +int proc_douintvec_conv(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos, + int (*conv)(bool *negp, ulong *u_ptr, uint *k_ptr, + int dir, const struct ctl_table *ctl)); +int proc_doulongvec_conv(const struct ctl_table *ctl, int dir, void *buf, + size_t *lenp, loff_t *ppos, + int (*conv)(bool *negp, ulong *u_ptr, ulong *k_ptr, + int dir, const struct ctl_table *ctl)); + +/* + * bi-directional converter functions + * + * Specify the converter function for both directions (user to kernel & kernel + * to user). Use when you want to change the value of the variable before + * assignment. Used to create custom proc_handler aggregators. + * + * Example of creating your custom bi-directional converter: + * int custom_u2k(ulong *u_ptr, const uint *k_ptr) { ... } + * int custom_converter(bool *negp, ulong *u_ptr, uint *k_ptr, + * int dir, const struct ctl_table *ctl) + * { return proc_uint_conv(u_ptr, k_ptr, dir, ctl, true, + * custom_u2k, proc_uint_k2u_conv} + */ int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr, int dir, const struct ctl_table *tbl, bool k_ptr_range_check, int (*user_to_kern)(const bool *negp, const ulong *u_ptr, int *k_ptr), int (*kern_to_user)(bool *negp, ulong *u_ptr, const int *k_ptr)); - -int proc_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); -int proc_douintvec_conv(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos, - int (*conv)(unsigned long *lvalp, unsigned int *valp, - int write, const struct ctl_table *table)); -int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr); -int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr, - ulong (*u_ptr_op)(const ulong)); int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir, const struct ctl_table *tbl, bool k_ptr_range_check, int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr), int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr)); +int proc_ulong_conv(ulong *u_ptr, ulong *k_ptr, int dir, + const struct ctl_table *tbl, bool k_ptr_range_check, + int (*user_to_kern)(const ulong *u_ptr, ulong *k_ptr), + int (*kern_to_user)(ulong *u_ptr, const ulong *k_ptr)); -int proc_dou8vec_minmax(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); -int proc_doulongvec_minmax(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir, - void *buffer, size_t *lenp, loff_t *ppos, - unsigned long convmul, unsigned long convdiv); -int proc_do_large_bitmap(const struct ctl_table *, int, void *, size_t *, loff_t *); -int proc_do_static_key(const struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); +/* + * uni-directional converter functions + * + * Specify the converter function for one directions (user to kernel or + * kernel to user). Use to call the actual value conversion. Used to Create + * bi-directional converters. + * + * Example of creating a uni-directional converter: + * ulong op(const ulong val) { ... } + * int custom_unidir_conv(ulong *u_ptr, const uint *k_ptr) + * { return proc_uint_k2u_conv_kop(u_ptr, k_ptr, op); } + */ +int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp, + ulong (*k_ptr_op)(const ulong)); +int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, + ulong (*u_ptr_op)(const ulong)); +int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr); +int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr, + ulong (*u_ptr_op)(const ulong)); +int proc_ulong_u2k_conv_uop(const ulong *u_ptr, ulong *k_ptr, + ulong (*u_ptr_op)(const ulong)); +int proc_ulong_k2u_conv_kop(ulong *u_ptr, const ulong *k_ptr, + ulong (*k_ptr_op)(const ulong)); /* * Register a set of sysctl names by calling register_sysctl @@ -190,9 +245,9 @@ struct ctl_node { * @nreg: When nreg drops to 0 the ctl_table_header will be unregistered. * @rcu: Delays the freeing of the inode. Introduced with "unfuck proc_sysctl ->d_compare()" * - * @type: Enumeration to differentiate between ctl target types - * @type.SYSCTL_TABLE_TYPE_DEFAULT: ctl target with no special considerations - * @type.SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY: Identifies a permanently empty dir + * @type: Enumeration to differentiate between ctl target types: + * type.SYSCTL_TABLE_TYPE_DEFAULT: ctl target with no special considerations + * type.SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY: Identifies a permanently empty dir * target to serve as a mount point */ struct ctl_table_header { diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h index 5226efde9ad4..ed23d6516223 100644 --- a/include/linux/sysfb.h +++ b/include/linux/sysfb.h @@ -118,7 +118,7 @@ struct platform_device *sysfb_create_simplefb(const struct screen_info *si, const struct simplefb_platform_data *mode, struct device *parent); -#else /* CONFIG_SYSFB_SIMPLE */ +#else /* CONFIG_SYSFB_SIMPLEFB */ static inline bool sysfb_parse_mode(const struct screen_info *si, struct simplefb_platform_data *mode) @@ -133,6 +133,6 @@ static inline struct platform_device *sysfb_create_simplefb(const struct screen_ return ERR_PTR(-EINVAL); } -#endif /* CONFIG_SYSFB_SIMPLE */ +#endif /* CONFIG_SYSFB_SIMPLEFB */ #endif /* _LINUX_SYSFB_H */ diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h index dbb4d124c7d7..995cd19b56c1 100644 --- a/include/linux/taskstats_kern.h +++ b/include/linux/taskstats_kern.h @@ -14,7 +14,6 @@ #ifdef CONFIG_TASKSTATS extern struct kmem_cache *taskstats_cache; -extern struct mutex taskstats_exit_mutex; static inline void taskstats_tgid_free(struct signal_struct *sig) { diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 8a6807082672..6a8c77719322 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -274,7 +274,7 @@ struct tcp_sock { u32 write_seq; /* Tail(+1) of data held in tcp send buffer */ u32 pushed_seq; /* Last pushed seq, required to talk to windows */ u32 lsndtime; /* timestamp of last sent data packet (for restart window) */ - u32 mdev_us; /* medium deviation */ + u32 mdev_us; /* mean deviation of RTT, scaled by 4 (<< 2) in usecs */ 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 */ diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index e561a26f537a..f3c5e106d853 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -9,7 +9,7 @@ #include <linux/device.h> #include <linux/kref.h> #include <linux/list.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/tee_client.h> #include <linux/tee.h> #include <linux/types.h> diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h index feb1af175cfd..d48623fda79b 100644 --- a/include/linux/thunderbolt.h +++ b/include/linux/thunderbolt.h @@ -23,7 +23,7 @@ struct device; #include <linux/idr.h> #include <linux/list.h> #include <linux/mutex.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/tb.h> #include <linux/pci.h> #include <linux/uuid.h> #include <linux/workqueue.h> @@ -465,7 +465,7 @@ static inline struct tb_service *tb_to_service(struct device *dev) */ struct tb_service_driver { struct device_driver driver; - int (*probe)(struct tb_service *svc, const struct tb_service_id *id); + int (*probe)(struct tb_service *svc); void (*remove)(struct tb_service *svc); void (*shutdown)(struct tb_service *svc); const struct tb_service_id *id_table; @@ -514,6 +514,11 @@ void tb_service_properties_changed(struct tb_service *svc); * @hop_count: Number of rings (end point hops) supported by NHI. * @quirks: NHI specific quirks if any * @domain_released: Completed when domain has been fully released + * @host_reset: Host router was reset on driver load, or forced on system + * shutdown/reboot. When set, tb_stop() asserts DPR on connected + * downstream ports to signal disconnect before tearing down the + * router tree. Only Thunderbolt 3 devices are reset; USB4 + * routers are skipped. */ struct tb_nhi { spinlock_t lock; @@ -528,6 +533,7 @@ struct tb_nhi { u32 hop_count; unsigned long quirks; struct completion domain_released; + bool host_reset; }; /** @@ -592,6 +598,8 @@ struct tb_ring { #define RING_FLAG_FRAME BIT(1) /* Enable end-to-end flow control */ #define RING_FLAG_E2E BIT(2) +/* Do not enable interrupt for the ring */ +#define RING_FLAG_NO_INTERRUPT BIT(3) struct ring_frame; typedef void (*ring_cb)(struct tb_ring *, struct ring_frame *, bool canceled); diff --git a/include/linux/tick.h b/include/linux/tick.h index 1cf4651f09ad..b121c5d53e30 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -7,6 +7,8 @@ #include <linux/clockchips.h> #include <linux/irqflags.h> +#include <linux/jiffies.h> +#include <linux/ktime.h> #include <linux/percpu.h> #include <linux/context_tracking_state.h> #include <linux/cpumask.h> @@ -44,9 +46,6 @@ static inline void tick_unfreeze(void) { } #ifdef CONFIG_TICK_ONESHOT extern void tick_irq_enter(void); -# ifndef arch_needs_cpu -# define arch_needs_cpu() (0) -# endif # else static inline void tick_irq_enter(void) { } #endif diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index 4486dfd5d0de..fe077d97b5f8 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h @@ -84,8 +84,6 @@ struct tk_read_base { * @cycle_interval: Number of clock cycles in one NTP interval * @xtime_interval: Number of clock shifted nano seconds in one NTP * interval. - * @xtime_remainder: Shifted nano seconds left over when rounding - * @cycle_interval * @raw_interval: Shifted raw nano seconds accumulated per NTP interval. * @next_leap_ktime: CLOCK_MONOTONIC time value of a pending leap-second * @ntp_tick: The ntp_tick_length() value currently being @@ -99,6 +97,10 @@ struct tk_read_base { * @ntp_error_shift: Shift conversion between clock shifted nano seconds and * ntp shifted nano seconds. * @ntp_err_mult: Multiplication factor for scaled math conversion + * @cs_tick_adj: Per-second adjustment handed to NTP via ntp_clear() + * accounting for the difference between the nominal + * NTP interval and the real time taken by the + * clocksource's integer @cycle_interval (upscaled). * @skip_second_overflow: Flag used to avoid updating NTP twice with same second * @tai_offset: The current UTC to TAI offset in seconds * @@ -167,7 +169,7 @@ struct timekeeper { u32 cs_ns_to_cyc_mult; u32 cs_ns_to_cyc_shift; u64 cs_ns_to_cyc_maxns; - unsigned int clock_was_set_seq; + u32 clock_was_set_seq; u8 cs_was_changed_seq; u8 clock_valid; @@ -178,7 +180,6 @@ struct timekeeper { u64 cycle_interval; u64 xtime_interval; - s64 xtime_remainder; u64 raw_interval; ktime_t next_leap_ktime; @@ -186,29 +187,10 @@ struct timekeeper { s64 ntp_error; u32 ntp_error_shift; u32 ntp_err_mult; + s64 cs_tick_adj; u32 skip_second_overflow; + s64 skew_delta; s32 tai_offset; }; -#ifdef CONFIG_GENERIC_GETTIMEOFDAY - -extern void update_vsyscall(struct timekeeper *tk); -extern void update_vsyscall_tz(void); - -#else - -static inline void update_vsyscall(struct timekeeper *tk) -{ -} -static inline void update_vsyscall_tz(void) -{ -} -#endif - -#if defined(CONFIG_GENERIC_GETTIMEOFDAY) && defined(CONFIG_POSIX_AUX_CLOCKS) -extern void vdso_time_update_aux(struct timekeeper *tk); -#else -static inline void vdso_time_update_aux(struct timekeeper *tk) { } -#endif - #endif /* _LINUX_TIMEKEEPER_INTERNAL_H */ diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index 984a866d293b..efa9442aaeef 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -44,7 +44,6 @@ extern void ktime_get_ts64(struct timespec64 *ts); extern void ktime_get_real_ts64(struct timespec64 *tv); extern void ktime_get_coarse_ts64(struct timespec64 *ts); extern void ktime_get_coarse_real_ts64(struct timespec64 *ts); -extern void ktime_get_clock_ts64(clockid_t id, struct timespec64 *ts); /* Multigrain timestamp interfaces */ extern void ktime_get_coarse_real_ts64_mg(struct timespec64 *ts); @@ -268,15 +267,18 @@ extern void timekeeping_inject_sleeptime64(const struct timespec64 *delta); * Auxiliary clock interfaces */ #ifdef CONFIG_POSIX_AUX_CLOCKS -extern bool ktime_get_aux(clockid_t id, ktime_t *kt); -extern bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt); +extern bool __must_check ktime_get_aux(clockid_t id, ktime_t *kt); +extern bool __must_check ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt); #else -static inline bool ktime_get_aux(clockid_t id, ktime_t *kt) { return false; } -static inline bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt) { return false; } +static inline bool __must_check ktime_get_aux(clockid_t id, ktime_t *kt) { return false; } +static inline bool __must_check ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt) +{ + return false; +} #endif /** - * struct system_time_snapshot - Simultaneous time capture of CLOCK_MONOTONIC_RAW, + * struct system_time_snapshot - Simultaneous time capture of monotonic raw time, * a selected CLOCK_* and the clocksource counter value * @cycles: Clocksource counter value to produce the system times * @hw_cycles: For derived clocksources, the hardware counter value from @@ -289,6 +291,10 @@ static inline bool ktime_get_aux_ts64(clockid_t id, struct timespec64 *kt) { ret * @clock_was_set_seq: The sequence number of clock-was-set events * @cs_was_changed_seq: The sequence number of clocksource change events * @valid: True if the snapshot is valid + * + * @monoraw is CLOCK_MONOTONIC_RAW for system time CLOCK ids. For CLOCK_AUX$N + * clock ids it's the monotonic raw time related to the AUX clock, which is + * CLOCK_MONOTONIC_RAW plus a AUX clock specific offset. */ struct system_time_snapshot { u64 cycles; @@ -297,7 +303,7 @@ struct system_time_snapshot { ktime_t monoraw; enum clocksource_ids cs_id; enum clocksource_ids hw_csid; - unsigned int clock_was_set_seq; + u32 clock_was_set_seq; u8 cs_was_changed_seq; u8 valid; }; @@ -326,6 +332,10 @@ struct system_counterval_t { * @sys_counter: Clocksource counter value simultaneous with device time * @sys_systime: System time for @clock_id * @sys_monoraw: Monotonic raw simultaneous with device time + * + * @sys_monoraw is CLOCK_MONOTONIC_RAW for system time CLOCK ids. For + * CLOCK_AUX$N clock ids it's the monotonic raw time related to the AUX clock, + * which is CLOCK_MONOTONIC_RAW plus a AUX clock specific offset. */ struct system_device_crosststamp { clockid_t clock_id; diff --git a/include/linux/timex.h b/include/linux/timex.h index 4ee32eff3f22..7014ccc638fc 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -156,8 +156,6 @@ extern int do_clock_adjtime(const clockid_t which_clock, struct __kernel_timex * extern void hardpps(const struct timespec64 *, const struct timespec64 *); -int read_current_timer(unsigned long *timer_val); - /* The clock frequency of the i8253/i8254 PIT */ #define PIT_TICK_RATE 1193182ul diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 202da079d500..0db277af45c3 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -25,10 +25,8 @@ #include <crypto/hash_info.h> #include <crypto/aes.h> -#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ - -#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE -#define TPM2_MAX_PCR_BANKS 8 +#include <linux/tpm_command.h> +#include <linux/tpm_buf.h> struct tpm_chip; struct trusted_key_payload; @@ -36,49 +34,6 @@ struct trusted_key_options; /* opaque structure, holds auth session parameters like the session key */ struct tpm2_auth; -enum tpm2_session_types { - TPM2_SE_HMAC = 0x00, - TPM2_SE_POLICY = 0x01, - TPM2_SE_TRIAL = 0x02, -}; - -/* if you add a new hash to this, increment TPM_MAX_HASHES below */ -enum tpm_algorithms { - TPM_ALG_ERROR = 0x0000, - TPM_ALG_SHA1 = 0x0004, - TPM_ALG_AES = 0x0006, - TPM_ALG_KEYEDHASH = 0x0008, - TPM_ALG_SHA256 = 0x000B, - TPM_ALG_SHA384 = 0x000C, - TPM_ALG_SHA512 = 0x000D, - TPM_ALG_NULL = 0x0010, - TPM_ALG_SM3_256 = 0x0012, - TPM_ALG_ECC = 0x0023, - TPM_ALG_CFB = 0x0043, -}; - -/* - * maximum number of hashing algorithms a TPM can have. This is - * basically a count of every hash in tpm_algorithms above - */ -#define TPM_MAX_HASHES 5 - -enum tpm2_curves { - TPM2_ECC_NONE = 0x0000, - TPM2_ECC_NIST_P256 = 0x0003, -}; - -struct tpm_digest { - u16 alg_id; - u8 digest[TPM2_MAX_DIGEST_SIZE]; -} __packed; - -struct tpm_bank_info { - u16 alg_id; - u16 digest_size; - u16 crypto_id; -}; - enum TPM_OPS_FLAGS { TPM_OPS_AUTO_STARTUP = BIT(0), }; @@ -136,7 +91,7 @@ struct tpm_chip_seqops { const struct seq_operations *seqops; }; -/* fixed define for the curve we use which is NIST_P256 */ +/* Fixed define for the curve we use which is NIST_P256 */ #define EC_PT_SZ 32 /* @@ -218,124 +173,11 @@ struct tpm_chip { #endif }; -#define TPM_HEADER_SIZE 10 - -enum tpm2_const { - TPM2_PLATFORM_PCR = 24, - TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8), -}; - -enum tpm2_timeouts { - TPM2_TIMEOUT_A = 750, - TPM2_TIMEOUT_B = 4000, - TPM2_TIMEOUT_C = 200, - TPM2_TIMEOUT_D = 30, -}; - -enum tpm2_durations { - TPM2_DURATION_SHORT = 20, - TPM2_DURATION_LONG = 2000, - TPM2_DURATION_DEFAULT = 120000, -}; - -enum tpm2_structures { - TPM2_ST_NO_SESSIONS = 0x8001, - TPM2_ST_SESSIONS = 0x8002, - TPM2_ST_CREATION = 0x8021, -}; - -/* Indicates from what layer of the software stack the error comes from */ -#define TSS2_RC_LAYER_SHIFT 16 -#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT) - -enum tpm2_return_codes { - TPM2_RC_SUCCESS = 0x0000, - TPM2_RC_HASH = 0x0083, /* RC_FMT1 */ - TPM2_RC_HANDLE = 0x008B, - TPM2_RC_INTEGRITY = 0x009F, - TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ - TPM2_RC_FAILURE = 0x0101, - TPM2_RC_DISABLED = 0x0120, - TPM2_RC_UPGRADE = 0x012D, - TPM2_RC_COMMAND_CODE = 0x0143, - TPM2_RC_TESTING = 0x090A, /* RC_WARN */ - TPM2_RC_REFERENCE_H0 = 0x0910, - TPM2_RC_RETRY = 0x0922, - TPM2_RC_SESSION_MEMORY = 0x0903, -}; - -enum tpm2_command_codes { - TPM2_CC_FIRST = 0x011F, - TPM2_CC_HIERARCHY_CONTROL = 0x0121, - TPM2_CC_HIERARCHY_CHANGE_AUTH = 0x0129, - TPM2_CC_CREATE_PRIMARY = 0x0131, - TPM2_CC_SEQUENCE_COMPLETE = 0x013E, - TPM2_CC_SELF_TEST = 0x0143, - TPM2_CC_STARTUP = 0x0144, - TPM2_CC_SHUTDOWN = 0x0145, - TPM2_CC_NV_READ = 0x014E, - TPM2_CC_CREATE = 0x0153, - TPM2_CC_LOAD = 0x0157, - TPM2_CC_SEQUENCE_UPDATE = 0x015C, - TPM2_CC_UNSEAL = 0x015E, - TPM2_CC_CONTEXT_LOAD = 0x0161, - TPM2_CC_CONTEXT_SAVE = 0x0162, - TPM2_CC_FLUSH_CONTEXT = 0x0165, - TPM2_CC_READ_PUBLIC = 0x0173, - TPM2_CC_START_AUTH_SESS = 0x0176, - TPM2_CC_VERIFY_SIGNATURE = 0x0177, - TPM2_CC_GET_CAPABILITY = 0x017A, - TPM2_CC_GET_RANDOM = 0x017B, - TPM2_CC_PCR_READ = 0x017E, - TPM2_CC_PCR_EXTEND = 0x0182, - TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185, - TPM2_CC_HASH_SEQUENCE_START = 0x0186, - TPM2_CC_CREATE_LOADED = 0x0191, - TPM2_CC_LAST = 0x0193, /* Spec 1.36 */ -}; - -enum tpm2_permanent_handles { - TPM2_RH_NULL = 0x40000007, - TPM2_RS_PW = 0x40000009, -}; - -/* Most Significant Octet for key types */ -enum tpm2_mso_type { - TPM2_MSO_NVRAM = 0x01, - TPM2_MSO_SESSION = 0x02, - TPM2_MSO_POLICY = 0x03, - TPM2_MSO_PERMANENT = 0x40, - TPM2_MSO_VOLATILE = 0x80, - TPM2_MSO_PERSISTENT = 0x81, -}; - static inline enum tpm2_mso_type tpm2_handle_mso(u32 handle) { return handle >> 24; } -enum tpm2_capabilities { - TPM2_CAP_HANDLES = 1, - TPM2_CAP_COMMANDS = 2, - TPM2_CAP_PCRS = 5, - TPM2_CAP_TPM_PROPERTIES = 6, -}; - -enum tpm2_properties { - TPM_PT_TOTAL_COMMANDS = 0x0129, -}; - -enum tpm2_startup_types { - TPM2_SU_CLEAR = 0x0000, - TPM2_SU_STATE = 0x0001, -}; - -enum tpm2_cc_attrs { - TPM2_CC_ATTR_CHANDLES = 25, - TPM2_CC_ATTR_RHANDLE = 28, - TPM2_CC_ATTR_VENDOR = 29, -}; - #define TPM_VID_INTEL 0x8086 #define TPM_VID_WINBOND 0x1050 #define TPM_VID_STM 0x104A @@ -359,77 +201,11 @@ enum tpm_chip_flags { #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) -struct tpm_header { - __be16 tag; - __be32 length; - union { - __be32 ordinal; - __be32 return_code; - }; -} __packed; - -enum tpm_buf_flags { - /* the capacity exceeded: */ - TPM_BUF_OVERFLOW = BIT(0), - /* TPM2B format: */ - TPM_BUF_TPM2B = BIT(1), - /* read out of boundary: */ - TPM_BUF_BOUNDARY_ERROR = BIT(2), -}; - -/* - * A string buffer type for constructing TPM commands. - */ -struct tpm_buf { - u32 flags; - u32 length; - u8 *data; - u8 handles; -}; - -enum tpm2_object_attributes { - TPM2_OA_FIXED_TPM = BIT(1), - TPM2_OA_ST_CLEAR = BIT(2), - TPM2_OA_FIXED_PARENT = BIT(4), - TPM2_OA_SENSITIVE_DATA_ORIGIN = BIT(5), - TPM2_OA_USER_WITH_AUTH = BIT(6), - TPM2_OA_ADMIN_WITH_POLICY = BIT(7), - TPM2_OA_NO_DA = BIT(10), - TPM2_OA_ENCRYPTED_DUPLICATION = BIT(11), - TPM2_OA_RESTRICTED = BIT(16), - TPM2_OA_DECRYPT = BIT(17), - TPM2_OA_SIGN = BIT(18), -}; - -enum tpm2_session_attributes { - TPM2_SA_CONTINUE_SESSION = BIT(0), - TPM2_SA_AUDIT_EXCLUSIVE = BIT(1), - TPM2_SA_AUDIT_RESET = BIT(3), - TPM2_SA_DECRYPT = BIT(5), - TPM2_SA_ENCRYPT = BIT(6), - TPM2_SA_AUDIT = BIT(7), -}; - struct tpm2_hash { unsigned int crypto_id; unsigned int tpm_id; }; -int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal); -void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal); -int tpm_buf_init_sized(struct tpm_buf *buf); -void tpm_buf_reset_sized(struct tpm_buf *buf); -void tpm_buf_destroy(struct tpm_buf *buf); -u32 tpm_buf_length(struct tpm_buf *buf); -void tpm_buf_append(struct tpm_buf *buf, const u8 *new_data, u16 new_length); -void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value); -void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value); -void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value); -u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset); -u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset); -u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset); -void tpm_buf_append_handle(struct tpm_chip *chip, struct tpm_buf *buf, u32 handle); - /* * Check if TPM device is in the firmware upgrade mode. */ diff --git a/include/linux/tpm_buf.h b/include/linux/tpm_buf.h new file mode 100644 index 000000000000..f8c105d8b8bf --- /dev/null +++ b/include/linux/tpm_buf.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Following copyright information was take from the original file + * <include/linux/tpm.h> where the definitions were moved from: + * + * Copyright (C) 2004,2007,2008 IBM Corporation + * + * Authors: + * Leendert van Doorn <leendert@watson.ibm.com> + * Dave Safford <safford@watson.ibm.com> + * Reiner Sailer <sailer@watson.ibm.com> + * Kylene Hall <kjhall@us.ibm.com> + * Debora Velarde <dvelarde@us.ibm.com> + * + * Maintained by: <tpmdd_devel@lists.sourceforge.net> + * + * Device driver for TCG/TCPA TPM (trusted platform module). + * Specifications at www.trustedcomputinggroup.org + */ + +#ifndef __LINUX_TPM_BUF_H__ +#define __LINUX_TPM_BUF_H__ + +#include <linux/types.h> +#include <linux/bits.h> + +enum tpm_buf_flags { + /* TPM2B format: */ + TPM_BUF_TPM2B = BIT(0), + /* The buffer is in invalid and unusable state: */ + TPM_BUF_INVALID = BIT(1), +}; + +/* + * A buffer for constructing and parsing TPM commands, responses and sized + * (TPM2B) buffers. + */ +struct tpm_buf { + u8 flags; + u8 handles; + u16 length; + u16 capacity; + u8 data[]; +}; + +void tpm_buf_init(struct tpm_buf *buf, u16 buf_size); +void tpm_buf_init_sized(struct tpm_buf *buf, u16 buf_size); +void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal); +void tpm_buf_reset_sized(struct tpm_buf *buf); +u16 tpm_buf_length(struct tpm_buf *buf); +void tpm_buf_append(struct tpm_buf *buf, const u8 *new_data, u16 new_length); +void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value); +void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value); +void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value); +u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset); +u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset); +u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset); +void tpm_buf_append_handle(struct tpm_buf *buf, u32 handle); + +#endif diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h index f5c03e9c3913..fc446a1282e2 100644 --- a/include/linux/tpm_command.h +++ b/include/linux/tpm_command.h @@ -2,28 +2,520 @@ #ifndef __LINUX_TPM_COMMAND_H__ #define __LINUX_TPM_COMMAND_H__ +#include <crypto/sha2.h> + /* - * TPM Command constants from specifications at - * http://www.trustedcomputinggroup.org + * == TPM 1 Family Chips == + * + * TPM 1.2 Main Specification: + * https://trustedcomputinggroup.org/resource/tpm-main-specification/ */ +#define TPM_MAX_ORDINAL 243 + /* Command TAGS */ -#define TPM_TAG_RQU_COMMAND 193 -#define TPM_TAG_RQU_AUTH1_COMMAND 194 -#define TPM_TAG_RQU_AUTH2_COMMAND 195 -#define TPM_TAG_RSP_COMMAND 196 -#define TPM_TAG_RSP_AUTH1_COMMAND 197 -#define TPM_TAG_RSP_AUTH2_COMMAND 198 +enum tpm_command_tags { + TPM_TAG_RQU_COMMAND = 193, + TPM_TAG_RQU_AUTH1_COMMAND = 194, + TPM_TAG_RQU_AUTH2_COMMAND = 195, + TPM_TAG_RSP_COMMAND = 196, + TPM_TAG_RSP_AUTH1_COMMAND = 197, + TPM_TAG_RSP_AUTH2_COMMAND = 198, +}; /* Command Ordinals */ -#define TPM_ORD_GETRANDOM 70 -#define TPM_ORD_OSAP 11 -#define TPM_ORD_OIAP 10 -#define TPM_ORD_SEAL 23 -#define TPM_ORD_UNSEAL 24 +enum tpm_command_ordinals { + TPM_ORD_CONTINUE_SELFTEST = 83, + TPM_ORD_GET_CAP = 101, + TPM_ORD_GET_RANDOM = 70, + TPM_ORD_PCR_EXTEND = 20, + TPM_ORD_PCR_READ = 21, + TPM_ORD_OSAP = 11, + TPM_ORD_OIAP = 10, + TPM_ORD_SAVESTATE = 152, + TPM_ORD_SEAL = 23, + TPM_ORD_STARTUP = 153, + TPM_ORD_UNSEAL = 24, +}; + +enum tpm_capabilities { + TPM_CAP_FLAG = 4, + TPM_CAP_PROP = 5, + TPM_CAP_VERSION_1_1 = 0x06, + TPM_CAP_VERSION_1_2 = 0x1A, +}; + +enum tpm_sub_capabilities { + TPM_CAP_PROP_PCR = 0x101, + TPM_CAP_PROP_MANUFACTURER = 0x103, + TPM_CAP_FLAG_PERM = 0x108, + TPM_CAP_FLAG_VOL = 0x109, + TPM_CAP_PROP_OWNER = 0x111, + TPM_CAP_PROP_TIS_TIMEOUT = 0x115, + TPM_CAP_PROP_TIS_DURATION = 0x120, +}; + +/* Return Codes */ +enum tpm_return_codes { + TPM_BASE_MASK = 0, + TPM_NON_FATAL_MASK = 0x00000800, + TPM_SUCCESS = TPM_BASE_MASK + 0, + TPM_ERR_DEACTIVATED = TPM_BASE_MASK + 6, + TPM_ERR_DISABLED = TPM_BASE_MASK + 7, + TPM_ERR_FAIL = TPM_BASE_MASK + 9, + TPM_ERR_FAILEDSELFTEST = TPM_BASE_MASK + 28, + TPM_ERR_INVALID_POSTINIT = TPM_BASE_MASK + 38, + TPM_ERR_INVALID_FAMILY = TPM_BASE_MASK + 55, + TPM_WARN_RETRY = TPM_BASE_MASK + TPM_NON_FATAL_MASK + 0, + TPM_WARN_DOING_SELFTEST = TPM_BASE_MASK + TPM_NON_FATAL_MASK + 2, +}; + +struct stclear_flags_t { + __be16 tag; + u8 deactivated; + u8 disableForceClear; + u8 physicalPresence; + u8 physicalPresenceLock; + u8 bGlobalLock; +} __packed; + +struct tpm1_version { + u8 major; + u8 minor; + u8 rev_major; + u8 rev_minor; +} __packed; + +struct tpm1_version2 { + __be16 tag; + struct tpm1_version version; +} __packed; + +struct timeout_t { + __be32 a; + __be32 b; + __be32 c; + __be32 d; +} __packed; + +struct duration_t { + __be32 tpm_short; + __be32 tpm_medium; + __be32 tpm_long; +} __packed; + +struct permanent_flags_t { + __be16 tag; + u8 disable; + u8 ownership; + u8 deactivated; + u8 readPubek; + u8 disableOwnerClear; + u8 allowMaintenance; + u8 physicalPresenceLifetimeLock; + u8 physicalPresenceHWEnable; + u8 physicalPresenceCMDEnable; + u8 CEKPUsed; + u8 TPMpost; + u8 TPMpostLock; + u8 FIPS; + u8 operator; + u8 enableRevokeEK; + u8 nvLocked; + u8 readSRKPub; + u8 tpmEstablished; + u8 maintenanceDone; + u8 disableFullDALogicInfo; +} __packed; + +typedef union { + struct permanent_flags_t perm_flags; + struct stclear_flags_t stclear_flags; + __u8 owned; + __be32 num_pcrs; + struct tpm1_version version1; + struct tpm1_version2 version2; + __be32 manufacturer_id; + struct timeout_t timeout; + struct duration_t duration; +} cap_t; + +/* + * 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18 + * bytes, but 128 is still a relatively large number of random bytes and + * anything much bigger causes users of struct tpm_cmd_t to start getting + * compiler warnings about stack frame size. + */ +#define TPM_MAX_RNG_DATA 128 + +struct tpm1_get_random_out { + __be32 rng_data_len; + u8 rng_data[TPM_MAX_RNG_DATA]; +} __packed; /* Other constants */ #define SRKHANDLE 0x40000000 #define TPM_NONCE_SIZE 20 +#define TPM_ST_CLEAR 1 + +/* + * == TPM 2 Family Chips == + * + * TPM 2.0 Library + * https://trustedcomputinggroup.org/resource/tpm-library-specification/ + */ + +/* TPM2 specific constants. */ +#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */ + +enum tpm2_session_types { + TPM2_SE_HMAC = 0x00, + TPM2_SE_POLICY = 0x01, + TPM2_SE_TRIAL = 0x02, +}; + +enum tpm2_timeouts { + TPM2_TIMEOUT_A = 750, + TPM2_TIMEOUT_B = 4000, + TPM2_TIMEOUT_C = 200, + TPM2_TIMEOUT_D = 30, + TPM2_DURATION_SHORT = 20, + TPM2_DURATION_MEDIUM = 750, + TPM2_DURATION_LONG = 2000, + TPM2_DURATION_LONG_LONG = 300000, + TPM2_DURATION_DEFAULT = 120000, +}; + +enum tpm2_structures { + TPM2_ST_NO_SESSIONS = 0x8001, + TPM2_ST_SESSIONS = 0x8002, + TPM2_ST_CREATION = 0x8021, +}; + +/* Indicates from what layer of the software stack the error comes from */ +#define TSS2_RC_LAYER_SHIFT 16 +#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT) + +enum tpm2_return_codes { + TPM2_RC_SUCCESS = 0x0000, + TPM2_RC_HASH = 0x0083, /* RC_FMT1 */ + TPM2_RC_HANDLE = 0x008B, + TPM2_RC_INTEGRITY = 0x009F, + TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ + TPM2_RC_FAILURE = 0x0101, + TPM2_RC_DISABLED = 0x0120, + TPM2_RC_UPGRADE = 0x012D, + TPM2_RC_COMMAND_CODE = 0x0143, + TPM2_RC_TESTING = 0x090A, /* RC_WARN */ + TPM2_RC_REFERENCE_H0 = 0x0910, + TPM2_RC_RETRY = 0x0922, + TPM2_RC_SESSION_MEMORY = 0x0903, +}; + +enum tpm2_command_codes { + TPM2_CC_FIRST = 0x011F, + TPM2_CC_HIERARCHY_CONTROL = 0x0121, + TPM2_CC_HIERARCHY_CHANGE_AUTH = 0x0129, + TPM2_CC_CREATE_PRIMARY = 0x0131, + TPM2_CC_SEQUENCE_COMPLETE = 0x013E, + TPM2_CC_SELF_TEST = 0x0143, + TPM2_CC_STARTUP = 0x0144, + TPM2_CC_SHUTDOWN = 0x0145, + TPM2_CC_NV_READ = 0x014E, + TPM2_CC_CREATE = 0x0153, + TPM2_CC_LOAD = 0x0157, + TPM2_CC_SEQUENCE_UPDATE = 0x015C, + TPM2_CC_UNSEAL = 0x015E, + TPM2_CC_CONTEXT_LOAD = 0x0161, + TPM2_CC_CONTEXT_SAVE = 0x0162, + TPM2_CC_FLUSH_CONTEXT = 0x0165, + TPM2_CC_READ_PUBLIC = 0x0173, + TPM2_CC_START_AUTH_SESS = 0x0176, + TPM2_CC_VERIFY_SIGNATURE = 0x0177, + TPM2_CC_GET_CAPABILITY = 0x017A, + TPM2_CC_GET_RANDOM = 0x017B, + TPM2_CC_PCR_READ = 0x017E, + TPM2_CC_PCR_EXTEND = 0x0182, + TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185, + TPM2_CC_HASH_SEQUENCE_START = 0x0186, + TPM2_CC_CREATE_LOADED = 0x0191, + TPM2_CC_LAST = 0x0193, /* Spec 1.36 */ +}; + +enum tpm2_capabilities { + TPM2_CAP_HANDLES = 1, + TPM2_CAP_COMMANDS = 2, + TPM2_CAP_PCRS = 5, + TPM2_CAP_TPM_PROPERTIES = 6, +}; + +enum tpm2_properties { + TPM_PT_TOTAL_COMMANDS = 0x0129, +}; + +enum tpm2_startup_types { + TPM2_SU_CLEAR = 0x0000, + TPM2_SU_STATE = 0x0001, +}; + +enum tpm2_cc_attrs { + TPM2_CC_ATTR_CHANDLES = 25, + TPM2_CC_ATTR_RHANDLE = 28, + TPM2_CC_ATTR_VENDOR = 29, +}; + +enum tpm2_permanent_handles { + TPM2_RH_NULL = 0x40000007, + TPM2_RS_PW = 0x40000009, +}; + +/* Most Significant Octet for key types */ +enum tpm2_mso_type { + TPM2_MSO_NVRAM = 0x01, + TPM2_MSO_SESSION = 0x02, + TPM2_MSO_POLICY = 0x03, + TPM2_MSO_PERMANENT = 0x40, + TPM2_MSO_VOLATILE = 0x80, + TPM2_MSO_PERSISTENT = 0x81, +}; + +enum tpm2_curves { + TPM2_ECC_NONE = 0x0000, + TPM2_ECC_NIST_P256 = 0x0003, +}; + +enum tpm2_object_attributes { + TPM2_OA_FIXED_TPM = BIT(1), + TPM2_OA_ST_CLEAR = BIT(2), + TPM2_OA_FIXED_PARENT = BIT(4), + TPM2_OA_SENSITIVE_DATA_ORIGIN = BIT(5), + TPM2_OA_USER_WITH_AUTH = BIT(6), + TPM2_OA_ADMIN_WITH_POLICY = BIT(7), + TPM2_OA_NO_DA = BIT(10), + TPM2_OA_ENCRYPTED_DUPLICATION = BIT(11), + TPM2_OA_RESTRICTED = BIT(16), + TPM2_OA_DECRYPT = BIT(17), + TPM2_OA_SIGN = BIT(18), +}; + +enum tpm2_session_attributes { + TPM2_SA_CONTINUE_SESSION = BIT(0), + TPM2_SA_AUDIT_EXCLUSIVE = BIT(1), + TPM2_SA_AUDIT_RESET = BIT(3), + TPM2_SA_DECRYPT = BIT(5), + TPM2_SA_ENCRYPT = BIT(6), + TPM2_SA_AUDIT = BIT(7), +}; + +enum tpm2_pcr_select { + TPM2_PLATFORM_PCR = 24, + TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8), +}; + +enum tpm2_handle_types { + TPM2_HT_HMAC_SESSION = 0x02000000, + TPM2_HT_POLICY_SESSION = 0x03000000, + TPM2_HT_TRANSIENT = 0x80000000, +}; + +enum tpm2_pt_props { + TPM2_PT_NONE = 0x00000000, + TPM2_PT_GROUP = 0x00000100, + TPM2_PT_FIXED = TPM2_PT_GROUP * 1, + TPM2_PT_FAMILY_INDICATOR = TPM2_PT_FIXED + 0, + TPM2_PT_LEVEL = TPM2_PT_FIXED + 1, + TPM2_PT_REVISION = TPM2_PT_FIXED + 2, + TPM2_PT_DAY_OF_YEAR = TPM2_PT_FIXED + 3, + TPM2_PT_YEAR = TPM2_PT_FIXED + 4, + TPM2_PT_MANUFACTURER = TPM2_PT_FIXED + 5, + TPM2_PT_VENDOR_STRING_1 = TPM2_PT_FIXED + 6, + TPM2_PT_VENDOR_STRING_2 = TPM2_PT_FIXED + 7, + TPM2_PT_VENDOR_STRING_3 = TPM2_PT_FIXED + 8, + TPM2_PT_VENDOR_STRING_4 = TPM2_PT_FIXED + 9, + TPM2_PT_VENDOR_TPM_TYPE = TPM2_PT_FIXED + 10, + TPM2_PT_FIRMWARE_VERSION_1 = TPM2_PT_FIXED + 11, + TPM2_PT_FIRMWARE_VERSION_2 = TPM2_PT_FIXED + 12, + TPM2_PT_INPUT_BUFFER = TPM2_PT_FIXED + 13, + TPM2_PT_HR_TRANSIENT_MIN = TPM2_PT_FIXED + 14, + TPM2_PT_HR_PERSISTENT_MIN = TPM2_PT_FIXED + 15, + TPM2_PT_HR_LOADED_MIN = TPM2_PT_FIXED + 16, + TPM2_PT_ACTIVE_SESSIONS_MAX = TPM2_PT_FIXED + 17, + TPM2_PT_PCR_COUNT = TPM2_PT_FIXED + 18, + TPM2_PT_PCR_SELECT_MIN = TPM2_PT_FIXED + 19, + TPM2_PT_CONTEXT_GAP_MAX = TPM2_PT_FIXED + 20, + TPM2_PT_NV_COUNTERS_MAX = TPM2_PT_FIXED + 22, + TPM2_PT_NV_INDEX_MAX = TPM2_PT_FIXED + 23, + TPM2_PT_MEMORY = TPM2_PT_FIXED + 24, + TPM2_PT_CLOCK_UPDATE = TPM2_PT_FIXED + 25, + TPM2_PT_CONTEXT_HASH = TPM2_PT_FIXED + 26, + TPM2_PT_CONTEXT_SYM = TPM2_PT_FIXED + 27, + TPM2_PT_CONTEXT_SYM_SIZE = TPM2_PT_FIXED + 28, + TPM2_PT_ORDERLY_COUNT = TPM2_PT_FIXED + 29, + TPM2_PT_MAX_COMMAND_SIZE = TPM2_PT_FIXED + 30, + TPM2_PT_MAX_RESPONSE_SIZE = TPM2_PT_FIXED + 31, + TPM2_PT_MAX_DIGEST = TPM2_PT_FIXED + 32, + TPM2_PT_MAX_OBJECT_CONTEXT = TPM2_PT_FIXED + 33, + TPM2_PT_MAX_SESSION_CONTEXT = TPM2_PT_FIXED + 34, + TPM2_PT_PS_FAMILY_INDICATOR = TPM2_PT_FIXED + 35, + TPM2_PT_PS_LEVEL = TPM2_PT_FIXED + 36, + TPM2_PT_PS_REVISION = TPM2_PT_FIXED + 37, + TPM2_PT_PS_DAY_OF_YEAR = TPM2_PT_FIXED + 38, + TPM2_PT_PS_YEAR = TPM2_PT_FIXED + 39, + TPM2_PT_SPLIT_MAX = TPM2_PT_FIXED + 40, + TPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41, + TPM2_PT_LIBRARY_COMMANDS = TPM2_PT_FIXED + 42, + TPM2_PT_VENDOR_COMMANDS = TPM2_PT_FIXED + 43, + TPM2_PT_NV_BUFFER_MAX = TPM2_PT_FIXED + 44, + TPM2_PT_MODES = TPM2_PT_FIXED + 45, + TPM2_PT_MAX_CAP_BUFFER = TPM2_PT_FIXED + 46, + TPM2_PT_VAR = TPM2_PT_GROUP * 2, + TPM2_PT_PERMANENT = TPM2_PT_VAR + 0, + TPM2_PT_STARTUP_CLEAR = TPM2_PT_VAR + 1, + TPM2_PT_HR_NV_INDEX = TPM2_PT_VAR + 2, + TPM2_PT_HR_LOADED = TPM2_PT_VAR + 3, + TPM2_PT_HR_LOADED_AVAIL = TPM2_PT_VAR + 4, + TPM2_PT_HR_ACTIVE = TPM2_PT_VAR + 5, + TPM2_PT_HR_ACTIVE_AVAIL = TPM2_PT_VAR + 6, + TPM2_PT_HR_TRANSIENT_AVAIL = TPM2_PT_VAR + 7, + TPM2_PT_HR_PERSISTENT = TPM2_PT_VAR + 8, + TPM2_PT_HR_PERSISTENT_AVAIL = TPM2_PT_VAR + 9, + TPM2_PT_NV_COUNTERS = TPM2_PT_VAR + 10, + TPM2_PT_NV_COUNTERS_AVAIL = TPM2_PT_VAR + 11, + TPM2_PT_ALGORITHM_SET = TPM2_PT_VAR + 12, + TPM2_PT_LOADED_CURVES = TPM2_PT_VAR + 13, + TPM2_PT_LOCKOUT_COUNTER = TPM2_PT_VAR + 14, + TPM2_PT_MAX_AUTH_FAIL = TPM2_PT_VAR + 15, + TPM2_PT_LOCKOUT_INTERVAL = TPM2_PT_VAR + 16, + TPM2_PT_LOCKOUT_RECOVERY = TPM2_PT_VAR + 17, + TPM2_PT_NV_WRITE_RECOVERY = TPM2_PT_VAR + 18, + TPM2_PT_AUDIT_COUNTER_0 = TPM2_PT_VAR + 19, + TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20, +}; + +struct tpm2_pcr_read_out { + __be32 update_cnt; + __be32 pcr_selects_cnt; + __be16 hash_alg; + u8 pcr_select_size; + u8 pcr_select[TPM2_PCR_SELECT_MIN]; + __be32 digests_cnt; + __be16 digest_size; + u8 digest[]; +} __packed; + +struct tpm2_get_random_out { + __be16 size; + u8 buffer[TPM_MAX_RNG_DATA]; +} __packed; + +struct tpm2_get_cap_out { + u8 more_data; + __be32 subcap_id; + __be32 property_cnt; + __be32 property_id; + __be32 value; +} __packed; + +struct tpm2_pcr_selection { + __be16 hash_alg; + u8 size_of_select; + u8 pcr_select[3]; +} __packed; + +struct tpm2_context { + __be64 sequence; + __be32 saved_handle; + __be32 hierarchy; + __be16 blob_size; +} __packed; + +/* + * == TPM Common Defs == + */ + +#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ +#define TPM_BUFSIZE 4096 + +/* + * SHA-512 is, as of today, the largest digest in the TCG algorithm repository. + */ +#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE + +/* + * A TPM name digest i.e., TPMT_HA, is a concatenation of TPM_ALG_ID of the + * name algorithm and hash of TPMT_PUBLIC. + */ +#define TPM2_MAX_NAME_SIZE (TPM2_MAX_DIGEST_SIZE + 2) + +/* + * Fixed define for the size of a name. This is actually HASHALG size + * plus 2, so 32 for SHA256 + */ +#define TPM2_NULL_NAME_SIZE 34 + +/* + * The maximum number of PCR banks. + */ +#define TPM2_MAX_PCR_BANKS 8 + +/* If you add a new hash to this, increment TPM_MAX_HASHES below */ +enum tpm_algorithms { + TPM_ALG_ERROR = 0x0000, + TPM_ALG_SHA1 = 0x0004, + TPM_ALG_AES = 0x0006, + TPM_ALG_KEYEDHASH = 0x0008, + TPM_ALG_SHA256 = 0x000B, + TPM_ALG_SHA384 = 0x000C, + TPM_ALG_SHA512 = 0x000D, + TPM_ALG_NULL = 0x0010, + TPM_ALG_SM3_256 = 0x0012, + TPM_ALG_ECC = 0x0023, + TPM_ALG_CFB = 0x0043, +}; + +/* + * The locality (0 - 4) for a TPM, as defined in section 3.2 of the + * Client Platform Profile Specification. + */ +enum tpm_localities { + TPM_LOCALITY_0 = 0, /* Static RTM */ + TPM_LOCALITY_1 = 1, /* Dynamic OS */ + TPM_LOCALITY_2 = 2, /* DRTM Environment */ + TPM_LOCALITY_3 = 3, /* Aux Components */ + TPM_LOCALITY_4 = 4, /* CPU DRTM Establishment */ + TPM_MAX_LOCALITY = TPM_LOCALITY_4 +}; + +/* + * Structure to represent active PCR algorithm banks usable by the + * TPM chip. + */ +struct tpm_bank_info { + u16 alg_id; + u16 digest_size; + u16 crypto_id; +}; + +/* + * Maximum number of hashing algorithms a TPM can have. This is + * basically a count of every hash in tpm_algorithms above + */ +#define TPM_MAX_HASHES 5 + +struct tpm_digest { + u16 alg_id; + u8 digest[TPM2_MAX_DIGEST_SIZE]; +} __packed; + +#define TPM_HEADER_SIZE 10 + +struct tpm_header { + __be16 tag; + __be32 length; + union { + __be32 ordinal; + __be32 return_code; + }; +} __packed; #endif diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h index aff8ea2fa98e..40fe92eb7deb 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -3,7 +3,7 @@ #ifndef __LINUX_TPM_EVENTLOG_H__ #define __LINUX_TPM_EVENTLOG_H__ -#include <linux/tpm.h> +#include <linux/tpm_command.h> #define TCG_EVENT_NAME_LEN_MAX 255 #define MAX_TEXT_EVENT 1000 /* Max event string length */ diff --git a/include/linux/tpm_ptp.h b/include/linux/tpm_ptp.h new file mode 100644 index 000000000000..e80ed810a269 --- /dev/null +++ b/include/linux/tpm_ptp.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Following copyright information was take from the original file + * <drivers/char/tpm/tpm_tis_core.h> where the definitions were moved + * from: + * + * Copyright (C) 2005, 2006 IBM Corporation + * Copyright (C) 2014, 2015 Intel Corporation + * + * Authors: + * Leendert van Doorn <leendert@watson.ibm.com> + * Kylene Hall <kjhall@us.ibm.com> + * + * Maintained by: <tpmdd-devel@lists.sourceforge.net> + * + * Device driver for TCG/TCPA TPM (trusted platform module). + * Specifications at www.trustedcomputinggroup.org + * + * This device driver implements the TPM interface as defined in + * the TCG TPM Interface Spec version 1.2, revision 1.0. + */ + +#ifndef __LINUX_TPM_PTP_H__ +#define __LINUX_TPM_PTP_H__ + +/* + * TCG PC Client Platform TPM Profile (PTP) Specification + * https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/ + */ + +/* TIS/FIFO macros and definitions */ + +enum tis_access { + TPM_ACCESS_VALID = 0x80, + TPM_ACCESS_ACTIVE_LOCALITY = 0x20, /* (R) */ + TPM_ACCESS_RELINQUISH_LOCALITY = 0x20, /* (W) */ + TPM_ACCESS_REQUEST_PENDING = 0x04, /* (W) */ + TPM_ACCESS_REQUEST_USE = 0x02, /* (W) */ +}; + +enum tis_status { + TPM_STS_VALID = 0x80, /* (R) */ + TPM_STS_COMMAND_READY = 0x40, /* (R) */ + TPM_STS_DATA_AVAIL = 0x10, /* (R) */ + TPM_STS_DATA_EXPECT = 0x08, /* (R) */ + TPM_STS_GO = 0x20, /* (W) */ + TPM_STS_RESPONSE_RETRY = 0x02, /* (R) */ + TPM_STS_READ_ZERO = 0x23, /* bits that must be zero on read */ +}; + +enum tis_int_flags { + TPM_GLOBAL_INT_ENABLE = 0x80000000, + TPM_INTF_BURST_COUNT_STATIC = 0x100, + TPM_INTF_CMD_READY_INT = 0x080, + TPM_INTF_INT_EDGE_FALLING = 0x040, + TPM_INTF_INT_EDGE_RISING = 0x020, + TPM_INTF_INT_LEVEL_LOW = 0x010, + TPM_INTF_INT_LEVEL_HIGH = 0x008, + TPM_INTF_LOCALITY_CHANGE_INT = 0x004, + TPM_INTF_STS_VALID_INT = 0x002, + TPM_INTF_DATA_AVAIL_INT = 0x001, +}; + +enum tis_defaults { + TIS_MEM_LEN = 0x5000, + TIS_SHORT_TIMEOUT = 750, /* ms */ + TIS_LONG_TIMEOUT = 4000, /* 4 secs */ + TIS_TIMEOUT_MIN_ATML = 14700, /* usecs */ + TIS_TIMEOUT_MAX_ATML = 15000, /* usecs */ +}; + +#define TIS_MEM_X86_LPC_BASE 0xFED40000 +#define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000 + +enum tis_x86_defaults { + TIS_MEM_X86_LEN = 0x5000, + ILB_REMAP_SIZE = 0x100, + LPC_CNTRL_OFFSET = 0x84, + LPC_CLKRUN_EN = (1 << 2), +}; + +/* + * Some timeout values are needed before it is known whether the chip is + * TPM 1.0 or TPM 2.0. + */ +#define TIS_TIMEOUT_A_MAX max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_A) +#define TIS_TIMEOUT_B_MAX max_t(int, TIS_LONG_TIMEOUT, TPM2_TIMEOUT_B) +#define TIS_TIMEOUT_C_MAX max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_C) +#define TIS_TIMEOUT_D_MAX max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_D) + +#define TPM_ACCESS(l) (0x0000 | ((l) << 12)) +#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12)) +#define TPM_INT_VECTOR(l) (0x000C | ((l) << 12)) +#define TPM_INT_STATUS(l) (0x0010 | ((l) << 12)) +#define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12)) +#define TPM_STS(l) (0x0018 | ((l) << 12)) +#define TPM_STS3(l) (0x001b | ((l) << 12)) +#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12)) +#define TPM_INTF_ID(l) (0x0030 | ((l) << 12)) + +#define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) +#define TPM_RID(l) (0x0F04 | ((l) << 12)) + +/* TPM HW Interface and Capabilities */ +#define TPM_TIS_INTF_ACTIVE 0x00 +#define TPM_CRB_INTF_ACTIVE 0x01 + +#define TPM_INTID_INTERFACE_TYPE GENMASK(3, 0) +#define TPM_INTID_INTERFACE_VERSION GENMASK(7, 4) +#define TPM_INTID_CAP_LOCALITY BIT(8) +#define TPM_INTID_CAP_TIS BIT(13) +#define TPM_INTID_CAP_CRB BIT(14) +#define TPM_INTID_CAP_IF_RES GENMASK(16, 15) +#define TPM_INTID_INTERFACE_SELECTOR GENMASK(18, 17) +#define TPM_INTID_INTF_SEL_LOCK BIT(19) + +#define TPM_TIS_INTF_12 0x00 +#define TPM_TIS_INTF_13 0x02 +#define TPM2_TIS_INTF_13 0x03 + +#define TPM_INTF_DATA_AVAIL_INT_SUPPORT BIT(0) +#define TPM_INTF_STS_VALID_INT_SUPPORT BIT(1) +#define TPM_INTF_LOCALITY_CHANGE_INT_SUPPORT BIT(2) +#define TPM_INTF_INTERRUPT_LEVEL_HIGH BIT(3) +#define TPM_INTF_INTERRUPT_LEVEL_LOW BIT(4) +#define TPM_INTF_INTERRUPT_EDGE_RISING BIT(5) +#define TPM_INTF_INTERRUPT_EDGE_FALLING BIT(6) +#define TPM_INTF_COMMAND_READY_INT_SUPPORT BIT(7) +#define TPM_INTF_BURST_COUNT_STATIC BIT(8) +#define TPM_INTF_DATA_TRANSFER_SIZE_SUPPORT GENMASK(10, 9) +#define TPM_INTF_INTERFACE_VERSION GENMASK(30, 28) + +#endif diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 308c76b57d13..5cbd09c8be8d 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -298,6 +298,15 @@ struct trace_event_class { struct list_head *(*get_fields)(struct trace_event_call *); struct list_head fields; int (*raw_init)(struct trace_event_call *); +#ifdef CONFIG_BPF_EVENTS + /* + * Per-template BTF ids set by DECLARE_EVENT_CLASS via BTF_ID() and + * patched by resolve_btfids at link time. NULL for handcrafted classes. + * [0] FUNC __bpf_trace_<template> + * [1] STRUCT trace_event_raw_<template> + */ + const u32 *btf_ids; +#endif }; extern int trace_event_reg(struct trace_event_call *event, diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 4a0c36f40fe2..e0d838c9ce93 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -292,13 +292,18 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) { \ } \ static inline bool \ + __trace_##name##_enabled(void) \ + { \ + return static_branch_unlikely(&__tracepoint_##name.key);\ + } \ + 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);\ + return __trace_##name##_enabled(); \ } #define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ @@ -457,6 +462,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) { \ } \ static inline bool \ + __trace_##name##_enabled(void) \ + { \ + return false; \ + } \ + static inline bool \ trace_##name##_enabled(void) \ { \ return false; \ diff --git a/include/linux/types.h b/include/linux/types.h index 93166b0b0617..53e0adca4b9f 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -163,6 +163,8 @@ typedef u32 dma_addr_t; typedef unsigned int __bitwise gfp_t; typedef unsigned int __bitwise slab_flags_t; typedef unsigned int __bitwise fmode_t; +typedef unsigned int __bitwise blk_mode_t; +typedef unsigned int __bitwise fop_flags_t; #ifdef CONFIG_PHYS_ADDR_T_64BIT typedef u64 phys_addr_t; @@ -255,6 +257,16 @@ struct callback_head { } __attribute__((aligned(sizeof(void *)))); #define rcu_head callback_head +#ifdef CONFIG_KVFREE_RCU_BATCHED +struct kvfree_rcu_head { + struct kvfree_rcu_head *next; +}; +#else +struct kvfree_rcu_head { + struct rcu_head head; +}; +#endif + typedef void (*rcu_callback_t)(struct rcu_head *head); typedef void (*call_rcu_func_t)(struct rcu_head *head, rcu_callback_t func); diff --git a/include/linux/udp.h b/include/linux/udp.h index ce56ebcee5cb..998906ec3b32 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h @@ -23,6 +23,33 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb) return (struct udphdr *)skb_transport_header(skb); } +static inline unsigned int udp_get_len(const struct sk_buff *skb, + const struct udphdr *uh, + unsigned int dataoff) +{ + if (uh->len) + return ntohs(uh->len); + if (skb_is_gso(skb)) /* BIG TCP */ + return skb->len - dataoff; + return 0; +} + +static inline unsigned int udp_get_len_short(const struct udphdr *uh) +{ + return ntohs(uh->len); +} + +static inline void udp_set_len(struct udphdr *uh, unsigned int len) +{ + uh->len = len < GRO_LEGACY_MAX_SIZE ? htons(len) : 0; +} + +static inline void udp_set_len_short(struct udphdr *uh, unsigned int len) +{ + DEBUG_NET_WARN_ON_ONCE(len >= GRO_LEGACY_MAX_SIZE); + uh->len = htons(len); +} + #define UDP_HTABLE_SIZE_MIN_PERNET 128 #define UDP_HTABLE_SIZE_MIN (IS_ENABLED(CONFIG_BASE_SMALL) ? 128 : 256) #define UDP_HTABLE_SIZE_MAX 65536 diff --git a/include/linux/uio.h b/include/linux/uio.h index a9bc5b3067e3..fe2e985d74d2 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -389,9 +389,17 @@ ssize_t iov_iter_extract_pages(struct iov_iter *i, struct page ***pages, size_t maxsize, unsigned int maxpages, iov_iter_extraction_t extraction_flags, size_t *offset0); +/* + * Block-layer consumers (e.g. bio_iov_iter_get_pages()) require that the + * segments of an ITER_BVEC iterator are already aligned to the target device's + * DMA alignment, and forward them as-is. In-kernel users that build their own + * bvecs must not create sub-aligned segments; iov_iter_extract_bvecs() enforces + * the same for the segments it extracts via @mem_align_mask. + */ ssize_t iov_iter_extract_bvecs(struct iov_iter *iter, struct bio_vec *bv, size_t max_size, unsigned short *nr_vecs, - unsigned short max_vecs, iov_iter_extraction_t extraction_flags); + unsigned short max_vecs, unsigned mem_align_mask, + iov_iter_extraction_t extraction_flags); /** * iov_iter_extract_will_pin - Indicate how pages from the iterator will be retained diff --git a/include/linux/ulpi/driver.h b/include/linux/ulpi/driver.h index a8cb617a3028..c668d9c8d876 100644 --- a/include/linux/ulpi/driver.h +++ b/include/linux/ulpi/driver.h @@ -2,7 +2,7 @@ #ifndef __LINUX_ULPI_DRIVER_H #define __LINUX_ULPI_DRIVER_H -#include <linux/mod_devicetable.h> +#include <linux/device-id/ulpi.h> #include <linux/device.h> diff --git a/include/linux/unicode.h b/include/linux/unicode.h index 5e6b212a2aed..64fa44fe180c 100644 --- a/include/linux/unicode.h +++ b/include/linux/unicode.h @@ -66,9 +66,6 @@ int utf8_strncasecmp_folded(const struct unicode_map *um, const struct qstr *cf, const struct qstr *s1); -int utf8_normalize(const struct unicode_map *um, const struct qstr *str, - unsigned char *dest, size_t dlen); - int utf8_casefold(const struct unicode_map *um, const struct qstr *str, unsigned char *dest, size_t dlen); diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index f548fea2adec..d34dbc0fbbfe 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -25,6 +25,7 @@ struct mm_struct; struct inode; struct notifier_block; struct page; +struct srcu_ctr; /* * Allowed return values from uprobe consumer's handler callback @@ -106,7 +107,7 @@ enum hprobe_state { * underlying uprobe is not guaranteed anymore. __UPROBE_DEAD is just an * internal marker and is handled transparently by hprobe_fetch() helper. * - * When uprobe is SRCU-protected, we also record srcu_idx value, necessary for + * When uprobe is SRCU-protected, we also record srcu_scp value, necessary for * SRCU unlocking. * * See hprobe_expire() and hprobe_fetch() for details of race-free uprobe @@ -115,7 +116,7 @@ enum hprobe_state { */ struct hprobe { enum hprobe_state state; - int srcu_idx; + struct srcu_ctr __percpu *srcu_scp; struct uprobe *uprobe; }; @@ -186,9 +187,6 @@ struct xol_area; struct uprobes_state { struct xol_area *xol_area; -#ifdef CONFIG_X86_64 - struct hlist_head head_tramps; -#endif }; typedef int (*uprobe_write_verify_t)(struct page *page, unsigned long vaddr, @@ -238,8 +236,6 @@ extern void uprobe_handle_trampoline(struct pt_regs *regs); extern void *arch_uretprobe_trampoline(unsigned long *psize); extern unsigned long uprobe_get_trampoline_vaddr(void); extern void uprobe_copy_from_page(struct page *page, unsigned long vaddr, void *dst, int len); -extern void arch_uprobe_clear_state(struct mm_struct *mm); -extern void arch_uprobe_init_state(struct mm_struct *mm); extern void handle_syscall_uprobe(struct pt_regs *regs, unsigned long bp_vaddr); extern void arch_uprobe_optimize(struct arch_uprobe *auprobe, unsigned long vaddr); extern unsigned long arch_uprobe_get_xol_area(void); diff --git a/include/linux/usb.h b/include/linux/usb.h index 25a203ac7a7e..49ab8dbb885f 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -2,7 +2,7 @@ #ifndef __LINUX_USB_H #define __LINUX_USB_H -#include <linux/mod_devicetable.h> +#include <linux/device-id/usb.h> #include <linux/usb/ch9.h> #define USB_MAJOR 180 @@ -1185,7 +1185,8 @@ extern ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf); * interface. It may also use usb_set_interface() to specify the * appropriate altsetting. If unwilling to manage the interface, * return -ENODEV, if genuine IO errors occurred, an appropriate - * negative errno value. + * negative errno value. The usb_device_id parameter is only valid during + * probe. * @disconnect: Called when the interface is no longer accessible, usually * because its device has been (or is being) disconnected or the * driver module is being unloaded. diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index a2f6f1e04efb..4bb04a371105 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -2,7 +2,7 @@ /* * mctp-usb.h - MCTP USB transport binding: common definitions, * based on DMTF0283 specification: - * https://www.dmtf.org/sites/default/files/standards/documents/DSP0283_1.0.1.pdf + * https://www.dmtf.org/sites/default/files/standards/documents/DSP0283_1.1.0.pdf * * These are protocol-level definitions, that may be shared between host * and gadget drivers. @@ -13,18 +13,96 @@ #ifndef __LINUX_USB_MCTP_USB_H #define __LINUX_USB_MCTP_USB_H +#include <linux/netdevice.h> +#include <linux/skbuff.h> #include <linux/types.h> +/* + * MCTP-over-USB transport header. DSP0283 v1.0 has an 8-bit length field + * (preceded by 8 reserved bits), v1.1 has a 13-bit length field (preceded by + * 3 reserved bits). We use a be16 for our length to handle the larger v1.1 + * representation, and mask as appropriate. + */ struct mctp_usb_hdr { __be16 id; - u8 rsvd; - u8 len; + __be16 len; } __packed; -#define MCTP_USB_XFER_SIZE 512 +/* max transfer size for DSP0283 v1.0 */ +#define MCTP_USB_1_0_XFER_SIZE 512 #define MCTP_USB_BTU 68 #define MCTP_USB_MTU_MIN MCTP_USB_BTU -#define MCTP_USB_MTU_MAX (U8_MAX - sizeof(struct mctp_usb_hdr)) +#define MCTP_USB_1_0_PKTLEN_MAX U8_MAX +#define MCTP_USB_1_0_MTU_MAX (MCTP_USB_1_0_PKTLEN_MAX - sizeof(struct mctp_usb_hdr)) +#define MCTP_USB_1_1_PKTLEN_MAX GENMASK(12, 0) +#define MCTP_USB_1_1_MTU_MAX (MCTP_USB_1_1_PKTLEN_MAX - sizeof(struct mctp_usb_hdr)) #define MCTP_USB_DMTF_ID 0x1ab4 +/* mctp-usblib */ + +/* + * RX handle: drivers will typically create one on init, which persists for + * the life of the driver. The same handle is used for progressive + * prepare -> complete operations (for each incoming USB transfer), which + * result in netif_rx()-ing the MCTP packets received + */ +struct mctp_usblib_rx { + struct sk_buff *skb; + u16 ep_pktlen; + bool span; +}; + +int mctp_usblib_rx_init(struct mctp_usblib_rx *rx, u16 ep_pktlen, bool span); +void mctp_usblib_rx_fini(struct mctp_usblib_rx *rx); + +int mctp_usblib_rx_prepare(struct net_device *netdev, + struct mctp_usblib_rx *rx, + void **bufp, size_t *lenp, gfp_t gfp); + +int mctp_usblib_rx_complete(struct net_device *netdev, + struct mctp_usblib_rx *rx, size_t len); + +void mctp_usblib_rx_cancel(struct mctp_usblib_rx *rx); + +/* + * TX handle: created by mctp_usblib_tx_push() during the tx path, and + * may persist across multiple packet transmits. + */ +struct mctp_usblib_tx_ctx; + +struct mctp_usblib_tx_ops { + /* Start a USB TX for @data. On returning success, the implementation + * must arrange for mctp_usblib_tx_send_complete() to be called at some + * later point (eg., on urb completion). + */ + int (*send)(struct mctp_usblib_tx_ctx *tx_ctx, void *data, size_t len); +}; + +struct mctp_usblib_tx { + struct mctp_usblib_tx_ops ops; + void *priv; + bool span; + /* protects access to cur_ctx */ + spinlock_t lock; + /* context to which we are adding packets, cleared on send */ + struct mctp_usblib_tx_ctx *cur_ctx; +}; + +void mctp_usblib_tx_init(struct mctp_usblib_tx *tx, + const struct mctp_usblib_tx_ops *ops, void *priv, + bool span); +void mctp_usblib_tx_fini(struct mctp_usblib_tx *tx); + +void *mctp_usblib_tx_ctx_priv(struct mctp_usblib_tx_ctx *tx_ctx); + +int mctp_usblib_tx_push(struct net_device *dev, + struct mctp_usblib_tx *tx, + struct sk_buff *skb, bool more); + +void mctp_usblib_tx_send_complete(struct mctp_usblib_tx_ctx *tx_ctx, + struct net_device *dev, bool ok); + +void mctp_usblib_tx_cancel(struct mctp_usblib_tx *tx, struct net_device *dev, + enum skb_drop_reason reason); + #endif /* __LINUX_USB_MCTP_USB_H */ diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h index 337a5485af7c..914e78f8acfd 100644 --- a/include/linux/usb/pd.h +++ b/include/linux/usb/pd.h @@ -106,6 +106,9 @@ enum pd_ext_msg_type { #define PD_HEADER_LE(type, pwr, data, rev, id, cnt) \ cpu_to_le16(PD_HEADER((type), (pwr), (data), (rev), (id), (cnt), (0))) +#define PD_HEADER_EXT_LE(type, pwr, data, rev, id, cnt) \ + cpu_to_le16(PD_HEADER((type), (pwr), (data), (rev), (id), (cnt), (1))) + static inline unsigned int pd_header_cnt(u16 header) { return (header >> PD_HEADER_CNT_SHIFT) & PD_HEADER_CNT_MASK; @@ -219,6 +222,25 @@ static inline u8 count_chunked_data_objs(u32 size) return ((size / 4) + (size % 4 ? 1 : 0)); } +/** + * batt_cap_ext_msg - Battery capability extended PD message + * @vid: Battery Vendor ID (assigned by USB-IF) + * @pid: Battery Product ID (assigned by battery or device vendor) + * @batt_design_cap: Battery design capacity in 0.1Wh + * @batt_last_chg_cap: Battery last full charge capacity in 0.1Wh + * @batt_type: Battery Type. bit0 when set indicates invalid battery reference. + * Rest of the bits are reserved. + */ +struct batt_cap_ext_msg { + __le16 vid; + __le16 pid; + __le16 batt_design_cap; + __le16 batt_last_chg_cap; + u8 batt_type; +} __packed; + +#define BATT_CAP_BATT_TYPE_INVALID_REF BIT(0) + /* Sink Caps Extended Data Block Version */ #define SKEDB_VER_1_0 1 @@ -493,7 +515,7 @@ static inline unsigned int pdo_epr_avs_apdo_min_voltage_mv(u32 pdo) static inline unsigned int pdo_epr_avs_apdo_max_voltage_mv(u32 pdo) { - return FIELD_GET(PDO_EPR_AVS_APDO_MIN_VOLT, pdo) * 100; + return FIELD_GET(PDO_EPR_AVS_APDO_MAX_VOLT, pdo) * 100; } static inline unsigned int pdo_epr_avs_apdo_pdp_w(u32 pdo) @@ -724,4 +746,33 @@ void usb_power_delivery_unlink_device(struct usb_power_delivery *pd, struct devi #endif /* CONFIG_TYPEC */ +/* Battery Status Data Object */ +#define BSDO_PRESENT_CAPACITY GENMASK(31, 16) +#define BSDO_CHG_STATUS GENMASK(11, 10) +#define BSDO_BATTERY_PRESENT BIT(9) +#define BSDO_INVALID_BATTERY_REFERENCE BIT(8) + +/* + * Battery Charge Status: Battery Charging Status Values as defined in + * "USB PD Spec Rev3.1 Ver1.8", "Table 6-46 Battery Status Data Object (BSDO)". + */ +#define BSDO_BATTERY_INFO_CHARGING 0x0 +#define BSDO_BATTERY_INFO_DISCHARGING 0x1 +#define BSDO_BATTERY_INFO_IDLE 0x2 +#define BSDO_BATTERY_INFO_RSVD 0x3 + +/** + * BSDO() - Pack data into Battery Status Data Object format. + * @batt_charge: Battery's present state of charge in 0.1WH increment. + * @chg_status: Battery charge status. + * @batt_present: Indicates that battery is present/attached when set else absent when unset. + * @invalid_ref: Indicates that an invalid battery reference was made in the Get_Battery_Status + * request. + */ +#define BSDO(batt_charge, chg_status, batt_present, invalid_ref) \ + ((FIELD_PREP(BSDO_PRESENT_CAPACITY, batt_charge)) | \ + (FIELD_PREP(BSDO_CHG_STATUS, chg_status)) | \ + ((batt_present) ? BSDO_BATTERY_PRESENT : 0) | \ + ((invalid_ref) ? BSDO_INVALID_BATTERY_REFERENCE : 0)) + #endif /* __LINUX_USB_PD_H */ diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index b3cc7beab4a3..a4043b33c2c2 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h @@ -81,4 +81,7 @@ /* Device claims zero configurations, forcing to 1 */ #define USB_QUIRK_FORCE_ONE_CONFIG BIT(18) +/* Use a 255 bytes config descriptor request mirroring windows behavior */ +#define USB_QUIRK_WINDOWS_CONFIG_REQ_SIZE BIT(19) + #endif /* __LINUX_USB_QUIRKS_H */ diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 75b2b763f1ba..534e6650e2aa 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -13,6 +13,7 @@ #include <linux/mutex.h> #include <linux/serial.h> #include <linux/kfifo.h> +#include <linux/usb.h> /* The maximum number of ports one device can grab at once */ #define MAX_NUM_PORTS 16 diff --git a/include/linux/usb/tcpci.h b/include/linux/usb/tcpci.h index f7f5cfbdef12..9b46a6bc762c 100644 --- a/include/linux/usb/tcpci.h +++ b/include/linux/usb/tcpci.h @@ -144,6 +144,7 @@ #define TCPC_RX_BUF_FRAME_TYPE 0x31 #define TCPC_RX_BUF_FRAME_TYPE_SOP 0 #define TCPC_RX_BUF_FRAME_TYPE_SOP1 1 +#define TCPC_RX_BUF_FRAME_TYPE_MASK GENMASK(2, 0) #define TCPC_RX_HDR 0x32 #define TCPC_RX_DATA 0x34 /* through 0x4f */ diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index d61ec38216fa..10a783b738ef 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -337,6 +337,7 @@ void typec_unregister_cable(struct typec_cable *cable); struct typec_cable *typec_cable_get(struct typec_port *port); void typec_cable_put(struct typec_cable *cable); int typec_cable_is_active(struct typec_cable *cable); +bool typec_cable_altmode_unsupported(struct typec_altmode *alt); struct typec_plug *typec_register_plug(struct typec_cable *cable, struct typec_plug_desc *desc); diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h index b90cc5cfff8d..ef21ead551be 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -3,7 +3,7 @@ #ifndef __USB_TYPEC_ALTMODE_H #define __USB_TYPEC_ALTMODE_H -#include <linux/mod_devicetable.h> +#include <linux/device-id/typec.h> #include <linux/usb/typec.h> #include <linux/device.h> diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index 9c3be157397e..e38d9e60569f 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -58,6 +58,9 @@ enum ucount_type { UCOUNT_FANOTIFY_GROUPS, UCOUNT_FANOTIFY_MARKS, #endif +#if IS_ENABLED(CONFIG_BINFMT_MISC) + UCOUNT_BINFMT_MISC_INTERPRETERS, +#endif UCOUNT_COUNTS, }; diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h index 68edac4dcd78..a4351cffc60c 100644 --- a/include/linux/userfaultfd_k.h +++ b/include/linux/userfaultfd_k.h @@ -21,10 +21,11 @@ #include <linux/hugetlb_inline.h> /* The set of all possible UFFD-related VM flags. */ -#define __VM_UFFD_FLAGS (VM_UFFD_MISSING | VM_UFFD_WP | VM_UFFD_MINOR) +#define __VM_UFFD_FLAGS (VM_UFFD_MISSING | VM_UFFD_MINOR | \ + VM_UFFD_WP | VM_UFFD_RWP) #define __VMA_UFFD_FLAGS mk_vma_flags_from_masks(VMA_UFFD_MISSING, VMA_UFFD_WP, \ - VMA_UFFD_MINOR) + VMA_UFFD_MINOR, VMA_UFFD_RWP) /* * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining @@ -149,6 +150,8 @@ static inline uffd_flags_t uffd_flags_set_mode(uffd_flags_t flags, enum mfill_at extern long uffd_wp_range(struct vm_area_struct *vma, unsigned long start, unsigned long len, bool enable_wp); +extern int mrwprotect_range(struct userfaultfd_ctx *ctx, unsigned long start, + unsigned long len, bool enable_rwp); /* move_pages */ void double_pt_lock(spinlock_t *ptl1, spinlock_t *ptl2); @@ -168,7 +171,8 @@ static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma, /* * Never enable huge pmd sharing on some uffd registered vmas: * - * - VM_UFFD_WP VMAs, because write protect information is per pgtable entry. + * - VM_UFFD_WP and VM_UFFD_RWP VMAs, because the write protect / access + * tracking information is per pgtable entry. * * - VM_UFFD_MINOR VMAs, because otherwise we would never get minor faults for * VMAs which share huge pmds. (If you have two mappings to the same @@ -178,51 +182,86 @@ static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma, */ static inline bool uffd_disable_huge_pmd_share(struct vm_area_struct *vma) { - return vma->vm_flags & (VM_UFFD_WP | VM_UFFD_MINOR); + return vma_test_any_mask(vma, + mk_vma_flags_from_masks(VMA_UFFD_WP, VMA_UFFD_RWP, + VMA_UFFD_MINOR)); } /* - * Don't do fault around for either WP or MINOR registered uffd range. For + * Don't do fault around for WP, RWP or MINOR registered uffd range. For * MINOR registered range, fault around will be a total disaster and ptes can * be installed without notifications; for WP it should mostly be fine as long * as the fault around checks for pte_none() before the installation, however - * to be super safe we just forbid it. + * to be super safe we just forbid it; for RWP, pre-faulted neighbours would + * be indistinguishable from accessed pages in PAGEMAP_SCAN (PAGE_IS_ACCESSED) + * and pollute the tracked working set, so each page must be populated by its + * own fault. */ static inline bool uffd_disable_fault_around(struct vm_area_struct *vma) { - return vma->vm_flags & (VM_UFFD_WP | VM_UFFD_MINOR); + return vma_test_any_mask(vma, + mk_vma_flags_from_masks(VMA_UFFD_WP, VMA_UFFD_RWP, + VMA_UFFD_MINOR)); } static inline bool userfaultfd_missing(struct vm_area_struct *vma) { - return vma->vm_flags & VM_UFFD_MISSING; + return vma_test_any_mask(vma, VMA_UFFD_MISSING); } static inline bool userfaultfd_wp(struct vm_area_struct *vma) { - return vma->vm_flags & VM_UFFD_WP; + return vma_test_any_mask(vma, VMA_UFFD_WP); } static inline bool userfaultfd_minor(struct vm_area_struct *vma) { - return vma->vm_flags & VM_UFFD_MINOR; + return vma_test_any_mask(vma, VMA_UFFD_MINOR); +} + +static inline bool userfaultfd_rwp(struct vm_area_struct *vma) +{ + /* + * Callers gate PAGE_NONE usage on this; PAGE_NONE is a BUILD_BUG() + * without CONFIG_ARCH_HAS_PTE_PROTNONE, so fold to false. + */ + if (!IS_ENABLED(CONFIG_ARCH_HAS_PTE_PROTNONE)) + return false; + return vma_test_single_mask(vma, VMA_UFFD_RWP); +} + +static inline bool userfaultfd_protected(struct vm_area_struct *vma) +{ + return userfaultfd_wp(vma) || userfaultfd_rwp(vma); } static inline bool userfaultfd_pte_wp(struct vm_area_struct *vma, pte_t pte) { - return userfaultfd_wp(vma) && pte_uffd_wp(pte); + return userfaultfd_wp(vma) && pte_uffd(pte); } static inline bool userfaultfd_huge_pmd_wp(struct vm_area_struct *vma, pmd_t pmd) { - return userfaultfd_wp(vma) && pmd_uffd_wp(pmd); + return userfaultfd_wp(vma) && pmd_uffd(pmd); +} + +static inline bool userfaultfd_pte_rwp(struct vm_area_struct *vma, + pte_t pte) +{ + return userfaultfd_rwp(vma) && pte_uffd(pte); +} + +static inline bool userfaultfd_huge_pmd_rwp(struct vm_area_struct *vma, + pmd_t pmd) +{ + return userfaultfd_rwp(vma) && pmd_uffd(pmd); } static inline bool userfaultfd_armed(struct vm_area_struct *vma) { - return vma->vm_flags & __VM_UFFD_FLAGS; + return vma_test_any_mask(vma, __VMA_UFFD_FLAGS); } static inline bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma) @@ -253,6 +292,7 @@ extern void userfaultfd_unmap_complete(struct mm_struct *mm, struct list_head *uf); extern bool userfaultfd_wp_unpopulated(struct vm_area_struct *vma); extern bool userfaultfd_wp_async(struct vm_area_struct *vma); +extern bool userfaultfd_rwp_async(struct vm_area_struct *vma); static inline bool userfaultfd_wp_use_markers(struct vm_area_struct *vma) { @@ -272,10 +312,10 @@ static inline bool userfaultfd_wp_use_markers(struct vm_area_struct *vma) } /* - * Returns true if this is a swap pte and was uffd-wp wr-protected in either - * forms (pte marker or a normal swap pte), false otherwise. + * Returns true if this swap pte carries uffd-tracked state in either + * form (pte marker or a normal swap pte), false otherwise. */ -static inline bool pte_swp_uffd_wp_any(pte_t pte) +static inline bool pte_swp_uffd_any(pte_t pte) { if (!uffd_supports_wp_marker()) return false; @@ -283,7 +323,7 @@ static inline bool pte_swp_uffd_wp_any(pte_t pte) if (pte_present(pte)) return false; - if (pte_swp_uffd_wp(pte)) + if (pte_swp_uffd(pte)) return true; if (pte_is_uffd_wp_marker(pte)) @@ -328,6 +368,16 @@ static inline bool userfaultfd_minor(struct vm_area_struct *vma) return false; } +static inline bool userfaultfd_rwp(struct vm_area_struct *vma) +{ + return false; +} + +static inline bool userfaultfd_protected(struct vm_area_struct *vma) +{ + return false; +} + static inline bool userfaultfd_pte_wp(struct vm_area_struct *vma, pte_t pte) { @@ -340,6 +390,17 @@ static inline bool userfaultfd_huge_pmd_wp(struct vm_area_struct *vma, return false; } +static inline bool userfaultfd_pte_rwp(struct vm_area_struct *vma, + pte_t pte) +{ + return false; +} + +static inline bool userfaultfd_huge_pmd_rwp(struct vm_area_struct *vma, + pmd_t pmd) +{ + return false; +} static inline bool userfaultfd_armed(struct vm_area_struct *vma) { @@ -410,6 +471,11 @@ static inline bool userfaultfd_wp_async(struct vm_area_struct *vma) return false; } +static inline bool userfaultfd_rwp_async(struct vm_area_struct *vma) +{ + return false; +} + static inline bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma) { return false; @@ -421,10 +487,10 @@ static inline bool userfaultfd_wp_use_markers(struct vm_area_struct *vma) } /* - * Returns true if this is a swap pte and was uffd-wp wr-protected in either - * forms (pte marker or a normal swap pte), false otherwise. + * Returns true if this swap pte carries uffd-tracked state in either + * form (pte marker or a normal swap pte), false otherwise. */ -static inline bool pte_swp_uffd_wp_any(pte_t pte) +static inline bool pte_swp_uffd_any(pte_t pte) { return false; } diff --git a/include/linux/utsname.h b/include/linux/utsname.h index 547bd4439706..dc5594ffffcc 100644 --- a/include/linux/utsname.h +++ b/include/linux/utsname.h @@ -18,7 +18,7 @@ enum uts_proc { UTS_PROC_DOMAINNAME, }; -#ifdef CONFIG_PROC_SYSCTL +#ifdef CONFIG_SYSCTL extern void uts_proc_notify(enum uts_proc proc); #else static inline void uts_proc_notify(enum uts_proc proc) diff --git a/include/linux/vdso_datastore.h b/include/linux/vdso_datastore.h index 3dfba9502d78..13b01baf3497 100644 --- a/include/linux/vdso_datastore.h +++ b/include/linux/vdso_datastore.h @@ -7,10 +7,10 @@ extern const struct vm_special_mapping vdso_vvar_mapping; struct vm_area_struct *vdso_install_vvar_mapping(struct mm_struct *mm, unsigned long addr); -#ifdef CONFIG_HAVE_GENERIC_VDSO +#ifdef CONFIG_VDSO_DATASTORE void __init vdso_setup_data_pages(void); -#else /* !CONFIG_HAVE_GENERIC_VDSO */ +#else /* !CONFIG_VDSO_DATASTORE */ static inline void vdso_setup_data_pages(void) { } -#endif /* CONFIG_HAVE_GENERIC_VDSO */ +#endif /* CONFIG_VDSO_DATASTORE */ #endif /* _LINUX_VDSO_DATASTORE_H */ diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 31b826efba00..45f08986359e 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -74,6 +74,7 @@ struct vfio_device { u8 iommufd_attached:1; #endif u8 cdev_opened:1; + u8 noiommu:1; /* * debug_root is a static property of the vfio_device * which must be set prior to registering the vfio_device. diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index 5fc6ce4dd786..9a1674c152aa 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -101,6 +101,9 @@ struct vfio_pci_core_device { const struct vfio_pci_device_ops *pci_ops; void __iomem *barmap[PCI_STD_NUM_BARS]; bool bar_mmap_supported[PCI_STD_NUM_BARS]; + /* Flags modified at runtime - dedicated storage unit */ + bool virq_disabled; + bool bardirty; u8 *pci_config_map; u8 *vconfig; struct perm_bits *msi_perm; @@ -115,18 +118,21 @@ struct vfio_pci_core_device { u16 msix_size; u32 msix_offset; u32 rbar[7]; + /* Flags only modified on setup/release - bitfield ok */ bool has_dyn_msix:1; bool pci_2_3:1; - bool virq_disabled:1; bool reset_works:1; bool extended_caps:1; - bool bardirty:1; bool has_vga:1; - bool needs_reset:1; bool nointx:1; bool needs_pm_restore:1; - bool pm_intx_masked:1; - bool pm_runtime_engaged:1; + bool disable_idle_d3:1; + bool nointxmask:1; + bool disable_vga:1; + /* Flags modified at runtime - dedicated storage unit */ + bool needs_reset; + bool pm_intx_masked; + bool pm_runtime_engaged; bool sriov_active; struct pci_saved_state *pci_saved_state; struct pci_saved_state *pm_save; @@ -157,8 +163,6 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev, unsigned int type, unsigned int subtype, const struct vfio_pci_regops *ops, size_t size, u32 flags, void *data); -void vfio_pci_core_set_params(bool nointxmask, bool is_disable_vga, - bool is_disable_idle_d3); void vfio_pci_core_close_device(struct vfio_device *core_vdev); int vfio_pci_core_init_dev(struct vfio_device *core_vdev); void vfio_pci_core_release_dev(struct vfio_device *core_vdev); diff --git a/include/linux/virtio.h b/include/linux/virtio.h index bf089e51970e..f923e42cfd01 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -7,7 +7,7 @@ #include <linux/scatterlist.h> #include <linux/spinlock.h> #include <linux/device.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/virtio.h> #include <linux/gfp.h> #include <linux/dma-mapping.h> #include <linux/completion.h> @@ -213,6 +213,7 @@ int virtio_device_freeze(struct virtio_device *dev); int virtio_device_restore(struct virtio_device *dev); #endif void virtio_reset_device(struct virtio_device *dev); +void virtio_device_shutdown(struct virtio_device *dev); int virtio_device_reset_prepare(struct virtio_device *dev); int virtio_device_reset_done(struct virtio_device *dev); diff --git a/include/linux/virtio_dma_buf.h b/include/linux/virtio_dma_buf.h index a2fdf217ac62..545ac5f17a54 100644 --- a/include/linux/virtio_dma_buf.h +++ b/include/linux/virtio_dma_buf.h @@ -17,7 +17,7 @@ * @ops: the base dma_buf_ops. ops.attach MUST be virtio_dma_buf_attach. * @device_attach: [optional] callback invoked by virtio_dma_buf_attach during * all attach operations. - * @get_uid: [required] callback to get the uuid of the exported object. + * @get_uuid: [required] callback to get the uuid of the exported object. */ struct virtio_dma_buf_ops { struct dma_buf_ops ops; diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index f36d21b5bc19..c381b916c1b5 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -6,6 +6,7 @@ #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/udp.h> +#include <net/tcp.h> #include <uapi/linux/tcp.h> #include <uapi/linux/virtio_net.h> @@ -179,6 +180,9 @@ retry: if (skb->ip_summed == CHECKSUM_PARTIAL && skb->csum_offset != offsetof(struct tcphdr, check)) return -EINVAL; + + BUILD_BUG_ON(TCP_MIN_GSO_SIZE * GSO_MAX_SEGS < GSO_MAX_SIZE); + gso_size = max(gso_size, TCP_MIN_GSO_SIZE); break; } diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index 03fe95f5a020..2628ccda076a 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -175,6 +175,10 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, KSTACK_REST, #endif #endif /* CONFIG_DEBUG_STACK_USAGE */ +#ifdef CONFIG_SWAP + NRSWPIN, + NRSWPOUT, +#endif /* CONFIG_SWAP */ NR_VM_EVENT_ITEMS }; diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index d87dc7f77f4e..aed121d729b0 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -62,7 +62,7 @@ struct vm_struct { #ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC unsigned int page_order; #endif - unsigned int nr_pages; + unsigned long nr_pages; phys_addr_t phys_addr; const void *caller; unsigned long requested_size; @@ -310,14 +310,14 @@ static inline void set_vm_flush_reset_perms(void *addr) {} #if defined(CONFIG_MMU) && defined(CONFIG_SMP) struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, const size_t *sizes, int nr_vms, - size_t align); + size_t align, gfp_t gfp); void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms); # else static inline struct vm_struct ** pcpu_get_vm_areas(const unsigned long *offsets, const size_t *sizes, int nr_vms, - size_t align) + size_t align, gfp_t gfp) { return NULL; } diff --git a/include/linux/vmpressure.h b/include/linux/vmpressure.h index faecd5522401..b4d13457bc2a 100644 --- a/include/linux/vmpressure.h +++ b/include/linux/vmpressure.h @@ -13,18 +13,31 @@ struct vmpressure { unsigned long scanned; unsigned long reclaimed; + /* The lock is used to keep the scanned/reclaimed in sync. */ + spinlock_t sr_lock; +#ifdef CONFIG_MEMCG_V1 + /* + * tree=true accumulators feed the v1 userspace eventfd interface + * (memory.pressure_level). Drained by @work. v2 has no equivalent + * interface, so this state is omitted on CONFIG_MEMCG_V1=n builds. + */ unsigned long tree_scanned; unsigned long tree_reclaimed; - /* The lock is used to keep the scanned/reclaimed above in sync. */ - spinlock_t sr_lock; - /* The list of vmpressure_event structs. */ struct list_head events; /* Have to grab the lock on events traversal or modifications. */ struct mutex events_lock; struct work_struct work; +#endif +}; + +enum vmpressure_levels { + VMPRESSURE_LOW = 0, + VMPRESSURE_MEDIUM, + VMPRESSURE_CRITICAL, + VMPRESSURE_NUM_LEVELS, }; struct mem_cgroup; @@ -32,18 +45,41 @@ struct mem_cgroup; #ifdef CONFIG_MEMCG 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); extern void vmpressure_cleanup(struct vmpressure *vmpr); extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg); extern struct mem_cgroup *vmpressure_to_memcg(struct vmpressure *vmpr); + +/* Shared with the v1 vmpressure block in mm/memcontrol-v1.c. */ +extern const unsigned long vmpressure_win; +extern enum vmpressure_levels vmpressure_calc_level(unsigned long scanned, + unsigned long reclaimed); + +#ifdef CONFIG_MEMCG_V1 +extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio); extern int vmpressure_register_event(struct mem_cgroup *memcg, struct eventfd_ctx *eventfd, const char *args); extern void vmpressure_unregister_event(struct mem_cgroup *memcg, struct eventfd_ctx *eventfd); + +/* v1 hooks called from mm/vmpressure.c; no-ops below when !MEMCG_V1. */ +extern void vmpressure_v1_init(struct vmpressure *vmpr); +extern void vmpressure_v1_cleanup(struct vmpressure *vmpr); +extern void vmpressure_v1_account_tree(struct vmpressure *vmpr, + unsigned long scanned, + unsigned long reclaimed); #else +static inline void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, + int prio) {} +static inline void vmpressure_v1_init(struct vmpressure *vmpr) {} +static inline void vmpressure_v1_cleanup(struct vmpressure *vmpr) {} +static inline void vmpressure_v1_account_tree(struct vmpressure *vmpr, + unsigned long scanned, + unsigned long reclaimed) {} +#endif /* CONFIG_MEMCG_V1 */ + +#else /* !CONFIG_MEMCG */ static inline void vmpressure(gfp_t gfp, int order, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed) {} diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 3c9c266cf782..5b31d8e7ae40 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -20,7 +20,6 @@ struct reclaim_stat { unsigned nr_congested; unsigned nr_writeback; unsigned nr_immediate; - unsigned nr_pageout; unsigned nr_activate[ANON_AND_FILE]; unsigned nr_ref_keep; unsigned nr_unmap_fail; @@ -194,6 +193,19 @@ unsigned long global_node_page_state_pages(enum node_stat_item item) return x; } +/* + * Non-clamping variant of global_node_page_state() intended for callers that + * snapshot a monotonically-incremented counter and subtract two samples. + * Returns the raw wrapping value so that unsigned modular subtraction stays + * correct across a signed-long overflow (a real hazard on 32-bit) that the + * clamp in global_node_page_state() would otherwise turn into a huge spurious + * delta. Do NOT use for non-monotonic page-count reads. + */ +static inline unsigned long global_node_page_state_monotonic(enum node_stat_item item) +{ + return (unsigned long)atomic_long_read(&vm_node_stat[item]); +} + static inline unsigned long global_node_page_state(enum node_stat_item item) { VM_WARN_ON_ONCE(vmstat_item_in_bytes(item)); @@ -259,11 +271,14 @@ extern unsigned long node_page_state(struct pglist_data *pgdat, enum node_stat_item item); extern unsigned long node_page_state_pages(struct pglist_data *pgdat, enum node_stat_item item); +extern unsigned long node_page_state_monotonic(struct pglist_data *pgdat, + enum node_stat_item item); extern void fold_vm_numa_events(void); #else #define sum_zone_node_page_state(node, item) global_zone_page_state(item) #define node_page_state(node, item) global_node_page_state(item) #define node_page_state_pages(node, item) global_node_page_state_pages(item) +#define node_page_state_monotonic(node, item) global_node_page_state_monotonic(item) static inline void fold_vm_numa_events(void) { } diff --git a/include/linux/wait.h b/include/linux/wait.h index dce055e6add3..7e215330199c 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -1228,6 +1228,7 @@ long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_en void finish_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout); int woken_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key); +int woken_wake_bit_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key); int autoremove_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key); #define DEFINE_WAIT_FUNC(name, function) \ diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h index ace7379d627d..553d7b23e3ad 100644 --- a/include/linux/wait_bit.h +++ b/include/linux/wait_bit.h @@ -32,6 +32,7 @@ int out_of_line_wait_on_bit_timeout(unsigned long *word, int, wait_bit_action_f int out_of_line_wait_on_bit_lock(unsigned long *word, int, wait_bit_action_f *action, unsigned int mode); struct wait_queue_head *bit_waitqueue(unsigned long *word, int bit); extern void __init wait_bit_init(void); +extern struct wait_bit_key *__var_wake_key(struct wait_queue_entry *wq_entry, void *arg); int wake_bit_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key); diff --git a/include/linux/wmi.h b/include/linux/wmi.h index d723e4b1cafb..defcb624a7e2 100644 --- a/include/linux/wmi.h +++ b/include/linux/wmi.h @@ -11,7 +11,7 @@ #include <linux/compiler_attributes.h> #include <linux/device.h> #include <linux/acpi.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/wmi.h> #include <linux/types.h> /** diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index a283766a192a..c8a36423cb34 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -661,6 +661,7 @@ extern void workqueue_set_min_active(struct workqueue_struct *wq, int min_active); extern struct work_struct *current_work(void); extern bool current_is_workqueue_rescuer(void); +extern bool current_is_workqueue_mem_reclaim(void); extern bool workqueue_congested(int cpu, struct workqueue_struct *wq); extern unsigned int work_busy(struct work_struct *work); extern __printf(1, 2) void set_worker_desc(const char *fmt, ...); diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 62552a2ce5b9..b749a9a5a5ee 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -244,7 +244,7 @@ void wbc_attach_fdatawrite_inode(struct writeback_control *wbc, struct inode *inode); /** - * wbc_init_bio - writeback specific initializtion of bio + * wbc_init_bio - writeback specific initialization of bio * @wbc: writeback_control for the writeback in progress * @bio: bio to be initialized * diff --git a/include/linux/zorro.h b/include/linux/zorro.h index f36c8d39553d..4514c3109deb 100644 --- a/include/linux/zorro.h +++ b/include/linux/zorro.h @@ -17,7 +17,7 @@ #include <linux/device.h> #include <linux/init.h> #include <linux/ioport.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/zorro.h> #include <asm/zorro.h> |
