Skip to content

Commit 8a09bb1

Browse files
Sakari Ailusmchehab
authored andcommitted
media: intel/ipu6: Don't re-allocate memory for firmware
The ipu6 driver allocated vmalloc memory for the firmware if request_firmware() somehow managed not to use vmalloc to allocate it. Still how the memory is allocated by request_firmware() is not specified in its API, so be prepared for kmalloc-allocated firmware, too. Instead of allocating new vmalloc-backed buffer for the firmware, obtain the pages from virtual addresses instead. Link: https://lore.kernel.org/linux-media/[email protected] Reported-by: Stephen Rothwell <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/ Fixes: 25fedc0 ("media: intel/ipu6: add Intel IPU6 PCI device driver") Signed-off-by: Sakari Ailus <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 1aa1329 commit 8a09bb1

File tree

2 files changed

+7
-41
lines changed

2 files changed

+7
-41
lines changed

drivers/media/pci/intel/ipu6/ipu6-buttress.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,12 +552,16 @@ int ipu6_buttress_reset_authentication(struct ipu6_device *isp)
552552
int ipu6_buttress_map_fw_image(struct ipu6_bus_device *sys,
553553
const struct firmware *fw, struct sg_table *sgt)
554554
{
555+
bool is_vmalloc = is_vmalloc_addr(fw->data);
555556
struct page **pages;
556557
const void *addr;
557558
unsigned long n_pages;
558559
unsigned int i;
559560
int ret;
560561

562+
if (!is_vmalloc && !virt_addr_valid(fw->data))
563+
return -EDOM;
564+
561565
n_pages = PHYS_PFN(PAGE_ALIGN(fw->size));
562566

563567
pages = kmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
@@ -566,7 +570,8 @@ int ipu6_buttress_map_fw_image(struct ipu6_bus_device *sys,
566570

567571
addr = fw->data;
568572
for (i = 0; i < n_pages; i++) {
569-
struct page *p = vmalloc_to_page(addr);
573+
struct page *p = is_vmalloc ?
574+
vmalloc_to_page(addr) : virt_to_page(addr);
570575

571576
if (!p) {
572577
ret = -ENOMEM;

drivers/media/pci/intel/ipu6/ipu6.c

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -503,45 +503,6 @@ static void ipu6_configure_vc_mechanism(struct ipu6_device *isp)
503503
writel(val, isp->base + BUTTRESS_REG_BTRS_CTRL);
504504
}
505505

506-
static int request_cpd_fw(const struct firmware **firmware_p, const char *name,
507-
struct device *device)
508-
{
509-
const struct firmware *fw;
510-
struct firmware *dst;
511-
int ret = 0;
512-
513-
ret = request_firmware(&fw, name, device);
514-
if (ret)
515-
return ret;
516-
517-
if (is_vmalloc_addr(fw->data)) {
518-
*firmware_p = fw;
519-
return 0;
520-
}
521-
522-
dst = kzalloc(sizeof(*dst), GFP_KERNEL);
523-
if (!dst) {
524-
ret = -ENOMEM;
525-
goto release_firmware;
526-
}
527-
528-
dst->size = fw->size;
529-
dst->data = vmalloc(fw->size);
530-
if (!dst->data) {
531-
kfree(dst);
532-
ret = -ENOMEM;
533-
goto release_firmware;
534-
}
535-
536-
memcpy((void *)dst->data, fw->data, fw->size);
537-
*firmware_p = dst;
538-
539-
release_firmware:
540-
release_firmware(fw);
541-
542-
return ret;
543-
}
544-
545506
static int ipu6_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
546507
{
547508
struct ipu6_buttress_ctrl *isys_ctrl = NULL, *psys_ctrl = NULL;
@@ -627,7 +588,7 @@ static int ipu6_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
627588
if (ret)
628589
return ret;
629590

630-
ret = request_cpd_fw(&isp->cpd_fw, isp->cpd_fw_name, dev);
591+
ret = request_firmware(&isp->cpd_fw, isp->cpd_fw_name, dev);
631592
if (ret) {
632593
dev_err_probe(&isp->pdev->dev, ret,
633594
"Requesting signed firmware %s failed\n",

0 commit comments

Comments
 (0)