Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: dts: imx: Pass an empty 'chosen' node
From: Uwe Kleine-König @ 2016-12-19 21:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOMZO5Be3f4YmGO0FJbeGZO55CJd9P9QO28SfhPLYuivtSHk7w@mail.gmail.com>

On Mon, Dec 19, 2016 at 07:30:25PM -0200, Fabio Estevam wrote:
> Hi Uwe,
> 
> On Mon, Dec 19, 2016 at 4:41 PM, Uwe Kleine-K?nig
> <u.kleine-koenig@pengutronix.de> wrote:
> 
> > wouldn't it be better to fix the decompressor code to eventually create
> > the /chosen node when it doesn't exist?
> 
> Thanks for the suggestion.
> 
> I don't have a Barebox setup handy, but would the following change fix
> it as you propose?
> 
> --- a/arch/arm/boot/compressed/atags_to_fdt.c
> +++ b/arch/arm/boot/compressed/atags_to_fdt.c
> @@ -66,13 +66,21 @@ static uint32_t get_cell_size(const void *fdt)
>         return cell_size;
>  }
> 
> -static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
> +static int merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
>  {
>         char cmdline[COMMAND_LINE_SIZE];
>         const char *fdt_bootargs;
>         char *ptr = cmdline;
> +       int chosen_off;
>         int len = 0;
> 
> +       /* find or add chosen node */
> +       chosen_off = fdt_path_offset(fdt, "/chosen");
> +       if (chosen_off == -FDT_ERR_NOTFOUND)
> +               chosen_off = fdt_add_subnode(fdt, 0, "chosen");
> +       if (chosen_off < 0)
> +               return chosen_off;

I would have done:

	ret = fdt_add_subnode(fdt, 0, "chosen")
	if (ret < 0 && ret != -FDT_ERR_EXISTS)
		return -ESOMETHING;

but I don't have the right machine@hand. Will check tomorrow.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* [PATCH] ARM: dts: imx: Pass an empty 'chosen' node
From: Javier Martinez Canillas @ 2016-12-19 21:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOMZO5Be3f4YmGO0FJbeGZO55CJd9P9QO28SfhPLYuivtSHk7w@mail.gmail.com>

[adding Pali who first reported this issue]

Hello Pali,

On 12/19/2016 06:30 PM, Fabio Estevam wrote:
> Hi Uwe,
> 
> On Mon, Dec 19, 2016 at 4:41 PM, Uwe Kleine-K?nig
> <u.kleine-koenig@pengutronix.de> wrote:
> 
>> wouldn't it be better to fix the decompressor code to eventually create
>> the /chosen node when it doesn't exist?
>
> Thanks for the suggestion.
> 
> I don't have a Barebox setup handy, but would the following change fix
> it as you propose?
>

Could you test Fabio's patch with NoLo to see if it fixes your issue?

I also think it makes more sense for Linux to create the "chosen" node
if not present since this is a requirement due a Linux implementation
detail.

Forcing to have a "chosen" node in dts leaks this implementation detail
since the ePAPR document says that the "chosen" node should be optional.
 
> --- a/arch/arm/boot/compressed/atags_to_fdt.c
> +++ b/arch/arm/boot/compressed/atags_to_fdt.c
> @@ -66,13 +66,21 @@ static uint32_t get_cell_size(const void *fdt)
>         return cell_size;
>  }
> 
> -static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
> +static int merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
>  {
>         char cmdline[COMMAND_LINE_SIZE];
>         const char *fdt_bootargs;
>         char *ptr = cmdline;
> +       int chosen_off;
>         int len = 0;
> 
> +       /* find or add chosen node */
> +       chosen_off = fdt_path_offset(fdt, "/chosen");
> +       if (chosen_off == -FDT_ERR_NOTFOUND)
> +               chosen_off = fdt_add_subnode(fdt, 0, "chosen");
> +       if (chosen_off < 0)
> +               return chosen_off;
> +
>         /* copy the fdt command line into the buffer */
>         fdt_bootargs = getprop(fdt, "/chosen", "bootargs", &len);
>         if (fdt_bootargs)
> 

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America

^ permalink raw reply

* [PATCH v2] efi/libstub: arm*: Pass latest memory map to the kernel
From: Matt Fleming @ 2016-12-19 21:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161219142419.16780-1-james.morse@arm.com>

On Mon, 19 Dec, at 02:24:19PM, James Morse wrote:
> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> 
> As reported by James, the current libstub code involving the annotated
> memory map only works somewhat correctly by accident, due to the fact
> that a pool allocation happens to be reused immediately, retaining its
> former contents.
> 
> Instead of juggling memory maps, which makes the code more complex than
> it needs to be, simply put a placholder value into the FDT, and only
> write the actual value after ExitBootServices() has been called.
> 
> Reported-by: James Morse <james.morse@arm.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> [Update mmap-size too, remove updated_fdt()s unused params and header entry]
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
> Hi Ard,
> 
> This is a v2 of your patch that updates the mmap-size too. This solves the
> truncated memmap problem I saw with v1 on Seattle.
> 
> The original patch was CC-stable, so I think this should also have:
> Cc: <stable@vger.kernel.org>
> Fixes: ed9cc156c42f ("efi/libstub: Use efi_exit_boot_services() in FDT")
> 
> 
> Thanks,
> 
> James
> 
>  drivers/firmware/efi/libstub/efistub.h |  8 ----
>  drivers/firmware/efi/libstub/fdt.c     | 75 +++++++++++++++++++++-------------
>  2 files changed, 47 insertions(+), 36 deletions(-)

Thanks James. I've queued this one up in the 'urgent' queue and tagged
it for stable. I'll send it to tip before the end of the week.

^ permalink raw reply

* [PATCH pci/host-iproc] PCI: iproc: Allow more than slot 0 on PAXC
From: Andy Gospodarek @ 2016-12-19 21:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f370a4d0-c8e8-1c71-8eca-f6ac48eb30d3@broadcom.com>

On Mon, Dec 19, 2016 at 10:54:15AM -0800, Ray Jui wrote:
> 
> 
> On 12/8/2016 1:30 PM, Andy Gospodarek wrote:
> > The iproc host driver limits the number of slots that are available on
> > PAXC devices.  Enforcing this limit prevents VFs from being created
> > beyond the first port.  After this change it is possible to create VFs
> > associated with all four devices.
> > 
> > The first four devices below are the PFs and the next four are the newly
> > created VFs:
> > 
> > 0008:01:00.0 Ethernet controller: Broadcom Limited Device 16cd
> > 0008:01:00.1 Ethernet controller: Broadcom Limited Device 16cd
> > 0008:01:00.2 Ethernet controller: Broadcom Limited Device 16cd
> > 0008:01:00.3 Ethernet controller: Broadcom Limited Device 16cd
> > 0008:01:00.4 Ethernet controller: Broadcom Limited BCM57304 NetXtreme-C Ethernet Virtual Function
> > 0008:01:01.0 Ethernet controller: Broadcom Limited BCM57304 NetXtreme-C Ethernet Virtual Function
> > 0008:01:01.4 Ethernet controller: Broadcom Limited BCM57304 NetXtreme-C Ethernet Virtual Function
> > 0008:01:02.0 Ethernet controller: Broadcom Limited BCM57304 NetXtreme-C Ethernet Virtual Function
> > 
> > Based on the git history around 923c6bb1f641 ("PCI: iproc: Allow multiple
> > devices except on PAXC") and 943ebae781f5 ("PCI: iproc: Add PAXC interface
> > support") I expect there may be an unmentioned or unknown-to-me reason why this
> > code exists.  I certainly cannot create and use VFs without some kind of change
> > around this space, so I would like to see the current limitation simply removed.
> > 
> > Fixes: 923c6bb1f641 ("PCI: iproc: Allow multiple devices except on PAXC")
> 
> > Signed-off-by: Andy Gospodarek <gospo@broadcom.com>
> > ---
> >  drivers/pci/host/pcie-iproc.c | 8 --------
> >  1 file changed, 8 deletions(-)
> > 
> > diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
> > index 3ebc025..9311826 100644
> > --- a/drivers/pci/host/pcie-iproc.c
> > +++ b/drivers/pci/host/pcie-iproc.c
> > @@ -477,14 +477,6 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
> >  			return (pcie->base + offset);
> >  	}
> >  
> > -	/*
> > -	 * PAXC is connected to an internally emulated EP within the SoC.  It
> > -	 * allows only one device.
> > -	 */
> > -	if (pcie->ep_is_internal)
> > -		if (slot > 0)
> > -			return NULL;
> > -
> >  	/* EP device access */
> >  	val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
> >  		(slot << CFG_ADDR_DEV_NUM_SHIFT) |
> > 
> 
> With this change, standard v4.9 kernel would crash on a NS2 SVK with the
> log shown below. This is inline with my previous observation and
> therefore slot number has been limited to only zero for the PAXC
> interface. Does it require more than just this change in order for the
> kernel to boot to complete?
> 
> [    2.190515] OF: PCI: host bridge /pcie at 60c00000 ranges:
> [    2.196400] OF: PCI:   MEM 0x60000000..0x60bfffff -> 0x00000000
> [    2.203135] iproc-pcie 60c00000.pcie: PCI host bridge to bus 0008:00
> [    2.210289] pci_bus 0008:00: root bus resource [bus 00-01]
> [    2.216349] pci_bus 0008:00: root bus resource [mem
> 0x60000000-0x60bfffff] (bus address [0x00000000-0x00bfffff])
> [    2.227769] iproc-pcie 60c00000.pcie: not using iProc MSI
> [    2.234050] pci 0008:00:00.0: bridge configuration invalid ([bus
> 00-00]), reconfiguring
> [    2.244285] Bad mode in Error handler detected on CPU1, code
> 0xbf000002 -- SError
> [    2.252661] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.9.0+ #24
> [    2.259430] Hardware name: Broadcom NS2 SVK (DT)
> [    2.264550] task: ffff8000fb488000 task.stack: ffff8000fb490000
> [    2.271161] PC is at pci_generic_config_read32+0x74/0xa0
> [    2.277043] LR is at pci_generic_config_read32+0x28/0xa0
> [    2.283005] pc : [<ffff00000839d984>] lr : [<ffff00000839d938>]
> pstate: 200000c5
> [    2.291225] sp : ffff8000fb4937f0
> [    2.294937] x29: ffff8000fb4937f0 x28: ffff8000fadb9000
> [    2.300884] x27: ffff8000faf27098 x26: 0000000000000000
> [    2.306803] x25: 0000000000000000 x24: ffff8000fadb9400
> [    2.312757] x23: 0000000000000040 x22: ffff0000089c55d8
> [    2.318730] x21: 0000000000000010 x20: ffff8000fb49391c
> [    2.324666] x19: 0000000000000000 x18: 000000000000077f
> [    2.330594] x17: ffffffffffffffff x16: ffff000008a49fff
> [    2.336539] x15: ffff000008a49fff x14: 0000000000000000
> [    2.342502] x13: 0000000000000007 x12: 0000000000000018
> [    2.348456] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> [    2.354392] x9 : 0000000000000000 x8 : ffff8000fa80e680
> [    2.360355] x7 : 000000000000ffff x6 : ffff8000faf0ca98
> [    2.366300] x5 : 0000000000000002 x4 : ffff8000fb49389c
> [    2.372290] x3 : 0000000000000004 x2 : 0000000000100001
> [    2.378209] x1 : ffff000008a49000 x0 : 0000000000000000
> [    2.384145]
> [    2.385807] Internal error: Oops - bad mode: 0 [#1] PREEMPT SMP
> [    2.392351] Modules linked in:
> [    2.395770] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.9.0+ #24
> [    2.402529] Hardware name: Broadcom NS2 SVK (DT)
> [    2.407693] task: ffff8000fb488000 task.stack: ffff8000fb490000
> [    2.414301] PC is at pci_generic_config_read32+0x74/0xa0
> [    2.420299] LR is at pci_generic_config_read32+0x28/0xa0
> [    2.426279] pc : [<ffff00000839d984>] lr : [<ffff00000839d938>]
> pstate: 200000c5
> [    2.434552] sp : ffff8000fb4937f0
> [    2.438246] x29: ffff8000fb4937f0 x28: ffff8000fadb9000
> [    2.444209] x27: ffff8000faf27098 x26: 0000000000000000
> [    2.450137] x25: 0000000000000000 x24: ffff8000fadb9400
> [    2.456091] x23: 0000000000000040 x22: ffff0000089c55d8
> [    2.462037] x21: 0000000000000010 x20: ffff8000fb49391c
> [    2.467947] x19: 0000000000000000 x18: 000000000000077f
> [    2.473945] x17: ffffffffffffffff x16: ffff000008a49fff
> [    2.479881] x15: ffff000008a49fff x14: 0000000000000000
> [    2.485826] x13: 0000000000000007 x12: 0000000000000018
> [    2.491798] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> [    2.497752] x9 : 0000000000000000 x8 : ffff8000fa80e680
> [    2.503689] x7 : 000000000000ffff x6 : ffff8000faf0ca98
> [    2.509643] x5 : 0000000000000002 x4 : ffff8000fb49389c
> [    2.515561] x3 : 0000000000000004 x2 : 0000000000100001
> [    2.521453] x1 : ffff000008a49000 x0 : 0000000000000000
> [    2.527388]
> [    2.529058] Process swapper/0 (pid: 1, stack limit = 0xffff8000fb490020)
> [    2.536607] Stack: (0xffff8000fb4937f0 to 0xffff8000fb494000)
> [    2.543044] 37e0:                                   ffff8000fb493820
> ffff0000083b65cc
> [    2.551830] 3800: ffff8000fadb9400 ffff00000867606c 0000000000000004
> ffff8000fb49389c
> [    2.560481] 3820: ffff8000fb493840 ffff00000839dcc8 ffff8000fadb9400
> ffff00000839dce0
> [    2.569158] 3840: ffff8000fb4938a0 ffff00000839fcb8 0000000000000000
> ffff8000fb49391c
> [    2.577915] 3860: 000000000000ea60 0000000000000001 0000000000000010
> 0000000000000000
> [    2.586718] 3880: ffff8000faef9000 0000000000000000 ffff8000fb4938b0
> 00000000083a94d8
> [    2.595548] 38a0: ffff8000fb4938e0 ffff0000083a1380 0000000000000000
> ffff8000fadb9400
> [    2.604359] 38c0: 0000000000000010 0000000000000001 ffff0000087fb000
> ffff8000fadb9528
> [    2.613180] 38e0: ffff8000fb493920 ffff0000083a1444 ffff8000fadb9400
> ffff8000fadb9400
> [    2.621938] 3900: 0000000000000010 0000000000000004 ffff8000fb493960
> fffffffffb493960
> [    2.630767] 3920: ffff8000fb493960 ffff0000083a237c 0000000000000018
> ffff8000fadb9400
> [    2.639543] 3940: 0000000000000001 0000000000000000 ffff8000fadb9000
> 0000000000000007
> [    2.648355] 3960: ffff8000fb4939b0 ffff0000083a20d8 ffff8000faf27000
> ffff8000fadb9400
> [    2.657166] 3980: 0000000000000001 0000000000000000 0000000000000000
> 0000000000000001
> [    2.665960] 39a0: 0000000000000000 0000000000000018 ffff8000fb493a30
> ffff0000083a23d8
> [    2.674789] 39c0: ffff8000faf27000 ffff8000fadb9000 ffff8000fadb9028
> 0000000000000000
> [    2.683547] 39e0: ffff0000087fb000 ffff8000fadb9128 0000000000000001
> ffff0000088c0460
> [    2.692341] 3a00: ffff0000089a4000 ffff0000088f8b60 ffff8000fb49396c
> 0000000000000000
> [    2.701117] 3a20: 0000000000000000 00ff010000000000 ffff8000fb493a80
> ffff0000083b731c
> [    2.709910] 3a40: ffff8000faf0e218 ffff8000fffe7748 ffff8000fb63f410
> ffff8000fadb9000
> [    2.718695] 3a60: ffff0000086e9000 ffff8000fffe1e00 ffff0000088f8bc0
> 6c6071652c6c3175
> [    2.727489] 3a80: ffff8000fb493bc0 ffff0000083b8774 0000000000000000
> ffff8000faf0e218
> [    2.736291] 3aa0: ffff8000fb63f410 ffff8000fb493c10 ffff8000fffe1e00
> ffff8000fb63f400
> [    2.745058] 3ac0: ffff0000088f8bc0 ffff0000088c0460 ffff0000089a4000
> ffff0000088f8b60
> [    2.753816] 3ae0: ffff8000fb493b20 ffff00000858b7b0 ffff8000fb493c08
> ffff000008855f08
> [    2.762583] 3b00: ffff0000089b6000 ffff8000fb493c10 ffff8000fffe1e00
> 0000000060000000
> [    2.771376] 3b20: ffff8000fb493bc0 ffff0000083b8744 0000000000000000
> ffff8000faf0e218
> [    2.780125] 3b40: ffff8000fb63f410 ffff8000fb493c10 ffff8000fffe1e00
> ffff8000fb63f400
> [    2.788937] 3b60: ffff8000fffe1e00 0000000000000000 ffff0000004d454d
> 0000000200000007
> [    2.797731] 3b80: ffff7dfffe8009dc ffff7dfffe8009dc 0000000200000007
> ffff000000000083
> [    2.806533] 3ba0: 0000000000000000 0000000060000000 0000000000c00000
> 0000000000000200
> [    2.815372] 3bc0: ffff8000fb493c60 ffff000008414ef8 ffff000008962258
> ffff8000fb63f410
> [    2.824121] 3be0: 0000000000000000 ffff000008962280 0000000000000000
> ffff0000089a4000
> [    2.832950] 3c00: ffff8000fb493c40 ffffffffffffffff ffff8000fb493c10
> ffff8000fb493c10
> [    2.841717] 3c20: 0000000060c00000 0000000060c00fff ffff8000fffe1ea8
> 0000000000000200
> [    2.850529] 3c40: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    2.859358] 3c60: ffff8000fb493c80 ffff000008413688 ffff8000fb63f410
> ffff0000089c8000
> [    2.868161] 3c80: ffff8000fb493cc0 ffff0000084137c0 ffff8000fb63f410
> ffff000008962280
> [    2.876919] 3ca0: ffff8000fb63f470 ffff00000896cd30 ffff00000896c000
> ffff00000841190c
> [    2.885677] 3cc0: ffff8000fb493cf0 ffff000008411900 0000000000000000
> ffff000008962280
> [    2.894497] 3ce0: ffff000008413720 ffff8000fb493d40 ffff8000fb493d30
> ffff000008413124
> [    2.903308] 3d00: ffff000008962280 ffff8000faf0e100 0000000000000000
> ffff00000867606c
> [    2.912058] 3d20: ffff8000fb43eca8 ffff8000fb625b68 ffff8000fb493d40
> ffff000008412d84
> [    2.920815] 3d40: ffff8000fb493d80 ffff000008413eb4 ffff000008962280
> ffff0000088e1438
> [    2.929591] 3d60: 0000000000000000 ffff0000088f8b30 ffff0000088aba00
> ffff0000089c5000
> [    2.938358] 3d80: ffff8000fb493db0 ffff000008414eb8 ffff8000fb490000
> ffff0000088e1438
> [    2.947134] 3da0: 0000000000000000 0000000000000000 ffff8000fb493dc0
> ffff0000088e1450
> [    2.955936] 3dc0: ffff8000fb493dd0 ffff000008083144 ffff8000fb493e40
> ffff0000088c0c98
> [    2.964658] 3de0: ffff000008907240 0000000000000006 00000000000000e7
> ffff0000088f8b30
> [    2.973506] 3e00: ffff8000fb493e00 ffff0000087f42c8 ffff8000fb493e20
> ffff0000087f3ae8
> [    2.982326] 3e20: 0000000600000006 0000000000000000 0000000000000000
> ffff0000088aba00
> [    2.991129] 3e40: ffff8000fb493ea0 ffff000008678154 ffff000008678144
> 0000000000000000
> [    2.999922] 3e60: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.008671] 3e80: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.017500] 3ea0: 0000000000000000 ffff000008082e80 ffff000008678144
> 0000000000000000
> [    3.026294] 3ec0: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.035043] 3ee0: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.043818] 3f00: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.052639] 3f20: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.061432] 3f40: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.070207] 3f60: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.079036] 3f80: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.087820] 3fa0: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> [    3.096623] 3fc0: 0000000000000000 0000000000000005 0000000000000000
> 0000000000000000
> [    3.105398] 3fe0: 0000000000000000 0000000000000000 000000017b493ff0
> 000000017b493ff8
> [    3.114173] Call trace:
> [    3.116920] [<ffff00000839d984>] pci_generic_config_read32+0x74/0xa0
> [    3.124039] [<ffff0000083b65cc>] iproc_pcie_config_read32+0x2c/0xe0
> [    3.131041] [<ffff00000839dcc8>] pci_bus_read_config_dword+0x80/0xb0
> [    3.138143] [<ffff00000839fcb8>] pci_bus_read_dev_vendor_id+0x30/0x104
> [    3.145459] [<ffff0000083a1380>] pci_scan_single_device+0x50/0xc4
> [    3.152345] [<ffff0000083a1444>] pci_scan_slot+0x50/0xf0
> [    3.158334] [<ffff0000083a237c>] pci_scan_child_bus+0x50/0x164
> [    3.164798] [<ffff0000083a20d8>] pci_scan_bridge+0x2c0/0x514
> [    3.171154] [<ffff0000083a23d8>] pci_scan_child_bus+0xac/0x164
> [    3.177690] [<ffff0000083b731c>] iproc_pcie_setup+0x71c/0xc78
> [    3.184172] [<ffff0000083b8774>] iproc_pcie_pltfm_probe+0x170/0x260
> [    3.191176] [<ffff000008414ef8>] platform_drv_probe+0x38/0x7c
> [    3.197640] [<ffff000008413688>] really_probe+0x1b0/0x248
> [    3.203701] [<ffff0000084137c0>] __driver_attach+0xa0/0xb0
> [    3.209878] [<ffff000008411900>] bus_for_each_dev+0x58/0x98
> [    3.216110] [<ffff000008413124>] driver_attach+0x20/0x28
> [    3.222063] [<ffff000008412d84>] bus_add_driver+0x1c8/0x22c
> [    3.228285] [<ffff000008413eb4>] driver_register+0x68/0x108
> [    3.234517] [<ffff000008414eb8>] __platform_driver_register+0x4c/0x54
> [    3.241772] [<ffff0000088e1450>] iproc_pcie_pltfm_driver_init+0x18/0x20
> [    3.249224] [<ffff000008083144>] do_one_initcall+0x38/0x128
> [    3.255466] [<ffff0000088c0c98>] kernel_init_freeable+0x14c/0x1ec
> [    3.262344] [<ffff000008678154>] kernel_init+0x10/0xfc
> [    3.268118] [<ffff000008082e80>] ret_from_fork+0x10/0x50
> [    3.274108] Code: 52800000 f9400bf3 a8c37bfd d65f03c0 (b9000080)
> [    3.280984] ---[ end trace d90bb74924ac9e8e ]---
> [    3.286202] note: swapper/0[1] exited with preempt_count 1
> [    3.292340] Kernel panic - not syncing: Attempted to kill init!
> exitcode=0x0000000b
> [    3.292340]
> 

I originally tested this patch with the following DT change to enable
that PCI slot on the host-iproc branch (uname reports it as 4.9.0-rc1+).
I also just tested it again to be sure and I do not see the same crash
you see.  I'll test Linus' tree and see if I can reproduce what you are
seeing.  We can also share configs offline if needed.

diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
index 2d7872a..23e7f15 100644
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@ -72,6 +72,10 @@
 	status = "ok";
 };
 
+&pcie8 {
+	status = "ok";
+};
+
 &i2c0 {
 	status = "ok";
 };
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index 7ade88f..0dc4a67 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -133,6 +133,9 @@
 
 		status = "disabled";
 
+		phys = <&pci_phy0>;
+		phy-names = "pcie-phy";
+
 		msi-parent = <&msi0>;
 		msi0: msi at 20020000 {
 			compatible = "brcm,iproc-msi";
@@ -171,6 +174,9 @@
 
 		status = "disabled";
 
+		phys = <&pci_phy1>;
+		phy-names = "pcie-phy";
+
 		msi-parent = <&msi4>;
 		msi4: msi at 50020000 {
 			compatible = "brcm,iproc-msi";
@@ -183,6 +189,34 @@
 		};
 	};
 
+	pcie8: pcie at 60c00000 {
+		compatible = "brcm,iproc-pcie-paxc";
+		reg = <0 0x60c00000 0 0x1000>;
+		dma-coherent;
+		linux,pci-domain = <8>;
+
+		bus-range = <0x0 0x1>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x83000000 0 0x00000000 0 0x60000000 0 0x00c00000>;
+
+		status = "disabled";
+
+		msi-parent = <&msi8>;
+		msi8: msi at 60c00000 {
+			msi-controller;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 439 IRQ_TYPE_NONE>,
+				     <GIC_SPI 440 IRQ_TYPE_NONE>,
+				     <GIC_SPI 441 IRQ_TYPE_NONE>,
+				     <GIC_SPI 442 IRQ_TYPE_NONE>;
+			brcm,num-eq-region = <4>;
+			brcm,num-msi-msg-region = <4>;
+		};
+	};
+
 	soc: soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;

^ permalink raw reply related

* [PATCH] ARM: dts: imx: Pass an empty 'chosen' node
From: Fabio Estevam @ 2016-12-19 21:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161219184130.o2dpr7lie256hq76@pengutronix.de>

Hi Uwe,

On Mon, Dec 19, 2016 at 4:41 PM, Uwe Kleine-K?nig
<u.kleine-koenig@pengutronix.de> wrote:

> wouldn't it be better to fix the decompressor code to eventually create
> the /chosen node when it doesn't exist?

Thanks for the suggestion.

I don't have a Barebox setup handy, but would the following change fix
it as you propose?

--- a/arch/arm/boot/compressed/atags_to_fdt.c
+++ b/arch/arm/boot/compressed/atags_to_fdt.c
@@ -66,13 +66,21 @@ static uint32_t get_cell_size(const void *fdt)
        return cell_size;
 }

-static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
+static int merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
 {
        char cmdline[COMMAND_LINE_SIZE];
        const char *fdt_bootargs;
        char *ptr = cmdline;
+       int chosen_off;
        int len = 0;

+       /* find or add chosen node */
+       chosen_off = fdt_path_offset(fdt, "/chosen");
+       if (chosen_off == -FDT_ERR_NOTFOUND)
+               chosen_off = fdt_add_subnode(fdt, 0, "chosen");
+       if (chosen_off < 0)
+               return chosen_off;
+
        /* copy the fdt command line into the buffer */
        fdt_bootargs = getprop(fdt, "/chosen", "bootargs", &len);
        if (fdt_bootargs)

^ permalink raw reply

* [PATCH 2/2] mfd: mc13xxx: Pass the IRQF_TRIGGER_HIGH flag.
From: Magnus Lilja @ 2016-12-19 21:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482182934-18559-1-git-send-email-lilja.magnus@gmail.com>

All supported mc13xxx devices have active high interrupt outputs. Make sure
to configure the interrupt as active high by passing the IRQF_TRIGGER_HIGH
flag. This is required at least on the i.MX31 PDK board.

Signed-off-by: Magnus Lilja <lilja.magnus@gmail.com>
---

 drivers/mfd/mc13xxx-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index d7f54e4..4cbe6b7 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -440,7 +440,7 @@ int mc13xxx_common_init(struct device *dev)
 	mc13xxx->irq_chip.irqs = mc13xxx->irqs;
 	mc13xxx->irq_chip.num_irqs = ARRAY_SIZE(mc13xxx->irqs);
 
-	ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT,
+	ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
 				  0, &mc13xxx->irq_chip, &mc13xxx->irq_data);
 	if (ret)
 		return ret;
-- 
2.7.4

^ permalink raw reply related

* [PATCH 1/2] i.MX31: ipu: Make sure the interrupt routine checks all interrupts.
From: Magnus Lilja @ 2016-12-19 21:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482182934-18559-1-git-send-email-lilja.magnus@gmail.com>

Commit 3d8cc00073d6750ffe883685e49b2e4a0f596370 consolidated the two
interrupts routines into one, but the remaining interrupt routine only
checks the status of the error interrupts, not the normal interrupts.

This patch fixes that problem (tested on i.MX31 PDK board).

Signed-off-by: Magnus Lilja <lilja.magnus@gmail.com>
---
 drivers/dma/ipu/ipu_irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index dd184b5..2846278 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -272,7 +272,7 @@ static void ipu_irq_handler(struct irq_desc *desc)
 	u32 status;
 	int i, line;
 
-	for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
+	for (i = 0; i < IPU_IRQ_NR_BANKS; i++) {
 		struct ipu_irq_bank *bank = irq_bank + i;
 
 		raw_spin_lock(&bank_lock);
-- 
2.7.4

^ permalink raw reply related

* [PATCH 0/2] Patches to make i.MX31 PDK board boot again
From: Magnus Lilja @ 2016-12-19 21:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

I've been working on getting the current kernel (v4.9) as well as the stable
kernels to boot on the i.MX31 PDK board. The following is my summary of 
which patches/changes are required for each kernel series. Some patches
have been posted on the mailing lists, one is in the v4.9 kernel and then
there are two new patches in this series.

On all kernels the standard imx_v6_v7_defconfig was used.

The patches in this series applies on v4.9 as well as the imx-soc/for-next
tree as of today.

Kernel 4.9:
[RESERVE-PATCH] [IMX-WDT-PATCH] [IPU-IRQ-PATCH] [MC13xxx-PATCH]

Kernel 4.8.x:
[RESERVE-PATCH] [IMX-WDT-PATCH] [IPU-IRQ-PATCH] [MC13xxx-PATCH] 
[IMX-SPI-PATCH]

Kernel 4.4.x:
[RESERVE-PATCH] [IMX-WDT-PATCH] [IPU-IRQ-PATCH] [MC13xxx-PATCH]

Kernel 4.1.x:
[RESERVE-PATCH] [IMX-WDT-PATCH] [IPU-IRQ-PATCH] [MC13xxx-PATCH]

Kernel 3.18.x:
[RESERVE-PATCH] [MC13xxx-PATCH]

Kernel 3.16.x:
[RESERVE-PATCH]

Kernel 3.14.x, 3.12.x, 3.10..x, 3.4.x, 3.2.x:
No changes needed.

[RESERVE-PATCH] https://marc.info/?l=linux-arm-kernel&m=148168166012794&w=2
[IMX-WDT-PATCH] https://marc.info/?l=linux-arm-kernel&m=148141853206440&w=2
[IPU-IRQ-PATCH] Patch 1 in my series
[MC13xxx-PATCH] Patch 2 in my series
[IMX-SPI-PATCH] Commit 2636ba8fa39915c7b8d73166961ebbb4c14251cd

Regards, Magnus

Magnus Lilja (2):
  i.MX31: ipu: Make sure the interrupt routine checks all interrupts.
  mfd: mc13xxx: Pass the IRQF_TRIGGER_HIGH flag.

 drivers/dma/ipu/ipu_irq.c  | 2 +-
 drivers/mfd/mc13xxx-core.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH 2/3] arm64: Work around Falkor erratum 1003
From: Christopher Covington @ 2016-12-19 21:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161208103115.GF33075@MBP.local>

Hi Catalin,

On 12/08/2016 05:31 AM, Catalin Marinas wrote:
> On Wed, Dec 07, 2016 at 03:00:26PM -0500, Christopher Covington wrote:
>> From: Shanker Donthineni <shankerd@codeaurora.org>
>>
>> On the Qualcomm Datacenter Technologies Falkor v1 CPU, memory accesses may
>> allocate TLB entries using an incorrect ASID when TTBRx_EL1 is being
>> updated. Changing the TTBRx_EL1[ASID] and TTBRx_EL1[BADDR] fields
>> separately using a reserved ASID will ensure that there are no TLB entries
>> with incorrect ASID after changing the the ASID.
>>
>> Pseudo code:
>>   write TTBRx_EL1[ASID] to a reserved value
>>   ISB
>>   write TTBRx_EL1[BADDR] to a desired value
>>   ISB
>>   write TTBRx_EL1[ASID] to a desired value
>>   ISB
> 
> While the new ASID probably won't have incorrect TLB entries, the
> reserved ASID will have random entries from all over the place. That's
> because in step 1 you change the ASID to the reserved one while leaving
> the old BADDR in place. There is a brief time before changing the ASID
> when speculative page table walks will populate the TLB with entries
> tagged with the reserved ASID. Such entries are never removed during TLB
> shoot-down for the real ASID, so, depending on how this CPU implements
> the walk cache, you could end up with intermediate level entries still
> active and pointing to freed/reused pages. It will eventually hit an
> entry that looks global with weird consequences.
> 
> We've been bitten by this in the past on arm32: 52af9c6cd863 ("ARM:
> 6943/1: mm: use TTBR1 instead of reserved context ID").

Thanks for bringing this up, but I'm told the scenario you describe won't
happen on the Falkor 1.0 CPU.

Thanks,
Cov

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code
Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH] iommu/arm-smmu-v3: prevent corruption of ste stage-1 context ptr
From: Nate Watterson @ 2016-12-19 20:38 UTC (permalink / raw)
  To: linux-arm-kernel

To ensure that the stage-1 context ptr for an ste points to the
intended context descriptor, this patch adds code to clear away
the stale context ptr value prior to or'ing in the new one.

Signed-off-by: Nate Watterson <nwatters@codeaurora.org>
---
 drivers/iommu/arm-smmu-v3.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 4d6ec44..093f9f1 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1080,6 +1080,8 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
 		if (smmu->features & ARM_SMMU_FEAT_STALLS)
 			dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
 
+		val &= ~(STRTAB_STE_0_S1CTXPTR_MASK <<
+			 STRTAB_STE_0_S1CTXPTR_SHIFT);
 		val |= (ste->s1_cfg->cdptr_dma & STRTAB_STE_0_S1CTXPTR_MASK
 		        << STRTAB_STE_0_S1CTXPTR_SHIFT) |
 			STRTAB_STE_0_CFG_S1_TRANS;
-- 
Qualcomm Datacenter Technologies, Inc. on behalf of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux
Foundation Collaborative Project.

^ permalink raw reply related

* [PATCH] iommu/arm-smmu-v3: avoid over allocating for l2 stream tables
From: Nate Watterson @ 2016-12-19 20:26 UTC (permalink / raw)
  To: linux-arm-kernel

Currently, all l2 stream tables are being allocated with space for
(1<<split) stes without regard to the number of sid bits the smmu
physically supports. To avoid allocating memory for inaccessible
stes, this patch limits the span of an l2 table to be no larger
than the sid size of the smmu to which it belongs.

Signed-off-by: Nate Watterson <nwatters@codeaurora.org>
---
 drivers/iommu/arm-smmu-v3.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 4d6ec44..5dca671 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1129,6 +1129,7 @@ static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent)
 
 static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
 {
+	u8 span;
 	size_t size;
 	void *strtab;
 	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
@@ -1137,10 +1138,11 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
 	if (desc->l2ptr)
 		return 0;
 
-	size = 1 << (STRTAB_SPLIT + ilog2(STRTAB_STE_DWORDS) + 3);
+	span = (smmu->sid_bits < STRTAB_SPLIT) ? smmu->sid_bits : STRTAB_SPLIT;
+	size = 1 << (span + ilog2(STRTAB_STE_DWORDS) + 3);
 	strtab = &cfg->strtab[(sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS];
 
-	desc->span = STRTAB_SPLIT + 1;
+	desc->span = span + 1;
 	desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, &desc->l2ptr_dma,
 					  GFP_KERNEL | __GFP_ZERO);
 	if (!desc->l2ptr) {
@@ -1150,7 +1152,7 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
 		return -ENOMEM;
 	}
 
-	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT);
+	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << span);
 	arm_smmu_write_strtab_l1_desc(strtab, desc);
 	return 0;
 }
@@ -2001,6 +2003,8 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
 		dev_warn(smmu->dev,
 			 "2-level strtab only covers %u/%u bits of SID\n",
 			 size, smmu->sid_bits);
+	else if (smmu->sid_bits < size)
+		size = smmu->sid_bits;
 
 	l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
 	strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
-- 
Qualcomm Datacenter Technologies, Inc. on behalf of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux
Foundation Collaborative Project.

^ permalink raw reply related

* [PATCH v10 0/8] power: add power sequence library
From: Krzysztof Kozlowski @ 2016-12-19 19:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479087359-7547-1-git-send-email-peter.chen@nxp.com>

On Mon, Nov 14, 2016 at 09:35:51AM +0800, Peter Chen wrote:
> Hi all,
> 
> This is a follow-up for my last power sequence framework patch set [1].
> According to Rob Herring and Ulf Hansson's comments[2]. The kinds of
> power sequence instances will be added at postcore_initcall, the match
> criteria is compatible string first, if the compatible string is not
> matched between dts and library, it will try to use generic power sequence.
> 	 
> The host driver just needs to call of_pwrseq_on/of_pwrseq_off
> if only one power sequence instance is needed, for more power sequences
> are used, using of_pwrseq_on_list/of_pwrseq_off_list instead (eg, USB hub driver).
> 
> In future, if there are special power sequence requirements, the special
> power sequence library can be created.
> 
> This patch set is tested on i.mx6 sabresx evk using a dts change, I use
> two hot-plug devices to simulate this use case, the related binding
> change is updated at patch [1/6], The udoo board changes were tested
> using my last power sequence patch set.[3]
> 
> Except for hard-wired MMC and USB devices, I find the USB ULPI PHY also
> need to power on itself before it can be found by ULPI bus.
> 
> [1] http://www.spinics.net/lists/linux-usb/msg142755.html
> [2] http://www.spinics.net/lists/linux-usb/msg143106.html
> [3] http://www.spinics.net/lists/linux-usb/msg142815.html
> 
> Changes for v10:
> - Improve the kernel-doc for power sequence core, including exported APIs and
>   main structure. [Patch 2/8]
> - Change Kconfig, and let the user choose power sequence. [Patch 2/8]
> - Delete EXPORT_SYMBOL and change related APIs as local, these APIs do not
>   be intended to export currently. [Patch 2/8]
> - Selete POWER_SEQUENCE at USB core's Kconfig. [Patch 4/8]

Hi Peter,

It is great that you continued the work on this.

I saw (in some previous mails) your repo mentioned:
https://git.kernel.org/cgit/linux/kernel/git/peter.chen/usb.git/
Does it contain the recent version of this patchset?

I want to build on top of it fixes for usb3503 on Odroid U3 board.

Best regards,
Krzysztof

> 
> Changes for v9:
> - Add Vaibhav Hiremath's reviewed-by [Patch 4/8]
> - Rebase to v4.9-rc1
> 
> Changes for v8:
> - Allocate one extra pwrseq instance if pwrseq_get has succeed, it can avoid
>   preallocate instances problem which the number of instance is decided at
>   compile time, thanks for Heiko Stuebner's suggestion [Patch 2/8]
> - Delete pwrseq_compatible_sample.c which is the demo purpose to show compatible
>   match method. [Patch 2/8]
> - Add Maciej S. Szmigiero's tested-by. [Patch 7/8]
> 
> Changes for v7:
> - Create kinds of power sequence instance at postcore_initcall, and match
>   the instance with node using compatible string, the beneit of this is
>   the host driver doesn't need to consider which pwrseq instance needs
>   to be used, and pwrseq core will match it, however, it eats some memories
>   if less power sequence instances are used. [Patch 2/8]
> - Add pwrseq_compatible_sample.c to test match pwrseq using device_id. [Patch 2/8]
> - Fix the comments Vaibhav Hiremath adds for error path for clock and do not
>   use device_node for parameters at pwrseq_on. [Patch 2/8]
> - Simplify the caller to use power sequence, follows Alan's commnets [Patch 4/8]
> - Tested three pwrseq instances together using both specific compatible string and
>   generic libraries.
> 
> Changes for v6:
> - Add Matthias Kaehlcke's Reviewed-by and Tested-by. (patch [2/6])
> - Change chipidea core of_node assignment for coming user. (patch [5/6])
> - Applies Joshua Clayton's three dts changes for two boards,
>   the USB device's reg has only #address-cells, but without #size-cells.
> 
> Changes for v5:
> - Delete pwrseq_register/pwrseq_unregister, which is useless currently
> - Fix the linker error when the pwrseq user is compiled as module
> 
> Changes for v4:
> - Create the patch on next-20160722 
> - Fix the of_node is not NULL after chipidea driver is unbinded [Patch 5/6]
> - Using more friendly wait method for reset gpio [Patch 2/6]
> - Support multiple input clocks [Patch 2/6]
> - Add Rob Herring's ack for DT changes
> - Add Joshua Clayton's Tested-by
> 
> Changes for v3:
> - Delete "power-sequence" property at binding-doc, and change related code
>   at both library and user code.
> - Change binding-doc example node name with Rob's comments
> - of_get_named_gpio_flags only gets the gpio, but without setting gpio flags,
>   add additional code request gpio with proper gpio flags
> - Add Philipp Zabel's Ack and MAINTAINER's entry
> 
> Changes for v2:
> - Delete "pwrseq" prefix and clock-names for properties at dt binding
> - Should use structure not but its pointer for kzalloc
> - Since chipidea core has no of_node, let core's of_node equals glue
>   layer's at core's probe
> 
> Joshua Clayton (2):
>   ARM: dts: imx6qdl: Enable usb node children with <reg>
>   ARM: dts: imx6q-evi: Fix onboard hub reset line
> 
> Peter Chen (6):
>   binding-doc: power: pwrseq-generic: add binding doc for generic power
>     sequence library
>   power: add power sequence library
>   binding-doc: usb: usb-device: add optional properties for power
>     sequence
>   usb: core: add power sequence handling for USB devices
>   usb: chipidea: let chipidea core device of_node equal's glue layer
>     device of_node
>   ARM: dts: imx6qdl-udoo.dtsi: fix onboard USB HUB property
> 
>  .../bindings/power/pwrseq/pwrseq-generic.txt       |  48 +++++
>  .../devicetree/bindings/usb/usb-device.txt         |  10 +-
>  MAINTAINERS                                        |   9 +
>  arch/arm/boot/dts/imx6q-evi.dts                    |  25 +--
>  arch/arm/boot/dts/imx6qdl-udoo.dtsi                |  26 ++-
>  arch/arm/boot/dts/imx6qdl.dtsi                     |   6 +
>  drivers/power/Kconfig                              |   1 +
>  drivers/power/Makefile                             |   1 +
>  drivers/power/pwrseq/Kconfig                       |  21 ++
>  drivers/power/pwrseq/Makefile                      |   2 +
>  drivers/power/pwrseq/core.c                        | 237 +++++++++++++++++++++
>  drivers/power/pwrseq/pwrseq_generic.c              | 183 ++++++++++++++++
>  drivers/usb/Kconfig                                |   1 +
>  drivers/usb/chipidea/core.c                        |  27 ++-
>  drivers/usb/core/hub.c                             |  41 +++-
>  drivers/usb/core/hub.h                             |   1 +
>  include/linux/power/pwrseq.h                       |  60 ++++++
>  17 files changed, 658 insertions(+), 41 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
>  create mode 100644 drivers/power/pwrseq/Kconfig
>  create mode 100644 drivers/power/pwrseq/Makefile
>  create mode 100644 drivers/power/pwrseq/core.c
>  create mode 100644 drivers/power/pwrseq/pwrseq_generic.c
>  create mode 100644 include/linux/power/pwrseq.h
> 
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH pci/host-iproc] PCI: iproc: Allow more than slot 0 on PAXC
From: Ray Jui @ 2016-12-19 18:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481232618-10614-1-git-send-email-gospo@broadcom.com>



On 12/8/2016 1:30 PM, Andy Gospodarek wrote:
> The iproc host driver limits the number of slots that are available on
> PAXC devices.  Enforcing this limit prevents VFs from being created
> beyond the first port.  After this change it is possible to create VFs
> associated with all four devices.
> 
> The first four devices below are the PFs and the next four are the newly
> created VFs:
> 
> 0008:01:00.0 Ethernet controller: Broadcom Limited Device 16cd
> 0008:01:00.1 Ethernet controller: Broadcom Limited Device 16cd
> 0008:01:00.2 Ethernet controller: Broadcom Limited Device 16cd
> 0008:01:00.3 Ethernet controller: Broadcom Limited Device 16cd
> 0008:01:00.4 Ethernet controller: Broadcom Limited BCM57304 NetXtreme-C Ethernet Virtual Function
> 0008:01:01.0 Ethernet controller: Broadcom Limited BCM57304 NetXtreme-C Ethernet Virtual Function
> 0008:01:01.4 Ethernet controller: Broadcom Limited BCM57304 NetXtreme-C Ethernet Virtual Function
> 0008:01:02.0 Ethernet controller: Broadcom Limited BCM57304 NetXtreme-C Ethernet Virtual Function
> 
> Based on the git history around 923c6bb1f641 ("PCI: iproc: Allow multiple
> devices except on PAXC") and 943ebae781f5 ("PCI: iproc: Add PAXC interface
> support") I expect there may be an unmentioned or unknown-to-me reason why this
> code exists.  I certainly cannot create and use VFs without some kind of change
> around this space, so I would like to see the current limitation simply removed.
> 
> Fixes: 923c6bb1f641 ("PCI: iproc: Allow multiple devices except on PAXC")

> Signed-off-by: Andy Gospodarek <gospo@broadcom.com>
> ---
>  drivers/pci/host/pcie-iproc.c | 8 --------
>  1 file changed, 8 deletions(-)
> 
> diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
> index 3ebc025..9311826 100644
> --- a/drivers/pci/host/pcie-iproc.c
> +++ b/drivers/pci/host/pcie-iproc.c
> @@ -477,14 +477,6 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
>  			return (pcie->base + offset);
>  	}
>  
> -	/*
> -	 * PAXC is connected to an internally emulated EP within the SoC.  It
> -	 * allows only one device.
> -	 */
> -	if (pcie->ep_is_internal)
> -		if (slot > 0)
> -			return NULL;
> -
>  	/* EP device access */
>  	val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
>  		(slot << CFG_ADDR_DEV_NUM_SHIFT) |
> 

With this change, standard v4.9 kernel would crash on a NS2 SVK with the
log shown below. This is inline with my previous observation and
therefore slot number has been limited to only zero for the PAXC
interface. Does it require more than just this change in order for the
kernel to boot to complete?

[    2.190515] OF: PCI: host bridge /pcie at 60c00000 ranges:
[    2.196400] OF: PCI:   MEM 0x60000000..0x60bfffff -> 0x00000000
[    2.203135] iproc-pcie 60c00000.pcie: PCI host bridge to bus 0008:00
[    2.210289] pci_bus 0008:00: root bus resource [bus 00-01]
[    2.216349] pci_bus 0008:00: root bus resource [mem
0x60000000-0x60bfffff] (bus address [0x00000000-0x00bfffff])
[    2.227769] iproc-pcie 60c00000.pcie: not using iProc MSI
[    2.234050] pci 0008:00:00.0: bridge configuration invalid ([bus
00-00]), reconfiguring
[    2.244285] Bad mode in Error handler detected on CPU1, code
0xbf000002 -- SError
[    2.252661] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.9.0+ #24
[    2.259430] Hardware name: Broadcom NS2 SVK (DT)
[    2.264550] task: ffff8000fb488000 task.stack: ffff8000fb490000
[    2.271161] PC is at pci_generic_config_read32+0x74/0xa0
[    2.277043] LR is at pci_generic_config_read32+0x28/0xa0
[    2.283005] pc : [<ffff00000839d984>] lr : [<ffff00000839d938>]
pstate: 200000c5
[    2.291225] sp : ffff8000fb4937f0
[    2.294937] x29: ffff8000fb4937f0 x28: ffff8000fadb9000
[    2.300884] x27: ffff8000faf27098 x26: 0000000000000000
[    2.306803] x25: 0000000000000000 x24: ffff8000fadb9400
[    2.312757] x23: 0000000000000040 x22: ffff0000089c55d8
[    2.318730] x21: 0000000000000010 x20: ffff8000fb49391c
[    2.324666] x19: 0000000000000000 x18: 000000000000077f
[    2.330594] x17: ffffffffffffffff x16: ffff000008a49fff
[    2.336539] x15: ffff000008a49fff x14: 0000000000000000
[    2.342502] x13: 0000000000000007 x12: 0000000000000018
[    2.348456] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
[    2.354392] x9 : 0000000000000000 x8 : ffff8000fa80e680
[    2.360355] x7 : 000000000000ffff x6 : ffff8000faf0ca98
[    2.366300] x5 : 0000000000000002 x4 : ffff8000fb49389c
[    2.372290] x3 : 0000000000000004 x2 : 0000000000100001
[    2.378209] x1 : ffff000008a49000 x0 : 0000000000000000
[    2.384145]
[    2.385807] Internal error: Oops - bad mode: 0 [#1] PREEMPT SMP
[    2.392351] Modules linked in:
[    2.395770] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.9.0+ #24
[    2.402529] Hardware name: Broadcom NS2 SVK (DT)
[    2.407693] task: ffff8000fb488000 task.stack: ffff8000fb490000
[    2.414301] PC is at pci_generic_config_read32+0x74/0xa0
[    2.420299] LR is at pci_generic_config_read32+0x28/0xa0
[    2.426279] pc : [<ffff00000839d984>] lr : [<ffff00000839d938>]
pstate: 200000c5
[    2.434552] sp : ffff8000fb4937f0
[    2.438246] x29: ffff8000fb4937f0 x28: ffff8000fadb9000
[    2.444209] x27: ffff8000faf27098 x26: 0000000000000000
[    2.450137] x25: 0000000000000000 x24: ffff8000fadb9400
[    2.456091] x23: 0000000000000040 x22: ffff0000089c55d8
[    2.462037] x21: 0000000000000010 x20: ffff8000fb49391c
[    2.467947] x19: 0000000000000000 x18: 000000000000077f
[    2.473945] x17: ffffffffffffffff x16: ffff000008a49fff
[    2.479881] x15: ffff000008a49fff x14: 0000000000000000
[    2.485826] x13: 0000000000000007 x12: 0000000000000018
[    2.491798] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
[    2.497752] x9 : 0000000000000000 x8 : ffff8000fa80e680
[    2.503689] x7 : 000000000000ffff x6 : ffff8000faf0ca98
[    2.509643] x5 : 0000000000000002 x4 : ffff8000fb49389c
[    2.515561] x3 : 0000000000000004 x2 : 0000000000100001
[    2.521453] x1 : ffff000008a49000 x0 : 0000000000000000
[    2.527388]
[    2.529058] Process swapper/0 (pid: 1, stack limit = 0xffff8000fb490020)
[    2.536607] Stack: (0xffff8000fb4937f0 to 0xffff8000fb494000)
[    2.543044] 37e0:                                   ffff8000fb493820
ffff0000083b65cc
[    2.551830] 3800: ffff8000fadb9400 ffff00000867606c 0000000000000004
ffff8000fb49389c
[    2.560481] 3820: ffff8000fb493840 ffff00000839dcc8 ffff8000fadb9400
ffff00000839dce0
[    2.569158] 3840: ffff8000fb4938a0 ffff00000839fcb8 0000000000000000
ffff8000fb49391c
[    2.577915] 3860: 000000000000ea60 0000000000000001 0000000000000010
0000000000000000
[    2.586718] 3880: ffff8000faef9000 0000000000000000 ffff8000fb4938b0
00000000083a94d8
[    2.595548] 38a0: ffff8000fb4938e0 ffff0000083a1380 0000000000000000
ffff8000fadb9400
[    2.604359] 38c0: 0000000000000010 0000000000000001 ffff0000087fb000
ffff8000fadb9528
[    2.613180] 38e0: ffff8000fb493920 ffff0000083a1444 ffff8000fadb9400
ffff8000fadb9400
[    2.621938] 3900: 0000000000000010 0000000000000004 ffff8000fb493960
fffffffffb493960
[    2.630767] 3920: ffff8000fb493960 ffff0000083a237c 0000000000000018
ffff8000fadb9400
[    2.639543] 3940: 0000000000000001 0000000000000000 ffff8000fadb9000
0000000000000007
[    2.648355] 3960: ffff8000fb4939b0 ffff0000083a20d8 ffff8000faf27000
ffff8000fadb9400
[    2.657166] 3980: 0000000000000001 0000000000000000 0000000000000000
0000000000000001
[    2.665960] 39a0: 0000000000000000 0000000000000018 ffff8000fb493a30
ffff0000083a23d8
[    2.674789] 39c0: ffff8000faf27000 ffff8000fadb9000 ffff8000fadb9028
0000000000000000
[    2.683547] 39e0: ffff0000087fb000 ffff8000fadb9128 0000000000000001
ffff0000088c0460
[    2.692341] 3a00: ffff0000089a4000 ffff0000088f8b60 ffff8000fb49396c
0000000000000000
[    2.701117] 3a20: 0000000000000000 00ff010000000000 ffff8000fb493a80
ffff0000083b731c
[    2.709910] 3a40: ffff8000faf0e218 ffff8000fffe7748 ffff8000fb63f410
ffff8000fadb9000
[    2.718695] 3a60: ffff0000086e9000 ffff8000fffe1e00 ffff0000088f8bc0
6c6071652c6c3175
[    2.727489] 3a80: ffff8000fb493bc0 ffff0000083b8774 0000000000000000
ffff8000faf0e218
[    2.736291] 3aa0: ffff8000fb63f410 ffff8000fb493c10 ffff8000fffe1e00
ffff8000fb63f400
[    2.745058] 3ac0: ffff0000088f8bc0 ffff0000088c0460 ffff0000089a4000
ffff0000088f8b60
[    2.753816] 3ae0: ffff8000fb493b20 ffff00000858b7b0 ffff8000fb493c08
ffff000008855f08
[    2.762583] 3b00: ffff0000089b6000 ffff8000fb493c10 ffff8000fffe1e00
0000000060000000
[    2.771376] 3b20: ffff8000fb493bc0 ffff0000083b8744 0000000000000000
ffff8000faf0e218
[    2.780125] 3b40: ffff8000fb63f410 ffff8000fb493c10 ffff8000fffe1e00
ffff8000fb63f400
[    2.788937] 3b60: ffff8000fffe1e00 0000000000000000 ffff0000004d454d
0000000200000007
[    2.797731] 3b80: ffff7dfffe8009dc ffff7dfffe8009dc 0000000200000007
ffff000000000083
[    2.806533] 3ba0: 0000000000000000 0000000060000000 0000000000c00000
0000000000000200
[    2.815372] 3bc0: ffff8000fb493c60 ffff000008414ef8 ffff000008962258
ffff8000fb63f410
[    2.824121] 3be0: 0000000000000000 ffff000008962280 0000000000000000
ffff0000089a4000
[    2.832950] 3c00: ffff8000fb493c40 ffffffffffffffff ffff8000fb493c10
ffff8000fb493c10
[    2.841717] 3c20: 0000000060c00000 0000000060c00fff ffff8000fffe1ea8
0000000000000200
[    2.850529] 3c40: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    2.859358] 3c60: ffff8000fb493c80 ffff000008413688 ffff8000fb63f410
ffff0000089c8000
[    2.868161] 3c80: ffff8000fb493cc0 ffff0000084137c0 ffff8000fb63f410
ffff000008962280
[    2.876919] 3ca0: ffff8000fb63f470 ffff00000896cd30 ffff00000896c000
ffff00000841190c
[    2.885677] 3cc0: ffff8000fb493cf0 ffff000008411900 0000000000000000
ffff000008962280
[    2.894497] 3ce0: ffff000008413720 ffff8000fb493d40 ffff8000fb493d30
ffff000008413124
[    2.903308] 3d00: ffff000008962280 ffff8000faf0e100 0000000000000000
ffff00000867606c
[    2.912058] 3d20: ffff8000fb43eca8 ffff8000fb625b68 ffff8000fb493d40
ffff000008412d84
[    2.920815] 3d40: ffff8000fb493d80 ffff000008413eb4 ffff000008962280
ffff0000088e1438
[    2.929591] 3d60: 0000000000000000 ffff0000088f8b30 ffff0000088aba00
ffff0000089c5000
[    2.938358] 3d80: ffff8000fb493db0 ffff000008414eb8 ffff8000fb490000
ffff0000088e1438
[    2.947134] 3da0: 0000000000000000 0000000000000000 ffff8000fb493dc0
ffff0000088e1450
[    2.955936] 3dc0: ffff8000fb493dd0 ffff000008083144 ffff8000fb493e40
ffff0000088c0c98
[    2.964658] 3de0: ffff000008907240 0000000000000006 00000000000000e7
ffff0000088f8b30
[    2.973506] 3e00: ffff8000fb493e00 ffff0000087f42c8 ffff8000fb493e20
ffff0000087f3ae8
[    2.982326] 3e20: 0000000600000006 0000000000000000 0000000000000000
ffff0000088aba00
[    2.991129] 3e40: ffff8000fb493ea0 ffff000008678154 ffff000008678144
0000000000000000
[    2.999922] 3e60: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.008671] 3e80: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.017500] 3ea0: 0000000000000000 ffff000008082e80 ffff000008678144
0000000000000000
[    3.026294] 3ec0: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.035043] 3ee0: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.043818] 3f00: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.052639] 3f20: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.061432] 3f40: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.070207] 3f60: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.079036] 3f80: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.087820] 3fa0: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
[    3.096623] 3fc0: 0000000000000000 0000000000000005 0000000000000000
0000000000000000
[    3.105398] 3fe0: 0000000000000000 0000000000000000 000000017b493ff0
000000017b493ff8
[    3.114173] Call trace:
[    3.116920] [<ffff00000839d984>] pci_generic_config_read32+0x74/0xa0
[    3.124039] [<ffff0000083b65cc>] iproc_pcie_config_read32+0x2c/0xe0
[    3.131041] [<ffff00000839dcc8>] pci_bus_read_config_dword+0x80/0xb0
[    3.138143] [<ffff00000839fcb8>] pci_bus_read_dev_vendor_id+0x30/0x104
[    3.145459] [<ffff0000083a1380>] pci_scan_single_device+0x50/0xc4
[    3.152345] [<ffff0000083a1444>] pci_scan_slot+0x50/0xf0
[    3.158334] [<ffff0000083a237c>] pci_scan_child_bus+0x50/0x164
[    3.164798] [<ffff0000083a20d8>] pci_scan_bridge+0x2c0/0x514
[    3.171154] [<ffff0000083a23d8>] pci_scan_child_bus+0xac/0x164
[    3.177690] [<ffff0000083b731c>] iproc_pcie_setup+0x71c/0xc78
[    3.184172] [<ffff0000083b8774>] iproc_pcie_pltfm_probe+0x170/0x260
[    3.191176] [<ffff000008414ef8>] platform_drv_probe+0x38/0x7c
[    3.197640] [<ffff000008413688>] really_probe+0x1b0/0x248
[    3.203701] [<ffff0000084137c0>] __driver_attach+0xa0/0xb0
[    3.209878] [<ffff000008411900>] bus_for_each_dev+0x58/0x98
[    3.216110] [<ffff000008413124>] driver_attach+0x20/0x28
[    3.222063] [<ffff000008412d84>] bus_add_driver+0x1c8/0x22c
[    3.228285] [<ffff000008413eb4>] driver_register+0x68/0x108
[    3.234517] [<ffff000008414eb8>] __platform_driver_register+0x4c/0x54
[    3.241772] [<ffff0000088e1450>] iproc_pcie_pltfm_driver_init+0x18/0x20
[    3.249224] [<ffff000008083144>] do_one_initcall+0x38/0x128
[    3.255466] [<ffff0000088c0c98>] kernel_init_freeable+0x14c/0x1ec
[    3.262344] [<ffff000008678154>] kernel_init+0x10/0xfc
[    3.268118] [<ffff000008082e80>] ret_from_fork+0x10/0x50
[    3.274108] Code: 52800000 f9400bf3 a8c37bfd d65f03c0 (b9000080)
[    3.280984] ---[ end trace d90bb74924ac9e8e ]---
[    3.286202] note: swapper/0[1] exited with preempt_count 1
[    3.292340] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0000000b
[    3.292340]

^ permalink raw reply

* [PATCH v8 04/16] MSI-X: update GSI routing after changed MSI-X configuration
From: Andre Przywara @ 2016-12-19 18:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <da4e554a-ebd1-fa59-3e94-0e0190ddade3@arm.com>

Hi,

On 09/12/16 17:13, Marc Zyngier wrote:
> On 04/11/16 17:31, Andre Przywara wrote:
>> When we set up GSI routing to map MSIs to KVM's GSI numbers, we
>> write the current device's MSI setup into the kernel routing table.
>> However the device driver in the guest can use PCI configuration space
>> accesses to change the MSI configuration (address and/or payload data).
>> Whenever this happens after we have setup the routing table already,
>> we must amend the previously sent data.
>> So when MSI-X PCI config space accesses write address or payload,
>> find the associated GSI number and the matching routing table entry
>> and update the kernel routing table (only if the data has changed).
>>
>> This fixes vhost-net, where the queue's IRQFD was setup before the
>> MSI vectors.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>> ---
>>  include/kvm/irq.h |  1 +
>>  irq.c             | 31 +++++++++++++++++++++++++++++++
>>  virtio/pci.c      | 36 +++++++++++++++++++++++++++++++++---
>>  3 files changed, 65 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/kvm/irq.h b/include/kvm/irq.h
>> index bb71521..f35eb7e 100644
>> --- a/include/kvm/irq.h
>> +++ b/include/kvm/irq.h
>> @@ -21,5 +21,6 @@ int irq__exit(struct kvm *kvm);
>>  
>>  int irq__allocate_routing_entry(void);
>>  int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg);
>> +void irq__update_msix_route(struct kvm *kvm, u32 gsi, struct msi_msg *msg);
>>  
>>  #endif
>> diff --git a/irq.c b/irq.c
>> index a742aa2..895e5eb 100644
>> --- a/irq.c
>> +++ b/irq.c
>> @@ -93,6 +93,37 @@ int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg)
>>  	return next_gsi++;
>>  }
>>  
>> +static bool update_data(u32 *ptr, u32 newdata)
>> +{
>> +	if (*ptr == newdata)
>> +		return false;
>> +
>> +	*ptr = newdata;
>> +	return true;
>> +}
>> +
>> +void irq__update_msix_route(struct kvm *kvm, u32 gsi, struct msi_msg *msg)
>> +{
>> +	struct kvm_irq_routing_msi *entry;
>> +	unsigned int i;
>> +	bool changed;
>> +
>> +	for (i = 0; i < irq_routing->nr; i++)
>> +		if (gsi == irq_routing->entries[i].gsi)
>> +			break;
>> +	if (i == irq_routing->nr)
>> +		return;
>> +
>> +	entry = &irq_routing->entries[i].u.msi;
>> +
>> +	changed  = update_data(&entry->address_hi, msg->address_hi);
>> +	changed |= update_data(&entry->address_lo, msg->address_lo);
>> +	changed |= update_data(&entry->data, msg->data);
>> +
>> +	if (changed)
>> +		ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing);
> 
> Check the return value and let the caller know if something has failed?

As the caller is a void function and the call chain for this originates
in an MMIO access triggered by the guest (update MSI information in the
PCI config space), I guess again die() would be the appropriate action here?

> 
>> +}
>> +
>>  int __attribute__((weak)) irq__exit(struct kvm *kvm)
>>  {
>>  	free(irq_routing);
>> diff --git a/virtio/pci.c b/virtio/pci.c
>> index 072e5b7..b3b4aac 100644
>> --- a/virtio/pci.c
>> +++ b/virtio/pci.c
>> @@ -152,6 +152,30 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 p
>>  	return ret;
>>  }
>>  
>> +static void update_msix_map(struct virtio_pci *vpci,
>> +			    struct msix_table *msix_entry, u32 vecnum)
>> +{
>> +	u32 gsi, i;
>> +
>> +	/* Find the GSI number used for that vector */
>> +	if (vecnum == vpci->config_vector) {
>> +		gsi = vpci->config_gsi;
>> +	} else {
>> +		for (i = 0; i < VIRTIO_PCI_MAX_VQ; i++)
>> +			if (vpci->vq_vector[i] == vecnum)
>> +				break;
>> +		if (i == VIRTIO_PCI_MAX_VQ)
>> +			return;
>> +		gsi = vpci->gsis[i];
>> +	}
>> +
>> +	if (gsi == 0)
>> +		return;
>> +
>> +	msix_entry = &msix_entry[vecnum];
>> +	irq__update_msix_route(vpci->kvm, gsi, &msix_entry->msg);
>> +}
>> +
>>  static bool virtio_pci__specific_io_out(struct kvm *kvm, struct virtio_device *vdev, u16 port,
>>  					void *data, int size, int offset)
>>  {
>> @@ -270,10 +294,16 @@ static void virtio_pci__msix_mmio_callback(struct kvm_cpu *vcpu,
>>  		offset	= vpci->msix_io_block;
>>  	}
>>  
>> -	if (is_write)
>> -		memcpy(table + addr - offset, data, len);
>> -	else
>> +	if (!is_write) {
>>  		memcpy(data, table + addr - offset, len);
>> +		return;
>> +	}
>> +
>> +	memcpy(table + addr - offset, data, len);
>> +
>> +	/* Did we just update the address or payload? */
>> +	if (addr % 0x10 < 0xc)
>> +		update_msix_map(vpci, table, (addr - offset) / 16);
> 
> Where are these constants coming from? Please stick to either decimal or
> hex...

Sure, seems to be a leftover from my initial hacking approach. Thanks
for spotting that.

Cheers,
Andre.

> 
>>  }
>>  
>>  static void virtio_pci__signal_msi(struct kvm *kvm, struct virtio_pci *vpci, int vec)
>>
> 
> Thanks,
> 
> 	M.
> 

^ permalink raw reply

* [PATCH v8 01/16] FDT: introduce global phandle allocation
From: Andre Przywara @ 2016-12-19 18:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <d1dc4e68-66e1-85d1-f5d1-5743e5172409@arm.com>

Hi Marc,

On 09/12/16 12:03, Marc Zyngier wrote:
> On 04/11/16 17:31, Andre Przywara wrote:
>> Allocating an FDT phandle (a unique identifier) using a static
>> variable in a static inline function defined in a header file works
>> only if all users are in the same source file. So trying to allocate
>> a handle from two different compilation units fails.
>> Introduce global phandle allocation and reference code to properly
>> allocate unique phandles.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>> ---
>>  Makefile          |  1 +
>>  arm/fdt.c         |  2 +-
>>  arm/gic.c         |  2 +-
>>  include/kvm/fdt.h | 10 +++++-----
>>  kvm-fdt.c         | 26 ++++++++++++++++++++++++++
>>  5 files changed, 34 insertions(+), 7 deletions(-)
>>  create mode 100644 kvm-fdt.c
>>
>> diff --git a/Makefile b/Makefile
>> index 1f0196f..e4a4002 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -98,6 +98,7 @@ OBJS	+= kvm-ipc.o
>>  OBJS	+= builtin-sandbox.o
>>  OBJS	+= virtio/mmio.o
>>  OBJS	+= hw/i8042.o
>> +OBJS	+= kvm-fdt.o
>>  
>>  # Translate uname -m into ARCH string
>>  ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/ \
>> diff --git a/arm/fdt.c b/arm/fdt.c
>> index 381d48f..8bcfffb 100644
>> --- a/arm/fdt.c
>> +++ b/arm/fdt.c
>> @@ -114,7 +114,7 @@ static int setup_fdt(struct kvm *kvm)
>>  {
>>  	struct device_header *dev_hdr;
>>  	u8 staging_fdt[FDT_MAX_SIZE];
>> -	u32 gic_phandle		= fdt__alloc_phandle();
>> +	u32 gic_phandle		= fdt__get_phandle(PHANDLE_GIC);
>>  	u64 mem_reg_prop[]	= {
>>  		cpu_to_fdt64(kvm->arch.memory_guest_start),
>>  		cpu_to_fdt64(kvm->ram_size),
>> diff --git a/arm/gic.c b/arm/gic.c
>> index d6d6dd0..b60437e 100644
>> --- a/arm/gic.c
>> +++ b/arm/gic.c
>> @@ -222,7 +222,7 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
>>  	_FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS));
>>  	_FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
>>  	_FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
>> -	_FDT(fdt_property_cell(fdt, "phandle", phandle));
>> +	_FDT(fdt_property_cell(fdt, "phandle", fdt__get_phandle(PHANDLE_GIC)));
>>  	_FDT(fdt_end_node(fdt));
>>  }
>>  
>> diff --git a/include/kvm/fdt.h b/include/kvm/fdt.h
>> index 53d85a4..cd2bb72 100644
>> --- a/include/kvm/fdt.h
>> +++ b/include/kvm/fdt.h
>> @@ -8,6 +8,10 @@
>>  #include <linux/types.h>
>>  
>>  #define FDT_MAX_SIZE	0x10000
>> +#define FDT_INVALID_PHANDLE 0
>> +#define FDT_IS_VALID_PHANDLE(phandle) ((phandle) != FDT_INVALID_PHANDLE)
>> +
>> +enum phandles {PHANDLE_GIC, PHANDLES_MAX};
> 
> Another nit here: PHANDLE_GIC is pretty much ARM-specific, while FDT is
> supposed to be generic. Can't we move the enum to be architecture
> specific and not put this in an architecture agnostic one?

Yes, that indeed makes sense.
This requires an include file for every architecture, but well ...

Cheers,
Andre.

^ permalink raw reply

* [PATCH v8 01/16] FDT: introduce global phandle allocation
From: Andre Przywara @ 2016-12-19 18:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <be44a9ad-f820-9a62-9a5d-682867674e91@arm.com>

Hi Marc,

On 09/12/16 11:55, Marc Zyngier wrote:
> Hi Andre,
> 
> On 04/11/16 17:31, Andre Przywara wrote:
>> Allocating an FDT phandle (a unique identifier) using a static
>> variable in a static inline function defined in a header file works
>> only if all users are in the same source file. So trying to allocate
>> a handle from two different compilation units fails.
>> Introduce global phandle allocation and reference code to properly
>> allocate unique phandles.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>> ---
>>  Makefile          |  1 +
>>  arm/fdt.c         |  2 +-
>>  arm/gic.c         |  2 +-
>>  include/kvm/fdt.h | 10 +++++-----
>>  kvm-fdt.c         | 26 ++++++++++++++++++++++++++
>>  5 files changed, 34 insertions(+), 7 deletions(-)
>>  create mode 100644 kvm-fdt.c
>>
>> diff --git a/Makefile b/Makefile
>> index 1f0196f..e4a4002 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -98,6 +98,7 @@ OBJS	+= kvm-ipc.o
>>  OBJS	+= builtin-sandbox.o
>>  OBJS	+= virtio/mmio.o
>>  OBJS	+= hw/i8042.o
>> +OBJS	+= kvm-fdt.o
>>  
>>  # Translate uname -m into ARCH string
>>  ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/ \
>> diff --git a/arm/fdt.c b/arm/fdt.c
>> index 381d48f..8bcfffb 100644
>> --- a/arm/fdt.c
>> +++ b/arm/fdt.c
>> @@ -114,7 +114,7 @@ static int setup_fdt(struct kvm *kvm)
>>  {
>>  	struct device_header *dev_hdr;
>>  	u8 staging_fdt[FDT_MAX_SIZE];
>> -	u32 gic_phandle		= fdt__alloc_phandle();
>> +	u32 gic_phandle		= fdt__get_phandle(PHANDLE_GIC);
>>  	u64 mem_reg_prop[]	= {
>>  		cpu_to_fdt64(kvm->arch.memory_guest_start),
>>  		cpu_to_fdt64(kvm->ram_size),
>> diff --git a/arm/gic.c b/arm/gic.c
>> index d6d6dd0..b60437e 100644
>> --- a/arm/gic.c
>> +++ b/arm/gic.c
>> @@ -222,7 +222,7 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
>>  	_FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS));
>>  	_FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
>>  	_FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
>> -	_FDT(fdt_property_cell(fdt, "phandle", phandle));
>> +	_FDT(fdt_property_cell(fdt, "phandle", fdt__get_phandle(PHANDLE_GIC)));
>>  	_FDT(fdt_end_node(fdt));
>>  }
>>  
>> diff --git a/include/kvm/fdt.h b/include/kvm/fdt.h
>> index 53d85a4..cd2bb72 100644
>> --- a/include/kvm/fdt.h
>> +++ b/include/kvm/fdt.h
>> @@ -8,6 +8,10 @@
>>  #include <linux/types.h>
>>  
>>  #define FDT_MAX_SIZE	0x10000
>> +#define FDT_INVALID_PHANDLE 0
>> +#define FDT_IS_VALID_PHANDLE(phandle) ((phandle) != FDT_INVALID_PHANDLE)
>> +
>> +enum phandles {PHANDLE_GIC, PHANDLES_MAX};
>>  
>>  /* Those definitions are generic FDT values for specifying IRQ
>>   * types and are used in the Linux kernel internally as well as in
>> @@ -33,10 +37,6 @@ enum irq_type {
>>  		}							\
>>  	} while (0)
>>  
>> -static inline u32 fdt__alloc_phandle(void)
>> -{
>> -	static u32 phandle = 0;
>> -	return ++phandle;
>> -}
>> +u32 fdt__get_phandle(enum phandles phandle);
>>  
>>  #endif /* KVM__FDT_H */
>> diff --git a/kvm-fdt.c b/kvm-fdt.c
>> new file mode 100644
>> index 0000000..d05f3fe
>> --- /dev/null
>> +++ b/kvm-fdt.c
>> @@ -0,0 +1,26 @@
>> +/*
>> + * Commonly used FDT functions.
>> + */
>> +
>> +#include <stdio.h>
>> +#include "kvm/fdt.h"
>> +#include "kvm/util.h"
>> +
>> +u32 phandles[PHANDLES_MAX] = {};
> 
> It is a bit weird that you're initializing this to zero...
> 
>> +u32 next_phandle = 1;
>> +
>> +u32 fdt__get_phandle(enum phandles phandle)
>> +{
>> +	u32 ret;
>> +
>> +	if (phandle >= PHANDLES_MAX)
>> +		return FDT_INVALID_PHANDLE;
>> +
>> +	ret = phandles[phandle];
>> +	if (ret == FDT_INVALID_PHANDLE) {
> 
> and yet test against a #define that isn't the initializer.

Well, yes. The problem is that AFAIK you cannot initialize an array
easily with all the values getting set to something other than zero.
So I could write
	u32 phandles[PHANDLES_MAX] = {FDT_INVALID_PHANDLE};
above, but as that would only set the first member to
FDT_INVALID_PHANDLE (and all the others to 0), so it would rely on the
define actually being zero to work reliably. So my thought was to avoid
readers falling into this trap by not specifying the reset value
explicitly. Also that's the reason that 0 is the invalid value, which I
don't like too much, tbh.

So shall I make this a comment then?

Or do I miss something here?

> Also, given that fdt__get_phandle() can now fail by returning
> FDT_INVALID_HANDLE, maybe we should abort instead of returning something
> that is definitely wrong and use it blindly (which is going to be fun to
> debug...).

Yes, good point. Given that this hints at an internal error, die() seems
to be the appropriate action here.

Cheers,
Andre.

> 
> 
>> +		ret = next_phandle++;
>> +		phandles[phandle] = ret;
>> +	}
>> +
>> +	return ret;
>> +}
>>
> 
> Thanks,
> 
> 	M.
> 

^ permalink raw reply

* [PATCH] ARM: dts: imx: Pass an empty 'chosen' node
From: Uwe Kleine-König @ 2016-12-19 18:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1482161298-32624-1-git-send-email-fabio.estevam@nxp.com>

Hello,

On Mon, Dec 19, 2016 at 01:28:18PM -0200, Fabio Estevam wrote:
> Commit 7f107887d199 ("ARM: dts: imx: Remove skeleton.dtsi") causes boot
> issues when the bootloader does not create a 'chosen' node if such node
> is not present in the dtb.
> 
> The reason for the boot failure is well explained by Javier Martinez
> Canillas: "the decompressor relies on a pre-existing chosen node to be
> available to insert the command line and merge other ATAGS info."
> 
> , so pass an empty 'chosen' node to fix the boot problem.
> 
> This issue has been seen in the kernelci reports with Barebox as
> bootloader.

wouldn't it be better to fix the decompressor code to eventually create
the /chosen node when it doesn't exist?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* [PATCH v8 1/8] soc: samsung: add exynos chipid driver support
From: Krzysztof Kozlowski @ 2016-12-19 18:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9b64f5c0-e289-9091-c784-ae4bfad3caf5@samsung.com>

On Mon, Dec 19, 2016 at 3:29 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>
> Hi Markus,
>
> On Monday 19 December 2016 05:29 PM, Markus Reichl wrote:
> > Hi Pankaj,
> >
> > tested your patches 1/8 and 2/8 + Javiers diff for verbose output:
> > https://www.spinics.net/lists/linux-samsung-soc/msg56576.html
> >
> > on Odroid U3:
> > [    0.080178] Exynos: CPU[UNKNOWN] CPU_REV[0x20] PKG_ID[0x602d058] AUX_INFO[0x0]
> > on Odroid X:
> > [    0.080169] Exynos: CPU[UNKNOWN] CPU_REV[0x11] PKG_ID[0x1b0f6008] AUX_INFO[0x0]

Hmm.... this needs fixes.

Best regards,
Krzysztof

^ permalink raw reply

* [PATCH] clocksource: arm_arch_timer: print timer value at init time
From: Olof Johansson @ 2016-12-19 17:47 UTC (permalink / raw)
  To: linux-arm-kernel

This is useful to get an indication of how much time we spent in firmware.

It's not guaranteed that the timer started at 0 on reset, so it's just
an approximation, and might very well be invalid on some systems. But
it's still a useful metric to have access to.

Signed-off-by: Olof Johansson <olof@lixom.net>
---
 drivers/clocksource/arm_arch_timer.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 02fef68..c26078b 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -521,6 +521,8 @@ arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
 
 static void arch_timer_banner(unsigned type)
 {
+	unsigned long cnt = arch_timer_read_counter();
+
 	pr_info("Architected %s%s%s timer(s) running at %lu.%02luMHz (%s%s%s).\n",
 		     type & ARCH_CP15_TIMER ? "cp15" : "",
 		     type == (ARCH_CP15_TIMER | ARCH_MEM_TIMER) ?  " and " : "",
@@ -534,6 +536,8 @@ static void arch_timer_banner(unsigned type)
 		     type & ARCH_MEM_TIMER ?
 			arch_timer_mem_use_virtual ? "virt" : "phys" :
 			"");
+	pr_info("Initial timer value: 0x%lx: %ld.%02lds\n",
+		cnt, cnt/arch_timer_rate, (cnt/(arch_timer_rate/100)) % 100);
 }
 
 u32 arch_timer_get_rate(void)
-- 
2.8.0.rc3.29.gb552ff8

^ permalink raw reply related

* [PATCH 1/3] dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor
From: Laurent Pinchart @ 2016-12-19 17:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <C246CAC1457055469EF09E3A7AC4E11A4A65D58E@XAP-PVEXMBX01.xlnx.xilinx.com>

Hi Kedar,

On Monday 19 Dec 2016 15:39:43 Appana Durga Kedareswara Rao wrote:
> Hi Laurent Pinchart,
> 
> 	Thanks for the review...
> 
> > > +	if (!chan->idle)
> > > +		return;
> > 
> > Don't you need to perform the same check for the DMA and CDMA channels ?
> > If so, shouldn't this be moved to common code ?
> 
> Will fix it in v2...
> 
> > There's another problem (not strictly introduced by this patch) I wanted
> > to mention. The append_desc_queue() function, called from your tx_submit
> > handler, appends descriptors to the pending_list. The DMA engine API
> > states that a transfer submitted by tx_submit will not be executed until
> > .issue_pending() is called. However, if a transfer is in progress at
> > tx_submit time, I believe that the IRQ handler, at transfer completion,
> > will start the next transfer from the pending_list even if
> > .issue_pending() hasn't been called for it.
> > 
> > >  	if (list_empty(&chan->pending_list))
> > >  		return;
> 
> If user submits more than h/w limit then that case only driver will process
> The descriptors from the pending_list for other cases the pending_list will
> be Empty so driver just returns from there.

I understand that, but that's not the problem. Your .tx_submit() handler calls 
append_desc_queue() which adds the tx descriptor to the pending_list. If a 
transfer is in progress at that time, I believe the transfer completion IRQ 
handler will take the next descriptor from the pending_list and process it, 
even though issue_pending() hasn't been called for it.

> > Now that you catch busy channels with a software flag, do you still need
> > the xilinx_dma_is_running() and xilinx_dma_is_idle() checks ? Three
> > different checks for the same or very similar conditions are confusing,
> > if you really need them you should document clearly how they differ.
> 
> Will remove the xilinx_dma_is_running and xilinx_dmais_idle() checks and
> will use Chan->idle check across all the IP's. Will fix it v2...
> 
> > > @@ -1110,6 +1116,7 @@ static void xilinx_vdma_start_transfer(struct
> > > xilinx_dma_chan *chan) vdma_desc_write(chan, XILINX_DMA_REG_VSIZE,
> > > last->hw.vsize);
> > > 
> > >  	}
> > > 
> > > +	chan->idle = false;
> > 
> > (and this too)
> 
> Will fix in v2...

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* [PATCH v10 6/8] arm/arm64: vgic: Implement VGICv3 CPU interface access
From: Auger Eric @ 2016-12-19 17:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480576187-5012-7-git-send-email-vijay.kilari@gmail.com>

Hi Vijaya, Christoffer,

On 01/12/2016 08:09, vijay.kilari at gmail.com wrote:
> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> 
> VGICv3 CPU interface registers are accessed using
> KVM_DEV_ARM_VGIC_CPU_SYSREGS ioctl. These registers are accessed
> as 64-bit. The cpu MPIDR value is passed along with register id.
> is used to identify the cpu for registers access.
> 
> The VM that supports SEIs expect it on destination machine to handle
> guest aborts and hence checked for ICC_CTLR_EL1.SEIS compatibility.
> Similarly, VM that supports Affinity Level 3 that is required for AArch64
> mode, is required to be supported on destination machine. Hence checked
> for ICC_CTLR_EL1.A3V compatibility.
> 
> The arch/arm64/kvm/vgic-sys-reg-v3.c handles read and write of VGIC
> CPU registers for AArch64.
> 
> For AArch32 mode, arch/arm/kvm/vgic-v3-coproc.c file is created but
> APIs are not implemented.
> 
> Updated arch/arm/include/uapi/asm/kvm.h with new definitions
> required to compile for AArch32.
> 
> The version of VGIC v3 specification is define here
> Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> 
> Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> ---
>  arch/arm/include/uapi/asm/kvm.h     |   2 +
>  arch/arm/kvm/Makefile               |   4 +-
>  arch/arm/kvm/vgic-v3-coproc.c       |  35 ++++
>  arch/arm64/include/uapi/asm/kvm.h   |   3 +
>  arch/arm64/kvm/Makefile             |   3 +-
>  arch/arm64/kvm/vgic-sys-reg-v3.c    | 338 ++++++++++++++++++++++++++++++++++++
>  include/kvm/arm_vgic.h              |   9 +
>  virt/kvm/arm/vgic/vgic-kvm-device.c |  28 +++
>  virt/kvm/arm/vgic/vgic-mmio-v3.c    |  18 ++
>  virt/kvm/arm/vgic/vgic-v3.c         |   8 +
>  virt/kvm/arm/vgic/vgic.h            |   4 +
>  11 files changed, 449 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> index 0ae6035..98658d9d 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -186,9 +186,11 @@ struct kvm_arch_memory_slot {
>  			(0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
>  #define   KVM_DEV_ARM_VGIC_OFFSET_SHIFT	0
>  #define   KVM_DEV_ARM_VGIC_OFFSET_MASK	(0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
> +#define   KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
>  #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS	3
>  #define KVM_DEV_ARM_VGIC_GRP_CTRL       4
>  #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
> +#define KVM_DEV_ARM_VGIC_CPU_SYSREGS    6
nit: arm-vgic-v3.txt spec uses that name. To be homogeneous with other
groups, shouldn't we correct this into KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS?

Thanks

Eric
>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT    0
>  
>  /* KVM_IRQ_LINE irq field index values */
> diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
> index d571243..68fb023 100644
> --- a/arch/arm/kvm/Makefile
> +++ b/arch/arm/kvm/Makefile
> @@ -7,7 +7,7 @@ ifeq ($(plus_virt),+virt)
>  	plus_virt_def := -DREQUIRES_VIRT=1
>  endif
>  
> -ccflags-y += -Iarch/arm/kvm
> +ccflags-y += -Iarch/arm/kvm -Ivirt/kvm/arm/vgic
>  CFLAGS_arm.o := -I. $(plus_virt_def)
>  CFLAGS_mmu.o := -I.
>  
> @@ -20,7 +20,7 @@ kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vf
>  obj-$(CONFIG_KVM_ARM_HOST) += hyp/
>  obj-y += kvm-arm.o init.o interrupts.o
>  obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
> -obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o
> +obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o vgic-v3-coproc.o
>  obj-y += $(KVM)/arm/aarch32.o
>  
>  obj-y += $(KVM)/arm/vgic/vgic.o
> diff --git a/arch/arm/kvm/vgic-v3-coproc.c b/arch/arm/kvm/vgic-v3-coproc.c
> new file mode 100644
> index 0000000..f41abf7
> --- /dev/null
> +++ b/arch/arm/kvm/vgic-v3-coproc.c
> @@ -0,0 +1,35 @@
> +/*
> + * VGIC system registers handling functions for AArch32 mode
> + *
> + * 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.
> + */
> +
> +#include <linux/kvm.h>
> +#include <linux/kvm_host.h>
> +#include <asm/kvm_emulate.h>
> +#include "vgic.h"
> +
> +int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> +				 u64 *reg)
> +{
> +	/*
> +	 * TODO: Implement for AArch32
> +	 */
> +	return -ENXIO;
> +}
> +
> +int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> +				u64 *reg)
> +{
> +	/*
> +	 * TODO: Implement for AArch32
> +	 */
> +	return -ENXIO;
> +}
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index 56dc08d..91c7137 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -206,9 +206,12 @@ struct kvm_arch_memory_slot {
>  			(0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
>  #define   KVM_DEV_ARM_VGIC_OFFSET_SHIFT	0
>  #define   KVM_DEV_ARM_VGIC_OFFSET_MASK	(0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
> +#define   KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
>  #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS	3
>  #define KVM_DEV_ARM_VGIC_GRP_CTRL	4
>  #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
> +#define KVM_DEV_ARM_VGIC_CPU_SYSREGS    6
> +
>  #define   KVM_DEV_ARM_VGIC_CTRL_INIT	0
>  
>  /* Device Control API on vcpu fd */
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index d50a82a..d89aa50 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -2,7 +2,7 @@
>  # Makefile for Kernel-based Virtual Machine module
>  #
>  
> -ccflags-y += -Iarch/arm64/kvm
> +ccflags-y += -Iarch/arm64/kvm -Ivirt/kvm/arm/vgic
>  CFLAGS_arm.o := -I.
>  CFLAGS_mmu.o := -I.
>  
> @@ -19,6 +19,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += guest.o debug.o reset.o sys_regs.o sys_regs_generic_v8.o
> +kvm-$(CONFIG_KVM_ARM_HOST) += vgic-sys-reg-v3.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/aarch32.o
>  
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic.o
> diff --git a/arch/arm64/kvm/vgic-sys-reg-v3.c b/arch/arm64/kvm/vgic-sys-reg-v3.c
> new file mode 100644
> index 0000000..76663f9
> --- /dev/null
> +++ b/arch/arm64/kvm/vgic-sys-reg-v3.c
> @@ -0,0 +1,338 @@
> +/*
> + * VGIC system registers handling functions for AArch64 mode
> + *
> + * 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.
> + */
> +
> +#include <linux/irqchip/arm-gic-v3.h>
> +#include <linux/kvm.h>
> +#include <linux/kvm_host.h>
> +#include <asm/kvm_emulate.h>
> +#include "vgic.h"
> +#include "sys_regs.h"
> +
> +static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			    const struct sys_reg_desc *r)
> +{
> +	u32 host_pri_bits, host_id_bits, host_seis, host_a3v, seis, a3v;
> +	struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
> +	struct vgic_vmcr vmcr;
> +	u64 val;
> +
> +	vgic_get_vmcr(vcpu, &vmcr);
> +	if (p->is_write) {
> +		val = p->regval;
> +
> +		/*
> +		 * Disallow restoring VM state if not supported by this
> +		 * hardware.
> +		 */
> +		host_pri_bits = ((val & ICC_CTLR_EL1_PRI_BITS_MASK) >>
> +				 ICC_CTLR_EL1_PRI_BITS_SHIFT) + 1;
> +		if (host_pri_bits > vgic_v3_cpu->num_pri_bits)
> +			return false;
> +
> +		vgic_v3_cpu->num_pri_bits = host_pri_bits;
> +
> +		host_id_bits = (val & ICC_CTLR_EL1_ID_BITS_MASK) >>
> +				ICC_CTLR_EL1_ID_BITS_SHIFT;
> +		if (host_id_bits > vgic_v3_cpu->num_id_bits)
> +			return false;
> +
> +		vgic_v3_cpu->num_id_bits = host_id_bits;
> +
> +		host_seis = ((kvm_vgic_global_state.ich_vtr_el2 &
> +			     ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT);
> +		seis = (val & ICC_CTLR_EL1_SEIS_MASK) >>
> +			ICC_CTLR_EL1_SEIS_SHIFT;
> +		if (host_seis != seis)
> +			return false;
> +
> +		host_a3v = ((kvm_vgic_global_state.ich_vtr_el2 &
> +			    ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT);
> +		a3v = (val & ICC_CTLR_EL1_A3V_MASK) >> ICC_CTLR_EL1_A3V_SHIFT;
> +		if (host_a3v != a3v)
> +			return false;
> +
> +		vmcr.ctlr = val & ICC_CTLR_EL1_CBPR_MASK;
> +		vmcr.ctlr |= val & ICC_CTLR_EL1_EOImode_MASK;
> +		vgic_set_vmcr(vcpu, &vmcr);
> +	} else {
> +		val = 0;
> +		val |= (vgic_v3_cpu->num_pri_bits - 1) <<
> +			ICC_CTLR_EL1_PRI_BITS_SHIFT;
> +		val |= vgic_v3_cpu->num_id_bits << ICC_CTLR_EL1_ID_BITS_SHIFT;
> +		val |= ((kvm_vgic_global_state.ich_vtr_el2 &
> +			ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT) <<
> +			ICC_CTLR_EL1_SEIS_SHIFT;
> +		val |= ((kvm_vgic_global_state.ich_vtr_el2 &
> +			ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) <<
> +			ICC_CTLR_EL1_A3V_SHIFT;
> +		val |= vmcr.ctlr & ICC_CTLR_EL1_CBPR_MASK;
> +		val |= vmcr.ctlr & ICC_CTLR_EL1_EOImode_MASK;
> +
> +		p->regval = val;
> +	}
> +
> +	return true;
> +}
> +
> +static bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			   const struct sys_reg_desc *r)
> +{
> +	struct vgic_vmcr vmcr;
> +
> +	vgic_get_vmcr(vcpu, &vmcr);
> +	if (p->is_write) {
> +		vmcr.pmr = (p->regval & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT;
> +		vgic_set_vmcr(vcpu, &vmcr);
> +	} else {
> +		p->regval = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK;
> +	}
> +
> +	return true;
> +}
> +
> +static bool access_gic_bpr0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			    const struct sys_reg_desc *r)
> +{
> +	struct vgic_vmcr vmcr;
> +
> +	vgic_get_vmcr(vcpu, &vmcr);
> +	if (p->is_write) {
> +		vmcr.bpr = (p->regval & ICC_BPR0_EL1_MASK) >>
> +			    ICC_BPR0_EL1_SHIFT;
> +		vgic_set_vmcr(vcpu, &vmcr);
> +	} else {
> +		p->regval = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) &
> +			     ICC_BPR0_EL1_MASK;
> +	}
> +
> +	return true;
> +}
> +
> +static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			    const struct sys_reg_desc *r)
> +{
> +	struct vgic_vmcr vmcr;
> +
> +	if (!p->is_write)
> +		p->regval = 0;
> +
> +	vgic_get_vmcr(vcpu, &vmcr);
> +	if (!((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT)) {
> +		if (p->is_write) {
> +			vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >>
> +				     ICC_BPR1_EL1_SHIFT;
> +			vgic_set_vmcr(vcpu, &vmcr);
> +		} else {
> +			p->regval = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) &
> +				     ICC_BPR1_EL1_MASK;
> +		}
> +	} else {
> +		if (!p->is_write)
> +			p->regval = min((vmcr.bpr + 1), 7U);
> +	}
> +
> +	return true;
> +}
> +
> +static bool access_gic_grpen0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			      const struct sys_reg_desc *r)
> +{
> +	struct vgic_vmcr vmcr;
> +
> +	vgic_get_vmcr(vcpu, &vmcr);
> +	if (p->is_write) {
> +		vmcr.grpen0 = (p->regval & ICC_IGRPEN0_EL1_MASK) >>
> +			       ICC_IGRPEN0_EL1_SHIFT;
> +		vgic_set_vmcr(vcpu, &vmcr);
> +	} else {
> +		p->regval = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) &
> +			     ICC_IGRPEN0_EL1_MASK;
> +	}
> +
> +	return true;
> +}
> +
> +static bool access_gic_grpen1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			      const struct sys_reg_desc *r)
> +{
> +	struct vgic_vmcr vmcr;
> +
> +	vgic_get_vmcr(vcpu, &vmcr);
> +	if (p->is_write) {
> +		vmcr.grpen1 = (p->regval & ICC_IGRPEN1_EL1_MASK) >>
> +			       ICC_IGRPEN1_EL1_SHIFT;
> +		vgic_set_vmcr(vcpu, &vmcr);
> +	} else {
> +		p->regval = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) &
> +			     ICC_IGRPEN1_EL1_MASK;
> +	}
> +
> +	return true;
> +}
> +
> +static void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu,
> +				   struct sys_reg_params *p, u8 apr, u8 idx)
> +{
> +	struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
> +	uint32_t *ap_reg;
> +
> +	if (apr)
> +		ap_reg = &vgicv3->vgic_ap1r[idx];
> +	else
> +		ap_reg = &vgicv3->vgic_ap0r[idx];
> +
> +	if (p->is_write)
> +		*ap_reg = p->regval;
> +	else
> +		p->regval = *ap_reg;
> +}
> +
> +static bool access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			    const struct sys_reg_desc *r, u8 apr)
> +{
> +	struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
> +	u8 idx = r->Op2 & 3;
> +
> +	/*
> +	 * num_pri_bits are initialized with HW supported values.
> +	 * We can rely safely on num_pri_bits even if VM has not
> +	 * restored ICC_CTLR_EL1 before restoring APnR registers.
> +	 */
> +	switch (vgic_v3_cpu->num_pri_bits) {
> +	case 7:
> +		vgic_v3_access_apr_reg(vcpu, p, apr, idx);
> +		break;
> +	case 6:
> +		if (idx > 1)
> +			goto err;
> +		vgic_v3_access_apr_reg(vcpu, p, apr, idx);
> +		break;
> +	default:
> +		if (idx > 0)
> +			goto err;
> +		vgic_v3_access_apr_reg(vcpu, p, apr, idx);
> +	}
> +
> +	return true;
> +err:
> +	if (!p->is_write)
> +		p->regval = 0;
> +
> +	return false;
> +}
> +
> +static bool access_gic_ap0r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			    const struct sys_reg_desc *r)
> +
> +{
> +	return access_gic_aprn(vcpu, p, r, 0);
> +}
> +
> +static bool access_gic_ap1r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			    const struct sys_reg_desc *r)
> +{
> +	return access_gic_aprn(vcpu, p, r, 1);
> +}
> +
> +static bool access_gic_sre(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> +			   const struct sys_reg_desc *r)
> +{
> +	struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
> +
> +	/* Validate SRE bit */
> +	if (p->is_write) {
> +		if (!(p->regval & ICC_SRE_EL1_SRE))
> +			return false;
> +	} else {
> +		p->regval = vgicv3->vgic_sre;
> +	}
> +
> +	return true;
> +}
> +static const struct sys_reg_desc gic_v3_icc_reg_descs[] = {
> +	/* ICC_PMR_EL1 */
> +	{ Op0(3), Op1(0), CRn(4), CRm(6), Op2(0), access_gic_pmr },
> +	/* ICC_BPR0_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(3), access_gic_bpr0 },
> +	/* ICC_AP0R0_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(4), access_gic_ap0r },
> +	/* ICC_AP0R1_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(5), access_gic_ap0r },
> +	/* ICC_AP0R2_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(6), access_gic_ap0r },
> +	/* ICC_AP0R3_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(7), access_gic_ap0r },
> +	/* ICC_AP1R0_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(9), Op2(0), access_gic_ap1r },
> +	/* ICC_AP1R1_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(9), Op2(1), access_gic_ap1r },
> +	/* ICC_AP1R2_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(9), Op2(2), access_gic_ap1r },
> +	/* ICC_AP1R3_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(9), Op2(3), access_gic_ap1r },
> +	/* ICC_BPR1_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(3), access_gic_bpr1 },
> +	/* ICC_CTLR_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(4), access_gic_ctlr },
> +	/* ICC_SRE_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(5), access_gic_sre },
> +	/* ICC_IGRPEN0_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(6), access_gic_grpen0 },
> +	/* ICC_GRPEN1_EL1 */
> +	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(7), access_gic_grpen1 },
> +};
> +
> +int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> +				u64 *reg)
> +{
> +	struct sys_reg_params params;
> +	u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
> +
> +	params.regval = *reg;
> +	params.is_write = is_write;
> +	params.is_aarch32 = false;
> +	params.is_32bit = false;
> +
> +	if (find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs,
> +			      ARRAY_SIZE(gic_v3_icc_reg_descs)))
> +		return 0;
> +
> +	return -ENXIO;
> +}
> +
> +int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> +				u64 *reg)
> +{
> +	struct sys_reg_params params;
> +	const struct sys_reg_desc *r;
> +	u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
> +
> +	if (is_write)
> +		params.regval = *reg;
> +	params.is_write = is_write;
> +	params.is_aarch32 = false;
> +	params.is_32bit = false;
> +
> +	r = find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs,
> +			   ARRAY_SIZE(gic_v3_icc_reg_descs));
> +	if (!r)
> +		return -ENXIO;
> +
> +	if (!r->access(vcpu, &params, r))
> +		return -EINVAL;
> +
> +	if (!is_write)
> +		*reg = params.regval;
> +
> +	return 0;
> +}
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 002f092..730a18a 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -71,6 +71,9 @@ struct vgic_global {
>  
>  	/* GIC system register CPU interface */
>  	struct static_key_false gicv3_cpuif;
> +
> +	/* Cache ICH_VTR_EL2 reg value */
> +	u32			ich_vtr_el2;
>  };
>  
>  extern struct vgic_global kvm_vgic_global_state;
> @@ -269,6 +272,12 @@ struct vgic_cpu {
>  	u64 pendbaser;
>  
>  	bool lpis_enabled;
> +
> +	/* Cache guest priority bits */
> +	u32 num_pri_bits;
> +
> +	/* Cache guest interrupt ID bits */
> +	u32 num_id_bits;
>  };
>  
>  extern struct static_key_false vgic_v2_cpuif_trap;
> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
> index bc7de95..b6266fe 100644
> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
> @@ -16,6 +16,7 @@
>  #include <linux/kvm_host.h>
>  #include <kvm/arm_vgic.h>
>  #include <linux/uaccess.h>
> +#include <asm/kvm_emulate.h>
>  #include <asm/kvm_mmu.h>
>  #include "vgic.h"
>  
> @@ -501,6 +502,14 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
>  		if (!is_write)
>  			*reg = tmp32;
>  		break;
> +	case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
> +		u64 regid;
> +
> +		regid = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK);
> +		ret = vgic_v3_cpu_sysregs_uaccess(vcpu, is_write,
> +						  regid, reg);
> +		break;
> +	}
>  	default:
>  		ret = -EINVAL;
>  		break;
> @@ -534,6 +543,15 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
>  		reg = tmp32;
>  		return vgic_v3_attr_regs_access(dev, attr, &reg, true);
>  	}
> +	case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
> +		u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +		u64 reg;
> +
> +		if (get_user(reg, uaddr))
> +			return -EFAULT;
> +
> +		return vgic_v3_attr_regs_access(dev, attr, &reg, true);
> +	}
>  	}
>  	return -ENXIO;
>  }
> @@ -560,6 +578,15 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
>  		tmp32 = reg;
>  		return put_user(tmp32, uaddr);
>  	}
> +	case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
> +		u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +		u64 reg;
> +
> +		ret = vgic_v3_attr_regs_access(dev, attr, &reg, false);
> +		if (ret)
> +			return ret;
> +		return put_user(reg, uaddr);
> +	}
>  	}
>  
>  	return -ENXIO;
> @@ -578,6 +605,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
>  		break;
>  	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
>  	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
> +	case KVM_DEV_ARM_VGIC_CPU_SYSREGS:
>  		return vgic_v3_has_attr_regs(dev, attr);
>  	case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
>  		return 0;
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> index e4799ae..51439c9 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> @@ -642,6 +642,24 @@ int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
>  		nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers);
>  		break;
>  	}
> +	case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
> +		u64 reg, id;
> +		unsigned long vgic_mpidr, mpidr_reg;
> +		struct kvm_vcpu *vcpu;
> +
> +		vgic_mpidr = (attr->attr & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) >>
> +			      KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT;
> +
> +		/* Convert plain mpidr value to MPIDR reg format */
> +		mpidr_reg = VGIC_TO_MPIDR(vgic_mpidr);
> +
> +		vcpu = kvm_mpidr_to_vcpu(dev->kvm, mpidr_reg);
> +		if (!vcpu)
> +			return -EINVAL;
> +
> +		id = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK);
> +		return vgic_v3_has_cpu_sysregs_attr(vcpu, 0, id, &reg);
> +	}
>  	default:
>  		return -ENXIO;
>  	}
> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
> index c21968b..c98a1c5 100644
> --- a/virt/kvm/arm/vgic/vgic-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-v3.c
> @@ -238,6 +238,13 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
>  		vgic_v3->vgic_sre = 0;
>  	}
>  
> +	vcpu->arch.vgic_cpu.num_id_bits = (kvm_vgic_global_state.ich_vtr_el2 &
> +					   ICH_VTR_ID_BITS_MASK) >>
> +					   ICH_VTR_ID_BITS_SHIFT;
> +	vcpu->arch.vgic_cpu.num_pri_bits = ((kvm_vgic_global_state.ich_vtr_el2 &
> +					    ICH_VTR_PRI_BITS_MASK) >>
> +					    ICH_VTR_PRI_BITS_SHIFT) + 1;
> +
>  	/* Get the show on the road... */
>  	vgic_v3->vgic_hcr = ICH_HCR_EN;
>  }
> @@ -338,6 +345,7 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
>  	 */
>  	kvm_vgic_global_state.nr_lr = (ich_vtr_el2 & 0xf) + 1;
>  	kvm_vgic_global_state.can_emulate_gicv2 = false;
> +	kvm_vgic_global_state.ich_vtr_el2 = ich_vtr_el2;
>  
>  	if (!info->vcpu.start) {
>  		kvm_info("GICv3: no GICV resource entry\n");
> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
> index 9232791..eac272c 100644
> --- a/virt/kvm/arm/vgic/vgic.h
> +++ b/virt/kvm/arm/vgic/vgic.h
> @@ -140,6 +140,10 @@ int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>  			 int offset, u32 *val);
>  int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>  			 int offset, u32 *val);
> +int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> +			 u64 id, u64 *val);
> +int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> +				u64 *reg);
>  int kvm_register_vgic_device(unsigned long type);
>  void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
>  void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
> 

^ permalink raw reply

* [PATCH] drm: tilcdc: simplify the recovery from sync lost error on rev1
From: Jyri Sarha @ 2016-12-19 16:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMpxmJVHXoP0BokfbPwQmC=eBaNfS5yfG77EB_MnScmSbUVAdA@mail.gmail.com>

On 12/19/16 16:19, Bartosz Golaszewski wrote:
>> I would add here:
>> +               if ((tilcdc_read(dev, LCDC_RASTER_CTRL_REG) &
>> +                               LCDC_RASTER_ENABLE)) {
>>
>>> +                     tilcdc_clear(dev,
>>> +                                  LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
>>> +                     tilcdc_set(dev,
>>> +                                LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
>> +               }
>>
>> Just in case the interrupt is for some reason handled right after the
>> crtc is disabled.
>>
>> With this addition I could send a pull request for this fix still today,
>> if you agree with the change.
> I'm not sure this can really happen, but it won't hurt either, so I'll
> send a v2.

Well, in theory it is quite possible. If the driver clears the raster
enable at the same time when sync lost interrupt is generated, then the
irq routine handles the irq before the interrupts are disabled. Then it
happens that rastere remains on but the driver thinks it has already
turned it off.

In practice this is of course terribly unlikely, but a race is a race
and should be avoided.

Anyway, my vacation has already been started so I won't send a pull
request now. I do not like the idea of doing something like that and
then vanishing for two weeks. I hope they still take fixes for 4.10 in
4th Jan.

Best regards,
Jyri

^ permalink raw reply

* [PATCH v2 03/10] dt-bindings: perf: hisi: Add Devicetree bindings for Hisilicon SoC PMU
From: Rob Herring @ 2016-12-19 16:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481129759-159533-1-git-send-email-anurup.m@huawei.com>

On Wed, Dec 07, 2016 at 11:55:59AM -0500, Anurup M wrote:
> 1) Device tree bindings for Hisilicon SoC PMU.
> 2) Add example for Hisilicon L3 cache and MN PMU.
> 3) Add child nodes of L3C and MN in djtag bindings example.
> 
> Signed-off-by: Anurup M <anurup.m@huawei.com>
> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> ---
>  .../devicetree/bindings/arm/hisilicon/djtag.txt    | 25 ++++++
>  .../devicetree/bindings/arm/hisilicon/pmu.txt      | 98 ++++++++++++++++++++++
>  2 files changed, 123 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt b/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
> index 733498e..c885507 100644
> --- a/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
> +++ b/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
> @@ -27,6 +27,31 @@ Example 1: Djtag for CPU die
>  		scl-id = <0x02>;
>  
>  		/* All connecting components will appear as child nodes */
> +
> +		pmul3c0 {
> +			compatible = "hisilicon,hisi-pmu-l3c-v1";
> +			module-id = <0x04 0x02>;
> +		};
> +
> +		pmul3c1 {
> +			compatible = "hisilicon,hisi-pmu-l3c-v1";
> +			module-id = <0x04 0x04>;
> +		};
> +
> +		pmul3c2 {
> +			compatible = "hisilicon,hisi-pmu-l3c-v1";
> +			module-id = <0x04 0x01>;
> +		};
> +
> +		pmul3c3 {
> +			compatible = "hisilicon,hisi-pmu-l3c-v1";
> +			module-id = <0x04 0x08>;
> +		};
> +
> +		pmumn0 {
> +			compatible = "hisilicon,hisi-pmu-mn-v1";
> +			module-id = <0x0b>;
> +		};
>  	};
>  
>  Example 2: Djtag for IO die
> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
> new file mode 100644
> index 0000000..e2160ad
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/hisilicon/pmu.txt
> @@ -0,0 +1,98 @@
> +Hisilicon SoC HiP05/06/07 ARMv8 PMU
> +===================================
> +
> +The Hisilicon SoC chips like HiP05/06/07 etc. consist of various independent
> +system device PMUs such as L3 cache (L3C) and Miscellaneous Nodes(MN). These
> +PMU devices are independent and have hardware logic to gather statistics and
> +performance information.
> +
> +HiSilicon SoC chip is encapsulated by multiple CPU and IO dies. The CPU die
> +is called as Super CPU cluster (SCCL) which includes 16 cpu-cores. Every SCCL
> +in HiP05/06/07 chips are further grouped as CPU clusters (CCL) which includes
> +4 cpu-cores each.
> +e.g. In the case of HiP05/06/07, each SCCL has 1 L3 cache and 1 MN PMU device.
> +The L3 cache is further grouped as 4 L3 cache banks in a SCCL.
> +
> +The Hisilicon SoC PMU DT node bindings for uncore PMU devices are as below.
> +For PMU devices like L3 cache. MN etc. which are accessed using the djtag,
> +the parent node will be the djtag node of the corresponding CPU die (SCCL).
> +
> +L3 cache
> +---------
> +The L3 cache is dedicated for each SCCL. Each SCCL in HiP05/06/07 chips have 4
> +L3 cache banks. Each L3 cache bank have separate DT nodes.
> +
> +Required properties:
> +
> +	- compatible : This value should be as follows
> +		(a) "hisilicon,hisi-pmu-l3c-v1" for v1 hw in HiP05/06 chips
> +		(b) "hisilicon,hisi-pmu-l3c-v2" for v2 hw in HiP07 chip

Use SoC specific compatible strings.

> +
> +	- module-id : This property is a combination of two values in the below order.
> +		      a) Module ID: The module identifier for djtag.
> +		      b) Instance or Bank ID: This will identify the L3 cache bank
> +			 or instance.

Needs a vendor prefix.

> +
> +Optional properties:
> +
> +	- interrupt-parent : A phandle indicating which interrupt controller
> +		this PMU signals interrupts to.
> +
> +	- interrupts : Interrupt lines used by this L3 cache bank.

How many interrupts and what are they?

> +
> +	*The counter overflow IRQ is not supported in v1 hardware (HiP05/06).
> +
> +Miscellaneous Node
> +------------------
> +The MN is dedicated for each SCCL and hence there are separate DT nodes for MN
> +for each SCCL.

Similar comments here.

> +
> +Required properties:
> +
> +	- compatible : This value should be as follows
> +		(a) "hisilicon,hisi-pmu-mn-v1" for v1 hw in HiP05/06 chips
> +		(b) "hisilicon,hisi-pmu-mn-v2" for v2 hw in HiP07 chip
> +
> +	- module-id : Module ID to input for djtag.
> +
> +Optional properties:
> +
> +	- interrupt-parent : A phandle indicating which interrupt controller
> +		this PMU signals interrupts to.
> +
> +	- interrupts : Interrupt lines used by this PMU.
> +
> +	*The counter overflow IRQ is not supported in v1 hardware (HiP05/06).
> +
> +Example:
> +
> +	djtag0: djtag at 80010000 {
> +		compatible = "hisilicon,hisi-djtag-v1";
> +		reg = <0x0 0x80010000 0x0 0x10000>;
> +		scl-id = <0x02>;
> +
> +		pmul3c0 {
> +			compatible = "hisilicon,hisi-pmu-l3c-v1";
> +			module-id = <0x04 0x02>;
> +		};
> +
> +		pmul3c1 {
> +			compatible = "hisilicon,hisi-pmu-l3c-v1";
> +			module-id = <0x04 0x04>;
> +		};
> +
> +		pmul3c2 {
> +			compatible = "hisilicon,hisi-pmu-l3c-v1";
> +			module-id = <0x04 0x01>;
> +		};
> +
> +		pmul3c3 {
> +			compatible = "hisilicon,hisi-pmu-l3c-v1";
> +			module-id = <0x04 0x08>;
> +		};
> +
> +		pmumn0 {
> +			compatible = "hisilicon,hisi-pmu-mn-v1";
> +			module-id = <0x0b>;
> +		};
> +	};
> -- 
> 2.1.4
> 

^ permalink raw reply

* [PATCH v2 02/10] dt-bindings: hisi: Add Hisilicon HiP05/06/07 Djtag dts bindings
From: Rob Herring @ 2016-12-19 16:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481129719-159487-1-git-send-email-anurup.m@huawei.com>

On Wed, Dec 07, 2016 at 11:55:19AM -0500, Anurup M wrote:
> From: Tan Xiaojun <tanxiaojun@huawei.com>
> 
> Add Hisilicon HiP05/06/07 Djtag dts bindings for CPU and IO Die
> 
> Signed-off-by: Tan Xiaojun <tanxiaojun@huawei.com>
> Signed-off-by: Anurup M <anurup.m@huawei.com>
> ---
>  .../devicetree/bindings/arm/hisilicon/djtag.txt    | 41 ++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt b/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
> new file mode 100644
> index 0000000..733498e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/hisilicon/djtag.txt
> @@ -0,0 +1,41 @@
> +The Hisilicon Djtag is an independent component which connects with some other
> +components in the SoC by Debug Bus. The djtag is available in CPU and IO dies
> +in the chip. The djtag controls access to connecting modules of CPU and IO
> +dies.
> +The various connecting components in CPU die (like L3 cache, L3 cache PMU etc.)
> +are accessed by djtag during real time debugging. In IO die there are connecting
> +components like RSA. These components appear as devices atatched to djtag bus.
> +
> +Hisilicon HiP05/06 djtag for CPU and HiP05 IO die
> +Required properties:
> +  - compatible : "hisilicon,hisi-djtag-v1"

These need SoC specific compatible strings. They probably should 
also include cpu or io in the compatible string. I would expect there 
are things like events, triggers, or component connections for debug 
that are SoC specifc.

> +  - reg : Register address and size
> +  - scl-id : The Super Cluster ID for CPU or IO die
> +
> +Hisilicon HiP06 djtag for IO die and HiP07 djtag for CPU and IO die
> +Required properties:
> +  - compatible : "hisilicon,hisi-djtag-v2"

Same here.

> +  - reg : Register address and size
> +  - scl-id : The Super Cluster ID for CPU or IO die
> +
> +Example 1: Djtag for CPU die
> +
> +	/* for Hisilicon HiP05 djtag for CPU Die */
> +	djtag0: djtag at 80010000 {
> +		compatible = "hisilicon,hisi-djtag-v1";
> +		reg = <0x0 0x80010000 0x0 0x10000>;
> +		scl-id = <0x02>;
> +
> +		/* All connecting components will appear as child nodes */
> +	};
> +
> +Example 2: Djtag for IO die
> +
> +	/* for Hisilicon HiP05 djtag for IO Die */
> +	djtag1: djtag at d0000000 {
> +		compatible = "hisilicon,hisi-djtag-v1";
> +		reg = <0x0 0xd0000000 0x0 0x10000>;
> +		scl-id = <0x01>;
> +
> +		/* All connecting components will appear as child nodes */
> +	};
> -- 
> 2.1.4
> 

^ permalink raw reply

* Problems to Allwinner H3's eFUSE/SID
From: Hans de Goede @ 2016-12-19 16:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <13032681482164747@web30h.yandex.ru>

Hi,

On 19-12-16 17:25, Icenowy Zheng wrote:
>
>
> 20.12.2016, 00:17, "Hans de Goede" <hdegoede@redhat.com>:
>> Hi,
>>
>> On 19-12-16 17:06, Icenowy Zheng wrote:
>>>  19.12.2016, 23:30, "Hans de Goede" <hdegoede@redhat.com>:
>>>>  Hi,
>>>>
>>>>  On 19-12-16 16:22, Icenowy Zheng wrote:
>>>>>   Hi everyone,
>>>>>
>>>>>   Today, I and KotCzarny on IRC of linux-sunxi found a problem in the SID
>>>>>   controller of H3 (incl. H2+).
>>>>>
>>>>>   See https://irclog.whitequark.org/linux-sunxi/2016-12-19 .
>>>>>
>>>>>   Two read method of the H3 eFUSE is used in the BSP: by register accessing, or
>>>>>   directly access 0x01c14200.
>>>>>
>>>>>   From http://linux-sunxi.org/SID_Register_Guide we can see a difference between
>>>>>   the H3 SIDs read out by sunxi-fel and the H3 SIDs read out by devmem2 (in
>>>>>   legacy kernel).
>>>>>
>>>>>   According to the source of H2+ BSP[1], H2+ and H3 can be differed by the last
>>>>>   byte of the first word of SID. (0x42 and 0x83 is H2+, 0x00 and 0x81 is H3,
>>>>>   0x58 is H3D (currently not known SoC) )
>>>>>
>>>>>   However, all the SIDs retrieved by `sunxi-fel sid`, both H2+ and H3, start
>>>>>   with 0x02004620, which do not match this rule.
>>>>>
>>>>>   The readout by devmem2 is satisfying this rule: their first word is
>>>>>   0x02c00081, matches H3.
>>>>>
>>>>>   Then I found the SID-reading code from BSP U-Boot[2], which is based on
>>>>>   register operations. With this kind of code (I wrote one prototype in
>>>>>   userspace with /dev/mem), I got "02c00081 74004620 50358720 3c27048e" on
>>>>>   my Orange Pi One. ("02004620 74358720 5027048e 3c0000c3" with sunxi-fel sid)
>>>>>   And, after accessing to the SID by registers, the value of *0x01c14200 become
>>>>>   also "02c00081".
>>>>>
>>>>>   With direct access to 0x01c14200 after boot with mainline kernel, I got also
>>>>>   "02004620".
>>>>>
>>>>>   Then I altered the program to do the register operations with sunxi-fel, the
>>>>>   result is also "02c00081", and changed `sunxi-fel sid` result to "02c00081".
>>>>>
>>>>>   Summary:
>>>>>
>>>>>   +-----------------------------------------------+----------------+
>>>>>   | Read situation | The first word |
>>>>>   +-----------------------------------------------+----------------+
>>>>>   | Direct read by sunxi-fel | 02004620 |
>>>>>   | Direct read in mainline /dev/mem | 02004620 |
>>>>>   | Direct read in legacy /dev/mem | 02c00081 |
>>>>>   | Register access in FEL | 02c00081 |
>>>>>   | Register access in mainline | 02c00081 |
>>>>>   | Direct read after register access in FEL | 02c00081 |
>>>>>   | Direct read after register access in mainline | 02c00081 |
>>>>>   +-----------------------------------------------+----------------+
>>>>>
>>>>>   According to some facts:
>>>>>   - The register based access to SID is weird: it needs ~5 register
>>>>>     operations per word of SID.
>>>>>   - Reading via register access will change the value when reading by accessing
>>>>>     0x01c14200.
>>>>>   - In the u-boot code[2] there's some functions which read out the SID by
>>>>>     registers and then abandoned the value.
>>>>>   - This mismatch do not exist on A64.
>>>>>
>>>>>   I think that: Allwinner designed a "cache" to the SID to make the simplify the
>>>>>   code to read it, and it automatically loaded the cache when booting; however,
>>>>>   when doing first cache on H3, some byte shifts occured, and the value become
>>>>>   wrong. A manual read on H3 can make the cache right again. This is a silicon
>>>>>   bug, and fixed in A64.
>>>>>
>>>>>   This raises a problem: currently many systems has used the misread SID value to
>>>>>   generated lots of MAC addresses, and workaround this SID bug will change them.
>>>>>
>>>>>   However, if this bug is not workarounded, the sun8i-ths driver won't work well
>>>>>   (as some calibartion value lies in eFUSE). I think some early user of this
>>>>>   driver has already experienced bad readout value.
>>>>>   (The calibration value differs on my opi1 and KotCzarny's opipc)
>>>>>
>>>>>   And many wrong SID values have been generated by `sunxi-fel sid`. (Although I
>>>>>   think sunxi-fel must have the workaround)
>>>>>
>>>>>   Note: in this email, "SID" and "eFUSE" both indicate the controller on H3/A64
>>>>>   at 0x01c14000, which is a OTP memory implemented by eFUSE technique.
>>>>>
>>>>>   Furthermore, A83T may also have this problem, testers are welcome!
>>>>>
>>>>>   [1] http://filez.zoobab.com/allwinner/h2/201609022/lichee/linux-3.4/arch/arm/mach-sunxi/sun8i.c
>>>>>   [2] http://filez.zoobab.com/allwinner/h2/201609022/lichee/brandy/u-boot-2011.09/arch/arm/cpu/armv7/sun8iw7/efuse.c
>>>>>
>>>>>   Experiments:
>>>>>   - https://gist.github.com/Icenowy/2f4859ab1bc05814522fc7445179a8c9
>>>>>     A SID readout shell script via FEL with register access.
>>>>>   - https://31.135.195.151:20281/d/efuse/
>>>>>     A SID readout program via /dev/mem with register access by KotCzarny.
>>>>>     (with statically compiled binary)
>>>>
>>>>  Good detective work!
>>>>
>>>>  I believe this would best be fixed by making u-boot use the register access
>>>>  method to get the SID on affected chips, and make sure u-boot reads the
>>>>  SID at-least once.
>>>
>>>  Yes.
>>>
>>>  However, what I considered is that fixing this bug will change H3 devices'
>>>  MAC addresses, as they are derived from SID.
>>
>> I know, but I think we will just need to accept this onetime change
>> of the fixed MAC addresses to fix this bug. I don't think this is
>> a big problem since the driver for the H3 ethernet has not been
>> merged into the mainline kernel yet.
>>
>>>  Maybe we should add #ifdef's to MAC generation code after this fix.
>>
>> I would rather not see #ifdefs for this, see above, but that is no
>> longer my call, see below.
>>
>>>  (This is why I will create this discussion)
>>>
>>>  P.S. Are you still the maintainer of sunxi boards support of u-boot? The
>>>  MAINTAINER file in board/sunxi indicates this.
>>
>> No I'm no longer the maintainer, I'm still the MAINTAINER file because
>> I have a lot of boards and as such I'm still the point of contact for
>> those boards (if there are any board specific issues / questions), but
>> as indicated in the main MAINTAINERS file Jagan Teki <jagan@openedev.com>
>> is the maintainer now.
>
> But the current status of the file will indicates you are the maintainer of boards
> support of sunxi.

No it indicates that I'm the maintainer for the defconfig files for a whole list
of boards, nothing more and nothing less.

If you think it needs to be clarified, feel free to submit a patch to make this
more clear.

Regards,

Hans

^ permalink raw reply


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