2017-04-01 13:22:41

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 00/19] 3.16.43-rc1 review

This is the start of the stable review cycle for the 3.16.43 release.
There are 19 patches in this series, which will be posted as responses
to this one. If anyone has any issues with these being applied, please
let me know.

Responses should be made by Tue Apr 04 00:00:00 UTC 2017.
Anything received after that time might be too late.

A combined patch relative to 3.16.42 will be posted as an additional
response to this. A shortlog and diffstat can be found below.

Ben.

-------------

Andre Przywara (1):
fs/nfs: fix new compiler warning about boolean in switch
[c7757074839f2cd440521482d76ea180d0d4bdac]

Arnd Bergmann (2):
crypto: improve gcc optimization flags for serpent and wp512
[7d6e9105026788c497f0ab32fa16c82f4ab5ff61]
mmc: sunxi: avoid invalid pointer calculation
[d34712d2e3db9b241d0484a6e3839c6b7ef9df78]

Ben Hutchings (1):
keys: Guard against null match function in keyring_search_aux()
[c06cfb08b88dfbe13be44a69ae2fdc3a7c902d81]

Eric W. Biederman (1):
vfs: Commit to never having exectuables on proc and sysfs.
[22f6b4d34fcf039c63a94e7670e0da24f8575a5a]

Fabio Estevam (1):
serial: samsung: Use %pa to print 'resource_size_t' type
[1ff5b64dccbf23acfe7993b9132b6992922a4756]

Florian Westphal (1):
netlink: remove mmapped netlink support
[d1b4c689d4130bcfd3532680b64db562300716b6]

James C Boyd (1):
HID: hid-input: Add parentheses to quell gcc warning
[09a5c34e8d6b05663ec4c3d22b1fbd9fec89aaf9]

Jann Horn (1):
aio: mark AIO pseudo-fs noexec
[22f6b4d34fcf039c63a94e7670e0da24f8575a5a]

John Crispin (1):
MIPS: ralink: Cosmetic change to prom_init().
[9c48568b3692f1a56cbf1935e4eea835e6b185b1]

Linus Torvalds (1):
blk: rq_data_dir() should not return a boolean
[10fbd36e362a0f367e34a7cd876a81295d8fc5ca]

Manuel Lauss (1):
MIPS: Fix build with binutils 2.24.51+
[842dfc11ea9a21f9825167c8a4f2834b205b0a79]

Paul Burton (4):
MIPS: init upper 64b of vector registers when MSA is first used
[c9017757c532d48bf43d6e7d3b7282443ad4207b]
MIPS: preserve scalar FP CSR when switching vector context
[b83406735a4ae0aff4b614664d6a64a0fd6b9917]
MIPS: save/disable MSA in lose_fpu
[33c771ba5c5d067f85a5a6c4b11047219b5b8f4e]
MIPS: save/restore MSACSR register on context switch
[f7a46fa7bb0047d3e226702a0c4b786862fe6843]

Ralf Baechle (1):
MIPS: Zero variable read by get_user / __get_user in case of an error.
[640465bda58c7078725201be7430c31a349121e9]

Tillmann Heidsieck (1):
atm: iphase: fix misleading indention
[cbb41b91e68a302087762823136c9067138cff7c]

Tim Gardner (1):
fs: namespace: suppress 'may be used uninitialized' warnings
[b8850d1fa8e2f6653e57daf6d08e58c5f5eb2c85]

Documentation/networking/netlink_mmap.txt | 339 --------------
Makefile | 4 +-
arch/mips/Makefile | 9 +
arch/mips/include/asm/asmmacro-32.h | 6 +
arch/mips/include/asm/asmmacro.h | 49 ++
arch/mips/include/asm/fpregdef.h | 14 +
arch/mips/include/asm/fpu.h | 15 +-
arch/mips/include/asm/mipsregs.h | 11 +-
arch/mips/include/asm/msa.h | 1 +
arch/mips/include/asm/uaccess.h | 5 +-
arch/mips/kernel/asm-offsets.c | 1 +
arch/mips/kernel/branch.c | 8 +-
arch/mips/kernel/genex.S | 1 +
arch/mips/kernel/r2300_fpu.S | 6 +
arch/mips/kernel/r2300_switch.S | 5 +
arch/mips/kernel/r4k_fpu.S | 27 +-
arch/mips/kernel/r4k_switch.S | 24 +-
arch/mips/kernel/r6000_fpu.S | 5 +
arch/mips/kernel/traps.c | 38 +-
arch/mips/math-emu/cp1emu.c | 6 +-
arch/mips/ralink/prom.c | 9 +-
crypto/Makefile | 2 +
drivers/atm/iphase.c | 2 +-
drivers/hid/hid-input.c | 2 +-
drivers/mmc/host/sunxi-mmc.c | 5 +-
drivers/tty/serial/samsung.c | 4 +-
fs/aio.c | 1 +
fs/compat.c | 10 +-
fs/exec.c | 10 +-
fs/internal.h | 2 +-
fs/namespace.c | 26 +-
fs/nfs/nfs4proc.c | 11 +-
fs/open.c | 2 +-
fs/proc/root.c | 2 +-
fs/sysfs/mount.c | 3 +-
include/linux/blkdev.h | 2 +-
include/linux/fs.h | 3 +
include/uapi/linux/netlink.h | 4 +
include/uapi/linux/netlink_diag.h | 2 +
kernel/sys.c | 3 +-
mm/mmap.c | 4 +-
mm/nommu.c | 2 +-
net/netlink/Kconfig | 9 -
net/netlink/af_netlink.c | 738 +-----------------------------
net/netlink/af_netlink.h | 15 -
net/netlink/diag.c | 39 --
security/keys/keyring.c | 6 +-
security/security.c | 2 +-
48 files changed, 279 insertions(+), 1215 deletions(-)

--
Ben Hutchings
It is easier to change the specification to fit the program than vice versa.


2017-04-01 13:22:51

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 13/19] MIPS: ralink: Cosmetic change to prom_init().

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: John Crispin <[email protected]>

commit 9c48568b3692f1a56cbf1935e4eea835e6b185b1 upstream.

Over the years the code has been changed various times leading to
argc/argv being defined in a different function to where we actually
use the variables. Clean this up by moving them to prom_init_cmdline().

Signed-off-by: John Crispin <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/14902/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
arch/mips/ralink/prom.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

--- a/arch/mips/ralink/prom.c
+++ b/arch/mips/ralink/prom.c
@@ -24,8 +24,10 @@ const char *get_system_type(void)
return soc_info.sys_type;
}

-static __init void prom_init_cmdline(int argc, char **argv)
+static __init void prom_init_cmdline(void)
{
+ int argc;
+ char **argv;
int i;

pr_debug("prom: fw_arg0=%08x fw_arg1=%08x fw_arg2=%08x fw_arg3=%08x\n",
@@ -54,14 +56,11 @@ static __init void prom_init_cmdline(int

void __init prom_init(void)
{
- int argc;
- char **argv;
-
prom_soc_init(&soc_info);

pr_info("SoC Type: %s\n", get_system_type());

- prom_init_cmdline(argc, argv);
+ prom_init_cmdline();
}

void __init prom_free_prom_memory(void)

2017-04-01 13:22:50

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 02/19] blk: rq_data_dir() should not return a boolean

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit 10fbd36e362a0f367e34a7cd876a81295d8fc5ca upstream.

rq_data_dir() returns either READ or WRITE (0 == READ, 1 == WRITE), not
a boolean value.

Now, admittedly the "!= 0" doesn't really change the value (0 stays as
zero, 1 stays as one), but it's not only redundant, it confuses gcc, and
causes gcc to warn about the construct

switch (rq_data_dir(req)) {
case READ:
...
case WRITE:
...

that we have in a few drivers.

Now, the gcc warning is silly and stupid (it seems to warn not about the
switch value having a different type from the case statements, but about
_any_ boolean switch value), but in this case the code itself is silly
and stupid too, so let's just change it, and get rid of warnings like
this:

drivers/block/hd.c: In function ‘hd_request’:
drivers/block/hd.c:630:11: warning: switch condition has boolean value [-Wswitch-bool]
switch (rq_data_dir(req)) {

The odd '!= 0' came in when "cmd_flags" got turned into a "u64" in
commit 5953316dbf90 ("block: make rq->cmd_flags be 64-bit") and is
presumably because the old code (that just did a logical 'and' with 1)
would then end up making the type of rq_data_dir() be u64 too.

But if we want to retain the old regular integer type, let's just cast
the result to 'int' rather than use that rather odd '!= 0'.

Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
include/linux/blkdev.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -620,7 +620,7 @@ static inline void queue_flag_clear(unsi

#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)

-#define rq_data_dir(rq) (((rq)->cmd_flags & 1) != 0)
+#define rq_data_dir(rq) ((int)((rq)->cmd_flags & 1))

/*
* Driver can handle struct request, if it either has an old style

2017-04-01 13:23:29

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 06/19] MIPS: init upper 64b of vector registers when MSA is first used

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit c9017757c532d48bf43d6e7d3b7282443ad4207b upstream.

When a task first makes use of MSA we need to ensure that the upper
64b of the vector registers are set to some value such that no
information can be leaked to it from the previous task to use MSA
context on the CPU. The architecture formerly specified that these
bits would be cleared to 0 when a scalar FP instructions wrote to the
aliased FP registers, which would have implicitly handled this as the
kernel restored scalar FP context. However more recent versions of the
specification now state that the value of the bits in such cases is
unpredictable. Initialise them explictly to be sure, and set all the
bits to 1 rather than 0 for consistency with the least significant
64b.

Signed-off-by: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/7497/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
arch/mips/include/asm/asmmacro.h | 20 ++++++++++++++++++++
arch/mips/include/asm/msa.h | 1 +
arch/mips/kernel/r4k_switch.S | 5 +++++
arch/mips/kernel/traps.c | 39 ++++++++++++++++++++++++++++++---------
4 files changed, 56 insertions(+), 9 deletions(-)

--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -426,4 +426,24 @@
ld_d 31, THREAD_FPR31, \thread
.endm

+ .macro msa_init_upper wd
+#ifdef CONFIG_64BIT
+ insert_d \wd, 1
+#else
+ insert_w \wd, 2
+ insert_w \wd, 3
+#endif
+ .if 31-\wd
+ msa_init_upper (\wd+1)
+ .endif
+ .endm
+
+ .macro msa_init_all_upper
+ .set push
+ .set noat
+ not $1, zero
+ msa_init_upper 0
+ .set pop
+ .endm
+
#endif /* _ASM_ASMMACRO_H */
--- a/arch/mips/include/asm/msa.h
+++ b/arch/mips/include/asm/msa.h
@@ -14,6 +14,7 @@

extern void _save_msa(struct task_struct *);
extern void _restore_msa(struct task_struct *);
+extern void _init_msa_upper(void);

static inline void enable_msa(void)
{
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -144,6 +144,11 @@ LEAF(_restore_msa)
jr ra
END(_restore_msa)

+LEAF(_init_msa_upper)
+ msa_init_all_upper
+ jr ra
+ END(_init_msa_upper)
+
#endif

/*
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1094,13 +1094,15 @@ static int default_cu2_call(struct notif

static int enable_restore_fp_context(int msa)
{
- int err, was_fpu_owner;
+ int err, was_fpu_owner, prior_msa;

if (!used_math()) {
/* First time FP context user. */
err = init_fpu();
- if (msa && !err)
+ if (msa && !err) {
enable_msa();
+ _init_msa_upper();
+ }
if (!err)
set_used_math();
return err;
@@ -1152,18 +1154,37 @@ static int enable_restore_fp_context(int
/*
* If this is the first time that the task is using MSA and it has
* previously used scalar FP in this time slice then we already nave
- * FP context which we shouldn't clobber.
+ * FP context which we shouldn't clobber. We do however need to clear
+ * the upper 64b of each vector register so that this task has no
+ * opportunity to see data left behind by another.
*/
- if (!test_and_set_thread_flag(TIF_MSA_CTX_LIVE) && was_fpu_owner)
+ prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE);
+ if (!prior_msa && was_fpu_owner) {
+ _init_msa_upper();
return 0;
+ }

- /* We need to restore the vector context. */
- restore_msa(current);
-
- /* Restore the scalar FP control & status register */
- if (!was_fpu_owner)
- asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31));
-
+ if (!prior_msa) {
+ /*
+ * Restore the least significant 64b of each vector register
+ * from the existing scalar FP context.
+ */
+ _restore_fp(current);
+
+ /*
+ * The task has not formerly used MSA, so clear the upper 64b
+ * of each vector register such that it cannot see data left
+ * behind by another task.
+ */
+ _init_msa_upper();
+ } else {
+ /* We need to restore the vector context. */
+ restore_msa(current);
+
+ /* Restore the scalar FP control & status register */
+ if (!was_fpu_owner)
+ asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31));
+ }
return 0;
}


2017-04-01 13:23:52

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 10/19] fs/nfs: fix new compiler warning about boolean in switch

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Andre Przywara <[email protected]>

commit c7757074839f2cd440521482d76ea180d0d4bdac upstream.

The brand new GCC 5.1.0 warns by default on using a boolean in the
switch condition. This results in the following warning:

fs/nfs/nfs4proc.c: In function 'nfs4_proc_get_rootfh':
fs/nfs/nfs4proc.c:3100:10: warning: switch condition has boolean value [-Wswitch-bool]
switch (auth_probe) {
^

This code was obviously using switch to make use of the fall-through
semantics (without the usual comment, though).
Rewrite that code using if statements to avoid the warning and make
the code a bit more readable on the way.

Signed-off-by: Andre Przywara <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
fs/nfs/nfs4proc.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)

--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3000,16 +3000,13 @@ int nfs4_proc_get_rootfh(struct nfs_serv
struct nfs_fsinfo *info,
bool auth_probe)
{
- int status;
+ int status = 0;

- switch (auth_probe) {
- case false:
+ if (!auth_probe)
status = nfs4_lookup_root(server, fhandle, info);
- if (status != -NFS4ERR_WRONGSEC)
- break;
- default:
+
+ if (auth_probe || status == NFS4ERR_WRONGSEC)
status = nfs4_do_find_root_sec(server, fhandle, info);
- }

if (status == 0)
status = nfs4_server_capabilities(server, fhandle);

2017-04-01 13:22:48

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 19/19] keys: Guard against null match function in keyring_search_aux()

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Ben Hutchings <[email protected]>

The "dead" key type has no match operation, and a search for keys of
this type can cause a null dereference in keyring_search_iterator().
keyring_search() has a check for this, but request_keyring_and_link()
does not. Move the check into keyring_search_aux(), covering both of
them.

This was fixed upstream by commit c06cfb08b88d ("KEYS: Remove
key_type::match in favour of overriding default by match_preparse"),
part of a series of large changes that are not suitable for
backporting.

CVE-2017-2647 / CVE-2017-6951

Reported-by: Igor Redko <[email protected]>
Reported-by: Andrey Ryabinin <[email protected]>
References: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2017-2647
Reported-by: idl3r <[email protected]>
References: https://www.spinics.net/lists/keyrings/msg01845.html
Signed-off-by: Ben Hutchings <[email protected]>
Cc: David Howells <[email protected]>
---
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -848,6 +848,9 @@ key_ref_t keyring_search_aux(key_ref_t k
return ERR_PTR(err);
}

+ if (!ctx->match)
+ return ERR_PTR(-ENOKEY);
+
rcu_read_lock();
ctx->now = current_kernel_time();
if (search_nested_keyrings(keyring, ctx))
@@ -879,9 +882,6 @@ key_ref_t keyring_search(key_ref_t keyri
KEYRING_SEARCH_DO_STATE_CHECK),
};

- if (!ctx.match)
- return ERR_PTR(-ENOKEY);
-
return keyring_search_aux(keyring, &ctx);
}
EXPORT_SYMBOL(keyring_search);

2017-04-01 13:23:54

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 17/19] vfs: Commit to never having exectuables on proc and sysfs.

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: "Eric W. Biederman" <[email protected]>

commit 22f6b4d34fcf039c63a94e7670e0da24f8575a5a upstream.

Today proc and sysfs do not contain any executable files. Several
applications today mount proc or sysfs without noexec and nosuid and
then depend on there being no exectuables files on proc or sysfs.
Having any executable files show on proc or sysfs would cause
a user space visible regression, and most likely security problems.

Therefore commit to never allowing executables on proc and sysfs by
adding a new flag to mark them as filesystems without executables and
enforce that flag.

Test the flag where MNT_NOEXEC is tested today, so that the only user
visible effect will be that exectuables will be treated as if the
execute bit is cleared.

The filesystems proc and sysfs do not currently incoporate any
executable files so this does not result in any user visible effects.

This makes it unnecessary to vet changes to proc and sysfs tightly for
adding exectuable files or changes to chattr that would modify
existing files, as no matter what the individual file say they will
not be treated as exectuable files by the vfs.

Not having to vet changes to closely is important as without this we
are only one proc_create call (or another goof up in the
implementation of notify_change) from having problematic executables
on proc. Those mistakes are all too easy to make and would create
a situation where there are security issues or the assumptions of
some program having to be broken (and cause userspace regressions).

Signed-off-by: "Eric W. Biederman" <[email protected]>
[bwh: Backported to 3.16: we don't have super_block::s_iflags; use
file_system_type::fs_flags instead]
Signed-off-by: Ben Hutchings <[email protected]>
---
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -98,6 +98,12 @@ static inline void put_binfmt(struct lin
module_put(fmt->module);
}

+bool path_noexec(const struct path *path)
+{
+ return (path->mnt->mnt_flags & MNT_NOEXEC) ||
+ (path->mnt->mnt_sb->s_type->fs_flags & FS_NOEXEC);
+}
+
#ifdef CONFIG_USELIB
/*
* Note that a shared library must be both readable and executable due to
@@ -132,7 +138,7 @@ SYSCALL_DEFINE1(uselib, const char __use
goto exit;

error = -EACCES;
- if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
+ if (path_noexec(&file->f_path))
goto exit;

fsnotify_open(file);
@@ -773,7 +779,7 @@ static struct file *do_open_exec(struct
if (!S_ISREG(file_inode(file)->i_mode))
goto exit;

- if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
+ if (path_noexec(&file->f_path))
goto exit;

fsnotify_open(file);
--- a/fs/open.c
+++ b/fs/open.c
@@ -359,7 +359,7 @@ retry:
* with the "noexec" flag.
*/
res = -EACCES;
- if (path.mnt->mnt_flags & MNT_NOEXEC)
+ if (path_noexec(&path))
goto out_path_release;
}

--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -161,7 +161,7 @@ static struct file_system_type proc_fs_t
.name = "proc",
.mount = proc_mount,
.kill_sb = proc_kill_sb,
- .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
+ .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT | FS_NOEXEC,
};

void __init proc_root_init(void)
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -40,6 +40,7 @@ static struct dentry *sysfs_mount(struct
SYSFS_MAGIC, &new_sb, ns);
if (IS_ERR(root) || !new_sb)
kobj_ns_drop(KOBJ_NS_TYPE_NET, ns);
+
return root;
}

@@ -55,7 +56,7 @@ static struct file_system_type sysfs_fs_
.name = "sysfs",
.mount = sysfs_mount,
.kill_sb = sysfs_kill_sb,
- .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
+ .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT | FS_NOEXEC,
};

int __init sysfs_init(void)
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1767,6 +1767,7 @@ struct file_system_type {
#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */
#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */
#define FS_USERNS_VISIBLE 32 /* FS must already be visible */
+#define FS_NOEXEC 64 /* Ignore executables on this fs */
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
struct dentry *(*mount) (struct file_system_type *, int,
const char *, void *);
@@ -2782,4 +2783,6 @@ static inline bool dir_relax(struct inod
return !IS_DEADDIR(inode);
}

+extern bool path_noexec(const struct path *path);
+
#endif /* _LINUX_FS_H */
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1646,8 +1646,7 @@ static int prctl_set_mm_exe_file(struct
* overall picture.
*/
err = -EACCES;
- if (!S_ISREG(inode->i_mode) ||
- exe.file->f_path.mnt->mnt_flags & MNT_NOEXEC)
+ if (!S_ISREG(inode->i_mode) || path_noexec(&exe.file->f_path))
goto exit;

err = inode_permission(inode, MAY_EXEC);
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1250,7 +1250,7 @@ unsigned long do_mmap_pgoff(struct file
* mounted, in which case we dont add PROT_EXEC.)
*/
if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
- if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
+ if (!(file && path_noexec(&file->f_path)))
prot |= PROT_EXEC;

if (!len)
@@ -1322,7 +1322,7 @@ unsigned long do_mmap_pgoff(struct file
case MAP_PRIVATE:
if (!(file->f_mode & FMODE_READ))
return -EACCES;
- if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) {
+ if (path_noexec(&file->f_path)) {
if (vm_flags & VM_EXEC)
return -EPERM;
vm_flags &= ~VM_MAYEXEC;
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1043,7 +1043,7 @@ static int validate_mmap_request(struct

/* handle executable mappings and implied executable
* mappings */
- if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) {
+ if (path_noexec(&file->f_path)) {
if (prot & PROT_EXEC)
return -EPERM;
} else if ((prot & PROT_READ) && !(prot & PROT_EXEC)) {
--- a/security/security.c
+++ b/security/security.c
@@ -728,7 +728,7 @@ static inline unsigned long mmap_prot(st
* ditto if it's not on noexec mount, except that on !MMU we need
* BDI_CAP_EXEC_MMAP (== VM_MAYEXEC) in this case
*/
- if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC)) {
+ if (!path_noexec(&file->f_path)) {
#ifndef CONFIG_MMU
unsigned long caps = 0;
struct address_space *mapping = file->f_mapping;

2017-04-01 13:23:51

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 09/19] crypto: improve gcc optimization flags for serpent and wp512

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit 7d6e9105026788c497f0ab32fa16c82f4ab5ff61 upstream.

An ancient gcc bug (first reported in 2003) has apparently resurfaced
on MIPS, where kernelci.org reports an overly large stack frame in the
whirlpool hash algorithm:

crypto/wp512.c:987:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=]

With some testing in different configurations, I'm seeing large
variations in stack frames size up to 1500 bytes for what should have
around 300 bytes at most. I also checked the reference implementation,
which is essentially the same code but also comes with some test and
benchmarking infrastructure.

It seems that recent compiler versions on at least arm, arm64 and powerpc
have a partial fix for this problem, but enabling "-fsched-pressure", but
even with that fix they suffer from the issue to a certain degree. Some
testing on arm64 shows that the time needed to hash a given amount of
data is roughly proportional to the stack frame size here, which makes
sense given that the wp512 implementation is doing lots of loads for
table lookups, and the problem with the overly large stack is a result
of doing a lot more loads and stores for spilled registers (as seen from
inspecting the object code).

Disabling -fschedule-insns consistently fixes the problem for wp512,
in my collection of cross-compilers, the results are consistently better
or identical when comparing the stack sizes in this function, though
some architectures (notable x86) have schedule-insns disabled by
default.

The four columns are:
default: -O2
press: -O2 -fsched-pressure
nopress: -O2 -fschedule-insns -fno-sched-pressure
nosched: -O2 -no-schedule-insns (disables sched-pressure)

default press nopress nosched
alpha-linux-gcc-4.9.3 1136 848 1136 176
am33_2.0-linux-gcc-4.9.3 2100 2076 2100 2104
arm-linux-gnueabi-gcc-4.9.3 848 848 1048 352
cris-linux-gcc-4.9.3 272 272 272 272
frv-linux-gcc-4.9.3 1128 1000 1128 280
hppa64-linux-gcc-4.9.3 1128 336 1128 184
hppa-linux-gcc-4.9.3 644 308 644 276
i386-linux-gcc-4.9.3 352 352 352 352
m32r-linux-gcc-4.9.3 720 656 720 268
microblaze-linux-gcc-4.9.3 1108 604 1108 256
mips64-linux-gcc-4.9.3 1328 592 1328 208
mips-linux-gcc-4.9.3 1096 624 1096 240
powerpc64-linux-gcc-4.9.3 1088 432 1088 160
powerpc-linux-gcc-4.9.3 1080 584 1080 224
s390-linux-gcc-4.9.3 456 456 624 360
sh3-linux-gcc-4.9.3 292 292 292 292
sparc64-linux-gcc-4.9.3 992 240 992 208
sparc-linux-gcc-4.9.3 680 592 680 312
x86_64-linux-gcc-4.9.3 224 240 272 224
xtensa-linux-gcc-4.9.3 1152 704 1152 304

aarch64-linux-gcc-7.0.0 224 224 1104 208
arm-linux-gnueabi-gcc-7.0.1 824 824 1048 352
mips-linux-gcc-7.0.0 1120 648 1120 272
x86_64-linux-gcc-7.0.1 240 240 304 240

arm-linux-gnueabi-gcc-4.4.7 840 392
arm-linux-gnueabi-gcc-4.5.4 784 728 784 320
arm-linux-gnueabi-gcc-4.6.4 736 728 736 304
arm-linux-gnueabi-gcc-4.7.4 944 784 944 352
arm-linux-gnueabi-gcc-4.8.5 464 464 760 352
arm-linux-gnueabi-gcc-4.9.3 848 848 1048 352
arm-linux-gnueabi-gcc-5.3.1 824 824 1064 336
arm-linux-gnueabi-gcc-6.1.1 808 808 1056 344
arm-linux-gnueabi-gcc-7.0.1 824 824 1048 352

Trying the same test for serpent-generic, the picture is a bit different,
and while -fno-schedule-insns is generally better here than the default,
-fsched-pressure wins overall, so I picked that instead.

default press nopress nosched
alpha-linux-gcc-4.9.3 1392 864 1392 960
am33_2.0-linux-gcc-4.9.3 536 524 536 528
arm-linux-gnueabi-gcc-4.9.3 552 552 776 536
cris-linux-gcc-4.9.3 528 528 528 528
frv-linux-gcc-4.9.3 536 400 536 504
hppa64-linux-gcc-4.9.3 524 208 524 480
hppa-linux-gcc-4.9.3 768 472 768 508
i386-linux-gcc-4.9.3 564 564 564 564
m32r-linux-gcc-4.9.3 712 576 712 532
microblaze-linux-gcc-4.9.3 724 392 724 512
mips64-linux-gcc-4.9.3 720 384 720 496
mips-linux-gcc-4.9.3 728 384 728 496
powerpc64-linux-gcc-4.9.3 704 304 704 480
powerpc-linux-gcc-4.9.3 704 296 704 480
s390-linux-gcc-4.9.3 560 560 592 536
sh3-linux-gcc-4.9.3 540 540 540 540
sparc64-linux-gcc-4.9.3 544 352 544 496
sparc-linux-gcc-4.9.3 544 344 544 496
x86_64-linux-gcc-4.9.3 528 536 576 528
xtensa-linux-gcc-4.9.3 752 544 752 544

aarch64-linux-gcc-7.0.0 432 432 656 480
arm-linux-gnueabi-gcc-7.0.1 616 616 808 536
mips-linux-gcc-7.0.0 720 464 720 488
x86_64-linux-gcc-7.0.1 536 528 600 536

arm-linux-gnueabi-gcc-4.4.7 592 440
arm-linux-gnueabi-gcc-4.5.4 776 448 776 544
arm-linux-gnueabi-gcc-4.6.4 776 448 776 544
arm-linux-gnueabi-gcc-4.7.4 768 448 768 544
arm-linux-gnueabi-gcc-4.8.5 488 488 776 544
arm-linux-gnueabi-gcc-4.9.3 552 552 776 536
arm-linux-gnueabi-gcc-5.3.1 552 552 776 536
arm-linux-gnueabi-gcc-6.1.1 560 560 776 536
arm-linux-gnueabi-gcc-7.0.1 616 616 808 536

I did not do any runtime tests with serpent, so it is possible that stack
frame size does not directly correlate with runtime performance here and
it actually makes things worse, but it's more likely to help here, and
the reduced stack frame size is probably enough reason to apply the patch,
especially given that the crypto code is often used in deep call chains.

Link: https://kernelci.org/build/id/58797d7559b5149efdf6c3a9/logs/
Link: http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11488
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
Cc: Ralf Baechle <[email protected]>
Signed-off-by: Arnd Bergmann <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
crypto/Makefile | 2 ++
1 file changed, 2 insertions(+)

--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_CRYPTO_SHA1) += sha1_generi
obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o
obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o
obj-$(CONFIG_CRYPTO_WP512) += wp512.o
+CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
obj-$(CONFIG_CRYPTO_ECB) += ecb.o
@@ -67,6 +68,7 @@ obj-$(CONFIG_CRYPTO_BLOWFISH_COMMON) +=
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o
obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o
+CFLAGS_serpent_generic.o := $(call cc-option,-fsched-pressure) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
obj-$(CONFIG_CRYPTO_AES) += aes_generic.o
obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o
obj-$(CONFIG_CRYPTO_CAST_COMMON) += cast_common.o

2017-04-01 13:23:50

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 16/19] netlink: remove mmapped netlink support

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Florian Westphal <[email protected]>

commit d1b4c689d4130bcfd3532680b64db562300716b6 upstream.

mmapped netlink has a number of unresolved issues:

- TX zerocopy support had to be disabled more than a year ago via
commit 4682a0358639b29cf ("netlink: Always copy on mmap TX.")
because the content of the mmapped area can change after netlink
attribute validation but before message processing.

- RX support was implemented mainly to speed up nfqueue dumping packet
payload to userspace. However, since commit ae08ce0021087a5d812d2
("netfilter: nfnetlink_queue: zero copy support") we avoid one copy
with the socket-based interface too (via the skb_zerocopy helper).

The other problem is that skbs attached to mmaped netlink socket
behave different from normal skbs:

- they don't have a shinfo area, so all functions that use skb_shinfo()
(e.g. skb_clone) cannot be used.

- reserving headroom prevents userspace from seeing the content as
it expects message to start at skb->head.
See for instance
commit aa3a022094fa ("netlink: not trim skb for mmaped socket when dump").

- skbs handed e.g. to netlink_ack must have non-NULL skb->sk, else we
crash because it needs the sk to check if a tx ring is attached.

Also not obvious, leads to non-intuitive bug fixes such as 7c7bdf359
("netfilter: nfnetlink: use original skbuff when acking batches").

mmaped netlink also didn't play nicely with the skb_zerocopy helper
used by nfqueue and openvswitch. Daniel Borkmann fixed this via
commit 6bb0fef489f6 ("netlink, mmap: fix edge-case leakages in nf queue
zero-copy")' but at the cost of also needing to provide remaining
length to the allocation function.

nfqueue also has problems when used with mmaped rx netlink:
- mmaped netlink doesn't allow use of nfqueue batch verdict messages.
Problem is that in the mmap case, the allocation time also determines
the ordering in which the frame will be seen by userspace (A
allocating before B means that A is located in earlier ring slot,
but this also means that B might get a lower sequence number then A
since seqno is decided later. To fix this we would need to extend the
spinlocked region to also cover the allocation and message setup which
isn't desirable.
- nfqueue can now be configured to queue large (GSO) skbs to userspace.
Queing GSO packets is faster than having to force a software segmentation
in the kernel, so this is a desirable option. However, with a mmap based
ring one has to use 64kb per ring slot element, else mmap has to fall back
to the socket path (NL_MMAP_STATUS_COPY) for all large packets.

To use the mmap interface, userspace not only has to probe for mmap netlink
support, it also has to implement a recv/socket receive path in order to
handle messages that exceed the size of an rx ring element.

Cc: Daniel Borkmann <[email protected]>
Cc: Ken-ichirou MATSUZAWA <[email protected]>
Cc: Pablo Neira Ayuso <[email protected]>
Cc: Patrick McHardy <[email protected]>
Cc: Thomas Graf <[email protected]>
Signed-off-by: Florian Westphal <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
[bwh: Backported to 3.16: deleted code and documentation is different in places]
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Shi Yuejie <[email protected]>
---
--- a/Documentation/networking/netlink_mmap.txt
+++ /dev/null
@@ -1,339 +0,0 @@
-This file documents how to use memory mapped I/O with netlink.
-
-Author: Patrick McHardy <[email protected]>
-
-Overview
---------
-
-Memory mapped netlink I/O can be used to increase throughput and decrease
-overhead of unicast receive and transmit operations. Some netlink subsystems
-require high throughput, these are mainly the netfilter subsystems
-nfnetlink_queue and nfnetlink_log, but it can also help speed up large
-dump operations of f.i. the routing database.
-
-Memory mapped netlink I/O used two circular ring buffers for RX and TX which
-are mapped into the processes address space.
-
-The RX ring is used by the kernel to directly construct netlink messages into
-user-space memory without copying them as done with regular socket I/O,
-additionally as long as the ring contains messages no recvmsg() or poll()
-syscalls have to be issued by user-space to get more message.
-
-The TX ring is used to process messages directly from user-space memory, the
-kernel processes all messages contained in the ring using a single sendmsg()
-call.
-
-Usage overview
---------------
-
-In order to use memory mapped netlink I/O, user-space needs three main changes:
-
-- ring setup
-- conversion of the RX path to get messages from the ring instead of recvmsg()
-- conversion of the TX path to construct messages into the ring
-
-Ring setup is done using setsockopt() to provide the ring parameters to the
-kernel, then a call to mmap() to map the ring into the processes address space:
-
-- setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, &params, sizeof(params));
-- setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, &params, sizeof(params));
-- ring = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
-
-Usage of either ring is optional, but even if only the RX ring is used the
-mapping still needs to be writable in order to update the frame status after
-processing.
-
-Conversion of the reception path involves calling poll() on the file
-descriptor, once the socket is readable the frames from the ring are
-processed in order until no more messages are available, as indicated by
-a status word in the frame header.
-
-On kernel side, in order to make use of memory mapped I/O on receive, the
-originating netlink subsystem needs to support memory mapped I/O, otherwise
-it will use an allocated socket buffer as usual and the contents will be
- copied to the ring on transmission, nullifying most of the performance gains.
-Dumps of kernel databases automatically support memory mapped I/O.
-
-Conversion of the transmit path involves changing message construction to
-use memory from the TX ring instead of (usually) a buffer declared on the
-stack and setting up the frame header appropriately. Optionally poll() can
-be used to wait for free frames in the TX ring.
-
-Structured and definitions for using memory mapped I/O are contained in
-<linux/netlink.h>.
-
-RX and TX rings
-----------------
-
-Each ring contains a number of continuous memory blocks, containing frames of
-fixed size dependent on the parameters used for ring setup.
-
-Ring: [ block 0 ]
- [ frame 0 ]
- [ frame 1 ]
- [ block 1 ]
- [ frame 2 ]
- [ frame 3 ]
- ...
- [ block n ]
- [ frame 2 * n ]
- [ frame 2 * n + 1 ]
-
-The blocks are only visible to the kernel, from the point of view of user-space
-the ring just contains the frames in a continuous memory zone.
-
-The ring parameters used for setting up the ring are defined as follows:
-
-struct nl_mmap_req {
- unsigned int nm_block_size;
- unsigned int nm_block_nr;
- unsigned int nm_frame_size;
- unsigned int nm_frame_nr;
-};
-
-Frames are grouped into blocks, where each block is a continuous region of memory
-and holds nm_block_size / nm_frame_size frames. The total number of frames in
-the ring is nm_frame_nr. The following invariants hold:
-
-- frames_per_block = nm_block_size / nm_frame_size
-
-- nm_frame_nr = frames_per_block * nm_block_nr
-
-Some parameters are constrained, specifically:
-
-- nm_block_size must be a multiple of the architectures memory page size.
- The getpagesize() function can be used to get the page size.
-
-- nm_frame_size must be equal or larger to NL_MMAP_HDRLEN, IOW a frame must be
- able to hold at least the frame header
-
-- nm_frame_size must be smaller or equal to nm_block_size
-
-- nm_frame_size must be a multiple of NL_MMAP_MSG_ALIGNMENT
-
-- nm_frame_nr must equal the actual number of frames as specified above.
-
-When the kernel can't allocate physically continuous memory for a ring block,
-it will fall back to use physically discontinuous memory. This might affect
-performance negatively, in order to avoid this the nm_frame_size parameter
-should be chosen to be as small as possible for the required frame size and
-the number of blocks should be increased instead.
-
-Ring frames
-------------
-
-Each frames contain a frame header, consisting of a synchronization word and some
-meta-data, and the message itself.
-
-Frame: [ header message ]
-
-The frame header is defined as follows:
-
-struct nl_mmap_hdr {
- unsigned int nm_status;
- unsigned int nm_len;
- __u32 nm_group;
- /* credentials */
- __u32 nm_pid;
- __u32 nm_uid;
- __u32 nm_gid;
-};
-
-- nm_status is used for synchronizing processing between the kernel and user-
- space and specifies ownership of the frame as well as the operation to perform
-
-- nm_len contains the length of the message contained in the data area
-
-- nm_group specified the destination multicast group of message
-
-- nm_pid, nm_uid and nm_gid contain the netlink pid, UID and GID of the sending
- process. These values correspond to the data available using SOCK_PASSCRED in
- the SCM_CREDENTIALS cmsg.
-
-The possible values in the status word are:
-
-- NL_MMAP_STATUS_UNUSED:
- RX ring: frame belongs to the kernel and contains no message
- for user-space. Approriate action is to invoke poll()
- to wait for new messages.
-
- TX ring: frame belongs to user-space and can be used for
- message construction.
-
-- NL_MMAP_STATUS_RESERVED:
- RX ring only: frame is currently used by the kernel for message
- construction and contains no valid message yet.
- Appropriate action is to invoke poll() to wait for
- new messages.
-
-- NL_MMAP_STATUS_VALID:
- RX ring: frame contains a valid message. Approriate action is
- to process the message and release the frame back to
- the kernel by setting the status to
- NL_MMAP_STATUS_UNUSED or queue the frame by setting the
- status to NL_MMAP_STATUS_SKIP.
-
- TX ring: the frame contains a valid message from user-space to
- be processed by the kernel. After completing processing
- the kernel will release the frame back to user-space by
- setting the status to NL_MMAP_STATUS_UNUSED.
-
-- NL_MMAP_STATUS_COPY:
- RX ring only: a message is ready to be processed but could not be
- stored in the ring, either because it exceeded the
- frame size or because the originating subsystem does
- not support memory mapped I/O. Appropriate action is
- to invoke recvmsg() to receive the message and release
- the frame back to the kernel by setting the status to
- NL_MMAP_STATUS_UNUSED.
-
-- NL_MMAP_STATUS_SKIP:
- RX ring only: user-space queued the message for later processing, but
- processed some messages following it in the ring. The
- kernel should skip this frame when looking for unused
- frames.
-
-The data area of a frame begins at a offset of NL_MMAP_HDRLEN relative to the
-frame header.
-
-TX limitations
---------------
-
-Kernel processing usually involves validation of the message received by
-user-space, then processing its contents. The kernel must assure that
-userspace is not able to modify the message contents after they have been
-validated. In order to do so, the message is copied from the ring frame
-to an allocated buffer if either of these conditions is false:
-
-- only a single mapping of the ring exists
-- the file descriptor is not shared between processes
-
-This means that for threaded programs, the kernel will fall back to copying.
-
-Example
--------
-
-Ring setup:
-
- unsigned int block_size = 16 * getpagesize();
- struct nl_mmap_req req = {
- .nm_block_size = block_size,
- .nm_block_nr = 64,
- .nm_frame_size = 16384,
- .nm_frame_nr = 64 * block_size / 16384,
- };
- unsigned int ring_size;
- void *rx_ring, *tx_ring;
-
- /* Configure ring parameters */
- if (setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req)) < 0)
- exit(1);
- if (setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req)) < 0)
- exit(1)
-
- /* Calculate size of each individual ring */
- ring_size = req.nm_block_nr * req.nm_block_size;
-
- /* Map RX/TX rings. The TX ring is located after the RX ring */
- rx_ring = mmap(NULL, 2 * ring_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0);
- if ((long)rx_ring == -1L)
- exit(1);
- tx_ring = rx_ring + ring_size:
-
-Message reception:
-
-This example assumes some ring parameters of the ring setup are available.
-
- unsigned int frame_offset = 0;
- struct nl_mmap_hdr *hdr;
- struct nlmsghdr *nlh;
- unsigned char buf[16384];
- ssize_t len;
-
- while (1) {
- struct pollfd pfds[1];
-
- pfds[0].fd = fd;
- pfds[0].events = POLLIN | POLLERR;
- pfds[0].revents = 0;
-
- if (poll(pfds, 1, -1) < 0 && errno != -EINTR)
- exit(1);
-
- /* Check for errors. Error handling omitted */
- if (pfds[0].revents & POLLERR)
- <handle error>
-
- /* If no new messages, poll again */
- if (!(pfds[0].revents & POLLIN))
- continue;
-
- /* Process all frames */
- while (1) {
- /* Get next frame header */
- hdr = rx_ring + frame_offset;
-
- if (hdr->nm_status == NL_MMAP_STATUS_VALID) {
- /* Regular memory mapped frame */
- nlh = (void *)hdr + NL_MMAP_HDRLEN;
- len = hdr->nm_len;
-
- /* Release empty message immediately. May happen
- * on error during message construction.
- */
- if (len == 0)
- goto release;
- } else if (hdr->nm_status == NL_MMAP_STATUS_COPY) {
- /* Frame queued to socket receive queue */
- len = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
- if (len <= 0)
- break;
- nlh = buf;
- } else
- /* No more messages to process, continue polling */
- break;
-
- process_msg(nlh);
-release:
- /* Release frame back to the kernel */
- hdr->nm_status = NL_MMAP_STATUS_UNUSED;
-
- /* Advance frame offset to next frame */
- frame_offset = (frame_offset + frame_size) % ring_size;
- }
- }
-
-Message transmission:
-
-This example assumes some ring parameters of the ring setup are available.
-A single message is constructed and transmitted, to send multiple messages
-at once they would be constructed in consecutive frames before a final call
-to sendto().
-
- unsigned int frame_offset = 0;
- struct nl_mmap_hdr *hdr;
- struct nlmsghdr *nlh;
- struct sockaddr_nl addr = {
- .nl_family = AF_NETLINK,
- };
-
- hdr = tx_ring + frame_offset;
- if (hdr->nm_status != NL_MMAP_STATUS_UNUSED)
- /* No frame available. Use poll() to avoid. */
- exit(1);
-
- nlh = (void *)hdr + NL_MMAP_HDRLEN;
-
- /* Build message */
- build_message(nlh);
-
- /* Fill frame header: length and status need to be set */
- hdr->nm_len = nlh->nlmsg_len;
- hdr->nm_status = NL_MMAP_STATUS_VALID;
-
- if (sendto(fd, NULL, 0, 0, &addr, sizeof(addr)) < 0)
- exit(1);
-
- /* Advance frame offset to next frame */
- frame_offset = (frame_offset + frame_size) % ring_size;
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -106,8 +106,10 @@ struct nlmsgerr {
#define NETLINK_PKTINFO 3
#define NETLINK_BROADCAST_ERROR 4
#define NETLINK_NO_ENOBUFS 5
+#ifndef __KERNEL__
#define NETLINK_RX_RING 6
#define NETLINK_TX_RING 7
+#endif

struct nl_pktinfo {
__u32 group;
@@ -130,6 +132,7 @@ struct nl_mmap_hdr {
__u32 nm_gid;
};

+#ifndef __KERNEL__
enum nl_mmap_status {
NL_MMAP_STATUS_UNUSED,
NL_MMAP_STATUS_RESERVED,
@@ -141,6 +144,7 @@ enum nl_mmap_status {
#define NL_MMAP_MSG_ALIGNMENT NLMSG_ALIGNTO
#define NL_MMAP_MSG_ALIGN(sz) __ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT)
#define NL_MMAP_HDRLEN NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr))
+#endif

#define NET_MAJOR 36 /* Major 36 is reserved for networking */

--- a/include/uapi/linux/netlink_diag.h
+++ b/include/uapi/linux/netlink_diag.h
@@ -48,6 +48,8 @@ enum {

#define NDIAG_SHOW_MEMINFO 0x00000001 /* show memory info of a socket */
#define NDIAG_SHOW_GROUPS 0x00000002 /* show groups of a netlink socket */
+#ifndef __KERNEL__
#define NDIAG_SHOW_RING_CFG 0x00000004 /* show ring configuration */
+#endif

#endif
--- a/net/netlink/Kconfig
+++ b/net/netlink/Kconfig
@@ -2,15 +2,6 @@
# Netlink Sockets
#

-config NETLINK_MMAP
- bool "NETLINK: mmaped IO"
- ---help---
- This option enables support for memory mapped netlink IO. This
- reduces overhead by avoiding copying data between kernel- and
- userspace.
-
- If unsure, say N.
-
config NETLINK_DIAG
tristate "NETLINK: socket monitoring interface"
default n
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -218,7 +218,7 @@ static int __netlink_deliver_tap_skb(str

dev_hold(dev);

- if (netlink_skb_is_mmaped(skb) || is_vmalloc_addr(skb->head))
+ if (is_vmalloc_addr(skb->head))
nskb = netlink_to_full_skb(skb, GFP_ATOMIC);
else
nskb = skb_clone(skb, GFP_ATOMIC);
@@ -292,599 +292,8 @@ static void netlink_rcv_wake(struct sock
wake_up_interruptible(&nlk->wait);
}

-#ifdef CONFIG_NETLINK_MMAP
-static bool netlink_rx_is_mmaped(struct sock *sk)
-{
- return nlk_sk(sk)->rx_ring.pg_vec != NULL;
-}
-
-static bool netlink_tx_is_mmaped(struct sock *sk)
-{
- return nlk_sk(sk)->tx_ring.pg_vec != NULL;
-}
-
-static __pure struct page *pgvec_to_page(const void *addr)
-{
- if (is_vmalloc_addr(addr))
- return vmalloc_to_page(addr);
- else
- return virt_to_page(addr);
-}
-
-static void free_pg_vec(void **pg_vec, unsigned int order, unsigned int len)
-{
- unsigned int i;
-
- for (i = 0; i < len; i++) {
- if (pg_vec[i] != NULL) {
- if (is_vmalloc_addr(pg_vec[i]))
- vfree(pg_vec[i]);
- else
- free_pages((unsigned long)pg_vec[i], order);
- }
- }
- kfree(pg_vec);
-}
-
-static void *alloc_one_pg_vec_page(unsigned long order)
-{
- void *buffer;
- gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | __GFP_ZERO |
- __GFP_NOWARN | __GFP_NORETRY;
-
- buffer = (void *)__get_free_pages(gfp_flags, order);
- if (buffer != NULL)
- return buffer;
-
- buffer = vzalloc((1 << order) * PAGE_SIZE);
- if (buffer != NULL)
- return buffer;
-
- gfp_flags &= ~__GFP_NORETRY;
- return (void *)__get_free_pages(gfp_flags, order);
-}
-
-static void **alloc_pg_vec(struct netlink_sock *nlk,
- struct nl_mmap_req *req, unsigned int order)
-{
- unsigned int block_nr = req->nm_block_nr;
- unsigned int i;
- void **pg_vec;
-
- pg_vec = kcalloc(block_nr, sizeof(void *), GFP_KERNEL);
- if (pg_vec == NULL)
- return NULL;
-
- for (i = 0; i < block_nr; i++) {
- pg_vec[i] = alloc_one_pg_vec_page(order);
- if (pg_vec[i] == NULL)
- goto err1;
- }
-
- return pg_vec;
-err1:
- free_pg_vec(pg_vec, order, block_nr);
- return NULL;
-}
-
-
-static void
-__netlink_set_ring(struct sock *sk, struct nl_mmap_req *req, bool tx_ring, void **pg_vec,
- unsigned int order)
-{
- struct netlink_sock *nlk = nlk_sk(sk);
- struct sk_buff_head *queue;
- struct netlink_ring *ring;
-
- queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
- ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring;
-
- spin_lock_bh(&queue->lock);
-
- ring->frame_max = req->nm_frame_nr - 1;
- ring->head = 0;
- ring->frame_size = req->nm_frame_size;
- ring->pg_vec_pages = req->nm_block_size / PAGE_SIZE;
-
- swap(ring->pg_vec_len, req->nm_block_nr);
- swap(ring->pg_vec_order, order);
- swap(ring->pg_vec, pg_vec);
-
- __skb_queue_purge(queue);
- spin_unlock_bh(&queue->lock);
-
- WARN_ON(atomic_read(&nlk->mapped));
-
- if (pg_vec)
- free_pg_vec(pg_vec, order, req->nm_block_nr);
-}
-
-static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req,
- bool tx_ring)
-{
- struct netlink_sock *nlk = nlk_sk(sk);
- struct netlink_ring *ring;
- void **pg_vec = NULL;
- unsigned int order = 0;
-
- ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring;
-
- if (atomic_read(&nlk->mapped))
- return -EBUSY;
- if (atomic_read(&ring->pending))
- return -EBUSY;
-
- if (req->nm_block_nr) {
- if (ring->pg_vec != NULL)
- return -EBUSY;
-
- if ((int)req->nm_block_size <= 0)
- return -EINVAL;
- if (!IS_ALIGNED(req->nm_block_size, PAGE_SIZE))
- return -EINVAL;
- if (req->nm_frame_size < NL_MMAP_HDRLEN)
- return -EINVAL;
- if (!IS_ALIGNED(req->nm_frame_size, NL_MMAP_MSG_ALIGNMENT))
- return -EINVAL;
-
- ring->frames_per_block = req->nm_block_size /
- req->nm_frame_size;
- if (ring->frames_per_block == 0)
- return -EINVAL;
- if (ring->frames_per_block * req->nm_block_nr !=
- req->nm_frame_nr)
- return -EINVAL;
-
- order = get_order(req->nm_block_size);
- pg_vec = alloc_pg_vec(nlk, req, order);
- if (pg_vec == NULL)
- return -ENOMEM;
- } else {
- if (req->nm_frame_nr)
- return -EINVAL;
- }
-
- mutex_lock(&nlk->pg_vec_lock);
- if (atomic_read(&nlk->mapped) == 0) {
- __netlink_set_ring(sk, req, tx_ring, pg_vec, order);
- mutex_unlock(&nlk->pg_vec_lock);
- return 0;
- }
-
- mutex_unlock(&nlk->pg_vec_lock);
-
- if (pg_vec)
- free_pg_vec(pg_vec, order, req->nm_block_nr);
-
- return -EBUSY;
-}
-
-static void netlink_mm_open(struct vm_area_struct *vma)
-{
- struct file *file = vma->vm_file;
- struct socket *sock = file->private_data;
- struct sock *sk = sock->sk;
-
- if (sk)
- atomic_inc(&nlk_sk(sk)->mapped);
-}
-
-static void netlink_mm_close(struct vm_area_struct *vma)
-{
- struct file *file = vma->vm_file;
- struct socket *sock = file->private_data;
- struct sock *sk = sock->sk;
-
- if (sk)
- atomic_dec(&nlk_sk(sk)->mapped);
-}
-
-static const struct vm_operations_struct netlink_mmap_ops = {
- .open = netlink_mm_open,
- .close = netlink_mm_close,
-};
-
-static int netlink_mmap(struct file *file, struct socket *sock,
- struct vm_area_struct *vma)
-{
- struct sock *sk = sock->sk;
- struct netlink_sock *nlk = nlk_sk(sk);
- struct netlink_ring *ring;
- unsigned long start, size, expected;
- unsigned int i;
- int err = -EINVAL;
-
- if (vma->vm_pgoff)
- return -EINVAL;
-
- mutex_lock(&nlk->pg_vec_lock);
-
- expected = 0;
- for (ring = &nlk->rx_ring; ring <= &nlk->tx_ring; ring++) {
- if (ring->pg_vec == NULL)
- continue;
- expected += ring->pg_vec_len * ring->pg_vec_pages * PAGE_SIZE;
- }
-
- if (expected == 0)
- goto out;
-
- size = vma->vm_end - vma->vm_start;
- if (size != expected)
- goto out;
-
- start = vma->vm_start;
- for (ring = &nlk->rx_ring; ring <= &nlk->tx_ring; ring++) {
- if (ring->pg_vec == NULL)
- continue;
-
- for (i = 0; i < ring->pg_vec_len; i++) {
- struct page *page;
- void *kaddr = ring->pg_vec[i];
- unsigned int pg_num;
-
- for (pg_num = 0; pg_num < ring->pg_vec_pages; pg_num++) {
- page = pgvec_to_page(kaddr);
- err = vm_insert_page(vma, start, page);
- if (err < 0)
- goto out;
- start += PAGE_SIZE;
- kaddr += PAGE_SIZE;
- }
- }
- }
-
- atomic_inc(&nlk->mapped);
- vma->vm_ops = &netlink_mmap_ops;
- err = 0;
-out:
- mutex_unlock(&nlk->pg_vec_lock);
- return err;
-}
-
-static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr, unsigned int nm_len)
-{
-#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE == 1
- struct page *p_start, *p_end;
-
- /* First page is flushed through netlink_{get,set}_status */
- p_start = pgvec_to_page(hdr + PAGE_SIZE);
- p_end = pgvec_to_page((void *)hdr + NL_MMAP_HDRLEN + nm_len - 1);
- while (p_start <= p_end) {
- flush_dcache_page(p_start);
- p_start++;
- }
-#endif
-}
-
-static enum nl_mmap_status netlink_get_status(const struct nl_mmap_hdr *hdr)
-{
- smp_rmb();
- flush_dcache_page(pgvec_to_page(hdr));
- return hdr->nm_status;
-}
-
-static void netlink_set_status(struct nl_mmap_hdr *hdr,
- enum nl_mmap_status status)
-{
- smp_mb();
- hdr->nm_status = status;
- flush_dcache_page(pgvec_to_page(hdr));
-}
-
-static struct nl_mmap_hdr *
-__netlink_lookup_frame(const struct netlink_ring *ring, unsigned int pos)
-{
- unsigned int pg_vec_pos, frame_off;
-
- pg_vec_pos = pos / ring->frames_per_block;
- frame_off = pos % ring->frames_per_block;
-
- return ring->pg_vec[pg_vec_pos] + (frame_off * ring->frame_size);
-}
-
-static struct nl_mmap_hdr *
-netlink_lookup_frame(const struct netlink_ring *ring, unsigned int pos,
- enum nl_mmap_status status)
-{
- struct nl_mmap_hdr *hdr;
-
- hdr = __netlink_lookup_frame(ring, pos);
- if (netlink_get_status(hdr) != status)
- return NULL;
-
- return hdr;
-}
-
-static struct nl_mmap_hdr *
-netlink_current_frame(const struct netlink_ring *ring,
- enum nl_mmap_status status)
-{
- return netlink_lookup_frame(ring, ring->head, status);
-}
-
-static struct nl_mmap_hdr *
-netlink_previous_frame(const struct netlink_ring *ring,
- enum nl_mmap_status status)
-{
- unsigned int prev;
-
- prev = ring->head ? ring->head - 1 : ring->frame_max;
- return netlink_lookup_frame(ring, prev, status);
-}
-
-static void netlink_increment_head(struct netlink_ring *ring)
-{
- ring->head = ring->head != ring->frame_max ? ring->head + 1 : 0;
-}
-
-static void netlink_forward_ring(struct netlink_ring *ring)
-{
- unsigned int head = ring->head, pos = head;
- const struct nl_mmap_hdr *hdr;
-
- do {
- hdr = __netlink_lookup_frame(ring, pos);
- if (hdr->nm_status == NL_MMAP_STATUS_UNUSED)
- break;
- if (hdr->nm_status != NL_MMAP_STATUS_SKIP)
- break;
- netlink_increment_head(ring);
- } while (ring->head != head);
-}
-
-static bool netlink_dump_space(struct netlink_sock *nlk)
-{
- struct netlink_ring *ring = &nlk->rx_ring;
- struct nl_mmap_hdr *hdr;
- unsigned int n;
-
- hdr = netlink_current_frame(ring, NL_MMAP_STATUS_UNUSED);
- if (hdr == NULL)
- return false;
-
- n = ring->head + ring->frame_max / 2;
- if (n > ring->frame_max)
- n -= ring->frame_max;
-
- hdr = __netlink_lookup_frame(ring, n);
-
- return hdr->nm_status == NL_MMAP_STATUS_UNUSED;
-}
-
-static unsigned int netlink_poll(struct file *file, struct socket *sock,
- poll_table *wait)
-{
- struct sock *sk = sock->sk;
- struct netlink_sock *nlk = nlk_sk(sk);
- unsigned int mask;
- int err;
-
- if (nlk->rx_ring.pg_vec != NULL) {
- /* Memory mapped sockets don't call recvmsg(), so flow control
- * for dumps is performed here. A dump is allowed to continue
- * if at least half the ring is unused.
- */
- while (nlk->cb_running && netlink_dump_space(nlk)) {
- err = netlink_dump(sk);
- if (err < 0) {
- sk->sk_err = -err;
- sk->sk_error_report(sk);
- break;
- }
- }
- netlink_rcv_wake(sk);
- }
-
- mask = datagram_poll(file, sock, wait);
-
- spin_lock_bh(&sk->sk_receive_queue.lock);
- if (nlk->rx_ring.pg_vec) {
- netlink_forward_ring(&nlk->rx_ring);
- if (!netlink_previous_frame(&nlk->rx_ring, NL_MMAP_STATUS_UNUSED))
- mask |= POLLIN | POLLRDNORM;
- }
- spin_unlock_bh(&sk->sk_receive_queue.lock);
-
- spin_lock_bh(&sk->sk_write_queue.lock);
- if (nlk->tx_ring.pg_vec) {
- if (netlink_current_frame(&nlk->tx_ring, NL_MMAP_STATUS_UNUSED))
- mask |= POLLOUT | POLLWRNORM;
- }
- spin_unlock_bh(&sk->sk_write_queue.lock);
-
- return mask;
-}
-
-static struct nl_mmap_hdr *netlink_mmap_hdr(struct sk_buff *skb)
-{
- return (struct nl_mmap_hdr *)(skb->head - NL_MMAP_HDRLEN);
-}
-
-static void netlink_ring_setup_skb(struct sk_buff *skb, struct sock *sk,
- struct netlink_ring *ring,
- struct nl_mmap_hdr *hdr)
-{
- unsigned int size;
- void *data;
-
- size = ring->frame_size - NL_MMAP_HDRLEN;
- data = (void *)hdr + NL_MMAP_HDRLEN;
-
- skb->head = data;
- skb->data = data;
- skb_reset_tail_pointer(skb);
- skb->end = skb->tail + size;
- skb->len = 0;
-
- skb->destructor = netlink_skb_destructor;
- NETLINK_CB(skb).flags |= NETLINK_SKB_MMAPED;
- NETLINK_CB(skb).sk = sk;
-}
-
-static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg,
- u32 dst_portid, u32 dst_group,
- struct sock_iocb *siocb)
-{
- struct netlink_sock *nlk = nlk_sk(sk);
- struct netlink_ring *ring;
- struct nl_mmap_hdr *hdr;
- struct sk_buff *skb;
- unsigned int maxlen;
- int err = 0, len = 0;
-
- mutex_lock(&nlk->pg_vec_lock);
-
- ring = &nlk->tx_ring;
- maxlen = ring->frame_size - NL_MMAP_HDRLEN;
-
- do {
- unsigned int nm_len;
-
- hdr = netlink_current_frame(ring, NL_MMAP_STATUS_VALID);
- if (hdr == NULL) {
- if (!(msg->msg_flags & MSG_DONTWAIT) &&
- atomic_read(&nlk->tx_ring.pending))
- schedule();
- continue;
- }
-
- nm_len = ACCESS_ONCE(hdr->nm_len);
- if (nm_len > maxlen) {
- err = -EINVAL;
- goto out;
- }
-
- netlink_frame_flush_dcache(hdr, nm_len);
-
- skb = alloc_skb(nm_len, GFP_KERNEL);
- if (skb == NULL) {
- err = -ENOBUFS;
- goto out;
- }
- __skb_put(skb, nm_len);
- memcpy(skb->data, (void *)hdr + NL_MMAP_HDRLEN, nm_len);
- netlink_set_status(hdr, NL_MMAP_STATUS_UNUSED);
-
- netlink_increment_head(ring);
-
- NETLINK_CB(skb).portid = nlk->portid;
- NETLINK_CB(skb).dst_group = dst_group;
- NETLINK_CB(skb).creds = siocb->scm->creds;
-
- err = security_netlink_send(sk, skb);
- if (err) {
- kfree_skb(skb);
- goto out;
- }
-
- if (unlikely(dst_group)) {
- atomic_inc(&skb->users);
- netlink_broadcast(sk, skb, dst_portid, dst_group,
- GFP_KERNEL);
- }
- err = netlink_unicast(sk, skb, dst_portid,
- msg->msg_flags & MSG_DONTWAIT);
- if (err < 0)
- goto out;
- len += err;
-
- } while (hdr != NULL ||
- (!(msg->msg_flags & MSG_DONTWAIT) &&
- atomic_read(&nlk->tx_ring.pending)));
-
- if (len > 0)
- err = len;
-out:
- mutex_unlock(&nlk->pg_vec_lock);
- return err;
-}
-
-static void netlink_queue_mmaped_skb(struct sock *sk, struct sk_buff *skb)
-{
- struct nl_mmap_hdr *hdr;
-
- hdr = netlink_mmap_hdr(skb);
- hdr->nm_len = skb->len;
- hdr->nm_group = NETLINK_CB(skb).dst_group;
- hdr->nm_pid = NETLINK_CB(skb).creds.pid;
- hdr->nm_uid = from_kuid(sk_user_ns(sk), NETLINK_CB(skb).creds.uid);
- hdr->nm_gid = from_kgid(sk_user_ns(sk), NETLINK_CB(skb).creds.gid);
- netlink_frame_flush_dcache(hdr, hdr->nm_len);
- netlink_set_status(hdr, NL_MMAP_STATUS_VALID);
-
- NETLINK_CB(skb).flags |= NETLINK_SKB_DELIVERED;
- kfree_skb(skb);
-}
-
-static void netlink_ring_set_copied(struct sock *sk, struct sk_buff *skb)
-{
- struct netlink_sock *nlk = nlk_sk(sk);
- struct netlink_ring *ring = &nlk->rx_ring;
- struct nl_mmap_hdr *hdr;
-
- spin_lock_bh(&sk->sk_receive_queue.lock);
- hdr = netlink_current_frame(ring, NL_MMAP_STATUS_UNUSED);
- if (hdr == NULL) {
- spin_unlock_bh(&sk->sk_receive_queue.lock);
- kfree_skb(skb);
- netlink_overrun(sk);
- return;
- }
- netlink_increment_head(ring);
- __skb_queue_tail(&sk->sk_receive_queue, skb);
- spin_unlock_bh(&sk->sk_receive_queue.lock);
-
- hdr->nm_len = skb->len;
- hdr->nm_group = NETLINK_CB(skb).dst_group;
- hdr->nm_pid = NETLINK_CB(skb).creds.pid;
- hdr->nm_uid = from_kuid(sk_user_ns(sk), NETLINK_CB(skb).creds.uid);
- hdr->nm_gid = from_kgid(sk_user_ns(sk), NETLINK_CB(skb).creds.gid);
- netlink_set_status(hdr, NL_MMAP_STATUS_COPY);
-}
-
-#else /* CONFIG_NETLINK_MMAP */
-#define netlink_rx_is_mmaped(sk) false
-#define netlink_tx_is_mmaped(sk) false
-#define netlink_mmap sock_no_mmap
-#define netlink_poll datagram_poll
-#define netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, siocb) 0
-#endif /* CONFIG_NETLINK_MMAP */
-
static void netlink_skb_destructor(struct sk_buff *skb)
{
-#ifdef CONFIG_NETLINK_MMAP
- struct nl_mmap_hdr *hdr;
- struct netlink_ring *ring;
- struct sock *sk;
-
- /* If a packet from the kernel to userspace was freed because of an
- * error without being delivered to userspace, the kernel must reset
- * the status. In the direction userspace to kernel, the status is
- * always reset here after the packet was processed and freed.
- */
- if (netlink_skb_is_mmaped(skb)) {
- hdr = netlink_mmap_hdr(skb);
- sk = NETLINK_CB(skb).sk;
-
- if (NETLINK_CB(skb).flags & NETLINK_SKB_TX) {
- netlink_set_status(hdr, NL_MMAP_STATUS_UNUSED);
- ring = &nlk_sk(sk)->tx_ring;
- } else {
- if (!(NETLINK_CB(skb).flags & NETLINK_SKB_DELIVERED)) {
- hdr->nm_len = 0;
- netlink_set_status(hdr, NL_MMAP_STATUS_VALID);
- }
- ring = &nlk_sk(sk)->rx_ring;
- }
-
- WARN_ON(atomic_read(&ring->pending) == 0);
- atomic_dec(&ring->pending);
- sock_put(sk);
-
- skb->head = NULL;
- }
-#endif
if (is_vmalloc_addr(skb->head)) {
if (!skb->cloned ||
!atomic_dec_return(&(skb_shinfo(skb)->dataref)))
@@ -918,18 +327,6 @@ static void netlink_sock_destruct(struct
}

skb_queue_purge(&sk->sk_receive_queue);
-#ifdef CONFIG_NETLINK_MMAP
- if (1) {
- struct nl_mmap_req req;
-
- memset(&req, 0, sizeof(req));
- if (nlk->rx_ring.pg_vec)
- __netlink_set_ring(sk, &req, false, NULL, 0);
- memset(&req, 0, sizeof(req));
- if (nlk->tx_ring.pg_vec)
- __netlink_set_ring(sk, &req, true, NULL, 0);
- }
-#endif /* CONFIG_NETLINK_MMAP */

if (!sock_flag(sk, SOCK_DEAD)) {
printk(KERN_ERR "Freeing alive netlink socket %p\n", sk);
@@ -1202,9 +599,6 @@ static int __netlink_create(struct net *
mutex_init(nlk->cb_mutex);
}
init_waitqueue_head(&nlk->wait);
-#ifdef CONFIG_NETLINK_MMAP
- mutex_init(&nlk->pg_vec_lock);
-#endif

sk->sk_destruct = netlink_sock_destruct;
sk->sk_protocol = protocol;
@@ -1708,8 +1102,7 @@ int netlink_attachskb(struct sock *sk, s
nlk = nlk_sk(sk);

if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
- test_bit(NETLINK_CONGESTED, &nlk->state)) &&
- !netlink_skb_is_mmaped(skb)) {
+ test_bit(NETLINK_CONGESTED, &nlk->state))) {
DECLARE_WAITQUEUE(wait, current);
if (!*timeo) {
if (!ssk || netlink_is_kernel(ssk))
@@ -1747,14 +1140,7 @@ static int __netlink_sendskb(struct sock

netlink_deliver_tap(skb);

-#ifdef CONFIG_NETLINK_MMAP
- if (netlink_skb_is_mmaped(skb))
- netlink_queue_mmaped_skb(sk, skb);
- else if (netlink_rx_is_mmaped(sk))
- netlink_ring_set_copied(sk, skb);
- else
-#endif /* CONFIG_NETLINK_MMAP */
- skb_queue_tail(&sk->sk_receive_queue, skb);
+ skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk);
return len;
}
@@ -1778,9 +1164,6 @@ static struct sk_buff *netlink_trim(stru
int delta;

WARN_ON(skb->sk != NULL);
- if (netlink_skb_is_mmaped(skb))
- return skb;
-
delta = skb->end - skb->tail;
if (is_vmalloc_addr(skb->head) || delta * 2 < skb->truesize)
return skb;
@@ -1860,71 +1243,6 @@ struct sk_buff *__netlink_alloc_skb(stru
unsigned int ldiff, u32 dst_portid,
gfp_t gfp_mask)
{
-#ifdef CONFIG_NETLINK_MMAP
- unsigned int maxlen, linear_size;
- struct sock *sk = NULL;
- struct sk_buff *skb;
- struct netlink_ring *ring;
- struct nl_mmap_hdr *hdr;
-
- sk = netlink_getsockbyportid(ssk, dst_portid);
- if (IS_ERR(sk))
- goto out;
-
- ring = &nlk_sk(sk)->rx_ring;
- /* fast-path without atomic ops for common case: non-mmaped receiver */
- if (ring->pg_vec == NULL)
- goto out_put;
-
- /* We need to account the full linear size needed as a ring
- * slot cannot have non-linear parts.
- */
- linear_size = size + ldiff;
- if (ring->frame_size - NL_MMAP_HDRLEN < linear_size)
- goto out_put;
-
- skb = alloc_skb_head(gfp_mask);
- if (skb == NULL)
- goto err1;
-
- spin_lock_bh(&sk->sk_receive_queue.lock);
- /* check again under lock */
- if (ring->pg_vec == NULL)
- goto out_free;
-
- /* check again under lock */
- maxlen = ring->frame_size - NL_MMAP_HDRLEN;
- if (maxlen < linear_size)
- goto out_free;
-
- netlink_forward_ring(ring);
- hdr = netlink_current_frame(ring, NL_MMAP_STATUS_UNUSED);
- if (hdr == NULL)
- goto err2;
-
- netlink_ring_setup_skb(skb, sk, ring, hdr);
- netlink_set_status(hdr, NL_MMAP_STATUS_RESERVED);
- atomic_inc(&ring->pending);
- netlink_increment_head(ring);
-
- spin_unlock_bh(&sk->sk_receive_queue.lock);
- return skb;
-
-err2:
- kfree_skb(skb);
- spin_unlock_bh(&sk->sk_receive_queue.lock);
- netlink_overrun(sk);
-err1:
- sock_put(sk);
- return NULL;
-
-out_free:
- kfree_skb(skb);
- spin_unlock_bh(&sk->sk_receive_queue.lock);
-out_put:
- sock_put(sk);
-out:
-#endif
return alloc_skb(size, gfp_mask);
}
EXPORT_SYMBOL_GPL(__netlink_alloc_skb);
@@ -2189,8 +1507,7 @@ static int netlink_setsockopt(struct soc
if (level != SOL_NETLINK)
return -ENOPROTOOPT;

- if (optname != NETLINK_RX_RING && optname != NETLINK_TX_RING &&
- optlen >= sizeof(int) &&
+ if (optlen >= sizeof(int) &&
get_user(val, (unsigned int __user *)optval))
return -EFAULT;

@@ -2243,25 +1560,6 @@ static int netlink_setsockopt(struct soc
}
err = 0;
break;
-#ifdef CONFIG_NETLINK_MMAP
- case NETLINK_RX_RING:
- case NETLINK_TX_RING: {
- struct nl_mmap_req req;
-
- /* Rings might consume more memory than queue limits, require
- * CAP_NET_ADMIN.
- */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (optlen < sizeof(req))
- return -EINVAL;
- if (copy_from_user(&req, optval, sizeof(req)))
- return -EFAULT;
- err = netlink_set_ring(sk, &req,
- optname == NETLINK_TX_RING);
- break;
- }
-#endif /* CONFIG_NETLINK_MMAP */
default:
err = -ENOPROTOOPT;
}
@@ -2374,13 +1672,6 @@ static int netlink_sendmsg(struct kiocb
goto out;
}

- if (netlink_tx_is_mmaped(sk) &&
- msg->msg_iov->iov_base == NULL) {
- err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group,
- siocb);
- goto out;
- }
-
err = -EMSGSIZE;
if (len > sk->sk_sndbuf - 32)
goto out;
@@ -2704,8 +1995,7 @@ static int netlink_dump(struct sock *sk)
goto errout_skb;
}

- if (!netlink_rx_is_mmaped(sk) &&
- atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
+ if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
goto errout_skb;

/* NLMSG_GOODSIZE is small to avoid high order allocations being
@@ -2740,8 +2030,7 @@ static int netlink_dump(struct sock *sk)
* reasonable static buffer based on the expected largest dump of a
* single netdev. The outcome is MSG_TRUNC error.
*/
- if (!netlink_rx_is_mmaped(sk))
- skb_reserve(skb, skb_tailroom(skb) - alloc_size);
+ skb_reserve(skb, skb_tailroom(skb) - alloc_size);
netlink_skb_set_owner_r(skb, sk);

len = cb->dump(skb, cb);
@@ -2795,16 +2084,7 @@ int __netlink_dump_start(struct sock *ss
struct netlink_sock *nlk;
int ret;

- /* Memory mapped dump requests need to be copied to avoid looping
- * on the pending state in netlink_mmap_sendmsg() while the CB hold
- * a reference to the skb.
- */
- if (netlink_skb_is_mmaped(skb)) {
- skb = skb_copy(skb, GFP_KERNEL);
- if (skb == NULL)
- return -ENOBUFS;
- } else
- atomic_inc(&skb->users);
+ atomic_inc(&skb->users);

sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).portid);
if (sk == NULL) {
@@ -3140,7 +2420,7 @@ static const struct proto_ops netlink_op
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.getname = netlink_getname,
- .poll = netlink_poll,
+ .poll = datagram_poll,
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
@@ -3148,7 +2428,7 @@ static const struct proto_ops netlink_op
.getsockopt = netlink_getsockopt,
.sendmsg = netlink_sendmsg,
.recvmsg = netlink_recvmsg,
- .mmap = netlink_mmap,
+ .mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
};

--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -41,12 +41,6 @@ struct netlink_sock {
int (*netlink_bind)(int group);
void (*netlink_unbind)(int group);
struct module *module;
-#ifdef CONFIG_NETLINK_MMAP
- struct mutex pg_vec_lock;
- struct netlink_ring rx_ring;
- struct netlink_ring tx_ring;
- atomic_t mapped;
-#endif /* CONFIG_NETLINK_MMAP */
};

static inline struct netlink_sock *nlk_sk(struct sock *sk)
@@ -67,15 +61,6 @@ struct nl_portid_hash {
u32 rnd;
};

-static inline bool netlink_skb_is_mmaped(const struct sk_buff *skb)
-{
-#ifdef CONFIG_NETLINK_MMAP
- return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
-#else
- return false;
-#endif /* CONFIG_NETLINK_MMAP */
-}
-
struct netlink_table {
struct nl_portid_hash hash;
struct hlist_head mc_list;
--- a/net/netlink/diag.c
+++ b/net/netlink/diag.c
@@ -7,41 +7,6 @@

#include "af_netlink.h"

-#ifdef CONFIG_NETLINK_MMAP
-static int sk_diag_put_ring(struct netlink_ring *ring, int nl_type,
- struct sk_buff *nlskb)
-{
- struct netlink_diag_ring ndr;
-
- ndr.ndr_block_size = ring->pg_vec_pages << PAGE_SHIFT;
- ndr.ndr_block_nr = ring->pg_vec_len;
- ndr.ndr_frame_size = ring->frame_size;
- ndr.ndr_frame_nr = ring->frame_max + 1;
-
- return nla_put(nlskb, nl_type, sizeof(ndr), &ndr);
-}
-
-static int sk_diag_put_rings_cfg(struct sock *sk, struct sk_buff *nlskb)
-{
- struct netlink_sock *nlk = nlk_sk(sk);
- int ret;
-
- mutex_lock(&nlk->pg_vec_lock);
- ret = sk_diag_put_ring(&nlk->rx_ring, NETLINK_DIAG_RX_RING, nlskb);
- if (!ret)
- ret = sk_diag_put_ring(&nlk->tx_ring, NETLINK_DIAG_TX_RING,
- nlskb);
- mutex_unlock(&nlk->pg_vec_lock);
-
- return ret;
-}
-#else
-static int sk_diag_put_rings_cfg(struct sock *sk, struct sk_buff *nlskb)
-{
- return 0;
-}
-#endif
-
static int sk_diag_dump_groups(struct sock *sk, struct sk_buff *nlskb)
{
struct netlink_sock *nlk = nlk_sk(sk);
@@ -86,10 +51,6 @@ static int sk_diag_fill(struct sock *sk,
sock_diag_put_meminfo(sk, skb, NETLINK_DIAG_MEMINFO))
goto out_nlmsg_trim;

- if ((req->ndiag_show & NDIAG_SHOW_RING_CFG) &&
- sk_diag_put_rings_cfg(sk, skb))
- goto out_nlmsg_trim;
-
return nlmsg_end(skb, nlh);

out_nlmsg_trim:

2017-04-01 13:23:48

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 12/19] serial: samsung: Use %pa to print 'resource_size_t' type

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Fabio Estevam <[email protected]>

commit 1ff5b64dccbf23acfe7993b9132b6992922a4756 upstream.

When building multi_v7_defconfig with CONFIG_ARM_LPAE=y the following warning
is seen:

drivers/tty/serial/samsung.c: In function 's3c24xx_serial_init_port':
drivers/tty/serial/samsung.c:1229:2: warning: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'resource_size_t' [-Wformat]

Use %pa to print 'resource_size_t' type to fix the warning.

Reported-by: Olof's autobuilder <[email protected]>
Signed-off-by: Fabio Estevam <[email protected]>
Reviewed-by: Jingoo Han <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
drivers/tty/serial/samsung.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -1231,8 +1231,8 @@ static int s3c24xx_serial_init_port(stru
wr_regl(port, S3C64XX_UINTSP, 0xf);
}

- dbg("port: map=%08x, mem=%p, irq=%d (%d,%d), clock=%u\n",
- port->mapbase, port->membase, port->irq,
+ dbg("port: map=%pa, mem=%p, irq=%d (%d,%d), clock=%u\n",
+ &port->mapbase, port->membase, port->irq,
ourport->rx_irq, ourport->tx_irq, port->uartclk);

/* reset the fifos (and setup the uart) */

2017-04-01 13:24:57

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 15/19] HID: hid-input: Add parentheses to quell gcc warning

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: James C Boyd <[email protected]>

commit 09a5c34e8d6b05663ec4c3d22b1fbd9fec89aaf9 upstream.

GCC reports a -Wlogical-not-parentheses warning here; therefore
add parentheses to shut it up and to express our intent more.

Signed-off-by: James C Boyd <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
drivers/hid/hid-input.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1119,7 +1119,7 @@ void hidinput_hid_event(struct hid_devic
return;

/* report the usage code as scancode if the key status has changed */
- if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
+ if (usage->type == EV_KEY && (!!test_bit(usage->code, input->key)) != value)
input_event(input, EV_MSC, MSC_SCAN, usage->hid);

input_event(input, usage->type, usage->code, value);

2017-04-01 13:24:55

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 07/19] MIPS: Fix build with binutils 2.24.51+

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Manuel Lauss <[email protected]>

commit 842dfc11ea9a21f9825167c8a4f2834b205b0a79 upstream.

Starting with version 2.24.51.20140728 MIPS binutils complain loudly
about mixing soft-float and hard-float object files, leading to this
build failure since GCC is invoked with "-msoft-float" on MIPS:

{standard input}: Warning: .gnu_attribute 4,3 requires `softfloat'
LD arch/mips/alchemy/common/built-in.o
mipsel-softfloat-linux-gnu-ld: Warning: arch/mips/alchemy/common/built-in.o
uses -msoft-float (set by arch/mips/alchemy/common/prom.o),
arch/mips/alchemy/common/sleeper.o uses -mhard-float

To fix this, we detect if GAS is new enough to support "-msoft-float" command
option, and if it does, we can let GCC pass it to GAS; but then we also need
to sprinkle the files which make use of floating point registers with the
necessary ".set hardfloat" directives.

Signed-off-by: Manuel Lauss <[email protected]>
Cc: Linux-MIPS <[email protected]>
Cc: Matthew Fortune <[email protected]>
Cc: Markos Chandras <[email protected]>
Cc: Maciej W. Rozycki <[email protected]>
Patchwork: https://patchwork.linux-mips.org/patch/8355/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
arch/mips/Makefile | 9 +++++++++
arch/mips/include/asm/asmmacro-32.h | 6 ++++++
arch/mips/include/asm/asmmacro.h | 18 ++++++++++++++++++
arch/mips/include/asm/fpregdef.h | 14 ++++++++++++++
arch/mips/include/asm/fpu.h | 4 ++--
arch/mips/include/asm/mipsregs.h | 11 ++++++++++-
arch/mips/kernel/branch.c | 8 ++------
arch/mips/kernel/genex.S | 1 +
arch/mips/kernel/r2300_fpu.S | 6 ++++++
arch/mips/kernel/r2300_switch.S | 5 +++++
arch/mips/kernel/r4k_fpu.S | 27 +++++++++++++++++++++++++--
arch/mips/kernel/r4k_switch.S | 15 ++++++++++++++-
arch/mips/kernel/r6000_fpu.S | 5 +++++
arch/mips/math-emu/cp1emu.c | 6 +-----
14 files changed, 118 insertions(+), 17 deletions(-)

--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -93,6 +93,15 @@ LDFLAGS_vmlinux += -G 0 -static -n -no
KBUILD_AFLAGS_MODULE += -mlong-calls
KBUILD_CFLAGS_MODULE += -mlong-calls

+#
+# pass -msoft-float to GAS if it supports it. However on newer binutils
+# (specifically newer than 2.24.51.20140728) we then also need to explicitly
+# set ".set hardfloat" in all files which manipulate floating point registers.
+#
+ifneq ($(call as-option,-Wa$(comma)-msoft-float,),)
+ cflags-y += -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float
+endif
+
cflags-y += -ffreestanding

#
--- a/arch/mips/include/asm/asmmacro-32.h
+++ b/arch/mips/include/asm/asmmacro-32.h
@@ -13,6 +13,8 @@
#include <asm/mipsregs.h>

.macro fpu_save_single thread tmp=t0
+ .set push
+ SET_HARDFLOAT
cfc1 \tmp, fcr31
swc1 $f0, THREAD_FPR0_LS64(\thread)
swc1 $f1, THREAD_FPR1_LS64(\thread)
@@ -47,9 +49,12 @@
swc1 $f30, THREAD_FPR30_LS64(\thread)
swc1 $f31, THREAD_FPR31_LS64(\thread)
sw \tmp, THREAD_FCR31(\thread)
+ .set pop
.endm

.macro fpu_restore_single thread tmp=t0
+ .set push
+ SET_HARDFLOAT
lw \tmp, THREAD_FCR31(\thread)
lwc1 $f0, THREAD_FPR0_LS64(\thread)
lwc1 $f1, THREAD_FPR1_LS64(\thread)
@@ -84,6 +89,7 @@
lwc1 $f30, THREAD_FPR30_LS64(\thread)
lwc1 $f31, THREAD_FPR31_LS64(\thread)
ctc1 \tmp, fcr31
+ .set pop
.endm

.macro cpu_save_nonscratch thread
--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -57,6 +57,8 @@
#endif /* CONFIG_CPU_MIPSR2 */

.macro fpu_save_16even thread tmp=t0
+ .set push
+ SET_HARDFLOAT
cfc1 \tmp, fcr31
sdc1 $f0, THREAD_FPR0_LS64(\thread)
sdc1 $f2, THREAD_FPR2_LS64(\thread)
@@ -75,11 +77,13 @@
sdc1 $f28, THREAD_FPR28_LS64(\thread)
sdc1 $f30, THREAD_FPR30_LS64(\thread)
sw \tmp, THREAD_FCR31(\thread)
+ .set pop
.endm

.macro fpu_save_16odd thread
.set push
.set mips64r2
+ SET_HARDFLOAT
sdc1 $f1, THREAD_FPR1_LS64(\thread)
sdc1 $f3, THREAD_FPR3_LS64(\thread)
sdc1 $f5, THREAD_FPR5_LS64(\thread)
@@ -110,6 +114,8 @@
.endm

.macro fpu_restore_16even thread tmp=t0
+ .set push
+ SET_HARDFLOAT
lw \tmp, THREAD_FCR31(\thread)
ldc1 $f0, THREAD_FPR0_LS64(\thread)
ldc1 $f2, THREAD_FPR2_LS64(\thread)
@@ -133,6 +139,7 @@
.macro fpu_restore_16odd thread
.set push
.set mips64r2
+ SET_HARDFLOAT
ldc1 $f1, THREAD_FPR1_LS64(\thread)
ldc1 $f3, THREAD_FPR3_LS64(\thread)
ldc1 $f5, THREAD_FPR5_LS64(\thread)
@@ -277,6 +284,7 @@
.macro cfcmsa rd, cs
.set push
.set noat
+ SET_HARDFLOAT
.insn
.word CFC_MSA_INSN | (\cs << 11)
move \rd, $1
@@ -286,6 +294,7 @@
.macro ctcmsa cd, rs
.set push
.set noat
+ SET_HARDFLOAT
move $1, \rs
.word CTC_MSA_INSN | (\cd << 6)
.set pop
@@ -294,6 +303,7 @@
.macro ld_d wd, off, base
.set push
.set noat
+ SET_HARDFLOAT
addu $1, \base, \off
.word LDD_MSA_INSN | (\wd << 6)
.set pop
@@ -302,6 +312,7 @@
.macro st_d wd, off, base
.set push
.set noat
+ SET_HARDFLOAT
addu $1, \base, \off
.word STD_MSA_INSN | (\wd << 6)
.set pop
@@ -310,6 +321,7 @@
.macro copy_u_w rd, ws, n
.set push
.set noat
+ SET_HARDFLOAT
.insn
.word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
/* move triggers an assembler bug... */
@@ -320,6 +332,7 @@
.macro copy_u_d rd, ws, n
.set push
.set noat
+ SET_HARDFLOAT
.insn
.word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
/* move triggers an assembler bug... */
@@ -330,6 +343,7 @@
.macro insert_w wd, n, rs
.set push
.set noat
+ SET_HARDFLOAT
/* move triggers an assembler bug... */
or $1, \rs, zero
.word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
@@ -339,6 +353,7 @@
.macro insert_d wd, n, rs
.set push
.set noat
+ SET_HARDFLOAT
/* move triggers an assembler bug... */
or $1, \rs, zero
.word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
@@ -381,6 +396,7 @@
st_d 31, THREAD_FPR31, \thread
.set push
.set noat
+ SET_HARDFLOAT
cfcmsa $1, MSA_CSR
sw $1, THREAD_MSA_CSR(\thread)
.set pop
@@ -389,6 +405,7 @@
.macro msa_restore_all thread
.set push
.set noat
+ SET_HARDFLOAT
lw $1, THREAD_MSA_CSR(\thread)
ctcmsa MSA_CSR, $1
.set pop
@@ -441,6 +458,7 @@
.macro msa_init_all_upper
.set push
.set noat
+ SET_HARDFLOAT
not $1, zero
msa_init_upper 0
.set pop
--- a/arch/mips/include/asm/fpregdef.h
+++ b/arch/mips/include/asm/fpregdef.h
@@ -14,6 +14,20 @@

#include <asm/sgidefs.h>

+/*
+ * starting with binutils 2.24.51.20140729, MIPS binutils warn about mixing
+ * hardfloat and softfloat object files. The kernel build uses soft-float by
+ * default, so we also need to pass -msoft-float along to GAS if it supports it.
+ * But this in turn causes assembler errors in files which access hardfloat
+ * registers. We detect if GAS supports "-msoft-float" in the Makefile and
+ * explicitly put ".set hardfloat" where floating point registers are touched.
+ */
+#ifdef GAS_HAS_SET_HARDFLOAT
+#define SET_HARDFLOAT .set hardfloat
+#else
+#define SET_HARDFLOAT
+#endif
+
#if _MIPS_SIM == _MIPS_SIM_ABI32

/*
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -145,8 +145,8 @@ static inline void lose_fpu(int save)
if (is_msa_enabled()) {
if (save) {
save_msa(current);
- asm volatile("cfc1 %0, $31"
- : "=r"(current->thread.fpu.fcr31));
+ current->thread.fpu.fcr31 =
+ read_32bit_cp1_register(CP1_STATUS);
}
disable_msa();
clear_thread_flag(TIF_USEDMSA);
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1270,7 +1270,7 @@ do { \
/*
* Macros to access the floating point coprocessor control registers
*/
-#define read_32bit_cp1_register(source) \
+#define _read_32bit_cp1_register(source, gas_hardfloat) \
({ \
int __res; \
\
@@ -1280,12 +1280,21 @@ do { \
" # gas fails to assemble cfc1 for some archs, \n" \
" # like Octeon. \n" \
" .set mips1 \n" \
+ " "STR(gas_hardfloat)" \n" \
" cfc1 %0,"STR(source)" \n" \
" .set pop \n" \
: "=r" (__res)); \
__res; \
})

+#ifdef GAS_HAS_SET_HARDFLOAT
+#define read_32bit_cp1_register(source) \
+ _read_32bit_cp1_register(source, .set hardfloat)
+#else
+#define read_32bit_cp1_register(source) \
+ _read_32bit_cp1_register(source, )
+#endif
+
#ifdef HAVE_AS_DSP
#define rddsp(mask) \
({ \
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -144,7 +144,7 @@ int __mm_isBranchInstr(struct pt_regs *r
case mm_bc1t_op:
preempt_disable();
if (is_fpu_owner())
- asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+ fcr31 = read_32bit_cp1_register(CP1_STATUS);
else
fcr31 = current->thread.fpu.fcr31;
preempt_enable();
@@ -562,11 +562,7 @@ int __compute_return_epc_for_insn(struct
case cop1_op:
preempt_disable();
if (is_fpu_owner())
- asm volatile(
- ".set push\n"
- "\t.set mips1\n"
- "\tcfc1\t%0,$31\n"
- "\t.set pop" : "=r" (fcr31));
+ fcr31 = read_32bit_cp1_register(CP1_STATUS);
else
fcr31 = current->thread.fpu.fcr31;
preempt_enable();
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -358,6 +358,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
.set push
/* gas fails to assemble cfc1 for some archs (octeon).*/ \
.set mips1
+ SET_HARDFLOAT
cfc1 a1, fcr31
li a2, ~(0x3f << 12)
and a2, a1
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -28,6 +28,8 @@
.set mips1
/* Save floating point context */
LEAF(_save_fp_context)
+ .set push
+ SET_HARDFLOAT
li v0, 0 # assume success
cfc1 t1,fcr31
EX(swc1 $f0,(SC_FPREGS+0)(a0))
@@ -65,6 +67,7 @@ LEAF(_save_fp_context)
EX(sw t1,(SC_FPC_CSR)(a0))
cfc1 t0,$0 # implementation/version
jr ra
+ .set pop
.set nomacro
EX(sw t0,(SC_FPC_EIR)(a0))
.set macro
@@ -80,6 +83,8 @@ LEAF(_save_fp_context)
* stack frame which might have been changed by the user.
*/
LEAF(_restore_fp_context)
+ .set push
+ SET_HARDFLOAT
li v0, 0 # assume success
EX(lw t0,(SC_FPC_CSR)(a0))
EX(lwc1 $f0,(SC_FPREGS+0)(a0))
@@ -116,6 +121,7 @@ LEAF(_restore_fp_context)
EX(lwc1 $f31,(SC_FPREGS+248)(a0))
jr ra
ctc1 t0,fcr31
+ .set pop
END(_restore_fp_context)
.set reorder

--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -120,6 +120,9 @@ LEAF(_restore_fp)

#define FPU_DEFAULT 0x00000000

+ .set push
+ SET_HARDFLOAT
+
LEAF(_init_fpu)
mfc0 t0, CP0_STATUS
li t1, ST0_CU1
@@ -165,3 +168,5 @@ LEAF(_init_fpu)
mtc1 t0, $f31
jr ra
END(_init_fpu)
+
+ .set pop
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -19,8 +19,12 @@
#include <asm/asm-offsets.h>
#include <asm/regdef.h>

+/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
+#undef fp
+
.macro EX insn, reg, src
.set push
+ SET_HARDFLOAT
.set nomacro
.ex\@: \insn \reg, \src
.set pop
@@ -33,12 +37,17 @@
.set arch=r4000

LEAF(_save_fp_context)
+ .set push
+ SET_HARDFLOAT
cfc1 t1, fcr31
+ .set pop

#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
.set push
+ SET_HARDFLOAT
#ifdef CONFIG_CPU_MIPS32_R2
- .set mips64r2
+ .set mips32r2
+ .set fp=64
mfc0 t0, CP0_STATUS
sll t0, t0, 5
bgez t0, 1f # skip storing odd if FR=0
@@ -64,6 +73,8 @@ LEAF(_save_fp_context)
1: .set pop
#endif

+ .set push
+ SET_HARDFLOAT
/* Store the 16 even double precision registers */
EX sdc1 $f0, SC_FPREGS+0(a0)
EX sdc1 $f2, SC_FPREGS+16(a0)
@@ -84,11 +95,14 @@ LEAF(_save_fp_context)
EX sw t1, SC_FPC_CSR(a0)
jr ra
li v0, 0 # success
+ .set pop
END(_save_fp_context)

#ifdef CONFIG_MIPS32_COMPAT
/* Save 32-bit process floating point context */
LEAF(_save_fp_context32)
+ .set push
+ SET_HARDFLOAT
cfc1 t1, fcr31

mfc0 t0, CP0_STATUS
@@ -134,6 +148,7 @@ LEAF(_save_fp_context32)
EX sw t1, SC32_FPC_CSR(a0)
cfc1 t0, $0 # implementation/version
EX sw t0, SC32_FPC_EIR(a0)
+ .set pop

jr ra
li v0, 0 # success
@@ -150,8 +165,10 @@ LEAF(_restore_fp_context)

#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
.set push
+ SET_HARDFLOAT
#ifdef CONFIG_CPU_MIPS32_R2
- .set mips64r2
+ .set mips32r2
+ .set fp=64
mfc0 t0, CP0_STATUS
sll t0, t0, 5
bgez t0, 1f # skip loading odd if FR=0
@@ -175,6 +192,8 @@ LEAF(_restore_fp_context)
EX ldc1 $f31, SC_FPREGS+248(a0)
1: .set pop
#endif
+ .set push
+ SET_HARDFLOAT
EX ldc1 $f0, SC_FPREGS+0(a0)
EX ldc1 $f2, SC_FPREGS+16(a0)
EX ldc1 $f4, SC_FPREGS+32(a0)
@@ -192,6 +211,7 @@ LEAF(_restore_fp_context)
EX ldc1 $f28, SC_FPREGS+224(a0)
EX ldc1 $f30, SC_FPREGS+240(a0)
ctc1 t1, fcr31
+ .set pop
jr ra
li v0, 0 # success
END(_restore_fp_context)
@@ -199,6 +219,8 @@ LEAF(_restore_fp_context)
#ifdef CONFIG_MIPS32_COMPAT
LEAF(_restore_fp_context32)
/* Restore an o32 sigcontext. */
+ .set push
+ SET_HARDFLOAT
EX lw t1, SC32_FPC_CSR(a0)

mfc0 t0, CP0_STATUS
@@ -242,6 +264,7 @@ LEAF(_restore_fp_context32)
ctc1 t1, fcr31
jr ra
li v0, 0 # success
+ .set pop
END(_restore_fp_context32)
#endif

--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -22,6 +22,9 @@

#include <asm/asmmacro.h>

+/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
+#undef fp
+
/*
* Offset to the current process status flags, the first 32 bytes of the
* stack are not used.
@@ -65,8 +68,12 @@
bgtz a3, 1f

/* Save 128b MSA vector context + scalar FP control & status. */
+ .set push
+ SET_HARDFLOAT
cfc1 t1, fcr31
msa_save_all a0
+ .set pop /* SET_HARDFLOAT */
+
sw t1, THREAD_FCR31(a0)
b 2f

@@ -161,6 +168,9 @@ LEAF(_init_msa_upper)

#define FPU_DEFAULT 0x00000000

+ .set push
+ SET_HARDFLOAT
+
LEAF(_init_fpu)
mfc0 t0, CP0_STATUS
li t1, ST0_CU1
@@ -232,7 +242,8 @@ LEAF(_init_fpu)

#ifdef CONFIG_CPU_MIPS32_R2
.set push
- .set mips64r2
+ .set mips32r2
+ .set fp=64
sll t0, t0, 5 # is Status.FR set?
bgez t0, 1f # no: skip setting upper 32b

@@ -291,3 +302,5 @@ LEAF(_init_fpu)
#endif
jr ra
END(_init_fpu)
+
+ .set pop /* SET_HARDFLOAT */
--- a/arch/mips/kernel/r6000_fpu.S
+++ b/arch/mips/kernel/r6000_fpu.S
@@ -18,6 +18,9 @@

.set noreorder
.set mips2
+ .set push
+ SET_HARDFLOAT
+
/* Save floating point context */
LEAF(_save_fp_context)
mfc0 t0,CP0_STATUS
@@ -85,3 +88,5 @@
1: jr ra
nop
END(_restore_fp_context)
+
+ .set pop /* SET_HARDFLOAT */
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -586,11 +586,7 @@ static int isBranchInstr(struct pt_regs
if (insn.i_format.rs == bc_op) {
preempt_disable();
if (is_fpu_owner())
- asm volatile(
- ".set push\n"
- "\t.set mips1\n"
- "\tcfc1\t%0,$31\n"
- "\t.set pop" : "=r" (fcr31));
+ fcr31 = read_32bit_cp1_register(CP1_STATUS);
else
fcr31 = current->thread.fpu.fcr31;
preempt_enable();

2017-04-01 13:25:34

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 08/19] atm: iphase: fix misleading indention

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Tillmann Heidsieck <[email protected]>

commit cbb41b91e68a302087762823136c9067138cff7c upstream.

Fix a smatch warning:
drivers/atm/iphase.c:1178 rx_pkt() warn: curly braces intended?

The code is correct, the indention is misleading. In case the allocation
of skb fails, we want to skip to the end.

Signed-off-by: Tillmann Heidsieck <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
drivers/atm/iphase.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -1175,7 +1175,7 @@ static int rx_pkt(struct atm_dev *dev)
if (!(skb = atm_alloc_charge(vcc, len, GFP_ATOMIC))) {
if (vcc->vci < 32)
printk("Drop control packets\n");
- goto out_free_desc;
+ goto out_free_desc;
}
skb_put(skb,len);
// pwang_test

2017-04-01 13:25:31

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 05/19] MIPS: save/disable MSA in lose_fpu

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit 33c771ba5c5d067f85a5a6c4b11047219b5b8f4e upstream.

The kernel depends upon MSA never being enabled when the FPU is not, a
condition which is currently violated in a few places (whilst saving
sigcontext, following mips_cpu_save). Catch all the problem cases by
disabling MSA in lose_fpu, after saving context if necessary.

Signed-off-by: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/7302/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
arch/mips/include/asm/fpu.h | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)

--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -21,6 +21,7 @@
#include <asm/hazards.h>
#include <asm/processor.h>
#include <asm/current.h>
+#include <asm/msa.h>

#ifdef CONFIG_MIPS_MT_FPAFF
#include <asm/mips_mt.h>
@@ -141,13 +142,21 @@ static inline int own_fpu(int restore)
static inline void lose_fpu(int save)
{
preempt_disable();
- if (is_fpu_owner()) {
+ if (is_msa_enabled()) {
+ if (save) {
+ save_msa(current);
+ asm volatile("cfc1 %0, $31"
+ : "=r"(current->thread.fpu.fcr31));
+ }
+ disable_msa();
+ clear_thread_flag(TIF_USEDMSA);
+ } else if (is_fpu_owner()) {
if (save)
_save_fp(current);
- KSTK_STATUS(current) &= ~ST0_CU1;
- clear_thread_flag(TIF_USEDFPU);
__disable_fpu();
}
+ KSTK_STATUS(current) &= ~ST0_CU1;
+ clear_thread_flag(TIF_USEDFPU);
preempt_enable();
}


2017-04-01 13:25:32

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 03/19] MIPS: save/restore MSACSR register on context switch

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit f7a46fa7bb0047d3e226702a0c4b786862fe6843 upstream.

I added a field for the MSACSR register in struct mips_fpu_struct, but
never actually made use of it... This is a clear bug. Save and restore
the MSACSR register along with the vector registers.

Signed-off-by: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/7300/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
arch/mips/include/asm/asmmacro.h | 11 +++++++++++
arch/mips/kernel/asm-offsets.c | 1 +
2 files changed, 12 insertions(+)

--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -10,6 +10,7 @@

#include <asm/hazards.h>
#include <asm/asm-offsets.h>
+#include <asm/msa.h>

#ifdef CONFIG_32BIT
#include <asm/asmmacro-32.h>
@@ -378,9 +379,19 @@
st_d 29, THREAD_FPR29, \thread
st_d 30, THREAD_FPR30, \thread
st_d 31, THREAD_FPR31, \thread
+ .set push
+ .set noat
+ cfcmsa $1, MSA_CSR
+ sw $1, THREAD_MSA_CSR(\thread)
+ .set pop
.endm

.macro msa_restore_all thread
+ .set push
+ .set noat
+ lw $1, THREAD_MSA_CSR(\thread)
+ ctcmsa MSA_CSR, $1
+ .set pop
ld_d 0, THREAD_FPR0, \thread
ld_d 1, THREAD_FPR1, \thread
ld_d 2, THREAD_FPR2, \thread
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -234,6 +234,7 @@ void output_thread_fpu_defines(void)
thread.fpu.fpr[31].val64[FPR_IDX(64, 0)]);

OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31);
+ OFFSET(THREAD_MSA_CSR, task_struct, thread.fpu.msacsr);
BLANK();
}


2017-04-01 13:25:29

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 11/19] mmc: sunxi: avoid invalid pointer calculation

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Arnd Bergmann <[email protected]>

commit d34712d2e3db9b241d0484a6e3839c6b7ef9df78 upstream.

The sunxi mmc driver tries to calculate a dma address by using pointer
arithmetic, which causes a warning when dma_addr_t is wider than a pointer:

drivers/mmc/host/sunxi-mmc.c: In function 'sunxi_mmc_init_idma_des':
drivers/mmc/host/sunxi-mmc.c:296:35: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
struct sunxi_idma_des *pdes_pa = (struct sunxi_idma_des *)host->sg_dma;
^

To avoid this warning and to simplify the logic, this changes
the code to avoid the cast and calculate the correct address
manually. The behavior should be unchanged.

Signed-off-by: Arnd Bergmann <[email protected]>
Acked-by: David Lanzendörfer <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
drivers/mmc/host/sunxi-mmc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -294,7 +294,7 @@ static void sunxi_mmc_init_idma_des(stru
struct mmc_data *data)
{
struct sunxi_idma_des *pdes = (struct sunxi_idma_des *)host->sg_cpu;
- struct sunxi_idma_des *pdes_pa = (struct sunxi_idma_des *)host->sg_dma;
+ dma_addr_t next_desc = host->sg_dma;
int i, max_len = (1 << host->idma_des_size_bits);

for (i = 0; i < data->sg_len; i++) {
@@ -306,8 +306,9 @@ static void sunxi_mmc_init_idma_des(stru
else
pdes[i].buf_size = data->sg[i].length;

+ next_desc += sizeof(struct sunxi_idma_des);
pdes[i].buf_addr_ptr1 = sg_dma_address(&data->sg[i]);
- pdes[i].buf_addr_ptr2 = (u32)&pdes_pa[i + 1];
+ pdes[i].buf_addr_ptr2 = (u32)next_desc;
}

pdes[0].config |= SDXC_IDMAC_DES0_FD;

2017-04-01 13:25:28

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 04/19] MIPS: preserve scalar FP CSR when switching vector context

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit b83406735a4ae0aff4b614664d6a64a0fd6b9917 upstream.

Switching the vector context implicitly saves & restores the state of
the aliased scalar FP data registers, however the scalar FP control
& status register is distinct from the MSA control & status register.
In order to allow scalar FP to function correctly in programs using
MSA, the scalar CSR needs to be saved & restored along with the MSA
vector context.

Signed-off-by: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/7301/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
arch/mips/kernel/r4k_switch.S | 4 +++-
arch/mips/kernel/traps.c | 5 +++++
2 files changed, 8 insertions(+), 1 deletion(-)

--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -64,8 +64,10 @@
/* Check whether we're saving scalar or vector context. */
bgtz a3, 1f

- /* Save 128b MSA vector context. */
+ /* Save 128b MSA vector context + scalar FP control & status. */
+ cfc1 t1, fcr31
msa_save_all a0
+ sw t1, THREAD_FCR31(a0)
b 2f

1: /* Save 32b/64b scalar FP context. */
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1159,6 +1159,11 @@ static int enable_restore_fp_context(int

/* We need to restore the vector context. */
restore_msa(current);
+
+ /* Restore the scalar FP control & status register */
+ if (!was_fpu_owner)
+ asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31));
+
return 0;
}


2017-04-01 13:25:26

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 18/19] aio: mark AIO pseudo-fs noexec

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Jann Horn <[email protected]>

commit 22f6b4d34fcf039c63a94e7670e0da24f8575a5a upstream.

This ensures that do_mmap() won't implicitly make AIO memory mappings
executable if the READ_IMPLIES_EXEC personality flag is set. Such
behavior is problematic because the security_mmap_file LSM hook doesn't
catch this case, potentially permitting an attacker to bypass a W^X
policy enforced by SELinux.

I have tested the patch on my machine.

To test the behavior, compile and run this:

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/personality.h>
#include <linux/aio_abi.h>
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/syscall.h>

int main(void) {
personality(READ_IMPLIES_EXEC);
aio_context_t ctx = 0;
if (syscall(__NR_io_setup, 1, &ctx))
err(1, "io_setup");

char cmd[1000];
sprintf(cmd, "cat /proc/%d/maps | grep -F '/[aio]'",
(int)getpid());
system(cmd);
return 0;
}

In the output, "rw-s" is good, "rwxs" is bad.

Signed-off-by: Jann Horn <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
[bwh: Backported to 3.16: we don't have super_block::s_iflags; use
file_system_type::fs_flags instead]
Signed-off-by: Ben Hutchings <[email protected]>
---
fs/aio.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

--- a/fs/aio.c
+++ b/fs/aio.c
@@ -226,6 +226,7 @@ static int __init aio_setup(void)
.name = "aio",
.mount = aio_mount,
.kill_sb = kill_anon_super,
+ .fs_flags = FS_NOEXEC,
};
aio_mnt = kern_mount(&aio_fs);
if (IS_ERR(aio_mnt))

2017-04-01 13:25:25

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 14/19] MIPS: Zero variable read by get_user / __get_user in case of an error.

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Ralf Baechle <[email protected]>

commit 640465bda58c7078725201be7430c31a349121e9 upstream.

This wasn't happening in all cases.

Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
arch/mips/include/asm/uaccess.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -302,7 +302,8 @@ do { \
__get_kernel_common((x), size, __gu_ptr); \
else \
__get_user_common((x), size, __gu_ptr); \
- } \
+ } else \
+ (x) = 0; \
\
__gu_err; \
})
@@ -317,6 +318,7 @@ do { \
" .insn \n" \
" .section .fixup,\"ax\" \n" \
"3: li %0, %4 \n" \
+ " move %1, $0 \n" \
" j 2b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
@@ -631,6 +633,7 @@ do { \
" .insn \n" \
" .section .fixup,\"ax\" \n" \
"3: li %0, %4 \n" \
+ " move %1, $0 \n" \
" j 2b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \

2017-04-01 13:26:59

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 01/19] fs: namespace: suppress 'may be used uninitialized' warnings

3.16.43-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Tim Gardner <[email protected]>

commit b8850d1fa8e2f6653e57daf6d08e58c5f5eb2c85 upstream.

The gcc version 4.9.1 compiler complains Even though it isn't possible for
these variables to not get initialized before they are used.

fs/namespace.c: In function ‘SyS_mount’:
fs/namespace.c:2720:8: warning: ‘kernel_dev’ may be used uninitialized in this function [-Wmaybe-uninitialized]
ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags,
^
fs/namespace.c:2699:8: note: ‘kernel_dev’ was declared here
char *kernel_dev;
^
fs/namespace.c:2720:8: warning: ‘kernel_type’ may be used uninitialized in this function [-Wmaybe-uninitialized]
ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags,
^
fs/namespace.c:2697:8: note: ‘kernel_type’ was declared here
char *kernel_type;
^

Fix the warnings by simplifying copy_mount_string() as suggested by Al Viro.

Cc: Alexander Viro <[email protected]>
Signed-off-by: Tim Gardner <[email protected]>
Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
fs/compat.c | 10 ++++++----
fs/internal.h | 2 +-
fs/namespace.c | 26 ++++++++------------------
3 files changed, 15 insertions(+), 23 deletions(-)

--- a/fs/compat.c
+++ b/fs/compat.c
@@ -797,8 +797,9 @@ COMPAT_SYSCALL_DEFINE5(mount, const char
struct filename *dir;
int retval;

- retval = copy_mount_string(type, &kernel_type);
- if (retval < 0)
+ kernel_type = copy_mount_string(type);
+ retval = PTR_ERR(kernel_type);
+ if (IS_ERR(kernel_type))
goto out;

dir = getname(dir_name);
@@ -806,8 +807,9 @@ COMPAT_SYSCALL_DEFINE5(mount, const char
if (IS_ERR(dir))
goto out1;

- retval = copy_mount_string(dev_name, &kernel_dev);
- if (retval < 0)
+ kernel_dev = copy_mount_string(dev_name);
+ retval = PTR_ERR(kernel_dev);
+ if (IS_ERR(kernel_dev))
goto out2;

retval = copy_mount_options(data, &data_page);
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -51,7 +51,7 @@ extern int vfs_path_lookup(struct dentry
* namespace.c
*/
extern int copy_mount_options(const void __user *, unsigned long *);
-extern int copy_mount_string(const void __user *, char **);
+extern char *copy_mount_string(const void __user *);

extern struct vfsmount *lookup_mnt(struct path *);
extern int finish_automount(struct vfsmount *, struct path *);
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2482,21 +2482,9 @@ int copy_mount_options(const void __user
return 0;
}

-int copy_mount_string(const void __user *data, char **where)
+char *copy_mount_string(const void __user *data)
{
- char *tmp;
-
- if (!data) {
- *where = NULL;
- return 0;
- }
-
- tmp = strndup_user(data, PAGE_SIZE);
- if (IS_ERR(tmp))
- return PTR_ERR(tmp);
-
- *where = tmp;
- return 0;
+ return data ? strndup_user(data, PAGE_SIZE) : NULL;
}

/*
@@ -2766,8 +2754,9 @@ SYSCALL_DEFINE5(mount, char __user *, de
char *kernel_dev;
unsigned long data_page;

- ret = copy_mount_string(type, &kernel_type);
- if (ret < 0)
+ kernel_type = copy_mount_string(type);
+ ret = PTR_ERR(kernel_type);
+ if (IS_ERR(kernel_type))
goto out_type;

kernel_dir = getname(dir_name);
@@ -2776,8 +2765,9 @@ SYSCALL_DEFINE5(mount, char __user *, de
goto out_dir;
}

- ret = copy_mount_string(dev_name, &kernel_dev);
- if (ret < 0)
+ kernel_dev = copy_mount_string(dev_name);
+ ret = PTR_ERR(kernel_dev);
+ if (IS_ERR(kernel_dev))
goto out_dev;

ret = copy_mount_options(data, &data_page);

2017-04-01 17:44:04

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 3.16 00/19] 3.16.43-rc1 review

On 04/01/2017 06:17 AM, Ben Hutchings wrote:
> This is the start of the stable review cycle for the 3.16.43 release.
> There are 19 patches in this series, which will be posted as responses
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Tue Apr 04 00:00:00 UTC 2017.
> Anything received after that time might be too late.
>

Build results:
total: 140 pass: 126 fail: 14
Failed builds:
binutils 2.22:
mips:defconfig
mips:allnoconfig
binutils 2.24:
mips:defconfig
mips:allmodconfig
mips:allnoconfig
mips:bcm47xx_defconfig
mips:bcm63xx_defconfig
mips:nlm_xlp_defconfig
mips:ath79_defconfig
mips:ar7_defconfig
mips:e55_defconfig
mips:cavium_octeon_defconfig
mips:malta_defconfig
mips:rt305x_defconfig

Qemu test results:
total: 107 pass: 98 fail: 9
Failed tests:
mips:malta_defconfig:nosmp
mips:malta_defconfig:smp
mips64:malta_defconfig:nosmp
mips64:malta_defconfig:smp
mipsel:24Kf:malta_defconfig:nosmp
mipsel:24Kf:malta_defconfig:smp
mipsel64:malta_defconfig:nosmp
mipsel64:malta_defconfig:smp
mipsel64:fuloong2e_defconfig:fulong2e

I tried to build mips:allnoconfig with the following binutils versions.
They all fail with the same errors.
2.22 (from Poky version 1.3)
2.22 (kernel toolchain, gcc 4.6.3)
2.24 (kernel toolchain, gcc 4.9.0)
2.26.1 (buildroot toolchain, gcc 5.4.0)

Bisect points to commit c4cf8e3a3e8f as the culprit.

Details are available at http://kerneltests.org/builders.
Unfortunately, just reverting this one patch doesn't work.
Reverting

f1ece3b9dd5e MIPS: Fix build with binutils 2.24.51+
f8547d2f97c8 MIPS: init upper 64b of vector registers when MSA is first used
c4cf8e3a3e8f MIPS: save/restore MSACSR register on context switch

fixes the problem, at least for an allnoconfig build with binutils 2.24.

Guenter

2017-04-01 18:52:11

by David Lanzendörfer

[permalink] [raw]
Subject: Re: [PATCH 3.16 11/19] mmc: sunxi: avoid invalid pointer calculation

Hi
> 3.16.43-rc1 review patch. If anyone has any objections, please let me know.
When it has been tested on multiple Allwinner platforms and it has been
working well, then I don't have any objections.
It's actually way more elegant than the thing I did.
Thanks a lot for the improvement!
--
Best regards

CEO, David Lanzend?rfer
Lanceville Technology
22A, Block2, China Phoenix Mansion,
No.2008 Shennan Boulevard,
Futian District, Shenzhen


Attachments:
signature.asc (195.00 B)
This is a digitally signed message part.

2017-04-01 19:53:40

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 3.16 11/19] mmc: sunxi: avoid invalid pointer calculation

On Sun, 2017-04-02 at 02:45 +0800, David Lanzendörfer wrote:
> Hi
> > 3.16.43-rc1 review patch.  If anyone has any objections, please let me know.
>
> When it has been tested on multiple Allwinner platforms and it has been 
> working well, then I don't have any objections.
> It's actually way more elegant than the thing I did.
> Thanks a lot for the improvement!

I'm not in a position to test this, but it was applied upstream over 2
years ago and doesn't appear to have required any follow-up fixes.

Ben.

--
Ben Hutchings
It is easier to change the specification to fit the program than vice
versa.


Attachments:
signature.asc (833.00 B)
This is a digitally signed message part

2017-04-01 22:40:28

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 3.16 00/19] 3.16.43-rc1 review

On Sat, 2017-04-01 at 10:43 -0700, Guenter Roeck wrote:
[snip list of MIPS failures]
> I tried to build mips:allnoconfig with the following binutils versions.
> They all fail with the same errors.
> 2.22 (from Poky version 1.3)
> 2.22 (kernel toolchain, gcc 4.6.3)
> 2.24 (kernel toolchain, gcc 4.9.0)
> 2.26.1 (buildroot toolchain, gcc 5.4.0)
>
> Bisect points to commit c4cf8e3a3e8f as the culprit.
>
> > Details are available at http://kerneltests.org/builders.
> Unfortunately, just reverting this one patch doesn't work.
> Reverting
>
> f1ece3b9dd5e MIPS: Fix build with binutils 2.24.51+
> f8547d2f97c8 MIPS: init upper 64b of vector registers when MSA is first used
> c4cf8e3a3e8f MIPS: save/restore MSACSR register on context switch
>
> fixes the problem, at least for an allnoconfig build with binutils 2.24.

I've now tested with binutils 2.25 and 2.28 and added these:

558155a0a731 MIPS: allow msa.h to be included in assembly files
631afc65e8f4 MIPS: Push .set mips64r* into the functions needing it
f23ce3883a30 MIPS: assume at as source/dest of MSA copy/insert instructions
a3a49810c55e MIPS: remove MSA macro recursion
e1bebbab1eae MIPS: wrap cfcmsa & ctcmsa accesses for toolchains with MSA support

which resolve the build regressions for these versions at least.

I can't build a MIPS allnoconfig with binutils 2.25, but selecting the
Malta platform instead of IP22 works. This is not a regression and is
apparently due to a binutils bug; see commit ae2f5e5ed04a. I could
pick that workaround for the next cycle.

Ben.

--
Ben Hutchings
It is easier to change the specification to fit the program than vice
versa.


Attachments:
signature.asc (833.00 B)
This is a digitally signed message part

2017-04-02 02:21:20

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 3.16 00/19] 3.16.43-rc1 review

On 04/01/2017 03:40 PM, Ben Hutchings wrote:
> On Sat, 2017-04-01 at 10:43 -0700, Guenter Roeck wrote:
> [snip list of MIPS failures]
>> I tried to build mips:allnoconfig with the following binutils versions.
>> They all fail with the same errors.
>> 2.22 (from Poky version 1.3)
>> 2.22 (kernel toolchain, gcc 4.6.3)
>> 2.24 (kernel toolchain, gcc 4.9.0)
>> 2.26.1 (buildroot toolchain, gcc 5.4.0)
>>
>> Bisect points to commit c4cf8e3a3e8f as the culprit.
>>
>>> Details are available at http://kerneltests.org/builders.
>> Unfortunately, just reverting this one patch doesn't work.
>> Reverting
>>
>> f1ece3b9dd5e MIPS: Fix build with binutils 2.24.51+
>> f8547d2f97c8 MIPS: init upper 64b of vector registers when MSA is first used
>> c4cf8e3a3e8f MIPS: save/restore MSACSR register on context switch
>>
>> fixes the problem, at least for an allnoconfig build with binutils 2.24.
>
> I've now tested with binutils 2.25 and 2.28 and added these:
>
> 558155a0a731 MIPS: allow msa.h to be included in assembly files
> 631afc65e8f4 MIPS: Push .set mips64r* into the functions needing it
> f23ce3883a30 MIPS: assume at as source/dest of MSA copy/insert instructions
> a3a49810c55e MIPS: remove MSA macro recursion
> e1bebbab1eae MIPS: wrap cfcmsa & ctcmsa accesses for toolchains with MSA support
>
> which resolve the build regressions for these versions at least.
>
> I can't build a MIPS allnoconfig with binutils 2.25, but selecting the
> Malta platform instead of IP22 works. This is not a regression and is
> apparently due to a binutils bug; see commit ae2f5e5ed04a. I could
> pick that workaround for the next cycle.
>
> Ben.
>

Hi Ben,

I switched to use binutils 2.26.1 for the qemu tests. With that, we are down to:

Build results:
total: 140 pass: 137 fail: 3
Failed builds:
binutils 2.24:
mips:ath79_defconfig
mips:malta_defconfig
mips:rt305x_defconfig

with the following failures:

{standard input}: Assembler messages:
{standard input}:1376: Error: opcode not supported on this processor: mips32r2 (mips32r2) `ctc1 $2,$31'

Guenter

2017-04-02 02:48:28

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 3.16 00/19] 3.16.43-rc1 review

On Sat, 2017-04-01 at 23:40 +0100, Ben Hutchings wrote:
> On Sat, 2017-04-01 at 10:43 -0700, Guenter Roeck wrote:
> [snip list of MIPS failures]
> > I tried to build mips:allnoconfig with the following binutils versions.
> > They all fail with the same errors.
> > 2.22 (from Poky version 1.3)
> > 2.22 (kernel toolchain, gcc 4.6.3)
> > 2.24 (kernel toolchain, gcc 4.9.0)
> > 2.26.1 (buildroot toolchain, gcc 5.4.0)
> >
> > Bisect points to commit c4cf8e3a3e8f as the culprit.
> >
> > Details are available at http://kerneltests.org/builders.
> >
> > Unfortunately, just reverting this one patch doesn't work.
> > Reverting
> >
> > f1ece3b9dd5e MIPS: Fix build with binutils 2.24.51+
> > f8547d2f97c8 MIPS: init upper 64b of vector registers when MSA is first used
> > c4cf8e3a3e8f MIPS: save/restore MSACSR register on context switch
> >
> > fixes the problem, at least for an allnoconfig build with binutils 2.24.
>
> I've now tested with binutils 2.25 and 2.28 and added these:
>
> 558155a0a731 MIPS: allow msa.h to be included in assembly files
> 631afc65e8f4 MIPS: Push .set mips64r* into the functions needing it
> f23ce3883a30 MIPS: assume at as source/dest of MSA copy/insert instructions
> a3a49810c55e MIPS: remove MSA macro recursion
> e1bebbab1eae MIPS: wrap cfcmsa & ctcmsa accesses for toolchains with MSA support
>
> which resolve the build regressions for these versions at least.
[...]

Also added:

5e32033e14ca MIPS: mipsregs.h: Add write_32bit_cp1_register()
d76e9b9fc5de MIPS: traps: Fix inline asm ctc1 missing .set hardfloat

to address 3 remaining build failures on your build farm.

Ben.

--
Ben Hutchings
It is impossible to make anything foolproof because fools are so
ingenious.


Attachments:
signature.asc (833.00 B)
This is a digitally signed message part

2017-04-02 03:10:11

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 00/26] 3.16.43-rc2 review

I've added several more patches for MIPS to the queue for this release,
which will be sent as replies to this message.

Responses should be made by Tue Apr 04 00:00:00 UTC 2017.
Anything received after that time might be too late.

A combined patch relative to 3.16.42 will be posted as an additional
response to this. A shortlog and diffstat can be found below.

Ben.

-------------

Andre Przywara (1):
fs/nfs: fix new compiler warning about boolean in switch
[c7757074839f2cd440521482d76ea180d0d4bdac]

Arnd Bergmann (2):
crypto: improve gcc optimization flags for serpent and wp512
[7d6e9105026788c497f0ab32fa16c82f4ab5ff61]
mmc: sunxi: avoid invalid pointer calculation
[d34712d2e3db9b241d0484a6e3839c6b7ef9df78]

Ben Hutchings (1):
keys: Guard against null match function in keyring_search_aux()
[not upstream]

Eric W. Biederman (1):
vfs: Commit to never having exectuables on proc and sysfs.
[22f6b4d34fcf039c63a94e7670e0da24f8575a5a]

Fabio Estevam (1):
serial: samsung: Use %pa to print 'resource_size_t' type
[1ff5b64dccbf23acfe7993b9132b6992922a4756]

Florian Westphal (1):
netlink: remove mmapped netlink support
[d1b4c689d4130bcfd3532680b64db562300716b6]

James C Boyd (1):
HID: hid-input: Add parentheses to quell gcc warning
[09a5c34e8d6b05663ec4c3d22b1fbd9fec89aaf9]

James Hogan (2):
MIPS: mipsregs.h: Add write_32bit_cp1_register()
[5e32033e14ca9c7f7341cb383f5a05699b0b5382]
MIPS: traps: Fix inline asm ctc1 missing .set hardfloat
[d76e9b9fc5de7e8fc4fd0e72a94e8c723929ffea]

Jann Horn (1):
aio: mark AIO pseudo-fs noexec
[22f6b4d34fcf039c63a94e7670e0da24f8575a5a]

John Crispin (1):
MIPS: ralink: Cosmetic change to prom_init().
[9c48568b3692f1a56cbf1935e4eea835e6b185b1]

Linus Torvalds (1):
blk: rq_data_dir() should not return a boolean
[10fbd36e362a0f367e34a7cd876a81295d8fc5ca]

Manuel Lauss (1):
MIPS: Fix build with binutils 2.24.51+
[842dfc11ea9a21f9825167c8a4f2834b205b0a79]

Paul Burton (9):
MIPS: Push .set mips64r* into the functions needing it
[631afc65e8f4f845945ef9e90236d10cee601498]
MIPS: allow msa.h to be included in assembly files
[558155a0a731b4f56846559a57ca7ca921230497]
MIPS: assume at as source/dest of MSA copy/insert instructions
[f23ce3883a30743a5b779dc6fb90ca8620688a23]
MIPS: init upper 64b of vector registers when MSA is first used
[c9017757c532d48bf43d6e7d3b7282443ad4207b]
MIPS: preserve scalar FP CSR when switching vector context
[b83406735a4ae0aff4b614664d6a64a0fd6b9917]
MIPS: remove MSA macro recursion
[a3a49810c55e3489dfb5d72a9b2e41ab1db9ffb9]
MIPS: save/disable MSA in lose_fpu
[33c771ba5c5d067f85a5a6c4b11047219b5b8f4e]
MIPS: save/restore MSACSR register on context switch
[f7a46fa7bb0047d3e226702a0c4b786862fe6843]
MIPS: wrap cfcmsa & ctcmsa accesses for toolchains with MSA support
[e1bebbab1eaecac77d77033010b5e0f51b737e64]

Ralf Baechle (1):
MIPS: Zero variable read by get_user / __get_user in case of an error.
[640465bda58c7078725201be7430c31a349121e9]

Tillmann Heidsieck (1):
atm: iphase: fix misleading indention
[cbb41b91e68a302087762823136c9067138cff7c]

Tim Gardner (1):
fs: namespace: suppress 'may be used uninitialized' warnings
[b8850d1fa8e2f6653e57daf6d08e58c5f5eb2c85]

Documentation/networking/netlink_mmap.txt | 339 --------------
Makefile | 4 +-
arch/mips/Makefile | 9 +
arch/mips/include/asm/asmmacro-32.h | 6 +
arch/mips/include/asm/asmmacro.h | 129 +++++-
arch/mips/include/asm/fpregdef.h | 14 +
arch/mips/include/asm/fpu.h | 15 +-
arch/mips/include/asm/mipsregs.h | 11 +-
arch/mips/include/asm/msa.h | 23 +-
arch/mips/include/asm/uaccess.h | 5 +-
arch/mips/kernel/asm-offsets.c | 1 +
arch/mips/kernel/branch.c | 8 +-
arch/mips/kernel/genex.S | 1 +
arch/mips/kernel/r2300_fpu.S | 6 +
arch/mips/kernel/r2300_switch.S | 5 +
arch/mips/kernel/r4k_fpu.S | 29 +-
arch/mips/kernel/r4k_switch.S | 24 +-
arch/mips/kernel/r6000_fpu.S | 5 +
arch/mips/kernel/traps.c | 39 +-
arch/mips/math-emu/cp1emu.c | 6 +-
arch/mips/ralink/prom.c | 9 +-
crypto/Makefile | 2 +
drivers/atm/iphase.c | 2 +-
drivers/hid/hid-input.c | 2 +-
drivers/mmc/host/sunxi-mmc.c | 5 +-
drivers/tty/serial/samsung.c | 4 +-
fs/aio.c | 1 +
fs/compat.c | 10 +-
fs/exec.c | 10 +-
fs/internal.h | 2 +-
fs/namespace.c | 26 +-
fs/nfs/nfs4proc.c | 11 +-
fs/open.c | 2 +-
fs/proc/root.c | 2 +-
fs/sysfs/mount.c | 3 +-
include/linux/blkdev.h | 2 +-
include/linux/fs.h | 3 +
include/uapi/linux/netlink.h | 4 +
include/uapi/linux/netlink_diag.h | 2 +
kernel/sys.c | 3 +-
mm/mmap.c | 4 +-
mm/nommu.c | 2 +-
net/netlink/Kconfig | 9 -
net/netlink/af_netlink.c | 738 +-----------------------------
net/netlink/af_netlink.h | 15 -
net/netlink/diag.c | 39 --
security/keys/keyring.c | 6 +-
security/security.c | 2 +-
48 files changed, 352 insertions(+), 1247 deletions(-)

--
Ben Hutchings
It is impossible to make anything foolproof because fools are so ingenious.

2017-04-02 03:10:14

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 21/26] MIPS: mipsregs.h: Add write_32bit_cp1_register()

3.16.43-rc2 review patch. If anyone has any objections, please let me know.

------------------

From: James Hogan <[email protected]>

commit 5e32033e14ca9c7f7341cb383f5a05699b0b5382 upstream.

Add a write_32bit_cp1_register() macro to compliment the
read_32bit_cp1_register() macro. This is to abstract whether .set
hardfloat needs to be used based on GAS_HAS_SET_HARDFLOAT.

The implementation of _read_32bit_cp1_register() .sets mips1 due to
failure of gas v2.19 to assemble cfc1 for Octeon (see commit
25c300030016 ("MIPS: Override assembler target architecture for
octeon.")). I haven't copied this over to _write_32bit_cp1_register() as
I'm uncertain whether it applies to ctc1 too, or whether anybody cares
about that version of binutils any longer.

Signed-off-by: James Hogan <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: David Daney <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/9172/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/include/asm/mipsregs.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 5e4aef304b02..5b720d8c2745 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1386,12 +1386,27 @@ do { \
__res; \
})

+#define _write_32bit_cp1_register(dest, val, gas_hardfloat) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set reorder \n" \
+ " "STR(gas_hardfloat)" \n" \
+ " ctc1 %0,"STR(dest)" \n" \
+ " .set pop \n" \
+ : : "r" (val)); \
+} while (0)
+
#ifdef GAS_HAS_SET_HARDFLOAT
#define read_32bit_cp1_register(source) \
_read_32bit_cp1_register(source, .set hardfloat)
+#define write_32bit_cp1_register(dest, val) \
+ _write_32bit_cp1_register(dest, val, .set hardfloat)
#else
#define read_32bit_cp1_register(source) \
_read_32bit_cp1_register(source, )
+#define write_32bit_cp1_register(dest, val) \
+ _write_32bit_cp1_register(dest, val, )
#endif

#ifdef HAVE_AS_DSP

2017-04-02 03:10:12

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 22/26] MIPS: traps: Fix inline asm ctc1 missing .set hardfloat

3.16.43-rc2 review patch. If anyone has any objections, please let me know.

------------------

From: James Hogan <[email protected]>

commit d76e9b9fc5de7e8fc4fd0e72a94e8c723929ffea upstream.

Commit 842dfc11ea9a ("MIPS: Fix build with binutils 2.24.51+") in v3.18
enabled -msoft-float and sprinkled ".set hardfloat" where necessary to
use FP instructions. However it missed enable_restore_fp_context() which
since v3.17 does a ctc1 with inline assembly, causing the following
assembler errors on Mentor's 2014.05 toolchain:

{standard input}: Assembler messages:
{standard input}:2913: Error: opcode not supported on this processor: mips32r2 (mips32r2) `ctc1 $2,$31'
scripts/Makefile.build:257: recipe for target 'arch/mips/kernel/traps.o' failed

Fix that to use the new write_32bit_cp1_register() macro so that ".set
hardfloat" is automatically added when -msoft-float is in use.

Fixes 842dfc11ea9a ("MIPS: Fix build with binutils 2.24.51+")
Signed-off-by: James Hogan <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/9173/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/kernel/traps.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1183,7 +1183,8 @@ static int enable_restore_fp_context(int

/* Restore the scalar FP control & status register */
if (!was_fpu_owner)
- asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31));
+ write_32bit_cp1_register(CP1_STATUS,
+ current->thread.fpu.fcr31);
}
return 0;
}

2017-04-02 03:10:10

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 23/26] MIPS: Push .set mips64r* into the functions needing it

3.16.43-rc2 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit 631afc65e8f4f845945ef9e90236d10cee601498 upstream.

The {save,restore}_fp_context{,32} functions require that the assembler
allows the use of sdc instructions on any FP register, and this is
acomplished by setting the arch to mips64r2 or mips64r6
(using MIPS_ISA_ARCH_LEVEL_RAW).

However this has the effect of enabling the assembler to use mips64
instructions in the expansion of pseudo-instructions. This was done in
the (now-reverted) commit eec43a224cf1 "MIPS: Save/restore MSA context
around signals" which led to my mistakenly believing that there was an
assembler bug, when in reality the assembler was just emitting mips64
instructions. Avoid the issue for future commits which will add code to
r4k_fpu.S by pushing the .set MIPS_ISA_ARCH_LEVEL_RAW directives into
the functions that require it, and remove the spurious assertion
declaring the assembler bug.

Signed-off-by: Paul Burton <[email protected]>
[[email protected]: Rebase on v4.0-rc1 and reword commit message to
reflect use of MIPS_ISA_ARCH_LEVEL_RAW]
Signed-off-by: James Hogan <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/9612/
Signed-off-by: Ralf Baechle <[email protected]>
[bwh: Backported to 3.16: in r4k_fpu.S, keep using arch=r4000]
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/include/asm/asmmacro.h | 12 ++++--------
arch/mips/kernel/r4k_fpu.S | 2 +-
2 files changed, 5 insertions(+), 9 deletions(-)

--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -324,8 +324,7 @@
SET_HARDFLOAT
.insn
.word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
- /* move triggers an assembler bug... */
- or \rd, $1, zero
+ move \rd, $1
.set pop
.endm

@@ -335,8 +334,7 @@
SET_HARDFLOAT
.insn
.word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
- /* move triggers an assembler bug... */
- or \rd, $1, zero
+ move \rd, $1
.set pop
.endm

@@ -344,8 +342,7 @@
.set push
.set noat
SET_HARDFLOAT
- /* move triggers an assembler bug... */
- or $1, \rs, zero
+ move $1, \rs
.word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
.set pop
.endm
@@ -354,8 +351,7 @@
.set push
.set noat
SET_HARDFLOAT
- /* move triggers an assembler bug... */
- or $1, \rs, zero
+ move $1, \rs
.word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
.set pop
.endm
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -34,7 +34,6 @@
.endm

.set noreorder
- .set arch=r4000

LEAF(_save_fp_context)
.set push
@@ -102,6 +101,7 @@ LEAF(_save_fp_context)
/* Save 32-bit process floating point context */
LEAF(_save_fp_context32)
.set push
+ .set arch=r4000
SET_HARDFLOAT
cfc1 t1, fcr31


2017-04-02 03:10:09

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 25/26] MIPS: remove MSA macro recursion

3.16.43-rc2 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit a3a49810c55e3489dfb5d72a9b2e41ab1db9ffb9 upstream.

Recursive macros made the code more concise & worked great for the
case where the toolchain doesn't support MSA. However, with toolchains
which do support MSA they lead to build failures such as:

arch/mips/kernel/r4k_switch.S: Assembler messages:
arch/mips/kernel/r4k_switch.S:148: Error: invalid operands `insert.w $w(0+1)[2],$1'
arch/mips/kernel/r4k_switch.S:148: Error: invalid operands `insert.w $w(0+1)[3],$1'
arch/mips/kernel/r4k_switch.S:148: Error: invalid operands `insert.w $w((0+1)+1)[2],$1'
arch/mips/kernel/r4k_switch.S:148: Error: invalid operands `insert.w $w((0+1)+1)[3],$1'
...

Drop the recursion from msa_init_all_upper invoking the msa_init_upper
macro explicitly for each vector register.

Signed-off-by: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/9162/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/include/asm/asmmacro.h | 34 +++++++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)

--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -442,9 +442,6 @@
insert_w \wd, 2
insert_w \wd, 3
#endif
- .if 31-\wd
- msa_init_upper (\wd+1)
- .endif
.endm

.macro msa_init_all_upper
@@ -453,6 +450,37 @@
SET_HARDFLOAT
not $1, zero
msa_init_upper 0
+ msa_init_upper 1
+ msa_init_upper 2
+ msa_init_upper 3
+ msa_init_upper 4
+ msa_init_upper 5
+ msa_init_upper 6
+ msa_init_upper 7
+ msa_init_upper 8
+ msa_init_upper 9
+ msa_init_upper 10
+ msa_init_upper 11
+ msa_init_upper 12
+ msa_init_upper 13
+ msa_init_upper 14
+ msa_init_upper 15
+ msa_init_upper 16
+ msa_init_upper 17
+ msa_init_upper 18
+ msa_init_upper 19
+ msa_init_upper 20
+ msa_init_upper 21
+ msa_init_upper 22
+ msa_init_upper 23
+ msa_init_upper 24
+ msa_init_upper 25
+ msa_init_upper 26
+ msa_init_upper 27
+ msa_init_upper 28
+ msa_init_upper 29
+ msa_init_upper 30
+ msa_init_upper 31
.set pop
.endm


2017-04-02 03:10:07

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 20/26] MIPS: allow msa.h to be included in assembly files

3.16.43-rc2 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit 558155a0a731b4f56846559a57ca7ca921230497 upstream.

Just #ifdef away the C functions when included from an assembly file,
as will be done in a following commit.

Signed-off-by: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/7299/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/include/asm/msa.h | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h
index 538f6d482db8..e80e85c1334f 100644
--- a/arch/mips/include/asm/msa.h
+++ b/arch/mips/include/asm/msa.h
@@ -12,6 +12,8 @@

#include <asm/mipsregs.h>

+#ifndef __ASSEMBLY__
+
extern void _save_msa(struct task_struct *);
extern void _restore_msa(struct task_struct *);

@@ -133,15 +135,6 @@ static inline void write_msa_##name(unsigned int val) \

#endif /* !TOOLCHAIN_SUPPORTS_MSA */

-#define MSA_IR 0
-#define MSA_CSR 1
-#define MSA_ACCESS 2
-#define MSA_SAVE 3
-#define MSA_MODIFY 4
-#define MSA_REQUEST 5
-#define MSA_MAP 6
-#define MSA_UNMAP 7
-
__BUILD_MSA_CTL_REG(ir, 0)
__BUILD_MSA_CTL_REG(csr, 1)
__BUILD_MSA_CTL_REG(access, 2)
@@ -151,6 +144,17 @@ __BUILD_MSA_CTL_REG(request, 5)
__BUILD_MSA_CTL_REG(map, 6)
__BUILD_MSA_CTL_REG(unmap, 7)

+#endif /* !__ASSEMBLY__ */
+
+#define MSA_IR 0
+#define MSA_CSR 1
+#define MSA_ACCESS 2
+#define MSA_SAVE 3
+#define MSA_MODIFY 4
+#define MSA_REQUEST 5
+#define MSA_MAP 6
+#define MSA_UNMAP 7
+
/* MSA Implementation Register (MSAIR) */
#define MSA_IR_REVB 0
#define MSA_IR_REVF (_ULCAST_(0xff) << MSA_IR_REVB)

2017-04-02 03:10:06

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 24/26] MIPS: assume at as source/dest of MSA copy/insert instructions

3.16.43-rc2 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit f23ce3883a30743a5b779dc6fb90ca8620688a23 upstream.

Assuming at ($1) as the source or destination register of copy or
insert instructions:

- Simplifies the macros providing those instructions for toolchains
without MSA support.

- Avoids an unnecessary move instruction when at is used as the source
or destination register anyway.

- Is sufficient for the uses to be introduced in the kernel by a
subsequent patch.

Note that due to a patch ordering snafu on my part this also fixes the
currently broken build with MSA support enabled. The build has been
broken since commit c9017757c532 "MIPS: init upper 64b of vector
registers when MSA is first used", which this patch should have
preceeded.

Signed-off-by: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/9161/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/include/asm/asmmacro.h | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)

--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -225,35 +225,35 @@
.set pop
.endm

- .macro copy_u_w rd, ws, n
+ .macro copy_u_w ws, n
.set push
.set mips32r2
.set msa
- copy_u.w \rd, $w\ws[\n]
+ copy_u.w $1, $w\ws[\n]
.set pop
.endm

- .macro copy_u_d rd, ws, n
+ .macro copy_u_d ws, n
.set push
.set mips64r2
.set msa
- copy_u.d \rd, $w\ws[\n]
+ copy_u.d $1, $w\ws[\n]
.set pop
.endm

- .macro insert_w wd, n, rs
+ .macro insert_w wd, n
.set push
.set mips32r2
.set msa
- insert.w $w\wd[\n], \rs
+ insert.w $w\wd[\n], $1
.set pop
.endm

- .macro insert_d wd, n, rs
+ .macro insert_d wd, n
.set push
.set mips64r2
.set msa
- insert.d $w\wd[\n], \rs
+ insert.d $w\wd[\n], $1
.set pop
.endm
#else
@@ -318,40 +318,36 @@
.set pop
.endm

- .macro copy_u_w rd, ws, n
+ .macro copy_u_w ws, n
.set push
.set noat
SET_HARDFLOAT
.insn
.word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
- move \rd, $1
.set pop
.endm

- .macro copy_u_d rd, ws, n
+ .macro copy_u_d ws, n
.set push
.set noat
SET_HARDFLOAT
.insn
.word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
- move \rd, $1
.set pop
.endm

- .macro insert_w wd, n, rs
+ .macro insert_w wd, n
.set push
.set noat
SET_HARDFLOAT
- move $1, \rs
.word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
.set pop
.endm

- .macro insert_d wd, n, rs
+ .macro insert_d wd, n
.set push
.set noat
SET_HARDFLOAT
- move $1, \rs
.word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
.set pop
.endm

2017-04-02 03:10:04

by Ben Hutchings

[permalink] [raw]
Subject: [PATCH 3.16 26/26] MIPS: wrap cfcmsa & ctcmsa accesses for toolchains with MSA support

3.16.43-rc2 review patch. If anyone has any objections, please let me know.

------------------

From: Paul Burton <[email protected]>

commit e1bebbab1eaecac77d77033010b5e0f51b737e64 upstream.

Uses of the cfcmsa & ctcmsa instructions were not being wrapped by a
macro in the case where the toolchain supports MSA, since the arguments
exactly match a typical use of the instructions. However using current
toolchains this leads to errors such as:

arch/mips/kernel/genex.S:437: Error: opcode not supported on this processor: mips32r2 (mips32r2) `cfcmsa $5,1'

Thus uses of the instructions must be in the context of a ".set msa"
directive, however doing that from the users of the instructions would
be messy due to the possibility that the toolchain does not support
MSA. Fix this by renaming the macros (prepending an underscore) in order
to avoid recursion when attempting to emit the instructions, and provide
implementations for the TOOLCHAIN_SUPPORTS_MSA case which ".set msa" as
appropriate.

Signed-off-by: Paul Burton <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/9163/
Signed-off-by: Ralf Baechle <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
arch/mips/include/asm/asmmacro.h | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)

--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -209,6 +209,22 @@
.endm

#ifdef TOOLCHAIN_SUPPORTS_MSA
+ .macro _cfcmsa rd, cs
+ .set push
+ .set mips32r2
+ .set msa
+ cfcmsa \rd, $\cs
+ .set pop
+ .endm
+
+ .macro _ctcmsa cd, rs
+ .set push
+ .set mips32r2
+ .set msa
+ ctcmsa $\cd, \rs
+ .set pop
+ .endm
+
.macro ld_d wd, off, base
.set push
.set mips32r2
@@ -281,7 +297,7 @@
/*
* Temporary until all toolchains in use include MSA support.
*/
- .macro cfcmsa rd, cs
+ .macro _cfcmsa rd, cs
.set push
.set noat
SET_HARDFLOAT
@@ -291,7 +307,7 @@
.set pop
.endm

- .macro ctcmsa cd, rs
+ .macro _ctcmsa cd, rs
.set push
.set noat
SET_HARDFLOAT
@@ -389,7 +405,7 @@
.set push
.set noat
SET_HARDFLOAT
- cfcmsa $1, MSA_CSR
+ _cfcmsa $1, MSA_CSR
sw $1, THREAD_MSA_CSR(\thread)
.set pop
.endm
@@ -399,7 +415,7 @@
.set noat
SET_HARDFLOAT
lw $1, THREAD_MSA_CSR(\thread)
- ctcmsa MSA_CSR, $1
+ _ctcmsa MSA_CSR, $1
.set pop
ld_d 0, THREAD_FPR0, \thread
ld_d 1, THREAD_FPR1, \thread

2017-04-02 03:15:26

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 3.16 00/26] 3.16.43-rc2 review

This is the combined diff for 3.16.43-rc2 relative to 3.16.42.

Ben.

--
Ben Hutchings
It is impossible to make anything foolproof because fools are so
ingenious.


Attachments:
linux-3.16.43-rc2.patch (78.65 kB)
signature.asc (833.00 B)
This is a digitally signed message part
Download all attachments