Linux v4.17.2

This commit is contained in:
Justin M. Forbes 2018-06-22 09:56:46 -05:00
parent a98ecb2de3
commit b1f098774e
10729 changed files with 16885 additions and 6848 deletions

View File

@ -1,72 +0,0 @@
From b42db0860e13067fcc7cbfba3966c9e652668bbc Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@sandeen.net>
Date: Mon, 16 Apr 2018 23:06:53 -0700
Subject: [PATCH] xfs: enhance dinode verifier
Add several more validations to xfs_dinode_verify:
- For LOCAL data fork formats, di_nextents must be 0.
- For LOCAL attr fork formats, di_anextents must be 0.
- For inodes with no attr fork offset,
- format must be XFS_DINODE_FMT_EXTENTS if set at all
- di_anextents must be 0.
Thanks to dchinner for pointing out a couple related checks I had
forgotten to add.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199377
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
fs/xfs/libxfs/xfs_inode_buf.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index ef68b1de006a..1201107eabc6 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -466,6 +466,8 @@ xfs_dinode_verify(
return __this_address;
if (di_size > XFS_DFORK_DSIZE(dip, mp))
return __this_address;
+ if (dip->di_nextents)
+ return __this_address;
/* fall through */
case XFS_DINODE_FMT_EXTENTS:
case XFS_DINODE_FMT_BTREE:
@@ -484,12 +486,31 @@ xfs_dinode_verify(
if (XFS_DFORK_Q(dip)) {
switch (dip->di_aformat) {
case XFS_DINODE_FMT_LOCAL:
+ if (dip->di_anextents)
+ return __this_address;
+ /* fall through */
case XFS_DINODE_FMT_EXTENTS:
case XFS_DINODE_FMT_BTREE:
break;
default:
return __this_address;
}
+ } else {
+ /*
+ * If there is no fork offset, this may be a freshly-made inode
+ * in a new disk cluster, in which case di_aformat is zeroed.
+ * Otherwise, such an inode must be in EXTENTS format; this goes
+ * for freed inodes as well.
+ */
+ switch (dip->di_aformat) {
+ case 0:
+ case XFS_DINODE_FMT_EXTENTS:
+ break;
+ default:
+ return __this_address;
+ }
+ if (dip->di_anextents)
+ return __this_address;
}
/* only version 3 or greater inodes are extensively verified here */
--
2.17.0

View File

@ -1,45 +0,0 @@
From 2c4306f719b083d17df2963bc761777576b8ad1b Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Mon, 16 Apr 2018 23:07:27 -0700
Subject: [PATCH] xfs: set format back to extents if xfs_bmap_extents_to_btree
If xfs_bmap_extents_to_btree fails in a mode where we call
xfs_iroot_realloc(-1) to de-allocate the root, set the
format back to extents.
Otherwise we can assume we can dereference ifp->if_broot
based on the XFS_DINODE_FMT_BTREE format, and crash.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199423
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
fs/xfs/libxfs/xfs_bmap.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 6a7c2f03ea11..040eeda8426f 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -725,12 +725,16 @@ xfs_bmap_extents_to_btree(
*logflagsp = 0;
if ((error = xfs_alloc_vextent(&args))) {
xfs_iroot_realloc(ip, -1, whichfork);
+ ASSERT(ifp->if_broot == NULL);
+ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
return error;
}
if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) {
xfs_iroot_realloc(ip, -1, whichfork);
+ ASSERT(ifp->if_broot == NULL);
+ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
return -ENOSPC;
}
--
2.17.0

View File

@ -0,0 +1,46 @@
From patchwork Thu Jun 21 13:00:20 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [1/2] xen-netfront: Fix mismatched rtnl_unlock
X-Patchwork-Submitter: Ross Lagerwall <ross.lagerwall@citrix.com>
X-Patchwork-Id: 932721
Message-Id: <20180621130021.27029-2-ross.lagerwall@citrix.com>
To: <netdev@vger.kernel.org>
Cc: Ross Lagerwall <ross.lagerwall@citrix.com>,
Boris Ostrovsky <boris.ostrovsky@oracle.com>,
Juergen Gross <jgross@suse.com>, "David S. Miller" <davem@davemloft.net>,
<xen-devel@lists.xenproject.org>, <linux-kernel@vger.kernel.org>
Date: Thu, 21 Jun 2018 14:00:20 +0100
From: Ross Lagerwall <ross.lagerwall@citrix.com>
List-Id: <netdev.vger.kernel.org>
Fixes: f599c64fdf7d ("xen-netfront: Fix race between device setup and open")
Reported-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
---
drivers/net/xen-netfront.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 922ce0a..ee4cb6c 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1810,7 +1810,7 @@ static int talk_to_netback(struct xenbus_device *dev,
err = xen_net_read_mac(dev, info->netdev->dev_addr);
if (err) {
xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
- goto out;
+ goto out_unlocked;
}
rtnl_lock();
@@ -1925,6 +1925,7 @@ static int talk_to_netback(struct xenbus_device *dev,
xennet_destroy_queues(info);
out:
rtnl_unlock();
+out_unlocked:
device_unregister(&dev->dev);
return err;
}

View File

@ -0,0 +1,58 @@
From patchwork Thu Jun 21 13:00:21 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [2/2] xen-netfront: Update features after registering netdev
X-Patchwork-Submitter: Ross Lagerwall <ross.lagerwall@citrix.com>
X-Patchwork-Id: 932720
Message-Id: <20180621130021.27029-3-ross.lagerwall@citrix.com>
To: <netdev@vger.kernel.org>
Cc: Ross Lagerwall <ross.lagerwall@citrix.com>,
Boris Ostrovsky <boris.ostrovsky@oracle.com>,
Juergen Gross <jgross@suse.com>, "David S. Miller" <davem@davemloft.net>,
<xen-devel@lists.xenproject.org>, <linux-kernel@vger.kernel.org>,
Liam Shepherd <liam@dancer.es>
Date: Thu, 21 Jun 2018 14:00:21 +0100
From: Ross Lagerwall <ross.lagerwall@citrix.com>
List-Id: <netdev.vger.kernel.org>
Update the features after calling register_netdev() otherwise the
device features are not set up correctly and it not possible to change
the MTU of the device. After this change, the features reported by
ethtool match the device's features before the commit which introduced
the issue and it is possible to change the device's MTU.
Fixes: f599c64fdf7d ("xen-netfront: Fix race between device setup and open")
Reported-by: Liam Shepherd <liam@dancer.es>
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
---
drivers/net/xen-netfront.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index ee4cb6c..a57daec 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1951,10 +1951,6 @@ static int xennet_connect(struct net_device *dev)
/* talk_to_netback() sets the correct number of queues */
num_queues = dev->real_num_tx_queues;
- rtnl_lock();
- netdev_update_features(dev);
- rtnl_unlock();
-
if (dev->reg_state == NETREG_UNINITIALIZED) {
err = register_netdev(dev);
if (err) {
@@ -1964,6 +1960,10 @@ static int xennet_connect(struct net_device *dev)
}
}
+ rtnl_lock();
+ netdev_update_features(dev);
+ rtnl_unlock();
+
/*
* All public and private state should now be sane. Get
* ready to start sending and receiving packets and give the driver

View File

@ -33,9 +33,9 @@ config heirarchy.
Instead of having to maintain a config file for every arch variant we build on,
the kernel spec uses a nested system of configs. Each option CONFIG_FOO is
represented by a single file named CONFIG_FOO which contains the state (=y, =m,
=n). These options are collected in the folder baseconfig. Architecture specifi
options are set in nested folders. An option set in a nested folder will
override the same option set in one of the higher levels.
=n). These options are collected in the folder base-generic. Architecture
specific options are set in nested folders. An option set in a nested folder
will override the same option set in one of the higher levels.
The individual CONFIG_FOO files only exist in the pkg-git repository. The RPM
contains kernel-foo.config files which are the result of combining all the
@ -45,10 +45,10 @@ script _must_ be run each time one of the options is changed.
Example flow:
# Enable the option CONFIG_ABC123 as a module for all arches
echo "CONFIG_ABC123=m" > baseconfig/CONFIG_ABC1234
echo "CONFIG_ABC123=m" > configs/base-generic/CONFIG_ABC1234
# enable the option CONFIG_XYZ321 for only x86
echo "# CONFIG_XYZ321 is not set" > baseconfig/CONFIG_XYZ321
echo "CONFIG_XYZ321=m" > baseconfig/x86/CONFIG_XYZ321
echo "# CONFIG_XYZ321 is not set" > configs/base-generic/CONFIG_XYZ321
echo "CONFIG_XYZ321=m" > configs/base-generic/x86/CONFIG_XYZ321
# regenerate the combined config files
./build_configs.sh
@ -72,7 +72,7 @@ the status quo to:
This is done to increase coverage testing, as not many people actually
run kernel-debug.
The debug options are managed in a separate heierarchy under debugconfig. This
works in a similar manner to baseconfig. More deeply nested folders, again,
The debug options are managed in a separate heierarchy under base-debug. This
works in a similar manner to base-generic. More deeply nested folders, again,
override options. The file config_generation gives a listing of what folders
go into each config file generated.

View File

@ -1,160 +0,0 @@
From 5744a0927df22f46e4b7f134b3dfb405fdfcf6ce Mon Sep 17 00:00:00 2001
From: Jeremy Cline <jeremy@jcline.org>
Date: Wed, 2 May 2018 15:16:29 -0400
Subject: [PATCH 1/2] Revert "random: use a different mixing algorithm for
add_device_randomness()"
This reverts commit 89b59f050347d376c2ace8b1ceb908a218cfdc2e.
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
---
drivers/char/random.c | 55 ++++---------------------------------------
1 file changed, 4 insertions(+), 51 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 8f4e11842c60..aa5b04af86c6 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -831,10 +831,6 @@ static void numa_crng_init(void)
static void numa_crng_init(void) {}
#endif
-/*
- * crng_fast_load() can be called by code in the interrupt service
- * path. So we can't afford to dilly-dally.
- */
static int crng_fast_load(const char *cp, size_t len)
{
unsigned long flags;
@@ -861,51 +857,6 @@ static int crng_fast_load(const char *cp, size_t len)
return 1;
}
-/*
- * crng_slow_load() is called by add_device_randomness, which has two
- * attributes. (1) We can't trust the buffer passed to it is
- * guaranteed to be unpredictable (so it might not have any entropy at
- * all), and (2) it doesn't have the performance constraints of
- * crng_fast_load().
- *
- * So we do something more comprehensive which is guaranteed to touch
- * all of the primary_crng's state, and which uses a LFSR with a
- * period of 255 as part of the mixing algorithm. Finally, we do
- * *not* advance crng_init_cnt since buffer we may get may be something
- * like a fixed DMI table (for example), which might very well be
- * unique to the machine, but is otherwise unvarying.
- */
-static int crng_slow_load(const char *cp, size_t len)
-{
- unsigned long flags;
- static unsigned char lfsr = 1;
- unsigned char tmp;
- unsigned i, max = CHACHA20_KEY_SIZE;
- const char * src_buf = cp;
- char * dest_buf = (char *) &primary_crng.state[4];
-
- if (!spin_trylock_irqsave(&primary_crng.lock, flags))
- return 0;
- if (crng_init != 0) {
- spin_unlock_irqrestore(&primary_crng.lock, flags);
- return 0;
- }
- if (len > max)
- max = len;
-
- for (i = 0; i < max ; i++) {
- tmp = lfsr;
- lfsr >>= 1;
- if (tmp & 1)
- lfsr ^= 0xE1;
- tmp = dest_buf[i % CHACHA20_KEY_SIZE];
- dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr;
- lfsr += (tmp << 3) | (tmp >> 5);
- }
- spin_unlock_irqrestore(&primary_crng.lock, flags);
- return 1;
-}
-
static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
{
unsigned long flags;
@@ -1089,8 +1040,10 @@ void add_device_randomness(const void *buf, unsigned int size)
unsigned long time = random_get_entropy() ^ jiffies;
unsigned long flags;
- if (!crng_ready() && size)
- crng_slow_load(buf, size);
+ if (!crng_ready()) {
+ crng_fast_load(buf, size);
+ return;
+ }
trace_add_device_randomness(size, _RET_IP_);
spin_lock_irqsave(&input_pool.lock, flags);
--
2.17.0
From e1b1b5b62740b0e6ea8258a4eb81b2a336538fed Mon Sep 17 00:00:00 2001
From: Jeremy Cline <jeremy@jcline.org>
Date: Wed, 2 May 2018 15:18:03 -0400
Subject: [PATCH 2/2] Revert "random: fix crng_ready() test"
This reverts commit cd8d7a5778a4abf76ee8fe8f1bfcf78976029f8d.
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
---
drivers/char/random.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index aa5b04af86c6..ef05cc685b74 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -428,7 +428,7 @@ struct crng_state primary_crng = {
* its value (from 0->1->2).
*/
static int crng_init = 0;
-#define crng_ready() (likely(crng_init > 1))
+#define crng_ready() (likely(crng_init > 0))
static int crng_init_cnt = 0;
static unsigned long crng_global_init_time = 0;
#define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
@@ -838,7 +838,7 @@ static int crng_fast_load(const char *cp, size_t len)
if (!spin_trylock_irqsave(&primary_crng.lock, flags))
return 0;
- if (crng_init != 0) {
+ if (crng_ready()) {
spin_unlock_irqrestore(&primary_crng.lock, flags);
return 0;
}
@@ -913,7 +913,7 @@ static void _extract_crng(struct crng_state *crng,
{
unsigned long v, flags;
- if (crng_ready() &&
+ if (crng_init > 1 &&
(time_after(crng_global_init_time, crng->init_time) ||
time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)))
crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
@@ -1200,7 +1200,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
fast_mix(fast_pool);
add_interrupt_bench(cycles);
- if (unlikely(crng_init == 0)) {
+ if (!crng_ready()) {
if ((fast_pool->count >= 64) &&
crng_fast_load((char *) fast_pool->pool,
sizeof(fast_pool->pool))) {
@@ -2269,7 +2269,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
{
struct entropy_store *poolp = &input_pool;
- if (unlikely(crng_init == 0)) {
+ if (!crng_ready()) {
crng_fast_load(buffer, count);
return;
}
--
2.17.0

View File

@ -1,7 +1,19 @@
From bb86b4b0bbae12341df16fedf51aeda480364fbf Mon Sep 17 00:00:00 2001
From: Peter Robinson <pbrobinson@gmail.com>
Date: Thu, 19 Apr 2018 19:35:58 +0100
Subject: [PATCH] ARM: dts: Add am335x-pocketbeagle
From patchwork Tue Apr 17 17:14:04 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v3] ARM: dts: Add am335x-pocketbeagle
From: Robert Nelson <robertcnelson@gmail.com>
X-Patchwork-Id: 10346089
Message-Id: <20180417171404.13624-1-robertcnelson@gmail.com>
To: tony@atomide.com,
devicetree@vger.kernel.org
Cc: Drew Fustini <drew@beagleboard.org>,
Peter Robinson <pbrobinson@redhat.com>,
Jason Kridner <jkridner@beagleboard.org>, linux-omap@vger.kernel.org,
Robert Nelson <robertcnelson@gmail.com>,
linux-arm-kernel@lists.infradead.org
Date: Tue, 17 Apr 2018 12:14:04 -0500
PocketBeagle is an ultra-tiny-yet-complete open-source USB-key-fob computer.
@ -12,7 +24,6 @@ http://beagleboard.org/pocket
https://github.com/beagleboard/pocketbeagle
Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
CC: Tony Lindgren <tony@atomide.com>
CC: Jason Kridner <jkridner@beagleboard.org>
CC: Drew Fustini <drew@beagleboard.org>
@ -35,11 +46,11 @@ Changes in v2:
create mode 100644 arch/arm/boot/dts/am335x-pocketbeagle.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index ade7a38543dc..a632bbef01f5 100644
index 7e2424957809..5a09ff15743b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -675,6 +675,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \
am335x-nano.dtb \
@@ -688,6 +688,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \
am335x-pdu001.dtb \
am335x-pepper.dtb \
am335x-phycore-rdk.dtb \
+ am335x-pocketbeagle.dtb \
@ -48,7 +59,7 @@ index ade7a38543dc..a632bbef01f5 100644
am335x-sl50.dtb \
diff --git a/arch/arm/boot/dts/am335x-osd335x-common.dtsi b/arch/arm/boot/dts/am335x-osd335x-common.dtsi
new file mode 100644
index 000000000000..f8ff473f94f0
index 000000000000..d2150d207b7a
--- /dev/null
+++ b/arch/arm/boot/dts/am335x-osd335x-common.dtsi
@@ -0,0 +1,124 @@
@ -419,6 +430,3 @@ index 000000000000..62fe5cab9fae
+&cppi41dma {
+ status = "okay";
+};
--
2.17.0

View File

@ -1,131 +0,0 @@
From 0ab09d651b5858f9bc7d5f74e725334a661828e0 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Fri, 9 Mar 2018 14:47:17 +0000
Subject: nvmem: sunxi-sid: fix H3 SID controller support
It seems that doing some operation will make the value pre-read on H3
SID controller wrong again, so all operation should be performed by
register.
Change the SID reading to use register only.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/sunxi_sid.c | 71 +++++++++++++++++++++++++++++++++--------------
1 file changed, 50 insertions(+), 21 deletions(-)
diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 99bd54d..26bb637 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -85,13 +85,14 @@ static int sunxi_sid_read(void *context, unsigned int offset,
}
static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
- const unsigned int word)
+ const unsigned int offset,
+ u32 *out)
{
u32 reg_val;
int ret;
/* Set word, lock access, and set read command */
- reg_val = (word & SUN8I_SID_OFFSET_MASK)
+ reg_val = (offset & SUN8I_SID_OFFSET_MASK)
<< SUN8I_SID_OFFSET_SHIFT;
reg_val |= SUN8I_SID_OP_LOCK | SUN8I_SID_READ;
writel(reg_val, sid->base + SUN8I_SID_PRCTL);
@@ -101,7 +102,49 @@ static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
if (ret)
return ret;
+ if (out)
+ *out = readl(sid->base + SUN8I_SID_RDKEY);
+
writel(0, sid->base + SUN8I_SID_PRCTL);
+
+ return 0;
+}
+
+/*
+ * On Allwinner H3, the value on the 0x200 offset of the SID controller seems
+ * to be not reliable at all.
+ * Read by the registers instead.
+ */
+static int sun8i_sid_read_byte_by_reg(const struct sunxi_sid *sid,
+ const unsigned int offset,
+ u8 *out)
+{
+ u32 word;
+ int ret;
+
+ ret = sun8i_sid_register_readout(sid, offset & ~0x03, &word);
+
+ if (ret)
+ return ret;
+
+ *out = (word >> ((offset & 0x3) * 8)) & 0xff;
+
+ return 0;
+}
+
+static int sun8i_sid_read_by_reg(void *context, unsigned int offset,
+ void *val, size_t bytes)
+{
+ struct sunxi_sid *sid = context;
+ u8 *buf = val;
+ int ret;
+
+ while (bytes--) {
+ ret = sun8i_sid_read_byte_by_reg(sid, offset++, buf++);
+ if (ret)
+ return ret;
+ }
+
return 0;
}
@@ -131,26 +174,12 @@ static int sunxi_sid_probe(struct platform_device *pdev)
size = cfg->size;
- if (cfg->need_register_readout) {
- /*
- * H3's SID controller have a bug that the value at 0x200
- * offset is not the correct value when the hardware is reseted.
- * However, after doing a register-based read operation, the
- * value become right.
- * Do a full read operation here, but ignore its value
- * (as it's more fast to read by direct MMIO value than
- * with registers)
- */
- for (i = 0; i < (size >> 2); i++) {
- ret = sun8i_sid_register_readout(sid, i);
- if (ret)
- return ret;
- }
- }
-
econfig.size = size;
econfig.dev = dev;
- econfig.reg_read = sunxi_sid_read;
+ if (cfg->need_register_readout)
+ econfig.reg_read = sun8i_sid_read_by_reg;
+ else
+ econfig.reg_read = sunxi_sid_read;
econfig.priv = sid;
nvmem = nvmem_register(&econfig);
if (IS_ERR(nvmem))
@@ -163,7 +192,7 @@ static int sunxi_sid_probe(struct platform_device *pdev)
}
for (i = 0; i < size; i++)
- randomness[i] = sunxi_sid_read_byte(sid, i);
+ econfig.reg_read(sid, i, &randomness[i], 1);
add_device_randomness(randomness, size);
kfree(randomness);
--
cgit v1.1

View File

@ -1,857 +0,0 @@
From patchwork Wed Mar 28 09:50:48 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v2,1/2] arm64: fpsimd: Split cpu field out from struct fpsimd_state
From: Dave P Martin <Dave.Martin@arm.com>
X-Patchwork-Id: 10312693
Message-Id: <1522230649-22008-2-git-send-email-Dave.Martin@arm.com>
To: linux-arm-kernel@lists.infradead.org
Cc: Mark Rutland <mark.rutland@arm.com>, Will Deacon <will.deacon@arm.com>,
Kees Cook <keescook@chromium.org>
Date: Wed, 28 Mar 2018 10:50:48 +0100
In preparation for using a common representation of the FPSIMD
state for tasks and KVM vcpus, this patch separates out the "cpu"
field that is used to track the cpu on which the state was most
recently loaded.
This will allow common code to operate on task and vcpu contexts
without requiring the cpu field to be stored at the same offset
from the FPSIMD register data in both cases. This should avoid the
need for messing with the definition of those parts of struct
vcpu_arch that are exposed in the KVM user ABI.
The resulting change is also convenient for grouping and defining
the set of thread_struct fields that are supposed to be accessible
to copy_{to,from}_user(), which includes user_fpsimd_state but
should exclude the cpu field. This patch does not amend the
usercopy whitelist to match: that will be addressed in a subsequent
patch.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm64/include/asm/fpsimd.h | 29 ++------------------------
arch/arm64/include/asm/processor.h | 4 ++--
arch/arm64/kernel/fpsimd.c | 42 +++++++++++++++++++++-----------------
arch/arm64/kernel/ptrace.c | 10 ++++-----
arch/arm64/kernel/signal.c | 3 +--
arch/arm64/kernel/signal32.c | 3 +--
6 files changed, 34 insertions(+), 57 deletions(-)
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 8857a0f..1bfc920 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -24,31 +24,6 @@
#include <linux/cache.h>
#include <linux/stddef.h>
-/*
- * FP/SIMD storage area has:
- * - FPSR and FPCR
- * - 32 128-bit data registers
- *
- * Note that user_fpsimd forms a prefix of this structure, which is
- * relied upon in the ptrace FP/SIMD accessors.
- */
-struct fpsimd_state {
- union {
- struct user_fpsimd_state user_fpsimd;
- struct {
- __uint128_t vregs[32];
- u32 fpsr;
- u32 fpcr;
- /*
- * For ptrace compatibility, pad to next 128-bit
- * boundary here if extending this struct.
- */
- };
- };
- /* the id of the last cpu to have restored this state */
- unsigned int cpu;
-};
-
#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
/* Masks for extracting the FPSR and FPCR from the FPSCR */
#define VFP_FPSCR_STAT_MASK 0xf800009f
@@ -62,8 +37,8 @@ struct fpsimd_state {
struct task_struct;
-extern void fpsimd_save_state(struct fpsimd_state *state);
-extern void fpsimd_load_state(struct fpsimd_state *state);
+extern void fpsimd_save_state(struct user_fpsimd_state *state);
+extern void fpsimd_load_state(struct user_fpsimd_state *state);
extern void fpsimd_thread_switch(struct task_struct *next);
extern void fpsimd_flush_thread(void);
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index fce604e..4a04535 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -37,7 +37,6 @@
#include <linux/string.h>
#include <asm/alternative.h>
-#include <asm/fpsimd.h>
#include <asm/hw_breakpoint.h>
#include <asm/lse.h>
#include <asm/pgtable-hwdef.h>
@@ -107,7 +106,8 @@ struct thread_struct {
#ifdef CONFIG_COMPAT
unsigned long tp2_value;
#endif
- struct fpsimd_state fpsimd_state;
+ struct user_fpsimd_state fpsimd_state;
+ unsigned int fpsimd_cpu;
void *sve_state; /* SVE registers, if any */
unsigned int sve_vl; /* SVE vector length */
unsigned int sve_vl_onexec; /* SVE vl after next exec */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index e7226c4..c4be311 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -64,7 +64,7 @@
* been loaded into its FPSIMD registers most recently, or whether it has
* been used to perform kernel mode NEON in the meantime.
*
- * For (a), we add a 'cpu' field to struct fpsimd_state, which gets updated to
+ * For (a), we add a fpsimd_cpu field to thread_struct, which gets updated to
* the id of the current CPU every time the state is loaded onto a CPU. For (b),
* we add the per-cpu variable 'fpsimd_last_state' (below), which contains the
* address of the userland FPSIMD state of the task that was loaded onto the CPU
@@ -73,7 +73,7 @@
* With this in place, we no longer have to restore the next FPSIMD state right
* when switching between tasks. Instead, we can defer this check to userland
* resume, at which time we verify whether the CPU's fpsimd_last_state and the
- * task's fpsimd_state.cpu are still mutually in sync. If this is the case, we
+ * task's fpsimd_cpu are still mutually in sync. If this is the case, we
* can omit the FPSIMD restore.
*
* As an optimization, we use the thread_info flag TIF_FOREIGN_FPSTATE to
@@ -90,14 +90,14 @@
* flag with local_bh_disable() unless softirqs are already masked.
*
* For a certain task, the sequence may look something like this:
- * - the task gets scheduled in; if both the task's fpsimd_state.cpu field
+ * - the task gets scheduled in; if both the task's fpsimd_cpu field
* contains the id of the current CPU, and the CPU's fpsimd_last_state per-cpu
* variable points to the task's fpsimd_state, the TIF_FOREIGN_FPSTATE flag is
* cleared, otherwise it is set;
*
* - the task returns to userland; if TIF_FOREIGN_FPSTATE is set, the task's
* userland FPSIMD state is copied from memory to the registers, the task's
- * fpsimd_state.cpu field is set to the id of the current CPU, the current
+ * fpsimd_cpu field is set to the id of the current CPU, the current
* CPU's fpsimd_last_state pointer is set to this task's fpsimd_state and the
* TIF_FOREIGN_FPSTATE flag is cleared;
*
@@ -115,7 +115,7 @@
* whatever is in the FPSIMD registers is not saved to memory, but discarded.
*/
struct fpsimd_last_state_struct {
- struct fpsimd_state *st;
+ struct user_fpsimd_state *st;
bool sve_in_use;
};
@@ -417,7 +417,7 @@ static void fpsimd_to_sve(struct task_struct *task)
{
unsigned int vq;
void *sst = task->thread.sve_state;
- struct fpsimd_state const *fst = &task->thread.fpsimd_state;
+ struct user_fpsimd_state const *fst = &task->thread.fpsimd_state;
unsigned int i;
if (!system_supports_sve())
@@ -443,7 +443,7 @@ static void sve_to_fpsimd(struct task_struct *task)
{
unsigned int vq;
void const *sst = task->thread.sve_state;
- struct fpsimd_state *fst = &task->thread.fpsimd_state;
+ struct user_fpsimd_state *fst = &task->thread.fpsimd_state;
unsigned int i;
if (!system_supports_sve())
@@ -539,7 +539,7 @@ void sve_sync_from_fpsimd_zeropad(struct task_struct *task)
{
unsigned int vq;
void *sst = task->thread.sve_state;
- struct fpsimd_state const *fst = &task->thread.fpsimd_state;
+ struct user_fpsimd_state const *fst = &task->thread.fpsimd_state;
unsigned int i;
if (!test_tsk_thread_flag(task, TIF_SVE))
@@ -908,10 +908,9 @@ void fpsimd_thread_switch(struct task_struct *next)
* the TIF_FOREIGN_FPSTATE flag so the state will be loaded
* upon the next return to userland.
*/
- struct fpsimd_state *st = &next->thread.fpsimd_state;
-
- if (__this_cpu_read(fpsimd_last_state.st) == st
- && st->cpu == smp_processor_id())
+ if (__this_cpu_read(fpsimd_last_state.st) ==
+ &next->thread.fpsimd_state
+ && next->thread.fpsimd_cpu == smp_processor_id())
clear_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE);
else
set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE);
@@ -927,7 +926,8 @@ void fpsimd_flush_thread(void)
local_bh_disable();
- memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
+ memset(&current->thread.fpsimd_state, 0,
+ sizeof current->thread.fpsimd_state);
fpsimd_flush_task_state(current);
if (system_supports_sve()) {
@@ -1004,11 +1004,10 @@ static void fpsimd_bind_to_cpu(void)
{
struct fpsimd_last_state_struct *last =
this_cpu_ptr(&fpsimd_last_state);
- struct fpsimd_state *st = &current->thread.fpsimd_state;
- last->st = st;
+ last->st = &current->thread.fpsimd_state;
last->sve_in_use = test_thread_flag(TIF_SVE);
- st->cpu = smp_processor_id();
+ current->thread.fpsimd_cpu = smp_processor_id();
}
/*
@@ -1043,7 +1042,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
local_bh_disable();
- current->thread.fpsimd_state.user_fpsimd = *state;
+ current->thread.fpsimd_state = *state;
if (system_supports_sve() && test_thread_flag(TIF_SVE))
fpsimd_to_sve(current);
@@ -1055,12 +1054,17 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
local_bh_enable();
}
+void fpsimd_flush_state(unsigned int *cpu)
+{
+ *cpu = NR_CPUS;
+}
+
/*
* Invalidate live CPU copies of task t's FPSIMD state
*/
void fpsimd_flush_task_state(struct task_struct *t)
{
- t->thread.fpsimd_state.cpu = NR_CPUS;
+ fpsimd_flush_state(&t->thread.fpsimd_cpu);
}
static inline void fpsimd_flush_cpu_state(void)
@@ -1159,7 +1163,7 @@ EXPORT_SYMBOL(kernel_neon_end);
#ifdef CONFIG_EFI
-static DEFINE_PER_CPU(struct fpsimd_state, efi_fpsimd_state);
+static DEFINE_PER_CPU(struct user_fpsimd_state, efi_fpsimd_state);
static DEFINE_PER_CPU(bool, efi_fpsimd_state_used);
static DEFINE_PER_CPU(bool, efi_sve_state_used);
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 9ae31f7..fdeaba0de 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -629,7 +629,7 @@ static int __fpr_get(struct task_struct *target,
sve_sync_to_fpsimd(target);
- uregs = &target->thread.fpsimd_state.user_fpsimd;
+ uregs = &target->thread.fpsimd_state;
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs,
start_pos, start_pos + sizeof(*uregs));
@@ -660,14 +660,14 @@ static int __fpr_set(struct task_struct *target,
*/
sve_sync_to_fpsimd(target);
- newstate = target->thread.fpsimd_state.user_fpsimd;
+ newstate = target->thread.fpsimd_state;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate,
start_pos, start_pos + sizeof(newstate));
if (ret)
return ret;
- target->thread.fpsimd_state.user_fpsimd = newstate;
+ target->thread.fpsimd_state = newstate;
return ret;
}
@@ -1169,7 +1169,7 @@ static int compat_vfp_get(struct task_struct *target,
compat_ulong_t fpscr;
int ret, vregs_end_pos;
- uregs = &target->thread.fpsimd_state.user_fpsimd;
+ uregs = &target->thread.fpsimd_state;
if (target == current)
fpsimd_preserve_current_state();
@@ -1202,7 +1202,7 @@ static int compat_vfp_set(struct task_struct *target,
compat_ulong_t fpscr;
int ret, vregs_end_pos;
- uregs = &target->thread.fpsimd_state.user_fpsimd;
+ uregs = &target->thread.fpsimd_state;
vregs_end_pos = VFP_STATE_SIZE - sizeof(compat_ulong_t);
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0,
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index f60c052..d026615 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -178,8 +178,7 @@ static void __user *apply_user_offset(
static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
{
- struct user_fpsimd_state const *fpsimd =
- &current->thread.fpsimd_state.user_fpsimd;
+ struct user_fpsimd_state const *fpsimd = &current->thread.fpsimd_state;
int err;
/* copy the FP and status/control registers */
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 79feb86..4ea38d3 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -148,8 +148,7 @@ union __fpsimd_vreg {
static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame)
{
- struct user_fpsimd_state const *fpsimd =
- &current->thread.fpsimd_state.user_fpsimd;
+ struct user_fpsimd_state const *fpsimd = &current->thread.fpsimd_state;
compat_ulong_t magic = VFP_MAGIC;
compat_ulong_t size = VFP_STORAGE_SIZE;
compat_ulong_t fpscr, fpexc;
From patchwork Wed Mar 28 09:50:49 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v2,2/2] arm64: uaccess: Fix omissions from usercopy whitelist
From: Dave P Martin <Dave.Martin@arm.com>
X-Patchwork-Id: 10312691
Message-Id: <1522230649-22008-3-git-send-email-Dave.Martin@arm.com>
To: linux-arm-kernel@lists.infradead.org
Cc: Mark Rutland <mark.rutland@arm.com>, Will Deacon <will.deacon@arm.com>,
Kees Cook <keescook@chromium.org>
Date: Wed, 28 Mar 2018 10:50:49 +0100
When the hardend usercopy support was added for arm64, it was
concluded that all cases of usercopy into and out of thread_struct
were statically sized and so didn't require explicit whitelisting
of the appropriate fields in thread_struct.
Testing with usercopy hardening enabled has revealed that this is
not the case for certain ptrace regset manipulation calls on arm64.
This occurs because the sizes of usercopies associated with the
regset API are dynamic by construction, and because arm64 does not
always stage such copies via the stack: indeed the regset API is
designed to avoid the need for that by adding some bounds checking.
This is currently believed to affect only the fpsimd and TLS
registers.
Because the whitelisted fields in thread_struct must be contiguous,
this patch groups them together in a nested struct. It is also
necessary to be able to determine the location and size of that
struct, so rather than making the struct anonymous (which would
save on edits elsewhere) or adding an anonymous union containing
named and unnamed instances of the same struct (gross), this patch
gives the struct a name and makes the necessary edits to code that
references it (noisy but simple).
Care is needed to ensure that the new struct does not contain
padding (which the usercopy hardening would fail to protect).
For this reason, the presence of tp2_value is made unconditional,
since a padding field would be needed there in any case. This pads
up to the 16-byte alignment required by struct user_fpsimd_state.
Reported-by: Mark Rutland <mark.rutland@arm.com>
Fixes: 9e8084d3f761 ("arm64: Implement thread_struct whitelist for hardened usercopy")
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Kees Cook <keescook@chromium.org>
---
Changes since v1:
* Add a BUILD_BUG_ON() check for padding in the whitelist struct.
* Move to using sizeof_field() for assigning *size; get rid of the
dummy pointer that was used previously.
* Delete bogus comment about why no whitelist is (was) needed.
---
arch/arm64/include/asm/processor.h | 38 +++++++++++++++++++-----------
arch/arm64/kernel/fpsimd.c | 47 +++++++++++++++++++-------------------
arch/arm64/kernel/process.c | 6 ++---
arch/arm64/kernel/ptrace.c | 30 ++++++++++++------------
arch/arm64/kernel/signal.c | 3 ++-
arch/arm64/kernel/signal32.c | 3 ++-
arch/arm64/kernel/sys_compat.c | 2 +-
7 files changed, 72 insertions(+), 57 deletions(-)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 4a04535..224af48 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -34,6 +34,8 @@
#ifdef __KERNEL__
+#include <linux/build_bug.h>
+#include <linux/stddef.h>
#include <linux/string.h>
#include <asm/alternative.h>
@@ -102,11 +104,18 @@ struct cpu_context {
struct thread_struct {
struct cpu_context cpu_context; /* cpu context */
- unsigned long tp_value; /* TLS register */
-#ifdef CONFIG_COMPAT
- unsigned long tp2_value;
-#endif
- struct user_fpsimd_state fpsimd_state;
+
+ /*
+ * Whitelisted fields for hardened usercopy:
+ * Maintainers must ensure manually that this contains no
+ * implicit padding.
+ */
+ struct {
+ unsigned long tp_value; /* TLS register */
+ unsigned long tp2_value;
+ struct user_fpsimd_state fpsimd_state;
+ } uw;
+
unsigned int fpsimd_cpu;
void *sve_state; /* SVE registers, if any */
unsigned int sve_vl; /* SVE vector length */
@@ -116,14 +125,17 @@ struct thread_struct {
struct debug_info debug; /* debugging */
};
-/*
- * Everything usercopied to/from thread_struct is statically-sized, so
- * no hardened usercopy whitelist is needed.
- */
static inline void arch_thread_struct_whitelist(unsigned long *offset,
unsigned long *size)
{
- *offset = *size = 0;
+ /* Verify that there is no padding among the whitelisted fields: */
+ BUILD_BUG_ON(sizeof_field(struct thread_struct, uw) !=
+ sizeof_field(struct thread_struct, uw.tp_value) +
+ sizeof_field(struct thread_struct, uw.tp2_value) +
+ sizeof_field(struct thread_struct, uw.fpsimd_state));
+
+ *offset = offsetof(struct thread_struct, uw);
+ *size = sizeof_field(struct thread_struct, uw);
}
#ifdef CONFIG_COMPAT
@@ -131,13 +143,13 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
({ \
unsigned long *__tls; \
if (is_compat_thread(task_thread_info(t))) \
- __tls = &(t)->thread.tp2_value; \
+ __tls = &(t)->thread.uw.tp2_value; \
else \
- __tls = &(t)->thread.tp_value; \
+ __tls = &(t)->thread.uw.tp_value; \
__tls; \
})
#else
-#define task_user_tls(t) (&(t)->thread.tp_value)
+#define task_user_tls(t) (&(t)->thread.uw.tp_value)
#endif
/* Sync TPIDR_EL0 back to thread_struct for current */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index c4be311..7a8ac960b6 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -222,7 +222,7 @@ static void sve_user_enable(void)
* sets TIF_SVE.
*
* When stored, FPSIMD registers V0-V31 are encoded in
- * task->fpsimd_state; bits [max : 128] for each of Z0-Z31 are
+ * task->thread.uw.fpsimd_state; bits [max : 128] for each of Z0-Z31 are
* logically zero but not stored anywhere; P0-P15 and FFR are not
* stored and have unspecified values from userspace's point of
* view. For hygiene purposes, the kernel zeroes them on next use,
@@ -231,9 +231,9 @@ static void sve_user_enable(void)
* task->thread.sve_state does not need to be non-NULL, valid or any
* particular size: it must not be dereferenced.
*
- * * FPSR and FPCR are always stored in task->fpsimd_state irrespctive of
- * whether TIF_SVE is clear or set, since these are not vector length
- * dependent.
+ * * FPSR and FPCR are always stored in task->thread.uw.fpsimd_state
+ * irrespective of whether TIF_SVE is clear or set, since these are
+ * not vector length dependent.
*/
/*
@@ -251,10 +251,10 @@ static void task_fpsimd_load(void)
if (system_supports_sve() && test_thread_flag(TIF_SVE))
sve_load_state(sve_pffr(current),
- &current->thread.fpsimd_state.fpsr,
+ &current->thread.uw.fpsimd_state.fpsr,
sve_vq_from_vl(current->thread.sve_vl) - 1);
else
- fpsimd_load_state(&current->thread.fpsimd_state);
+ fpsimd_load_state(&current->thread.uw.fpsimd_state);
if (system_supports_sve()) {
/* Toggle SVE trapping for userspace if needed */
@@ -291,9 +291,9 @@ static void task_fpsimd_save(void)
}
sve_save_state(sve_pffr(current),
- &current->thread.fpsimd_state.fpsr);
+ &current->thread.uw.fpsimd_state.fpsr);
} else
- fpsimd_save_state(&current->thread.fpsimd_state);
+ fpsimd_save_state(&current->thread.uw.fpsimd_state);
}
}
@@ -404,20 +404,21 @@ static int __init sve_sysctl_init(void) { return 0; }
(SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET))
/*
- * Transfer the FPSIMD state in task->thread.fpsimd_state to
+ * Transfer the FPSIMD state in task->thread.uw.fpsimd_state to
* task->thread.sve_state.
*
* Task can be a non-runnable task, or current. In the latter case,
* softirqs (and preemption) must be disabled.
* task->thread.sve_state must point to at least sve_state_size(task)
* bytes of allocated kernel memory.
- * task->thread.fpsimd_state must be up to date before calling this function.
+ * task->thread.uw.fpsimd_state must be up to date before calling this
+ * function.
*/
static void fpsimd_to_sve(struct task_struct *task)
{
unsigned int vq;
void *sst = task->thread.sve_state;
- struct user_fpsimd_state const *fst = &task->thread.fpsimd_state;
+ struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;
unsigned int i;
if (!system_supports_sve())
@@ -431,7 +432,7 @@ static void fpsimd_to_sve(struct task_struct *task)
/*
* Transfer the SVE state in task->thread.sve_state to
- * task->thread.fpsimd_state.
+ * task->thread.uw.fpsimd_state.
*
* Task can be a non-runnable task, or current. In the latter case,
* softirqs (and preemption) must be disabled.
@@ -443,7 +444,7 @@ static void sve_to_fpsimd(struct task_struct *task)
{
unsigned int vq;
void const *sst = task->thread.sve_state;
- struct user_fpsimd_state *fst = &task->thread.fpsimd_state;
+ struct user_fpsimd_state *fst = &task->thread.uw.fpsimd_state;
unsigned int i;
if (!system_supports_sve())
@@ -510,7 +511,7 @@ void fpsimd_sync_to_sve(struct task_struct *task)
}
/*
- * Ensure that task->thread.fpsimd_state is up to date with respect to
+ * Ensure that task->thread.uw.fpsimd_state is up to date with respect to
* the user task, irrespective of whether SVE is in use or not.
*
* This should only be called by ptrace. task must be non-runnable.
@@ -525,21 +526,21 @@ void sve_sync_to_fpsimd(struct task_struct *task)
/*
* Ensure that task->thread.sve_state is up to date with respect to
- * the task->thread.fpsimd_state.
+ * the task->thread.uw.fpsimd_state.
*
* This should only be called by ptrace to merge new FPSIMD register
* values into a task for which SVE is currently active.
* task must be non-runnable.
* task->thread.sve_state must point to at least sve_state_size(task)
* bytes of allocated kernel memory.
- * task->thread.fpsimd_state must already have been initialised with
+ * task->thread.uw.fpsimd_state must already have been initialised with
* the new FPSIMD register values to be merged in.
*/
void sve_sync_from_fpsimd_zeropad(struct task_struct *task)
{
unsigned int vq;
void *sst = task->thread.sve_state;
- struct user_fpsimd_state const *fst = &task->thread.fpsimd_state;
+ struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;
unsigned int i;
if (!test_tsk_thread_flag(task, TIF_SVE))
@@ -909,7 +910,7 @@ void fpsimd_thread_switch(struct task_struct *next)
* upon the next return to userland.
*/
if (__this_cpu_read(fpsimd_last_state.st) ==
- &next->thread.fpsimd_state
+ &next->thread.uw.fpsimd_state
&& next->thread.fpsimd_cpu == smp_processor_id())
clear_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE);
else
@@ -926,8 +927,8 @@ void fpsimd_flush_thread(void)
local_bh_disable();
- memset(&current->thread.fpsimd_state, 0,
- sizeof current->thread.fpsimd_state);
+ memset(&current->thread.uw.fpsimd_state, 0,
+ sizeof current->thread.uw.fpsimd_state);
fpsimd_flush_task_state(current);
if (system_supports_sve()) {
@@ -986,7 +987,7 @@ void fpsimd_preserve_current_state(void)
/*
* Like fpsimd_preserve_current_state(), but ensure that
- * current->thread.fpsimd_state is updated so that it can be copied to
+ * current->thread.uw.fpsimd_state is updated so that it can be copied to
* the signal frame.
*/
void fpsimd_signal_preserve_current_state(void)
@@ -1005,7 +1006,7 @@ static void fpsimd_bind_to_cpu(void)
struct fpsimd_last_state_struct *last =
this_cpu_ptr(&fpsimd_last_state);
- last->st = &current->thread.fpsimd_state;
+ last->st = &current->thread.uw.fpsimd_state;
last->sve_in_use = test_thread_flag(TIF_SVE);
current->thread.fpsimd_cpu = smp_processor_id();
}
@@ -1042,7 +1043,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
local_bh_disable();
- current->thread.fpsimd_state = *state;
+ current->thread.uw.fpsimd_state = *state;
if (system_supports_sve() && test_thread_flag(TIF_SVE))
fpsimd_to_sve(current);
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index c0da6ef..f08a2ed 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -257,7 +257,7 @@ static void tls_thread_flush(void)
write_sysreg(0, tpidr_el0);
if (is_compat_task()) {
- current->thread.tp_value = 0;
+ current->thread.uw.tp_value = 0;
/*
* We need to ensure ordering between the shadow state and the
@@ -351,7 +351,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
* for the new thread.
*/
if (clone_flags & CLONE_SETTLS)
- p->thread.tp_value = childregs->regs[3];
+ p->thread.uw.tp_value = childregs->regs[3];
} else {
memset(childregs, 0, sizeof(struct pt_regs));
childregs->pstate = PSR_MODE_EL1h;
@@ -379,7 +379,7 @@ static void tls_thread_switch(struct task_struct *next)
tls_preserve_current_state();
if (is_compat_thread(task_thread_info(next)))
- write_sysreg(next->thread.tp_value, tpidrro_el0);
+ write_sysreg(next->thread.uw.tp_value, tpidrro_el0);
else if (!arm64_kernel_unmapped_at_el0())
write_sysreg(0, tpidrro_el0);
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index fdeaba0de..436a132 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -629,7 +629,7 @@ static int __fpr_get(struct task_struct *target,
sve_sync_to_fpsimd(target);
- uregs = &target->thread.fpsimd_state;
+ uregs = &target->thread.uw.fpsimd_state;
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs,
start_pos, start_pos + sizeof(*uregs));
@@ -655,19 +655,19 @@ static int __fpr_set(struct task_struct *target,
struct user_fpsimd_state newstate;
/*
- * Ensure target->thread.fpsimd_state is up to date, so that a
+ * Ensure target->thread.uw.fpsimd_state is up to date, so that a
* short copyin can't resurrect stale data.
*/
sve_sync_to_fpsimd(target);
- newstate = target->thread.fpsimd_state;
+ newstate = target->thread.uw.fpsimd_state;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate,
start_pos, start_pos + sizeof(newstate));
if (ret)
return ret;
- target->thread.fpsimd_state = newstate;
+ target->thread.uw.fpsimd_state = newstate;
return ret;
}
@@ -692,7 +692,7 @@ static int tls_get(struct task_struct *target, const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
- unsigned long *tls = &target->thread.tp_value;
+ unsigned long *tls = &target->thread.uw.tp_value;
if (target == current)
tls_preserve_current_state();
@@ -705,13 +705,13 @@ static int tls_set(struct task_struct *target, const struct user_regset *regset,
const void *kbuf, const void __user *ubuf)
{
int ret;
- unsigned long tls = target->thread.tp_value;
+ unsigned long tls = target->thread.uw.tp_value;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
if (ret)
return ret;
- target->thread.tp_value = tls;
+ target->thread.uw.tp_value = tls;
return ret;
}
@@ -842,7 +842,7 @@ static int sve_get(struct task_struct *target,
start = end;
end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpsimd_state.fpsr,
+ &target->thread.uw.fpsimd_state.fpsr,
start, end);
if (ret)
return ret;
@@ -941,7 +941,7 @@ static int sve_set(struct task_struct *target,
start = end;
end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpsimd_state.fpsr,
+ &target->thread.uw.fpsimd_state.fpsr,
start, end);
out:
@@ -1169,7 +1169,7 @@ static int compat_vfp_get(struct task_struct *target,
compat_ulong_t fpscr;
int ret, vregs_end_pos;
- uregs = &target->thread.fpsimd_state;
+ uregs = &target->thread.uw.fpsimd_state;
if (target == current)
fpsimd_preserve_current_state();
@@ -1202,7 +1202,7 @@ static int compat_vfp_set(struct task_struct *target,
compat_ulong_t fpscr;
int ret, vregs_end_pos;
- uregs = &target->thread.fpsimd_state;
+ uregs = &target->thread.uw.fpsimd_state;
vregs_end_pos = VFP_STATE_SIZE - sizeof(compat_ulong_t);
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0,
@@ -1225,7 +1225,7 @@ static int compat_tls_get(struct task_struct *target,
const struct user_regset *regset, unsigned int pos,
unsigned int count, void *kbuf, void __user *ubuf)
{
- compat_ulong_t tls = (compat_ulong_t)target->thread.tp_value;
+ compat_ulong_t tls = (compat_ulong_t)target->thread.uw.tp_value;
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
}
@@ -1235,13 +1235,13 @@ static int compat_tls_set(struct task_struct *target,
const void __user *ubuf)
{
int ret;
- compat_ulong_t tls = target->thread.tp_value;
+ compat_ulong_t tls = target->thread.uw.tp_value;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
if (ret)
return ret;
- target->thread.tp_value = tls;
+ target->thread.uw.tp_value = tls;
return ret;
}
@@ -1538,7 +1538,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
break;
case COMPAT_PTRACE_GET_THREAD_AREA:
- ret = put_user((compat_ulong_t)child->thread.tp_value,
+ ret = put_user((compat_ulong_t)child->thread.uw.tp_value,
(compat_ulong_t __user *)datap);
break;
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index d026615..a0c4138 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -178,7 +178,8 @@ static void __user *apply_user_offset(
static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
{
- struct user_fpsimd_state const *fpsimd = &current->thread.fpsimd_state;
+ struct user_fpsimd_state const *fpsimd =
+ &current->thread.uw.fpsimd_state;
int err;
/* copy the FP and status/control registers */
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 4ea38d3..884177a 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -148,7 +148,8 @@ union __fpsimd_vreg {
static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame)
{
- struct user_fpsimd_state const *fpsimd = &current->thread.fpsimd_state;
+ struct user_fpsimd_state const *fpsimd =
+ &current->thread.uw.fpsimd_state;
compat_ulong_t magic = VFP_MAGIC;
compat_ulong_t size = VFP_STORAGE_SIZE;
compat_ulong_t fpscr, fpexc;
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index a382b2a..9155989 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -88,7 +88,7 @@ long compat_arm_syscall(struct pt_regs *regs)
return do_compat_cache_op(regs->regs[0], regs->regs[1], regs->regs[2]);
case __ARM_NR_compat_set_tls:
- current->thread.tp_value = regs->regs[0];
+ current->thread.uw.tp_value = regs->regs[0];
/*
* Protect against register corruption from context switch.

View File

@ -0,0 +1,116 @@
From patchwork Wed Apr 18 16:34:15 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: arm64: msm8916: fix gic_irq_domain_translate warnings
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
X-Patchwork-Id: 10348701
Message-Id: <20180418163415.21646-1-srinivas.kandagatla@linaro.org>
To: andy.gross@linaro.org, linux-arm-msm@vger.kernel.org
Cc: david.brown@linaro.org, robh+dt@kernel.org,
linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Wed, 18 Apr 2018 17:34:15 +0100
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Remove the usage of IRQ_TYPE_NONE to fix loud warnings from
patch (83a86fbb5b56b "irqchip/gic: Loudly complain about
the use of IRQ_TYPE_NONE").
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Reviewed-by: Thierry Escande <thierry.escande@linaro.org>
Tested-by: Thierry Escande <thierry.escande@linaro.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
Tested-by: Amit Kucheria <amit.kucheria@linaro.org>
Tested-by: Vinod Koul <vkoul@kernel.org>
---
arch/arm64/boot/dts/qcom/msm8916.dtsi | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index cfbd72186762..5d66a575c7e1 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -180,7 +180,7 @@
pmu {
compatible = "arm,cortex-a53-pmu";
- interrupts = <GIC_PPI 7 GIC_CPU_MASK_SIMPLE(4)>;
+ interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4)| IRQ_TYPE_LEVEL_HIGH)>;
};
thermal-zones {
@@ -513,7 +513,7 @@
blsp_i2c2: i2c@78b6000 {
compatible = "qcom,i2c-qup-v2.2.1";
reg = <0x078b6000 0x500>;
- interrupts = <GIC_SPI 96 0>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP1_AHB_CLK>,
<&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
clock-names = "iface", "core";
@@ -528,7 +528,7 @@
blsp_i2c4: i2c@78b8000 {
compatible = "qcom,i2c-qup-v2.2.1";
reg = <0x078b8000 0x500>;
- interrupts = <GIC_SPI 98 0>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP1_AHB_CLK>,
<&gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>;
clock-names = "iface", "core";
@@ -543,7 +543,7 @@
blsp_i2c6: i2c@78ba000 {
compatible = "qcom,i2c-qup-v2.2.1";
reg = <0x078ba000 0x500>;
- interrupts = <GIC_SPI 100 0>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP1_AHB_CLK>,
<&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>;
clock-names = "iface", "core";
@@ -575,7 +575,7 @@
"mi2s-bit-clk3";
#sound-dai-cells = <1>;
- interrupts = <0 160 0>;
+ interrupts = <0 160 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "lpass-irq-lpaif";
reg = <0x07708000 0x10000>;
reg-names = "lpass-lpaif";
@@ -595,7 +595,7 @@
reg = <0x07824900 0x11c>, <0x07824000 0x800>;
reg-names = "hc_mem", "core_mem";
- interrupts = <0 123 0>, <0 138 0>;
+ interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>, <0 138 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hc_irq", "pwr_irq";
clocks = <&gcc GCC_SDCC1_APPS_CLK>,
<&gcc GCC_SDCC1_AHB_CLK>,
@@ -612,7 +612,7 @@
reg = <0x07864900 0x11c>, <0x07864000 0x800>;
reg-names = "hc_mem", "core_mem";
- interrupts = <0 125 0>, <0 221 0>;
+ interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>, <0 221 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hc_irq", "pwr_irq";
clocks = <&gcc GCC_SDCC2_APPS_CLK>,
<&gcc GCC_SDCC2_AHB_CLK>,
@@ -819,7 +819,7 @@
iommu-ctx@2000 {
compatible = "qcom,msm-iommu-v1-ns";
reg = <0x2000 0x1000>;
- interrupts = <GIC_SPI 242 0>;
+ interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
};
};
@@ -864,7 +864,7 @@
"bus_clk",
"vsync_clk";
- interrupts = <0 72 0>;
+ interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;

View File

@ -1,529 +0,0 @@
From 08af112e79cab22f318ca0ad1a48187eee5ac2f0 Mon Sep 17 00:00:00 2001
From: Baruch Siach <baruch@tkos.co.il>
Date: Tue, 20 Feb 2018 14:19:31 +0200
Subject: soc: bcm2835: sync firmware properties with downstream
Add latest firmware property tags from the latest Raspberry Pi downstream
kernel. This is needed for the GPIO tags, so we can control the GPIO
multiplexor lines.
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
include/soc/bcm2835/raspberrypi-firmware.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index cb979ad..50df5b2 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -63,6 +63,7 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008,
RPI_FIRMWARE_GET_TURBO = 0x00030009,
RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a,
+ RPI_FIRMWARE_GET_STC = 0x0003000b,
RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c,
RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d,
RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e,
@@ -72,12 +73,22 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012,
RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014,
RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020,
+ RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021,
RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030,
RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001,
RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002,
RPI_FIRMWARE_SET_VOLTAGE = 0x00038003,
RPI_FIRMWARE_SET_TURBO = 0x00038009,
+ RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021,
RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030,
+ RPI_FIRMWARE_GET_GPIO_STATE = 0x00030041,
+ RPI_FIRMWARE_SET_GPIO_STATE = 0x00038041,
+ RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042,
+ RPI_FIRMWARE_GET_GPIO_CONFIG = 0x00030043,
+ RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043,
+ RPI_FIRMWARE_GET_PERIPH_REG = 0x00030045,
+ RPI_FIRMWARE_SET_PERIPH_REG = 0x00038045,
+
/* Dispmanx TAGS */
RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,
@@ -91,6 +102,8 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009,
RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a,
RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b,
+ RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f,
+ RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010,
RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001,
RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004,
@@ -100,6 +113,7 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009,
RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a,
RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b,
+ RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e,
RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003,
RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004,
RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005,
@@ -108,6 +122,10 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009,
RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a,
RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e,
+ RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f,
RPI_FIRMWARE_VCHIQ_INIT = 0x00048010,
--
cgit v1.1
From 9777d8099a4a9df1625b4caaee1388c0158478c5 Mon Sep 17 00:00:00 2001
From: Baruch Siach <baruch@tkos.co.il>
Date: Tue, 20 Feb 2018 14:19:32 +0200
Subject: dt-bindings: gpio: add raspberry pi GPIO expander binding
The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware over
I2C. The firmware mailbox interface allows the ARM core to control the
GPIO lines.
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
.../bindings/gpio/raspberrypi,firmware-gpio.txt | 30 ++++++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
diff --git a/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
new file mode 100644
index 0000000..ce97265
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
@@ -0,0 +1,30 @@
+Raspberry Pi GPIO expander
+
+The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware. The
+firmware exposes a mailbox interface that allows the ARM core to control the
+GPIO lines on the expander.
+
+The Raspberry Pi GPIO expander node must be a child node of the Raspberry Pi
+firmware node.
+
+Required properties:
+
+- compatible : Should be "raspberrypi,firmware-gpio"
+- gpio-controller : Marks the device node as a gpio controller
+- #gpio-cells : Should be two. The first cell is the pin number, and
+ the second cell is used to specify the gpio polarity:
+ 0 = active high
+ 1 = active low
+
+Example:
+
+firmware: firmware-rpi {
+ compatible = "raspberrypi,bcm2835-firmware";
+ mboxes = <&mailbox>;
+
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+};
--
cgit v1.1
From a98d90e7d588045716c3c85d63f93dc3f15a079b Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
Date: Tue, 20 Feb 2018 14:19:33 +0200
Subject: gpio: raspberrypi-exp: Driver for RPi3 GPIO expander via mailbox
service
Pi3 and Compute Module 3 have a GPIO expander that the
VPU communicates with.
There is a mailbox service that now allows control of this
expander, so add a kernel driver that can make use of it.
Reviewed-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/gpio/Kconfig | 9 ++
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-raspberrypi-exp.c | 252 ++++++++++++++++++++++++++++++++++++
3 files changed, 262 insertions(+)
create mode 100644 drivers/gpio/gpio-raspberrypi-exp.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8dbb228..fd0562a 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -122,6 +122,15 @@ config GPIO_ATH79
Select this option to enable GPIO driver for
Atheros AR71XX/AR724X/AR913X SoC devices.
+config GPIO_RASPBERRYPI_EXP
+ tristate "Raspberry Pi 3 GPIO Expander"
+ default RASPBERRYPI_FIRMWARE
+ depends on OF_GPIO
+ depends on (ARCH_BCM2835 && RASPBERRYPI_FIRMWARE) || COMPILE_TEST
+ help
+ Turn on GPIO support for the expander on Raspberry Pi 3 boards, using
+ the firmware mailbox to communicate with VideoCore on BCM283x chips.
+
config GPIO_BCM_KONA
bool "Broadcom Kona GPIO"
depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index cccb0d4..76dc0a0 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
+obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o
obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
new file mode 100644
index 0000000..d6d36d5
--- /dev/null
+++ b/drivers/gpio/gpio-raspberrypi-exp.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Raspberry Pi 3 expander GPIO driver
+ *
+ * Uses the firmware mailbox service to communicate with the
+ * GPIO expander on the VPU.
+ *
+ * Copyright (C) 2017 Raspberry Pi Trading Ltd.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+#define MODULE_NAME "raspberrypi-exp-gpio"
+#define NUM_GPIO 8
+
+#define RPI_EXP_GPIO_BASE 128
+
+#define RPI_EXP_GPIO_DIR_IN 0
+#define RPI_EXP_GPIO_DIR_OUT 1
+
+struct rpi_exp_gpio {
+ struct gpio_chip gc;
+ struct rpi_firmware *fw;
+};
+
+/* VC4 firmware mailbox interface data structures */
+
+struct gpio_set_config {
+ u32 gpio;
+ u32 direction;
+ u32 polarity;
+ u32 term_en;
+ u32 term_pull_up;
+ u32 state;
+};
+
+struct gpio_get_config {
+ u32 gpio;
+ u32 direction;
+ u32 polarity;
+ u32 term_en;
+ u32 term_pull_up;
+};
+
+struct gpio_get_set_state {
+ u32 gpio;
+ u32 state;
+};
+
+static int rpi_exp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_get_config get;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
+ &get, sizeof(get));
+ if (ret || get.gpio != 0) {
+ dev_err(gc->parent, "Failed to get GPIO %u config (%d %x)\n",
+ off, ret, get.gpio);
+ return ret ? ret : -EIO;
+ }
+ return get.polarity;
+}
+
+static int rpi_exp_gpio_dir_in(struct gpio_chip *gc, unsigned int off)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_set_config set_in;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ set_in.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+ set_in.direction = RPI_EXP_GPIO_DIR_IN;
+ set_in.term_en = 0; /* termination disabled */
+ set_in.term_pull_up = 0; /* n/a as termination disabled */
+ set_in.state = 0; /* n/a as configured as an input */
+
+ ret = rpi_exp_gpio_get_polarity(gc, off);
+ if (ret < 0)
+ return ret;
+ set_in.polarity = ret; /* Retain existing setting */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
+ &set_in, sizeof(set_in));
+ if (ret || set_in.gpio != 0) {
+ dev_err(gc->parent, "Failed to set GPIO %u to input (%d %x)\n",
+ off, ret, set_in.gpio);
+ return ret ? ret : -EIO;
+ }
+ return 0;
+}
+
+static int rpi_exp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_set_config set_out;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ set_out.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+ set_out.direction = RPI_EXP_GPIO_DIR_OUT;
+ set_out.term_en = 0; /* n/a as an output */
+ set_out.term_pull_up = 0; /* n/a as termination disabled */
+ set_out.state = val; /* Output state */
+
+ ret = rpi_exp_gpio_get_polarity(gc, off);
+ if (ret < 0)
+ return ret;
+ set_out.polarity = ret; /* Retain existing setting */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
+ &set_out, sizeof(set_out));
+ if (ret || set_out.gpio != 0) {
+ dev_err(gc->parent, "Failed to set GPIO %u to output (%d %x)\n",
+ off, ret, set_out.gpio);
+ return ret ? ret : -EIO;
+ }
+ return 0;
+}
+
+static int rpi_exp_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_get_config get;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
+ &get, sizeof(get));
+ if (ret || get.gpio != 0) {
+ dev_err(gc->parent,
+ "Failed to get GPIO %u config (%d %x)\n", off, ret,
+ get.gpio);
+ return ret ? ret : -EIO;
+ }
+ return !get.direction;
+}
+
+static int rpi_exp_gpio_get(struct gpio_chip *gc, unsigned int off)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_get_set_state get;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ get.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+ get.state = 0; /* storage for returned value */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE,
+ &get, sizeof(get));
+ if (ret || get.gpio != 0) {
+ dev_err(gc->parent,
+ "Failed to get GPIO %u state (%d %x)\n", off, ret,
+ get.gpio);
+ return ret ? ret : -EIO;
+ }
+ return !!get.state;
+}
+
+static void rpi_exp_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
+{
+ struct rpi_exp_gpio *gpio;
+ struct gpio_get_set_state set;
+ int ret;
+
+ gpio = gpiochip_get_data(gc);
+
+ set.gpio = off + RPI_EXP_GPIO_BASE; /* GPIO to update */
+ set.state = val; /* Output state */
+
+ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE,
+ &set, sizeof(set));
+ if (ret || set.gpio != 0)
+ dev_err(gc->parent,
+ "Failed to set GPIO %u state (%d %x)\n", off, ret,
+ set.gpio);
+}
+
+static int rpi_exp_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *fw_node;
+ struct rpi_firmware *fw;
+ struct rpi_exp_gpio *rpi_gpio;
+
+ fw_node = of_get_parent(np);
+ if (!fw_node) {
+ dev_err(dev, "Missing firmware node\n");
+ return -ENOENT;
+ }
+
+ fw = rpi_firmware_get(fw_node);
+ if (!fw)
+ return -EPROBE_DEFER;
+
+ rpi_gpio = devm_kzalloc(dev, sizeof(*rpi_gpio), GFP_KERNEL);
+ if (!rpi_gpio)
+ return -ENOMEM;
+
+ rpi_gpio->fw = fw;
+ rpi_gpio->gc.parent = dev;
+ rpi_gpio->gc.label = MODULE_NAME;
+ rpi_gpio->gc.owner = THIS_MODULE;
+ rpi_gpio->gc.of_node = np;
+ rpi_gpio->gc.base = -1;
+ rpi_gpio->gc.ngpio = NUM_GPIO;
+
+ rpi_gpio->gc.direction_input = rpi_exp_gpio_dir_in;
+ rpi_gpio->gc.direction_output = rpi_exp_gpio_dir_out;
+ rpi_gpio->gc.get_direction = rpi_exp_gpio_get_direction;
+ rpi_gpio->gc.get = rpi_exp_gpio_get;
+ rpi_gpio->gc.set = rpi_exp_gpio_set;
+ rpi_gpio->gc.can_sleep = true;
+
+ return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
+}
+
+static const struct of_device_id rpi_exp_gpio_ids[] = {
+ { .compatible = "raspberrypi,firmware-gpio" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, rpi_exp_gpio_ids);
+
+static struct platform_driver rpi_exp_gpio_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .of_match_table = of_match_ptr(rpi_exp_gpio_ids),
+ },
+ .probe = rpi_exp_gpio_probe,
+};
+module_platform_driver(rpi_exp_gpio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.org>");
+MODULE_DESCRIPTION("Raspberry Pi 3 expander GPIO driver");
+MODULE_ALIAS("platform:rpi-exp-gpio");
--
cgit v1.1
From b0c07c5af6d286f3d3b907743998e9d41f6ab042 Mon Sep 17 00:00:00 2001
From: Baruch Siach <baruch@tkos.co.il>
Date: Tue, 20 Feb 2018 14:19:34 +0200
Subject: ARM: dts: bcm2835: make the firmware node into a bus
This allows adding devices for which the firmware exposes control interface
via the mailbox. An example of such device is the GPIO expander.
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Eric Anholt <eric@anholt.net>
---
arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index e36c392..0198bd4 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -18,7 +18,9 @@
soc {
firmware: firmware {
- compatible = "raspberrypi,bcm2835-firmware";
+ compatible = "raspberrypi,bcm2835-firmware", "simple-bus";
+ #address-cells = <0>;
+ #size-cells = <0>;
mboxes = <&mailbox>;
};
--
cgit v1.1
From 4d5b2eaf3ca80c56a59f230208c4ff11e3f68d55 Mon Sep 17 00:00:00 2001
From: Baruch Siach <baruch@tkos.co.il>
Date: Tue, 20 Feb 2018 14:19:35 +0200
Subject: ARM: dts: bcm2837-rpi-3-b: add GPIO expander
Add a description of the RPi3 GPIO expander that the VC4 firmware controls.
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Eric Anholt <eric@anholt.net>
---
arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
index 3e4ed7c..0b31d99 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
@@ -25,6 +25,23 @@
};
};
+&firmware {
+ expgpio: gpio {
+ compatible = "raspberrypi,firmware-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "BT_ON",
+ "WL_ON",
+ "STATUS_LED",
+ "LAN_RUN",
+ "HPD_N",
+ "CAM_GPIO0",
+ "CAM_GPIO1",
+ "PWR_LOW_N";
+ status = "okay";
+ };
+};
+
/* uart0 communicates with the BT module */
&uart0 {
pinctrl-names = "default";
--
cgit v1.1

View File

@ -1,77 +1,3 @@
From 502356f8db439d77a41958041feec187c42f72bb Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 11 Apr 2018 12:02:47 +0100
Subject: [PATCH 3/9] lan78xx: Avoid spurious kevent 4 "error"
lan78xx_defer_event generates an error message whenever the work item
is already scheduled. lan78xx_open defers three events -
EVENT_STAT_UPDATE, EVENT_DEV_OPEN and EVENT_LINK_RESET. Being aware
of the likelihood (or certainty) of an error message, the DEV_OPEN
event is added to the set of pending events directly, relying on
the subsequent deferral of the EVENT_LINK_RESET call to schedule the
work. Take the same precaution with EVENT_STAT_UPDATE to avoid a
totally unnecessary error message.
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/usb/lan78xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 145bb7cbf5b2..bdb696612e11 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -2503,7 +2503,7 @@ static void lan78xx_init_stats(struct lan78xx_net *dev)
dev->stats.rollover_max.eee_tx_lpi_transitions = 0xFFFFFFFF;
dev->stats.rollover_max.eee_tx_lpi_time = 0xFFFFFFFF;
- lan78xx_defer_kevent(dev, EVENT_STAT_UPDATE);
+ set_bit(EVENT_STAT_UPDATE, &dev->flags);
}
static int lan78xx_open(struct net_device *net)
--
2.17.0
From d9332c56373a8c43bc4761267ba3a246082e2270 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 10 Apr 2018 13:18:25 +0100
Subject: [PATCH 4/9] lan78xx: Don't reset the interface on open
Commit 92571a1aae40 ("lan78xx: Connect phy early") moves the PHY
initialisation into lan78xx_probe, but lan78xx_open subsequently calls
lan78xx_reset. As well as forcing a second round of link negotiation,
this reset frequently prevents the phy interrupt from being generated
(even though the link is up), rendering the interface unusable.
Fix this issue by removing the lan78xx_reset call from lan78xx_open.
Fixes: 92571a1aae40 ("lan78xx: Connect phy early")
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/usb/lan78xx.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index bdb696612e11..0867f7275852 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -2515,10 +2515,6 @@ static int lan78xx_open(struct net_device *net)
if (ret < 0)
goto out;
- ret = lan78xx_reset(dev);
- if (ret < 0)
- goto done;
-
phy_start(net->phydev);
netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
--
2.17.0
From bce4fe9fa48df0cbbe842e80d9a520f7265b4cd4 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
Date: Wed, 4 Apr 2018 16:34:24 +0100
@ -524,4 +450,3 @@ index 8f9c90379732..fd1fc8c248ef 100644
#endif /* _MICROCHIPPHY_H */
--
2.17.0

View File

@ -1,74 +0,0 @@
From patchwork Fri Feb 16 10:55:33 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [V3, 1/2,
RESEND] dt-bindings: bcm283x: Fix register ranges of bcm2835-i2s
From: Stefan Wahren <stefan.wahren@i2se.com>
X-Patchwork-Id: 10224429
Message-Id: <1518778534-3328-2-git-send-email-stefan.wahren@i2se.com>
To: Rob Herring <robh+dt@kernel.org>, Mark Rutland <mark.rutland@arm.com>,
Eric Anholt <eric@anholt.net>
Cc: Stefan Wahren <stefan.wahren@i2se.com>, devicetree@vger.kernel.org,
alsa-devel@alsa-project.org, Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>, linux-rpi-kernel@lists.infradead.org,
linux-arm-kernel@lists.infradead.org
Date: Fri, 16 Feb 2018 11:55:33 +0100
Since 517e7a1537a ("ASoC: bcm2835: move to use the clock framework")
the bcm2835-i2s requires a clock as DT property. Unfortunately
the necessary DT change has never been applied. While we are at it
also fix the first PCM register range to cover the PCM_GRAY register.
This patch only fixes the affected dt-bindings.
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt | 4 ++--
Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt | 9 ++++-----
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
index baf9b34..b6a8cc0 100644
--- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
+++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
@@ -74,8 +74,8 @@ Example:
bcm2835_i2s: i2s@7e203000 {
compatible = "brcm,bcm2835-i2s";
- reg = < 0x7e203000 0x20>,
- < 0x7e101098 0x02>;
+ reg = < 0x7e203000 0x24>;
+ clocks = <&clocks BCM2835_CLOCK_PCM>;
dmas = <&dma 2>,
<&dma 3>;
diff --git a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt
index 65783de..7bb0362 100644
--- a/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/brcm,bcm2835-i2s.txt
@@ -2,9 +2,8 @@
Required properties:
- compatible: "brcm,bcm2835-i2s"
-- reg: A list of base address and size entries:
- * The first entry should cover the PCM registers
- * The second entry should cover the PCM clock registers
+- reg: Should contain PCM registers location and length.
+- clocks: the (PCM) clock to use
- dmas: List of DMA controller phandle and DMA request line ordered pairs.
- dma-names: Identifier string for each DMA request line in the dmas property.
These strings correspond 1:1 with the ordered pairs in dmas.
@@ -16,8 +15,8 @@ Example:
bcm2835_i2s: i2s@7e203000 {
compatible = "brcm,bcm2835-i2s";
- reg = <0x7e203000 0x20>,
- <0x7e101098 0x02>;
+ reg = <0x7e203000 0x24>;
+ clocks = <&clocks BCM2835_CLOCK_PCM>;
dmas = <&dma 2>,
<&dma 3>;

View File

@ -1,127 +0,0 @@
From patchwork Thu Aug 3 15:52:08 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v3] dma-mapping: skip USB devices when configuring DMA during probe
From: Johan Hovold <johan@kernel.org>
X-Patchwork-Id: 9879371
Message-Id: <20170803155208.22165-1-johan@kernel.org>
To: Christoph Hellwig <hch@lst.de>,
Marek Szyprowski <m.szyprowski@samsung.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: =?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber@suse.de>,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
Alan Stern <stern@rowland.harvard.edu>, Johan Hovold <johan@kernel.org>,
stable <stable@vger.kernel.org>, Robin Murphy <robin.murphy@arm.com>,
Sricharan R <sricharan@codeaurora.org>,
Stefan Wahren <stefan.wahren@i2se.com>
Date: Thu, 3 Aug 2017 17:52:08 +0200
USB devices use the DMA mask and offset of the controller, which have
already been setup when a device is probed. Note that modifying the
DMA mask of a USB device would change the mask for the controller (and
all devices on the bus) as the mask is literally shared.
Since commit 2bf698671205 ("USB: of: fix root-hub device-tree node
handling"), of_dma_configure() would be called also for root hubs, which
use the device node of the controller. A separate, long-standing bug
that makes of_dma_configure() generate a 30-bit DMA mask from the RPI3's
"dma-ranges" would thus set a broken mask also for the controller. This
in turn prevents USB devices from enumerating when control transfers
fail:
dwc2 3f980000.usb: Cannot do DMA to address 0x000000003a166a00
Note that the aforementioned DMA-mask bug was benign for the HCD itself
as the dwc2 driver overwrites the mask previously set by
of_dma_configure() for the platform device in its probe callback. The
mask would only later get corrupted when the root-hub child device was
probed.
Fix this, and similar future problems, by adding a flag to struct device
which prevents driver core from calling dma_configure() during probe and
making sure it is set for USB devices.
Fixes: 09515ef5ddad ("of/acpi: Configure dma operations at probe time for platform/amba/pci bus devices")
Cc: stable <stable@vger.kernel.org> # 4.12
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Sricharan R <sricharan@codeaurora.org>
Cc: Stefan Wahren <stefan.wahren@i2se.com>
Reported-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
v3
- add flag to struct device to prevent DMA configuration during probe instead
of checking for the USB bus type, which is not available when USB is built
as a module as noted by Alan
- drop moderated rpi list from CC
v2
- amend commit message and point out that the long-standing 30-bit DMA-mask
bug was benign to the dwc2 HCD itself (Robin)
- add and use a new dev_is_usb() helper (Robin)
drivers/base/dma-mapping.c | 6 ++++++
drivers/usb/core/usb.c | 1 +
include/linux/device.h | 3 +++
3 files changed, 10 insertions(+)
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index b555ff9dd8fc..f9f703be0ad1 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -345,6 +345,9 @@ int dma_configure(struct device *dev)
enum dev_dma_attr attr;
int ret = 0;
+ if (dev->skip_dma_configure)
+ return 0;
+
if (dev_is_pci(dev)) {
bridge = pci_get_host_bridge_device(to_pci_dev(dev));
dma_dev = bridge;
@@ -369,6 +372,9 @@ int dma_configure(struct device *dev)
void dma_deconfigure(struct device *dev)
{
+ if (dev->skip_dma_configure)
+ return;
+
of_dma_deconfigure(dev);
acpi_dma_deconfigure(dev);
}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 17681d5638ac..2a85d905b539 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -588,6 +588,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
* Note: calling dma_set_mask() on a USB device would set the
* mask for the entire HCD, so don't do that.
*/
+ dev->dev.skip_dma_configure = true;
dev->dev.dma_mask = bus->sysdev->dma_mask;
dev->dev.dma_pfn_offset = bus->sysdev->dma_pfn_offset;
set_dev_node(&dev->dev, dev_to_node(bus->sysdev));
diff --git a/include/linux/device.h b/include/linux/device.h
index 723cd54b94da..022cf258068b 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -877,6 +877,8 @@ struct dev_links_info {
* @offline: Set after successful invocation of bus type's .offline().
* @of_node_reused: Set if the device-tree node is shared with an ancestor
* device.
+ * @skip_dma_configure: Set if driver core should not configure DMA for this
+ * device during probe.
*
* At the lowest level, every device in a Linux system is represented by an
* instance of struct device. The device structure contains the information
@@ -965,6 +967,7 @@ struct device {
bool offline_disabled:1;
bool offline:1;
bool of_node_reused:1;
+ bool skip_dma_configure:1;
};
static inline struct device *kobj_to_dev(struct kobject *kobj)

View File

@ -1,89 +0,0 @@
#!/bin/bash
#
# This script merges together the hierarchy of CONFIG_* files under generic
# and debug to form the necessary $PACKAGE_NAME<version>-<arch>-<variant>.config
# files for building RHEL kernels, based on the contents of a control file
PACKAGE_NAME=kernel # defines the package name used
set errexit
set nounset
control_file="config_generation"
function combine_config_layer()
{
dir=$1
file="config-$(echo $dir | sed -e 's|/|-|g')"
if [ $(ls $dir/ | grep -c "^CONFIG_") -eq 0 ]; then
touch $file
return
fi
cat $dir/CONFIG_* > $file
}
function merge_configs()
{
archvar=$1
arch=$(echo "$archvar" | cut -f1 -d"-")
configs=$2
name=$PACKAGE_NAME-$archvar.config
echo -n "Building $name ... "
touch config-merging config-merged
for config in $(echo $configs | sed -e 's/:/ /g')
do
perl merge.pl config-$config config-merging > config-merged
if [ ! $? -eq 0 ]; then
exit
fi
mv config-merged config-merging
done
if [ "x$arch" == "xaarch64" ]; then
echo "# arm64" > $name
elif [ "x$arch" == "xppc64" ]; then
echo "# powerpc" > $name
elif [ "x$arch" == "xppc64le" ]; then
echo "# powerpc" > $name
elif [ "x$arch" == "xs390x" ]; then
echo "# s390" > $name
elif [ "x$arch" == "xarmv7hl" ]; then
echo "# arm" > $name
elif [ "x$arch" == "xi686" ]; then
echo "# i386" > $name
else
echo "# $arch" > $name
fi
sort config-merging >> $name
rm -f config-merged config-merging
echo "done"
}
glist=$(find baseconfig -type d)
dlist=$(find debugconfig -type d)
for d in $glist $dlist
do
combine_config_layer $d
done
while read line
do
if [ $(echo "$line" | grep -c "^#") -ne 0 ]; then
continue
elif [ $(echo "$line" | grep -c "^$") -ne 0 ]; then
continue
else
arch=$(echo "$line" | cut -f1 -d"=")
configs=$(echo "$line" | cut -f2 -d"=")
if [ -n "$SUBARCH" -a "$SUBARCH" != "$arch" ]; then
continue
fi
merge_configs $arch $configs
fi
done < $control_file
rm -f config-*

1
build_configs.sh Symbolic link
View File

@ -0,0 +1 @@
configs/build_configs.sh

View File

@ -1,36 +0,0 @@
# config-variant=config:config:config
# kernel.config files are build on the fly based on this config,
# the first arg is arch and variant, the second is a hierarchy of
# config options, lowest priority to highest
# x86_64
x86_64=baseconfig:baseconfig-x86:baseconfig-x86-x86_64
x86_64-debug=baseconfig:baseconfig-x86:baseconfig-x86-x86_64:debugconfig:debugconfig-x86:debugconfig-x86-x86_64
# i686
i686=baseconfig:baseconfig-x86:baseconfig-x86-i686
i686-debug=baseconfig:baseconfig-x86:baseconfig-x86-i686:debugconfig:debugconfig-x86
i686-PAE=baseconfig:baseconfig-x86:baseconfig-x86-i686PAE
i686-PAEdebug=baseconfig:baseconfig-x86:baseconfig-x86-i686PAE:debugconfig:debugconfig-x86
# ppc64
ppc64=baseconfig:baseconfig-powerpc:baseconfig-powerpc-powerpc64
ppc64-debug=baseconfig:baseconfig-powerpc:baseconfig-powerpc-powerpc64:debugconfig
# ppc64le
ppc64le=baseconfig:baseconfig-powerpc:baseconfig-powerpc-powerpc64le
ppc64le-debug=baseconfig:baseconfig-powerpc:baseconfig-powerpc-powerpc64le:debugconfig
# s390x
s390x=baseconfig:baseconfig-s390x
s390x-debug=baseconfig:baseconfig-s390x:debugconfig
# aarch64
aarch64=baseconfig:baseconfig-arm:baseconfig-arm-aarch64
aarch64-debug=baseconfig:baseconfig-arm:baseconfig-arm-aarch64:debugconfig:debugconfig-arm
# arm
armv7hl=baseconfig:baseconfig-arm:baseconfig-arm-armv7:baseconfig-arm-armv7-armv7
armv7hl-debug=baseconfig:baseconfig-arm:baseconfig-arm-armv7:baseconfig-arm-armv7-armv7:debugconfig:debugconfig-arm
armv7hl-lpae=baseconfig:baseconfig-arm:baseconfig-arm-armv7:baseconfig-arm-armv7-lpae
armv7hl-lpae-debug=baseconfig:baseconfig-arm:baseconfig-arm-armv7:baseconfig-arm-armv7-lpae:debugconfig:debugconfig-arm

1
config_generation Symbolic link
View File

@ -0,0 +1 @@
configs/config_generation

View File

@ -0,0 +1 @@
CONFIG_ACPI_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_ARM64_PTDUMP=y

View File

@ -0,0 +1 @@
CONFIG_ARM_PTDUMP=y

View File

@ -0,0 +1 @@
CONFIG_ARM_PTDUMP_DEBUGFS=y

View File

@ -0,0 +1 @@
CONFIG_ATH_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_B43LEGACY_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_B43_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION=y

View File

@ -0,0 +1 @@
CONFIG_BPF_KPROBE_OVERRIDE=y

View File

@ -0,0 +1 @@
CONFIG_CAN_DEBUG_DEVICES=y

View File

@ -0,0 +1 @@
CONFIG_CARL9170_DEBUGFS=y

View File

@ -0,0 +1 @@
CONFIG_CEPH_LIB_PRETTYDEBUG=y

View File

@ -0,0 +1 @@
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m

View File

@ -0,0 +1 @@
CONFIG_DEBUG_ATOMIC_SLEEP=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_BLK_CGROUP=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_CREDENTIALS=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_KMEMLEAK=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4096

View File

@ -0,0 +1 @@
CONFIG_DEBUG_LOCK_ALLOC=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_MUTEXES=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_NOTIFIERS=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_OBJECTS=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_OBJECTS_FREE=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_OBJECTS_TIMERS=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_OBJECTS_WORK=y

View File

@ -0,0 +1 @@
# CONFIG_DEBUG_PAGEALLOC is not set

View File

@ -0,0 +1 @@
CONFIG_DEBUG_PERF_USE_VMALLOC=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_PER_CPU_MAPS=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_PI_LIST=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_REFCOUNT=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_RT_MUTEXES=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_RWSEMS=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_SG=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_SLAB=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_SPINLOCK=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_STACK_USAGE=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_VM=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_VM_PGFLAGS=y

View File

@ -0,0 +1 @@
CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y

View File

@ -0,0 +1 @@
CONFIG_DETECT_HUNG_TASK=y

View File

@ -0,0 +1 @@
CONFIG_DMADEVICES_DEBUG=y

View File

@ -0,0 +1 @@
# CONFIG_DMADEVICES_VDEBUG is not set

View File

@ -0,0 +1 @@
CONFIG_DMA_API_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_DRBD_FAULT_INJECTION=y

View File

@ -0,0 +1 @@
CONFIG_EFI_PGT_DUMP=y

View File

@ -0,0 +1 @@
CONFIG_EXT4_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_FAILSLAB=y

View File

@ -0,0 +1 @@
CONFIG_FAIL_FUNCTION=y

View File

@ -0,0 +1 @@
CONFIG_FAIL_IO_TIMEOUT=y

View File

@ -0,0 +1 @@
CONFIG_FAIL_MAKE_REQUEST=y

View File

@ -0,0 +1 @@
CONFIG_FAIL_MMC_REQUEST=y

View File

@ -0,0 +1 @@
CONFIG_FAIL_PAGE_ALLOC=y

View File

@ -0,0 +1 @@
CONFIG_FAULT_INJECTION=y

View File

@ -0,0 +1 @@
CONFIG_FAULT_INJECTION_DEBUG_FS=y

View File

@ -0,0 +1 @@
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y

View File

@ -0,0 +1 @@
CONFIG_IWLWIFI_DEVICE_TRACING=y

View File

@ -0,0 +1 @@
CONFIG_JBD2_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_KDB_DEFAULT_ENABLE=0x0

View File

@ -0,0 +1 @@
CONFIG_KDB_KEYBOARD=y

View File

@ -0,0 +1 @@
CONFIG_KGDB_KDB=y

View File

@ -0,0 +1 @@
CONFIG_LOCK_STAT=y

View File

@ -0,0 +1 @@
CONFIG_LOCK_TORTURE_TEST=m

View File

@ -0,0 +1 @@
CONFIG_MAXSMP=y

View File

@ -0,0 +1 @@
CONFIG_MMIOTRACE=y

View File

@ -0,0 +1 @@
CONFIG_MODULE_FORCE_UNLOAD=y

View File

@ -0,0 +1 @@
CONFIG_NFSD_FAULT_INJECTION=y

View File

@ -0,0 +1 @@
CONFIG_NOUVEAU_DEBUG_MMU=y

View File

@ -0,0 +1 @@
CONFIG_PM_ADVANCED_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_PM_TEST_SUSPEND=y

View File

@ -0,0 +1 @@
CONFIG_PROVE_LOCKING=y

View File

@ -0,0 +1 @@
CONFIG_PROVE_RCU=y

View File

@ -0,0 +1 @@
CONFIG_QUOTA_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_REFCOUNT_FULL=y

View File

@ -0,0 +1 @@
CONFIG_SND_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_SND_PCM_XRUN_DEBUG=y

View File

@ -0,0 +1 @@
CONFIG_SND_VERBOSE_PRINTK=y

View File

@ -0,0 +1 @@
CONFIG_TEST_LIST_SORT=y

View File

@ -0,0 +1 @@
CONFIG_WQ_WATCHDOG=y

Some files were not shown because too many files have changed in this diff Show More