Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] ARM: dts: imx6ul-14x14-evk: add USB dual-role support
From: Fabio Estevam @ 2016-10-28 11:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1470128903-942-1-git-send-email-peter.chen@nxp.com>

On Tue, Aug 2, 2016 at 6:08 AM, Peter Chen <peter.chen@nxp.com> wrote:
> With commit 851ce932242d ("usb: chipidea: otg: don't wait vbus
> drops below BSV when starts host"), the driver can support
> enabling vbus output without software control, so this board
> (control vbus output through ID pin) can support dual-role now.
>
> Signed-off-by: Peter Chen <peter.chen@nxp.com>

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

^ permalink raw reply

* [GIT PULL] arm64: dts: juno: updates for v4.10
From: Sudeep Holla @ 2016-10-28 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi ARM SoC Team,

Please pull.

--
Regards,
Sudeep

The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:

  Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/juno-dt-4.10

for you to fetch changes up to c1ab65b24065ab04bdb0bc4e89d88784d38dc644:

  arm64: dts: juno: add cpu capacity-dmips-mhz information to R2 boards (2016-10-17 17:43:22 +0100)

----------------------------------------------------------------
ARMv8 Vexpress/Juno DT updates for v4.10

1. Addition of SMMU(MMU-401) device nodes mainly to assist other
   developments and testing

2. Addition of CPU dmips/capacity information on all the Juno boards

----------------------------------------------------------------
Juri Lelli (3):
      arm64: dts: juno: add cpu capacity-dmips-mhz information to R0 boards
      arm64: dts: juno: add cpu capacity-dmips-mhz information to R1 boards
      arm64: dts: juno: add cpu capacity-dmips-mhz information to R2 boards

Robin Murphy (1):
      arm64: dts: juno: Add SMMUs device nodes

 arch/arm64/boot/dts/arm/juno-base.dtsi | 80 ++++++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/arm/juno-r1.dts    |  6 +++
 arch/arm64/boot/dts/arm/juno-r2.dts    |  6 +++
 arch/arm64/boot/dts/arm/juno.dts       |  6 +++
 4 files changed, 98 insertions(+)

^ permalink raw reply

* [GIT PULL] ARM: dts: vexpress: fixes/updates for v4.10
From: Sudeep Holla @ 2016-10-28 11:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi ARM Soc Team,

Please pull !

--
Regards,
Sudeep

The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:

  Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/vexpress-dt-4.10

for you to fetch changes up to b01c3994817dc4e117c5642c3e09e0a231b5b477:

  ARM: dts: vexpress: add TC2 cpu capacity-dmips-mhz information (2016-10-17 17:05:58 +0100)

----------------------------------------------------------------
ARMv7 Vexpress DT fixes/updates for v4.10

1. Addition of CPU dmips/capacity information to TC2 platform

2. Cleanup/fix unit address warnings and removal of skeleton.dtsi from
   MPS2 device tree

----------------------------------------------------------------
Juri Lelli (1):
      ARM: dts: vexpress: add TC2 cpu capacity-dmips-mhz information

Vladimir Murzin (1):
      ARM: dts: mps2: remove skeleton.dtsi include and fix unit address warnings

 arch/arm/boot/dts/mps2-an385.dts           | 2 +-
 arch/arm/boot/dts/mps2-an399.dts           | 2 +-
 arch/arm/boot/dts/mps2.dtsi                | 4 +++-
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 5 +++++
 4 files changed, 10 insertions(+), 3 deletions(-)

^ permalink raw reply

* [GIT PULL] ARM: vexpress: fixes for v4.10
From: Sudeep Holla @ 2016-10-28 11:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi ARM SoC team,

These couple of fixes help to boot TC2 in HYP mode with CONFIG_MCPM
enabled. This was not supported directly before and hence targeting for
v4.10. Currently those who want to boot in HYP mode have to disable
MCPM config in the build.

Please pull.

--
Regards,
Sudeep

The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:

  Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/vexpress-fixes-4.10

for you to fetch changes up to 801f33be8e902d8cea75cb7ac056d07c4fdd25f8:

  drivers: cci: add missing CCI port availability firmware check (2016-10-17 14:27:54 +0100)

----------------------------------------------------------------
ARMv7 Vexpress fixes for v4.10

Couple of fixes to MCPM/CCI drivers to check and ensure that the kernel
is actually allowed to take control over CCI ports(i.e. running in
secure mode) before enabling MCPM.

This is needed to boot Linux in HYP mode (very useful for development
on virtualization) with CONFIG_MCPM enabled kernel.

----------------------------------------------------------------
Lorenzo Pieralisi (2):
      ARM: vexpress: refine MCPM smp operations override criteria
      drivers: cci: add missing CCI port availability firmware check

 arch/arm/mach-vexpress/platsmp.c | 34 ++++++++++++++++++++++++++--------
 drivers/bus/arm-cci.c            | 10 ++++++++++
 2 files changed, 36 insertions(+), 8 deletions(-)

^ permalink raw reply

* [GIT PULL] firmware: SCPI updates for v4.10
From: Sudeep Holla @ 2016-10-28 11:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi ARM-SoC Team,

Please pull !

--
Regards,
Sudeep

The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:

  Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/scpi-updates-4.10

for you to fetch changes up to a9e0192d8b35c6ab115a154ed1499ff39a0e5b06:

  firmware: arm_scpi: add support for legacy match table on Amlogic GXBB SoC (2016-10-19 15:17:28 +0100)

----------------------------------------------------------------
SCPI updates for v4.10

1. Adds support for Legacy SCPI(pre- SCPI v1.0) protocol

2. Adds support for SCPI used on Amlogic GXBB SoC using the legacy
   SCPI protocol

----------------------------------------------------------------
Neil Armstrong (5):
      dt-bindings: Add support for Amlogic GXBB SCPI Interface
      firmware: arm_scpi: increase MAX_DVFS_OPPS to 16 entries
      firmware: arm_scpi: add alternative legacy structures, functions and macros
      firmware: arm_scpi: allow firmware with get_capabilities not implemented
      firmware: arm_scpi: add support for legacy match table on Amlogic GXBB SoC

Sudeep Holla (1):
      firmware: arm_scpi: add command indirection to support legacy commands

 Documentation/devicetree/bindings/arm/arm,scpi.txt |   8 +-
 drivers/firmware/arm_scpi.c                        | 276 ++++++++++++++++++---
 2 files changed, 249 insertions(+), 35 deletions(-)

^ permalink raw reply

* [PATCH 2/2] irqchip/gic-v3: Use nops macro for Cavium ThunderX erratum 23154
From: Will Deacon @ 2016-10-28 11:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477653838-21569-1-git-send-email-will.deacon@arm.com>

The workaround for Cavium ThunderX erratum 23154 has a homebrew
pipeflush built out of NOP sequences around the read of the IAR.

This patch converts the code to use the new nops macro, which makes it
a little easier to read.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/arch_gicv3.h | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index fdf34f8b4ee0..0313670a3e3f 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -122,14 +122,9 @@ static inline u64 gic_read_iar_cavium_thunderx(void)
 {
 	u64 irqstat;
 
-	asm volatile(
-		"nop;nop;nop;nop\n\t"
-		"nop;nop;nop;nop");
-
+	nops(8);
 	irqstat = read_sysreg_s(ICC_IAR1_EL1);
-
-	asm volatile(
-		"nop;nop;nop;nop");
+	nops(4);
 	mb();
 
 	return irqstat;
-- 
2.1.4

^ permalink raw reply related

* [PATCH 1/2] irqchip/gic-v3: Convert arm64 GIC accessors to {read, write}_sysreg_s
From: Will Deacon @ 2016-10-28 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

The GIC system registers are accessed using open-coded wrappers around
the mrs_s/msr_s asm macros.

This patch moves the code over to the {read,wrote}_sysreg_s accessors
instead, reducing the amount of explicit asm blocks in the arch headers.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/arch_gicv3.h | 45 ++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index f8ae6d6e4767..fdf34f8b4ee0 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -80,18 +80,8 @@
 #include <linux/stringify.h>
 #include <asm/barrier.h>
 
-#define read_gicreg(r)							\
-	({								\
-		u64 reg;						\
-		asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg));	\
-		reg;							\
-	})
-
-#define write_gicreg(v,r)						\
-	do {								\
-		u64 __val = (v);					\
-		asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
-	} while (0)
+#define read_gicreg			read_sysreg_s
+#define write_gicreg			write_sysreg_s
 
 /*
  * Low-level accessors
@@ -102,13 +92,13 @@
 
 static inline void gic_write_eoir(u32 irq)
 {
-	asm volatile("msr_s " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" ((u64)irq));
+	write_sysreg_s(irq, ICC_EOIR1_EL1);
 	isb();
 }
 
 static inline void gic_write_dir(u32 irq)
 {
-	asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" ((u64)irq));
+	write_sysreg_s(irq, ICC_DIR_EL1);
 	isb();
 }
 
@@ -116,7 +106,7 @@ static inline u64 gic_read_iar_common(void)
 {
 	u64 irqstat;
 
-	asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
+	irqstat = read_sysreg_s(ICC_IAR1_EL1);
 	dsb(sy);
 	return irqstat;
 }
@@ -134,10 +124,12 @@ static inline u64 gic_read_iar_cavium_thunderx(void)
 
 	asm volatile(
 		"nop;nop;nop;nop\n\t"
-		"nop;nop;nop;nop\n\t"
-		"mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
-		"nop;nop;nop;nop"
-		: "=r" (irqstat));
+		"nop;nop;nop;nop");
+
+	irqstat = read_sysreg_s(ICC_IAR1_EL1);
+
+	asm volatile(
+		"nop;nop;nop;nop");
 	mb();
 
 	return irqstat;
@@ -145,37 +137,34 @@ static inline u64 gic_read_iar_cavium_thunderx(void)
 
 static inline void gic_write_pmr(u32 val)
 {
-	asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" ((u64)val));
+	write_sysreg_s(val, ICC_PMR_EL1);
 }
 
 static inline void gic_write_ctlr(u32 val)
 {
-	asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" ((u64)val));
+	write_sysreg_s(val, ICC_CTLR_EL1);
 	isb();
 }
 
 static inline void gic_write_grpen1(u32 val)
 {
-	asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" ((u64)val));
+	write_sysreg_s(val, ICC_GRPEN1_EL1);
 	isb();
 }
 
 static inline void gic_write_sgi1r(u64 val)
 {
-	asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val));
+	write_sysreg_s(val, ICC_SGI1R_EL1);
 }
 
 static inline u32 gic_read_sre(void)
 {
-	u64 val;
-
-	asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
-	return val;
+	return read_sysreg_s(ICC_SRE_EL1);
 }
 
 static inline void gic_write_sre(u32 val)
 {
-	asm volatile("msr_s " __stringify(ICC_SRE_EL1) ", %0" : : "r" ((u64)val));
+	write_sysreg_s(val, ICC_SRE_EL1);
 	isb();
 }
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH] fpga zynq: Check the bitstream for validity
From: Matthias Brugger @ 2016-10-28 11:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026225413.GA6220@obsidianresearch.com>



On 10/27/2016 12:54 AM, Jason Gunthorpe wrote:
> There is no sense in sending a bitstream we know will not work, and
> with the variety of options for bitstream generation in Xilinx tools
> it is not terribly clear or very well documented what the correct
> input should be, especially since auto-detection was removed from this
> driver.
>
> All Zynq full configuration bitstreams must start with the sync word in
> the correct byte order.
>
> Zynq is also only able to DMA dword quantities, so bitstreams must be
> a multiple of 4 bytes. This also fixes a DMA-past the end bug.
>

The you can also fix the transfer_length calculation in 
zynq_fpga_ops_write, as we don't allow buffers which are not a multiple 
of 4.

Regards,
Matthias

^ permalink raw reply

* [RFC][PATCH] arm64: Add support for CONFIG_DEBUG_VIRTUAL
From: Mark Rutland @ 2016-10-28 11:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu9-Pm_j-3shoiGZY+8zMBjTpNOXOphwea+tdC4KPbie3Q@mail.gmail.com>

On Fri, Oct 28, 2016 at 08:52:50AM +0100, Ard Biesheuvel wrote:
> Hi Laura,
> 
> On 28 October 2016 at 01:18, Laura Abbott <labbott@redhat.com> wrote:
> > x86 has an option CONFIG_DEBUG_VIRTUAL to do additional checks
> > on virt_to_phys calls. The goal is to catch users who are calling
> > virt_to_phys on non-linear addresses immediately. As features
> > such as CONFIG_VMAP_STACK get enabled for arm64, this becomes
> > increasingly important. Add checks to catch bad virt_to_phys
> > usage.
> 
> I think this is a useful thing to have. However, the Kconfig
> description talks about virt to page translations, not virt to phys.
> Of course, this is a shift away from being equivalent on x86, but not
> so much on arm64. Any concerns there?

See commit 59ea746337c69f6a ("MM: virtual address debug"); the existing
x86 cases cover virt to phys also.

The Kconfig text does say "and friends"...

Thanks,
Mark.

^ permalink raw reply

* [PATCH] fpga zynq: Check the bitstream for validity
From: Matthias Brugger @ 2016-10-28 11:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161027143937.GC6818@obsidianresearch.com>



On 10/27/2016 04:39 PM, Jason Gunthorpe wrote:
> On Thu, Oct 27, 2016 at 10:50:48AM +0200, Matthias Brugger wrote:
>>> +		/* Sanity check the proposed bitstream. It must start with the
>>> +		 * sync word in the correct byte order and be a multiple of 4
>>> +		 * bytes.
>>> +		 */
>>> +		if (count <= 4 || buf[0] != 0x66 || buf[1] != 0x55 ||
>>> +		    buf[2] != 0x99 || buf[3] != 0xaa) {
>>
>> This checks if the bit stream is bigger then 4 bytes. We error out before,
>> if it is smaller.
>
> We do? Where?
>

Just a few lines before:

+	/* All valid bitstreams are multiples of 32 bits */
+	if ((count % 4) != 0)
+		return -EINVAL;
+

The only case we don't check is, if count == 0. If we check that here, 
we can get rid of the count <= 4 check.

>> So you should fix the wording in the comment and check for count ==
>> 4.
>
> Ah right, the comment reflected an earlier revision that had the
> length check here.
>
> The count <= 4 should stay here since it is primarily guarding against
> read past the buffer in the if.

If you insist in doing this check, it should be count < 4, because we 
check the first four elements of buf, or do I miss something?

Cheers,
Matthias

>
> Jason
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

^ permalink raw reply

* [PATCH v2] irqchip/bcm2836: Prevent spurious interrupts
From: Thomas Gleixner @ 2016-10-28 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161027182038.11312-1-eric@anholt.net>

On Thu, 27 Oct 2016, Eric Anholt wrote:

> From: Phil Elwell <phil@raspberrypi.org>
> 
> The old arch-specific IRQ macros included a dsb to ensure the
> write to clear the mailbox interrupt completed before returning
> from the interrupt. The BCM2836 irqchip driver needs the same
> precaution to avoid spurious interrupts.

This is missing a fixes tag. I have no idea when that problem was
introduced, so I have no way to decide whether this needs to be tagged
stable or not.

Thanks,

	tglx

> 
> Signed-off-by: Phil Elwell <phil@raspberrypi.org>
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  drivers/irqchip/irq-bcm2836.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
> index d96b2c947e74..93e3f7660c42 100644
> --- a/drivers/irqchip/irq-bcm2836.c
> +++ b/drivers/irqchip/irq-bcm2836.c
> @@ -175,6 +175,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
>  		u32 ipi = ffs(mbox_val) - 1;
>  
>  		writel(1 << ipi, mailbox0);
> +		dsb(sy);
>  		handle_IPI(ipi, regs);
>  #endif
>  	} else if (stat) {
> -- 
> 2.9.3
> 
> 

^ permalink raw reply

* [PATCH v6] tty/serial: at91: fix hardware handshake on Atmel platforms
From: Richard Genoud @ 2016-10-28 10:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161028095151.f24lhelfknzrpy6c@pengutronix.de>

2016-10-28 11:51 GMT+02:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Fri, Oct 28, 2016 at 01:13:31AM +0200, Alexandre Belloni wrote:
>> On 27/10/2016 at 20:02:29 +0200, Uwe Kleine-K?nig wrote :
>> > Hello Richard,
>> >
>> > On Thu, Oct 27, 2016 at 06:04:06PM +0200, Richard Genoud wrote:
>> > > diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
>> > > index fd8aa1f4ba78..168b10cad47b 100644
>> > > --- a/drivers/tty/serial/atmel_serial.c
>> > > +++ b/drivers/tty/serial/atmel_serial.c
>> > > @@ -2132,11 +2132,29 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
>> > >           mode |= ATMEL_US_USMODE_RS485;
>> > >   } else if (termios->c_cflag & CRTSCTS) {
>> > >           /* RS232 with hardware handshake (RTS/CTS) */
>> > > -         if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) {
>> > > -                 dev_info(port->dev, "not enabling hardware flow control because DMA is used");
>> > > -                 termios->c_cflag &= ~CRTSCTS;
>> > > -         } else {
>> > > +         if (atmel_use_fifo(port) &&
>> > > +             !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) {
>> > > +                 /*
>> > > +                  * with ATMEL_US_USMODE_HWHS set, the controller will
>> > > +                  * be able to drive the RTS pin high/low when the RX
>> > > +                  * FIFO is above RXFTHRES/below RXFTHRES2.
>> > > +                  * It will also disable the transmitter when the CTS
>> > > +                  * pin is high.
>> > > +                  * This mode is not activated if CTS pin is a GPIO
>> > > +                  * because in this case, the transmitter is always
>> > > +                  * disabled (there must be an internal pull-up
>> > > +                  * responsible for this behaviour).
>> > > +                  * If the RTS pin is a GPIO, the controller won't be
>> > > +                  * able to drive it according to the FIFO thresholds,
>> > > +                  * but it will be handled by the driver.
>> > > +                  */
>> > >                   mode |= ATMEL_US_USMODE_HWHS;
>> >
>> > You use
>> >
>> >     !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)
>> >
>> > as indicator that the cts mode of the respective pin is used. Is this
>> > reliable? (It's not if there are machines that don't use CTS, neither as
>> > gpio nor using the hardware function.) Maybe this needs a dt property to
>> > indicate that there is no (hw)handshaking available?
>> >
>>
>> We had a call today were we agreed that this should be added in a future
>> patch. Let's fix the regression for now.
>
> A machine without CTS (neither gpio nor hw function) used to work fine
> before the breaking commit, right? So this case is part of the
> regression and needs a fix?
Actually, a machine with a FIFO and without CTS didn't even exist at the
time of the breaking commit (v4.0), the FIFO handling was introduced later,
so it's not even a regression !

> Anyhow, this probably shouldn't stop the commit entering mainline
> because there are probably very few such machines (if any).
>
> So:
> Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
>
> Best regards
> Uwe


Thanks !

Greg, could you take this in your tree ?

regards,
Richard.

^ permalink raw reply

* [v15, 0/7] Fix eSDHC host version register bug
From: Arnd Bergmann @ 2016-10-28 10:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477637418-38938-1-git-send-email-yangbo.lu@nxp.com>

On Friday, October 28, 2016 2:50:11 PM CEST Yangbo Lu wrote:
> This patchset is used to fix a host version register bug in the T4240-R1.0-R2.0
> eSDHC controller. To match the SoC version and revision, 10 previous version
> patchsets had tried many methods but all of them were rejected by reviewers.
> Such as
>         - dts compatible method
>         - syscon method
>         - ifdef PPC method
>         - GUTS driver getting SVR method
> Anrd suggested a soc_device_match method in v10, and this is the only available
> method left now. This v11 patchset introduces the soc_device_match interface in
> soc driver.
> 
> The first five patches of Yangbo are to add the GUTS driver. This is used to
> register a soc device which contain soc version and revision information.
> The other two patches introduce the soc_device_match method in soc driver
> and apply it on esdhc driver to fix this bug.
> 

Looks good overall. With patch 3 dropped (or an explanation why it's still
needed), everything

Acked-by: Arnd Bergmann <arnd@arndb.de>

	Arnd

^ permalink raw reply

* [v15, 3/7] powerpc/fsl: move mpc85xx.h to include/linux/fsl
From: Arnd Bergmann @ 2016-10-28 10:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477637418-38938-4-git-send-email-yangbo.lu@nxp.com>

On Friday, October 28, 2016 2:50:14 PM CEST Yangbo Lu wrote:
> Move mpc85xx.h to include/linux/fsl and rename it to svr.h as a common
> header file.  This SVR numberspace is used on some ARM chips as well as
> PPC, and even to check for a PPC SVR multi-arch drivers would otherwise
> need to ifdef the header inclusion and all references to the SVR symbols.
> 
> 

I don't see any of the contents of this header referenced by the soc driver
any more. I think you can just drop this patch.

	Arnd

^ permalink raw reply

* [PATCH v5 1/7] ARM: dts: r8a7743: initial SoC device tree
From: Geert Uytterhoeven @ 2016-10-28 10:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <13559419.B3v0G6vn24@wasted.cogentembedded.com>

Hi Sergei,

On Thu, Oct 27, 2016 at 11:36 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> The  initial R8A7743 SoC device tree including CPU0, GIC, timer, SYSC, RST,
> CPG, and the required clock descriptions.
>
> Based on the original (and large) patch by Dmitry Shifrin
> <dmitry.shifrin@cogentembedded.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
> ---
> Changes in version 5:
> - added the RST device node, updated the patch description accordingly.

Thanks for the update!

> +++ renesas/arch/arm/boot/dts/r8a7743.dtsi
> @@ -0,0 +1,120 @@

> +               rst: reset-controller at e6160000 {
> +                       compatible = "renesas,r8a7743-rst";
> +                       reg = <0 0xe6160000 0 0x0200>;

I'd use "reg = <0 0xe6160000 0 0x0100>".
Only R-Car Gen3 has registers above offset 0x100.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [v15, 6/7] base: soc: introduce soc_device_match() interface
From: Arnd Bergmann @ 2016-10-28 10:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477637418-38938-7-git-send-email-yangbo.lu@nxp.com>

On Friday, October 28, 2016 2:50:17 PM CEST Yangbo Lu wrote:
> +
> +static int soc_device_match_one(struct device *dev, void *arg)
> +{
> +       struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
> +       const struct soc_device_attribute *match = arg;
> +
> +       if (match->machine &&
> +           !glob_match(match->machine, soc_dev->attr->machine))
> +               return 0;
> +
> +       if (match->family &&
> +           !glob_match(match->family, soc_dev->attr->family))
> +               return 0;
> +
> 

Geert found a bug in my code, and submitted a fix at
https://patchwork.kernel.org/patch/9361395/

I think you should include that one in your series.

	Arnd

^ permalink raw reply

* [PATCH] arm64: swp emulation: bound LL/SC retries before rescheduling
From: Will Deacon @ 2016-10-28 10:42 UTC (permalink / raw)
  To: linux-arm-kernel

commit 1c5b51dfb7b4564008e0cadec5381a69e88b0d21 upstream.

If a CPU does not implement a global monitor for certain memory types,
then userspace can attempt a kernel DoS by issuing SWP instructions
targetting the problematic memory (for example, a framebuffer mapped
with non-cacheable attributes).

The SWP emulation code protects against these sorts of attacks by
checking for pending signals and potentially rescheduling when the STXR
instruction fails during the emulation. Whilst this is good for avoiding
livelock, it harms emulation of legitimate SWP instructions on CPUs
where forward progress is not guaranteed if there are memory accesses to
the same reservation granule (up to 2k) between the failing STXR and
the retry of the LDXR.

This patch solves the problem by retrying the STXR a bounded number of
times (4) before breaking out of the LL/SC loop and looking for
something else to do.

Cc: <stable@vger.kernel.org> # 4.4
Fixes: bd35a4adc413 ("arm64: Port SWP/SWPB emulation support from arm")
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/armv8_deprecated.c | 36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index 937f5e58a4d3..8496770723dd 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -280,21 +280,28 @@ static void register_insn_emulation_sysctl(struct ctl_table *table)
 /*
  * Error-checking SWP macros implemented using ldxr{b}/stxr{b}
  */
-#define __user_swpX_asm(data, addr, res, temp, B)		\
+
+/* Arbitrary constant to ensure forward-progress of the LL/SC loop */
+#define __SWP_LL_SC_LOOPS	4
+
+#define __user_swpX_asm(data, addr, res, temp, temp2, B)	\
 	__asm__ __volatile__(					\
+	"	mov		%w3, %w7\n"			\
 	ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN,	\
 		    CONFIG_ARM64_PAN)				\
-	"0:	ldxr"B"		%w2, [%3]\n"			\
-	"1:	stxr"B"		%w0, %w1, [%3]\n"		\
+	"0:	ldxr"B"		%w2, [%4]\n"			\
+	"1:	stxr"B"		%w0, %w1, [%4]\n"		\
 	"	cbz		%w0, 2f\n"			\
-	"	mov		%w0, %w4\n"			\
+	"	sub		%w3, %w3, #1\n"			\
+	"	cbnz		%w3, 0b\n"			\
+	"	mov		%w0, %w5\n"			\
 	"	b		3f\n"				\
 	"2:\n"							\
 	"	mov		%w1, %w2\n"			\
 	"3:\n"							\
 	"	.pushsection	 .fixup,\"ax\"\n"		\
 	"	.align		2\n"				\
-	"4:	mov		%w0, %w5\n"			\
+	"4:	mov		%w0, %w6\n"			\
 	"	b		3b\n"				\
 	"	.popsection"					\
 	"	.pushsection	 __ex_table,\"a\"\n"		\
@@ -304,14 +311,15 @@ static void register_insn_emulation_sysctl(struct ctl_table *table)
 	"	.popsection\n"					\
 	ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN,	\
 		CONFIG_ARM64_PAN)				\
-	: "=&r" (res), "+r" (data), "=&r" (temp)		\
-	: "r" (addr), "i" (-EAGAIN), "i" (-EFAULT)		\
+	: "=&r" (res), "+r" (data), "=&r" (temp), "=&r" (temp2)	\
+	: "r" (addr), "i" (-EAGAIN), "i" (-EFAULT),		\
+	  "i" (__SWP_LL_SC_LOOPS)				\
 	: "memory")
 
-#define __user_swp_asm(data, addr, res, temp) \
-	__user_swpX_asm(data, addr, res, temp, "")
-#define __user_swpb_asm(data, addr, res, temp) \
-	__user_swpX_asm(data, addr, res, temp, "b")
+#define __user_swp_asm(data, addr, res, temp, temp2) \
+	__user_swpX_asm(data, addr, res, temp, temp2, "")
+#define __user_swpb_asm(data, addr, res, temp, temp2) \
+	__user_swpX_asm(data, addr, res, temp, temp2, "b")
 
 /*
  * Bit 22 of the instruction encoding distinguishes between
@@ -353,12 +361,12 @@ static int emulate_swpX(unsigned int address, unsigned int *data,
 	}
 
 	while (1) {
-		unsigned long temp;
+		unsigned long temp, temp2;
 
 		if (type == TYPE_SWPB)
-			__user_swpb_asm(*data, address, res, temp);
+			__user_swpb_asm(*data, address, res, temp, temp2);
 		else
-			__user_swp_asm(*data, address, res, temp);
+			__user_swp_asm(*data, address, res, temp, temp2);
 
 		if (likely(res != -EAGAIN) || signal_pending(current))
 			break;
-- 
2.5.0

^ permalink raw reply related

* [PATCH] drm/mediatek: fix null pointer dereference
From: Matthias Brugger @ 2016-10-28 10:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477643686.17640.3.camel@mtksdaap41>



On 10/28/2016 10:34 AM, CK Hu wrote:
> Hi, Matthias:
>
> Even though OVL HW would not be enabled before component_add() in
> current design, your patch would be safe for any situation.

Maybe the FW I use left an interrupt pending before loading the kernel 
and this leads to the case where we enter the handler before all data 
structures are set up.

>
> Acked-by CK Hu <ck.hu@mediatek.com>

Thanks!

Matthias

^ permalink raw reply

* [PATCH v7, 0/8] Add MediaTek USB3 DRD Driver
From: Matthias Brugger @ 2016-10-28 10:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476844107-31087-1-git-send-email-chunfeng.yun@mediatek.com>

Hi Chunfeng,

On 10/19/2016 04:28 AM, Chunfeng Yun wrote:
> These patches introduce the MediaTek USB3 dual-role controller
> driver.
>
> The driver can be configured as Dual-Role Device (DRD),
> Peripheral Only and Host Only (xHCI) modes. It works well
> with Mass Storage, RNDIS and g_zero on FS/HS and SS. And it is
> tested on MT8173 platform which only contains USB2.0 device IP,
> and on MT6290 platform which contains USB3.0 device IP.
>
> Change in v7:
> 1. split dual-role driver into four patchs
> 2. remove QMU done tasklet
> 3. add a bool in xhci_hcd_mtk to signal absence of IPPC
>
> Change in v6:
> 1. handle endianness of GPD and SETUP data
> 2. remove dummy error log and return suitable error number
> 3. cancel delay work when deregiseter driver
>
> Change in v5:
> 1. modify some comments
> 2. rename some unsuitable variables
> 3. add reg-names property for host node
> 4. add USB_MTU3_DEBUG to control debug messages
>
> Change in v4:
> 1. fix build errors on non-mediatek platforms
> 2. provide manual dual-role switch via debugfs instead of sysfs
>
> Change in v3:
> 1. fix some typo error
> 2. rename mtu3.txt to mt8173-mtu3.txt
>
> Change in v2:
> 1. modify binding docs according to suggestions
> 2. modify some comments and remove some dummy blank lines
> 3. fix memory leakage
>
>
> Chunfeng Yun (8):
>   dt-bindings: mt8173-xhci: support host side of dual-role mode
>   dt-bindings: mt8173-mtu3: add devicetree bindings
>   usb: xhci-mtk: make IPPC register optional
>   usb: Add MediaTek USB3 DRD driver
>   usb: mtu3: Super-Speed Peripheral mode support
>   usb: mtu3: host only mode support
>   usb: mtu3: dual-role mode support
>   arm64: dts: mediatek: add USB3 DRD driver
>

I tried the driver with my mt8173-evb, but wasn't able to get USB 
working (no usb stick detected when adding to the usb port).

# dmesg |grep mtu
[    0.428420] mtu3 11271000.usb: failed to get vusb33
[    0.510570] mtu3 11271000.usb: failed to get vbus
[    0.592103] mtu3 11271000.usb: failed to get vbus


Relevant config options:
CONFIG_USB_MTU3=y
CONFIG_USB_MTU3_HOST=y
CONFIG_USB_MTU3_DEBUG=y
CONFIG_PHY_MT65XX_USB3=y


Looks like an error in the device tree. I can see that the mt6397 
regulater get's initialized *after* the mtu3 driver:
[    0.505166] mt6397-regulator mt6397-regulator: Chip ID = 0x4097

Not sure if this is related.
Any idea whats going wrong here?

Cheers,
Matthias

^ permalink raw reply

* [PATCH v4] drivers: psci: PSCI checker module
From: Kevin Brodsky @ 2016-10-28 10:31 UTC (permalink / raw)
  To: linux-arm-kernel

On arm and arm64, PSCI is one of the possible firmware interfaces
used for power management. This includes both turning CPUs on and off,
and suspending them (entering idle states).

This patch adds a PSCI checker module that enables basic testing of
PSCI operations during startup. There are two main tests: CPU
hotplugging and suspending.

In the hotplug tests, the hotplug API is used to turn off and on again
all CPUs in the system, and then all CPUs in each cluster, checking
the consistency of the return codes.

In the suspend tests, a high-priority thread is created on each core
and uses low-level cpuidle functionalities to enter suspend, in all
the possible states and multiple times. This should allow a maximum
number of CPUs to enter the same sleep state at the same or slightly
different time.

In essence, the suspend tests use a principle similar to that of the
intel_powerclamp driver (drivers/thermal/intel_powerclamp.c), but the
threads are only kept for the duration of the test (they are already
gone when userspace is started).

While in theory power management PSCI functions (CPU_{ON,OFF,SUSPEND})
could be directly called, this proved too difficult as it would imply
the duplication of all the logic used by the kernel to allow for a
clean shutdown/bringup/suspend of the CPU (the deepest sleep states
implying potentially the shutdown of the CPU).

Note that this file cannot be compiled as a loadable module, since it
uses a number of non-exported identifiers (essentially for
PSCI-specific checks and direct use of cpuidle) and relies on the
absence of userspace to avoid races when calling hotplug and cpuidle
functions.

For now at least, CONFIG_PSCI_CHECKER is mutually exclusive with
CONFIG_TORTURE_TEST, because torture tests may also use hotplug and
cause false positives in the hotplug tests.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kevin Hilman <khilman@kernel.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
Changelog v3..v4:
* Prevent enabling CONFIG_PSCI_CHECKER if CONFIG_TORTURE_TEST is
  selected, to avoid any interference during hotplug operations. Both
  could potentially be made to work together subsequently.

Cheers,
Kevin

 drivers/firmware/Kconfig        |  11 +
 drivers/firmware/Makefile       |   1 +
 drivers/firmware/psci_checker.c | 488 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 500 insertions(+)
 create mode 100644 drivers/firmware/psci_checker.c

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index bca172d42c74..3b526291c1a6 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -206,6 +206,17 @@ config QCOM_SCM_64
 config HAVE_ARM_SMCCC
 	bool
 
+config PSCI_CHECKER
+	bool "PSCI checker"
+	depends on ARM_PSCI_FW && HOTPLUG_CPU && !TORTURE_TEST
+	help
+	  Run the PSCI checker during startup. This checks that hotplug and
+	  suspend operations work correctly when using PSCI.
+
+	  The torture tests may interfere with the PSCI checker by turning CPUs
+	  on and off through hotplug, so for now torture tests and PSCI checker
+	  are mutually exclusive.
+
 source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 898ac41fa8b3..e7248eacc796 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_QCOM_SCM)		+= qcom_scm.o
 obj-$(CONFIG_QCOM_SCM_64)	+= qcom_scm-64.o
 obj-$(CONFIG_QCOM_SCM_32)	+= qcom_scm-32.o
 CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a
+obj-$(CONFIG_PSCI_CHECKER)	+= psci_checker.o
 
 obj-y				+= broadcom/
 obj-y				+= meson/
diff --git a/drivers/firmware/psci_checker.c b/drivers/firmware/psci_checker.c
new file mode 100644
index 000000000000..a49794a50ed6
--- /dev/null
+++ b/drivers/firmware/psci_checker.c
@@ -0,0 +1,488 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2016 ARM Limited
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/atomic.h>
+#include <linux/completion.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/psci.h>
+#include <linux/slab.h>
+#include <linux/tick.h>
+#include <linux/topology.h>
+
+#include <asm/cpuidle.h>
+
+#include <uapi/linux/psci.h>
+
+#define NUM_SUSPEND_CYCLE (10)
+
+static unsigned int nb_available_cpus;
+static int tos_resident_cpu = -1;
+
+static atomic_t nb_active_threads;
+static struct completion suspend_threads_started =
+	COMPLETION_INITIALIZER(suspend_threads_started);
+static struct completion suspend_threads_done =
+	COMPLETION_INITIALIZER(suspend_threads_done);
+
+/*
+ * We assume that PSCI operations are used if they are available. This is not
+ * necessarily true on arm64, since the decision is based on the
+ * "enable-method" property of each CPU in the DT, but given that there is no
+ * arch-specific way to check this, we assume that the DT is sensible.
+ */
+static int psci_ops_check(void)
+{
+	int migrate_type = -1;
+	int cpu;
+
+	if (!(psci_ops.cpu_off && psci_ops.cpu_on && psci_ops.cpu_suspend)) {
+		pr_warn("Missing PSCI operations, aborting tests\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (psci_ops.migrate_info_type)
+		migrate_type = psci_ops.migrate_info_type();
+
+	if (migrate_type == PSCI_0_2_TOS_UP_MIGRATE ||
+	    migrate_type == PSCI_0_2_TOS_UP_NO_MIGRATE) {
+		/* There is a UP Trusted OS, find on which core it resides. */
+		for_each_online_cpu(cpu)
+			if (psci_tos_resident_on(cpu)) {
+				tos_resident_cpu = cpu;
+				break;
+			}
+		if (tos_resident_cpu == -1)
+			pr_warn("UP Trusted OS resides on no online CPU\n");
+	}
+
+	return 0;
+}
+
+static int find_clusters(const struct cpumask *cpus,
+			 const struct cpumask **clusters)
+{
+	unsigned int nb = 0;
+	cpumask_var_t tmp;
+
+	if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
+		return -ENOMEM;
+	cpumask_copy(tmp, cpus);
+
+	while (!cpumask_empty(tmp)) {
+		const struct cpumask *cluster =
+			topology_core_cpumask(cpumask_any(tmp));
+
+		clusters[nb++] = cluster;
+		cpumask_andnot(tmp, tmp, cluster);
+	}
+
+	free_cpumask_var(tmp);
+	return nb;
+}
+
+/*
+ * offlined_cpus is a temporary array but passing it as an argument avoids
+ * multiple allocations.
+ */
+static unsigned int down_and_up_cpus(const struct cpumask *cpus,
+				     struct cpumask *offlined_cpus)
+{
+	int cpu;
+	int err = 0;
+
+	cpumask_clear(offlined_cpus);
+
+	/* Try to power down all CPUs in the mask. */
+	for_each_cpu(cpu, cpus) {
+		int ret = cpu_down(cpu);
+
+		/*
+		 * cpu_down() checks the number of online CPUs before the TOS
+		 * resident CPU.
+		 */
+		if (cpumask_weight(offlined_cpus) + 1 == nb_available_cpus) {
+			if (ret != -EBUSY) {
+				pr_err("Unexpected return code %d while trying "
+				       "to power down last online CPU %d\n",
+				       ret, cpu);
+				++err;
+			}
+		} else if (cpu == tos_resident_cpu) {
+			if (ret != -EPERM) {
+				pr_err("Unexpected return code %d while trying "
+				       "to power down TOS resident CPU %d\n",
+				       ret, cpu);
+				++err;
+			}
+		} else if (ret != 0) {
+			pr_err("Error occurred (%d) while trying "
+			       "to power down CPU %d\n", ret, cpu);
+			++err;
+		}
+
+		if (ret == 0)
+			cpumask_set_cpu(cpu, offlined_cpus);
+	}
+
+	/* Try to power up all the CPUs that have been offlined. */
+	for_each_cpu(cpu, offlined_cpus) {
+		int ret = cpu_up(cpu);
+
+		if (ret != 0) {
+			pr_err("Error occurred (%d) while trying "
+			       "to power up CPU %d\n", ret, cpu);
+			++err;
+		} else {
+			cpumask_clear_cpu(cpu, offlined_cpus);
+		}
+	}
+
+	/*
+	 * Something went bad at some point and some CPUs could not be turned
+	 * back on.
+	 */
+	WARN_ON(!cpumask_empty(offlined_cpus) ||
+		num_online_cpus() != nb_available_cpus);
+
+	return err;
+}
+
+static int hotplug_tests(void)
+{
+	int err;
+	cpumask_var_t offlined_cpus;
+	int i, nb_cluster;
+	const struct cpumask **clusters;
+	char *page_buf;
+
+	err = -ENOMEM;
+	if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
+		return err;
+	/* We may have up to nb_available_cpus clusters. */
+	clusters = kmalloc_array(nb_available_cpus, sizeof(*clusters),
+				 GFP_KERNEL);
+	if (!clusters)
+		goto out_free_cpus;
+	page_buf = (char *)__get_free_page(GFP_KERNEL);
+	if (!page_buf)
+		goto out_free_clusters;
+
+	err = 0;
+	nb_cluster = find_clusters(cpu_online_mask, clusters);
+
+	/*
+	 * Of course the last CPU cannot be powered down and cpu_down() should
+	 * refuse doing that.
+	 */
+	pr_info("Trying to turn off and on again all CPUs\n");
+	err += down_and_up_cpus(cpu_online_mask, offlined_cpus);
+
+	/*
+	 * Take down CPUs by cluster this time. When the last CPU is turned
+	 * off, the cluster itself should shut down.
+	 */
+	for (i = 0; i < nb_cluster; ++i) {
+		int cluster_id =
+			topology_physical_package_id(cpumask_any(clusters[i]));
+		ssize_t len = cpumap_print_to_pagebuf(true, page_buf,
+						      clusters[i]);
+		/* Remove trailing newline. */
+		page_buf[len - 1] = '\0';
+		pr_info("Trying to turn off and on again cluster %d "
+			"(CPUs %s)\n", cluster_id, page_buf);
+		err += down_and_up_cpus(clusters[i], offlined_cpus);
+	}
+
+	free_page((unsigned long)page_buf);
+out_free_clusters:
+	kfree(clusters);
+out_free_cpus:
+	free_cpumask_var(offlined_cpus);
+	return err;
+}
+
+static void dummy_callback(unsigned long ignored) {}
+
+static int suspend_cpu(int index, bool broadcast)
+{
+	int ret;
+
+	arch_cpu_idle_enter();
+
+	if (broadcast) {
+		/*
+		 * The local timer will be shut down, we need to enter tick
+		 * broadcast.
+		 */
+		ret = tick_broadcast_enter();
+		if (ret) {
+			/*
+			 * In the absence of hardware broadcast mechanism,
+			 * this CPU might be used to broadcast wakeups, which
+			 * may be why entering tick broadcast has failed.
+			 * There is little the kernel can do to work around
+			 * that, so enter WFI instead (idle state 0).
+			 */
+			cpu_do_idle();
+			ret = 0;
+			goto out_arch_exit;
+		}
+	}
+
+	/*
+	 * Replicate the common ARM cpuidle enter function
+	 * (arm_enter_idle_state).
+	 */
+	ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);
+
+	if (broadcast)
+		tick_broadcast_exit();
+
+out_arch_exit:
+	arch_cpu_idle_exit();
+
+	return ret;
+}
+
+static int suspend_test_thread(void *arg)
+{
+	int cpu = (long)arg;
+	int i, nb_suspend = 0, nb_shallow_sleep = 0, nb_err = 0;
+	struct sched_param sched_priority = { .sched_priority = MAX_RT_PRIO-1 };
+	struct cpuidle_device *dev;
+	struct cpuidle_driver *drv;
+	/* No need for an actual callback, we just want to wake up the CPU. */
+	struct timer_list wakeup_timer =
+		TIMER_INITIALIZER(dummy_callback, 0, 0);
+
+	/* Wait for the main thread to give the start signal. */
+	wait_for_completion(&suspend_threads_started);
+
+	/* Set maximum priority to preempt all other threads on this CPU. */
+	if (sched_setscheduler_nocheck(current, SCHED_FIFO, &sched_priority))
+		pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
+			cpu);
+
+	dev = this_cpu_read(cpuidle_devices);
+	drv = cpuidle_get_cpu_driver(dev);
+
+	pr_info("CPU %d entering suspend cycles, states 1 through %d\n",
+		cpu, drv->state_count - 1);
+
+	for (i = 0; i < NUM_SUSPEND_CYCLE; ++i) {
+		int index;
+		/*
+		 * Test all possible states, except 0 (which is usually WFI and
+		 * doesn't use PSCI).
+		 */
+		for (index = 1; index < drv->state_count; ++index) {
+			struct cpuidle_state *state = &drv->states[index];
+			bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
+			int ret;
+
+			/*
+			 * Set the timer to wake this CPU up in some time (which
+			 * should be largely sufficient for entering suspend).
+			 * If the local tick is disabled when entering suspend,
+			 * suspend_cpu() takes care of switching to a broadcast
+			 * tick, so the timer will still wake us up.
+			 */
+			mod_timer(&wakeup_timer, jiffies +
+				  usecs_to_jiffies(state->target_residency));
+
+			/* IRQs must be disabled during suspend operations. */
+			local_irq_disable();
+
+			ret = suspend_cpu(index, broadcast);
+
+			/*
+			 * We have woken up. Re-enable IRQs to handle any
+			 * pending interrupt, do not wait until the end of the
+			 * loop.
+			 */
+			local_irq_enable();
+
+			if (ret == index) {
+				++nb_suspend;
+			} else if (ret >= 0) {
+				/* We did not enter the expected state. */
+				++nb_shallow_sleep;
+			} else {
+				pr_err("Failed to suspend CPU %d: error %d "
+				       "(requested state %d, cycle %d)\n",
+				       cpu, ret, index, i);
+				++nb_err;
+			}
+		}
+	}
+
+	/*
+	 * Disable the timer to make sure that the timer will not trigger
+	 * later.
+	 */
+	del_timer(&wakeup_timer);
+
+	if (atomic_dec_return_relaxed(&nb_active_threads) == 0)
+		complete(&suspend_threads_done);
+
+	/* Give up on RT scheduling and wait for termination. */
+	sched_priority.sched_priority = 0;
+	if (sched_setscheduler_nocheck(current, SCHED_NORMAL, &sched_priority))
+		pr_warn("Failed to set suspend thread scheduler on CPU %d\n",
+			cpu);
+	for (;;) {
+		/* Needs to be set first to avoid missing a wakeup. */
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (kthread_should_stop()) {
+			__set_current_state(TASK_RUNNING);
+			break;
+		}
+		schedule();
+	}
+
+	pr_info("CPU %d suspend test results: success %d, shallow states %d, errors %d\n",
+		cpu, nb_suspend, nb_shallow_sleep, nb_err);
+
+	return nb_err;
+}
+
+static int suspend_tests(void)
+{
+	int i, cpu, err = 0;
+	struct task_struct **threads;
+	int nb_threads = 0;
+
+	threads = kmalloc_array(nb_available_cpus, sizeof(*threads),
+				GFP_KERNEL);
+	if (!threads)
+		return -ENOMEM;
+
+	for_each_online_cpu(cpu) {
+		struct task_struct *thread;
+		/* Check that cpuidle is available on that CPU. */
+		struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
+		struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+
+		if (cpuidle_not_available(drv, dev)) {
+			pr_warn("cpuidle not available on CPU %d, ignoring\n",
+				cpu);
+			continue;
+		}
+
+		thread = kthread_create_on_cpu(suspend_test_thread,
+					       (void *)(long)cpu, cpu,
+					       "psci_suspend_test");
+		if (IS_ERR(thread))
+			pr_err("Failed to create kthread on CPU %d\n", cpu);
+		else
+			threads[nb_threads++] = thread;
+	}
+	if (nb_threads < 1) {
+		kfree(threads);
+		return -ENODEV;
+	}
+
+	atomic_set(&nb_active_threads, nb_threads);
+
+	/*
+	 * Stop cpuidle to prevent the idle tasks from entering a deep sleep
+	 * mode, as it might interfere with the suspend threads on other CPUs.
+	 * This does not prevent the suspend threads from using cpuidle (only
+	 * the idle tasks check this status).
+	 */
+	cpuidle_pause();
+
+	/*
+	 * Wake up the suspend threads. To avoid the main thread being preempted
+	 * before all the threads have been unparked, the suspend threads will
+	 * wait for the completion of suspend_threads_started.
+	 */
+	for (i = 0; i < nb_threads; ++i)
+		wake_up_process(threads[i]);
+	complete_all(&suspend_threads_started);
+
+	wait_for_completion(&suspend_threads_done);
+
+	cpuidle_resume();
+
+	/* Stop and destroy all threads, get return status. */
+	for (i = 0; i < nb_threads; ++i)
+		err += kthread_stop(threads[i]);
+
+	kfree(threads);
+	return err;
+}
+
+static int __init psci_checker(void)
+{
+	int ret;
+
+	/*
+	 * Since we're in an initcall, we assume that all the CPUs that all
+	 * CPUs that can be onlined have been onlined.
+	 *
+	 * The tests assume that hotplug is enabled but nobody else is using it,
+	 * otherwise the results will be unpredictable. However, since there
+	 * is no userspace yet in initcalls, that should be fine, as long as
+	 * no torture test is running@the same time (see Kconfig).
+	 */
+	nb_available_cpus = num_online_cpus();
+
+	/* Check PSCI operations are set up and working. */
+	ret = psci_ops_check();
+	if (ret)
+		return ret;
+
+	pr_info("PSCI checker started using %u CPUs\n", nb_available_cpus);
+
+	pr_info("Starting hotplug tests\n");
+	ret = hotplug_tests();
+	if (ret == 0)
+		pr_info("Hotplug tests passed OK\n");
+	else if (ret > 0)
+		pr_err("%d error(s) encountered in hotplug tests\n", ret);
+	else {
+		pr_err("Out of memory\n");
+		return ret;
+	}
+
+	pr_info("Starting suspend tests (%d cycles per state)\n",
+		NUM_SUSPEND_CYCLE);
+	ret = suspend_tests();
+	if (ret == 0)
+		pr_info("Suspend tests passed OK\n");
+	else if (ret > 0)
+		pr_err("%d error(s) encountered in suspend tests\n", ret);
+	else {
+		switch (ret) {
+		case -ENOMEM:
+			pr_err("Out of memory\n");
+			break;
+		case -ENODEV:
+			pr_warn("Could not start suspend tests on any CPU\n");
+			break;
+		}
+	}
+
+	pr_info("PSCI checker completed\n");
+	return ret < 0 ? ret : 0;
+}
+late_initcall(psci_checker);
-- 
2.10.0

^ permalink raw reply related

* [PATCH] KVM: arm/arm64: vgic: Prevent access to invalid SPIs
From: Marc Zyngier @ 2016-10-28 10:28 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andre Przywara <andre.przywara@arm.com>

In our VGIC implementation we limit the number of SPIs to a number
that the userland application told us. Accordingly we limit the
allocation of memory for virtual IRQs to that number.
However in our MMIO dispatcher we didn't check if we ever access an
IRQ beyond that limit, leading to out-of-bound accesses.
Add a test against the number of allocated SPIs in check_region().

[maz: cleaned-up original patch]

Cc: stable at vger.kernel.org
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-mmio.c | 41 +++++++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index e18b30d..ebe1b9f 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -453,17 +453,33 @@ struct vgic_io_device *kvm_to_vgic_iodev(const struct kvm_io_device *dev)
 	return container_of(dev, struct vgic_io_device, dev);
 }
 
-static bool check_region(const struct vgic_register_region *region,
+static bool check_region(const struct kvm *kvm,
+			 const struct vgic_register_region *region,
 			 gpa_t addr, int len)
 {
-	if ((region->access_flags & VGIC_ACCESS_8bit) && len == 1)
-		return true;
-	if ((region->access_flags & VGIC_ACCESS_32bit) &&
-	    len == sizeof(u32) && !(addr & 3))
-		return true;
-	if ((region->access_flags & VGIC_ACCESS_64bit) &&
-	    len == sizeof(u64) && !(addr & 7))
-		return true;
+	int flags, nr_irqs = kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
+
+	switch (len) {
+	case sizeof(u8):
+		flags = VGIC_ACCESS_8bit;
+		break;
+	case sizeof(u32):
+		flags = VGIC_ACCESS_32bit;
+		break;
+	case sizeof(u64):
+		flags = VGIC_ACCESS_64bit;
+		break;
+	default:
+		return false;
+	}
+
+	if ((region->access_flags & flags) && IS_ALIGNED(addr, len)) {
+		if (!region->bits_per_irq)
+			return true;
+
+		/* Do we access a non-allocated IRQ? */
+		return VGIC_ADDR_TO_INTID(addr, region->bits_per_irq) < nr_irqs;
+	}
 
 	return false;
 }
@@ -477,7 +493,7 @@ static int dispatch_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
 
 	region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
 				       addr - iodev->base_addr);
-	if (!region || !check_region(region, addr, len)) {
+	if (!region || !check_region(vcpu->kvm, region, addr, len)) {
 		memset(val, 0, len);
 		return 0;
 	}
@@ -510,10 +526,7 @@ static int dispatch_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
 
 	region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
 				       addr - iodev->base_addr);
-	if (!region)
-		return 0;
-
-	if (!check_region(region, addr, len))
+	if (!region || !check_region(vcpu->kvm, region, addr, len))
 		return 0;
 
 	switch (iodev->iodev_type) {
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2] arm/arm64: KVM: Perform local TLB invalidation when multiplexing vcpus on a single CPU
From: Marc Zyngier @ 2016-10-28 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

Architecturally, TLBs are private to the (physical) CPU they're
associated with. But when multiple vcpus from the same VM are
being multiplexed on the same CPU, the TLBs are not private
to the vcpus (and are actually shared across the VMID).

Let's consider the following scenario:

- vcpu-0 maps PA to VA
- vcpu-1 maps PA' to VA

If run on the same physical CPU, vcpu-1 can hit TLB entries generated
by vcpu-0 accesses, and access the wrong physical page.

The solution to this is to keep a per-VM map of which vcpu ran last
on each given physical CPU, and invalidate local TLBs when switching
to a different vcpu from the same VM.

Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
Fixed comments, added Mark's RB.

 arch/arm/include/asm/kvm_host.h   | 11 ++++++++++-
 arch/arm/include/asm/kvm_hyp.h    |  1 +
 arch/arm/kvm/arm.c                | 35 ++++++++++++++++++++++++++++++++++-
 arch/arm/kvm/hyp/switch.c         |  9 +++++++++
 arch/arm64/include/asm/kvm_host.h | 11 ++++++++++-
 arch/arm64/kvm/hyp/switch.c       |  8 ++++++++
 6 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 2d19e02..7290de6 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -57,6 +57,9 @@ struct kvm_arch {
 	/* VTTBR value associated with below pgd and vmid */
 	u64    vttbr;
 
+	/* The last vcpu id that ran on each physical CPU */
+	int __percpu *last_vcpu_ran;
+
 	/* Timer */
 	struct arch_timer_kvm	timer;
 
@@ -174,6 +177,13 @@ struct kvm_vcpu_arch {
 	/* vcpu power-off state */
 	bool power_off;
 
+	/*
+	 * Local TLBs potentially contain conflicting entries from
+	 * another vCPU within this VMID. All entries for this VMID must
+	 * be invalidated from (local) TLBs before we run this vCPU.
+	 */
+	bool tlb_vmid_stale;
+
 	 /* Don't run the guest (internal implementation need) */
 	bool pause;
 
@@ -292,7 +302,6 @@ struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
-static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
 
 static inline void kvm_arm_init_debug(void) {}
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
index 343135e..5850890 100644
--- a/arch/arm/include/asm/kvm_hyp.h
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -71,6 +71,7 @@
 #define ICIALLUIS	__ACCESS_CP15(c7, 0, c1, 0)
 #define ATS1CPR		__ACCESS_CP15(c7, 0, c8, 0)
 #define TLBIALLIS	__ACCESS_CP15(c8, 0, c3, 0)
+#define TLBIALL		__ACCESS_CP15(c8, 0, c7, 0)
 #define TLBIALLNSNHIS	__ACCESS_CP15(c8, 4, c3, 4)
 #define PRRR		__ACCESS_CP15(c10, 0, c2, 0)
 #define NMRR		__ACCESS_CP15(c10, 0, c2, 1)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 08bb84f..e0d93cd 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -114,11 +114,18 @@ void kvm_arch_check_processor_compat(void *rtn)
  */
 int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 {
-	int ret = 0;
+	int ret, cpu;
 
 	if (type)
 		return -EINVAL;
 
+	kvm->arch.last_vcpu_ran = alloc_percpu(typeof(*kvm->arch.last_vcpu_ran));
+	if (!kvm->arch.last_vcpu_ran)
+		return -ENOMEM;
+
+	for_each_possible_cpu(cpu)
+		*per_cpu_ptr(kvm->arch.last_vcpu_ran, cpu) = -1;
+
 	ret = kvm_alloc_stage2_pgd(kvm);
 	if (ret)
 		goto out_fail_alloc;
@@ -141,6 +148,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 out_free_stage2_pgd:
 	kvm_free_stage2_pgd(kvm);
 out_fail_alloc:
+	free_percpu(kvm->arch.last_vcpu_ran);
+	kvm->arch.last_vcpu_ran = NULL;
 	return ret;
 }
 
@@ -168,6 +177,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 {
 	int i;
 
+	free_percpu(kvm->arch.last_vcpu_ran);
+	kvm->arch.last_vcpu_ran = NULL;
+
 	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
 		if (kvm->vcpus[i]) {
 			kvm_arch_vcpu_free(kvm->vcpus[i]);
@@ -310,6 +322,27 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu)
+{
+	int *last_ran;
+
+	last_ran = per_cpu_ptr(vcpu->kvm->arch.last_vcpu_ran, cpu);
+
+	/*
+	 * We might get preempted before the vCPU actually runs, but
+	 * this is fine. Our TLBI stays pending until we actually make
+	 * it to __activate_vm, so we won't miss a TLBI. If another
+	 * vCPU gets scheduled, it will see our vcpu_id in last_ran,
+	 * and pend a TLBI for itself.
+	 */
+	if (*last_ran != vcpu->vcpu_id) {
+		if (*last_ran != -1)
+			vcpu->arch.tlb_vmid_stale = true;
+
+		*last_ran = vcpu->vcpu_id;
+	}
+}
+
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	vcpu->cpu = cpu;
diff --git a/arch/arm/kvm/hyp/switch.c b/arch/arm/kvm/hyp/switch.c
index 92678b7..a411762 100644
--- a/arch/arm/kvm/hyp/switch.c
+++ b/arch/arm/kvm/hyp/switch.c
@@ -75,6 +75,15 @@ static void __hyp_text __activate_vm(struct kvm_vcpu *vcpu)
 {
 	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
 	write_sysreg(kvm->arch.vttbr, VTTBR);
+	if (vcpu->arch.tlb_vmid_stale) {
+		/* Force vttbr to be written */
+		isb();
+		/* Local invalidate only for this VMID */
+		write_sysreg(0, TLBIALL);
+		dsb(nsh);
+		vcpu->arch.tlb_vmid_stale = false;
+	}
+
 	write_sysreg(vcpu->arch.midr, VPIDR);
 }
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index bd94e67..0f62829 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -62,6 +62,9 @@ struct kvm_arch {
 	/* VTTBR value associated with above pgd and vmid */
 	u64    vttbr;
 
+	/* The last vcpu id that ran on each physical CPU */
+	int __percpu *last_vcpu_ran;
+
 	/* The maximum number of vCPUs depends on the used GIC model */
 	int max_vcpus;
 
@@ -252,6 +255,13 @@ struct kvm_vcpu_arch {
 	/* vcpu power-off state */
 	bool power_off;
 
+	/*
+	 * Local TLBs potentially contain conflicting entries from
+	 * another vCPU within this VMID. All entries for this VMID must
+	 * be invalidated from (local) TLBs before we run this vCPU.
+	 */
+	bool tlb_vmid_stale;
+
 	/* Don't run the guest (internal implementation need) */
 	bool pause;
 
@@ -368,7 +378,6 @@ static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
-static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
 
 void kvm_arm_init_debug(void);
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 83037cd..99d0f33 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -131,6 +131,14 @@ static void __hyp_text __activate_vm(struct kvm_vcpu *vcpu)
 {
 	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
 	write_sysreg(kvm->arch.vttbr, vttbr_el2);
+	if (vcpu->arch.tlb_vmid_stale) {
+		/* Force vttbr_el2 to be written */
+		isb();
+		/* Local invalidate only for this VMID */
+		asm volatile("tlbi vmalle1" : : );
+		dsb(nsh);
+		vcpu->arch.tlb_vmid_stale = false;
+	}
 }
 
 static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
-- 
2.1.4

^ permalink raw reply related

* [PATCH v3 1/3] powerpc/reloc32: fix corrupted modversion CRCs
From: Suzuki K Poulose @ 2016-10-28 10:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477585631-18574-2-git-send-email-ard.biesheuvel@linaro.org>

On 27/10/16 17:27, Ard Biesheuvel wrote:
> Commit 0e0ed6406e61 ("powerpc/modules: Module CRC relocation fix causes
> perf issues") fixed an issue with relocatable PIE kernels in a way that
> essentially reintroduced the issue again for 32-bit builds.
>
> Since the chosen approach does is not applicable to 32-bit, fix the
> issue by updating the runtime relocation routine to ignore the load
> offset for the interval [__start___kcrctab, __stop___kcrctab_gpl_future),
> which is where the CRCs reside. This ensures that the values of the CRC
> pseudo-symbols are no longer made dependent on the runtime load offset.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Ard,

These changes look good to me (having originally written the code).

Reviewed-by : Suzuki K Poulose <suzuki.poulose@arm.com>

Cheers
Suzuki

> ---
>  arch/powerpc/kernel/reloc_32.S | 36 +++++++++++++++++---
>  1 file changed, 32 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/kernel/reloc_32.S b/arch/powerpc/kernel/reloc_32.S
> index f366fedb0872..150686b9febb 100644
> --- a/arch/powerpc/kernel/reloc_32.S
> +++ b/arch/powerpc/kernel/reloc_32.S
> @@ -87,12 +87,12 @@ eodyn:				/* End of Dyn Table scan */
>  	 * Work out the current offset from the link time address of .rela
>  	 * section.
>  	 *  cur_offset[r7] = rela.run[r9] - rela.link [r7]
> -	 *  _stext.link[r12] = _stext.run[r10] - cur_offset[r7]
> -	 *  final_offset[r3] = _stext.final[r3] - _stext.link[r12]
> +	 *  _stext.link[r11] = _stext.run[r10] - cur_offset[r7]
> +	 *  final_offset[r3] = _stext.final[r3] - _stext.link[r11]
>  	 */
>  	subf	r7, r7, r9	/* cur_offset */
> -	subf	r12, r7, r10
> -	subf	r3, r12, r3	/* final_offset */
> +	subf	r11, r7, r10
> +	subf	r3, r11, r3	/* final_offset */
>
>  	subf	r8, r6, r8	/* relaz -= relaent */
>  	/*
> @@ -101,6 +101,21 @@ eodyn:				/* End of Dyn Table scan */
>  	 * r13	- points to the symbol table
>  	 */
>
> +#ifdef CONFIG_MODVERSIONS
> +	/*
> +	 * Treat R_PPC_RELATIVE relocations differently when they target the
> +	 * interval [__start___kcrctab, __stop___kcrctab_gpl_future): in this
> +	 * case, the relocated quantities are CRC pseudo-symbols, which should
> +	 * be preserved as-is, rather than be modified to take the runtime
> +	 * offset into account.
> +	 */
> +	lwz	r10, (p_kcrc_start - 0b)(r12)
> +	lwz	r11, (p_kcrc_stop - 0b)(r12)
> +	subf	r12, r7, r12			/* link time addr of 0b */
> +	add	r10, r10, r12
> +	add	r11, r11, r12
> +#endif
> +
>  	/*
>  	 * Check if we have a relocation based on symbol
>  	 * r5 will hold the value of the symbol.
> @@ -135,7 +150,15 @@ get_type:
>  	bne	hi16
>  	lwz	r4, 0(r9)	/* r_offset */
>  	lwz	r0, 8(r9)	/* r_addend */
> +#ifdef CONFIG_MODVERSIONS
> +	cmplw	r4, r10
> +	blt	do_add
> +	cmplw	r4, r11
> +	blt	skip_add
> +do_add:
> +#endif
>  	add	r0, r0, r3	/* final addend */
> +skip_add:
>  	stwx	r0, r4, r7	/* memory[r4+r7]) = (u32)r0 */
>  	b	nxtrela		/* continue */
>
> @@ -207,3 +230,8 @@ p_dyn:		.long	__dynamic_start - 0b
>  p_rela:		.long	__rela_dyn_start - 0b
>  p_sym:		.long	__dynamic_symtab - 0b
>  p_st:		.long	_stext - 0b
> +
> +#ifdef CONFIG_MODVERSIONS
> +p_kcrc_start:	.long	__start___kcrctab - 0b
> +p_kcrc_stop:	.long	__stop___kcrctab_gpl_future - 0b
> +#endif
>

^ permalink raw reply

* [RFC PATCH v2 4/8] arm64: compat: Add a 32-bit vDSO
From: Kevin Brodsky @ 2016-10-28 10:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161028110926.0176e0ea@xhacker>

On 28/10/16 04:09, Jisheng Zhang wrote:
> Dear Kevin,
>
> On Thu, 27 Oct 2016 17:30:54 +0100 Kevin Brodsky wrote:
>
>> Provide the files necessary for building a compat (AArch32) vDSO in
>> kernel/vdso32.
>>
>> This is mostly an adaptation of the arm vDSO. The most significant
>> change in vgettimeofday.c is the use of the arm64 vdso_data struct,
>> allowing the vDSO data page to be shared between the 32 and 64-bit
>> vDSOs.
>>
>> In addition to the time functions, sigreturn trampolines are also
>> provided, aiming at replacing those in the vector page. To improve
>> debugging, CFI and unwinding directives are used, based on glibc's
>> implementation. Symbol offsets are made available to the kernel using
>> the same method as the 64-bit vDSO.
>>
>> There is unfortunately an important caveat to all this: we cannot get
>> away with hand-coding 32-bit instructions like in kernel/kuser32.S,
>> this time we really need a 32-bit compiler. The compat vDSO Makefile
>> relies on CROSS_COMPILE_ARM32 to provide a 32-bit compiler,
>> appropriate logic will be added to the arm64 Makefile later on to
>> ensure that an attempt to build the compat vDSO is made only if this
>> variable has been set properly.
>>
>> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> ---
>>   arch/arm64/kernel/vdso32/Makefile        | 121 +++++++++++++
>>   arch/arm64/kernel/vdso32/sigreturn.S     |  86 +++++++++
>>   arch/arm64/kernel/vdso32/vdso.S          |  32 ++++
>>   arch/arm64/kernel/vdso32/vdso.lds.S      |  98 +++++++++++
>>   arch/arm64/kernel/vdso32/vgettimeofday.c | 294 +++++++++++++++++++++++++++++++
>>   5 files changed, 631 insertions(+)
>>   create mode 100644 arch/arm64/kernel/vdso32/Makefile
>>   create mode 100644 arch/arm64/kernel/vdso32/sigreturn.S
>>   create mode 100644 arch/arm64/kernel/vdso32/vdso.S
>>   create mode 100644 arch/arm64/kernel/vdso32/vdso.lds.S
>>   create mode 100644 arch/arm64/kernel/vdso32/vgettimeofday.c
>>
>> diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
>> new file mode 100644
>> index 000000000000..38facc870f6e
>> --- /dev/null
>> +++ b/arch/arm64/kernel/vdso32/Makefile
>> @@ -0,0 +1,121 @@
>> +#
>> +# Building a vDSO image for AArch32.
>> +#
>> +# Author: Kevin Brodsky <kevin.brodsky@arm.com>
>> +# A mix between the arm64 and arm vDSO Makefiles.
>> +
>> +CC_ARM32 := $(CROSS_COMPILE_ARM32)gcc
>> +
>> +# Same as cc-ldoption, but using CC_ARM32 instead of CC
>> +cc32-ldoption = $(call try-run,\
>> +        $(CC_ARM32) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
>> +
>> +# Borrow vdsomunge.c from the arm vDSO
>> +munge := arch/arm/vdso/vdsomunge
>> +hostprogs-y := $(srctree)/$(munge)
>> +
>> +c-obj-vdso := vgettimeofday.o
>> +asm-obj-vdso := sigreturn.o
>> +
>> +# Build rules
>> +targets := $(c-obj-vdso) $(asm-obj-vdso) vdso.so vdso.so.dbg vdso.so.raw
>> +c-obj-vdso := $(addprefix $(obj)/, $(c-obj-vdso))
>> +asm-obj-vdso := $(addprefix $(obj)/, $(asm-obj-vdso))
>> +obj-vdso := $(c-obj-vdso) $(asm-obj-vdso)
>> +
>> +ccflags-y := -fPIC -fno-common -fno-builtin -fno-stack-protector
>> +ccflags-y += -DDISABLE_BRANCH_PROFILING
>> +
>> +# Force -O2 to avoid libgcc dependencies
>> +VDSO_CFLAGS := -march=armv8-a -O2
> For completeness, bringing 32bit compiler need to check whether the 32bit
> toolchain support some options. IIRC, armv8-a support isn't enabled until
> gcc 4.8, so old toolchains such gcc-4.7 will complain:
>   error: unrecognized argument in option ?-march=armv8-a?
>
> Thanks,
> Jisheng

That's a fair point. I guess -march=armv8-a is not strictly necessary and the 
produced vDSO should be fine if arch/arm/vdso also compiles fine. However we would 
still need to pass -march=armv7-a. I'm not sure what to do between:
* Checking that the compiler supports -march=armv8-a when inspecting 
CROSS_COMPILE_ARM32, and if it doesn't vdso32 will not be built.
* Checking whether -march=armv8-a is available here, and if it is not fall back to 
-march=armv7-a.

Thanks!
Kevin

^ permalink raw reply

* [PATCH v12 RESEND 4/4] Documentation: tee subsystem and op-tee driver
From: Jens Wiklander @ 2016-10-28 10:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477649984-16777-1-git-send-email-jens.wiklander@linaro.org>

Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
---
 Documentation/00-INDEX |   2 +
 Documentation/tee.txt  | 118 +++++++++++++++++++++++++++++++++++++++++++++++++
 MAINTAINERS            |   1 +
 3 files changed, 121 insertions(+)
 create mode 100644 Documentation/tee.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 3acc4f1..4a5a887 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -436,6 +436,8 @@ sysrq.txt
 	- info on the magic SysRq key.
 target/
 	- directory with info on generating TCM v4 fabric .ko modules
+tee.txt
+	- info on the TEE subsystem and drivers
 this_cpu_ops.txt
 	- List rationale behind and the way to use this_cpu operations.
 thermal/
diff --git a/Documentation/tee.txt b/Documentation/tee.txt
new file mode 100644
index 0000000..7185993
--- /dev/null
+++ b/Documentation/tee.txt
@@ -0,0 +1,118 @@
+TEE subsystem
+This document describes the TEE subsystem in Linux.
+
+A TEE (Trusted Execution Environment) is a trusted OS running in some
+secure environment, for example, TrustZone on ARM CPUs, or a separate
+secure co-processor etc. A TEE driver handles the details needed to
+communicate with the TEE.
+
+This subsystem deals with:
+
+- Registration of TEE drivers
+
+- Managing shared memory between Linux and the TEE
+
+- Providing a generic API to the TEE
+
+The TEE interface
+=================
+
+include/uapi/linux/tee.h defines the generic interface to a TEE.
+
+User space (the client) connects to the driver by opening /dev/tee[0-9]* or
+/dev/teepriv[0-9]*.
+
+- TEE_IOC_SHM_ALLOC allocates shared memory and returns a file descriptor
+  which user space can mmap. When user space doesn't need the file
+  descriptor any more, it should be closed. When shared memory isn't needed
+  any longer it should be unmapped with munmap() to allow the reuse of
+  memory.
+
+- TEE_IOC_VERSION lets user space know which TEE this driver handles and
+  the its capabilities.
+
+- TEE_IOC_OPEN_SESSION opens a new session to a Trusted Application.
+
+- TEE_IOC_INVOKE invokes a function in a Trusted Application.
+
+- TEE_IOC_CANCEL may cancel an ongoing TEE_IOC_OPEN_SESSION or TEE_IOC_INVOKE.
+
+- TEE_IOC_CLOSE_SESSION closes a session to a Trusted Application.
+
+There are two classes of clients, normal clients and supplicants. The latter is
+a helper process for the TEE to access resources in Linux, for example file
+system access. A normal client opens /dev/tee[0-9]* and a supplicant opens
+/dev/teepriv[0-9].
+
+Much of the communication between clients and the TEE is opaque to the
+driver. The main job for the driver is to receive requests from the
+clients, forward them to the TEE and send back the results. In the case of
+supplicants the communication goes in the other direction, the TEE sends
+requests to the supplicant which then sends back the result.
+
+OP-TEE driver
+=============
+
+The OP-TEE driver handles OP-TEE [1] based TEEs. Currently it is only the ARM
+TrustZone based OP-TEE solution that is supported.
+
+Lowest level of communication with OP-TEE builds on ARM SMC Calling
+Convention (SMCCC) [2], which is the foundation for OP-TEE's SMC interface
+[3] used internally by the driver. Stacked on top of that is OP-TEE Message
+Protocol [4].
+
+OP-TEE SMC interface provides the basic functions required by SMCCC and some
+additional functions specific for OP-TEE. The most interesting functions are:
+
+- OPTEE_SMC_FUNCID_CALLS_UID (part of SMCCC) returns the version information
+  which is then returned by TEE_IOC_VERSION
+
+- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
+  to tell, for instance, a TrustZone OP-TEE apart from an OP-TEE running on a
+  separate secure co-processor.
+
+- OPTEE_SMC_CALL_WITH_ARG drives the OP-TEE message protocol
+
+- OPTEE_SMC_GET_SHM_CONFIG lets the driver and OP-TEE agree on which memory
+  range to used for shared memory between Linux and OP-TEE.
+
+The GlobalPlatform TEE Client API [5] is implemented on top of the generic
+TEE API.
+
+Picture of the relationship between the different components in the
+OP-TEE architecture.
+
+    User space                  Kernel                   Secure world
+    ~~~~~~~~~~                  ~~~~~~                   ~~~~~~~~~~~~
+ +--------+                                             +-------------+
+ | Client |                                             | Trusted     |
+ +--------+                                             | Application |
+    /\                                                  +-------------+
+    || +----------+                                           /\
+    || |tee-      |                                           ||
+    || |supplicant|                                           \/
+    || +----------+                                     +-------------+
+    \/      /\                                          | TEE Internal|
+ +-------+  ||                                          | API         |
+ + TEE   |  ||            +--------+--------+           +-------------+
+ | Client|  ||            | TEE    | OP-TEE |           | OP-TEE      |
+ | API   |  \/            | subsys | driver |           | Trusted OS  |
+ +-------+----------------+----+-------+----+-----------+-------------+
+ |      Generic TEE API        |       |     OP-TEE MSG               |
+ |      IOCTL (TEE_IOC_*)      |       |     SMCCC (OPTEE_SMC_CALL_*) |
+ +-----------------------------+       +------------------------------+
+
+RPC (Remote Procedure Call) are requests from secure world to kernel driver
+or tee-supplicant. An RPC is identified by a special range of SMCCC return
+values from OPTEE_SMC_CALL_WITH_ARG. RPC messages which are intended for the
+kernel are handled by the kernel driver. Other RPC messages will be forwarded to
+tee-supplicant without further involvement of the driver, except switching
+shared memory buffer representation.
+
+References:
+[1] https://github.com/OP-TEE/optee_os
+[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+[3] drivers/tee/optee/optee_smc.h
+[4] drivers/tee/optee/optee_msg.h
+[5] http://www.globalplatform.org/specificationsdevice.asp look for
+    "TEE Client API Specification v1.0" and click download.
diff --git a/MAINTAINERS b/MAINTAINERS
index 8130af1..76e3a28 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10645,6 +10645,7 @@ S:	Maintained
 F:	include/linux/tee_drv.h
 F:	include/uapi/linux/tee.h
 F:	drivers/tee/
+F:	Documentation/tee.txt
 
 THUNDERBOLT DRIVER
 M:	Andreas Noever <andreas.noever@gmail.com>
-- 
1.9.1

^ 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