Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] mm: fix the "counter.sh" failure for libhugetlbfs
From: Vlastimil Babka @ 2016-11-28 14:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479107259-2011-1-git-send-email-shijie.huang@arm.com>

On 11/14/2016 08:07 AM, Huang Shijie wrote:
> (1) Background
>    For the arm64, the hugetlb page size can be 32M (PMD + Contiguous bit).
>    In the 4K page environment, the max page order is 10 (max_order - 1),
>    so 32M page is the gigantic page.
>
>    The arm64 MMU supports a Contiguous bit which is a hint that the TTE
>    is one of a set of contiguous entries which can be cached in a single
>    TLB entry.  Please refer to the arm64v8 mannul :
>        DDI0487A_f_armv8_arm.pdf (in page D4-1811)
>
> (2) The bug
>    After I tested the libhugetlbfs, I found the test case "counter.sh"
>    will fail with the gigantic page (32M page in arm64 board).
>
>    This patch set adds support for gigantic surplus hugetlb pages,
>    allowing the counter.sh unit test to pass.
>
> v1 -- > v2:
>    1.) fix the compiler error in X86.
>    2.) add new patches for NUMA.
>        The patch #2 ~ #5 are new patches.
>
> Huang Shijie (6):
>   mm: hugetlb: rename some allocation functions
>   mm: hugetlb: add a new parameter for some functions
>   mm: hugetlb: change the return type for alloc_fresh_gigantic_page
>   mm: mempolicy: intruduce a helper huge_nodemask()
>   mm: hugetlb: add a new function to allocate a new gigantic page
>   mm: hugetlb: support gigantic surplus pages
>
>  include/linux/mempolicy.h |   8 +++
>  mm/hugetlb.c              | 128 ++++++++++++++++++++++++++++++++++++----------
>  mm/mempolicy.c            |  20 ++++++++
>  3 files changed, 130 insertions(+), 26 deletions(-)

Can't say I'm entirely happy with the continued direction of maze of 
functions for huge page allocation :( Feels like path of least 
resistance to basically copy/paste the missing parts here. Is there no 
way to consolidate the code more?

^ permalink raw reply

* [GIT PULL] ZTE arm64 device tree updates for 4.10
From: Shawn Guo @ 2016-11-28 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd, Olof,

If it's not too late, please pull this for 4.10.  It contains a single
patch which adds clock controller device nodes for zx296718.  Thanks.

Shawn


The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:

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

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/zte-dt64-4.10

for you to fetch changes up to 392ce382743b847eded4b40990de4e78a5eb494d:

  arm64: dts: zx: Add clock controller nodes (2016-10-24 16:54:20 +0800)

----------------------------------------------------------------
ZTE arm64 device tree update for 4.10:

Add clock controller device nodes, including one top clock controller,
two low speed clock controllers and one audio clock controller.

----------------------------------------------------------------
Jun Nie (1):
      arm64: dts: zx: Add clock controller nodes

 arch/arm64/boot/dts/zte/zx296718.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

^ permalink raw reply

* [PATCH V2 fix 5/6] mm: hugetlb: add a new function to allocate a new gigantic page
From: Vlastimil Babka @ 2016-11-28 14:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479279304-31379-1-git-send-email-shijie.huang@arm.com>

On 11/16/2016 07:55 AM, Huang Shijie wrote:
> There are three ways we can allocate a new gigantic page:
>
> 1. When the NUMA is not enabled, use alloc_gigantic_page() to get
>    the gigantic page.
>
> 2. The NUMA is enabled, but the vma is NULL.
>    There is no memory policy we can refer to.
>    So create a @nodes_allowed, initialize it with init_nodemask_of_mempolicy()
>    or init_nodemask_of_node(). Then use alloc_fresh_gigantic_page() to get
>    the gigantic page.
>
> 3. The NUMA is enabled, and the vma is valid.
>    We can follow the memory policy of the @vma.
>
>    Get @nodes_allowed by huge_nodemask(), and use alloc_fresh_gigantic_page()
>    to get the gigantic page.
>
> Signed-off-by: Huang Shijie <shijie.huang@arm.com>
> ---
> Since the huge_nodemask() is changed, we have to change this function a little.
>
> ---
>  mm/hugetlb.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 63 insertions(+)
>
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 6995087..c33bddc 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1502,6 +1502,69 @@ int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
>
>  /*
>   * There are 3 ways this can get called:
> + *
> + * 1. When the NUMA is not enabled, use alloc_gigantic_page() to get
> + *    the gigantic page.
> + *
> + * 2. The NUMA is enabled, but the vma is NULL.
> + *    Create a @nodes_allowed, and use alloc_fresh_gigantic_page() to get
> + *    the gigantic page.
> + *
> + * 3. The NUMA is enabled, and the vma is valid.
> + *    Use the @vma's memory policy.
> + *    Get @nodes_allowed by huge_nodemask(), and use alloc_fresh_gigantic_page()
> + *    to get the gigantic page.
> + */
> +static struct page *__hugetlb_alloc_gigantic_page(struct hstate *h,
> +		struct vm_area_struct *vma, unsigned long addr, int nid)
> +{
> +	NODEMASK_ALLOC(nodemask_t, nodes_allowed, GFP_KERNEL | __GFP_NORETRY);

What if the allocation fails and nodes_allowed is NULL?
It might work fine now, but it's rather fragile, so I'd rather see an 
explicit check.

BTW same thing applies to __nr_hugepages_store_common().

> +	struct page *page = NULL;
> +
> +	/* Not NUMA */
> +	if (!IS_ENABLED(CONFIG_NUMA)) {
> +		if (nid == NUMA_NO_NODE)
> +			nid = numa_mem_id();
> +
> +		page = alloc_gigantic_page(nid, huge_page_order(h));
> +		if (page)
> +			prep_compound_gigantic_page(page, huge_page_order(h));
> +
> +		NODEMASK_FREE(nodes_allowed);
> +		return page;
> +	}
> +
> +	/* NUMA && !vma */
> +	if (!vma) {
> +		if (nid == NUMA_NO_NODE) {
> +			if (!init_nodemask_of_mempolicy(nodes_allowed)) {
> +				NODEMASK_FREE(nodes_allowed);
> +				nodes_allowed = &node_states[N_MEMORY];
> +			}
> +		} else if (nodes_allowed) {
> +			init_nodemask_of_node(nodes_allowed, nid);
> +		} else {
> +			nodes_allowed = &node_states[N_MEMORY];
> +		}
> +
> +		page = alloc_fresh_gigantic_page(h, nodes_allowed, true);
> +
> +		if (nodes_allowed != &node_states[N_MEMORY])
> +			NODEMASK_FREE(nodes_allowed);
> +
> +		return page;
> +	}
> +
> +	/* NUMA && vma */
> +	if (huge_nodemask(vma, addr, nodes_allowed))
> +		page = alloc_fresh_gigantic_page(h, nodes_allowed, true);
> +
> +	NODEMASK_FREE(nodes_allowed);
> +	return page;
> +}
> +
> +/*
> + * There are 3 ways this can get called:
>   * 1. With vma+addr: we use the VMA's memory policy
>   * 2. With !vma, but nid=NUMA_NO_NODE:  We try to allocate a huge
>   *    page from any node, and let the buddy allocator itself figure
>

^ permalink raw reply

* [Qemu-devel] [kvm-unit-tests PATCH v7 00/11] QEMU MTTCG Test cases
From: Peter Maydell @ 2016-11-28 14:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161128140705.caqpoiuvxy3mg2zk@kamzik.brq.redhat.com>

On 28 November 2016 at 14:07, Andrew Jones <drjones@redhat.com> wrote:
> Er... actually mach-virt is 123, as we only allocate 123 redistributors.

Oh yes, I'd forgotten about that limit. We'd need to add
a KVM API for allocating redistributors in non-contiguous
bits of memory if we wanted to raise that.

thanks
-- PMM

^ permalink raw reply

* [PATCH v2 1/2] arm64: dts: zx: Fix gic GICR property
From: Shawn Guo @ 2016-11-28 14:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2953810.EeueujTjSC@wuerfel>

On Sat, Nov 26, 2016 at 6:03 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday, October 17, 2016 1:49:19 PM CET Olof Johansson wrote:
>> On Thu, Oct 13, 2016 at 08:31:20PM +0800, Jun Nie wrote:
>> > GICR for multiple CPU can be described with start address and stride,
>> > or with multiple address. Current multiple address and stride are
>> > both used. Fix it.
>> >
>> > vmalloc patch 727a7f5a9 triggered this bug:
>> > [    0.097146] Unable to handle kernel paging request at virtual address ffff000008060008
>> > [    0.097150] pgd = ffff000008602000
>> > [    0.097160] [ffff000008060008] *pgd=000000007fffe003, *pud=000000007fffd003, *pmd=000000007fffc003, *pte=0000000000000000
>> > [    0.097165] Internal error: Oops: 96000007 [#1] PREEMPT SMP
>> > [    0.097170] Modules linked in:
>> > [    0.097177] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.8.0+ #1474
>> > [    0.097179] Hardware name: ZTE zx296718 evaluation board (DT)
>> > [    0.097183] task: ffff80003e8c8b80 task.stack: ffff80003e8d0000
>> > [    0.097197] PC is at gic_populate_rdist+0x74/0x15c
>> > [    0.097202] LR is at gic_starting_cpu+0xc/0x20
>> > [    0.097206] pc : [<ffff0000082b1b18>] lr : [<ffff0000082b26e0>] pstate: 600001c5
>> >
>> > Signed-off-by: Jun Nie <jun.nie@linaro.org>
>>
>> A Fixes: tag would be useful on a patch like this, to tell what patch
>> introduced the problem. Please consider using them in the future.
>>
>> I've applied this one to fixes now.
>
> Hi Olof,
>
> I happened to still have this one in my todo folder as I must have
> missed your reply, and I stumbled over it while looking for things
> that may have gone missing.
>
> I don't see it in v4.9-rc6, did it get dropped accidentally?

Please help get this into v4.9 if possible, as it is required to get
v4.9 kernel boot up on ZTE ZX296718 SoC.  Thanks.

Shawn

^ permalink raw reply

* [Qemu-devel] [kvm-unit-tests PATCH v7 00/11] QEMU MTTCG Test cases
From: Andrew Jones @ 2016-11-28 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161128140445.j336ksd7vqhi4ivz@kamzik.brq.redhat.com>

On Mon, Nov 28, 2016 at 03:04:45PM +0100, Andrew Jones wrote:
> On Mon, Nov 28, 2016 at 01:30:54PM +0000, Peter Maydell wrote:
> > On 28 November 2016 at 11:58, Andrew Jones <drjones@redhat.com> wrote:
> > > On Mon, Nov 28, 2016 at 11:14:48AM +0000, Peter Maydell wrote:
> > >> On 28 November 2016 at 11:12, Alex Benn?e <alex.bennee@linaro.org> wrote:
> > >> >
> > >> > Andrew Jones <drjones@redhat.com> writes:
> > >> >> I've skimmed over everything looking at it from a framwork/sytle
> > >> >> perspective. I didn't dig in trying to understand the tests though.
> > >> >> One general comment, I see many tests introduce MAX_CPUS 8. Why do
> > >> >> that? Why not allow all cpus by using NR_CPUS for the array sizes?
> > >> >
> > >> > Yeah - I can fix those. I wonder what the maximum is with GIC V3?
> > >>
> > >> So large that you don't want to hardcode it as an array size...
> > >
> > > 255 with the gic series, not yet merged.
> > 
> > I was talking about the architectural GICv3 limit, which is larger
> > than that by many orders of magnitude. For QEMU it looks like
> > MAX_CPUMASK_BITS is now 288 rather than 255.
> 
> Ah, yeah. So far we haven't considered testing limits beyond what
> KVM supports, VGIC_V3_MAX_CPUS=255. However with TCG, and some
> patience, we could attempt to test bigger limits. In that case,
> though, we'll want to recompile kvm-unit-tests with a larger NR_CPUS
> and run a specific unit test.
> 
> mach-virt still has 255 as well, mc->max_cpus = 255, so we'd have
> to bump that too if we want to experiment.

Er... actually mach-virt is 123, as we only allocate 123 redistributors.

drew

^ permalink raw reply

* [Qemu-devel] [kvm-unit-tests PATCH v7 00/11] QEMU MTTCG Test cases
From: Andrew Jones @ 2016-11-28 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAFEAcA8-3qHnp1T4bAiUL3NT8fHWik7-8zruyQKGgfADn5xF9w@mail.gmail.com>

On Mon, Nov 28, 2016 at 01:30:54PM +0000, Peter Maydell wrote:
> On 28 November 2016 at 11:58, Andrew Jones <drjones@redhat.com> wrote:
> > On Mon, Nov 28, 2016 at 11:14:48AM +0000, Peter Maydell wrote:
> >> On 28 November 2016 at 11:12, Alex Benn?e <alex.bennee@linaro.org> wrote:
> >> >
> >> > Andrew Jones <drjones@redhat.com> writes:
> >> >> I've skimmed over everything looking at it from a framwork/sytle
> >> >> perspective. I didn't dig in trying to understand the tests though.
> >> >> One general comment, I see many tests introduce MAX_CPUS 8. Why do
> >> >> that? Why not allow all cpus by using NR_CPUS for the array sizes?
> >> >
> >> > Yeah - I can fix those. I wonder what the maximum is with GIC V3?
> >>
> >> So large that you don't want to hardcode it as an array size...
> >
> > 255 with the gic series, not yet merged.
> 
> I was talking about the architectural GICv3 limit, which is larger
> than that by many orders of magnitude. For QEMU it looks like
> MAX_CPUMASK_BITS is now 288 rather than 255.

Ah, yeah. So far we haven't considered testing limits beyond what
KVM supports, VGIC_V3_MAX_CPUS=255. However with TCG, and some
patience, we could attempt to test bigger limits. In that case,
though, we'll want to recompile kvm-unit-tests with a larger NR_CPUS
and run a specific unit test.

mach-virt still has 255 as well, mc->max_cpus = 255, so we'd have
to bump that too if we want to experiment.

Thanks,
drew

^ permalink raw reply

* [PATCH] ARM: BCM5301X: Enable UART by default for BCM4708(1) and BCM4709(4)
From: Rafał Miłecki @ 2016-11-28 14:01 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rafa? Mi?ecki <rafal@milecki.pl>

Every device tested so far got UART0 (at 0x18000300) working as serial
console. It's most likely part of reference design and all vendors use
it that way.

It seems to be easier to enable it by default and just disable it if we
ever see a device with different hardware design.

Signed-off-by: Rafa? Mi?ecki <rafal@milecki.pl>
---
 arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts  | 4 ----
 arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts       | 4 ----
 arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts       | 4 ----
 arch/arm/boot/dts/bcm4708-netgear-r6250.dts        | 4 ----
 arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts      | 4 ----
 arch/arm/boot/dts/bcm4708.dtsi                     | 4 ++++
 arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 4 ----
 arch/arm/boot/dts/bcm47081.dtsi                    | 4 ++++
 arch/arm/boot/dts/bcm4709-netgear-r7000.dts        | 4 ----
 arch/arm/boot/dts/bcm4709-netgear-r8000.dts        | 4 ----
 arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts  | 4 ----
 arch/arm/boot/dts/bcm4709.dtsi                     | 1 +
 arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts      | 4 ----
 arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts      | 4 ----
 arch/arm/boot/dts/bcm47094-netgear-r8500.dts       | 4 ----
 arch/arm/boot/dts/bcm47094.dtsi                    | 1 +
 16 files changed, 10 insertions(+), 48 deletions(-)

diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
index 9cb186e..d49afec0 100644
--- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
@@ -136,10 +136,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &usb2 {
 	vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
index 35e6ed6..f591b0f 100644
--- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
@@ -55,10 +55,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &spi_nor {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
index 1c7e53d..50d65d8 100644
--- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
@@ -56,10 +56,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &spi_nor {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
index 8ce39d5..8519548 100644
--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
@@ -83,10 +83,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &usb3 {
 	vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
index 70f4bb9..74cfcd3 100644
--- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
@@ -119,10 +119,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &spi_nor {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/bcm4708.dtsi b/arch/arm/boot/dts/bcm4708.dtsi
index eed4dd1..d0eec09 100644
--- a/arch/arm/boot/dts/bcm4708.dtsi
+++ b/arch/arm/boot/dts/bcm4708.dtsi
@@ -34,3 +34,7 @@
 	};
 
 };
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
index a9c8def..2922536 100644
--- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
@@ -122,7 +122,3 @@
 		};
 	};
 };
-
-&uart0 {
-	status = "okay";
-};
diff --git a/arch/arm/boot/dts/bcm47081.dtsi b/arch/arm/boot/dts/bcm47081.dtsi
index f720012..c5f7619 100644
--- a/arch/arm/boot/dts/bcm47081.dtsi
+++ b/arch/arm/boot/dts/bcm47081.dtsi
@@ -24,3 +24,7 @@
 		};
 	};
 };
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
index fd38d2a..0225d82 100644
--- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
@@ -100,7 +100,3 @@
 		};
 	};
 };
-
-&uart0 {
-	status = "okay";
-};
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
index 92f8a72..56d38a3 100644
--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
@@ -107,10 +107,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &usb2 {
 	vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
index 9a92c24..c67bfaa 100644
--- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
@@ -97,10 +97,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &usb2 {
 	vcc-gpio = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/boot/dts/bcm4709.dtsi b/arch/arm/boot/dts/bcm4709.dtsi
index f039765..c645fea 100644
--- a/arch/arm/boot/dts/bcm4709.dtsi
+++ b/arch/arm/boot/dts/bcm4709.dtsi
@@ -8,4 +8,5 @@
 
 &uart0 {
 	clock-frequency = <125000000>;
+	status = "okay";
 };
diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
index 661348d..7fb9270 100644
--- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
@@ -105,10 +105,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &usb3 {
 	vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
index 169b35f..2f4a651 100644
--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
@@ -98,10 +98,6 @@
 	};
 };
 
-&uart0 {
-	status = "okay";
-};
-
 &usb3 {
 	vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
index 521b415..7ecd57c 100644
--- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
@@ -97,7 +97,3 @@
 		};
 	};
 };
-
-&uart0 {
-	status = "okay";
-};
diff --git a/arch/arm/boot/dts/bcm47094.dtsi b/arch/arm/boot/dts/bcm47094.dtsi
index 4f09aa0..4840a78 100644
--- a/arch/arm/boot/dts/bcm47094.dtsi
+++ b/arch/arm/boot/dts/bcm47094.dtsi
@@ -14,4 +14,5 @@
 
 &uart0 {
 	clock-frequency = <125000000>;
+	status = "okay";
 };
-- 
2.10.1

^ permalink raw reply related

* [PATCH 1/2] bus: vexpress-config: fix device reference leak
From: Sudeep Holla @ 2016-11-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479317491-7435-1-git-send-email-sudeep.holla@arm.com>



On 16/11/16 17:31, Sudeep Holla wrote:
> From: Johan Hovold <johan@kernel.org>
>
> Make sure to drop the reference to the parent device taken by
> class_find_device() after populating the bus.
>
> Fixes: 3b9334ac835b ("mfd: vexpress: Convert custom func API to regmap")
> Acked-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Johan Hovold <johan@kernel.org>
> ---
>  drivers/bus/vexpress-config.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> Hi ARM-SoC team,
>
> I am not sure if these couple of patches can be considered as fixes for
> v4.9. I will leave that to you guys.
>
> Can you pick these couple of patches directly either for v4.9 or v4.10 ?
> I am trying to avoid single patch pull requests here. Let me know if
> you prefer PR instead.
>

Gentle ping. It need not go into v4.9. Please pick them for v4.10

-- 
Regards,
Sudeep

^ permalink raw reply

* [GIT PULL]: ARM ARTPEC changes for 4.10
From: Jesper Nilsson @ 2016-11-28 13:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <10339600.mZlnsf0Sve@wuerfel>

On Mon, Nov 28, 2016 at 01:57:10PM +0100, Arnd Bergmann wrote:
> On Monday, November 28, 2016 1:33:31 PM CET Jesper Nilsson wrote:
> > > Hi Jesper and Niklas,
> > > 
> > > I just found the old pull request while going through my mail backlog.
> > > 
> > > A few things for you to remember for next time:
> > > 
> > > - please send pull requests "To: arm at kernel.org" so we know they
> > >   are destined for arm-soc
> > 
> > Ok, should we add that in the MAINTAINERS file so we can
> > get it automatically from get_maintainer?
> 
> No, we don't want to get every single patch that people submit to
> platform maintainers, only the consolidated pull requests that you
> send.

Right, sounds reasonable, will do.

> 	Arnd

/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson at axis.com

^ permalink raw reply

* [PATCH 1/1] net: macb: fix the RX queue reset in macb_rx()
From: Cyrille Pitchen @ 2016-11-28 13:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161127.202549.1887792653016840262.davem@davemloft.net>

Hi David,

Le 28/11/2016 ? 02:25, David Miller a ?crit :
> From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
> Date: Fri, 25 Nov 2016 09:49:32 +0100
> 
>> On macb only (not gem), when a RX queue corruption was detected from
>> macb_rx(), the RX queue was reset: during this process the RX ring
>> buffer descriptor was initialized by macb_init_rx_ring() but we forgot
>> to also set bp->rx_tail to 0.
>>
>> Indeed, when processing the received frames, bp->rx_tail provides the
>> macb driver with the index in the RX ring buffer of the next buffer to
>> process. So when the whole ring buffer is reset we must also reset
>> bp->rx_tail so the driver is synchronized again with the hardware.
>>
>> Since macb_init_rx_ring() is called from many locations, currently from
>> macb_rx() and macb_init_rings(), we'd rather add the "bp->rx_tail = 0;"
>> line inside macb_init_rx_ring() than add the very same line after each
>> call of this function.
>>
>> Without this fix, the rx queue is not reset properly to recover from
>> queue corruption and connection drop may occur.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
>> Fixes: 9ba723b081a2 ("net: macb: remove BUG_ON() and reset the queue to handle RX errors")
> 
> This doesn't apply cleanly to the 'net' tree, where
> RX_RING_SIZE is used instead of bp->rx_ring_size. It seems
> you generated this against net-next, however you didn't say
> that either in your Subject line nor the commit message.
> 
> As a bug fix this should be targetted at 'net'.
> 

Indeed, sorry. I've just sent a v2 based on net/master.

Best regards,

Cyrille

^ permalink raw reply

* [PATCH net-next v3 0/4] Fix OdroidC2 Gigabit Tx link issue
From: Neil Armstrong @ 2016-11-28 13:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480326409-25419-1-git-send-email-jbrunet@baylibre.com>

On 11/28/2016 10:46 AM, Jerome Brunet wrote:
> This patchset fixes an issue with the OdroidC2 board (DWMAC + RTL8211F).
> The platform seems to enter LPI on the Rx path too often while performing
> relatively high TX transfer. This eventually break the link (both Tx and
> Rx), and require to bring the interface down and up again to get the Rx
> path working again.
> 
> The root cause of this issue is not fully understood yet but disabling EEE
> advertisement on the PHY prevent this feature to be negotiated.
> With this change, the link is stable and reliable, with the expected
> throughput performance.
> 
> The patchset adds options in the generic phy driver to disable EEE
> advertisement, through device tree. The way it is done is very similar
> to the handling of the max-speed property.
> 
> Changes since V2: [2]
>  - Rename "eee-advert-disable" to "eee-broken-modes" to make the intended
>    purpose of this option clear (flag broken configuration, not a
>    configuration option)
>  - Add DT bindings constants so the DT configuration is more user friendly
>  - Submit to net-next instead of net.
> 
> Changes since V1: [1]
>  - Disable the advertisement of EEE in the generic code instead of the
>    realtek driver.
> 
> [1] : http://lkml.kernel.org/r/1479220154-25851-1-git-send-email-jbrunet at baylibre.com
> [2] : http://lkml.kernel.org/r/1479742524-30222-1-git-send-email-jbrunet at baylibre.com
> 
> 
> Jerome Brunet (4):
>   net: phy: add an option to disable EEE advertisement
>   dt-bindings: net: add EEE capability constants
>   dt: bindings: add ethernet phy eee-broken-modes option documentation
>   ARM64: dts: meson: odroidc2: disable advertisement EEE for GbE.
> 
>  Documentation/devicetree/bindings/net/phy.txt      |  2 +
>  .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 16 +++++
>  drivers/net/phy/phy.c                              |  3 +
>  drivers/net/phy/phy_device.c                       | 80 +++++++++++++++++++---
>  include/dt-bindings/net/mdio.h                     | 19 +++++
>  include/linux/phy.h                                |  3 +
>  6 files changed, 114 insertions(+), 9 deletions(-)
>  create mode 100644 include/dt-bindings/net/mdio.h
> 

Tested using Nexbox A1 (S912) and Amlogic P230 (S905D) devices (DWMAC + RTL8211F).

Tested-by: Neil Armstrong <narmstrong@baylibre.com>

^ permalink raw reply

* [PATCH net v2 1/1] net: macb: fix the RX queue reset in macb_rx()
From: Cyrille Pitchen @ 2016-11-28 13:40 UTC (permalink / raw)
  To: linux-arm-kernel

On macb only (not gem), when a RX queue corruption was detected from
macb_rx(), the RX queue was reset: during this process the RX ring
buffer descriptor was initialized by macb_init_rx_ring() but we forgot
to also set bp->rx_tail to 0.

Indeed, when processing the received frames, bp->rx_tail provides the
macb driver with the index in the RX ring buffer of the next buffer to
process. So when the whole ring buffer is reset we must also reset
bp->rx_tail so the driver is synchronized again with the hardware.

Since macb_init_rx_ring() is called from many locations, currently from
macb_rx() and macb_init_rings(), we'd rather add the "bp->rx_tail = 0;"
line inside macb_init_rx_ring() than add the very same line after each
call of this function.

Without this fix, the rx queue is not reset properly to recover from
queue corruption and connection drop may occur.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Fixes: 9ba723b081a2 ("net: macb: remove BUG_ON() and reset the queue to handle RX errors")
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---

ChangeLog:

v1 -> v2:
- rebase on net/master (v1 was based on net-next/master)
- add "Acked-by:" tag from Nicolas Ferre.

 drivers/net/ethernet/cadence/macb.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 533653bd7aec..3ede59c9cae0 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -975,6 +975,7 @@ static inline void macb_init_rx_ring(struct macb *bp)
 		addr += bp->rx_buffer_size;
 	}
 	bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
+	bp->rx_tail = 0;
 }
 
 static int macb_rx(struct macb *bp, int budget)
@@ -1616,8 +1617,6 @@ static void macb_init_rings(struct macb *bp)
 	bp->queues[0].tx_head = 0;
 	bp->queues[0].tx_tail = 0;
 	bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
-
-	bp->rx_tail = 0;
 }
 
 static void macb_reset_hw(struct macb *bp)
-- 
2.7.4

^ permalink raw reply related

* [bug report v4.8] fs/locks.c: kernel oops during posix lock stress test
From: Jeff Layton @ 2016-11-28 13:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACVXFVPsHjh3CWjdUrKB_r6=hkXK=qS3wpykbacdKe1rzz1H8Q@mail.gmail.com>

On Mon, 2016-11-28 at 11:10 +0800, Ming Lei wrote:
> Hi Guys,
> 
> When I run stress-ng via the following steps on one ARM64 dual
> socket system(Cavium Thunder), the kernel oops[1] can often be
> triggered after running the stress test for several hours(sometimes
> it may take longer):
> 
> - git clone git://kernel.ubuntu.com/cking/stress-ng.git
> - apply the attachment patch which just makes the posix file
> lock stress test more aggressive
> - run the test via '~/git/stress-ng$./stress-ng --lockf 128 --aggressive'
> 
> 
> From the oops log, looks one garbage file_lock node is got
> from the linked list of 'ctx->flc_posix' when the issue happens.
> 
> BTW, the issue isn't observed on single socket Cavium Thunder yet,
> and the same issue can be seen on Ubuntu Xenial(v4.4 based kernel)
> too.
> 
> Thanks,
> Ming
> 

Some questions just for clarification:

- I assume this is being run on a local fs of some sort? ext4 or xfs or
something?

- have you seen this on any other arch, besides ARM?

The file locking code does do some lockless checking to see whether the
i_flctx is even present and whether the list is empty in
locks_remove_posix. It's possible we have some barrier problems there,
but I don't quite see how that would cause us to have a corrupt lock on
the flc_posix list.

> [1] kernel oops log
> ubuntu at ubuntu:~/git/stress-ng$ ./stress-ng --lockf 128 --aggressive
> stress-ng: info:  [63828] defaulting to a 86400 second run per stressor
> stress-ng: info:  [63828] dispatching hogs: 128 lockf
> stress-ng: info:  [63828] cache allocate: default cache size: 16384K
> [80659.799092] Unable to handle kernel NULL pointer dereference at
> virtual address 00000030
> [80659.807219] pgd = ffff81001f365800
> [80659.810683] [00000030] *pgd=000001001a290003,
> *pud=000001001a290003, *pmd=0000010fa07f0003, *pte=0000000000000000
> [80659.821029] Internal error: Oops: 96000007 [#1] SMP
> [80659.825901] Modules linked in:
> [80659.828962] CPU: 15 PID: 63848 Comm: stress-ng-lockf Tainted: G
>    W       4.8.0 #167
> [80659.837132] Hardware name: Cavium ThunderX CRB/To be filled by
> O.E.M., BIOS 5.11 12/12/2012
> [80659.845479] task: ffff81001ee78580 task.stack: ffff81001f798000
> [80659.851402] PC is at posix_locks_conflict+0x94/0xc0
> [80659.856282] LR is at posix_lock_inode+0x90/0x6b0
> [80659.860896] pc : [<ffff00000828c694>] lr : [<ffff00000828cd90>]
> pstate: a0000145
> [80659.868285] sp : ffff81001f79bca0
> [80659.871596] x29: ffff81001f79bca0 x28: ffff81001f798000
> [80659.876915] x27: ffff800fdffbc160 x26: 0000000000000000
> [80659.882234] x25: ffff800fd2da2b30 x24: ffff800fce927430
> [80659.887551] x23: ffff800fce92d8f0 x22: ffff81001f79bd30
> [80659.892869] x21: ffff800fd2da2b18 x20: fffffffffffffff8
> [80659.898187] x19: ffff800fdffbc160 x18: 0000000000001140
> [80659.903504] x17: 0000ffff8870a578 x16: ffff000008245768
> [80659.908821] x15: 0000ffff888bc000 x14: 0000000000000000
> [80659.914139] x13: 00000003e8000000 x12: 0000000000000018
> [80659.919457] x11: 00000000000e6a17 x10: 00000000ffffffd0
> [80659.924776] x9 : 0000000000000000 x8 : ffff800fce927500
> [80659.930094] x7 : 0000000000000000 x6 : 000000000000007f
> [80659.935413] x5 : 0000000000000080 x4 : ffff800fce927438
> [80659.940729] x3 : ffff800fce927458 x2 : 00000000000026b9
> [80659.946047] x1 : ffff81001f37f300 x0 : 0000000000000000
> [80659.951363]
> [80659.952851] Process stress-ng-lockf (pid: 63848, stack limit =
> 0xffff81001f798020)
> [80659.960415] Stack: (0xffff81001f79bca0 to 0xffff81001f79c000)
> [80659.966158] bca0: ffff81001f79bcc0 ffff00000828cd90
> fffffffffffffff8 ffff800fa3a66568
> [80659.973986] bcc0: ffff81001f79bd40 ffff00000828d5f0
> ffff800f8185c700 ffff800fdffbc160
> [80659.981812] bce0: 0000000000000006 0000000000000000
> ffff81001f79bdd0 0000000000000006
> [80659.989638] bd00: 0000000000000120 0000000000000019
> ffff0000088b1000 ffff81001f798000
> [80659.997465] bd20: ffff81001f79bd40 ffff000008403fec
> ffff81001f79bd30 ffff81001f79bd30
> [80660.005292] bd40: ffff81001f79bd70 ffff00000828d8bc
> ffff800f8185c700 ffff800fdffbc160
> [80660.013118] bd60: ffff800fdffbc1b8 ffff800f8185c700
> ffff81001f79bde0 ffff00000828ef10
> [80660.020944] bd80: ffff800f8185c700 0000000000000000
> ffff800fdffbc160 ffff800fa3a66568
> [80660.028770] bda0: 0000000000000006 0000000000000004
> ffff81001f79bde0 ffff00000828ee14
> [80660.036596] bdc0: ffff800f8185c700 00000000fffffff2
> ffff800fdffbc160 ffff810ff99aae80
> [80660.044423] bde0: ffff81001f79be70 ffff000008245b84
> ffff800f8185c700 ffff800f8185c700
> [80660.052249] be00: 0000000000000000 0000000000000006
> 0000ffffdad5d4b0 0000000000000004
> [80660.060087] be20: 0000000000000120 000000000000003e
> 0000000000010001 0000000000000000
> [80660.067916] be40: 0000000000000008 0000000000000000
> 0000000000010001 0000000000000000
> [80660.075742] be60: 0000000000000008 0000000000000000
> 0000000000000000 ffff0000080836f0
> [80660.083568] be80: 0000000000000000 00000000005c5000
> ffffffffffffffff 0000ffff8870a3b8
> [80660.091394] bea0: 0000000080000000 0000000000000015
> 0000000080000000 00000000005c5000
> [80660.099220] bec0: 0000000000000004 0000000000000006
> 0000ffffdad5d4b0 00000000ffffff80
> [80660.107046] bee0: 0000ffffdad5d490 0000000026c26373
> 000000000000176f 0000000000004650
> [80660.114873] bf00: 0000000000000019 0000000000006536
> 00000000ffffffd0 00000000000e6a17
> [80660.122698] bf20: 0000000000000018 00000003e8000000
> 0000000000000000 0000ffff888bc000
> [80660.130524] bf40: 000000000048a170 0000ffff8870a578
> 0000000000001140 000000000000055f
> [80660.138351] bf60: 00000000005c5000 0000000000000004
> 0000ffff879f9008 0000000000000000
> [80660.146177] bf80: 0000000000000002 000000000048b530
> 2001000800400201 0000ffffdad60758
> [80660.154004] bfa0: 000000000048b008 0000ffffdad5d390
> 0000ffff8870a518 0000ffffdad5d390
> [80660.161830] bfc0: 0000ffff8870a3b8 0000000080000000
> 0000000000000004 0000000000000019
> [80660.169656] bfe0: 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> [80660.177481] Call trace:
> [80660.179928] Exception stack(0xffff81001f79bad0 to 0xffff81001f79bc00)
> [80660.186365] bac0:
> ffff800fdffbc160 0001000000000000
> [80660.194192] bae0: ffff81001f79bca0 ffff00000828c694
> ffff800fc0002c00 ffff81001ee78600
> [80660.202017] bb00: ffff81001f79bb70 ffff00000820b57c
> ffff800fcb2a6d88 ffff800fc0002c00
> [80660.209843] bb20: 0000000000000001 ffff810008ddbf00
> ffff81001f79bc30 ffff81001f79bc30
> [80660.217670] bb40: 0000000000000000 ffff810fa0712be8
> ffff800f81dfd680 ffff810fa0712be8
> [80660.225496] bb60: 0000000000000001 ffff810008ddbf00
> 0000000000000000 ffff81001f37f300
> [80660.233322] bb80: 00000000000026b9 ffff800fce927458
> ffff800fce927438 0000000000000080
> [80660.241148] bba0: 000000000000007f 0000000000000000
> ffff800fce927500 0000000000000000
> [80660.248974] bbc0: 00000000ffffffd0 00000000000e6a17
> 0000000000000018 00000003e8000000
> [80660.256800] bbe0: 0000000000000000 0000ffff888bc000
> ffff000008245768 0000ffff8870a578
> [80660.264636] [<ffff00000828c694>] posix_locks_conflict+0x94/0xc0
> [80660.270559] [<ffff00000828cd90>] posix_lock_inode+0x90/0x6b0
> [80660.276220] [<ffff00000828d5f0>] vfs_lock_file+0x68/0x78
> [80660.281537] [<ffff00000828d8bc>] do_lock_file_wait+0x54/0xe0
> [80660.287199] [<ffff00000828ef10>] fcntl_setlk+0x1c0/0x308
> [80660.292513] [<ffff000008245b84>] SyS_fcntl+0x41c/0x5b8
> [80660.297653] [<ffff0000080836f0>] el0_svc_naked+0x24/0x28
> [80660.302961] Code: a8c27bfd d65f03c0 d503201f f9401e61 (f9401e80)
> [80660.309188] ---[ end trace aa50050684d3a3fe ]---

-- 
Jeff Layton <jlayton@poochiereds.net>

^ permalink raw reply

* [PATCH] crypto: arm64/sha2: add generated .S files to .gitignore
From: Ard Biesheuvel @ 2016-11-28 13:37 UTC (permalink / raw)
  To: linux-arm-kernel

Add the files that are generated by the recently merged OpenSSL
SHA-256/512 implementation to .gitignore so Git disregards them
when showing untracked files.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/crypto/.gitignore | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 arch/arm64/crypto/.gitignore

diff --git a/arch/arm64/crypto/.gitignore b/arch/arm64/crypto/.gitignore
new file mode 100644
index 000000000000..879df8781ed5
--- /dev/null
+++ b/arch/arm64/crypto/.gitignore
@@ -0,0 +1,2 @@
+sha256-core.S
+sha512-core.S
-- 
2.7.4

^ permalink raw reply related

* [GIT PULL v2] firmware: SCPI updates for v4.10
From: Sudeep Holla @ 2016-11-28 13:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161118115615.GB14913@e107155-lin>

Hi,

On 18/11/16 11:56, Sudeep Holla wrote:
> Hi ARM-SoC Team,
>
> I have decoupled the platform specific binding from generic SCPI. Also
> I have renamed "arm,legacy-scpi" to "arm,scpi-pre-1.0". Since I haven't
> heard back any objections from Olof/Rob for my response, I am sending
> the pull request now.
>

Gentle ping, looks like this got missed.

-- 
Regards,
Sudeep

^ permalink raw reply

* [PATCH v4] crypto: arm64/sha2: integrate OpenSSL implementations of SHA256/SHA512
From: Will Deacon @ 2016-11-28 13:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu-uzqR758CSPZ_sWwbeejgw1cU-zwxpLU11A=3mnvqcNg@mail.gmail.com>

On Mon, Nov 28, 2016 at 02:17:34PM +0100, Ard Biesheuvel wrote:
> On 28 November 2016 at 13:05, Will Deacon <will.deacon@arm.com> wrote:
> > On Sun, Nov 20, 2016 at 11:42:01AM +0000, Ard Biesheuvel wrote:
> >> This integrates both the accelerated scalar and the NEON implementations
> >> of SHA-224/256 as well as SHA-384/512 from the OpenSSL project.
> >>
> >> Relative performance compared to the respective generic C versions:
> >>
> >>                  |  SHA256-scalar  | SHA256-NEON* |  SHA512  |
> >>      ------------+-----------------+--------------+----------+
> >>      Cortex-A53  |      1.63x      |     1.63x    |   2.34x  |
> >>      Cortex-A57  |      1.43x      |     1.59x    |   1.95x  |
> >>      Cortex-A73  |      1.26x      |     1.56x    |     ?    |
> >>
> >> The core crypto code was authored by Andy Polyakov of the OpenSSL
> >> project, in collaboration with whom the upstream code was adapted so
> >> that this module can be built from the same version of sha512-armv8.pl.
> >>
> >> The version in this patch was taken from OpenSSL commit 32bbb62ea634
> >> ("sha/asm/sha512-armv8.pl: fix big-endian support in __KERNEL__ case.")
> >>
> >> * The core SHA algorithm is fundamentally sequential, but there is a
> >>   secondary transformation involved, called the schedule update, which
> >>   can be performed independently. The NEON version of SHA-224/SHA-256
> >>   only implements this part of the algorithm using NEON instructions,
> >>   the sequential part is always done using scalar instructions.
> >>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >> ---
> >>  arch/arm64/crypto/Kconfig               |    8 +
> >>  arch/arm64/crypto/Makefile              |   17 +
> >>  arch/arm64/crypto/sha256-core.S_shipped | 2061 ++++++++++++++++++++
> >>  arch/arm64/crypto/sha256-glue.c         |  185 ++
> >>  arch/arm64/crypto/sha512-armv8.pl       |  778 ++++++++
> >>  arch/arm64/crypto/sha512-core.S_shipped | 1085 +++++++++++
> >>  arch/arm64/crypto/sha512-glue.c         |   94 +
> >>  7 files changed, 4228 insertions(+)
> >
> > If I build a kernel with this applied and CRYPTO_SHA{256,512}_ARM64=y,
> > then I end up with untracked .S files according to git:
> >
> > $ git status
> > Untracked files:
> >         arch/arm64/crypto/sha256-core.S
> >         arch/arm64/crypto/sha512-core.S
> >
> 
> Ah right, I forgot to add a .gitignore for these: that is required
> with .S_shipped files. I didn't spot this myself because I always
> build out of tree
> 
> Would you mind taking a separate patch for that?

I think this should all go via herbert, so I guess just send him the extra
patch.

Will

^ permalink raw reply

* [Qemu-devel] [kvm-unit-tests PATCH v7 00/11] QEMU MTTCG Test cases
From: Peter Maydell @ 2016-11-28 13:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161128115824.hrofgivt2mlfk7fh@kamzik.brq.redhat.com>

On 28 November 2016 at 11:58, Andrew Jones <drjones@redhat.com> wrote:
> On Mon, Nov 28, 2016 at 11:14:48AM +0000, Peter Maydell wrote:
>> On 28 November 2016 at 11:12, Alex Benn?e <alex.bennee@linaro.org> wrote:
>> >
>> > Andrew Jones <drjones@redhat.com> writes:
>> >> I've skimmed over everything looking at it from a framwork/sytle
>> >> perspective. I didn't dig in trying to understand the tests though.
>> >> One general comment, I see many tests introduce MAX_CPUS 8. Why do
>> >> that? Why not allow all cpus by using NR_CPUS for the array sizes?
>> >
>> > Yeah - I can fix those. I wonder what the maximum is with GIC V3?
>>
>> So large that you don't want to hardcode it as an array size...
>
> 255 with the gic series, not yet merged.

I was talking about the architectural GICv3 limit, which is larger
than that by many orders of magnitude. For QEMU it looks like
MAX_CPUMASK_BITS is now 288 rather than 255.

thanks
-- PMM

^ permalink raw reply

* [PATCH v2 1/6] mm: hugetlb: rename some allocation functions
From: Vlastimil Babka @ 2016-11-28 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479107259-2011-2-git-send-email-shijie.huang@arm.com>

On 11/14/2016 08:07 AM, Huang Shijie wrote:
> After a future patch, the __alloc_buddy_huge_page() will not necessarily
> use the buddy allocator.
>
> So this patch removes the "buddy" from these functions:
> 	__alloc_buddy_huge_page -> __alloc_huge_page
> 	__alloc_buddy_huge_page_no_mpol -> __alloc_huge_page_no_mpol
> 	__alloc_buddy_huge_page_with_mpol -> __alloc_huge_page_with_mpol
>
> This patch makes preparation for the later patch.
>
> Signed-off-by: Huang Shijie <shijie.huang@arm.com>
> ---
>  mm/hugetlb.c | 24 ++++++++++++++----------
>  1 file changed, 14 insertions(+), 10 deletions(-)
>
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 3edb759..496b703 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1157,6 +1157,10 @@ static int alloc_fresh_gigantic_page(struct hstate *h,
>
>  static inline bool gigantic_page_supported(void) { return true; }
>  #else
> +static inline struct page *alloc_gigantic_page(int nid, unsigned int order)
> +{
> +	return NULL;
> +}

This hunk is not explained by the description. Could belong to a later 
patch?

^ permalink raw reply

* Adding a .platform_init callback to sdhci_arasan_ops
From: Sebastian Frias @ 2016-11-28 13:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <d1801c1e-cd74-b79c-0280-8fb5dc377c91@intel.com>

On 28/11/16 12:44, Adrian Hunter wrote:
> On 28/11/16 13:20, Sebastian Frias wrote:
>> Hi Adrian,
>>
>> On 28/11/16 11:30, Adrian Hunter wrote:
>>> On 28/11/16 09:32, Michal Simek wrote:
>>>> +Sai for Xilinx perspective.
>>>>
>>>> On 25.11.2016 16:24, Sebastian Frias wrote:
>>>>> Hi,
>>>>>
>>>>> When using the Arasan SDHCI HW IP, there is a set of parameters called
>>>>> "Hardware initialized registers"
>>>>>
>>>>> (Table 7, Section "Pin Signals", page 56 of Arasan "SD3.0/SDIO3.0/eMMC4.4
>>>>> AHB Host Controller", revision 6.0 document)
>>>>>
>>>>> In some platforms those signals are connected to registers that need to
>>>>> be programmed at some point for proper driver/HW initialisation.
>>>>>
>>>>> I found that the 'struct sdhci_ops' contains a '.platform_init' callback
>>>>> that is called from within 'sdhci_pltfm_init', and that seems a good
>>>>> candidate for a place to program those registers (*).
>>>>>
>>>>> Do you agree?
>>>
>>> We already killed .platform_init
>>
>> I just saw that, yet it was the perfect place for the HW initialisation I'm
>> talking about.
>> Any way we can restore it?
> 
> It doesn't serve any purpose I am aware of.

It would serve (for me) if it was there :-)

> 
>>
>>>
>>> What is wrong with sdhci_arasan_probe()?
>>
>> Well, in 4.7 sdhci_arasan_probe() did not call of_match_device(), so I had
>> put a call to it just before sdhci_pltfm_init(), something like:
>>
>> +static const struct of_device_id sdhci_arasan_of_match[] = {
>> +       {
>> +               .compatible = "arasan,sdhci-8.9a",
>> +               .data = &sdhci_arasan_ops,
>> +       },
>> +       {
>> +               .compatible = "arasan,sdhci-5.1",
>> +               .data = &sdhci_arasan_ops,
>> +       },
>> +       {
>> +               .compatible = "arasan,sdhci-4.9a",
>> +               .data = &sdhci_arasan_ops,
>> +       },
>> +       {
>> +               .compatible = "sigma,smp8734-sdio",
>> +               .data = &sdhci_arasan_tango4_ops,
>> +       },
>> +       { }
>> +};
>> +MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
>>
>> ...
>>
>> +       const struct of_device_id *match;
>> +
>> +       match = of_match_device(sdhci_arasan_of_match, &pdev->dev);
>> +       if (match)
>> +               sdhci_arasan_pdata.ops = match->data;
>>
>> where 'sdhci_arasan_tango4_ops' contained a pointer to a .platform_init
>> callback.
>>
>> However, as I stated earlier, an upstream commit:
>>
>> commit 3ea4666e8d429223fbb39c1dccee7599ef7657d5
>> Author: Douglas Anderson <dianders@chromium.org>
>> Date:   Mon Jun 20 10:56:47 2016 -0700
>>
>>     mmc: sdhci-of-arasan: Properly set corecfg_baseclkfreq on rk3399
>>
>> changed struct 'sdhci_arasan_of_match' to convey different data, which
>> means that instead of having a generic way of accessing such data (such
>> as 'of_match_device()' and ".data" field), one must also check for
>> specific "compatible" strings to make sense of the ".data" field, such as
>> "rockchip,rk3399-sdhci-5.1"
>>
>> With the current code:
>> - there's no 'of_match_device()' before 'sdhci_pltfm_init()'
>> - the sdhci_pltfm_init() call is made with a static 'sdhci_arasan_pdata'
>> struct (so it cannot be made dependent on the "compatible" string).
>> - since 'sdhci_arasan_pdata' is the same for all compatible devices, even
>> for those that require special handling, more "compatible" matching code is
>> required
>> - leading to spread "compatible" matching code; IMHO it would be cleaner if
>> the 'sdhci_arasan_probe()' code was generic, with just a generic "compatible"
>> matching, which then proceeded with specific initialisation and generic
>> initialisation.
>>
>> In a nutshell, IMHO it would be better if adding support for more SoCs only
>> involved changing just 'sdhci_arasan_of_match' without the need to change
>> 'sdhci_arasan_probe()'.
>> That would clearly separate the generic and "SoC"-specific code, thus allowing
>> better maintenance.
>>
>> Does that makes sense to you guys?
> 
> If you want to do that, then why not define your match data with your own
> callbacks. e.g. something like
> 
> struct sdhci_arasan_of_data {
> 	struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
> 	void (*platform_init)(struct sdhci_arasan_data *sdhci_arasan);
> };
> 
> 	struct sdhci_arasan_of_data *data;
> 
> 	data = match->data;
> 	sdhci_arasan->soc_ctl_map = data->soc_ctl_map;
> 	if (data->platform_init)
> 		platform_init(sdhci_arasan);

Well, that adds a level in the hierarchy, but here is what it would look like:


diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 410a55b..1cb3861 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -382,22 +382,6 @@ static int sdhci_arasan_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(sdhci_arasan_dev_pm_ops, sdhci_arasan_suspend,
 			 sdhci_arasan_resume);
 
-static const struct of_device_id sdhci_arasan_of_match[] = {
-	/* SoC-specific compatible strings w/ soc_ctl_map */
-	{
-		.compatible = "rockchip,rk3399-sdhci-5.1",
-		.data = &rk3399_soc_ctl_map,
-	},
-
-	/* Generic compatible below here */
-	{ .compatible = "arasan,sdhci-8.9a" },
-	{ .compatible = "arasan,sdhci-5.1" },
-	{ .compatible = "arasan,sdhci-4.9a" },
-
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
-
 /**
  * sdhci_arasan_sdcardclk_recalc_rate - Return the card clock rate
  *
@@ -578,6 +562,53 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev)
 	of_clk_del_provider(dev->of_node);
 }
 
+static void sdhci_tango4_platform_init(struct sdhci_host *host)
+{
+	printk("%s\n", __func__);
+
+	/*
+	  pad_mode[2:0]=0    must be 0
+	  sel_sdio[3]=1      must be 1 for SDIO
+	  inv_sdwp_pol[4]=0  if set inverts the SD write protect polarity
+	  inv_sdcd_pol[5]=0  if set inverts the SD card present polarity
+	*/
+	sdhci_writel(host, 0x00000008, 0x100 + 0x0);
+}
+
+struct sdhci_arasan_chip_specific_data {
+	const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
+	void (*platform_init)(struct sdhci_host *host);
+};
+
+static const struct sdhci_arasan_chip_specific_data sdhci_arasan_rockchip = {
+	.soc_ctl_map = &rk3399_soc_ctl_map,
+};
+
+static const struct sdhci_arasan_chip_specific_data sdhci_arasan_sigma = {
+	.platform_init = sdhci_tango4_platform_init,
+};
+
+static const struct of_device_id sdhci_arasan_of_match[] = {
+	/* SoC-specific compatible strings w/ soc_ctl_map */
+	{
+		.compatible = "rockchip,rk3399-sdhci-5.1",
+		.data = &sdhci_arasan_rockchip,
+	},
+	{
+		.compatible = "sigma,sdio-v1",
+		.data = &sdhci_arasan_sigma,
+	},
+
+	/* Generic compatible below here */
+	{ .compatible = "arasan,sdhci-8.9a" },
+	{ .compatible = "arasan,sdhci-5.1" },
+	{ .compatible = "arasan,sdhci-4.9a" },
+
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match);
+
+
 static int sdhci_arasan_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -587,6 +618,7 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
 	struct sdhci_host *host;
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_arasan_data *sdhci_arasan;
+	struct sdhci_arasan_chip_specific_data *sdhci_arasan_chip_specific;
 	struct device_node *np = pdev->dev.of_node;
 
 	host = sdhci_pltfm_init(pdev, &sdhci_arasan_pdata,
@@ -599,7 +631,11 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
 	sdhci_arasan->host = host;
 
 	match = of_match_node(sdhci_arasan_of_match, pdev->dev.of_node);
-	sdhci_arasan->soc_ctl_map = match->data;
+	sdhci_arasan_chip_specific = (struct sdhci_arasan_chip_specific_data *)match;
+	if (sdhci_arasan_chip_specific->soc_ctl_map)
+		sdhci_arasan->soc_ctl_map = sdhci_arasan_chip_specific->soc_ctl_map;
+	if (sdhci_arasan_chip_specific->platform_init)
+		sdhci_arasan_chip_specific->platform_init(host);
 
 	node = of_parse_phandle(pdev->dev.of_node, "arasan,soc-ctl-syscon", 0);
 	if (node) {


I will try to send another patch with what a different approach

^ permalink raw reply related

* [PATCH 4/4] crypto: arm/crct10dif - port x86 SSE implementation to ARM
From: Herbert Xu @ 2016-11-28 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8tPfX76ntdQmMz53waE73RHfB11oRs8w=Ufy7d=YqbGA@mail.gmail.com>

On Thu, Nov 24, 2016 at 05:32:42PM +0000, Ard Biesheuvel wrote:
> On 24 November 2016 at 15:43, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> > This is a straight transliteration of the Intel algorithm implemented
> > using SSE and PCLMULQDQ instructions that resides under in the file
> > arch/x86/crypto/crct10dif-pcl-asm_64.S.
> >
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > ---
> >  arch/arm/crypto/Kconfig                        |   5 +
> >  arch/arm/crypto/Makefile                       |   2 +
> >  arch/{arm64 => arm}/crypto/crct10dif-ce-core.S | 457 +++++++++++---------
> >  arch/{arm64 => arm}/crypto/crct10dif-ce-glue.c |  23 +-
> >  4 files changed, 277 insertions(+), 210 deletions(-)
> >
> 
> This patch needs the following hunk folded in to avoid breaking the
> Thumb2 build:
> 
> """
> diff --git a/arch/arm/crypto/crct10dif-ce-core.S
> b/arch/arm/crypto/crct10dif-ce-core.S
> index 30168b0f8581..4fdbca94dd0c 100644
> --- a/arch/arm/crypto/crct10dif-ce-core.S
> +++ b/arch/arm/crypto/crct10dif-ce-core.S
> @@ -152,7 +152,8 @@ CPU_LE(     vrev64.8        q7, q7                  )
>         // XOR the initial_crc value
>         veor.8          q0, q0, q10
> 
> -       adrl            ip, rk3
> +ARM(   adrl            ip, rk3         )
> +THUMB( adr             ip, rk3         )
>         vld1.64         {q10}, [ip]     // xmm10 has rk3 and rk4
>                                         // type of pmull instruction
>                                         // will determine which constant to use
> """

I'm sorry but this patch doesn't apply on top of the other four.
So please resend the whole series.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* [PATCH 2/2] net: dsa: mv88e6xxx: Add 88E6176 device tree support
From: Andrew Lunn @ 2016-11-28 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161128080939.ippqlytvojitefkp@perseus.defre.kleine-koenig.org>

> I still wonder (and didn't get an answer back when I asked about this)
> why a comment is preferred here. For other devices I know it's usual and
> requested by the maintainers to use:
> 
> 	compatible = "exact name", "earlyer device to match driver";
> 
> . This is more robust, documents the situation more formally and makes
> it better greppable. The price to pay is only a few bytes in the dtb
> which IMO is ok.

We did discuss this a while back. The information is useless and
should to be ignored if present.

The switch has a register which contains its model and revision. Each
port has a set of registers, and register 3 contains the
model/version. For all devices compatible with the 6085, the port
registers start at address 0x10. For the 6190, the port registers
start at 0x0. So given one of these two compatible strings, we can
find the model of the device, from something which is burned into the
silicon.

Now, say we did add per device compatible strings. We look up the
model burned into the silicon, find it is different to what the device
tree is and do what? Fail the probe? Or just keep going using the
value in the silicon? It seems silly to fail the probe if the driver
does support the model, but that means the device tree is never
verified and hence probably wrong. Why have wrong information in the
device tree, especially wrong information which we never use. It is
better to not have that information in the device tree.

Linus has said he does not like ARM devices because of all the busses
which are not enumerable. Here we have a device which with a little
bit of help we can enumerate. So we should. 

    Andrew

^ permalink raw reply

* [PATCH v4] crypto: arm64/sha2: integrate OpenSSL implementations of SHA256/SHA512
From: Ard Biesheuvel @ 2016-11-28 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161128120503.GC1485@arm.com>

On 28 November 2016 at 13:05, Will Deacon <will.deacon@arm.com> wrote:
> On Sun, Nov 20, 2016 at 11:42:01AM +0000, Ard Biesheuvel wrote:
>> This integrates both the accelerated scalar and the NEON implementations
>> of SHA-224/256 as well as SHA-384/512 from the OpenSSL project.
>>
>> Relative performance compared to the respective generic C versions:
>>
>>                  |  SHA256-scalar  | SHA256-NEON* |  SHA512  |
>>      ------------+-----------------+--------------+----------+
>>      Cortex-A53  |      1.63x      |     1.63x    |   2.34x  |
>>      Cortex-A57  |      1.43x      |     1.59x    |   1.95x  |
>>      Cortex-A73  |      1.26x      |     1.56x    |     ?    |
>>
>> The core crypto code was authored by Andy Polyakov of the OpenSSL
>> project, in collaboration with whom the upstream code was adapted so
>> that this module can be built from the same version of sha512-armv8.pl.
>>
>> The version in this patch was taken from OpenSSL commit 32bbb62ea634
>> ("sha/asm/sha512-armv8.pl: fix big-endian support in __KERNEL__ case.")
>>
>> * The core SHA algorithm is fundamentally sequential, but there is a
>>   secondary transformation involved, called the schedule update, which
>>   can be performed independently. The NEON version of SHA-224/SHA-256
>>   only implements this part of the algorithm using NEON instructions,
>>   the sequential part is always done using scalar instructions.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  arch/arm64/crypto/Kconfig               |    8 +
>>  arch/arm64/crypto/Makefile              |   17 +
>>  arch/arm64/crypto/sha256-core.S_shipped | 2061 ++++++++++++++++++++
>>  arch/arm64/crypto/sha256-glue.c         |  185 ++
>>  arch/arm64/crypto/sha512-armv8.pl       |  778 ++++++++
>>  arch/arm64/crypto/sha512-core.S_shipped | 1085 +++++++++++
>>  arch/arm64/crypto/sha512-glue.c         |   94 +
>>  7 files changed, 4228 insertions(+)
>
> If I build a kernel with this applied and CRYPTO_SHA{256,512}_ARM64=y,
> then I end up with untracked .S files according to git:
>
> $ git status
> Untracked files:
>         arch/arm64/crypto/sha256-core.S
>         arch/arm64/crypto/sha512-core.S
>

Ah right, I forgot to add a .gitignore for these: that is required
with .S_shipped files. I didn't spot this myself because I always
build out of tree

Would you mind taking a separate patch for that?

^ permalink raw reply

* [PATCH v9 02/11] arm/arm64: vgic: Add distributor and redistributor access
From: Christoffer Dall @ 2016-11-28 13:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479906118-15832-3-git-send-email-vijay.kilari@gmail.com>

On Wed, Nov 23, 2016 at 06:31:49PM +0530, vijay.kilari at gmail.com wrote:
> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> 
> VGICv3 Distributor and Redistributor registers are accessed using
> KVM_DEV_ARM_VGIC_GRP_DIST_REGS and KVM_DEV_ARM_VGIC_GRP_REDIST_REGS
> with KVM_SET_DEVICE_ATTR and KVM_GET_DEVICE_ATTR ioctls.
> These registers are accessed as 32-bit and cpu mpidr
> value passed along with register offset is used to identify the
> cpu for redistributor registers access.
> 
> The version of VGIC v3 specification is define here
> Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> 
> Also update arch/arm/include/uapi/asm/kvm.h to compile for
> AArch32 mode.
> 
> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> ---
>  arch/arm/include/uapi/asm/kvm.h     |   4 +
>  arch/arm64/include/uapi/asm/kvm.h   |   4 +
>  virt/kvm/arm/vgic/vgic-kvm-device.c | 144 ++++++++++++++++++++++++++++++++++--
>  virt/kvm/arm/vgic/vgic-mmio-v2.c    |  16 +---
>  virt/kvm/arm/vgic/vgic-mmio-v3.c    |  72 ++++++++++++++++++
>  virt/kvm/arm/vgic/vgic-mmio.c       |  22 ++++++
>  virt/kvm/arm/vgic/vgic-mmio.h       |   4 +
>  virt/kvm/arm/vgic/vgic.h            |  49 +++++++++++-
>  8 files changed, 292 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> index af05f8e..0ae6035 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -181,10 +181,14 @@ struct kvm_arch_memory_slot {
>  #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS	2
>  #define   KVM_DEV_ARM_VGIC_CPUID_SHIFT	32
>  #define   KVM_DEV_ARM_VGIC_CPUID_MASK	(0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
> +#define   KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
> +#define   KVM_DEV_ARM_VGIC_V3_MPIDR_MASK \
> +			(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_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_CTRL_INIT    0
>  
>  /* KVM_IRQ_LINE irq field index values */
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index 3051f86..56dc08d 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -201,10 +201,14 @@ struct kvm_arch_memory_slot {
>  #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS	2
>  #define   KVM_DEV_ARM_VGIC_CPUID_SHIFT	32
>  #define   KVM_DEV_ARM_VGIC_CPUID_MASK	(0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
> +#define   KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
> +#define   KVM_DEV_ARM_VGIC_V3_MPIDR_MASK \
> +			(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_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_CTRL_INIT	0
>  
>  /* Device Control API on vcpu fd */
> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
> index fbe87a6..bc7de95 100644
> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
> @@ -235,7 +235,7 @@ struct vgic_reg_attr {
>  	gpa_t addr;
>  };
>  
> -static int parse_vgic_v2_attr(struct kvm_device *dev,
> +static int vgic_v2_parse_attr(struct kvm_device *dev,
>  			      struct kvm_device_attr *attr,
>  			      struct vgic_reg_attr *reg_attr)
>  {
> @@ -292,14 +292,14 @@ static bool lock_all_vcpus(struct kvm *kvm)
>  }
>  
>  /**
> - * vgic_attr_regs_access_v2 - allows user space to access VGIC v2 state
> + * vgic_v2_attr_regs_access - allows user space to access VGIC v2 state
>   *
>   * @dev:      kvm device handle
>   * @attr:     kvm device attribute
>   * @reg:      address the value is read or written
>   * @is_write: true if userspace is writing a register
>   */
> -static int vgic_attr_regs_access_v2(struct kvm_device *dev,
> +static int vgic_v2_attr_regs_access(struct kvm_device *dev,
>  				    struct kvm_device_attr *attr,
>  				    u32 *reg, bool is_write)
>  {
> @@ -308,7 +308,7 @@ static int vgic_attr_regs_access_v2(struct kvm_device *dev,
>  	struct kvm_vcpu *vcpu;
>  	int ret;
>  
> -	ret = parse_vgic_v2_attr(dev, attr, &reg_attr);
> +	ret = vgic_v2_parse_attr(dev, attr, &reg_attr);
>  	if (ret)
>  		return ret;
>  
> @@ -362,7 +362,7 @@ static int vgic_v2_set_attr(struct kvm_device *dev,
>  		if (get_user(reg, uaddr))
>  			return -EFAULT;
>  
> -		return vgic_attr_regs_access_v2(dev, attr, &reg, true);
> +		return vgic_v2_attr_regs_access(dev, attr, &reg, true);
>  	}
>  	}
>  
> @@ -384,7 +384,7 @@ static int vgic_v2_get_attr(struct kvm_device *dev,
>  		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
>  		u32 reg = 0;
>  
> -		ret = vgic_attr_regs_access_v2(dev, attr, &reg, false);
> +		ret = vgic_v2_attr_regs_access(dev, attr, &reg, false);
>  		if (ret)
>  			return ret;
>  		return put_user(reg, uaddr);
> @@ -428,16 +428,141 @@ struct kvm_device_ops kvm_arm_vgic_v2_ops = {
>  	.has_attr = vgic_v2_has_attr,
>  };
>  
> +static int vgic_v3_parse_attr(struct kvm_device *dev,
> +			      struct kvm_device_attr *attr,
> +			      struct vgic_reg_attr *reg_attr)
> +{
> +	unsigned long vgic_mpidr, mpidr_reg;
> +
> +	vgic_mpidr = (attr->attr & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) >>
> +		      KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT;
> +
> +	mpidr_reg = VGIC_TO_MPIDR(vgic_mpidr);
> +	reg_attr->vcpu = kvm_mpidr_to_vcpu(dev->kvm, mpidr_reg);
> +	if (!reg_attr->vcpu)
> +		return -EINVAL;
> +
> +	reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
> +
> +	return 0;
> +}
> +
> +/*
> + * vgic_v3_attr_regs_access - allows user space to access VGIC v3 state
> + *
> + * @dev:      kvm device handle
> + * @attr:     kvm device attribute
> + * @reg:      address the value is read or written
> + * @is_write: true if userspace is writing a register
> + */
> +static int vgic_v3_attr_regs_access(struct kvm_device *dev,
> +				    struct kvm_device_attr *attr,
> +				    u64 *reg, bool is_write)
> +{
> +	struct vgic_reg_attr reg_attr;
> +	gpa_t addr;
> +	struct kvm_vcpu *vcpu;
> +	int ret;
> +	u32 tmp32;
> +
> +	ret = vgic_v3_parse_attr(dev, attr, &reg_attr);
> +	if (ret)
> +		return ret;
> +
> +	vcpu = reg_attr.vcpu;
> +	addr = reg_attr.addr;
> +
> +	mutex_lock(&dev->kvm->lock);
> +
> +	if (unlikely(!vgic_initialized(dev->kvm))) {
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +
> +	if (!lock_all_vcpus(dev->kvm)) {
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +
> +	switch (attr->group) {
> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
> +		if (is_write)
> +			tmp32 = *reg;
> +
> +		ret = vgic_v3_dist_uaccess(vcpu, is_write, addr, &tmp32);
> +		if (!is_write)
> +			*reg = tmp32;
> +		break;
> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
> +		if (is_write)
> +			tmp32 = *reg;
> +
> +		ret = vgic_v3_redist_uaccess(vcpu, is_write, addr, &tmp32);
> +		if (!is_write)
> +			*reg = tmp32;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	unlock_all_vcpus(dev->kvm);
> +out:
> +	mutex_unlock(&dev->kvm->lock);
> +	return ret;
> +}
> +
>  static int vgic_v3_set_attr(struct kvm_device *dev,
>  			    struct kvm_device_attr *attr)
>  {
> -	return vgic_set_common_attr(dev, attr);
> +	int ret;
> +
> +	ret = vgic_set_common_attr(dev, attr);
> +	if (ret != -ENXIO)
> +		return ret;
> +
> +	switch (attr->group) {
> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: {
> +		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
> +		u32 tmp32;
> +		u64 reg;
> +
> +		if (get_user(tmp32, uaddr))
> +			return -EFAULT;
> +
> +		reg = tmp32;
> +		return vgic_v3_attr_regs_access(dev, attr, &reg, true);
> +	}
> +	}
> +	return -ENXIO;
>  }
>  
>  static int vgic_v3_get_attr(struct kvm_device *dev,
>  			    struct kvm_device_attr *attr)
>  {
> -	return vgic_get_common_attr(dev, attr);
> +	int ret;
> +
> +	ret = vgic_get_common_attr(dev, attr);
> +	if (ret != -ENXIO)
> +		return ret;
> +
> +	switch (attr->group) {
> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: {
> +		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
> +		u64 reg;
> +		u32 tmp32;
> +
> +		ret = vgic_v3_attr_regs_access(dev, attr, &reg, false);
> +		if (ret)
> +			return ret;
> +		tmp32 = reg;
> +		return put_user(tmp32, uaddr);
> +	}
> +	}
> +
> +	return -ENXIO;
>  }
>  
>  static int vgic_v3_has_attr(struct kvm_device *dev,
> @@ -451,6 +576,9 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
>  			return 0;
>  		}
>  		break;
> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
> +		return vgic_v3_has_attr_regs(dev, attr);
>  	case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
>  		return 0;
>  	case KVM_DEV_ARM_VGIC_GRP_CTRL:
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
> index 0b32f40..2cb04b7 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
> @@ -368,10 +368,9 @@ unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev)
>  
>  int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
>  {
> -	int nr_irqs = dev->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
>  	const struct vgic_register_region *regions;
>  	gpa_t addr;
> -	int nr_regions, i, len;
> +	int nr_regions;
>  
>  	addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
>  
> @@ -392,18 +391,7 @@ int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
>  	if (addr & 3)
>  		return -ENXIO;
>  
> -	for (i = 0; i < nr_regions; i++) {
> -		if (regions[i].bits_per_irq)
> -			len = (regions[i].bits_per_irq * nr_irqs) / 8;
> -		else
> -			len = regions[i].len;
> -
> -		if (regions[i].reg_offset <= addr &&
> -		    regions[i].reg_offset + len > addr)
> -			return 0;
> -	}
> -
> -	return -ENXIO;
> +	return vgic_validate_mmio_region_addr(dev, regions, nr_regions, addr);
>  }
>  
>  int vgic_v2_cpuif_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> index 8e76d04..2a7cd62 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> @@ -18,6 +18,8 @@
>  #include <kvm/arm_vgic.h>
>  
>  #include <asm/kvm_emulate.h>
> +#include <asm/kvm_arm.h>
> +#include <asm/kvm_mmu.h>
>  
>  #include "vgic.h"
>  #include "vgic-mmio.h"
> @@ -439,6 +441,9 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
>  	REGISTER_DESC_WITH_LENGTH(GICD_CTLR,
>  		vgic_mmio_read_v3_misc, vgic_mmio_write_v3_misc, 16,
>  		VGIC_ACCESS_32bit),
> +	REGISTER_DESC_WITH_LENGTH(GICD_STATUSR,
> +		vgic_mmio_read_rao, vgic_mmio_write_wi, 4,
> +		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IGROUPR,
>  		vgic_mmio_read_rao, vgic_mmio_write_wi, NULL, NULL, 1,
>  		VGIC_ACCESS_32bit),
> @@ -486,12 +491,18 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
>  	REGISTER_DESC_WITH_LENGTH(GICR_CTLR,
>  		vgic_mmio_read_v3r_ctlr, vgic_mmio_write_v3r_ctlr, 4,
>  		VGIC_ACCESS_32bit),
> +	REGISTER_DESC_WITH_LENGTH(GICR_STATUSR,
> +		vgic_mmio_read_raz, vgic_mmio_write_wi, 4,
> +		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_LENGTH(GICR_IIDR,
>  		vgic_mmio_read_v3r_iidr, vgic_mmio_write_wi, 4,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_LENGTH(GICR_TYPER,
>  		vgic_mmio_read_v3r_typer, vgic_mmio_write_wi, 8,
>  		VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
> +	REGISTER_DESC_WITH_LENGTH(GICR_WAKER,
> +		vgic_mmio_read_raz, vgic_mmio_write_wi, 8,
> +		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_LENGTH(GICR_PROPBASER,
>  		vgic_mmio_read_propbase, vgic_mmio_write_propbase, 8,
>  		VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
> @@ -612,6 +623,34 @@ int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t redist_base_address)
>  	return ret;
>  }
>  
> +int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
> +{
> +	const struct vgic_register_region *regions;
> +	gpa_t addr;
> +	int nr_regions;
> +
> +	addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
> +
> +	switch (attr->group) {
> +	case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
> +		regions = vgic_v3_dist_registers;
> +		nr_regions = ARRAY_SIZE(vgic_v3_dist_registers);
> +		break;
> +	case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:{
> +		regions = vgic_v3_rdbase_registers;
> +		nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers);
> +		break;
> +	}
> +	default:
> +		return -ENXIO;
> +	}
> +
> +	/* We only support aligned 32-bit accesses. */
> +	if (addr & 3)
> +		return -ENXIO;
> +
> +	return vgic_validate_mmio_region_addr(dev, regions, nr_regions, addr);
> +}
>  /*
>   * Compare a given affinity (level 1-3 and a level 0 mask, from the SGI
>   * generation register ICC_SGI1R_EL1) with a given VCPU.
> @@ -718,3 +757,36 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
>  		vgic_put_irq(vcpu->kvm, irq);
>  	}
>  }
> +
> +int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> +			 int offset, u32 *val)
> +{
> +	struct vgic_io_device dev = {
> +		.regions = vgic_v3_dist_registers,
> +		.nr_regions = ARRAY_SIZE(vgic_v3_dist_registers),
> +	};
> +
> +	return vgic_uaccess(vcpu, &dev, is_write, offset, val);
> +}
> +
> +int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> +			   int offset, u32 *val)
> +{
> +	struct vgic_io_device rd_dev = {
> +		.regions = vgic_v3_rdbase_registers,
> +		.nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers),
> +	};
> +
> +	struct vgic_io_device sgi_dev = {
> +		.regions = vgic_v3_sgibase_registers,
> +		.nr_regions = ARRAY_SIZE(vgic_v3_sgibase_registers),
> +	};
> +
> +	/* SGI_base is the next 64K frame after RD_base */
> +	if (offset >= SZ_64K)
> +		return vgic_uaccess(vcpu, &sgi_dev, is_write,
> +				    offset - SZ_64K, val);
> +	else
> +		return vgic_uaccess(vcpu, &rd_dev, is_write,
> +				    offset, val);
> +}
> diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
> index d5f3ee2..0d1bc98 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio.c
> @@ -394,6 +394,28 @@ static int match_region(const void *key, const void *elt)
>  		       sizeof(region[0]), match_region);
>  }
>  
> +/* Check if address falls within the region */
> +int vgic_validate_mmio_region_addr(struct kvm_device *dev,
> +				   const struct vgic_register_region *regions,
> +				   int nr_regions, gpa_t addr)
> +{
> +	int i, len;
> +	int nr_irqs = dev->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
> +
> +	for (i = 0; i < nr_regions; i++) {
> +		if (regions[i].bits_per_irq)
> +			len = (regions[i].bits_per_irq * nr_irqs) / 8;
> +		else
> +			len = regions[i].len;
> +
> +		if (regions[i].reg_offset <= addr &&
> +		    regions[i].reg_offset + len > addr)
> +			return 0;
> +	}
> +
> +	return -ENXIO;
> +}
> +
>  /*
>   * kvm_mmio_read_buf() returns a value in a format where it can be converted
>   * to a byte array and be directly observed as the guest wanted it to appear
> diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
> index 7b30296..1cc7faf 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio.h
> +++ b/virt/kvm/arm/vgic/vgic-mmio.h
> @@ -177,6 +177,10 @@ void vgic_mmio_write_config(struct kvm_vcpu *vcpu,
>  int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev,
>  		 bool is_write, int offset, u32 *val);
>  
> +int vgic_validate_mmio_region_addr(struct kvm_device *dev,
> +				   const struct vgic_register_region *regions,
> +				   int nr_regions, gpa_t addr);
> +
>  unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev);
>  
>  unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev);
> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
> index 859f65c..91f58b2 100644
> --- a/virt/kvm/arm/vgic/vgic.h
> +++ b/virt/kvm/arm/vgic/vgic.h
> @@ -30,6 +30,49 @@
>  
>  #define vgic_irq_is_sgi(intid) ((intid) < VGIC_NR_SGIS)
>  
> +#define VGIC_AFFINITY_0_SHIFT 0
> +#define VGIC_AFFINITY_0_MASK (0xffUL << VGIC_AFFINITY_0_SHIFT)
> +#define VGIC_AFFINITY_1_SHIFT 8
> +#define VGIC_AFFINITY_1_MASK (0xffUL << VGIC_AFFINITY_1_SHIFT)
> +#define VGIC_AFFINITY_2_SHIFT 16
> +#define VGIC_AFFINITY_2_MASK (0xffUL << VGIC_AFFINITY_2_SHIFT)
> +#define VGIC_AFFINITY_3_SHIFT 24
> +#define VGIC_AFFINITY_3_MASK (0xffUL << VGIC_AFFINITY_3_SHIFT)
> +
> +#define VGIC_AFFINITY_LEVEL(reg, level) \
> +	((((reg) & VGIC_AFFINITY_## level ##_MASK) \
> +	>> VGIC_AFFINITY_## level ##_SHIFT) << MPIDR_LEVEL_SHIFT(level))
> +
> +/*
> + * The Userspace encodes the affinity differently from the MPIDR,
> + * Below macro converts vgic userspace format to MPIDR reg format.
> + */
> +#define VGIC_TO_MPIDR(val) (VGIC_AFFINITY_LEVEL(val, 0) | \
> +			    VGIC_AFFINITY_LEVEL(val, 1) | \
> +			    VGIC_AFFINITY_LEVEL(val, 2) | \
> +			    VGIC_AFFINITY_LEVEL(val, 3))
> +
> +/*
> + * As per Documentation/virtual/kvm/devices/arm-vgic-v3.txt,
> + * below macros are defined for CPUREG encoding.
> + */
> +#define KVM_REG_ARM_VGIC_SYSREG_OP0_MASK   0x000000000000c000
> +#define KVM_REG_ARM_VGIC_SYSREG_OP0_SHIFT  14
> +#define KVM_REG_ARM_VGIC_SYSREG_OP1_MASK   0x0000000000003800
> +#define KVM_REG_ARM_VGIC_SYSREG_OP1_SHIFT  11
> +#define KVM_REG_ARM_VGIC_SYSREG_CRN_MASK   0x0000000000000780
> +#define KVM_REG_ARM_VGIC_SYSREG_CRN_SHIFT  7
> +#define KVM_REG_ARM_VGIC_SYSREG_CRM_MASK   0x0000000000000078
> +#define KVM_REG_ARM_VGIC_SYSREG_CRM_SHIFT  3
> +#define KVM_REG_ARM_VGIC_SYSREG_OP2_MASK   0x0000000000000007
> +#define KVM_REG_ARM_VGIC_SYSREG_OP2_SHIFT  0
> +
> +#define KVM_DEV_ARM_VGIC_SYSREG_MASK (KVM_REG_ARM_VGIC_SYSREG_OP0_MASK | \
> +				      KVM_REG_ARM_VGIC_SYSREG_OP1_MASK | \
> +				      KVM_REG_ARM_VGIC_SYSREG_CRN_MASK | \
> +				      KVM_REG_ARM_VGIC_SYSREG_CRM_MASK | \
> +				      KVM_REG_ARM_VGIC_SYSREG_OP2_MASK)
> +
>  struct vgic_vmcr {
>  	u32	ctlr;
>  	u32	abpr;
> @@ -89,7 +132,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
>  int kvm_vgic_register_its_device(void);
>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>  int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
> -
> +int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr);
> +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 kvm_register_vgic_device(unsigned long type);
>  int vgic_lazy_init(struct kvm *kvm);
>  int vgic_init(struct kvm *kvm);
> -- 
> 1.9.1
> 

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply

* [PATCH v9 01/11] arm/arm64: vgic: Implement support for userspace access
From: Christoffer Dall @ 2016-11-28 13:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479906118-15832-2-git-send-email-vijay.kilari@gmail.com>

On Wed, Nov 23, 2016 at 06:31:48PM +0530, vijay.kilari at gmail.com wrote:
> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> 
> Read and write of some registers like ISPENDR and ICPENDR
> from userspace requires special handling when compared to
> guest access for these registers.
> 
> Refer to Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> for handling of ISPENDR, ICPENDR registers handling.
> 
> Add infrastructure to support guest and userspace read
> and write for the required registers
> Also moved vgic_uaccess from vgic-mmio-v2.c to vgic-mmio.c
> 
> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> ---
>  virt/kvm/arm/vgic/vgic-mmio-v2.c |  25 ----------
>  virt/kvm/arm/vgic/vgic-mmio-v3.c | 102 ++++++++++++++++++++++++++++++++-------
>  virt/kvm/arm/vgic/vgic-mmio.c    |  78 +++++++++++++++++++++++++++---
>  virt/kvm/arm/vgic/vgic-mmio.h    |  19 ++++++++
>  4 files changed, 175 insertions(+), 49 deletions(-)
> 
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
> index b44b359..0b32f40 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
> @@ -406,31 +406,6 @@ int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
>  	return -ENXIO;
>  }
>  
> -/*
> - * When userland tries to access the VGIC register handlers, we need to
> - * create a usable struct vgic_io_device to be passed to the handlers and we
> - * have to set up a buffer similar to what would have happened if a guest MMIO
> - * access occurred, including doing endian conversions on BE systems.
> - */
> -static int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev,
> -			bool is_write, int offset, u32 *val)
> -{
> -	unsigned int len = 4;
> -	u8 buf[4];
> -	int ret;
> -
> -	if (is_write) {
> -		vgic_data_host_to_mmio_bus(buf, len, *val);
> -		ret = kvm_io_gic_ops.write(vcpu, &dev->dev, offset, len, buf);
> -	} else {
> -		ret = kvm_io_gic_ops.read(vcpu, &dev->dev, offset, len, buf);
> -		if (!ret)
> -			*val = vgic_data_mmio_bus_to_host(buf, len);
> -	}
> -
> -	return ret;
> -}
> -
>  int vgic_v2_cpuif_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>  			  int offset, u32 *val)
>  {
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> index 50f42f0..8e76d04 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> @@ -207,6 +207,66 @@ static unsigned long vgic_mmio_read_v3_idregs(struct kvm_vcpu *vcpu,
>  	return 0;
>  }
>  
> +static unsigned long vgic_v3_uaccess_read_pending(struct kvm_vcpu *vcpu,
> +						  gpa_t addr, unsigned int len)
> +{
> +	u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
> +	u32 value = 0;
> +	int i;
> +
> +	/*
> +	 * A level triggerred interrupt pending state is latched in both
> +	 * "soft_pending" and "line_level" variables. Userspace will save
> +	 * and restore soft_pending and line_level separately.
> +	 * Refer to Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> +	 * handling of ISPENDR and ICPENDR.
> +	 */
> +	for (i = 0; i < len * 8; i++) {
> +		struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
> +
> +		if (irq->config == VGIC_CONFIG_LEVEL && irq->soft_pending)
> +			value |= (1U << i);
> +		if (irq->config == VGIC_CONFIG_EDGE && irq->pending)
> +			value |= (1U << i);
> +
> +		vgic_put_irq(vcpu->kvm, irq);
> +	}
> +
> +	return value;
> +}
> +
> +static void vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu,
> +					  gpa_t addr, unsigned int len,
> +					  unsigned long val)
> +{
> +	u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
> +	int i;
> +
> +	for (i = 0; i < len * 8; i++) {
> +		struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
> +
> +		spin_lock(&irq->irq_lock);
> +		if (test_bit(i, &val)) {
> +			/* soft_pending is set irrespective of irq type
> +			 * (level or edge) to avoid dependency that VM should
> +			 * restore irq config before pending info.
> +			 */

nit: kernel commenting style

> +			irq->pending = true;
> +			irq->soft_pending = true;
> +			vgic_queue_irq_unlock(vcpu->kvm, irq);
> +		} else {
> +			irq->soft_pending = false;
> +			if (irq->config == VGIC_CONFIG_EDGE ||
> +			    (irq->config == VGIC_CONFIG_LEVEL &&
> +			    !irq->line_level))
> +				irq->pending = false;
> +			spin_unlock(&irq->irq_lock);
> +		}
> +
> +		vgic_put_irq(vcpu->kvm, irq);
> +	}
> +}
> +
>  /* We want to avoid outer shareable. */
>  u64 vgic_sanitise_shareability(u64 field)
>  {
> @@ -356,7 +416,7 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
>   * We take some special care here to fix the calculation of the register
>   * offset.
>   */
> -#define REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(off, rd, wr, bpi, acc)	\
> +#define REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(off, rd, wr, ur, uw, bpi, acc) \
>  	{								\
>  		.reg_offset = off,					\
>  		.bits_per_irq = bpi,					\
> @@ -371,6 +431,8 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
>  		.access_flags = acc,					\
>  		.read = rd,						\
>  		.write = wr,						\
> +		.uaccess_read = ur,					\
> +		.uaccess_write = uw,					\
>  	}
>  
>  static const struct vgic_register_region vgic_v3_dist_registers[] = {
> @@ -378,40 +440,42 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
>  		vgic_mmio_read_v3_misc, vgic_mmio_write_v3_misc, 16,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IGROUPR,
> -		vgic_mmio_read_rao, vgic_mmio_write_wi, 1,
> +		vgic_mmio_read_rao, vgic_mmio_write_wi, NULL, NULL, 1,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISENABLER,
> -		vgic_mmio_read_enable, vgic_mmio_write_senable, 1,
> +		vgic_mmio_read_enable, vgic_mmio_write_senable, NULL, NULL, 1,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICENABLER,
> -		vgic_mmio_read_enable, vgic_mmio_write_cenable, 1,
> +		vgic_mmio_read_enable, vgic_mmio_write_cenable, NULL, NULL, 1,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISPENDR,
> -		vgic_mmio_read_pending, vgic_mmio_write_spending, 1,
> +		vgic_mmio_read_pending, vgic_mmio_write_spending,
> +		vgic_v3_uaccess_read_pending, vgic_v3_uaccess_write_pending, 1,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICPENDR,
> -		vgic_mmio_read_pending, vgic_mmio_write_cpending, 1,
> +		vgic_mmio_read_pending, vgic_mmio_write_cpending,
> +		vgic_mmio_read_raz, vgic_mmio_write_wi, 1,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISACTIVER,
> -		vgic_mmio_read_active, vgic_mmio_write_sactive, 1,
> +		vgic_mmio_read_active, vgic_mmio_write_sactive, NULL, NULL, 1,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICACTIVER,
> -		vgic_mmio_read_active, vgic_mmio_write_cactive, 1,
> +		vgic_mmio_read_active, vgic_mmio_write_cactive, NULL, NULL, 1,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IPRIORITYR,
> -		vgic_mmio_read_priority, vgic_mmio_write_priority, 8,
> -		VGIC_ACCESS_32bit | VGIC_ACCESS_8bit),
> +		vgic_mmio_read_priority, vgic_mmio_write_priority, NULL, NULL,
> +		8, VGIC_ACCESS_32bit | VGIC_ACCESS_8bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ITARGETSR,
> -		vgic_mmio_read_raz, vgic_mmio_write_wi, 8,
> +		vgic_mmio_read_raz, vgic_mmio_write_wi, NULL, NULL, 8,
>  		VGIC_ACCESS_32bit | VGIC_ACCESS_8bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICFGR,
> -		vgic_mmio_read_config, vgic_mmio_write_config, 2,
> +		vgic_mmio_read_config, vgic_mmio_write_config, NULL, NULL, 2,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IGRPMODR,
> -		vgic_mmio_read_raz, vgic_mmio_write_wi, 1,
> +		vgic_mmio_read_raz, vgic_mmio_write_wi, NULL, NULL, 1,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IROUTER,
> -		vgic_mmio_read_irouter, vgic_mmio_write_irouter, 64,
> +		vgic_mmio_read_irouter, vgic_mmio_write_irouter, NULL, NULL, 64,
>  		VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_LENGTH(GICD_IDREGS,
>  		vgic_mmio_read_v3_idregs, vgic_mmio_write_wi, 48,
> @@ -449,11 +513,13 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
>  	REGISTER_DESC_WITH_LENGTH(GICR_ICENABLER0,
>  		vgic_mmio_read_enable, vgic_mmio_write_cenable, 4,
>  		VGIC_ACCESS_32bit),
> -	REGISTER_DESC_WITH_LENGTH(GICR_ISPENDR0,
> -		vgic_mmio_read_pending, vgic_mmio_write_spending, 4,
> +	REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_ISPENDR0,
> +		vgic_mmio_read_pending, vgic_mmio_write_spending,
> +		vgic_v3_uaccess_read_pending, vgic_v3_uaccess_write_pending, 4,
>  		VGIC_ACCESS_32bit),
> -	REGISTER_DESC_WITH_LENGTH(GICR_ICPENDR0,
> -		vgic_mmio_read_pending, vgic_mmio_write_cpending, 4,
> +	REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_ICPENDR0,
> +		vgic_mmio_read_pending, vgic_mmio_write_cpending,
> +		vgic_mmio_read_raz, vgic_mmio_write_wi, 4,
>  		VGIC_ACCESS_32bit),
>  	REGISTER_DESC_WITH_LENGTH(GICR_ISACTIVER0,
>  		vgic_mmio_read_active, vgic_mmio_write_sactive, 4,
> diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
> index ebe1b9f..d5f3ee2 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio.c
> @@ -484,6 +484,74 @@ static bool check_region(const struct kvm *kvm,
>  	return false;
>  }
>  
> +static const struct vgic_register_region *
> +vgic_get_mmio_region(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev,
> +		     gpa_t addr, int len)
> +{
> +	const struct vgic_register_region *region;
> +
> +	region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
> +				       addr - iodev->base_addr);
> +	if (!region || !check_region(vcpu->kvm, region, addr, len))
> +		return NULL;
> +
> +	return region;
> +}
> +
> +static int vgic_uaccess_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
> +			     gpa_t addr, u32 *val)
> +{
> +	struct vgic_io_device *iodev = kvm_to_vgic_iodev(dev);
> +	const struct vgic_register_region *region;
> +	struct kvm_vcpu *r_vcpu;
> +
> +	region = vgic_get_mmio_region(vcpu, iodev, addr, sizeof(u32));
> +	if (!region) {
> +		*val = 0;
> +		return 0;
> +	}
> +
> +	r_vcpu = iodev->redist_vcpu ? iodev->redist_vcpu : vcpu;
> +	if (region->uaccess_read)
> +		*val = region->uaccess_read(r_vcpu, addr, sizeof(u32));
> +	else
> +		*val = region->read(r_vcpu, addr, sizeof(u32));
> +
> +	return 0;
> +}
> +
> +static int vgic_uaccess_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
> +			      gpa_t addr, const u32 *val)
> +{
> +	struct vgic_io_device *iodev = kvm_to_vgic_iodev(dev);
> +	const struct vgic_register_region *region;
> +	struct kvm_vcpu *r_vcpu;
> +
> +	region = vgic_get_mmio_region(vcpu, iodev, addr, sizeof(u32));
> +	if (!region)
> +		return 0;
> +
> +	r_vcpu = iodev->redist_vcpu ? iodev->redist_vcpu : vcpu;
> +	if (region->uaccess_write)
> +		region->uaccess_write(r_vcpu, addr, sizeof(u32), *val);
> +	else
> +		region->write(r_vcpu, addr, sizeof(u32), *val);
> +
> +	return 0;
> +}
> +
> +/*
> + * Userland access to VGIC registers.
> + */
> +int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev,
> +		 bool is_write, int offset, u32 *val)
> +{
> +	if (is_write)
> +		return vgic_uaccess_write(vcpu, &dev->dev, offset, val);
> +	else
> +		return vgic_uaccess_read(vcpu, &dev->dev, offset, val);
> +}
> +
>  static int dispatch_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
>  			      gpa_t addr, int len, void *val)
>  {
> @@ -491,9 +559,8 @@ static int dispatch_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
>  	const struct vgic_register_region *region;
>  	unsigned long data = 0;
>  
> -	region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
> -				       addr - iodev->base_addr);
> -	if (!region || !check_region(vcpu->kvm, region, addr, len)) {
> +	region = vgic_get_mmio_region(vcpu, iodev, addr, len);
> +	if (!region) {
>  		memset(val, 0, len);
>  		return 0;
>  	}
> @@ -524,9 +591,8 @@ static int dispatch_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
>  	const struct vgic_register_region *region;
>  	unsigned long data = vgic_data_mmio_bus_to_host(val, len);
>  
> -	region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
> -				       addr - iodev->base_addr);
> -	if (!region || !check_region(vcpu->kvm, region, addr, len))
> +	region = vgic_get_mmio_region(vcpu, iodev, addr, len);
> +	if (!region)
>  		return 0;
>  
>  	switch (iodev->iodev_type) {
> diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
> index 84961b4..7b30296 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio.h
> +++ b/virt/kvm/arm/vgic/vgic-mmio.h
> @@ -34,6 +34,10 @@ struct vgic_register_region {
>  				  gpa_t addr, unsigned int len,
>  				  unsigned long val);
>  	};
> +	unsigned long (*uaccess_read)(struct kvm_vcpu *vcpu, gpa_t addr,
> +				      unsigned int len);
> +	void (*uaccess_write)(struct kvm_vcpu *vcpu, gpa_t addr,
> +			      unsigned int len, unsigned long val);
>  };
>  
>  extern struct kvm_io_device_ops kvm_io_gic_ops;
> @@ -86,6 +90,18 @@ struct vgic_register_region {
>  		.write = wr,						\
>  	}
>  
> +#define REGISTER_DESC_WITH_LENGTH_UACCESS(off, rd, wr, urd, uwr, length, acc) \
> +	{								\
> +		.reg_offset = off,					\
> +		.bits_per_irq = 0,					\
> +		.len = length,						\
> +		.access_flags = acc,					\
> +		.read = rd,						\
> +		.write = wr,						\
> +		.uaccess_read = urd,					\
> +		.uaccess_write = uwr,					\
> +	}
> +
>  int kvm_vgic_register_mmio_region(struct kvm *kvm, struct kvm_vcpu *vcpu,
>  				  struct vgic_register_region *reg_desc,
>  				  struct vgic_io_device *region,
> @@ -158,6 +174,9 @@ void vgic_mmio_write_config(struct kvm_vcpu *vcpu,
>  			    gpa_t addr, unsigned int len,
>  			    unsigned long val);
>  
> +int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev,
> +		 bool is_write, int offset, u32 *val);
> +
>  unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev);
>  
>  unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev);
> -- 
> 1.9.1
> 

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ 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