Unverified Commit e666d1a0 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!15790 fix CVE-2025-21976

Merge Pull Request from: @ci-robot 
 
PR sync from: Xiangwei Li <liwei728@huawei.com>
https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/BYB43ETKBKORC26M6T4VJRDPVUIXN3OT/ 
Saurabh Sengar (2):
  fbdev: hyperv_fb: Simplify hvfb_putmem
  fbdev: hyperv_fb: Allow graceful removal of framebuffer

Thomas Weißschuh (1):
  fbdev: Introduce devm_register_framebuffer()


-- 
2.25.1
 
https://gitee.com/src-openeuler/kernel/issues/IBY436 
 
Link:https://gitee.com/openeuler/kernel/pulls/15790

 

Reviewed-by: default avatarWang ShaoBo <bobo.shaobowang@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents ee9df505 931c91dd
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -1084,6 +1084,36 @@ unregister_framebuffer(struct fb_info *fb_info)
}
EXPORT_SYMBOL(unregister_framebuffer);

static void devm_unregister_framebuffer(void *data)
{
	struct fb_info *info = data;

	unregister_framebuffer(info);
}

/**
 *	devm_register_framebuffer - resource-managed frame buffer device registration
 *	@dev: device the framebuffer belongs to
 *	@fb_info: frame buffer info structure
 *
 *	Registers a frame buffer device @fb_info to device @dev.
 *
 *	Returns negative errno on error, or zero for success.
 *
 */
int
devm_register_framebuffer(struct device *dev, struct fb_info *fb_info)
{
	int ret;

	ret = register_framebuffer(fb_info);
	if (ret)
		return ret;

	return devm_add_action_or_reset(dev, devm_unregister_framebuffer, fb_info);
}
EXPORT_SYMBOL(devm_register_framebuffer);

/**
 *	fb_set_suspend - low level driver signals suspend
 *	@info: framebuffer affected
+20 −10
Original line number Diff line number Diff line
@@ -283,6 +283,8 @@ static uint screen_depth;
static uint screen_fb_size;
static uint dio_fb_size; /* FB size for deferred IO */

static void hvfb_putmem(struct fb_info *info);

/* Send message to Hyper-V host */
static inline int synthvid_send(struct hv_device *hdev,
				struct synthvid_msg *msg)
@@ -887,6 +889,17 @@ static void hvfb_cfb_imageblit(struct fb_info *p,
					       image->width, image->height);
}

/*
 * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
 * of unregister_framebuffer() or fb_release(). Do any cleanup related to
 * framebuffer here.
 */
static void hvfb_destroy(struct fb_info *info)
{
	hvfb_putmem(info);
	framebuffer_release(info);
}

static const struct fb_ops hvfb_ops = {
	.owner = THIS_MODULE,
	.fb_check_var = hvfb_check_var,
@@ -897,6 +910,7 @@ static const struct fb_ops hvfb_ops = {
	.fb_imageblit = hvfb_cfb_imageblit,
	.fb_blank = hvfb_blank,
	.fb_mmap = fb_deferred_io_mmap,
	.fb_destroy = hvfb_destroy,
};


@@ -973,7 +987,7 @@ static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
}

/* Release contiguous physical memory */
static void hvfb_release_phymem(struct hv_device *hdev,
static void hvfb_release_phymem(struct device *device,
				phys_addr_t paddr, unsigned int size)
{
	unsigned int order = get_order(size);
@@ -981,7 +995,7 @@ static void hvfb_release_phymem(struct hv_device *hdev,
	if (order <= MAX_ORDER)
		__free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order);
	else
		dma_free_coherent(&hdev->device,
		dma_free_coherent(device,
				  round_up(size, PAGE_SIZE),
				  phys_to_virt(paddr),
				  paddr);
@@ -1100,7 +1114,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
}

/* Release the framebuffer */
static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
static void hvfb_putmem(struct fb_info *info)
{
	struct hvfb_par *par = info->par;

@@ -1109,7 +1123,7 @@ static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
		iounmap(info->screen_base);
		vmbus_free_mmio(par->mem->start, screen_fb_size);
	} else {
		hvfb_release_phymem(hdev, info->fix.smem_start,
		hvfb_release_phymem(info->device, info->fix.smem_start,
				    screen_fb_size);
	}

@@ -1198,7 +1212,7 @@ static int hvfb_probe(struct hv_device *hdev,
	if (ret)
		goto error;

	ret = register_framebuffer(info);
	ret = devm_register_framebuffer(&hdev->device, info);
	if (ret) {
		pr_err("Unable to register framebuffer\n");
		goto error;
@@ -1223,7 +1237,7 @@ static int hvfb_probe(struct hv_device *hdev,

error:
	fb_deferred_io_cleanup(info);
	hvfb_putmem(hdev, info);
	hvfb_putmem(info);
error2:
	vmbus_close(hdev->channel);
error1:
@@ -1246,14 +1260,10 @@ static void hvfb_remove(struct hv_device *hdev)

	fb_deferred_io_cleanup(info);

	unregister_framebuffer(info);
	cancel_delayed_work_sync(&par->dwork);

	vmbus_close(hdev->channel);
	hv_set_drvdata(hdev, NULL);

	hvfb_putmem(hdev, info);
	framebuffer_release(info);
}

static int hvfb_suspend(struct hv_device *hdev)
+1 −0
Original line number Diff line number Diff line
@@ -598,6 +598,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
/* fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
extern void unregister_framebuffer(struct fb_info *fb_info);
extern int devm_register_framebuffer(struct device *dev, struct fb_info *fb_info);
extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
extern int fb_show_logo(struct fb_info *fb_info, int rotate);
extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);