On Fri, Nov 09, 2012 at 11:04:58PM +0900, Inki Dae wrote:
> 2012/11/9 Ville Syrjälä <
ville.syrjala@linux.intel.com>
>
> > On Fri, Nov 09, 2012 at 09:41:19PM +0900, Inki Dae wrote:
> > > 2012/11/9 Ville Syrjälä <
ville.syrjala@linux.intel.com>
> > >
> > > > On Fri, Nov 09, 2012 at 04:39:30PM +0900, Inki Dae wrote:
> > > > > This patch fixes access issue to invalid memory region.
> > > > >
> > > > > crtc had only one drm_framebuffer object so when framebuffer
> > > > > cleanup was requested after page flip, it'd try to disable
> > > > > hardware overlay to current crtc.
> > > > > But if current crtc points to another drm_framebuffer,
> > > > > This may induce invalid memory access.
> > > > >
> > > > > Assume that some application are doing page flip with two
> > > > > drm_framebuffer objects. At this time, if second drm_framebuffer
> > > > > is set to current crtc and the cleanup to first drm_framebuffer
> > > > > is requested once drm release is requested, then first
> > > > > drm_framebuffer would be cleaned up without disabling
> > > > > hardware overlay because current crtc points to second
> > > > > drm_framebuffer. After that, gem buffer to first drm_framebuffer
> > > > > would be released and this makes dma access invalid memory region.
> > > > >
> > > > > This patch adds drm_framebuffer to drm_crtc structure as member
> > > >
> > > > That is exactly the reverse of what you're doing in the patch.
> > > > We already have crtc.fb, and you're adding fb.crtc.
> > > >
> > > > > and makes drm_framebuffer_cleanup function check if fb->crtc is
> > > > > same as desired fb. And also when setcrtc and pageflip are
> > > > > requested, it makes each drm_framebuffer point to current crtc.
> > > >
> > > > Looks like you're just setting the crtc.fb and fb.crtc pointers to
> > > > exactly mirror each other in the page flip ioctl. That can't fix
> > > > anything.
> > > >
> > > >
> > > At least, when drm is released, the crtc to framebuffer that was recently
> > > used for scanout can be disabled correctly.
> >
> > Let's take this scenario:
> >
> > setcrtc(crtc0, fb0)
> > -> crtc0.fb = fb0, fb0.crtc = crtc0
> > page_flip(crtc0, fb1)
> > -> crtc0.fb = fb1, fb1.crtc = crtc0
> > rmfb(fb0)
> > -> ?
> >
> > The rmfb() will now disable crtc0 because fb0.crtc == crtc0, but
> > let's consider this just a bug and ignore it for now. So let's assume
> > that crtc0 won't be disabled when we call rmfb(fb0).
> >
> >
> Ok, Please assume that my patch includes the below codes. when we call
> rmfb(fb0), fb0->crtc is NULL. so fb0 will be freed without disabling crtc.
>
> int drm_mode_rmfb(struct drm_device *dev, void *data, struct drm_file
> *file_priv) {
> ....
> fb->crtc = NULL;
> fb->funcs->destroy(fb);
> out:
> ...
> }