소스 검색

Merge tag 'drm-misc-fixes-2018-03-22' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

Main change is a patch to reject getfb call for multiplanar framebuffers,
then we have a couple of error path fixes on the sun4i driver. Still on that
driver there is a clk fix and finally a mmap offset fix on the udl driver.

* tag 'drm-misc-fixes-2018-03-22' of git://anongit.freedesktop.org/drm/drm-misc:
  drm: udl: Properly check framebuffer mmap offsets
  drm: Reject getfb for multi-plane framebuffers
  drm/sun4i: hdmi: Fix another error handling path in 'sun4i_hdmi_bind()'
  drm/sun4i: hdmi: Fix an error handling path in 'sun4i_hdmi_bind()'
  drm/sun4i: Fix an error handling path in 'sun4i_drv_bind()'
  drm/sun4i: Fix exclusivity of the TCON clocks
Dave Airlie 7 년 전
부모
커밋
b7b3f6696c

+ 7 - 0
drivers/gpu/drm/drm_framebuffer.c

@@ -461,6 +461,12 @@ int drm_mode_getfb(struct drm_device *dev,
 	if (!fb)
 	if (!fb)
 		return -ENOENT;
 		return -ENOENT;
 
 
+	/* Multi-planar framebuffers need getfb2. */
+	if (fb->format->num_planes > 1) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	r->height = fb->height;
 	r->height = fb->height;
 	r->width = fb->width;
 	r->width = fb->width;
 	r->depth = fb->format->depth;
 	r->depth = fb->format->depth;
@@ -484,6 +490,7 @@ int drm_mode_getfb(struct drm_device *dev,
 		ret = -ENODEV;
 		ret = -ENODEV;
 	}
 	}
 
 
+out:
 	drm_framebuffer_put(fb);
 	drm_framebuffer_put(fb);
 
 
 	return ret;
 	return ret;

+ 1 - 2
drivers/gpu/drm/sun4i/sun4i_drv.c

@@ -111,7 +111,7 @@ static int sun4i_drv_bind(struct device *dev)
 	/* drm_vblank_init calls kcalloc, which can fail */
 	/* drm_vblank_init calls kcalloc, which can fail */
 	ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
 	ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
 	if (ret)
 	if (ret)
-		goto free_mem_region;
+		goto cleanup_mode_config;
 
 
 	drm->irq_enabled = true;
 	drm->irq_enabled = true;
 
 
@@ -139,7 +139,6 @@ finish_poll:
 	sun4i_framebuffer_free(drm);
 	sun4i_framebuffer_free(drm);
 cleanup_mode_config:
 cleanup_mode_config:
 	drm_mode_config_cleanup(drm);
 	drm_mode_config_cleanup(drm);
-free_mem_region:
 	of_reserved_mem_device_release(dev);
 	of_reserved_mem_device_release(dev);
 free_drm:
 free_drm:
 	drm_dev_unref(drm);
 	drm_dev_unref(drm);

+ 4 - 2
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c

@@ -538,7 +538,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 					     &sun4i_hdmi_regmap_config);
 					     &sun4i_hdmi_regmap_config);
 	if (IS_ERR(hdmi->regmap)) {
 	if (IS_ERR(hdmi->regmap)) {
 		dev_err(dev, "Couldn't create HDMI encoder regmap\n");
 		dev_err(dev, "Couldn't create HDMI encoder regmap\n");
-		return PTR_ERR(hdmi->regmap);
+		ret = PTR_ERR(hdmi->regmap);
+		goto err_disable_mod_clk;
 	}
 	}
 
 
 	ret = sun4i_tmds_create(hdmi);
 	ret = sun4i_tmds_create(hdmi);
@@ -551,7 +552,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 		hdmi->ddc_parent_clk = devm_clk_get(dev, "ddc");
 		hdmi->ddc_parent_clk = devm_clk_get(dev, "ddc");
 		if (IS_ERR(hdmi->ddc_parent_clk)) {
 		if (IS_ERR(hdmi->ddc_parent_clk)) {
 			dev_err(dev, "Couldn't get the HDMI DDC clock\n");
 			dev_err(dev, "Couldn't get the HDMI DDC clock\n");
-			return PTR_ERR(hdmi->ddc_parent_clk);
+			ret = PTR_ERR(hdmi->ddc_parent_clk);
+			goto err_disable_mod_clk;
 		}
 		}
 	} else {
 	} else {
 		hdmi->ddc_parent_clk = hdmi->tmds_clk;
 		hdmi->ddc_parent_clk = hdmi->tmds_clk;

+ 3 - 2
drivers/gpu/drm/sun4i/sun4i_tcon.c

@@ -103,6 +103,7 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
 
 
 	if (enabled) {
 	if (enabled) {
 		clk_prepare_enable(clk);
 		clk_prepare_enable(clk);
+		clk_rate_exclusive_get(clk);
 	} else {
 	} else {
 		clk_rate_exclusive_put(clk);
 		clk_rate_exclusive_put(clk);
 		clk_disable_unprepare(clk);
 		clk_disable_unprepare(clk);
@@ -262,7 +263,7 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
 					const struct drm_display_mode *mode)
 					const struct drm_display_mode *mode)
 {
 {
 	/* Configure the dot clock */
 	/* Configure the dot clock */
-	clk_set_rate_exclusive(tcon->dclk, mode->crtc_clock * 1000);
+	clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
 
 
 	/* Set the resolution */
 	/* Set the resolution */
 	regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
 	regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
@@ -423,7 +424,7 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
 	WARN_ON(!tcon->quirks->has_channel_1);
 	WARN_ON(!tcon->quirks->has_channel_1);
 
 
 	/* Configure the dot clock */
 	/* Configure the dot clock */
-	clk_set_rate_exclusive(tcon->sclk1, mode->crtc_clock * 1000);
+	clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000);
 
 
 	/* Adjust clock delay */
 	/* Adjust clock delay */
 	clk_delay = sun4i_tcon_get_clk_delay(mode, 1);
 	clk_delay = sun4i_tcon_get_clk_delay(mode, 1);

+ 7 - 2
drivers/gpu/drm/udl/udl_fb.c

@@ -159,10 +159,15 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
 {
 	unsigned long start = vma->vm_start;
 	unsigned long start = vma->vm_start;
 	unsigned long size = vma->vm_end - vma->vm_start;
 	unsigned long size = vma->vm_end - vma->vm_start;
-	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long offset;
 	unsigned long page, pos;
 	unsigned long page, pos;
 
 
-	if (offset + size > info->fix.smem_len)
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+
+	offset = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (offset > info->fix.smem_len || size > info->fix.smem_len - offset)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	pos = (unsigned long)info->fix.smem_start + offset;
 	pos = (unsigned long)info->fix.smem_start + offset;