Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'driver-core-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core updates from Greg KH:
"Here is the set of driver core updates for 6.7-rc1. Nothing major in
here at all, just a small number of changes including:

- minor cleanups and updates from Andy Shevchenko

- __counted_by addition

- firmware_loader update for aborting loads cleaner

- other minor changes, details in the shortlog

- documentation update

All of these have been in linux-next for a while with no reported
issues"

* tag 'driver-core-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (21 commits)
firmware_loader: Abort all upcoming firmware load request once reboot triggered
firmware_loader: Refactor kill_pending_fw_fallback_reqs()
Documentation: security-bugs.rst: linux-distros relaxed their rules
driver core: Release all resources during unbind before updating device links
driver core: class: remove boilerplate code
driver core: platform: Annotate struct irq_affinity_devres with __counted_by
resource: Constify resource crosscheck APIs
resource: Unify next_resource() and next_resource_skip_children()
resource: Reuse for_each_resource() macro
PCI: Implement custom llseek for sysfs resource entries
kernfs: sysfs: support custom llseek method for sysfs entries
debugfs: Fix __rcu type comparison warning
device property: Replace custom implementation of COUNT_ARGS()
drivers: base: test: Make property entry API test modular
driver core: Add missing parameter description to __fwnode_link_add()
device property: Clarify usage scope of some struct fwnode_handle members
devres: rename the first parameter of devm_add_action(_or_reset)
driver core: platform: Unify the firmware node type check
driver core: platform: Use temporary variable in platform_device_add()
driver core: platform: Refactor error path in a couple places
...

+194 -100
+25 -8
Documentation/process/security-bugs.rst
··· 66 66 Coordination with other groups 67 67 ------------------------------ 68 68 69 - The kernel security team strongly recommends that reporters of potential 70 - security issues NEVER contact the "linux-distros" mailing list until 71 - AFTER discussing it with the kernel security team. Do not Cc: both 72 - lists at once. You may contact the linux-distros mailing list after a 73 - fix has been agreed on and you fully understand the requirements that 74 - doing so will impose on you and the kernel community. 69 + While the kernel security team solely focuses on getting bugs fixed, 70 + other groups focus on fixing issues in distros and coordinating 71 + disclosure between operating system vendors. Coordination is usually 72 + handled by the "linux-distros" mailing list and disclosure by the 73 + public "oss-security" mailing list, both of which are closely related 74 + and presented in the linux-distros wiki: 75 + <https://oss-security.openwall.org/wiki/mailing-lists/distros> 75 76 76 - The different lists have different goals and the linux-distros rules do 77 - not contribute to actually fixing any potential security problems. 77 + Please note that the respective policies and rules are different since 78 + the 3 lists pursue different goals. Coordinating between the kernel 79 + security team and other teams is difficult since for the kernel security 80 + team occasional embargoes (as subject to a maximum allowed number of 81 + days) start from the availability of a fix, while for "linux-distros" 82 + they start from the initial post to the list regardless of the 83 + availability of a fix. 84 + 85 + As such, the kernel security team strongly recommends that as a reporter 86 + of a potential security issue you DO NOT contact the "linux-distros" 87 + mailing list UNTIL a fix is accepted by the affected code's maintainers 88 + and you have read the distros wiki page above and you fully understand 89 + the requirements that contacting "linux-distros" will impose on you and 90 + the kernel community. This also means that in general it doesn't make 91 + sense to Cc: both lists at once, except maybe for coordination if and 92 + while an accepted fix has not yet been merged. In other words, until a 93 + fix is accepted do not Cc: "linux-distros", and after it's merged do not 94 + Cc: the kernel security team. 78 95 79 96 CVE assignment 80 97 --------------
+2 -4
drivers/base/class.c
··· 193 193 lockdep_register_key(key); 194 194 __mutex_init(&cp->mutex, "subsys mutex", key); 195 195 error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); 196 - if (error) { 197 - kfree(cp); 198 - return error; 199 - } 196 + if (error) 197 + goto err_out; 200 198 201 199 cp->subsys.kobj.kset = class_kset; 202 200 cp->subsys.kobj.ktype = &class_ktype;
+1
drivers/base/core.c
··· 49 49 * __fwnode_link_add - Create a link between two fwnode_handles. 50 50 * @con: Consumer end of the link. 51 51 * @sup: Supplier end of the link. 52 + * @flags: Link flags. 52 53 * 53 54 * Create a fwnode link between fwnode handles @con and @sup. The fwnode link 54 55 * represents the detail that the firmware lists @sup fwnode as supplying a
+1 -1
drivers/base/dd.c
··· 1274 1274 if (dev->bus && dev->bus->dma_cleanup) 1275 1275 dev->bus->dma_cleanup(dev); 1276 1276 1277 - device_links_driver_cleanup(dev); 1278 1277 device_unbind_cleanup(dev); 1278 + device_links_driver_cleanup(dev); 1279 1279 1280 1280 klist_remove(&dev->p->knode_driver); 1281 1281 device_pm_check_callbacks(dev);
+7 -3
drivers/base/firmware_loader/fallback.c
··· 46 46 47 47 static LIST_HEAD(pending_fw_head); 48 48 49 - void kill_pending_fw_fallback_reqs(bool only_kill_custom) 49 + void kill_pending_fw_fallback_reqs(bool kill_all) 50 50 { 51 51 struct fw_priv *fw_priv; 52 52 struct fw_priv *next; ··· 54 54 mutex_lock(&fw_lock); 55 55 list_for_each_entry_safe(fw_priv, next, &pending_fw_head, 56 56 pending_list) { 57 - if (!fw_priv->need_uevent || !only_kill_custom) 57 + if (kill_all || !fw_priv->need_uevent) 58 58 __fw_load_abort(fw_priv); 59 59 } 60 + 61 + if (kill_all) 62 + fw_load_abort_all = true; 63 + 60 64 mutex_unlock(&fw_lock); 61 65 } 62 66 ··· 90 86 } 91 87 92 88 mutex_lock(&fw_lock); 93 - if (fw_state_is_aborted(fw_priv)) { 89 + if (fw_load_abort_all || fw_state_is_aborted(fw_priv)) { 94 90 mutex_unlock(&fw_lock); 95 91 retval = -EINTR; 96 92 goto out;
+2 -2
drivers/base/firmware_loader/fallback.h
··· 13 13 struct device *device, 14 14 u32 opt_flags, 15 15 int ret); 16 - void kill_pending_fw_fallback_reqs(bool only_kill_custom); 16 + void kill_pending_fw_fallback_reqs(bool kill_all); 17 17 18 18 void fw_fallback_set_cache_timeout(void); 19 19 void fw_fallback_set_default_timeout(void); ··· 28 28 return ret; 29 29 } 30 30 31 - static inline void kill_pending_fw_fallback_reqs(bool only_kill_custom) { } 31 + static inline void kill_pending_fw_fallback_reqs(bool kill_all) { } 32 32 static inline void fw_fallback_set_cache_timeout(void) { } 33 33 static inline void fw_fallback_set_default_timeout(void) { } 34 34 #endif /* CONFIG_FW_LOADER_USER_HELPER */
+1
drivers/base/firmware_loader/firmware.h
··· 86 86 87 87 extern struct mutex fw_lock; 88 88 extern struct firmware_cache fw_cache; 89 + extern bool fw_load_abort_all; 89 90 90 91 static inline bool __fw_state_check(struct fw_priv *fw_priv, 91 92 enum fw_status status)
+5 -4
drivers/base/firmware_loader/main.c
··· 93 93 DEFINE_MUTEX(fw_lock); 94 94 95 95 struct firmware_cache fw_cache; 96 + bool fw_load_abort_all; 96 97 97 98 void fw_state_init(struct fw_priv *fw_priv) 98 99 { ··· 1525 1524 case PM_SUSPEND_PREPARE: 1526 1525 case PM_RESTORE_PREPARE: 1527 1526 /* 1528 - * kill pending fallback requests with a custom fallback 1529 - * to avoid stalling suspend. 1527 + * Here, kill pending fallback requests will only kill 1528 + * non-uevent firmware request to avoid stalling suspend. 1530 1529 */ 1531 - kill_pending_fw_fallback_reqs(true); 1530 + kill_pending_fw_fallback_reqs(false); 1532 1531 device_cache_fw_images(); 1533 1532 break; 1534 1533 ··· 1613 1612 * Kill all pending fallback requests to avoid both stalling shutdown, 1614 1613 * and avoid a deadlock with the usermode_lock. 1615 1614 */ 1616 - kill_pending_fw_fallback_reqs(false); 1615 + kill_pending_fw_fallback_reqs(true); 1617 1616 1618 1617 return NOTIFY_DONE; 1619 1618 }
+36 -35
drivers/base/platform.c
··· 178 178 ret = dev->archdata.irqs[num]; 179 179 goto out; 180 180 #else 181 + struct fwnode_handle *fwnode = dev_fwnode(&dev->dev); 181 182 struct resource *r; 182 183 183 - if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { 184 - ret = of_irq_get(dev->dev.of_node, num); 184 + if (is_of_node(fwnode)) { 185 + ret = of_irq_get(to_of_node(fwnode), num); 185 186 if (ret > 0 || ret == -EPROBE_DEFER) 186 187 goto out; 187 188 } 188 189 189 190 r = platform_get_resource(dev, IORESOURCE_IRQ, num); 190 - if (has_acpi_companion(&dev->dev)) { 191 + if (is_acpi_device_node(fwnode)) { 191 192 if (r && r->flags & IORESOURCE_DISABLED) { 192 - ret = acpi_irq_get(ACPI_HANDLE(&dev->dev), num, r); 193 + ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), num, r); 193 194 if (ret) 194 195 goto out; 195 196 } ··· 223 222 * the device will only expose one IRQ, and this fallback 224 223 * allows a common code path across either kind of resource. 225 224 */ 226 - if (num == 0 && has_acpi_companion(&dev->dev)) { 227 - ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num); 225 + if (num == 0 && is_acpi_device_node(fwnode)) { 226 + ret = acpi_dev_gpio_irq_get(to_acpi_device_node(fwnode), num); 228 227 /* Our callers expect -ENXIO for missing IRQs. */ 229 228 if (ret >= 0 || ret == -EPROBE_DEFER) 230 229 goto out; ··· 292 291 293 292 struct irq_affinity_devres { 294 293 unsigned int count; 295 - unsigned int irq[]; 294 + unsigned int irq[] __counted_by(count); 296 295 }; 297 296 298 297 static void platform_disable_acpi_irq(struct platform_device *pdev, int index) ··· 313 312 for (i = 0; i < ptr->count; i++) { 314 313 irq_dispose_mapping(ptr->irq[i]); 315 314 316 - if (has_acpi_companion(dev)) 315 + if (is_acpi_device_node(dev_fwnode(dev))) 317 316 platform_disable_acpi_irq(to_platform_device(dev), i); 318 317 } 319 318 } ··· 656 655 */ 657 656 int platform_device_add(struct platform_device *pdev) 658 657 { 658 + struct device *dev = &pdev->dev; 659 659 u32 i; 660 660 int ret; 661 661 662 - if (!pdev) 663 - return -EINVAL; 662 + if (!dev->parent) 663 + dev->parent = &platform_bus; 664 664 665 - if (!pdev->dev.parent) 666 - pdev->dev.parent = &platform_bus; 667 - 668 - pdev->dev.bus = &platform_bus_type; 665 + dev->bus = &platform_bus_type; 669 666 670 667 switch (pdev->id) { 671 668 default: 672 - dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); 669 + dev_set_name(dev, "%s.%d", pdev->name, pdev->id); 673 670 break; 674 671 case PLATFORM_DEVID_NONE: 675 - dev_set_name(&pdev->dev, "%s", pdev->name); 672 + dev_set_name(dev, "%s", pdev->name); 676 673 break; 677 674 case PLATFORM_DEVID_AUTO: 678 675 /* ··· 680 681 */ 681 682 ret = ida_alloc(&platform_devid_ida, GFP_KERNEL); 682 683 if (ret < 0) 683 - goto err_out; 684 + return ret; 684 685 pdev->id = ret; 685 686 pdev->id_auto = true; 686 - dev_set_name(&pdev->dev, "%s.%d.auto", pdev->name, pdev->id); 687 + dev_set_name(dev, "%s.%d.auto", pdev->name, pdev->id); 687 688 break; 688 689 } 689 690 ··· 691 692 struct resource *p, *r = &pdev->resource[i]; 692 693 693 694 if (r->name == NULL) 694 - r->name = dev_name(&pdev->dev); 695 + r->name = dev_name(dev); 695 696 696 697 p = r->parent; 697 698 if (!p) { ··· 704 705 if (p) { 705 706 ret = insert_resource(p, r); 706 707 if (ret) { 707 - dev_err(&pdev->dev, "failed to claim resource %d: %pR\n", i, r); 708 + dev_err(dev, "failed to claim resource %d: %pR\n", i, r); 708 709 goto failed; 709 710 } 710 711 } 711 712 } 712 713 713 - pr_debug("Registering platform device '%s'. Parent at %s\n", 714 - dev_name(&pdev->dev), dev_name(pdev->dev.parent)); 714 + pr_debug("Registering platform device '%s'. Parent at %s\n", dev_name(dev), 715 + dev_name(dev->parent)); 715 716 716 - ret = device_add(&pdev->dev); 717 - if (ret == 0) 718 - return ret; 717 + ret = device_add(dev); 718 + if (ret) 719 + goto failed; 720 + 721 + return 0; 719 722 720 723 failed: 721 724 if (pdev->id_auto) { ··· 731 730 release_resource(r); 732 731 } 733 732 734 - err_out: 735 733 return ret; 736 734 } 737 735 EXPORT_SYMBOL_GPL(platform_device_add); ··· 1447 1447 static int platform_dma_configure(struct device *dev) 1448 1448 { 1449 1449 struct platform_driver *drv = to_platform_driver(dev->driver); 1450 + struct fwnode_handle *fwnode = dev_fwnode(dev); 1450 1451 enum dev_dma_attr attr; 1451 1452 int ret = 0; 1452 1453 1453 - if (dev->of_node) { 1454 - ret = of_dma_configure(dev, dev->of_node, true); 1455 - } else if (has_acpi_companion(dev)) { 1456 - attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode)); 1454 + if (is_of_node(fwnode)) { 1455 + ret = of_dma_configure(dev, to_of_node(fwnode), true); 1456 + } else if (is_acpi_device_node(fwnode)) { 1457 + attr = acpi_get_dma_attr(to_acpi_device_node(fwnode)); 1457 1458 ret = acpi_dma_configure(dev, attr); 1458 1459 } 1460 + if (ret || drv->driver_managed_dma) 1461 + return ret; 1459 1462 1460 - if (!ret && !drv->driver_managed_dma) { 1461 - ret = iommu_device_use_default_domain(dev); 1462 - if (ret) 1463 - arch_teardown_dma_ops(dev); 1464 - } 1463 + ret = iommu_device_use_default_domain(dev); 1464 + if (ret) 1465 + arch_teardown_dma_ops(dev); 1465 1466 1466 1467 return ret; 1467 1468 }
+2 -2
drivers/base/test/Kconfig
··· 14 14 depends on KUNIT 15 15 16 16 config DRIVER_PE_KUNIT_TEST 17 - bool "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS 18 - depends on KUNIT=y 17 + tristate "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS 18 + depends on KUNIT 19 19 default KUNIT_ALL_TESTS
+4
drivers/base/test/property-entry-test.c
··· 506 506 }; 507 507 508 508 kunit_test_suite(property_entry_test_suite); 509 + 510 + MODULE_DESCRIPTION("Test module for the property entry API"); 511 + MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>"); 512 + MODULE_LICENSE("GPL");
+25 -1
drivers/pci/pci-sysfs.c
··· 831 831 .is_bin_visible = pci_dev_config_attr_is_visible, 832 832 }; 833 833 834 + /* 835 + * llseek operation for mmappable PCI resources. 836 + * May be left unused if the arch doesn't provide them. 837 + */ 838 + static __maybe_unused loff_t 839 + pci_llseek_resource(struct file *filep, 840 + struct kobject *kobj __always_unused, 841 + struct bin_attribute *attr, 842 + loff_t offset, int whence) 843 + { 844 + return fixed_size_llseek(filep, offset, whence, attr->size); 845 + } 846 + 834 847 #ifdef HAVE_PCI_LEGACY 835 848 /** 836 849 * pci_read_legacy_io - read byte(s) from legacy I/O port space ··· 976 963 b->legacy_io->attr.mode = 0600; 977 964 b->legacy_io->read = pci_read_legacy_io; 978 965 b->legacy_io->write = pci_write_legacy_io; 966 + /* See pci_create_attr() for motivation */ 967 + b->legacy_io->llseek = pci_llseek_resource; 979 968 b->legacy_io->mmap = pci_mmap_legacy_io; 980 969 b->legacy_io->f_mapping = iomem_get_mapping; 981 970 pci_adjust_legacy_attr(b, pci_mmap_io); ··· 992 977 b->legacy_mem->size = 1024*1024; 993 978 b->legacy_mem->attr.mode = 0600; 994 979 b->legacy_mem->mmap = pci_mmap_legacy_mem; 980 + /* See pci_create_attr() for motivation */ 981 + b->legacy_mem->llseek = pci_llseek_resource; 995 982 b->legacy_mem->f_mapping = iomem_get_mapping; 996 983 pci_adjust_legacy_attr(b, pci_mmap_mem); 997 984 error = device_create_bin_file(&b->dev, b->legacy_mem); ··· 1212 1195 res_attr->mmap = pci_mmap_resource_uc; 1213 1196 } 1214 1197 } 1215 - if (res_attr->mmap) 1198 + if (res_attr->mmap) { 1216 1199 res_attr->f_mapping = iomem_get_mapping; 1200 + /* 1201 + * generic_file_llseek() consults f_mapping->host to determine 1202 + * the file size. As iomem_inode knows nothing about the 1203 + * attribute, it's not going to work, so override it as well. 1204 + */ 1205 + res_attr->llseek = pci_llseek_resource; 1206 + } 1217 1207 res_attr->attr.name = res_attr_name; 1218 1208 res_attr->attr.mode = 0600; 1219 1209 res_attr->size = pci_resource_len(pdev, num);
+1 -1
fs/debugfs/file.c
··· 939 939 new[pos + count] = '\0'; 940 940 strim(new); 941 941 942 - rcu_assign_pointer(*(char **)file->private_data, new); 942 + rcu_assign_pointer(*(char __rcu **)file->private_data, new); 943 943 synchronize_rcu(); 944 944 kfree(old); 945 945
+28 -1
fs/kernfs/file.c
··· 854 854 return ret; 855 855 } 856 856 857 + static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence) 858 + { 859 + struct kernfs_open_file *of = kernfs_of(file); 860 + const struct kernfs_ops *ops; 861 + loff_t ret; 862 + 863 + /* 864 + * @of->mutex nests outside active ref and is primarily to ensure that 865 + * the ops aren't called concurrently for the same open file. 866 + */ 867 + mutex_lock(&of->mutex); 868 + if (!kernfs_get_active(of->kn)) { 869 + mutex_unlock(&of->mutex); 870 + return -ENODEV; 871 + } 872 + 873 + ops = kernfs_ops(of->kn); 874 + if (ops->llseek) 875 + ret = ops->llseek(of, offset, whence); 876 + else 877 + ret = generic_file_llseek(file, offset, whence); 878 + 879 + kernfs_put_active(of->kn); 880 + mutex_unlock(&of->mutex); 881 + return ret; 882 + } 883 + 857 884 static void kernfs_notify_workfn(struct work_struct *work) 858 885 { 859 886 struct kernfs_node *kn; ··· 983 956 const struct file_operations kernfs_file_fops = { 984 957 .read_iter = kernfs_fop_read_iter, 985 958 .write_iter = kernfs_fop_write_iter, 986 - .llseek = generic_file_llseek, 959 + .llseek = kernfs_fop_llseek, 987 960 .mmap = kernfs_fop_mmap, 988 961 .open = kernfs_fop_open, 989 962 .release = kernfs_fop_release,
+13
fs/sysfs/file.c
··· 167 167 return battr->mmap(of->file, kobj, battr, vma); 168 168 } 169 169 170 + static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset, 171 + int whence) 172 + { 173 + struct bin_attribute *battr = of->kn->priv; 174 + struct kobject *kobj = of->kn->parent->priv; 175 + 176 + if (battr->llseek) 177 + return battr->llseek(of->file, kobj, battr, offset, whence); 178 + else 179 + return generic_file_llseek(of->file, offset, whence); 180 + } 181 + 170 182 static int sysfs_kf_bin_open(struct kernfs_open_file *of) 171 183 { 172 184 struct bin_attribute *battr = of->kn->priv; ··· 261 249 .write = sysfs_kf_bin_write, 262 250 .mmap = sysfs_kf_bin_mmap, 263 251 .open = sysfs_kf_bin_open, 252 + .llseek = sysfs_kf_bin_llseek, 264 253 }; 265 254 266 255 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
+4 -4
include/linux/device.h
··· 389 389 void devm_release_action(struct device *dev, void (*action)(void *), void *data); 390 390 391 391 int __devm_add_action(struct device *dev, void (*action)(void *), void *data, const char *name); 392 - #define devm_add_action(release, action, data) \ 393 - __devm_add_action(release, action, data, #action) 392 + #define devm_add_action(dev, action, data) \ 393 + __devm_add_action(dev, action, data, #action) 394 394 395 395 static inline int __devm_add_action_or_reset(struct device *dev, void (*action)(void *), 396 396 void *data, const char *name) ··· 403 403 404 404 return ret; 405 405 } 406 - #define devm_add_action_or_reset(release, action, data) \ 407 - __devm_add_action_or_reset(release, action, data, #action) 406 + #define devm_add_action_or_reset(dev, action, data) \ 407 + __devm_add_action_or_reset(dev, action, data, #action) 408 408 409 409 /** 410 410 * devm_alloc_percpu - Resource-managed alloc_percpu
+2
include/linux/fwnode.h
··· 41 41 struct fwnode_handle { 42 42 struct fwnode_handle *secondary; 43 43 const struct fwnode_operations *ops; 44 + 45 + /* The below is used solely by device links, don't use otherwise */ 44 46 struct device *dev; 45 47 struct list_head suppliers; 46 48 struct list_head consumers;
+6 -6
include/linux/ioport.h
··· 229 229 return res->flags & IORESOURCE_EXT_TYPE_BITS; 230 230 } 231 231 /* True iff r1 completely contains r2 */ 232 - static inline bool resource_contains(struct resource *r1, struct resource *r2) 232 + static inline bool resource_contains(const struct resource *r1, const struct resource *r2) 233 233 { 234 234 if (resource_type(r1) != resource_type(r2)) 235 235 return false; ··· 239 239 } 240 240 241 241 /* True if any part of r1 overlaps r2 */ 242 - static inline bool resource_overlaps(struct resource *r1, struct resource *r2) 242 + static inline bool resource_overlaps(const struct resource *r1, const struct resource *r2) 243 243 { 244 244 return r1->start <= r2->end && r1->end >= r2->start; 245 245 } 246 246 247 - static inline bool 248 - resource_intersection(struct resource *r1, struct resource *r2, struct resource *r) 247 + static inline bool resource_intersection(const struct resource *r1, const struct resource *r2, 248 + struct resource *r) 249 249 { 250 250 if (!resource_overlaps(r1, r2)) 251 251 return false; ··· 254 254 return true; 255 255 } 256 256 257 - static inline bool 258 - resource_union(struct resource *r1, struct resource *r2, struct resource *r) 257 + static inline bool resource_union(const struct resource *r1, const struct resource *r2, 258 + struct resource *r) 259 259 { 260 260 if (!resource_overlaps(r1, r2)) 261 261 return false;
+1
include/linux/kernfs.h
··· 316 316 struct poll_table_struct *pt); 317 317 318 318 int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma); 319 + loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence); 319 320 }; 320 321 321 322 /*
+2 -1
include/linux/property.h
··· 10 10 #ifndef _LINUX_PROPERTY_H_ 11 11 #define _LINUX_PROPERTY_H_ 12 12 13 + #include <linux/args.h> 13 14 #include <linux/bits.h> 14 15 #include <linux/fwnode.h> 15 16 #include <linux/stddef.h> ··· 289 288 #define SOFTWARE_NODE_REFERENCE(_ref_, ...) \ 290 289 (const struct software_node_ref_args) { \ 291 290 .node = _ref_, \ 292 - .nargs = ARRAY_SIZE(((u64[]){ 0, ##__VA_ARGS__ })) - 1, \ 291 + .nargs = COUNT_ARGS(__VA_ARGS__), \ 293 292 .args = { __VA_ARGS__ }, \ 294 293 } 295 294
+2
include/linux/sysfs.h
··· 181 181 char *, loff_t, size_t); 182 182 ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *, 183 183 char *, loff_t, size_t); 184 + loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *, 185 + loff_t, int); 184 186 int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, 185 187 struct vm_area_struct *vma); 186 188 };
+24 -27
kernel/resource.c
··· 56 56 57 57 static DEFINE_RWLOCK(resource_lock); 58 58 59 - static struct resource *next_resource(struct resource *p) 59 + static struct resource *next_resource(struct resource *p, bool skip_children) 60 60 { 61 - if (p->child) 61 + if (!skip_children && p->child) 62 62 return p->child; 63 63 while (!p->sibling && p->parent) 64 64 p = p->parent; 65 65 return p->sibling; 66 66 } 67 67 68 - static struct resource *next_resource_skip_children(struct resource *p) 69 - { 70 - while (!p->sibling && p->parent) 71 - p = p->parent; 72 - return p->sibling; 73 - } 74 - 75 68 #define for_each_resource(_root, _p, _skip_children) \ 76 - for ((_p) = (_root)->child; (_p); \ 77 - (_p) = (_skip_children) ? next_resource_skip_children(_p) : \ 78 - next_resource(_p)) 79 - 80 - static void *r_next(struct seq_file *m, void *v, loff_t *pos) 81 - { 82 - struct resource *p = v; 83 - (*pos)++; 84 - return (void *)next_resource(p); 85 - } 69 + for ((_p) = (_root)->child; (_p); (_p) = next_resource(_p, _skip_children)) 86 70 87 71 #ifdef CONFIG_PROC_FS 88 72 ··· 75 91 static void *r_start(struct seq_file *m, loff_t *pos) 76 92 __acquires(resource_lock) 77 93 { 78 - struct resource *p = pde_data(file_inode(m->file)); 79 - loff_t l = 0; 94 + struct resource *root = pde_data(file_inode(m->file)); 95 + struct resource *p; 96 + loff_t l = *pos; 97 + 80 98 read_lock(&resource_lock); 81 - for (p = p->child; p && l < *pos; p = r_next(m, p, &l)) 82 - ; 99 + for_each_resource(root, p, false) { 100 + if (l-- == 0) 101 + break; 102 + } 103 + 83 104 return p; 105 + } 106 + 107 + static void *r_next(struct seq_file *m, void *v, loff_t *pos) 108 + { 109 + struct resource *p = v; 110 + 111 + (*pos)++; 112 + 113 + return (void *)next_resource(p, false); 84 114 } 85 115 86 116 static void r_stop(struct seq_file *m, void *v) ··· 334 336 335 337 read_lock(&resource_lock); 336 338 337 - for (p = iomem_resource.child; p; p = next_resource(p)) { 339 + for_each_resource(&iomem_resource, p, false) { 338 340 /* If we passed the resource we are looking for, stop */ 339 341 if (p->start > end) { 340 342 p = NULL; ··· 1639 1641 */ 1640 1642 int iomem_map_sanity_check(resource_size_t addr, unsigned long size) 1641 1643 { 1642 - struct resource *p = &iomem_resource; 1643 1644 resource_size_t end = addr + size - 1; 1645 + struct resource *p; 1644 1646 int err = 0; 1645 - loff_t l; 1646 1647 1647 1648 read_lock(&resource_lock); 1648 - for (p = p->child; p ; p = r_next(NULL, p, &l)) { 1649 + for_each_resource(&iomem_resource, p, false) { 1649 1650 /* 1650 1651 * We can probably skip the resources without 1651 1652 * IORESOURCE_IO attribute?