[frank-w-bpi-r2-4.14:7.2-dango 169/215] drivers/block/fitblk.c:219:2-8: preceding lock on line 217

kernel test robot <[email protected]>
Newsgroups dev.linux.lists.oe-kbuild
Message-ID <[email protected]>
BCC: [email protected]
CC: [email protected]
TO: Frank Wunderlich <[email protected]>

tree:   https://github.com/frank-w/BPI-R2-4.14 7.2-dango
head:   d19514df7d0958e914bdb3435ea4d64d2fc5766a
commit: fded98d6b2974396d028a155643d0d49018fb1d4 [169/215] block: add uImage.FIT subimage block driver
:::::: branch date: 16 hours ago
:::::: commit date: 2 days ago
config: x86_64-randconfig-r064-20260706 (https://download.01.org/0day-ci/archive/20260706/[email protected]/config)
compiler: clang version 22.1.3 (https://github.com/llvm/llvm-project e9846648fd6183ee6d8cbdb4502213fcf902a211)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Reported-by: Julia Lawall <[email protected]>
| Closes: https://lore.kernel.org/r/[email protected]/

cocci warnings: (new ones prefixed by >>)
>> drivers/block/fitblk.c:219:2-8: preceding lock on line 217
--
>> drivers/block/fitblk.c:633:3-8: No need to set .owner here. The core will do it.
--
>> drivers/block/fitblk.c:407:4-5: Unneeded semicolon
--
>> drivers/block/fitblk.c:579:10-14: opportunity for str_plural(slot)

vim +219 drivers/block/fitblk.c

fded98d6b29743 Daniel Golle 2022-11-16  207  
fded98d6b29743 Daniel Golle 2022-11-16  208  static int add_fit_subimage_device(struct file *bdev_file,
fded98d6b29743 Daniel Golle 2022-11-16  209  				   unsigned int slot, sector_t start_sect,
fded98d6b29743 Daniel Golle 2022-11-16  210  				   sector_t nr_sect, bool readonly)
fded98d6b29743 Daniel Golle 2022-11-16  211  {
fded98d6b29743 Daniel Golle 2022-11-16  212  	struct block_device *bdev = file_bdev(bdev_file);
fded98d6b29743 Daniel Golle 2022-11-16  213  	struct fitblk *fitblk;
fded98d6b29743 Daniel Golle 2022-11-16  214  	struct gendisk *disk;
fded98d6b29743 Daniel Golle 2022-11-16  215  	int err;
fded98d6b29743 Daniel Golle 2022-11-16  216  
fded98d6b29743 Daniel Golle 2022-11-16 @217  	mutex_lock(&devices_mutex);
fded98d6b29743 Daniel Golle 2022-11-16  218  	if (!refcount_inc_not_zero(&num_devs))
fded98d6b29743 Daniel Golle 2022-11-16 @219  		return -EBADF;
fded98d6b29743 Daniel Golle 2022-11-16  220  
fded98d6b29743 Daniel Golle 2022-11-16  221  	fitblk = kzalloc(sizeof(struct fitblk), GFP_KERNEL);
fded98d6b29743 Daniel Golle 2022-11-16  222  	if (!fitblk) {
fded98d6b29743 Daniel Golle 2022-11-16  223  		err = -ENOMEM;
fded98d6b29743 Daniel Golle 2022-11-16  224  		goto out_unlock;
fded98d6b29743 Daniel Golle 2022-11-16  225  	}
fded98d6b29743 Daniel Golle 2022-11-16  226  
fded98d6b29743 Daniel Golle 2022-11-16  227  	fitblk->bdev_file = bdev_file;
fded98d6b29743 Daniel Golle 2022-11-16  228  	fitblk->start_sect = start_sect;
fded98d6b29743 Daniel Golle 2022-11-16  229  	INIT_WORK(&fitblk->remove_work, fitblk_purge);
fded98d6b29743 Daniel Golle 2022-11-16  230  
fded98d6b29743 Daniel Golle 2022-11-16  231  	disk = blk_alloc_disk(&bdev->bd_disk->queue->limits, NUMA_NO_NODE);
fded98d6b29743 Daniel Golle 2022-11-16  232  	if (!disk) {
fded98d6b29743 Daniel Golle 2022-11-16  233  		err = -ENOMEM;
fded98d6b29743 Daniel Golle 2022-11-16  234  		goto out_free_fitblk;
fded98d6b29743 Daniel Golle 2022-11-16  235  	}
fded98d6b29743 Daniel Golle 2022-11-16  236  
fded98d6b29743 Daniel Golle 2022-11-16  237  	disk->first_minor = 0;
fded98d6b29743 Daniel Golle 2022-11-16  238  	disk->flags = bdev->bd_disk->flags | GENHD_FL_NO_PART;
fded98d6b29743 Daniel Golle 2022-11-16  239  	disk->fops = &fitblk_fops;
fded98d6b29743 Daniel Golle 2022-11-16  240  	disk->private_data = fitblk;
fded98d6b29743 Daniel Golle 2022-11-16  241  	if (readonly) {
fded98d6b29743 Daniel Golle 2022-11-16  242  		set_disk_ro(disk, 1);
fded98d6b29743 Daniel Golle 2022-11-16  243  		snprintf(disk->disk_name, sizeof(disk->disk_name), FIT_DEVICE_PREFIX "%u", slot);
fded98d6b29743 Daniel Golle 2022-11-16  244  	} else {
fded98d6b29743 Daniel Golle 2022-11-16  245  		strcpy(disk->disk_name, FIT_DEVICE_PREFIX "rw");
fded98d6b29743 Daniel Golle 2022-11-16  246  	}
fded98d6b29743 Daniel Golle 2022-11-16  247  
fded98d6b29743 Daniel Golle 2022-11-16  248  	set_capacity(disk, nr_sect);
fded98d6b29743 Daniel Golle 2022-11-16  249  	disk->queue->queue_flags = bdev->bd_disk->queue->queue_flags;
fded98d6b29743 Daniel Golle 2022-11-16  250  
fded98d6b29743 Daniel Golle 2022-11-16  251  	fitblk->disk = disk;
fded98d6b29743 Daniel Golle 2022-11-16  252  	fitblk->pdev = platform_device_alloc(disk->disk_name, PLATFORM_DEVID_NONE);
fded98d6b29743 Daniel Golle 2022-11-16  253  	if (!fitblk->pdev) {
fded98d6b29743 Daniel Golle 2022-11-16  254  		err = -ENOMEM;
fded98d6b29743 Daniel Golle 2022-11-16  255  		goto out_cleanup_disk;
fded98d6b29743 Daniel Golle 2022-11-16  256  	}
fded98d6b29743 Daniel Golle 2022-11-16  257  
fded98d6b29743 Daniel Golle 2022-11-16  258  	fitblk->pdev->dev.parent = &pdev->dev;
fded98d6b29743 Daniel Golle 2022-11-16  259  	err = platform_device_add(fitblk->pdev);
fded98d6b29743 Daniel Golle 2022-11-16  260  	if (err)
fded98d6b29743 Daniel Golle 2022-11-16  261  		goto out_put_pdev;
fded98d6b29743 Daniel Golle 2022-11-16  262  
fded98d6b29743 Daniel Golle 2022-11-16  263  	err = device_add_disk(&fitblk->pdev->dev, disk, NULL);
fded98d6b29743 Daniel Golle 2022-11-16  264  	if (err)
fded98d6b29743 Daniel Golle 2022-11-16  265  		goto out_del_pdev;
fded98d6b29743 Daniel Golle 2022-11-16  266  
fded98d6b29743 Daniel Golle 2022-11-16  267  	if (!ROOT_DEV)
fded98d6b29743 Daniel Golle 2022-11-16  268  		ROOT_DEV = disk->part0->bd_dev;
fded98d6b29743 Daniel Golle 2022-11-16  269  
fded98d6b29743 Daniel Golle 2022-11-16  270  	list_add_tail(&fitblk->list, &fitblk_devices);
fded98d6b29743 Daniel Golle 2022-11-16  271  
fded98d6b29743 Daniel Golle 2022-11-16  272  	mutex_unlock(&devices_mutex);
fded98d6b29743 Daniel Golle 2022-11-16  273  
fded98d6b29743 Daniel Golle 2022-11-16  274  	return 0;
fded98d6b29743 Daniel Golle 2022-11-16  275  
fded98d6b29743 Daniel Golle 2022-11-16  276  out_del_pdev:
fded98d6b29743 Daniel Golle 2022-11-16  277  	platform_device_del(fitblk->pdev);
fded98d6b29743 Daniel Golle 2022-11-16  278  out_put_pdev:
fded98d6b29743 Daniel Golle 2022-11-16  279  	platform_device_put(fitblk->pdev);
fded98d6b29743 Daniel Golle 2022-11-16  280  out_cleanup_disk:
fded98d6b29743 Daniel Golle 2022-11-16  281  	put_disk(disk);
fded98d6b29743 Daniel Golle 2022-11-16  282  out_free_fitblk:
fded98d6b29743 Daniel Golle 2022-11-16  283  	kfree(fitblk);
fded98d6b29743 Daniel Golle 2022-11-16  284  out_unlock:
fded98d6b29743 Daniel Golle 2022-11-16  285  	refcount_dec(&num_devs);
fded98d6b29743 Daniel Golle 2022-11-16  286  	mutex_unlock(&devices_mutex);
fded98d6b29743 Daniel Golle 2022-11-16  287  	return err;
fded98d6b29743 Daniel Golle 2022-11-16  288  }
fded98d6b29743 Daniel Golle 2022-11-16  289  
fded98d6b29743 Daniel Golle 2022-11-16  290  static void fitblk_mark_dead(struct block_device *bdev, bool surprise)
fded98d6b29743 Daniel Golle 2022-11-16  291  {
fded98d6b29743 Daniel Golle 2022-11-16  292  	struct list_head *n, *tmp;
fded98d6b29743 Daniel Golle 2022-11-16  293  	struct fitblk *fitblk;
fded98d6b29743 Daniel Golle 2022-11-16  294  
fded98d6b29743 Daniel Golle 2022-11-16  295  	mutex_lock(&devices_mutex);
fded98d6b29743 Daniel Golle 2022-11-16  296  	list_for_each_safe(n, tmp, &fitblk_devices) {
fded98d6b29743 Daniel Golle 2022-11-16  297  		fitblk = list_entry(n, struct fitblk, list);
fded98d6b29743 Daniel Golle 2022-11-16  298  		if (file_bdev(fitblk->bdev_file) != bdev)
fded98d6b29743 Daniel Golle 2022-11-16  299  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  300  
fded98d6b29743 Daniel Golle 2022-11-16  301  		fitblk->dead = true;
fded98d6b29743 Daniel Golle 2022-11-16  302  		list_del(&fitblk->list);
fded98d6b29743 Daniel Golle 2022-11-16  303  		/* removal needs to be deferred to avoid deadlock */
fded98d6b29743 Daniel Golle 2022-11-16  304  		schedule_work(&fitblk->remove_work);
fded98d6b29743 Daniel Golle 2022-11-16  305  	}
fded98d6b29743 Daniel Golle 2022-11-16  306  	mutex_unlock(&devices_mutex);
fded98d6b29743 Daniel Golle 2022-11-16  307  }
fded98d6b29743 Daniel Golle 2022-11-16  308  
fded98d6b29743 Daniel Golle 2022-11-16  309  static const struct blk_holder_ops fitblk_hops = {
fded98d6b29743 Daniel Golle 2022-11-16  310  	.mark_dead = fitblk_mark_dead,
fded98d6b29743 Daniel Golle 2022-11-16  311  };
fded98d6b29743 Daniel Golle 2022-11-16  312  
fded98d6b29743 Daniel Golle 2022-11-16  313  static int parse_fit_on_dev(struct device *dev)
fded98d6b29743 Daniel Golle 2022-11-16  314  {
fded98d6b29743 Daniel Golle 2022-11-16  315  	struct file *bdev_file;
fded98d6b29743 Daniel Golle 2022-11-16  316  	struct block_device *bdev;
fded98d6b29743 Daniel Golle 2022-11-16  317  	struct address_space *mapping;
fded98d6b29743 Daniel Golle 2022-11-16  318  	struct folio *folio;
fded98d6b29743 Daniel Golle 2022-11-16  319  	pgoff_t f_index = 0;
fded98d6b29743 Daniel Golle 2022-11-16  320  	size_t bytes_left, bytes_to_copy;
fded98d6b29743 Daniel Golle 2022-11-16  321  	void *pre_fit, *fit, *fit_c;
fded98d6b29743 Daniel Golle 2022-11-16  322  	u64 dsize, dsectors, imgmaxsect = 0;
fded98d6b29743 Daniel Golle 2022-11-16  323  	u32 size, image_pos, image_len;
fded98d6b29743 Daniel Golle 2022-11-16  324  	const __be32 *image_offset_be, *image_len_be, *image_pos_be;
fded98d6b29743 Daniel Golle 2022-11-16  325  	int ret = 0, node, images, config;
fded98d6b29743 Daniel Golle 2022-11-16  326  	const char *image_name, *image_type, *image_description,
fded98d6b29743 Daniel Golle 2022-11-16  327  		*config_default, *config_description, *config_loadables;
fded98d6b29743 Daniel Golle 2022-11-16  328  	u32 image_name_len, image_type_len, image_description_len,
fded98d6b29743 Daniel Golle 2022-11-16  329  		bootconf_len, config_default_len, config_description_len,
fded98d6b29743 Daniel Golle 2022-11-16  330  		config_loadables_len;
fded98d6b29743 Daniel Golle 2022-11-16  331  	sector_t start_sect, nr_sects;
fded98d6b29743 Daniel Golle 2022-11-16  332  	struct device_node *np = NULL;
fded98d6b29743 Daniel Golle 2022-11-16  333  	const char *bootconf_c;
fded98d6b29743 Daniel Golle 2022-11-16  334  	const char *loadable;
fded98d6b29743 Daniel Golle 2022-11-16  335  	char *bootconf = NULL, *bootconf_term;
fded98d6b29743 Daniel Golle 2022-11-16  336  	bool found;
fded98d6b29743 Daniel Golle 2022-11-16  337  	int loadables_rem_len, loadable_len;
fded98d6b29743 Daniel Golle 2022-11-16  338  	u16 loadcnt;
fded98d6b29743 Daniel Golle 2022-11-16  339  	unsigned int slot = 0;
fded98d6b29743 Daniel Golle 2022-11-16  340  
fded98d6b29743 Daniel Golle 2022-11-16  341  	/* Exclusive open the block device to receive holder notifications */
fded98d6b29743 Daniel Golle 2022-11-16  342  	bdev_file = bdev_file_open_by_dev(dev->devt, BLK_OPEN_READ | BLK_OPEN_RESTRICT_WRITES,
fded98d6b29743 Daniel Golle 2022-11-16  343  					  &_fitblk_claim_ptr, &fitblk_hops);
fded98d6b29743 Daniel Golle 2022-11-16  344  	if (!bdev_file)
fded98d6b29743 Daniel Golle 2022-11-16  345  		return -ENODEV;
fded98d6b29743 Daniel Golle 2022-11-16  346  
fded98d6b29743 Daniel Golle 2022-11-16  347  	if (IS_ERR(bdev_file))
fded98d6b29743 Daniel Golle 2022-11-16  348  		return PTR_ERR(bdev_file);
fded98d6b29743 Daniel Golle 2022-11-16  349  
fded98d6b29743 Daniel Golle 2022-11-16  350  	bdev = file_bdev(bdev_file);
fded98d6b29743 Daniel Golle 2022-11-16  351  	mapping = bdev_file->f_mapping;
fded98d6b29743 Daniel Golle 2022-11-16  352  
fded98d6b29743 Daniel Golle 2022-11-16  353  	/* map first page */
fded98d6b29743 Daniel Golle 2022-11-16  354  	folio = read_mapping_folio(mapping, f_index++, NULL);
fded98d6b29743 Daniel Golle 2022-11-16  355  	if (IS_ERR(folio)) {
fded98d6b29743 Daniel Golle 2022-11-16  356  		ret = PTR_ERR(folio);
fded98d6b29743 Daniel Golle 2022-11-16  357  		goto out_blkdev;
fded98d6b29743 Daniel Golle 2022-11-16  358  	}
fded98d6b29743 Daniel Golle 2022-11-16  359  	pre_fit = folio_address(folio) + offset_in_folio(folio, 0);
fded98d6b29743 Daniel Golle 2022-11-16  360  
fded98d6b29743 Daniel Golle 2022-11-16  361  	/* uImage.FIT is based on flattened device tree structure */
fded98d6b29743 Daniel Golle 2022-11-16  362  	if (fdt_check_header(pre_fit)) {
fded98d6b29743 Daniel Golle 2022-11-16  363  		ret = -EINVAL;
fded98d6b29743 Daniel Golle 2022-11-16  364  		folio_put(folio);
fded98d6b29743 Daniel Golle 2022-11-16  365  		goto out_blkdev;
fded98d6b29743 Daniel Golle 2022-11-16  366  	}
fded98d6b29743 Daniel Golle 2022-11-16  367  
fded98d6b29743 Daniel Golle 2022-11-16  368  	size = fdt_totalsize(pre_fit);
fded98d6b29743 Daniel Golle 2022-11-16  369  
fded98d6b29743 Daniel Golle 2022-11-16  370  	if (size > PAGE_SIZE * FIT_MAX_PAGES) {
fded98d6b29743 Daniel Golle 2022-11-16  371  		ret = -EOPNOTSUPP;
fded98d6b29743 Daniel Golle 2022-11-16  372  		folio_put(folio);
fded98d6b29743 Daniel Golle 2022-11-16  373  		goto out_blkdev;
fded98d6b29743 Daniel Golle 2022-11-16  374  	}
fded98d6b29743 Daniel Golle 2022-11-16  375  
fded98d6b29743 Daniel Golle 2022-11-16  376  	/* acquire disk size */
fded98d6b29743 Daniel Golle 2022-11-16  377  	dsectors = bdev_nr_sectors(bdev);
fded98d6b29743 Daniel Golle 2022-11-16  378  	dsize = dsectors << SECTOR_SHIFT;
fded98d6b29743 Daniel Golle 2022-11-16  379  
fded98d6b29743 Daniel Golle 2022-11-16  380  	/* abort if FIT structure is larger than disk or partition size */
fded98d6b29743 Daniel Golle 2022-11-16  381  	if (size >= dsize) {
fded98d6b29743 Daniel Golle 2022-11-16  382  		ret = -EFBIG;
fded98d6b29743 Daniel Golle 2022-11-16  383  		folio_put(folio);
fded98d6b29743 Daniel Golle 2022-11-16  384  		goto out_blkdev;
fded98d6b29743 Daniel Golle 2022-11-16  385  	}
fded98d6b29743 Daniel Golle 2022-11-16  386  
fded98d6b29743 Daniel Golle 2022-11-16  387  	fit = kmalloc(size, GFP_KERNEL);
fded98d6b29743 Daniel Golle 2022-11-16  388  	if (!fit) {
fded98d6b29743 Daniel Golle 2022-11-16  389  		ret = -ENOMEM;
fded98d6b29743 Daniel Golle 2022-11-16  390  		folio_put(folio);
fded98d6b29743 Daniel Golle 2022-11-16  391  		goto out_blkdev;
fded98d6b29743 Daniel Golle 2022-11-16  392  	}
fded98d6b29743 Daniel Golle 2022-11-16  393  
fded98d6b29743 Daniel Golle 2022-11-16  394  	bytes_left = size;
fded98d6b29743 Daniel Golle 2022-11-16  395  	fit_c = fit;
fded98d6b29743 Daniel Golle 2022-11-16  396  	while (bytes_left > 0) {
fded98d6b29743 Daniel Golle 2022-11-16  397  		bytes_to_copy = min_t(size_t, bytes_left, folio_size(folio) - offset_in_folio(folio, 0));
fded98d6b29743 Daniel Golle 2022-11-16  398  		memcpy(fit_c, pre_fit, bytes_to_copy);
fded98d6b29743 Daniel Golle 2022-11-16  399  		fit_c += bytes_to_copy;
fded98d6b29743 Daniel Golle 2022-11-16  400  		bytes_left -= bytes_to_copy;
fded98d6b29743 Daniel Golle 2022-11-16  401  		if (bytes_left) {
fded98d6b29743 Daniel Golle 2022-11-16  402  			folio_put(folio);
fded98d6b29743 Daniel Golle 2022-11-16  403  			folio = read_mapping_folio(mapping, f_index++, NULL);
fded98d6b29743 Daniel Golle 2022-11-16  404  			if (IS_ERR(folio)) {
fded98d6b29743 Daniel Golle 2022-11-16  405  				ret = PTR_ERR(folio);
fded98d6b29743 Daniel Golle 2022-11-16  406  				goto out_blkdev;
fded98d6b29743 Daniel Golle 2022-11-16 @407  			};
fded98d6b29743 Daniel Golle 2022-11-16  408  			pre_fit = folio_address(folio) + offset_in_folio(folio, 0);
fded98d6b29743 Daniel Golle 2022-11-16  409  		}
fded98d6b29743 Daniel Golle 2022-11-16  410  	}
fded98d6b29743 Daniel Golle 2022-11-16  411  	folio_put(folio);
fded98d6b29743 Daniel Golle 2022-11-16  412  
fded98d6b29743 Daniel Golle 2022-11-16  413  	/* set boot config node name U-Boot may have added to the device tree */
fded98d6b29743 Daniel Golle 2022-11-16  414  	np = of_find_node_by_path("/chosen");
fded98d6b29743 Daniel Golle 2022-11-16  415  	if (np) {
fded98d6b29743 Daniel Golle 2022-11-16  416  		bootconf_c = of_get_property(np, "u-boot,bootconf", &bootconf_len);
fded98d6b29743 Daniel Golle 2022-11-16  417  		if (bootconf_c && bootconf_len)
fded98d6b29743 Daniel Golle 2022-11-16  418  			bootconf = kmemdup_nul(bootconf_c, bootconf_len, GFP_KERNEL);
fded98d6b29743 Daniel Golle 2022-11-16  419  	}
fded98d6b29743 Daniel Golle 2022-11-16  420  
fded98d6b29743 Daniel Golle 2022-11-16  421  	if (bootconf) {
fded98d6b29743 Daniel Golle 2022-11-16  422  		bootconf_term = strchr(bootconf, '#');
fded98d6b29743 Daniel Golle 2022-11-16  423  		if (bootconf_term)
fded98d6b29743 Daniel Golle 2022-11-16  424  			*bootconf_term = '\0';
fded98d6b29743 Daniel Golle 2022-11-16  425  	}
fded98d6b29743 Daniel Golle 2022-11-16  426  
fded98d6b29743 Daniel Golle 2022-11-16  427  	/* find configuration path in uImage.FIT */
fded98d6b29743 Daniel Golle 2022-11-16  428  	config = fdt_path_offset(fit, FIT_CONFS_PATH);
fded98d6b29743 Daniel Golle 2022-11-16  429  	if (config < 0) {
fded98d6b29743 Daniel Golle 2022-11-16  430  		pr_err("FIT: Cannot find %s node: %d\n",
fded98d6b29743 Daniel Golle 2022-11-16  431  			FIT_CONFS_PATH, config);
fded98d6b29743 Daniel Golle 2022-11-16  432  		ret = -ENOENT;
fded98d6b29743 Daniel Golle 2022-11-16  433  		goto out_bootconf;
fded98d6b29743 Daniel Golle 2022-11-16  434  	}
fded98d6b29743 Daniel Golle 2022-11-16  435  
fded98d6b29743 Daniel Golle 2022-11-16  436  	/* get default configuration node name */
fded98d6b29743 Daniel Golle 2022-11-16  437  	config_default =
fded98d6b29743 Daniel Golle 2022-11-16  438  		fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len);
fded98d6b29743 Daniel Golle 2022-11-16  439  
fded98d6b29743 Daniel Golle 2022-11-16  440  	/* make sure we got either default or selected boot config node name */
fded98d6b29743 Daniel Golle 2022-11-16  441  	if (!config_default && !bootconf) {
fded98d6b29743 Daniel Golle 2022-11-16  442  		pr_err("FIT: Cannot find default configuration\n");
fded98d6b29743 Daniel Golle 2022-11-16  443  		ret = -ENOENT;
fded98d6b29743 Daniel Golle 2022-11-16  444  		goto out_bootconf;
fded98d6b29743 Daniel Golle 2022-11-16  445  	}
fded98d6b29743 Daniel Golle 2022-11-16  446  
fded98d6b29743 Daniel Golle 2022-11-16  447  	/* find selected boot config node, fallback on default config node */
fded98d6b29743 Daniel Golle 2022-11-16  448  	node = fdt_subnode_offset(fit, config, bootconf ?: config_default);
fded98d6b29743 Daniel Golle 2022-11-16  449  	if (node < 0) {
fded98d6b29743 Daniel Golle 2022-11-16  450  		pr_err("FIT: Cannot find %s node: %d\n",
fded98d6b29743 Daniel Golle 2022-11-16  451  			bootconf ?: config_default, node);
fded98d6b29743 Daniel Golle 2022-11-16  452  		ret = -ENOENT;
fded98d6b29743 Daniel Golle 2022-11-16  453  		goto out_bootconf;
fded98d6b29743 Daniel Golle 2022-11-16  454  	}
fded98d6b29743 Daniel Golle 2022-11-16  455  
fded98d6b29743 Daniel Golle 2022-11-16  456  	pr_info("FIT: Detected U-Boot %s\n", ubootver);
fded98d6b29743 Daniel Golle 2022-11-16  457  
fded98d6b29743 Daniel Golle 2022-11-16  458  	/* get selected configuration data */
fded98d6b29743 Daniel Golle 2022-11-16  459  	config_description =
fded98d6b29743 Daniel Golle 2022-11-16  460  		fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len);
fded98d6b29743 Daniel Golle 2022-11-16  461  	config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP,
fded98d6b29743 Daniel Golle 2022-11-16  462  				       &config_loadables_len);
fded98d6b29743 Daniel Golle 2022-11-16  463  
fded98d6b29743 Daniel Golle 2022-11-16  464  	pr_info("FIT: %s configuration: \"%.*s\"%s%.*s%s\n",
fded98d6b29743 Daniel Golle 2022-11-16  465  		bootconf ? "Selected" : "Default",
fded98d6b29743 Daniel Golle 2022-11-16  466  		bootconf ? bootconf_len : config_default_len,
fded98d6b29743 Daniel Golle 2022-11-16  467  		bootconf ?: config_default,
fded98d6b29743 Daniel Golle 2022-11-16  468  		config_description ? " (" : "",
fded98d6b29743 Daniel Golle 2022-11-16  469  		config_description ? config_description_len : 0,
fded98d6b29743 Daniel Golle 2022-11-16  470  		config_description ?: "",
fded98d6b29743 Daniel Golle 2022-11-16  471  		config_description ? ")" : "");
fded98d6b29743 Daniel Golle 2022-11-16  472  
fded98d6b29743 Daniel Golle 2022-11-16  473  	if (!config_loadables || !config_loadables_len) {
fded98d6b29743 Daniel Golle 2022-11-16  474  		pr_err("FIT: No loadables configured in \"%s\"\n",
fded98d6b29743 Daniel Golle 2022-11-16  475  			bootconf ?: config_default);
fded98d6b29743 Daniel Golle 2022-11-16  476  		ret = -ENOENT;
fded98d6b29743 Daniel Golle 2022-11-16  477  		goto out_bootconf;
fded98d6b29743 Daniel Golle 2022-11-16  478  	}
fded98d6b29743 Daniel Golle 2022-11-16  479  
fded98d6b29743 Daniel Golle 2022-11-16  480  	/* get images path in uImage.FIT */
fded98d6b29743 Daniel Golle 2022-11-16  481  	images = fdt_path_offset(fit, FIT_IMAGES_PATH);
fded98d6b29743 Daniel Golle 2022-11-16  482  	if (images < 0) {
fded98d6b29743 Daniel Golle 2022-11-16  483  		pr_err("FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images);
fded98d6b29743 Daniel Golle 2022-11-16  484  		ret = -EINVAL;
fded98d6b29743 Daniel Golle 2022-11-16  485  		goto out_bootconf;
fded98d6b29743 Daniel Golle 2022-11-16  486  	}
fded98d6b29743 Daniel Golle 2022-11-16  487  
fded98d6b29743 Daniel Golle 2022-11-16  488  	/* iterate over images in uImage.FIT */
fded98d6b29743 Daniel Golle 2022-11-16  489  	fdt_for_each_subnode(node, fit, images) {
fded98d6b29743 Daniel Golle 2022-11-16  490  		image_name = fdt_get_name(fit, node, &image_name_len);
fded98d6b29743 Daniel Golle 2022-11-16  491  		image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len);
fded98d6b29743 Daniel Golle 2022-11-16  492  		image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL);
fded98d6b29743 Daniel Golle 2022-11-16  493  		image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL);
fded98d6b29743 Daniel Golle 2022-11-16  494  		image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL);
fded98d6b29743 Daniel Golle 2022-11-16  495  
fded98d6b29743 Daniel Golle 2022-11-16  496  		if (!image_name || !image_type || !image_len_be ||
fded98d6b29743 Daniel Golle 2022-11-16  497  		    !image_name_len || !image_type_len)
fded98d6b29743 Daniel Golle 2022-11-16  498  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  499  
fded98d6b29743 Daniel Golle 2022-11-16  500  		image_len = be32_to_cpu(*image_len_be);
fded98d6b29743 Daniel Golle 2022-11-16  501  		if (!image_len)
fded98d6b29743 Daniel Golle 2022-11-16  502  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  503  
fded98d6b29743 Daniel Golle 2022-11-16  504  		if (image_offset_be)
fded98d6b29743 Daniel Golle 2022-11-16  505  			image_pos = be32_to_cpu(*image_offset_be) + size;
fded98d6b29743 Daniel Golle 2022-11-16  506  		else if (image_pos_be)
fded98d6b29743 Daniel Golle 2022-11-16  507  			image_pos = be32_to_cpu(*image_pos_be);
fded98d6b29743 Daniel Golle 2022-11-16  508  		else
fded98d6b29743 Daniel Golle 2022-11-16  509  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  510  
fded98d6b29743 Daniel Golle 2022-11-16  511  		image_description = fdt_getprop(fit, node, FIT_DESC_PROP,
fded98d6b29743 Daniel Golle 2022-11-16  512  						&image_description_len);
fded98d6b29743 Daniel Golle 2022-11-16  513  
fded98d6b29743 Daniel Golle 2022-11-16  514  		pr_info("FIT: %16s sub-image 0x%08x..0x%08x \"%.*s\"%s%.*s%s\n",
fded98d6b29743 Daniel Golle 2022-11-16  515  			image_type, image_pos, image_pos + image_len - 1,
fded98d6b29743 Daniel Golle 2022-11-16  516  			image_name_len, image_name, image_description ? " (" : "",
fded98d6b29743 Daniel Golle 2022-11-16  517  			image_description ? image_description_len : 0,
fded98d6b29743 Daniel Golle 2022-11-16  518  			image_description ?: "", image_description ? ") " : "");
fded98d6b29743 Daniel Golle 2022-11-16  519  
fded98d6b29743 Daniel Golle 2022-11-16  520  		/* only 'filesystem' images should be mapped as partitions */
fded98d6b29743 Daniel Golle 2022-11-16  521  		if (strncmp(image_type, FIT_FILESYSTEM_PROP, image_type_len))
fded98d6b29743 Daniel Golle 2022-11-16  522  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  523  
fded98d6b29743 Daniel Golle 2022-11-16  524  		/* check if sub-image is part of configured loadables */
fded98d6b29743 Daniel Golle 2022-11-16  525  		found = false;
fded98d6b29743 Daniel Golle 2022-11-16  526  		loadable = config_loadables;
fded98d6b29743 Daniel Golle 2022-11-16  527  		loadables_rem_len = config_loadables_len;
fded98d6b29743 Daniel Golle 2022-11-16  528  		for (loadcnt = 0; loadables_rem_len > 1 &&
fded98d6b29743 Daniel Golle 2022-11-16  529  				  loadcnt < MAX_FIT_LOADABLES; ++loadcnt) {
fded98d6b29743 Daniel Golle 2022-11-16  530  			loadable_len =
fded98d6b29743 Daniel Golle 2022-11-16  531  				strnlen(loadable, loadables_rem_len - 1) + 1;
fded98d6b29743 Daniel Golle 2022-11-16  532  			loadables_rem_len -= loadable_len;
fded98d6b29743 Daniel Golle 2022-11-16  533  			if (!strncmp(image_name, loadable, loadable_len)) {
fded98d6b29743 Daniel Golle 2022-11-16  534  				found = true;
fded98d6b29743 Daniel Golle 2022-11-16  535  				break;
fded98d6b29743 Daniel Golle 2022-11-16  536  			}
fded98d6b29743 Daniel Golle 2022-11-16  537  			loadable += loadable_len;
fded98d6b29743 Daniel Golle 2022-11-16  538  		}
fded98d6b29743 Daniel Golle 2022-11-16  539  		if (!found)
fded98d6b29743 Daniel Golle 2022-11-16  540  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  541  
fded98d6b29743 Daniel Golle 2022-11-16  542  		if (image_pos % (1 << PAGE_SHIFT)) {
fded98d6b29743 Daniel Golle 2022-11-16  543  			dev_err(dev, "FIT: image %.*s start not aligned to page boundaries, skipping\n",
fded98d6b29743 Daniel Golle 2022-11-16  544  				image_name_len, image_name);
fded98d6b29743 Daniel Golle 2022-11-16  545  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  546  		}
fded98d6b29743 Daniel Golle 2022-11-16  547  
fded98d6b29743 Daniel Golle 2022-11-16  548  		if (image_len % (1 << PAGE_SHIFT)) {
fded98d6b29743 Daniel Golle 2022-11-16  549  			dev_err(dev, "FIT: sub-image %.*s end not aligned to page boundaries, skipping\n",
fded98d6b29743 Daniel Golle 2022-11-16  550  				image_name_len, image_name);
fded98d6b29743 Daniel Golle 2022-11-16  551  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  552  		}
fded98d6b29743 Daniel Golle 2022-11-16  553  
fded98d6b29743 Daniel Golle 2022-11-16  554  		start_sect = image_pos >> SECTOR_SHIFT;
fded98d6b29743 Daniel Golle 2022-11-16  555  		nr_sects = image_len >> SECTOR_SHIFT;
fded98d6b29743 Daniel Golle 2022-11-16  556  		imgmaxsect = max_t(sector_t, imgmaxsect, start_sect + nr_sects);
fded98d6b29743 Daniel Golle 2022-11-16  557  
fded98d6b29743 Daniel Golle 2022-11-16  558  		if (start_sect + nr_sects > dsectors) {
fded98d6b29743 Daniel Golle 2022-11-16  559  			dev_err(dev, "FIT: sub-image %.*s disk access beyond EOD\n",
fded98d6b29743 Daniel Golle 2022-11-16  560  				image_name_len, image_name);
fded98d6b29743 Daniel Golle 2022-11-16  561  			continue;
fded98d6b29743 Daniel Golle 2022-11-16  562  		}
fded98d6b29743 Daniel Golle 2022-11-16  563  
fded98d6b29743 Daniel Golle 2022-11-16  564  		if (!slot) {
fded98d6b29743 Daniel Golle 2022-11-16  565  			ret = sysfs_create_link_nowarn(&pdev->dev.kobj, bdev_kobj(bdev), "lower_dev");
fded98d6b29743 Daniel Golle 2022-11-16  566  			if (ret && ret != -EEXIST)
fded98d6b29743 Daniel Golle 2022-11-16  567  				goto out_bootconf;
fded98d6b29743 Daniel Golle 2022-11-16  568  
fded98d6b29743 Daniel Golle 2022-11-16  569  			ret = 0;
fded98d6b29743 Daniel Golle 2022-11-16  570  		}
fded98d6b29743 Daniel Golle 2022-11-16  571  
fded98d6b29743 Daniel Golle 2022-11-16  572  		add_fit_subimage_device(bdev_file, slot++, start_sect, nr_sects, true);
fded98d6b29743 Daniel Golle 2022-11-16  573  	}
fded98d6b29743 Daniel Golle 2022-11-16  574  
fded98d6b29743 Daniel Golle 2022-11-16  575  	if (!slot)
fded98d6b29743 Daniel Golle 2022-11-16  576  		goto out_bootconf;
fded98d6b29743 Daniel Golle 2022-11-16  577  
fded98d6b29743 Daniel Golle 2022-11-16  578  	dev_info(dev, "mapped %u uImage.FIT filesystem sub-image%s as /dev/fit%s%u%s\n",
fded98d6b29743 Daniel Golle 2022-11-16  579  		 slot, (slot > 1)?"s":"", (slot > 1)?"[0...":"", slot - 1,
fded98d6b29743 Daniel Golle 2022-11-16  580  		 (slot > 1)?"]":"");
fded98d6b29743 Daniel Golle 2022-11-16  581  
fded98d6b29743 Daniel Golle 2022-11-16  582  	/* in case uImage.FIT is stored in a partition, map the remaining space */
fded98d6b29743 Daniel Golle 2022-11-16  583  	if (!bdev_read_only(bdev) && bdev_is_partition(bdev) &&
fded98d6b29743 Daniel Golle 2022-11-16  584  	    (imgmaxsect + MIN_FREE_SECT) < dsectors) {
fded98d6b29743 Daniel Golle 2022-11-16  585  		add_fit_subimage_device(bdev_file, slot++, imgmaxsect,
fded98d6b29743 Daniel Golle 2022-11-16  586  					dsectors - imgmaxsect, false);
fded98d6b29743 Daniel Golle 2022-11-16  587  		dev_info(dev, "mapped remaing space as /dev/fitrw\n");
fded98d6b29743 Daniel Golle 2022-11-16  588  	}
fded98d6b29743 Daniel Golle 2022-11-16  589  
fded98d6b29743 Daniel Golle 2022-11-16  590  out_bootconf:
fded98d6b29743 Daniel Golle 2022-11-16  591  	kfree(bootconf);
fded98d6b29743 Daniel Golle 2022-11-16  592  	kfree(fit);
fded98d6b29743 Daniel Golle 2022-11-16  593  out_blkdev:
fded98d6b29743 Daniel Golle 2022-11-16  594  	if (!slot)
fded98d6b29743 Daniel Golle 2022-11-16  595  		fput(bdev_file);
fded98d6b29743 Daniel Golle 2022-11-16  596  
fded98d6b29743 Daniel Golle 2022-11-16  597  	return ret;
fded98d6b29743 Daniel Golle 2022-11-16  598  }
fded98d6b29743 Daniel Golle 2022-11-16  599  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.