diff options
author | Alex Shi <alex.shi@linaro.org> | 2017-01-19 22:49:17 +0800 |
---|---|---|
committer | Alex Shi <alex.shi@linaro.org> | 2017-01-19 22:49:17 +0800 |
commit | d661f15677f5205c1d272c2db90b60b2d56b25dd (patch) | |
tree | de3654c1be908381cbe1e46d8ff1afd447851330 | |
parent | 659a75a439d055cc48086afc2e101ca6ad8343a4 (diff) | |
parent | 65117109f6344fa46542f85844bc292842116192 (diff) |
Merge branch 'lsk-v4.1-android' of git://android.git.linaro.org/kernel/linaro-android into linux-linaro-lsk-v4.1-androidlsk-v4.1-17.02-android
-rw-r--r-- | arch/arm64/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm64/include/asm/alternative.h | 71 | ||||
-rw-r--r-- | arch/arm64/include/asm/assembler.h | 9 | ||||
-rw-r--r-- | arch/arm64/include/asm/barrier.h | 3 | ||||
-rw-r--r-- | arch/arm64/xen/hypercall.S | 19 | ||||
-rw-r--r-- | fs/sdcardfs/inode.c | 4 | ||||
-rw-r--r-- | net/core/sock.c | 4 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip.c | 5 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip6.c | 5 | ||||
-rw-r--r-- | net/socket.c | 2 |
10 files changed, 77 insertions, 53 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1f282b96be05..6a22ef746994 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -718,14 +718,6 @@ config SETEND_EMULATION If unsure, say Y endif -config ARM64_SW_TTBR0_PAN - bool "Emulate Priviledged Access Never using TTBR0_EL1 switching" - help - Enabling this option prevents the kernel from accessing - user-space memory directly by pointing TTBR0_EL1 to a reserved - zeroed area and reserved ASID. The user access routines - restore the valid TTBR0_EL1 temporarily. - menu "ARMv8.1 architectural features" config ARM64_PAN diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h index b9d9791630a1..0417f95fddeb 100644 --- a/arch/arm64/include/asm/alternative.h +++ b/arch/arm64/include/asm/alternative.h @@ -1,6 +1,8 @@ #ifndef __ASM_ALTERNATIVE_H #define __ASM_ALTERNATIVE_H +#include <asm/insn.h> + #ifndef __ASSEMBLY__ #include <linux/init.h> @@ -86,34 +88,55 @@ void apply_alternatives(void *start, size_t length); .endm /* - * Begin an alternative code sequence. + * Alternative sequences + * + * The code for the case where the capability is not present will be + * assembled and linked as normal. There are no restrictions on this + * code. + * + * The code for the case where the capability is present will be + * assembled into a special section to be used for dynamic patching. + * Code for that case must: + * + * 1. Be exactly the same length (in bytes) as the default code + * sequence. * - * The code that follows this macro will be assembled and linked as - * normal. There are no restrictions on this code. + * 2. Not contain a branch target that is used outside of the + * alternative sequence it is defined in (branches into an + * alternative sequence are not fixed up). + */ + +/* + * Begin an alternative code sequence. */ .macro alternative_if_not cap + .set .Lasm_alt_mode, 0 .pushsection .altinstructions, "a" altinstruction_entry 661f, 663f, \cap, 662f-661f, 664f-663f .popsection 661: .endm +.macro alternative_if cap + .set .Lasm_alt_mode, 1 + .pushsection .altinstructions, "a" + altinstruction_entry 663f, 661f, \cap, 664f-663f, 662f-661f + .popsection + .pushsection .altinstr_replacement, "ax" + .align 2 /* So GAS knows label 661 is suitably aligned */ +661: +.endm + /* - * Provide the alternative code sequence. - * - * The code that follows this macro is assembled into a special - * section to be used for dynamic patching. Code that follows this - * macro must: - * - * 1. Be exactly the same length (in bytes) as the default code - * sequence. - * - * 2. Not contain a branch target that is used outside of the - * alternative sequence it is defined in (branches into an - * alternative sequence are not fixed up). + * Provide the other half of the alternative code sequence. */ .macro alternative_else -662: .pushsection .altinstr_replacement, "ax" +662: + .if .Lasm_alt_mode==0 + .pushsection .altinstr_replacement, "ax" + .else + .popsection + .endif 663: .endm @@ -121,11 +144,25 @@ void apply_alternatives(void *start, size_t length); * Complete an alternative code sequence. */ .macro alternative_endif -664: .popsection +664: + .if .Lasm_alt_mode==0 + .popsection + .endif .org . - (664b-663b) + (662b-661b) .org . - (662b-661b) + (664b-663b) .endm +/* + * Provides a trivial alternative or default sequence consisting solely + * of NOPs. The number of NOPs is chosen automatically to match the + * previous case. + */ +.macro alternative_else_nop_endif +alternative_else + nops (662b-661b) / AARCH64_INSN_SIZE +alternative_endif +.endm + #define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...) \ alternative_insn insn1, insn2, cap, IS_ENABLED(cfg) diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index d8732b773bd1..211003d861a1 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -109,6 +109,15 @@ dmb \opt .endm +/* + * NOP sequence + */ + .macro nops, num + .rept \num + nop + .endr + .endm + #define USER(l, x...) \ 9999: x; \ .section __ex_table,"a"; \ diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h index 2666c9b84ca0..3577413c35f7 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -20,6 +20,9 @@ #ifndef __ASSEMBLY__ +#define __nops(n) ".rept " #n "\nnop\n.endr\n" +#define nops(n) asm volatile(__nops(n)) + #define sev() asm volatile("sev" : : : "memory") #define wfe() asm volatile("wfe" : : : "memory") #define wfi() asm volatile("wfi" : : : "memory") diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S index 6d6e4af1a4bf..8bbe9401f4f0 100644 --- a/arch/arm64/xen/hypercall.S +++ b/arch/arm64/xen/hypercall.S @@ -49,7 +49,6 @@ #include <linux/linkage.h> #include <asm/assembler.h> -#include <asm/uaccess.h> #include <xen/interface/xen.h> @@ -90,24 +89,6 @@ ENTRY(privcmd_call) mov x2, x3 mov x3, x4 mov x4, x5 -#ifdef CONFIG_ARM64_SW_TTBR0_PAN - /* - * Privcmd calls are issued by the userspace. The kernel needs to - * enable access to TTBR0_EL1 as the hypervisor would issue stage 1 - * translations to user memory via AT instructions. Since AT - * instructions are not affected by the PAN bit (ARMv8.1), we only - * need the explicit uaccess_enable/disable if the TTBR0 PAN emulation - * is enabled (it implies that hardware UAO and PAN disabled). - */ - uaccess_enable_not_uao x6, x7 -#endif hvc XEN_IMM - -#ifdef CONFIG_ARM64_SW_TTBR0_PAN - /* - * Disable userspace access from kernel once the hyp call completed. - */ - uaccess_disable_not_uao x6 -#endif ret ENDPROC(privcmd_call); diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c index 17435631ca1f..878546ff78b2 100644 --- a/fs/sdcardfs/inode.c +++ b/fs/sdcardfs/inode.c @@ -639,11 +639,11 @@ static int sdcardfs_setattr(struct dentry *dentry, struct iattr *ia) inode = d_inode(dentry); /* - * Check if user has permission to change inode. We don't check if + * Check if user has permission to change dentry. We don't check if * this user can change the lower inode: that should happen when * calling notify_change on the lower inode. */ - err = inode_change_ok(inode, ia); + err = setattr_prepare(dentry, ia); /* no vfs_XXX operations required, cred overriding will be skipped. wj*/ if (!err) { diff --git a/net/core/sock.c b/net/core/sock.c index 6633a0cdf864..8875efe3096c 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -732,7 +732,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, val = min_t(u32, val, sysctl_wmem_max); set_sndbuf: sk->sk_userlocks |= SOCK_SNDBUF_LOCK; - sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF); + sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF); /* Wake up sending tasks if we upped the value. */ sk->sk_write_space(sk); break; @@ -768,7 +768,7 @@ set_rcvbuf: * returning the value we actually used in getsockopt * is the most desirable behavior. */ - sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF); + sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF); break; case SO_RCVBUFFORCE: diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 44ee0683b14b..1a8281de81d5 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -251,8 +251,6 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) int ret; int chk_addr_ret; - if (!sock_flag(sk, SOCK_ZAPPED)) - return -EINVAL; if (addr_len < sizeof(struct sockaddr_l2tpip)) return -EINVAL; if (addr->l2tp_family != AF_INET) @@ -267,6 +265,9 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) read_unlock_bh(&l2tp_ip_lock); lock_sock(sk); + if (!sock_flag(sk, SOCK_ZAPPED)) + goto out; + if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip)) goto out; diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 36f94dbde232..b25f69cedf42 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -266,8 +266,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) int addr_type; int err; - if (!sock_flag(sk, SOCK_ZAPPED)) - return -EINVAL; if (addr->l2tp_family != AF_INET6) return -EINVAL; if (addr_len < sizeof(*addr)) @@ -293,6 +291,9 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) lock_sock(sk); err = -EINVAL; + if (!sock_flag(sk, SOCK_ZAPPED)) + goto out_unlock; + if (sk->sk_state != TCP_CLOSE) goto out_unlock; diff --git a/net/socket.c b/net/socket.c index 811dd63690b1..94e4fd0247a6 100644 --- a/net/socket.c +++ b/net/socket.c @@ -523,7 +523,7 @@ int sockfs_setattr(struct dentry *dentry, struct iattr *iattr) { int err = simple_setattr(dentry, iattr); - if (!err) { + if (!err && (iattr->ia_valid & ATTR_UID)) { struct socket *sock = SOCKET_I(d_inode(dentry)); sock->sk->sk_uid = iattr->ia_uid; |