From fc7a6209d5710618eb4f72a77cd81b8d694ecf89 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 13 Jul 2021 21:35:22 +0200 Subject: bus: Make remove callback return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver core ignores the return value of this callback because there is only little it can do when a device disappears. This is the final bit of a long lasting cleanup quest where several buses were converted to also return void from their remove callback. Additionally some resource leaks were fixed that were caused by drivers returning an error code in the expectation that the driver won't go away. With struct bus_type::remove returning void it's prevented that newly implemented buses return an ignored error code and so don't anticipate wrong expectations for driver authors. Reviewed-by: Tom Rix (For fpga) Reviewed-by: Mathieu Poirier Reviewed-by: Cornelia Huck (For drivers/s390 and drivers/vfio) Acked-by: Russell King (Oracle) (For ARM, Amba and related parts) Acked-by: Mark Brown Acked-by: Chen-Yu Tsai (for sunxi-rsb) Acked-by: Pali Rohár Acked-by: Mauro Carvalho Chehab (for media) Acked-by: Hans de Goede (For drivers/platform) Acked-by: Alexandre Belloni Acked-By: Vinod Koul Acked-by: Juergen Gross (For xen) Acked-by: Lee Jones (For mfd) Acked-by: Johannes Thumshirn (For mcb) Acked-by: Johan Hovold Acked-by: Srinivas Kandagatla (For slimbus) Acked-by: Kirti Wankhede (For vfio) Acked-by: Maximilian Luz Acked-by: Heikki Krogerus (For ulpi and typec) Acked-by: Samuel Iglesias Gonsálvez (For ipack) Acked-by: Geoff Levand (For ps3) Acked-by: Yehezkel Bernat (For thunderbolt) Acked-by: Alexander Shishkin (For intel_th) Acked-by: Dominik Brodowski (For pcmcia) Acked-by: Rafael J. Wysocki (For ACPI) Acked-by: Bjorn Andersson (rpmsg and apr) Acked-by: Srinivas Pandruvada (For intel-ish-hid) Acked-by: Dan Williams (For CXL, DAX, and NVDIMM) Acked-by: William Breathitt Gray (For isa) Acked-by: Stefan Richter (For firewire) Acked-by: Benjamin Tissoires (For hid) Acked-by: Thorsten Scherer (For siox) Acked-by: Sven Van Asbroeck (For anybuss) Acked-by: Ulf Hansson (For MMC) Acked-by: Wolfram Sang # for I2C Acked-by: Sudeep Holla Acked-by: Geert Uytterhoeven Acked-by: Dmitry Torokhov Acked-by: Finn Thain Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20210713193522.1770306-6-u.kleine-koenig@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/base/auxiliary.c | 4 +--- drivers/base/isa.c | 4 +--- drivers/base/platform.c | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index adc199dfba3c..0c86f5bed9f4 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -79,7 +79,7 @@ static int auxiliary_bus_probe(struct device *dev) return ret; } -static int auxiliary_bus_remove(struct device *dev) +static void auxiliary_bus_remove(struct device *dev) { struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); struct auxiliary_device *auxdev = to_auxiliary_dev(dev); @@ -87,8 +87,6 @@ static int auxiliary_bus_remove(struct device *dev) if (auxdrv->remove) auxdrv->remove(auxdev); dev_pm_domain_detach(dev, true); - - return 0; } static void auxiliary_bus_shutdown(struct device *dev) diff --git a/drivers/base/isa.c b/drivers/base/isa.c index aa4737667026..55e3ee2da98f 100644 --- a/drivers/base/isa.c +++ b/drivers/base/isa.c @@ -46,14 +46,12 @@ static int isa_bus_probe(struct device *dev) return 0; } -static int isa_bus_remove(struct device *dev) +static void isa_bus_remove(struct device *dev) { struct isa_driver *isa_driver = dev->platform_data; if (isa_driver && isa_driver->remove) isa_driver->remove(dev, to_isa_dev(dev)->id); - - return 0; } static void isa_bus_shutdown(struct device *dev) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 8640578f45e9..a94b7f454881 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1438,7 +1438,7 @@ out: return ret; } -static int platform_remove(struct device *_dev) +static void platform_remove(struct device *_dev) { struct platform_driver *drv = to_platform_driver(_dev->driver); struct platform_device *dev = to_platform_device(_dev); @@ -1450,8 +1450,6 @@ static int platform_remove(struct device *_dev) dev_warn(_dev, "remove callback returned a non-zero value. This will be ignored.\n"); } dev_pm_domain_detach(_dev, true); - - return 0; } static void platform_shutdown(struct device *_dev) -- cgit v1.2.3 From 16b0dd40922995bb13f140b025bb760b6c5224b0 Mon Sep 17 00:00:00 2001 From: Jinchao Wang Date: Sat, 26 Jun 2021 17:46:06 +0800 Subject: driver: base: Replace symbolic permissions with octal permissions Resolve following checkpatch issue, Replace symbolic permissions with octal permissions Signed-off-by: Jinchao Wang Link: https://lore.kernel.org/r/20210626094606.53152-1-wjc@cdjrlc.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 6 +++--- drivers/base/power/wakeup.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 1f6b4bd61056..bdc98c5713d5 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -195,7 +195,7 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf, bus_put(bus); return err; } -static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, S_IWUSR, NULL, unbind_store); +static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store); /* * Manually attach a device to a driver. @@ -221,7 +221,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, bus_put(bus); return err; } -static DRIVER_ATTR_IGNORE_LOCKDEP(bind, S_IWUSR, NULL, bind_store); +static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store); static ssize_t drivers_autoprobe_show(struct bus_type *bus, char *buf) { @@ -767,7 +767,7 @@ static ssize_t bus_uevent_store(struct bus_type *bus, * DEVICE_ATTR_WO(uevent), which would cause a clash with the with the store * function name. */ -static struct bus_attribute bus_attr_uevent = __ATTR(uevent, S_IWUSR, NULL, +static struct bus_attribute bus_attr_uevent = __ATTR(uevent, 0200, NULL, bus_uevent_store); /** diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index f0b37c188514..99bda0da23a8 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -1180,7 +1180,7 @@ static const struct file_operations wakeup_sources_stats_fops = { static int __init wakeup_sources_debugfs_init(void) { - debugfs_create_file("wakeup_sources", S_IRUGO, NULL, NULL, + debugfs_create_file("wakeup_sources", 0444, NULL, NULL, &wakeup_sources_stats_fops); return 0; } -- cgit v1.2.3 From 3ecc8cb7c092b2f50e21d2aaaae35b8221ee7214 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Mon, 19 Jul 2021 14:45:31 +0800 Subject: firmware: fix theoretical UAF race with firmware cache and resume This race was discovered when I carefully analyzed the code to locate another firmware-related UAF issue. It can be triggered only when the firmware load operation is executed during suspend. This possibility is almost impossible because there are few firmware load and suspend actions in the actual environment. CPU0 CPU1 __device_uncache_fw_images(): assign_fw(): fw_cache_piggyback_on_request() <----- P0 spin_lock(&fwc->name_lock); ... list_del(&fce->list); spin_unlock(&fwc->name_lock); uncache_firmware(fce->name); <----- P1 kref_get(&fw_priv->ref); If CPU1 is interrupted at position P0, the new 'fce' has been added to the list fwc->fw_names by the fw_cache_piggyback_on_request(). In this case, CPU0 executes __device_uncache_fw_images() and will be able to see it when it traverses list fwc->fw_names. Before CPU1 executes kref_get() at P1, if CPU0 further executes uncache_firmware(), the count of fw_priv->ref may decrease to 0, causing fw_priv to be released in advance. Move kref_get() to the lock protection range of fwc->name_lock to fix it. Fixes: ac39b3ea73aa ("firmware loader: let caching firmware piggyback on loading firmware") Acked-by: Luis Chamberlain Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20210719064531.3733-2-thunder.leizhen@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/main.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 4fdb8219cd08..2f267b8d2fd9 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -165,7 +165,7 @@ static inline int fw_state_wait(struct fw_priv *fw_priv) return __fw_state_wait_common(fw_priv, MAX_SCHEDULE_TIMEOUT); } -static int fw_cache_piggyback_on_request(const char *name); +static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv); static struct fw_priv *__allocate_fw_priv(const char *fw_name, struct firmware_cache *fwc, @@ -707,10 +707,8 @@ int assign_fw(struct firmware *fw, struct device *device) * on request firmware. */ if (!(fw_priv->opt_flags & FW_OPT_NOCACHE) && - fw_priv->fwc->state == FW_LOADER_START_CACHE) { - if (fw_cache_piggyback_on_request(fw_priv->fw_name)) - kref_get(&fw_priv->ref); - } + fw_priv->fwc->state == FW_LOADER_START_CACHE) + fw_cache_piggyback_on_request(fw_priv); /* pass the pages buffer to driver at the last minute */ fw_set_page_data(fw_priv, fw); @@ -1257,11 +1255,11 @@ static int __fw_entry_found(const char *name) return 0; } -static int fw_cache_piggyback_on_request(const char *name) +static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv) { - struct firmware_cache *fwc = &fw_cache; + const char *name = fw_priv->fw_name; + struct firmware_cache *fwc = fw_priv->fwc; struct fw_cache_entry *fce; - int ret = 0; spin_lock(&fwc->name_lock); if (__fw_entry_found(name)) @@ -1269,13 +1267,12 @@ static int fw_cache_piggyback_on_request(const char *name) fce = alloc_fw_cache_entry(name); if (fce) { - ret = 1; list_add(&fce->list, &fwc->fw_names); + kref_get(&fw_priv->ref); pr_debug("%s: fw: %s\n", __func__, name); } found: spin_unlock(&fwc->name_lock); - return ret; } static void free_fw_cache_entry(struct fw_cache_entry *fce) @@ -1506,9 +1503,8 @@ static inline void unregister_fw_pm_ops(void) unregister_pm_notifier(&fw_cache.pm_notify); } #else -static int fw_cache_piggyback_on_request(const char *name) +static void fw_cache_piggyback_on_request(struct fw_priv *fw_priv) { - return 0; } static inline int register_fw_pm_ops(void) { -- cgit v1.2.3 From f04948dea236b000da09c466a7ec931ecd8d7867 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Wed, 7 Jul 2021 15:43:01 +0800 Subject: driver core: Fix error return code in really_probe() In the case of error handling, the error code returned by the subfunction should be propagated instead of 0. Fixes: 1901fb2604fb ("Driver core: fix "driver" symlink timing") Fixes: 23b6904442d0 ("driver core: add dev_groups to all drivers") Fixes: 8fd456ec0cf0 ("driver core: Add state_synced sysfs file for devices that support it") Reported-by: Hulk Robot Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20210707074301.2722-1-thunder.leizhen@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/dd.c b/drivers/base/dd.c index daeb9b5763ae..2b8cdb78384c 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -580,7 +580,8 @@ re_probe: goto probe_failed; } - if (driver_sysfs_add(dev)) { + ret = driver_sysfs_add(dev); + if (ret) { pr_err("%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); goto probe_failed; @@ -602,15 +603,18 @@ re_probe: goto probe_failed; } - if (device_add_groups(dev, drv->dev_groups)) { + ret = device_add_groups(dev, drv->dev_groups); + if (ret) { dev_err(dev, "device_add_groups() failed\n"); goto dev_groups_failed; } - if (dev_has_sync_state(dev) && - device_create_file(dev, &dev_attr_state_synced)) { - dev_err(dev, "state_synced sysfs add failed\n"); - goto dev_sysfs_state_synced_failed; + if (dev_has_sync_state(dev)) { + ret = device_create_file(dev, &dev_attr_state_synced); + if (ret) { + dev_err(dev, "state_synced sysfs add failed\n"); + goto dev_sysfs_state_synced_failed; + } } if (test_remove) { -- cgit v1.2.3 From e022eac85ecd2140a0829970d923d984356185eb Mon Sep 17 00:00:00 2001 From: Xiongfeng Wang Date: Wed, 14 Jul 2021 09:32:55 +0800 Subject: cacheinfo: clear cache_leaves(cpu) in free_cache_attributes() On ARM64, when PPTT(Processor Properties Topology Table) is not implemented in ACPI boot, we will goto 'free_ci' with the following print: Unable to detect cache hierarchy for CPU 0 But some other codes may still use 'num_leaves' to iterate through the 'info_list', such as get_cpu_cacheinfo_id(). If 'info_list' is NULL , it would crash. So clear 'num_leaves' in free_cache_attributes(). Reviewed-by: Sudeep Holla Signed-off-by: Xiongfeng Wang Link: https://lore.kernel.org/r/1626226375-58730-1-git-send-email-wangxiongfeng2@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/cacheinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/base') diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index bfc095956dd1..dad296229161 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -297,6 +297,7 @@ static void free_cache_attributes(unsigned int cpu) kfree(per_cpu_cacheinfo(cpu)); per_cpu_cacheinfo(cpu) = NULL; + cache_leaves(cpu) = 0; } int __weak init_cache_level(unsigned int cpu) -- cgit v1.2.3 From e7deeb9d79d8691f1e6c4c6707471ec3d7b9886b Mon Sep 17 00:00:00 2001 From: Jinchao Wang Date: Tue, 29 Jun 2021 01:19:07 +0800 Subject: driver: base: Prefer unsigned int to bare use of unsigned Fix checkpatch warnings: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' Signed-off-by: Jinchao Wang Link: https://lore.kernel.org/r/20210628171907.63646-2-wjc@cdjrlc.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/cpu.c | 4 ++-- drivers/base/map.c | 12 ++++++------ drivers/base/node.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 5ef14db97904..5fc258073bc7 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -388,7 +388,7 @@ int register_cpu(struct cpu *cpu, int num) return 0; } -struct device *get_cpu_device(unsigned cpu) +struct device *get_cpu_device(unsigned int cpu) { if (cpu < nr_cpu_ids && cpu_possible(cpu)) return per_cpu(cpu_sys_devices, cpu); @@ -484,7 +484,7 @@ static const struct attribute_group *cpu_root_attr_groups[] = { NULL, }; -bool cpu_is_hotpluggable(unsigned cpu) +bool cpu_is_hotpluggable(unsigned int cpu) { struct device *dev = get_cpu_device(cpu); return dev && container_of(dev, struct cpu, dev)->hotpluggable; diff --git a/drivers/base/map.c b/drivers/base/map.c index 5650ab2b247a..83aeb09ca161 100644 --- a/drivers/base/map.c +++ b/drivers/base/map.c @@ -33,9 +33,9 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, struct module *module, kobj_probe_t *probe, int (*lock)(dev_t, void *), void *data) { - unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; - unsigned index = MAJOR(dev); - unsigned i; + unsigned int n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; + unsigned int index = MAJOR(dev); + unsigned int i; struct probe *p; if (n > 255) @@ -67,9 +67,9 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range) { - unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; - unsigned index = MAJOR(dev); - unsigned i; + unsigned int n = MAJOR(dev + range - 1) - MAJOR(dev) + 1; + unsigned int index = MAJOR(dev); + unsigned int i; struct probe *found = NULL; if (n > 255) diff --git a/drivers/base/node.c b/drivers/base/node.c index 4a4ae868ad9f..2bc9089f3e78 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -75,7 +75,7 @@ static DEVICE_ATTR_RO(cpulist); struct node_access_nodes { struct device dev; struct list_head list_node; - unsigned access; + unsigned int access; #ifdef CONFIG_HMEM_REPORTING struct node_hmem_attrs hmem_attrs; #endif @@ -122,7 +122,7 @@ static void node_access_release(struct device *dev) } static struct node_access_nodes *node_init_node_access(struct node *node, - unsigned access) + unsigned int access) { struct node_access_nodes *access_node; struct device *dev; @@ -187,7 +187,7 @@ static struct attribute *access_attrs[] = { * @access: The access class the for the given attributes */ void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, - unsigned access) + unsigned int access) { struct node_access_nodes *c; struct node *node; @@ -711,7 +711,7 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid) */ int register_memory_node_under_compute_node(unsigned int mem_nid, unsigned int cpu_nid, - unsigned access) + unsigned int access) { struct node *init_node, *targ_node; struct node_access_nodes *initiator, *target; -- cgit v1.2.3 From bb9ec13d156e85dfd6a8afd0bb61ccf5736ed257 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 6 Aug 2021 23:02:49 +1200 Subject: topology: use bin_attribute to break the size limitation of cpumap ABI Reading /sys/devices/system/cpu/cpuX/topology/ returns cpu topology. However, the size of this file is limited to PAGE_SIZE because of the limitation for sysfs attribute. This patch moves to use bin_attribute to extend the ABI to be more than one page so that cpumap bitmask and list won't be potentially trimmed. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Reviewed-by: Jonathan Cameron Signed-off-by: Tian Tao Signed-off-by: Barry Song Link: https://lore.kernel.org/r/20210806110251.560-4-song.bao.hua@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/topology.c | 115 ++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 52 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 4d254fcc93d1..43c0940643f5 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -21,25 +21,27 @@ static ssize_t name##_show(struct device *dev, \ return sysfs_emit(buf, "%d\n", topology_##name(dev->id)); \ } -#define define_siblings_show_map(name, mask) \ -static ssize_t name##_show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - return cpumap_print_to_pagebuf(false, buf, topology_##mask(dev->id));\ +#define define_siblings_read_func(name, mask) \ +static ssize_t name##_read(struct file *file, struct kobject *kobj, \ + struct bin_attribute *attr, char *buf, \ + loff_t off, size_t count) \ +{ \ + struct device *dev = kobj_to_dev(kobj); \ + \ + return cpumap_print_bitmask_to_buf(buf, topology_##mask(dev->id), \ + off, count); \ +} \ + \ +static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \ + struct bin_attribute *attr, char *buf, \ + loff_t off, size_t count) \ +{ \ + struct device *dev = kobj_to_dev(kobj); \ + \ + return cpumap_print_list_to_buf(buf, topology_##mask(dev->id), \ + off, count); \ } -#define define_siblings_show_list(name, mask) \ -static ssize_t name##_list_show(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return cpumap_print_to_pagebuf(true, buf, topology_##mask(dev->id));\ -} - -#define define_siblings_show_func(name, mask) \ - define_siblings_show_map(name, mask); \ - define_siblings_show_list(name, mask) - define_id_show_func(physical_package_id); static DEVICE_ATTR_RO(physical_package_id); @@ -49,71 +51,80 @@ static DEVICE_ATTR_RO(die_id); define_id_show_func(core_id); static DEVICE_ATTR_RO(core_id); -define_siblings_show_func(thread_siblings, sibling_cpumask); -static DEVICE_ATTR_RO(thread_siblings); -static DEVICE_ATTR_RO(thread_siblings_list); +define_siblings_read_func(thread_siblings, sibling_cpumask); +static BIN_ATTR_RO(thread_siblings, 0); +static BIN_ATTR_RO(thread_siblings_list, 0); -define_siblings_show_func(core_cpus, sibling_cpumask); -static DEVICE_ATTR_RO(core_cpus); -static DEVICE_ATTR_RO(core_cpus_list); +define_siblings_read_func(core_cpus, sibling_cpumask); +static BIN_ATTR_RO(core_cpus, 0); +static BIN_ATTR_RO(core_cpus_list, 0); -define_siblings_show_func(core_siblings, core_cpumask); -static DEVICE_ATTR_RO(core_siblings); -static DEVICE_ATTR_RO(core_siblings_list); +define_siblings_read_func(core_siblings, core_cpumask); +static BIN_ATTR_RO(core_siblings, 0); +static BIN_ATTR_RO(core_siblings_list, 0); -define_siblings_show_func(die_cpus, die_cpumask); -static DEVICE_ATTR_RO(die_cpus); -static DEVICE_ATTR_RO(die_cpus_list); +define_siblings_read_func(die_cpus, die_cpumask); +static BIN_ATTR_RO(die_cpus, 0); +static BIN_ATTR_RO(die_cpus_list, 0); -define_siblings_show_func(package_cpus, core_cpumask); -static DEVICE_ATTR_RO(package_cpus); -static DEVICE_ATTR_RO(package_cpus_list); +define_siblings_read_func(package_cpus, core_cpumask); +static BIN_ATTR_RO(package_cpus, 0); +static BIN_ATTR_RO(package_cpus_list, 0); #ifdef CONFIG_SCHED_BOOK define_id_show_func(book_id); static DEVICE_ATTR_RO(book_id); -define_siblings_show_func(book_siblings, book_cpumask); -static DEVICE_ATTR_RO(book_siblings); -static DEVICE_ATTR_RO(book_siblings_list); +define_siblings_read_func(book_siblings, book_cpumask); +static BIN_ATTR_RO(book_siblings, 0); +static BIN_ATTR_RO(book_siblings_list, 0); #endif #ifdef CONFIG_SCHED_DRAWER define_id_show_func(drawer_id); static DEVICE_ATTR_RO(drawer_id); -define_siblings_show_func(drawer_siblings, drawer_cpumask); -static DEVICE_ATTR_RO(drawer_siblings); -static DEVICE_ATTR_RO(drawer_siblings_list); +define_siblings_read_func(drawer_siblings, drawer_cpumask); +static BIN_ATTR_RO(drawer_siblings, 0); +static BIN_ATTR_RO(drawer_siblings_list, 0); #endif +static struct bin_attribute *bin_attrs[] = { + &bin_attr_core_cpus, + &bin_attr_core_cpus_list, + &bin_attr_thread_siblings, + &bin_attr_thread_siblings_list, + &bin_attr_core_siblings, + &bin_attr_core_siblings_list, + &bin_attr_die_cpus, + &bin_attr_die_cpus_list, + &bin_attr_package_cpus, + &bin_attr_package_cpus_list, +#ifdef CONFIG_SCHED_BOOK + &bin_attr_book_siblings, + &bin_attr_book_siblings_list, +#endif +#ifdef CONFIG_SCHED_DRAWER + &bin_attr_drawer_siblings, + &bin_attr_drawer_siblings_list, +#endif + NULL +}; + static struct attribute *default_attrs[] = { &dev_attr_physical_package_id.attr, &dev_attr_die_id.attr, &dev_attr_core_id.attr, - &dev_attr_thread_siblings.attr, - &dev_attr_thread_siblings_list.attr, - &dev_attr_core_cpus.attr, - &dev_attr_core_cpus_list.attr, - &dev_attr_core_siblings.attr, - &dev_attr_core_siblings_list.attr, - &dev_attr_die_cpus.attr, - &dev_attr_die_cpus_list.attr, - &dev_attr_package_cpus.attr, - &dev_attr_package_cpus_list.attr, #ifdef CONFIG_SCHED_BOOK &dev_attr_book_id.attr, - &dev_attr_book_siblings.attr, - &dev_attr_book_siblings_list.attr, #endif #ifdef CONFIG_SCHED_DRAWER &dev_attr_drawer_id.attr, - &dev_attr_drawer_siblings.attr, - &dev_attr_drawer_siblings_list.attr, #endif NULL }; static const struct attribute_group topology_attr_group = { .attrs = default_attrs, + .bin_attrs = bin_attrs, .name = "topology" }; -- cgit v1.2.3 From 75bd50fa841db5434728d238b8b5659498ccf0ab Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 6 Aug 2021 23:02:50 +1200 Subject: drivers/base/node.c: use bin_attribute to break the size limitation of cpumap ABI Reading /sys/devices/system/cpu/cpuX/nodeX/ returns cpumap and cpulist. However, the size of this file is limited to PAGE_SIZE because of the limitation for sysfs attribute. This patch moves to use bin_attribute to extend the ABI to be more than one page so that cpumap bitmask and list won't be potentially trimmed. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Reviewed-by: Jonathan Cameron Signed-off-by: Tian Tao Signed-off-by: Barry Song Link: https://lore.kernel.org/r/20210806110251.560-5-song.bao.hua@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/node.c | 63 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/node.c b/drivers/base/node.c index 2bc9089f3e78..be16bbff11cc 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -26,43 +26,47 @@ static struct bus_type node_subsys = { .dev_name = "node", }; - -static ssize_t node_read_cpumap(struct device *dev, bool list, char *buf) +static inline ssize_t cpumap_read(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { - ssize_t n; - cpumask_var_t mask; + struct device *dev = kobj_to_dev(kobj); struct node *node_dev = to_node(dev); - - /* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */ - BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1)); + cpumask_var_t mask; + ssize_t n; if (!alloc_cpumask_var(&mask, GFP_KERNEL)) return 0; cpumask_and(mask, cpumask_of_node(node_dev->dev.id), cpu_online_mask); - n = cpumap_print_to_pagebuf(list, buf, mask); + n = cpumap_print_bitmask_to_buf(buf, mask, off, count); free_cpumask_var(mask); return n; } -static inline ssize_t cpumap_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static BIN_ATTR_RO(cpumap, 0); + +static inline ssize_t cpulist_read(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { - return node_read_cpumap(dev, false, buf); -} + struct device *dev = kobj_to_dev(kobj); + struct node *node_dev = to_node(dev); + cpumask_var_t mask; + ssize_t n; + + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + return 0; -static DEVICE_ATTR_RO(cpumap); + cpumask_and(mask, cpumask_of_node(node_dev->dev.id), cpu_online_mask); + n = cpumap_print_list_to_buf(buf, mask, off, count); + free_cpumask_var(mask); -static inline ssize_t cpulist_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return node_read_cpumap(dev, true, buf); + return n; } -static DEVICE_ATTR_RO(cpulist); +static BIN_ATTR_RO(cpulist, 0); /** * struct node_access_nodes - Access class device to hold user visible @@ -557,15 +561,28 @@ static ssize_t node_read_distance(struct device *dev, static DEVICE_ATTR(distance, 0444, node_read_distance, NULL); static struct attribute *node_dev_attrs[] = { - &dev_attr_cpumap.attr, - &dev_attr_cpulist.attr, &dev_attr_meminfo.attr, &dev_attr_numastat.attr, &dev_attr_distance.attr, &dev_attr_vmstat.attr, NULL }; -ATTRIBUTE_GROUPS(node_dev); + +static struct bin_attribute *node_dev_bin_attrs[] = { + &bin_attr_cpumap, + &bin_attr_cpulist, + NULL +}; + +static const struct attribute_group node_dev_group = { + .attrs = node_dev_attrs, + .bin_attrs = node_dev_bin_attrs +}; + +static const struct attribute_group *node_dev_groups[] = { + &node_dev_group, + NULL +}; #ifdef CONFIG_HUGETLBFS /* -- cgit v1.2.3 From bd1e336aa8535a99f339e2d66a611984262221ce Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 17 Aug 2021 13:24:49 +0300 Subject: driver core: platform: Remove platform_device_add_properties() There are no more users for it. The last place where it's called is in platform_device_register_full(). Replacing that call with device_create_managed_software_node() and removing the function. Reviewed-by: Andy Shevchenko Reviewed-by: Thierry Reding Signed-off-by: Heikki Krogerus Link: https://lore.kernel.org/r/20210817102449.39994-3-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 20 ++------------------ include/linux/platform_device.h | 2 -- 2 files changed, 2 insertions(+), 20 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index a94b7f454881..652531f67135 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -641,22 +641,6 @@ int platform_device_add_data(struct platform_device *pdev, const void *data, } EXPORT_SYMBOL_GPL(platform_device_add_data); -/** - * platform_device_add_properties - add built-in properties to a platform device - * @pdev: platform device to add properties to - * @properties: null terminated array of properties to add - * - * The function will take deep copy of @properties and attach the copy to the - * platform device. The memory associated with properties will be freed when the - * platform device is released. - */ -int platform_device_add_properties(struct platform_device *pdev, - const struct property_entry *properties) -{ - return device_add_properties(&pdev->dev, properties); -} -EXPORT_SYMBOL_GPL(platform_device_add_properties); - /** * platform_device_add - add a platform device to device hierarchy * @pdev: platform device we're adding @@ -842,8 +826,8 @@ struct platform_device *platform_device_register_full( goto err; if (pdevinfo->properties) { - ret = platform_device_add_properties(pdev, - pdevinfo->properties); + ret = device_create_managed_software_node(&pdev->dev, + pdevinfo->properties, NULL); if (ret) goto err; } diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index ed42ea9f60ba..7c96f169d274 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -197,8 +197,6 @@ 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); -extern int platform_device_add_properties(struct platform_device *pdev, - const struct property_entry *properties); 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); -- cgit v1.2.3