Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/3] arm64: dump: Add checking for writable and exectuable pages
From: Kees Cook @ 2016-09-30 17:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930164147.GD1729@remoulade>

On Fri, Sep 30, 2016 at 9:41 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> On Fri, Sep 30, 2016 at 09:25:45AM -0700, Kees Cook wrote:
>> On Fri, Sep 30, 2016 at 8:58 AM, Mark Rutland <mark.rutland@arm.com> wrote:
>
>> > Would it be worth verifying that all kernel mappings are UXN, too?
>> >
>> > ARMv8 allows execute-only mappings, and a !UXN mapping could result in an info
>> > leak (e.g. pointers in MOVZ+MOVK sequences), or potential asynchronous issues
>> > (e.g. user instruction fetches accessing read-destructive device registers).
>> > All kernel mappings *should* be UXN.
>>
>> I love this idea, but based on what came up with hardened usercopy,
>> there are a lot of readers of kernel memory still. I think the
>> expectations around UXN need to be clarified so we can reason about
>> things like perf that want to read the kernel text.
>
> The UXN (User eXecute Never) bit only controls whether userspace can execute a
> page, not whether the kernel can read it. The RW permissions come from the AP
> bits regardless.

Ah! Sorry, I misunderstood. Yeah, UXN checking makes sense there then. :)

> We already try to ensure that all kernel memory is UXN by construction, so this
> would just be a sanity check, as with the rest of the W^X checks.
>
> The MOVZ+MOVK case above is where a sequence of 16-bit immediate MOVs are used
> to encode a pointer. If a kernel mapping lacked UXN, userspace could execute it
> (unprivileged), and extract the pointer generated into a GPR.
>
> Having kernel exec-only memory is a different story entirely, though I agree
> it's something to look into.

Yeah, this'll need to get sorted out for x86 too.

-Kees

-- 
Kees Cook
Nexus Security

^ permalink raw reply

* [PATCH v2] clk: bcm2835: Clamp the PLL's requested rate to the hardware limits.
From: Eric Anholt @ 2016-09-30 17:07 UTC (permalink / raw)
  To: linux-arm-kernel

Fixes setting low-resolution video modes on HDMI.  Now the PLLH_PIX
divider adjusts itself until the PLLH is within bounds.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/clk/bcm/clk-bcm2835.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 7a7970865c2d..69a1849d140c 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -499,8 +499,12 @@ static long bcm2835_pll_rate_from_divisors(unsigned long parent_rate,
 static long bcm2835_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 				   unsigned long *parent_rate)
 {
+	struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+	const struct bcm2835_pll_data *data = pll->data;
 	u32 ndiv, fdiv;
 
+	rate = clamp(rate, data->min_rate, data->max_rate);
+
 	bcm2835_pll_choose_ndiv_and_fdiv(rate, *parent_rate, &ndiv, &fdiv);
 
 	return bcm2835_pll_rate_from_divisors(*parent_rate, ndiv, fdiv, 1);
@@ -605,13 +609,6 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
 	u32 ana[4];
 	int i;
 
-	if (rate < data->min_rate || rate > data->max_rate) {
-		dev_err(cprman->dev, "%s: rate out of spec: %lu vs (%lu, %lu)\n",
-			clk_hw_get_name(hw), rate,
-			data->min_rate, data->max_rate);
-		return -EINVAL;
-	}
-
 	if (rate > data->max_fb_rate) {
 		use_fb_prediv = true;
 		rate /= 2;
-- 
2.9.3

^ permalink raw reply related

* [PATCH] Adding Support for Coresight Components on Zynq 7000.
From: Sören Brinkmann @ 2016-09-30 16:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <920cac6c-e56a-60d5-4882-22892058346d@supelec.fr>

Hi Muhammad,

On Fri, 2016-09-30 at 09:39:51 +0200, Muhammad Abdul WAHAB wrote:
> Hi S?ren,
> 
> Thank you for your remarks. I corrected a few things as you suggested.
> 
[...]
> >> +        tpiu at F8803000 {
> >>>
> >>> +            compatible = "arm,coresight-tpiu", "arm,primecell";
> >>> +            reg = <0xf8803000 0x1000>;
> >>> +            clocks = <&clkc 47>, <&clkc 16>;
> >>
> >
> > I'm not sure this is correct for every setup. Sorry, that I don't recall
> > all the details, I haven't used tracing in a long time. But I guess this
> > clock is configurable as you're referring an fclk here. The other thing
> > that makes me a little suspicious is, that nothing in here uses the
> > 'dbg_trc' clock that the clock controller provides.
> 
> The TPIU setup included in my patch is specific to my configuration of TPIU.
> The second clock is configurable but I didn't know how to do so. As in
> Vivado setup I chose "fclk1" as the clock for TPIU, I decided to put fclk1.
> But, I am not sure about this. I am having some problems when I recover the
> trace from TPIU: it is not the same as in ETB even though it resembles a
> lot.
> I don't know if the problem is coming from the device tree or from the
> driver.
> I will have a look at 'dbg_trc' clock.

I tried to refresh my Zynq knowledge a bit. The clkc provides the
dbg_trc clock, and that is the clock you need (not fclk). I couldn't
find it in the binding (I guess I messed that up), but apparently,
you can provide a 'trace_emio_clk' as input to the clkc node in the
Zynq DT. Then, with the muxes correctly configured (FSBL should do
that if you select the EMIO trace clock in Vivado), the dbg_trc
output of the clkc should be that EMIO clock. And the dbg_trc output
of the clkc is what should be consumed by the tpiu node. Though, as
I see it the binding/driver for the TPIU do not support that.

I.e.
In the clkc description you'd have to add 'trace_emio_clk' to the
clock-names property together with a matching reference in the 'clocks'
property. As this change would be specific to local setups, this is not
really appropriate for upstream.

Then, for the trace clock, ideally the TPIU would consume and enable it
as needed.

> 
> >>
> >> +            clock-names = "apb_pclk", "fclk1";
> >>
> > Those names (at least fclk1) is not a good name for tpiu to identify
> > it's input. fclk1 is a zynq-specific clock, and as mentioned above, it
> > seems likely that this could easily become a different one. The
> > clock-names are meant to identify an input from the consumer's
> > perspective. The correct names should be documented in the DT binding.
> 
> The first name was chosen as "apb_pclk" because it was recommended in
> Documentation. On the second name, I agree with you but again for TPIU DT
> entry, I am not sure how to make this clock configurable. So, that's why
> I put the same clock name as I had in my Vivado setup. If you have any
> leads on how to make it configurable, I will be happy to take a look
> into it.

Unfortunately, this is not how it works. The DT bindings are not a
recommendation. The DT description must follow the binding, otherwise
drivers will not work correctly, or best case, just ignore what you put
there.

> 
> >> +            clock-frequency=<0xee6b280>;
> >>
> > I cannot find this property in the binding.
> >
> 
> This property was described in clock binding (in an example [2]) and the
> value here (250MHz) corresponds to the value I had chosen in Vivado for
> TPIU input clock.

As I don't see this in the coresight binding, I doubt that it has any
effect or should be here.

	S?ren

^ permalink raw reply

* [PATCH] mtd: mtk: avoid warning in mtk_ecc_encode
From: Boris Brezillon @ 2016-09-30 16:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930163429.380785-1-arnd@arndb.de>

Hi Arnd,

On Fri, 30 Sep 2016 18:33:02 +0200
Arnd Bergmann <arnd@arndb.de> wrote:

> When building with -Wmaybe-uninitialized, gcc produces a silly false positive
> warning for the mtk_ecc_encode function:
> 
> drivers/mtd/nand/mtk_ecc.c: In function 'mtk_ecc_encode':
> drivers/mtd/nand/mtk_ecc.c:402:15: error: 'val' may be used uninitialized in this function [-Werror=maybe-uninitialized]
> 
> The function for some reason contains a double byte swap on big-endian
> builds to get the OOB data into the correct order again, and is written
> in a slightly confusing way.
> 
> Using a simple memcpy32_fromio() to read the data simplifies it a lot
> so it becomes more readable and produces no warning. However, the
> output might not have 32-bit alignment, so we have to use another
> memcpy to avoid taking alignment faults or writing beyond the end
> of the array.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  drivers/mtd/nand/mtk_ecc.c | 18 ++++++++----------
>  1 file changed, 8 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c
> index d54f666417e1..237c83124a7d 100644
> --- a/drivers/mtd/nand/mtk_ecc.c
> +++ b/drivers/mtd/nand/mtk_ecc.c
> @@ -366,9 +366,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
>  		   u8 *data, u32 bytes)
>  {
>  	dma_addr_t addr;
> -	u8 *p;
> -	u32 len, i, val;
> -	int ret = 0;
> +	u32 len;
> +	u8 eccdata[112];
> +	int ret;
>  
>  	addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
>  	ret = dma_mapping_error(ecc->dev, addr);
> @@ -393,14 +393,12 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
>  
>  	/* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
>  	len = (config->strength * ECC_PARITY_BITS + 7) >> 3;
> -	p = data + bytes;
>  
> -	/* write the parity bytes generated by the ECC back to the OOB region */
> -	for (i = 0; i < len; i++) {
> -		if ((i % 4) == 0)
> -			val = readl(ecc->regs + ECC_ENCPAR(i / 4));
> -		p[i] = (val >> ((i % 4) * 8)) & 0xff;
> -	}
> +	/* write the parity bytes generated by the ECC back to temp buffer */
> +	__ioread32_copy(eccdata, ecc->regs + ECC_ENCPAR(0), round_up(len, 4));
> +
> +	/* copy into possibly unaligned OOB region with actual length */
> +	memcpy(data + bytes, eccdata, len);

Is it better than

	for (i = 0; i < len; i += 4) {
		u32 val = __raw_readl(ecc->regs + ECC_ENCPAR(i / 4));

		memcpy(data + bytes + i, &val, min(len, 4));
	}

I'm probably missing something, but what's the point of creating a
temporary buffer of 112 bytes on the stack since you'll have to copy
this data to the oob buffer at some point?

>  timeout:
>  
>  	dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);

^ permalink raw reply

* [PATCH 3/3] arm64: dump: Add checking for writable and exectuable pages
From: Mark Rutland @ 2016-09-30 16:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGXu5jJHohnRBxQAY-S7_iccgjc6xNUdBGb67b1-cOATyO-q0A@mail.gmail.com>

On Fri, Sep 30, 2016 at 09:25:45AM -0700, Kees Cook wrote:
> On Fri, Sep 30, 2016 at 8:58 AM, Mark Rutland <mark.rutland@arm.com> wrote:

> > Would it be worth verifying that all kernel mappings are UXN, too?
> >
> > ARMv8 allows execute-only mappings, and a !UXN mapping could result in an info
> > leak (e.g. pointers in MOVZ+MOVK sequences), or potential asynchronous issues
> > (e.g. user instruction fetches accessing read-destructive device registers).
> > All kernel mappings *should* be UXN.
> 
> I love this idea, but based on what came up with hardened usercopy,
> there are a lot of readers of kernel memory still. I think the
> expectations around UXN need to be clarified so we can reason about
> things like perf that want to read the kernel text.

The UXN (User eXecute Never) bit only controls whether userspace can execute a
page, not whether the kernel can read it. The RW permissions come from the AP
bits regardless.

We already try to ensure that all kernel memory is UXN by construction, so this
would just be a sanity check, as with the rest of the W^X checks.

The MOVZ+MOVK case above is where a sequence of 16-bit immediate MOVs are used
to encode a pointer. If a kernel mapping lacked UXN, userspace could execute it
(unprivileged), and extract the pointer generated into a GPR.

Having kernel exec-only memory is a different story entirely, though I agree
it's something to look into.

Thanks,
Mark

^ permalink raw reply

* [PATCH] drm/sun4i: Check that the plane coordinates are not negative
From: Boris Brezillon @ 2016-09-30 16:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930162211.GQ4329@intel.com>

On Fri, 30 Sep 2016 19:22:11 +0300
Ville Syrj?l? <ville.syrjala@linux.intel.com> wrote:

> On Fri, Sep 30, 2016 at 06:08:26PM +0200, Boris Brezillon wrote:
> > On Fri, 30 Sep 2016 16:33:20 +0200
> > Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
> >   
> > > Our planes cannot be set at negative coordinates. Make sure we reject such
> > > configuration.
> > > 
> > > Reported-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > > ---
> > >  drivers/gpu/drm/sun4i/sun4i_layer.c | 3 +++
> > >  1 file changed, 3 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
> > > index f0035bf5efea..f5463c4c2cde 100644
> > > --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
> > > +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
> > > @@ -29,6 +29,9 @@ struct sun4i_plane_desc {
> > >  static int sun4i_backend_layer_atomic_check(struct drm_plane *plane,
> > >  					    struct drm_plane_state *state)
> > >  {
> > > +	if ((state->crtc_x < 0) || (state->crtc_y < 0))
> > > +		return -EINVAL;
> > > +  
> > 
> > Hm, I think it's a perfectly valid use case from the DRM framework and
> > DRM user PoV: you may want to place your plane at a negative CRTC
> > offset (which means part of the plane will be hidden).
> > 
> > Maybe I'm wrong, but it seems you can support that by adapting the
> > start address of your framebuffer pointer and the layer size.
> > 
> > Have you tried doing something like that?  
> 
> You shouldn't even be looking at the user provided coordinates. Also
> you can't return an error from the atomic update hook. The void return
> value should have been a decent hint ;)

Note that Maxime is not returning a value from the atomic update
implementation (it's done in the atomic_check implem), and I'm not
checking crtc_x,y consistency at all (which is obviously wrong), I'm
just blindly patching the values in sun4i_backend helpers.

> The right fix would be
> to move all the error handling into the atomic check hook, which
> probably should just call the helper to clip the coordinates and
> whatnot. Then the update hook can just use at the clipped 
> coordinates when programming the hw registers.

That's probably the best approach indeed, but that means having our
private sun4i_plane_state struct where we would store the patched
crtc_{w,h,x,y} info.

Anyway, before we do that, that's probably better to check if it really
works on this HW (which is why I sent this informal patch).

> 
> >   
> > --->8---  
> > diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
> > index 3ab560450a82..6b68804f3035 100644
> > --- a/drivers/gpu/drm/sun4i/sun4i_backend.c
> > +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
> > @@ -110,15 +110,30 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
> >  {
> >         struct drm_plane_state *state = plane->state;
> >         struct drm_framebuffer *fb = state->fb;
> > +       int crtc_w, crtc_h, crtc_x, crtc_y;
> >  
> >         DRM_DEBUG_DRIVER("Updating layer %d\n", layer);
> >  
> > +       crtc_x = state->crtc_x;
> > +       crtc_y = state->crtc_y;
> > +       crtc_w = state->crtc_w;
> > +       crtc_h = state->crtc_h;
> > +
> > +       if (crtc_x < 0) {
> > +               crtc_w += crtx_x;
> > +               crtc_x = 0;
> > +       }
> > +
> > +       if (crtc_y < 0) {
> > +               crtc_h += crtx_y;
> > +               crtc_y = 0;
> > +       }
> > +
> >         if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
> >                 DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n",
> >                                  state->crtc_w, state->crtc_h);
> >                 regmap_write(backend->regs, SUN4I_BACKEND_DISSIZE_REG,
> > -                            SUN4I_BACKEND_DISSIZE(state->crtc_w,
> > -                                                  state->crtc_h));
> > +                            SUN4I_BACKEND_DISSIZE(crtc_w, crtc_h));
> >         }
> >  
> >         /* Set the line width */
> > @@ -130,15 +145,13 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
> >         DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n",
> >                          state->crtc_w, state->crtc_h);
> >         regmap_write(backend->regs, SUN4I_BACKEND_LAYSIZE_REG(layer),
> > -                    SUN4I_BACKEND_LAYSIZE(state->crtc_w,
> > -                                          state->crtc_h));
> > +                    SUN4I_BACKEND_LAYSIZE(crtc_w, crtc_h));
> >  
> >         /* Set base coordinates */
> >         DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n",
> >                          state->crtc_x, state->crtc_y);
> >         regmap_write(backend->regs, SUN4I_BACKEND_LAYCOOR_REG(layer),
> > -                    SUN4I_BACKEND_LAYCOOR(state->crtc_x,
> > -                                          state->crtc_y));
> > +                    SUN4I_BACKEND_LAYCOOR(crtc_x, crtc_y));
> >  
> >         return 0;
> >  }
> > @@ -198,6 +211,12 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
> >         paddr += (state->src_x >> 16) * bpp;
> >         paddr += (state->src_y >> 16) * fb->pitches[0];
> >  
> > +       if (state->crtc_x < 0)
> > +               paddr -= bpp * state->crtc_x;
> > +
> > +       if (state->crtc_y < 0)
> > +               paddr -= fb->pitches[0] * state->crtc_y;
> > +
> >         DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
> >  
> >         /* Write the 32 lower bits of the address (in bits) */
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel  
> 

^ permalink raw reply

* [PATCH] mtd: mtk: avoid warning in mtk_ecc_encode
From: Arnd Bergmann @ 2016-09-30 16:33 UTC (permalink / raw)
  To: linux-arm-kernel

When building with -Wmaybe-uninitialized, gcc produces a silly false positive
warning for the mtk_ecc_encode function:

drivers/mtd/nand/mtk_ecc.c: In function 'mtk_ecc_encode':
drivers/mtd/nand/mtk_ecc.c:402:15: error: 'val' may be used uninitialized in this function [-Werror=maybe-uninitialized]

The function for some reason contains a double byte swap on big-endian
builds to get the OOB data into the correct order again, and is written
in a slightly confusing way.

Using a simple memcpy32_fromio() to read the data simplifies it a lot
so it becomes more readable and produces no warning. However, the
output might not have 32-bit alignment, so we have to use another
memcpy to avoid taking alignment faults or writing beyond the end
of the array.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/mtd/nand/mtk_ecc.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c
index d54f666417e1..237c83124a7d 100644
--- a/drivers/mtd/nand/mtk_ecc.c
+++ b/drivers/mtd/nand/mtk_ecc.c
@@ -366,9 +366,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
 		   u8 *data, u32 bytes)
 {
 	dma_addr_t addr;
-	u8 *p;
-	u32 len, i, val;
-	int ret = 0;
+	u32 len;
+	u8 eccdata[112];
+	int ret;
 
 	addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
 	ret = dma_mapping_error(ecc->dev, addr);
@@ -393,14 +393,12 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
 
 	/* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
 	len = (config->strength * ECC_PARITY_BITS + 7) >> 3;
-	p = data + bytes;
 
-	/* write the parity bytes generated by the ECC back to the OOB region */
-	for (i = 0; i < len; i++) {
-		if ((i % 4) == 0)
-			val = readl(ecc->regs + ECC_ENCPAR(i / 4));
-		p[i] = (val >> ((i % 4) * 8)) & 0xff;
-	}
+	/* write the parity bytes generated by the ECC back to temp buffer */
+	__ioread32_copy(eccdata, ecc->regs + ECC_ENCPAR(0), round_up(len, 4));
+
+	/* copy into possibly unaligned OOB region with actual length */
+	memcpy(data + bytes, eccdata, len);
 timeout:
 
 	dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
-- 
2.9.0

^ permalink raw reply related

* [PATCH 3/3] arm64: dump: Add checking for writable and exectuable pages
From: Kees Cook @ 2016-09-30 16:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930155814.GA1729@remoulade>

On Fri, Sep 30, 2016 at 8:58 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> On Thu, Sep 29, 2016 at 02:32:57PM -0700, Laura Abbott wrote:
>> @@ -219,6 +223,15 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
>>               unsigned long delta;
>>
>>               if (st->current_prot) {
>> +                     if (st->check_wx &&
>> +                     ((st->current_prot & PTE_RDONLY) != PTE_RDONLY) &&
>> +                     ((st->current_prot & PTE_PXN) != PTE_PXN)) {
>> +                             WARN_ONCE(1, "arm64/mm: Found insecure W+X mapping at address %p/%pS\n",
>> +                                      (void *)st->start_address,
>> +                                      (void *)st->start_address);
>> +                             st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
>> +                     }
>> +
>
> Would it be worth verifying that all kernel mappings are UXN, too?
>
> ARMv8 allows execute-only mappings, and a !UXN mapping could result in an info
> leak (e.g. pointers in MOVZ+MOVK sequences), or potential asynchronous issues
> (e.g. user instruction fetches accessing read-destructive device registers).
> All kernel mappings *should* be UXN.

I love this idea, but based on what came up with hardened usercopy,
there are a lot of readers of kernel memory still. I think the
expectations around UXN need to be clarified so we can reason about
things like perf that want to read the kernel text.

-Kees

-- 
Kees Cook
Nexus Security

^ permalink raw reply

* [PATCH] drm/sun4i: Check that the plane coordinates are not negative
From: Ville Syrjälä @ 2016-09-30 16:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930180826.169e3daf@bbrezillon>

On Fri, Sep 30, 2016 at 06:08:26PM +0200, Boris Brezillon wrote:
> On Fri, 30 Sep 2016 16:33:20 +0200
> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
> 
> > Our planes cannot be set at negative coordinates. Make sure we reject such
> > configuration.
> > 
> > Reported-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> >  drivers/gpu/drm/sun4i/sun4i_layer.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
> > index f0035bf5efea..f5463c4c2cde 100644
> > --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
> > +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
> > @@ -29,6 +29,9 @@ struct sun4i_plane_desc {
> >  static int sun4i_backend_layer_atomic_check(struct drm_plane *plane,
> >  					    struct drm_plane_state *state)
> >  {
> > +	if ((state->crtc_x < 0) || (state->crtc_y < 0))
> > +		return -EINVAL;
> > +
> 
> Hm, I think it's a perfectly valid use case from the DRM framework and
> DRM user PoV: you may want to place your plane at a negative CRTC
> offset (which means part of the plane will be hidden).
> 
> Maybe I'm wrong, but it seems you can support that by adapting the
> start address of your framebuffer pointer and the layer size.
> 
> Have you tried doing something like that?

You shouldn't even be looking at the user provided coordinates. Also
you can't return an error from the atomic update hook. The void return
value should have been a decent hint ;) The right fix would be
to move all the error handling into the atomic check hook, which
probably should just call the helper to clip the coordinates and
whatnot. Then the update hook can just use at the clipped 
coordinates when programming the hw registers.

> 
> --->8---
> diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
> index 3ab560450a82..6b68804f3035 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_backend.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
> @@ -110,15 +110,30 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
>  {
>         struct drm_plane_state *state = plane->state;
>         struct drm_framebuffer *fb = state->fb;
> +       int crtc_w, crtc_h, crtc_x, crtc_y;
>  
>         DRM_DEBUG_DRIVER("Updating layer %d\n", layer);
>  
> +       crtc_x = state->crtc_x;
> +       crtc_y = state->crtc_y;
> +       crtc_w = state->crtc_w;
> +       crtc_h = state->crtc_h;
> +
> +       if (crtc_x < 0) {
> +               crtc_w += crtx_x;
> +               crtc_x = 0;
> +       }
> +
> +       if (crtc_y < 0) {
> +               crtc_h += crtx_y;
> +               crtc_y = 0;
> +       }
> +
>         if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
>                 DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n",
>                                  state->crtc_w, state->crtc_h);
>                 regmap_write(backend->regs, SUN4I_BACKEND_DISSIZE_REG,
> -                            SUN4I_BACKEND_DISSIZE(state->crtc_w,
> -                                                  state->crtc_h));
> +                            SUN4I_BACKEND_DISSIZE(crtc_w, crtc_h));
>         }
>  
>         /* Set the line width */
> @@ -130,15 +145,13 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
>         DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n",
>                          state->crtc_w, state->crtc_h);
>         regmap_write(backend->regs, SUN4I_BACKEND_LAYSIZE_REG(layer),
> -                    SUN4I_BACKEND_LAYSIZE(state->crtc_w,
> -                                          state->crtc_h));
> +                    SUN4I_BACKEND_LAYSIZE(crtc_w, crtc_h));
>  
>         /* Set base coordinates */
>         DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n",
>                          state->crtc_x, state->crtc_y);
>         regmap_write(backend->regs, SUN4I_BACKEND_LAYCOOR_REG(layer),
> -                    SUN4I_BACKEND_LAYCOOR(state->crtc_x,
> -                                          state->crtc_y));
> +                    SUN4I_BACKEND_LAYCOOR(crtc_x, crtc_y));
>  
>         return 0;
>  }
> @@ -198,6 +211,12 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
>         paddr += (state->src_x >> 16) * bpp;
>         paddr += (state->src_y >> 16) * fb->pitches[0];
>  
> +       if (state->crtc_x < 0)
> +               paddr -= bpp * state->crtc_x;
> +
> +       if (state->crtc_y < 0)
> +               paddr -= fb->pitches[0] * state->crtc_y;
> +
>         DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
>  
>         /* Write the 32 lower bits of the address (in bits) */
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrj?l?
Intel OTC

^ permalink raw reply

* [GIT PULL] arm64: updates for 4.9
From: Will Deacon @ 2016-09-30 16:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

Please pull the following arm64 updates for 4.9. I'm sending this before
the merge window actually opens, since I'm off fishing next week and
won't have internet access. Catalin will be in the office in case anything
goes wrong.

As for the changes themselves, there is a summary in the tag but it's
a bit all over the place this time with no "killer feature" to speak of.
Support for mismatched cache line sizes should help people seeing whacky
JIT failures on some SoCs, and the big.LITTLE perf updates have been a
long time coming, but a lot of the changes here are cleanups.

We stray outside arch/arm64 in a few areas: the arch/arm/ arch_timer
workaround is acked by Russell, the DT/OF bits are acked by Rob, the
arch_timer clocksource changes acked by Marc, CPU hotplug by tglx and
jump_label by Peter (all CC'd).

There are a couple of minor conflicts with mainline, due to fixes that
were merged after -rc3. I've included the resolution below, but it's
pretty straighforward.

Cheers,

Will

P.S. I've renewed my gpg key, so you may need to refetch it to see the
updated expiry date.

--->8

diff --cc arch/arm64/kernel/head.S
index 3e7b050e99dc,427f6d3f084c..000000000000
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
diff --cc drivers/perf/arm_pmu.c
index f5e1008a223d,77ac1ccb39ed..000000000000
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@@ -970,8 -990,7 +991,8 @@@ static int of_pmu_irq_cfg(struct arm_pm
  	if (cpumask_weight(&pmu->supported_cpus) == 0) {
  		int irq = platform_get_irq(pdev, 0);
  
- 		if (irq >= 0 && irq_is_percpu(irq)) {
+ 		if (irq > 0 && irq_is_percpu(irq)) {
 +			/* If using PPIs, check the affinity of the partition */
  			int ret;
  
  			ret = irq_get_percpu_devid_partition(irq, &pmu->supported_cpus);

--->8

The following changes since commit fa8410b355251fd30341662a40ac6b22d3e38468:

  Linux 4.8-rc3 (2016-08-21 16:14:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-upstream

for you to fetch changes up to db68f3e7594aca77632d56c449bd36c6c931d59a:

  arm64: tlbflush.h: add __tlbi() macro (2016-09-28 10:44:05 +0100)

----------------------------------------------------------------
arm64 updates for 4.9:

- Support for execute-only page permissions
- Support for hibernate and DEBUG_PAGEALLOC
- Support for heterogeneous systems with mismatches cache line sizes
- Errata workarounds (A53 843419 update and QorIQ A-008585 timer bug)
- arm64 PMU perf updates, including cpumasks for heterogeneous systems
- Set UTS_MACHINE for building rpm packages
- Yet another head.S tidy-up
- Some cleanups and refactoring, particularly in the NUMA code
- Lots of random, non-critical fixes across the board

----------------------------------------------------------------
AKASHI Takahiro (1):
      arm64: mark reserved memblock regions explicitly in iomem

Ard Biesheuvel (12):
      arm64: head.S: get rid of x25 and x26 with 'global' scope
      arm64: cpufeature: constify arm64_ftr_bits structures
      arm64: cpufeature: constify arm64_ftr_regs array
      arm64: cpufeature: expose arm64_ftr_reg struct for CTR_EL0
      arm64: kernel: fix style issues in sleep.S
      arm64: kernel: use ordinary return/argument register for el2_setup()
      arm64: head.S: move KASLR processing out of __enable_mmu()
      arm64: kernel: use x30 for __enable_mmu return address
      arm64: kernel: drop use of x24 from primary boot path
      arm64: head.S: use ordinary stack frame for __primary_switched()
      arm64: head.S: document the use of callee saved registers
      arm64: kernel: re-export _cpu_resume() from sleep.S

Catalin Marinas (3):
      arm64: Introduce execute-only page access permissions
      jump_labels: Allow array initialisers
      arm64: Use static keys for CPU features

Chris Metcalf (1):
      arm64: factor work_pending state machine to C

David A. Long (1):
      arm64: Improve kprobes test for atomic sequence

James Morse (7):
      arm64: Create sections.h
      arm64: vmlinux.ld: Add mmuoff data sections and move mmuoff text into idmap
      arm64: hibernate: Support DEBUG_PAGEALLOC
      cpu/hotplug: Allow suspend/resume CPU to be specified
      arm64: hibernate: Resume when hibernate image created on non-boot CPU
      Revert "arm64: hibernate: Refuse to hibernate if the boot cpu is offline"
      arm64: Drop generic xlate_dev_mem_{k,}ptr()

Jeremy Linton (2):
      arm64: pmu: Probe default hw/cache counters
      arm64: pmu: Hoist pmu platform device name

Jisheng Zhang (3):
      arm64: vdso: add __init section marker to alloc_vectors_page
      arm64: vdso: constify vm_special_mapping used for aarch32 vectors page
      arm64: apply __ro_after_init to some objects

Kefeng Wang (8):
      arm64: perf: Use the builtin_platform_driver
      arm64: cleanup unused UDBG_* define
      arm64: mm: drop fixup_init() and mm.h
      of_numa: Use of_get_next_parent to simplify code
      of_numa: Use pr_fmt()
      arm64: numa: Use pr_fmt()
      arm64: Kconfig: select OF/ACPI_NUMA under NUMA config
      arm64: Kconfig: remove SMP dependence for NUMA

Kim Phillips (1):
      arm64: don't select PERF_USE_VMALLOC by default

Kwangwoo Lee (1):
      arm64: mm: convert __dma_* routines to use start, size

Laura Abbott (1):
      arm64: Correctly bounds check virt_addr_valid

Marc Zyngier (1):
      drivers/perf: arm_pmu: Always consider IRQ0 as an error

Mark Rutland (19):
      arm64: hibernate: reduce TLB maintenance scope
      arm64: remove traces of perf_ops_bp
      arm64: always enable DEBUG_RODATA and remove the Kconfig option
      arm64: sysreg: allow write_sysreg to use XZR
      arm64: arch_timer: simplify accessors
      arm64: dcc: simplify accessors
      arm64/kvm: use {read,write}_sysreg()
      arm64: simplify sysreg manipulation
      arm64: simplify contextidr_thread_switch
      drivers/perf: arm_pmu: add common attr group fields
      arm64: perf: move to common attr_group fields
      arm: perf: move to common attr_group fields
      drivers/perf: arm_pmu: only use common attr_groups
      drivers/perf: arm_pmu: expose a cpumask in sysfs
      arm64: alternative: add auto-nop infrastructure
      arm64: use alternative auto-nop
      arm64/kvm: use alternative auto-nop
      arm64: fix dump_backtrace/unwind_frame with NULL tsk
      arm64: tlbflush.h: add __tlbi() macro

Mark Salter (1):
      arm64: pmu: add fallback probe table

Masahiro Yamada (1):
      arm64: remove redundant "select HAVE_CLK"

Michal Marek (1):
      arm64: Set UTS_MACHINE in the Makefile

Paul Gortmaker (1):
      arm64: migrate exception table users off module.h and onto extable.h

Pratyush Anand (2):
      arm64: kprobe: Always clear pstate.D in breakpoint exception handler
      arm64: ftrace: add save_stack_trace_regs()

Robin Murphy (2):
      arm64/io: Allow I/O writes to use {W,X}ZR
      arm64: Remove shadowed asm-generic headers

Scott Wood (3):
      arm64: arch_timer: Add device tree binding for A-008585 erratum
      arm64: arch_timer: Work around QorIQ Erratum A-008585
      arm/arm64: arch_timer: Use archdata to indicate vdso suitability

Suzuki K Poulose (9):
      arm64: Set the safe value for L1 icache policy
      arm64: Use consistent naming for errata handling
      arm64: Rearrange CPU errata workaround checks
      arm64: alternative: Disallow patching instructions using literals
      arm64: insn: Add helpers for adrp offsets
      arm64: alternative: Add support for patching adrp instructions
      arm64: Introduce raw_{d,i}cache_line_size
      arm64: Refactor sysinstr exception handling
      arm64: Work around systems with mismatched cache line sizes

Vladimir Murzin (1):
      arm64: kernel: do not need to reset UAO on exception entry

Will Deacon (9):
      arm64: errata: Pass --fix-cortex-a53-843419 to ld if workaround enabled
      arm64: debug: avoid resetting stepping state machine when TIF_SINGLESTEP
      arm64: hw_breakpoint: convert CPU hotplug notifier to new infrastructure
      arm64: debug: convert OS lock CPU hotplug notifier to new infrastructure
      arm64: debug: report TRAP_TRACE instead of TRAP_HWBRPT for singlestep
      arm64: sysreg: replace open-coded mrs_s/msr_s with {read,write}_sysreg_s
      arm64: barriers: introduce nops and __nops macros for NOP sequences
      arm64: lse: convert lse alternatives NOP padding to use __nops
      MAINTAINERS: Update ARM PMU PROFILING AND DEBUGGING entry

Zhen Lei (8):
      of/numa: remove a duplicated pr_debug information
      of/numa: fix a memory@ node can only contains one memory block
      of/numa: add nid check for memory block
      of/numa: remove a duplicated warning
      arm64/numa: avoid inconsistent information to be printed
      arm64/numa: support HAVE_SETUP_PER_CPU_AREA
      arm64/numa: remove some useless code
      arm64/numa: remove the limitation that cpu0 must bind to node0

zijun_hu (1):
      arm64: remove duplicate macro __KERNEL__ check

 Documentation/arm64/silicon-errata.txt             |   2 +
 .../devicetree/bindings/arm/arch_timer.txt         |   6 +
 Documentation/kernel-parameters.txt                |   9 +
 Documentation/static-keys.txt                      |   9 +
 MAINTAINERS                                        |   6 +-
 arch/arm/Kconfig                                   |   1 +
 arch/arm/include/asm/clocksource.h                 |   8 +
 arch/arm/kernel/perf_event_v7.c                    |  47 +++--
 arch/arm/kernel/vdso.c                             |   2 +-
 arch/arm64/Kconfig                                 |  33 ++--
 arch/arm64/Kconfig.debug                           |  10 --
 arch/arm64/Kconfig.platforms                       |   1 -
 arch/arm64/Makefile                                |  10 ++
 arch/arm64/include/asm/Kbuild                      |   5 -
 arch/arm64/include/asm/acpi.h                      |   8 +-
 arch/arm64/include/asm/alternative.h               |  70 ++++++--
 arch/arm64/include/asm/arch_timer.h                |  82 ++++++---
 arch/arm64/include/asm/assembler.h                 |  53 +++++-
 arch/arm64/include/asm/atomic_lse.h                |  64 +++----
 arch/arm64/include/asm/barrier.h                   |   3 +
 arch/arm64/include/asm/cacheflush.h                |   3 +-
 arch/arm64/include/asm/clocksource.h               |   8 +
 arch/arm64/include/asm/cmpxchg.h                   |   4 +-
 arch/arm64/include/asm/cpufeature.h                |  42 +++--
 arch/arm64/include/asm/cputype.h                   |   6 +-
 arch/arm64/include/asm/dcc.h                       |  14 +-
 arch/arm64/include/asm/esr.h                       |  84 ++++++++-
 arch/arm64/include/asm/hw_breakpoint.h             |  15 +-
 arch/arm64/include/asm/insn.h                      |  11 +-
 arch/arm64/include/asm/io.h                        |  19 +-
 arch/arm64/include/asm/kvm_mmu.h                   |  10 +-
 arch/arm64/include/asm/memory.h                    |   8 +-
 arch/arm64/include/asm/mmu_context.h               |  36 ++--
 arch/arm64/include/asm/pgtable-hwdef.h             |   1 +
 arch/arm64/include/asm/pgtable-prot.h              |   5 +-
 arch/arm64/include/asm/pgtable.h                   |  20 ++-
 arch/arm64/include/asm/processor.h                 |   2 -
 arch/arm64/include/asm/sections.h                  |  30 ++++
 arch/arm64/include/asm/spinlock.h                  |  27 ++-
 arch/arm64/include/asm/suspend.h                   |   3 +
 arch/arm64/include/asm/sysreg.h                    |  44 +++--
 arch/arm64/include/asm/system_misc.h               |   6 -
 arch/arm64/include/asm/thread_info.h               |   3 +
 arch/arm64/include/asm/tlbflush.h                  |  34 +++-
 arch/arm64/include/asm/traps.h                     |   6 +-
 arch/arm64/include/asm/virt.h                      |  15 +-
 arch/arm64/kernel/Makefile                         |   2 +
 arch/arm64/kernel/acpi_numa.c                      |   4 +-
 arch/arm64/kernel/alternative.c                    |  28 ++-
 arch/arm64/kernel/asm-offsets.c                    |   2 +
 arch/arm64/kernel/cacheinfo.c                      |   8 +-
 arch/arm64/kernel/cpu_errata.c                     |  26 ++-
 arch/arm64/kernel/cpu_ops.c                        |   3 +-
 arch/arm64/kernel/cpufeature.c                     | 137 +++++++-------
 arch/arm64/kernel/cpuinfo.c                        |   2 -
 arch/arm64/kernel/debug-monitors.c                 |  48 ++---
 arch/arm64/kernel/entry.S                          |  24 +--
 arch/arm64/kernel/head.S                           | 197 ++++++++++++---------
 arch/arm64/kernel/hibernate-asm.S                  |   6 +-
 arch/arm64/kernel/hibernate.c                      | 118 ++++++++----
 arch/arm64/kernel/hw_breakpoint.c                  |  48 ++---
 arch/arm64/kernel/insn.c                           |  15 +-
 arch/arm64/kernel/kaslr.c                          |   3 +-
 arch/arm64/kernel/perf_event.c                     | 100 ++++++++---
 arch/arm64/kernel/probes/decode-insn.c             |  48 +++--
 arch/arm64/kernel/probes/kprobes.c                 |  36 ++--
 arch/arm64/kernel/process.c                        |  14 +-
 arch/arm64/kernel/relocate_kernel.S                |   2 +-
 arch/arm64/kernel/setup.c                          |  11 +-
 arch/arm64/kernel/signal.c                         |  36 ++--
 arch/arm64/kernel/sleep.S                          |  29 ++-
 arch/arm64/kernel/smp.c                            |  14 +-
 arch/arm64/kernel/smp_spin_table.c                 |   3 +-
 arch/arm64/kernel/stacktrace.c                     |  26 ++-
 arch/arm64/kernel/suspend.c                        |  10 +-
 arch/arm64/kernel/sys_compat.c                     |   2 +-
 arch/arm64/kernel/traps.c                          |  97 ++++++----
 arch/arm64/kernel/vdso.c                           |  36 ++--
 arch/arm64/kernel/vmlinux.lds.S                    |  19 ++
 arch/arm64/kvm/hyp.S                               |   6 +-
 arch/arm64/kvm/sys_regs.c                          |  31 ++--
 arch/arm64/kvm/sys_regs_generic_v8.c               |   6 +-
 arch/arm64/lib/copy_page.S                         |  13 +-
 arch/arm64/mm/cache.S                              |  82 ++++-----
 arch/arm64/mm/dma-mapping.c                        |   9 +-
 arch/arm64/mm/extable.c                            |   2 +-
 arch/arm64/mm/fault.c                              |   7 +-
 arch/arm64/mm/flush.c                              |   2 -
 arch/arm64/mm/init.c                               |  15 +-
 arch/arm64/mm/mm.h                                 |   2 -
 arch/arm64/mm/mmu.c                                |  15 +-
 arch/arm64/mm/numa.c                               | 115 ++++++++----
 arch/arm64/mm/pageattr.c                           |  41 ++++-
 arch/arm64/mm/pgd.c                                |   2 -
 arch/arm64/mm/proc.S                               |  13 +-
 drivers/clocksource/Kconfig                        |  10 ++
 drivers/clocksource/arm_arch_timer.c               | 113 +++++++++++-
 drivers/of/of_numa.c                               |  66 +++----
 drivers/perf/arm_pmu.c                             |  35 +++-
 include/linux/cpu.h                                |   6 +-
 include/linux/cpuhotplug.h                         |   2 +
 include/linux/jump_label.h                         |  12 ++
 include/linux/perf/arm_pmu.h                       |  13 +-
 kernel/cpu.c                                       |   9 +-
 mm/mmap.c                                          |   5 +
 105 files changed, 1699 insertions(+), 972 deletions(-)
 create mode 100644 arch/arm/include/asm/clocksource.h
 create mode 100644 arch/arm64/include/asm/clocksource.h
 create mode 100644 arch/arm64/include/asm/sections.h
 delete mode 100644 arch/arm64/mm/mm.h

^ permalink raw reply

* [PATCH] drm/sun4i: Check that the plane coordinates are not negative
From: Boris Brezillon @ 2016-09-30 16:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930143320.26241-1-maxime.ripard@free-electrons.com>

On Fri, 30 Sep 2016 16:33:20 +0200
Maxime Ripard <maxime.ripard@free-electrons.com> wrote:

> Our planes cannot be set at negative coordinates. Make sure we reject such
> configuration.
> 
> Reported-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/gpu/drm/sun4i/sun4i_layer.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
> index f0035bf5efea..f5463c4c2cde 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
> @@ -29,6 +29,9 @@ struct sun4i_plane_desc {
>  static int sun4i_backend_layer_atomic_check(struct drm_plane *plane,
>  					    struct drm_plane_state *state)
>  {
> +	if ((state->crtc_x < 0) || (state->crtc_y < 0))
> +		return -EINVAL;
> +

Hm, I think it's a perfectly valid use case from the DRM framework and
DRM user PoV: you may want to place your plane at a negative CRTC
offset (which means part of the plane will be hidden).

Maybe I'm wrong, but it seems you can support that by adapting the
start address of your framebuffer pointer and the layer size.

Have you tried doing something like that?

--->8---
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 3ab560450a82..6b68804f3035 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -110,15 +110,30 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
 {
        struct drm_plane_state *state = plane->state;
        struct drm_framebuffer *fb = state->fb;
+       int crtc_w, crtc_h, crtc_x, crtc_y;
 
        DRM_DEBUG_DRIVER("Updating layer %d\n", layer);
 
+       crtc_x = state->crtc_x;
+       crtc_y = state->crtc_y;
+       crtc_w = state->crtc_w;
+       crtc_h = state->crtc_h;
+
+       if (crtc_x < 0) {
+               crtc_w += crtx_x;
+               crtc_x = 0;
+       }
+
+       if (crtc_y < 0) {
+               crtc_h += crtx_y;
+               crtc_y = 0;
+       }
+
        if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
                DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n",
                                 state->crtc_w, state->crtc_h);
                regmap_write(backend->regs, SUN4I_BACKEND_DISSIZE_REG,
-                            SUN4I_BACKEND_DISSIZE(state->crtc_w,
-                                                  state->crtc_h));
+                            SUN4I_BACKEND_DISSIZE(crtc_w, crtc_h));
        }
 
        /* Set the line width */
@@ -130,15 +145,13 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
        DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n",
                         state->crtc_w, state->crtc_h);
        regmap_write(backend->regs, SUN4I_BACKEND_LAYSIZE_REG(layer),
-                    SUN4I_BACKEND_LAYSIZE(state->crtc_w,
-                                          state->crtc_h));
+                    SUN4I_BACKEND_LAYSIZE(crtc_w, crtc_h));
 
        /* Set base coordinates */
        DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n",
                         state->crtc_x, state->crtc_y);
        regmap_write(backend->regs, SUN4I_BACKEND_LAYCOOR_REG(layer),
-                    SUN4I_BACKEND_LAYCOOR(state->crtc_x,
-                                          state->crtc_y));
+                    SUN4I_BACKEND_LAYCOOR(crtc_x, crtc_y));
 
        return 0;
 }
@@ -198,6 +211,12 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
        paddr += (state->src_x >> 16) * bpp;
        paddr += (state->src_y >> 16) * fb->pitches[0];
 
+       if (state->crtc_x < 0)
+               paddr -= bpp * state->crtc_x;
+
+       if (state->crtc_y < 0)
+               paddr -= fb->pitches[0] * state->crtc_y;
+
        DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
 
        /* Write the 32 lower bits of the address (in bits) */

^ permalink raw reply related

* [PATCH 3/3] arm64: dump: Add checking for writable and exectuable pages
From: Mark Rutland @ 2016-09-30 15:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160929213257.30505-4-labbott@redhat.com>

On Thu, Sep 29, 2016 at 02:32:57PM -0700, Laura Abbott wrote:
> @@ -219,6 +223,15 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
>  		unsigned long delta;
>  
>  		if (st->current_prot) {
> +			if (st->check_wx &&
> +			((st->current_prot & PTE_RDONLY) != PTE_RDONLY) &&
> +			((st->current_prot & PTE_PXN) != PTE_PXN)) {
> +				WARN_ONCE(1, "arm64/mm: Found insecure W+X mapping at address %p/%pS\n",
> +					 (void *)st->start_address,
> +					 (void *)st->start_address);
> +				st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
> +			}
> +

Would it be worth verifying that all kernel mappings are UXN, too?

ARMv8 allows execute-only mappings, and a !UXN mapping could result in an info
leak (e.g. pointers in MOVZ+MOVK sequences), or potential asynchronous issues
(e.g. user instruction fetches accessing read-destructive device registers).
All kernel mappings *should* be UXN.

Thanks,
Mark.

^ permalink raw reply

* [PATCH 0/3] Support userspace irqchip with arch timers
From: Alexander Graf @ 2016-09-30 15:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930154335.GB7996@cbox>



On 30.09.16 17:43, Christoffer Dall wrote:
> On Fri, Sep 30, 2016 at 05:38:11PM +0200, Alexander Graf wrote:
>>
>>
>> On 30.09.16 16:54, Alexander Graf wrote:
>>>
>>>
>>> On 27.09.16 21:08, Christoffer Dall wrote:
>>>> Hi Alex,
>>>>
>>>> Marc and I have been looking at this during Linaro connect and have
>>>> slightly reworked your patch into this small series.
>>>>
>>>> It would be good if you could have a look at it and test it out.
>>>>
>>>> I've tested it with your QEMU, and it works for UP, but secondary CPUs
>>>> fail to come up, and it looks like the kernel never gets an IPI for
>>>> those CPUs from userspace.  Any chance you're willing to take a look at
>>>> that?
>>>
>>> I still need to see whether I can come up with a prettier solution, but
>>> for now this works:
>>>
>>> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
>>
>> Eh, no, not in i386 code :). But the problem seems to be a missing
>> mpstate sync.
>>
> Yeah, that looked really dodgy.  Have you tested it? :)

I have, but I ran the wrong command line and by accident used -M
...,kernel-irqchip=on :)


Alex

^ permalink raw reply

* [PATCH] pwm: imx: Port "pwm: imx: support output polarity inversion" to Linux v4.7
From: Stefan Agner @ 2016-09-30 15:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930084958.2f3f6e3a@jawa>

On 2016-09-29 23:49, Lukasz Majewski wrote:
> Dear all,
> 
>> Dear Lothar, Stefan,
>>
>> > This patch ports "pwm: imx: support output polarity inversion" patch
>> > set written by Lothar Wassmann (v6 from 10.2014).
>> >
>>
>> I've read the e-mail from Stefan regarding missing support for pwm-imx
>> polarity inversion feature.
>>
>> I also would like to see it in ML. Hence, my patch. Lothar, please
>> feel free to squash it to your patches when you (I hope :-) ) will
>> prepare v7 of this feature.
>>
>> I hope that this would help.
> 
> Was there any decision about those patches?

Bhuvan here at Toradex is preparing an updated patchset...

> 
> Would they be included to main line anytime soon?

I don't think that there were fundamental issues with the patchset, so I
hope they make it once upon a time...

--
Stefan

> 
> Best regards,
> ?ukasz Majewski
> 
>>
>> Best regards,
>> ?ukasz Majewski
>>
>> > It is used to control backlight of panels via inverted PWM signal.
>> >
>> > The "inversion" of PWM output is not an issue at such devices, since
>> > separate GPIO pin is responsible for enabling and disabling the
>> > panel's backlight.
>> >
>> > This patch should be put on top of:
>> >
>> > https://patchwork.kernel.org/patch/5065841/
>> > https://patchwork.kernel.org/patch/5065821/
>> > https://patchwork.kernel.org/patch/5065811/
>> >
>> >
>> > Signed-off-by: Lukasz Majewski <l.majewski@majess.pl>
>> > ---
>> >  drivers/pwm/pwm-imx.c | 20 ++++++++++++++------
>> >  1 file changed, 14 insertions(+), 6 deletions(-)
>> >
>> > diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
>> > index 471a99e..c37d223 100644
>> > --- a/drivers/pwm/pwm-imx.c
>> > +++ b/drivers/pwm/pwm-imx.c
>> > @@ -181,7 +181,7 @@ static int imx_pwm_config_v2(struct pwm_chip
>> > *chip, if (enable)
>> >  		cr |= MX3_PWMCR_EN;
>> >
>> > -	if (pwm->polarity == PWM_POLARITY_INVERSED)
>> > +	if (pwm->args.polarity == PWM_POLARITY_INVERSED)
>> >  		cr |= MX3_PWMCR_POUTC;
>> >
>> >  	writel(cr, imx->mmio_base + MX3_PWMCR);
>> > @@ -201,11 +201,6 @@ static void imx_pwm_set_enable_v2(struct
>> > pwm_chip *chip, bool enable) else
>> >  		val &= ~MX3_PWMCR_EN;
>> >
>> > -	if (chip->pwms[0].polarity == PWM_POLARITY_INVERSED)
>> > -		val |= MX3_PWMCR_POUTC;
>> > -	else
>> > -		val &= ~MX3_PWMCR_POUTC;
>> > -
>> >  	writel(val, imx->mmio_base + MX3_PWMCR);
>> >  }
>> >
>> > @@ -253,6 +248,19 @@ static int imx_pwm_set_polarity(struct pwm_chip
>> > *chip, struct pwm_device *pwm, enum pwm_polarity polarity)
>> >  {
>> >  	struct imx_chip *imx = to_imx_chip(chip);
>> > +	u32 val;
>> > +
>> > +	if (polarity == pwm->args.polarity)
>> > +		return 0;
>> > +
>> > +	val = readl(imx->mmio_base + MX3_PWMCR);
>> > +
>> > +	if (polarity == PWM_POLARITY_INVERSED)
>> > +		val |= MX3_PWMCR_POUTC;
>> > +	else
>> > +		val &= ~MX3_PWMCR_POUTC;
>> > +
>> > +	writel(val, imx->mmio_base + MX3_PWMCR);
>> >
>> >  	dev_dbg(imx->chip.dev, "%s: polarity set to %s\n",
>> > __func__, polarity == PWM_POLARITY_INVERSED ? "inverted" :
>> > "normal");
>>

^ permalink raw reply

* [PATCH] ARM64: dts: meson-gxbb-odroidc2: Enable USB Nodes
From: Kevin Hilman @ 2016-09-30 15:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475227059-17462-1-git-send-email-brian.kim@hardkernel.com>

Brian Kim <brian.kim@hardkernel.com> writes:

> Enable both gxbb USB controller and add a 5V regulator for the OTG port
> VBUS
>
> Signed-off-by: Brian Kim <brian.kim@hardkernel.com>

Thanks for the patch.

In the future, please state what branch the patch should apply to when
not using mainline.  Because of the sd_emmc nodes in your patch, I could
tell that it was based on my integ branch so was able to figure it out,
but it's very helpful to maintainers if you state the branch and/or any
dependencies explicity.

> ---
>  .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 29 ++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
> index 8d89edc..997c671 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
> @@ -64,6 +64,18 @@
>  		reg = <0x0 0x0 0x0 0x80000000>;
>  	};
>  
> +	usb_pwr: regulator-usb-pwrs {

minor nit: since this is specific to the OTG part, can you call this
usb_otg_pwr? ...

> +		compatible = "regulator-fixed";
> +
> +		regulator-name = "USB_PWR";

... and rename this also?

> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +
> +		gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +

Thanks

Kevin

^ permalink raw reply

* [PATCH v5 01/14] drivers: iommu: add FWNODE_IOMMU fwnode type
From: Rafael J. Wysocki @ 2016-09-30 15:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930090702.GA7725@red-moon>

On Fri, Sep 30, 2016 at 11:07 AM, Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
> On Thu, Sep 29, 2016 at 10:59:40PM +0200, Rafael J. Wysocki wrote:
>> On Thursday, September 29, 2016 03:15:20 PM Lorenzo Pieralisi wrote:
>> > Hi Rafael,
>> >
>> > On Fri, Sep 09, 2016 at 03:23:30PM +0100, Lorenzo Pieralisi wrote:
>> > > On systems booting with a device tree, every struct device is
>> > > associated with a struct device_node, that represents its DT
>> > > representation. The device node can be used in generic kernel
>> > > contexts (eg IRQ translation, IOMMU streamid mapping), to
>> > > retrieve the properties associated with the device and carry
>> > > out kernel operation accordingly. Owing to the 1:1 relationship
>> > > between the device and its device_node, the device_node can also
>> > > be used as a look-up token for the device (eg looking up a device
>> > > through its device_node), to retrieve the device in kernel paths
>> > > where the device_node is available.
>> > >
>> > > On systems booting with ACPI, the same abstraction provided by
>> > > the device_node is required to provide look-up functionality.
>> > >
>> > > Therefore, mirroring the approach implemented in the IRQ domain
>> > > kernel layer, this patch adds an additional fwnode type FWNODE_IOMMU.
>> > >
>> > > This patch also implements a glue kernel layer that allows to
>> > > allocate/free FWNODE_IOMMU fwnode_handle structures and associate
>> > > them with IOMMU devices.
>> > >
>> > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> > > Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
>> > > Cc: Joerg Roedel <joro@8bytes.org>
>> > > Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
>> > > ---
>> > >  include/linux/fwnode.h |  1 +
>> > >  include/linux/iommu.h  | 25 +++++++++++++++++++++++++
>> > >  2 files changed, 26 insertions(+)
>> > >
>> > > diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
>> > > index 8516717..6e10050 100644
>> > > --- a/include/linux/fwnode.h
>> > > +++ b/include/linux/fwnode.h
>> > > @@ -19,6 +19,7 @@ enum fwnode_type {
>> > >   FWNODE_ACPI_DATA,
>> > >   FWNODE_PDATA,
>> > >   FWNODE_IRQCHIP,
>> > > + FWNODE_IOMMU,
>> >
>> > This patch provides groundwork for this series and it is key for
>> > the rest of it, basically the point here is that we need a fwnode
>> > to differentiate platform devices created out of static ACPI tables
>> > entries (ie IORT), that represent IOMMU components.
>> >
>> > The corresponding device is not an ACPI device (I could fabricate one as
>> > it is done for other static tables entries eg FADT power button, but I
>> > do not necessarily see the reason for doing that given that all we need
>> > the fwnode for is a token identifier), so FWNODE_ACPI does not apply
>> > here.
>> >
>> > Please let me know if it is reasonable how I sorted this out (it
>> > is basically identical to IRQCHIP, just another enum entry), the
>> > remainder of the code depends on this.
>>
>> I'm not familiar with the use case, so I don't see anything unreasonable
>> in it.
>
> The use case is pretty simple: on ARM SMMU devices are platform devices.
> When booting with DT they are identified through an of_node and related
> FWNODE_OF type. When booting with ACPI, the ARM SMMU platform devices,
> to be equivalent to DT booting path, should be created out of static
> IORT table entries (that's how we describe SMMUs); we need to create
> a fwnode "token" to associate with those platform devices and that's
> not a FWNODE_ACPI (that is for an ACPI device firmware object, here we
> really do not need one), so this patch.
>
>> If you're asking about whether or not I mind adding more fwnode types in
>> principle, then no, I don't. :-)
>
> Yes, that's what I was asking, the only point that bugs me is that for
> both FWNODE_IRQCHIP and FWNODE_IOMMU the fwnode is just a "token" (ie a
> valid pointer) used for look-up and the type in the fwnode_handle is
> mostly there for error checking, I was wondering if we could create a
> specific fwnode_type for this specific usage (eg FWNODE_TAG and then add
> a type to it as part of its container struct) instead of adding an enum
> value per subsystem - it seems there are other fwnode types in the
> pipeline :), so I am asking:
>
> lkml.kernel.org/r/3D1468514043-21081-3-git-send-email-minyard at acm.org

OK, I see your concern now, so thanks for presenting it so clearly.

While I don't see anything wrong with having per-subsystem fwnode
types in principle, I agree that if the only purpose of them is to
mean "this comes from ACPI, but from a static table, not from the
namespace", it would be better to have a single fwnode type for that,
like FWNODE_ACPI_STATIC or similar.

Thanks,
Rafael

^ permalink raw reply

* [PATCH 0/3] Support userspace irqchip with arch timers
From: Christoffer Dall @ 2016-09-30 15:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3e85d538-2539-f190-0d17-a2ecfe7b48ce@suse.de>

On Fri, Sep 30, 2016 at 05:38:11PM +0200, Alexander Graf wrote:
> 
> 
> On 30.09.16 16:54, Alexander Graf wrote:
> > 
> > 
> > On 27.09.16 21:08, Christoffer Dall wrote:
> >> Hi Alex,
> >>
> >> Marc and I have been looking at this during Linaro connect and have
> >> slightly reworked your patch into this small series.
> >>
> >> It would be good if you could have a look at it and test it out.
> >>
> >> I've tested it with your QEMU, and it works for UP, but secondary CPUs
> >> fail to come up, and it looks like the kernel never gets an IPI for
> >> those CPUs from userspace.  Any chance you're willing to take a look at
> >> that?
> > 
> > I still need to see whether I can come up with a prettier solution, but
> > for now this works:
> > 
> > diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> 
> Eh, no, not in i386 code :). But the problem seems to be a missing
> mpstate sync.
> 
Yeah, that looked really dodgy.  Have you tested it? :)

-Christoffer

^ permalink raw reply

* [PATCH 0/3] Support userspace irqchip with arch timers
From: Alexander Graf @ 2016-09-30 15:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <de375a6e-095c-a17a-0db7-876a5619df42@suse.de>



On 30.09.16 16:54, Alexander Graf wrote:
> 
> 
> On 27.09.16 21:08, Christoffer Dall wrote:
>> Hi Alex,
>>
>> Marc and I have been looking at this during Linaro connect and have
>> slightly reworked your patch into this small series.
>>
>> It would be good if you could have a look at it and test it out.
>>
>> I've tested it with your QEMU, and it works for UP, but secondary CPUs
>> fail to come up, and it looks like the kernel never gets an IPI for
>> those CPUs from userspace.  Any chance you're willing to take a look at
>> that?
> 
> I still need to see whether I can come up with a prettier solution, but
> for now this works:
> 
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c

Eh, no, not in i386 code :). But the problem seems to be a missing
mpstate sync.


Alex

^ permalink raw reply

* [PATCH 6/6] ARM: da850: adjust memory settings for tilcdc
From: Bartosz Golaszewski @ 2016-09-30 15:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4e089d20-d00f-ff54-7c54-85aa061e23c2@ti.com>

2016-09-30 14:59 GMT+02:00 Peter Ujfalusi <peter.ujfalusi@ti.com>:
> On 09/29/16 19:31, Bartosz Golaszewski wrote:
>> Default memory settings of da850 do not meet the throughput/latency
>> requirements of tilcdc. This results in the image displayed being
>> incorrect and the following warning being displayed by the LCDC
>> drm driver:
>>
>>   tilcdc da8xx_lcdc.0: tilcdc_crtc_irq(0x00000020): FIFO underfow
>>
>> Reconfigure the LCDC priority to the highest. This is a workaround
>> for the da850-lcdk board which has the LCD controller enabled in
>> the device tree, but a long-term, system-wide fix is needed for
>> all davinci boards.
>>
>> This patch has been modified for mainline linux. It comes from a
>> downstream TI release for da850[1].
>>
>> Original author: Vishwanathrao Badarkhe, Manish <manishv.b@ti.com>
>>

[snip]

>
> Is this safe to do for all da850 boards (to change PR_OLD_COUNT from 0xff to
> 0x20)? Most probably it is, but this setting has nothing to do with LCDC.
>
> The whole priority configuration has nothing to do with the LCDC, it is a
> system level priority.
>
> Now you have lowered the eDMA3_0-TPTC0/1 priority. Audio is serviced by
> eDMA3_0-TPTC1. So are we going to see issues in audio if LCDC is taking the
> highest priority?
>

Just ran a quick test with speaker-test -c2 -twav. Besides the fact
that the left and right channels are inverted (I'm looking into that),
I didn't notice any problems. Even at 1024x768 resolution, playing
audio at the same time seems to work fine.

Best regards,
Bartosz Golaszewski

^ permalink raw reply

* [PATCH 0/3] Support userspace irqchip with arch timers
From: Alexander Graf @ 2016-09-30 14:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160927190806.22988-1-christoffer.dall@linaro.org>



On 27.09.16 21:08, Christoffer Dall wrote:
> Hi Alex,
> 
> Marc and I have been looking at this during Linaro connect and have
> slightly reworked your patch into this small series.
> 
> It would be good if you could have a look at it and test it out.
> 
> I've tested it with your QEMU, and it works for UP, but secondary CPUs
> fail to come up, and it looks like the kernel never gets an IPI for
> those CPUs from userspace.  Any chance you're willing to take a look at
> that?

I still need to see whether I can come up with a prettier solution, but
for now this works:

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index f1ad805..8b9a084 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2393,7 +2393,11 @@ static int kvm_get_mp_state(X86CPU *cpu)
         return ret;
     }
     env->mp_state = mp_state.mp_state;
+#ifdef CONFIG_ARM
+    if (kvm_enabled()) {
+#else
     if (kvm_irqchip_in_kernel()) {
+#endif
         cs->halted = (mp_state.mp_state == KVM_MP_STATE_HALTED);
     }
     return 0;


Alex

^ permalink raw reply related

* [PATCH v5 5/5] ARM: sunxi: Enable VGA bridge
From: Maxime Ripard @ 2016-09-30 14:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930143709.1388-1-maxime.ripard@free-electrons.com>

Enable the VGA bridge used on the A13-Olinuxino in the sunxi defconfig

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/configs/sunxi_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 714da336ec86..d830e258db59 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -98,6 +98,7 @@ CONFIG_MEDIA_RC_SUPPORT=y
 CONFIG_RC_DEVICES=y
 CONFIG_IR_SUNXI=y
 CONFIG_DRM=y
+CONFIG_DRM_RGB_TO_VGA=y
 CONFIG_DRM_SUN4I=y
 CONFIG_FB=y
 CONFIG_FB_SIMPLE=y
-- 
2.9.3

^ permalink raw reply related

* [PATCH v5 4/5] ARM: multi_v7: enable VGA bridge
From: Maxime Ripard @ 2016-09-30 14:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930143709.1388-1-maxime.ripard@free-electrons.com>

Enable the RGB to VGA bridge driver in the defconfig

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 2c8665cd9dc5..22ef41afc658 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -567,6 +567,7 @@ CONFIG_DRM=y
 CONFIG_DRM_I2C_ADV7511=m
 # CONFIG_DRM_I2C_CH7006 is not set
 # CONFIG_DRM_I2C_SIL164 is not set
+CONFIG_DRM_RGB_TO_VGA=m
 CONFIG_DRM_NXP_PTN3460=m
 CONFIG_DRM_PARADE_PS8622=m
 CONFIG_DRM_NOUVEAU=m
-- 
2.9.3

^ permalink raw reply related

* [PATCH v5 3/5] ARM: sun5i: a13-olinuxino: Enable VGA bridge
From: Maxime Ripard @ 2016-09-30 14:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930143709.1388-1-maxime.ripard@free-electrons.com>

Now that we have support for the VGA bridges using our DRM driver, enable
the display engine for the Olimex A13-Olinuxino.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 54 +++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index b3c234c65ea1..01ce7ea9032d 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -72,6 +72,47 @@
 			default-state = "on";
 		};
 	};
+
+	bridge {
+		compatible = "rgb-to-vga-bridge";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				vga_bridge_in: endpoint {
+					remote-endpoint = <&tcon0_out_vga>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				vga_bridge_out: endpoint {
+					remote-endpoint = <&vga_con_in>;
+				};
+			};
+		};
+	};
+
+	vga {
+		compatible = "vga-connector";
+
+		port {
+			vga_con_in: endpoint {
+				remote-endpoint = <&vga_bridge_out>;
+			};
+		};
+	};
+};
+
+&be0 {
+	status = "okay";
 };
 
 &ehci0 {
@@ -211,6 +252,19 @@
 	status = "okay";
 };
 
+&tcon0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&lcd_rgb666_pins>;
+	status = "okay";
+};
+
+&tcon0_out {
+	tcon0_out_vga: endpoint at 0 {
+		reg = <0>;
+		remote-endpoint = <&vga_bridge_in>;
+	};
+};
+
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart1_pins_b>;
-- 
2.9.3

^ permalink raw reply related

* [PATCH v5 2/5] drm/bridge: Add RGB to VGA bridge support
From: Maxime Ripard @ 2016-09-30 14:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930143709.1388-1-maxime.ripard@free-electrons.com>

Some boards have an entirely passive RGB to VGA bridge, based on either
DACs or resistor ladders.

Those might or might not have an i2c bus routed to the VGA connector in
order to access the screen EDIDs.

Add a bridge that doesn't do anything but expose the modes available on the
screen, either based on the EDIDs if available, or based on the XGA
standards.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 .../bindings/display/bridge/rgb-to-vga-bridge.txt  |  48 +++++
 drivers/gpu/drm/bridge/Kconfig                     |   7 +
 drivers/gpu/drm/bridge/Makefile                    |   1 +
 drivers/gpu/drm/bridge/rgb-to-vga.c                | 229 +++++++++++++++++++++
 4 files changed, 285 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt
 create mode 100644 drivers/gpu/drm/bridge/rgb-to-vga.c

diff --git a/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt
new file mode 100644
index 000000000000..a8375bc1f9cb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt
@@ -0,0 +1,48 @@
+Dumb RGB to VGA bridge
+----------------------
+
+This binding is aimed for dumb RGB to VGA bridges that do not require
+any configuration.
+
+Required properties:
+
+- compatible: Must be "rgb-to-vga-bridge"
+
+Required nodes:
+
+This device has two video ports. Their connections are modeled using the OF
+graph bindings specified in Documentation/devicetree/bindings/graph.txt.
+
+- Video port 0 for RGB input
+- Video port 1 for VGA output
+
+
+Example
+-------
+
+bridge {
+	compatible = "rgb-to-vga-bridge";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+
+			vga_bridge_in: endpoint {
+				remote-endpoint = <&tcon0_out_vga>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			vga_bridge_out: endpoint {
+				remote-endpoint = <&vga_con_in>;
+			};
+		};
+	};
+};
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index b590e678052d..d690398c541c 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -17,6 +17,13 @@ config DRM_ANALOGIX_ANX78XX
 	  the HDMI output of an application processor to MyDP
 	  or DisplayPort.
 
+config DRM_RGB_TO_VGA
+	tristate "Dumb RGB to VGA Bridge support"
+	depends on OF
+	select DRM_KMS_HELPER
+	help
+	  Support for passive RGB to VGA bridges
+
 config DRM_DW_HDMI
 	tristate
 	select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index efdb07e878f5..3bb8cbe09fe9 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
 ccflags-y := -Iinclude/drm
 
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
+obj-$(CONFIG_DRM_RGB_TO_VGA) += rgb-to-vga.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
diff --git a/drivers/gpu/drm/bridge/rgb-to-vga.c b/drivers/gpu/drm/bridge/rgb-to-vga.c
new file mode 100644
index 000000000000..5ff4d4f3598f
--- /dev/null
+++ b/drivers/gpu/drm/bridge/rgb-to-vga.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2015-2016 Free Electrons
+ * Copyright (C) 2015-2016 NextThing Co
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/of_graph.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+
+struct dumb_vga {
+	struct drm_bridge	bridge;
+	struct drm_connector	connector;
+
+	struct i2c_adapter	*ddc;
+};
+
+static inline struct dumb_vga *
+drm_bridge_to_dumb_vga(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct dumb_vga, bridge);
+}
+
+static inline struct dumb_vga *
+drm_connector_to_dumb_vga(struct drm_connector *connector)
+{
+	return container_of(connector, struct dumb_vga, connector);
+}
+
+static int dumb_vga_get_modes(struct drm_connector *connector)
+{
+	struct dumb_vga *vga = drm_connector_to_dumb_vga(connector);
+	struct edid *edid;
+	int ret;
+
+	if (IS_ERR(vga->ddc))
+		goto fallback;
+
+	edid = drm_get_edid(connector, vga->ddc);
+	if (!edid) {
+		DRM_INFO("EDID readout failed, falling back to standard modes\n");
+		goto fallback;
+	}
+
+	drm_mode_connector_update_edid_property(connector, edid);
+	return drm_add_edid_modes(connector, edid);
+
+fallback:
+	/*
+	 * In case we cannot retrieve the EDIDs (broken or missing i2c
+	 * bus), fallback on the XGA standards
+	 */
+	ret = drm_add_modes_noedid(connector, 1920, 1200);
+
+	/* And prefer a mode pretty much anyone can handle */
+	drm_set_preferred_mode(connector, 1024, 768);
+
+	return ret;
+}
+
+static const struct drm_connector_helper_funcs dumb_vga_con_helper_funcs = {
+	.get_modes	= dumb_vga_get_modes,
+};
+
+static enum drm_connector_status
+dumb_vga_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct dumb_vga *vga = drm_connector_to_dumb_vga(connector);
+
+	/*
+	 * Even if we have an I2C bus, we can't assume that the cable
+	 * is disconnected if drm_probe_ddc fails. Some cables don't
+	 * wire the DDC pins, or the I2C bus might not be working at
+	 * all.
+	 */
+	if (!IS_ERR(vga->ddc) && drm_probe_ddc(vga->ddc))
+		return connector_status_connected;
+
+	return connector_status_unknown;
+}
+
+static void
+dumb_vga_connector_destroy(struct drm_connector *connector)
+{
+	drm_connector_cleanup(connector);
+}
+
+static const struct drm_connector_funcs dumb_vga_con_funcs = {
+	.dpms			= drm_atomic_helper_connector_dpms,
+	.detect			= dumb_vga_connector_detect,
+	.fill_modes		= drm_helper_probe_single_connector_modes,
+	.destroy		= dumb_vga_connector_destroy,
+	.reset			= drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
+};
+
+static int dumb_vga_attach(struct drm_bridge *bridge)
+{
+	struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
+	int ret;
+
+	if (!bridge->encoder) {
+		DRM_ERROR("Missing encoder\n");
+		return -ENODEV;
+	}
+
+	drm_connector_helper_add(&vga->connector,
+				 &dumb_vga_con_helper_funcs);
+	ret = drm_connector_init(bridge->dev, &vga->connector,
+				 &dumb_vga_con_funcs, DRM_MODE_CONNECTOR_VGA);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector\n");
+		return ret;
+	}
+
+	drm_mode_connector_attach_encoder(&vga->connector,
+					  bridge->encoder);
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs dumb_vga_bridge_funcs = {
+	.attach		= dumb_vga_attach,
+};
+
+static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
+{
+	struct device_node *end_node, *phandle, *remote;
+	struct i2c_adapter *ddc;
+
+	end_node = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
+	if (!end_node) {
+		dev_err(dev, "Missing connector endpoint\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	remote = of_graph_get_remote_port_parent(end_node);
+	of_node_put(end_node);
+	if (!remote) {
+		dev_err(dev, "Enable to parse remote node\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0);
+	of_node_put(remote);
+	if (!phandle)
+		return ERR_PTR(-ENODEV);
+
+	ddc = of_get_i2c_adapter_by_node(phandle);
+	of_node_put(phandle);
+	if (!ddc)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return ddc;
+}
+
+static int dumb_vga_probe(struct platform_device *pdev)
+{
+	struct dumb_vga *vga;
+	int ret;
+
+	vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL);
+	if (!vga)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, vga);
+
+	vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev);
+	if (IS_ERR(vga->ddc)) {
+		if (PTR_ERR(vga->ddc) == -ENODEV) {
+			dev_info(&pdev->dev,
+				 "No i2c bus specified... Disabling EDID readout\n");
+		} else {
+			dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n");
+			return PTR_ERR(vga->ddc);
+		}
+	}
+
+	vga->bridge.funcs = &dumb_vga_bridge_funcs;
+	vga->bridge.of_node = pdev->dev.of_node;
+
+	ret = drm_bridge_add(&vga->bridge);
+	if (ret && !IS_ERR(vga->ddc))
+		i2c_put_adapter(vga->ddc);
+
+	return ret;
+}
+
+static int dumb_vga_remove(struct platform_device *pdev)
+{
+	struct dumb_vga *vga = platform_get_drvdata(pdev);
+
+	drm_bridge_remove(&vga->bridge);
+
+	if (!IS_ERR(vga->ddc))
+		i2c_put_adapter(vga->ddc);
+
+	return 0;
+}
+
+static const struct of_device_id dumb_vga_match[] = {
+	{ .compatible = "rgb-to-vga-bridge" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dumb_vga_match);
+
+struct platform_driver dumb_vga_driver = {
+	.probe	= dumb_vga_probe,
+	.remove	= dumb_vga_remove,
+	.driver		= {
+		.name		= "rgb-to-vga-bridge",
+		.of_match_table	= dumb_vga_match,
+	},
+};
+module_platform_driver(dumb_vga_driver);
+
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_DESCRIPTION("Dumb RGB to VGA bridge driver");
+MODULE_LICENSE("GPL");
-- 
2.9.3

^ permalink raw reply related

* [PATCH v5 1/5] drm/sun4i: rgb: Remove the bridge enable/disable functions
From: Maxime Ripard @ 2016-09-30 14:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160930143709.1388-1-maxime.ripard@free-electrons.com>

The atomic helpers already call the drm_bridge_enable on our behalf,
there's no need to do it a second time.

Reported-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/gpu/drm/sun4i/sun4i_rgb.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
index 4e4bea6f395c..d198ad7e5323 100644
--- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
@@ -155,9 +155,6 @@ static void sun4i_rgb_encoder_enable(struct drm_encoder *encoder)
 	if (!IS_ERR(tcon->panel))
 		drm_panel_prepare(tcon->panel);
 
-	/* encoder->bridge can be NULL; drm_bridge_enable checks for it */
-	drm_bridge_enable(encoder->bridge);
-
 	sun4i_tcon_channel_enable(tcon, 0);
 
 	if (!IS_ERR(tcon->panel))
@@ -177,9 +174,6 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder)
 
 	sun4i_tcon_channel_disable(tcon, 0);
 
-	/* encoder->bridge can be NULL; drm_bridge_disable checks for it */
-	drm_bridge_disable(encoder->bridge);
-
 	if (!IS_ERR(tcon->panel))
 		drm_panel_unprepare(tcon->panel);
 }
-- 
2.9.3

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox