4.4.14-stable review
Greg Kroah-Hartman
maintainercover 4.4.14-stable review
This is the start of the stable review cycle for the 4.4.14 release. There are 75 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Jun 24 22:34:00 UTC 2016. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.14-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.4.14-rc1
Florian Westphal <[email protected]>
netfilter: x_tables: don't reject valid target size on some architectures
Florian Westphal <[email protected]>
netfilter: x_tables: validate all offsets and sizes in a rule
Florian Westphal <[email protected]>
netfilter: x_tables: check for bogus target offset
Florian Westphal <[email protected]>
netfilter: x_tables: check standard target size too
Florian Westphal <[email protected]>
netfilter: x_tables: add compat version of xt_check_entry_offsets
Florian Westphal <[email protected]>
netfilter: x_tables: assert minimum target size
Florian Westphal <[email protected]>
netfilter: x_tables: kill check_entry helper
Florian Westphal <[email protected]>
netfilter: x_tables: add and use xt_check_entry_offsets
Florian Westphal <[email protected]>
netfilter: x_tables: validate targets of jumps
Florian Westphal <[email protected]>
netfilter: x_tables: don't move to non-existent next rule
Maarten Lankhorst <[email protected]>
drm/core: Do not preserve framebuffer on rmfb, v4.
Tadeusz Struk <[email protected]>
crypto: qat - fix adf_ctl_drv.c:undefined reference to adf_init_pf_wq
Florian Westphal <[email protected]>
netfilter: x_tables: fix unconditional helper
Florian Westphal <[email protected]>
netfilter: x_tables: make sure e->next_offset covers remaining blob size
Florian Westphal <[email protected]>
netfilter: x_tables: validate e->target_offset early
Ralf Baechle <[email protected]>
MIPS: Fix 64k page support for 32 bit kernels.
David S. Miller <[email protected]>
sparc64: Fix return from trap window fill crashes.
David S. Miller <[email protected]>
sparc: Harden signal return frame checks.
David S. Miller <[email protected]>
sparc64: Take ctx_alloc_lock properly in hugetlb_setup().
Nitin Gupta <[email protected]>
sparc64: Reduce TLB flushes during hugepte changes
Babu Moger <[email protected]>
sparc/PCI: Fix for panic while enabling SR-IOV
David S. Miller <[email protected]>
sparc64: Fix sparc64_set_context stack handling.
Nitin Gupta <[email protected]>
sparc64: Fix numa node distance initialization
David S. Miller <[email protected]>
sparc64: Fix bootup regressions on some Kconfig combinations.
Mike Frysinger <[email protected]>
sparc: Fix system call tracing register handling.
Al Viro <[email protected]>
fix d_walk()/non-delayed __d_free() race
Jann Horn <[email protected]>
sched: panic on corrupted stack end
Jann Horn <[email protected]>
proc: prevent stacking filesystems on top
Andy Lutomirski <[email protected]>
x86/entry/traps: Don't force in_interrupt() to return true in IST handlers
Prasun Maiti <[email protected]>
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel
Jann Horn <[email protected]>
ecryptfs: forbid opening files without mmap handler
Tejun Heo <[email protected]>
memcg: add RCU locking around css_for_each_descendant_pre() in memcg_offline_kmem()
Helge Deller <[email protected]>
parisc: Fix pagefault crash in unaligned __get_user() call
hongkun.cao <[email protected]>
pinctrl: mediatek: fix dual-edge code defect
Thomas Huth <[email protected]>
powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support call
Thomas Huth <[email protected]>
powerpc: Use privileged SPR number for MMCR2
Thomas Huth <[email protected]>
powerpc: Fix definition of SIAR and SDAR registers
Russell Currey <[email protected]>
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge
Will Deacon <[email protected]>
arm64: mm: always take dirty state from new pte in ptep_set_access_flags
Catalin Marinas <[email protected]>
arm64: Provide "model name" in /proc/cpuinfo for PER_LINUX32 tasks
Tom Lendacky <[email protected]>
crypto: ccp - Fix AES XTS error for request sizes above 4096
Arnd Bergmann <[email protected]>
crypto: public_key: select CRYPTO_AKCIPHER
Marc Zyngier <[email protected]>
irqchip/gic-v3: Fix ICC_SGI1R_EL1.INTID decoding mask
Michael Holzheu <[email protected]>
s390/bpf: reduce maximum program size to 64 KB
Michael Holzheu <[email protected]>
s390/bpf: fix recache skb->data/hlen for skb_vlan_push/pop
Ben Dooks <[email protected]>
gpio: bcm-kona: fix bcm_kona_gpio_reset() warnings
Russell King <[email protected]>
ARM: fix PTRACE_SETVFPREGS on SMP systems
Torsten Hilbrich <[email protected]>
ALSA: hda/realtek: Add T560 docking unit fixup
Kailang Yang <[email protected]>
ALSA: hda/realtek - Add support for new codecs ALC700/ALC701/ALC703
Kailang Yang <[email protected]>
ALSA: hda/realtek - ALC256 speaker noise issue
AceLan Kao <[email protected]>
ALSA: hda - Fix headset mic detection problem for Dell machine
Vinod Koul <[email protected]>
ALSA: hda - Add PCI ID for Kabylake
Paolo Bonzini <[email protected]>
KVM: irqfd: fix NULL pointer dereference in kvm_irq_map_gsi
Paolo Bonzini <[email protected]>
KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS
David Wragg <[email protected]>
vxlan, gre, geneve: Set a large MTU on ovs-created tunnel devices
David Wragg <[email protected]>
geneve: Relax MTU constraints
David Wragg <[email protected]>
vxlan: Relax MTU constraints
Jakub Sitnicki <[email protected]>
ipv6: Skip XFRM lookup if dst_entry in socket cache is valid
Guillaume Nault <[email protected]>
l2tp: fix configuration passed to setup_udp_tunnel_sock()
Toshiaki Makita <[email protected]>
bridge: Don't insert unnecessary local fdb entry on changing mac address
Yuchung Cheng <[email protected]>
tcp: record TLP and ER timer stats in v6 stats
Chen Haiquan <[email protected]>
vxlan: Accept user specified MTU value when create new vxlan link
Ivan Vecera <[email protected]>
team: don't call netdev_change_features under team->lock
Edward Cree <[email protected]>
sfc: on MC reset, clear PIO buffer linkage in TXQs
Daniel Borkmann <[email protected]>
bpf, inode: disallow userns mounts
Nicolas Dichtel <[email protected]>
uapi glibc compat: fix compilation when !__USE_MISC in glibc
Hannes Frederic Sowa <[email protected]>
udp: prevent skbs lingering in tunnel socket queues
Eric W. Biederman <[email protected]>
bpf: Use mount_nodev not mount_ns to mount the bpf filesystem
Jason Wang <[email protected]>
tuntap: correctly wake up process during uninit
Jiri Pirko <[email protected]>
switchdev: pass pointer to fib_info instead of copy
Richard Alpe <[email protected]>
tipc: fix nametable publication field in nl compat
Herbert Xu <[email protected]>
netlink: Fix dump skb leak/double free
Richard Alpe <[email protected]>
tipc: check nl sock before parsing nested attributes
Ewan D. Milne <[email protected]>
scsi: Add QEMU CD-ROM to VPD Inquiry Blacklist
James Bottomley <[email protected]>
scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands
-------------
Diffstat:
Makefile | 4 +- arch/arm/kernel/ptrace.c | 2 +- arch/arm64/include/asm/elf.h | 4 +- arch/arm64/kernel/cpuinfo.c | 8 +- arch/arm64/mm/fault.c | 2 +- arch/mips/include/asm/processor.h | 2 +- arch/parisc/kernel/unaligned.c | 10 +- arch/powerpc/include/asm/reg.h | 6 +- arch/powerpc/kernel/prom_init.c | 1 + arch/powerpc/platforms/pseries/eeh_pseries.c | 51 +++++--- arch/s390/net/bpf_jit.h | 4 +- arch/s390/net/bpf_jit_comp.c | 4 +- arch/sparc/include/asm/head_64.h | 4 + arch/sparc/include/asm/pgtable_64.h | 43 +++++-- arch/sparc/include/asm/tlbflush_64.h | 3 +- arch/sparc/include/asm/ttable.h | 8 +- arch/sparc/kernel/Makefile | 1 + arch/sparc/kernel/cherrs.S | 14 +-- arch/sparc/kernel/entry.S | 17 +++ arch/sparc/kernel/fpu_traps.S | 11 +- arch/sparc/kernel/head_64.S | 24 ++-- arch/sparc/kernel/misctrap.S | 12 +- arch/sparc/kernel/pci.c | 17 +++ arch/sparc/kernel/rtrap_64.S | 57 ++------- arch/sparc/kernel/signal32.c | 46 ++++--- arch/sparc/kernel/signal_32.c | 41 ++++--- arch/sparc/kernel/signal_64.c | 33 ++++-- arch/sparc/kernel/sigutil_32.c | 9 +- arch/sparc/kernel/sigutil_64.c | 10 +- arch/sparc/kernel/spiterrs.S | 18 +-- arch/sparc/kernel/syscalls.S | 36 ++++++ arch/sparc/kernel/urtt_fill.S | 98 +++++++++++++++ arch/sparc/kernel/utrap.S | 3 +- arch/sparc/kernel/vmlinux.lds.S | 4 + arch/sparc/kernel/winfixup.S | 3 +- arch/sparc/mm/hugetlbpage.c | 33 +++++- arch/sparc/mm/init_64.c | 37 +++--- arch/sparc/mm/tlb.c | 25 ++-- arch/sparc/mm/tsb.c | 32 ++--- arch/x86/kernel/traps.c | 20 ++-- arch/x86/kvm/x86.c | 5 + crypto/asymmetric_keys/Kconfig | 1 + drivers/crypto/ccp/ccp-crypto-aes-xts.c | 17 ++- drivers/crypto/qat/qat_common/adf_common_drv.h | 13 +- drivers/gpio/gpio-bcm-kona.c | 4 +- drivers/gpu/drm/drm_crtc.c | 60 +++++++++- drivers/net/ethernet/rocker/rocker.c | 4 +- drivers/net/ethernet/sfc/ef10.c | 16 +++ drivers/net/geneve.c | 41 +++++-- drivers/net/team/team.c | 9 +- drivers/net/tun.c | 6 +- drivers/net/vxlan.c | 60 ++++++---- drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 5 +- drivers/scsi/scsi_devinfo.c | 1 + drivers/scsi/scsi_lib.c | 7 +- fs/dcache.c | 4 +- fs/ecryptfs/kthread.c | 13 +- fs/proc/root.c | 7 ++ include/linux/irqchip/arm-gic-v3.h | 2 +- include/linux/netfilter/x_tables.h | 7 ++ include/net/ip_tunnels.h | 1 + include/net/switchdev.h | 2 +- include/uapi/linux/libc-compat.h | 2 +- kernel/bpf/inode.c | 3 +- kernel/sched/core.c | 3 +- mm/memcontrol.c | 3 + net/bridge/br_fdb.c | 2 + net/ipv4/ip_gre.c | 8 ++ net/ipv4/ip_tunnel.c | 20 +++- net/ipv4/netfilter/arp_tables.c | 87 ++++++++------ net/ipv4/netfilter/ip_tables.c | 90 +++++++------- net/ipv4/udp.c | 2 +- net/ipv6/ip6_output.c | 11 +- net/ipv6/netfilter/ip6_tables.c | 90 +++++++------- net/ipv6/tcp_ipv6.c | 4 +- net/ipv6/udp.c | 2 +- net/l2tp/l2tp_core.c | 2 +- net/netfilter/x_tables.c | 158 +++++++++++++++++++++++++ net/netlink/af_netlink.c | 7 +- net/openvswitch/vport-vxlan.c | 2 + net/switchdev/switchdev.c | 6 +- net/tipc/netlink_compat.c | 2 +- net/tipc/socket.c | 3 + net/wireless/wext-core.c | 25 +++- sound/pci/hda/hda_intel.c | 11 +- sound/pci/hda/patch_realtek.c | 73 +++++++++++- virt/kvm/irqchip.c | 2 +- 87 files changed, 1184 insertions(+), 476 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/75 scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Bottomley <[email protected]>
commit a621bac3044ed6f7ec5fa0326491b2d4838bfa93 upstream.
When SCSI was written, all commands coming from the filesystem (REQ_TYPE_FS commands) had data. This meant that our signal for needing to complete the command was the number of bytes completed being equal to the number of bytes in the request. Unfortunately, with the advent of flush barriers, we can now get zero length REQ_TYPE_FS commands, which confuse this logic because they satisfy the condition every time. This means they never get retried even for retryable conditions, like UNIT ATTENTION because we complete them early assuming they're done. Fix this by special casing the early completion condition to recognise zero length commands with errors and let them drop through to the retry code.
--- drivers/scsi/scsi_lib.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/scsi/scsi_lib.c +5 -2
@@ -910,9 +910,12 @@ void scsi_io_completion(struct scsi_cmnd }/* -* If we finished all bytes in the request we are done now. +* special case: failed zero length commands always need to +* drop down into the retry code. Otherwise, if we finished +* all bytes in the request we are done now. */ -if (!scsi_end_request (req, error, good_bytes,0 )) +if (!(blk_rq_bytes (req) ==0 && error) && + !scsi_end_request (req, error, good_bytes,0 ))return ;/*
Greg Kroah-Hartman
maintainerPATCH 2/75 scsi: Add QEMU CD-ROM to VPD Inquiry Blacklist
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ewan D. Milne <[email protected]>
commit fbd83006e3e536fcb103228d2422ea63129ccb03 upstream.
Linux fails to boot as a guest with a QEMU CD-ROM:
[ 4.439488] ata2.00: ATAPI: QEMU CD-ROM, 0.8.2, max UDMA/100
[ 4.443649] ata2.00: configured for MWDMA2
[ 4.450267] scsi 1:0:0:0: CD-ROM QEMU QEMU CD-ROM 0.8. PQ: 0 ANSI: 5
[ 4.464317] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[ 4.464319] ata2.00: BMDMA stat 0x5
[ 4.464339] ata2.00: cmd a0/01:00:00:00:01/00:00:00:00:00/a0 tag 0 dma 16640 in
[ 4.464339] Inquiry 12 01 00 00 ff 00res 48/20:02:00:24:00/00:00:00:00:00/a0 Emask 0x2 (HSM violation)
[ 4.464341] ata2.00: status: { DRDY DRQ }
[ 4.465864] ata2: soft resetting link
[ 4.625971] ata2.00: configured for MWDMA2
[ 4.628290] ata2: EH complete
[ 4.646670] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[ 4.646671] ata2.00: BMDMA stat 0x5
[ 4.646683] ata2.00: cmd a0/01:00:00:00:01/00:00:00:00:00/a0 tag 0 dma 16640 in
[ 4.646683] Inquiry 12 01 00 00 ff 00res 48/20:02:00:24:00/00:00:00:00:00/a0 Emask 0x2 (HSM violation)
[ 4.646685] ata2.00: status: { DRDY DRQ }
[ 4.648193] ata2: soft resetting link...
Fix this by suppressing VPD inquiry for this device.
--- drivers/scsi/scsi_devinfo.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/scsi_devinfo.c +1 -0
@@ -227,6 +227,7 @@ static struct { {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC}, {"Promise", "", NULL, BLIST_SPARSELUN}, + {"QEMU", "QEMU CD-ROM", NULL, BLIST_SKIP_VPD_PAGES}, {"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024}, {"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024}, {"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
Greg Kroah-Hartman
maintainerPATCH 3/75 tipc: check nl sock before parsing nested attributes
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Alpe <[email protected]>
[ Upstream commit 45e093ae2830cd1264677d47ff9a95a71f5d9f9c ]
Make sure the socket for which the user is listing publication exists before parsing the socket netlink attributes.
Prior to this patch a call without any socket caused a NULL pointer dereference in tipc_nl_publ_dump().
--- net/tipc/socket.c | 3 +++ 1 file changed, 3 insertions(+)
net/tipc/socket.c +3 -0
@@ -2814,6 +2814,9 @@ int tipc_nl_publ_dump(struct sk_buff *skif (err)return err; +if (!attrs[TIPC_NLA_SOCK ]) +return -EINVAL ; + err =nla_parse_nested (sock,TIPC_NLA_SOCK_MAX , attrs[TIPC_NLA_SOCK ], tipc_nl_sock_policy);
Greg Kroah-Hartman
maintainerPATCH 4/75 netlink: Fix dump skb leak/double free
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit 92964c79b357efd980812c4de5c1fd2ec8bb5520 ]
When we free cb->skb after a dump, we do it after releasing the lock. This means that a new dump could have started in the time being and we'll end up freeing their skb instead of ours.
This patch saves the skb and module before we unlock so we free the right memory.
--- net/netlink/af_netlink.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/netlink/af_netlink.c +5 -2
@@ -2784,6 +2784,7 @@ static int netlink_dump(struct sock *sk)struct netlink_callback *cb;struct sk_buff *skb =NULL ;struct nlmsghdr *nlh; +struct module *module;int len, err = -ENOBUFS ;int alloc_min_size;int alloc_size;
@@ -2863,9 +2864,11 @@ static int netlink_dump(struct sock *sk) cb->done (cb); nlk->cb_running = false; + module = cb->module; + skb = cb->skb;mutex_unlock (nlk->cb_mutex); -module_put (cb->module); -consume_skb (cb->skb); +module_put (module); +consume_skb (skb);return 0 ; errout_skb:
Greg Kroah-Hartman
maintainerPATCH 5/75 tipc: fix nametable publication field in nl compat
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Alpe <[email protected]>
[ Upstream commit 03aaaa9b941e136757b55c4cf775aab6068dfd94 ]
The publication field of the old netlink API should contain the publication key and not the publication reference.
--- net/tipc/netlink_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/tipc/netlink_compat.c +1 -1
@@ -802,7 +802,7 @@ static int tipc_nl_compat_name_table_dum goto out;tipc_tlv_sprintf (msg->rep,"%-10u %s" , -nla_get_u32 (publ[TIPC_NLA_PUBL_REF ]), +nla_get_u32 (publ[TIPC_NLA_PUBL_KEY ]), scope_str[nla_get_u32 (publ[TIPC_NLA_PUBL_SCOPE ])]); out:tipc_tlv_sprintf (msg->rep,"\n" );
Greg Kroah-Hartman
maintainerPATCH 6/75 switchdev: pass pointer to fib_info instead of copy
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Pirko <[email protected]>
[ Upstream commit da4ed55165d41b1073f9a476f1c18493e9bf8c8e ]
The problem is that fib_info->nh is [0] so the struct fib_info allocation size depends on number of nexthops. If we just copy fib_info, we do not copy the nexthops info and driver accesses memory which is not ours.
Given the fact that fib4 does not defer operations and therefore it does not need copy, just pass the pointer down to drivers as it was done before.
--- drivers/net/ethernet/rocker/rocker.c | 4 ++-- include/net/switchdev.h | 2 +- net/switchdev/switchdev.c | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-)
drivers/net/ethernet/rocker/rocker.c +2 -2
@@ -4475,7 +4475,7 @@ static int rocker_port_obj_add(struct ne fib4 =SWITCHDEV_OBJ_IPV4_FIB (obj); err =rocker_port_fib_ipv4 (rocker_port, trans,htonl (fib4->dst), fib4->dst_len, - &fib4->fi, fib4->tb_id,0 ); + fib4->fi, fib4->tb_id,0 );break ;case SWITCHDEV_OBJ_ID_PORT_FDB : err = rocker_port_fdb_add(rocker_port, trans,
@@ -4547,7 +4547,7 @@ static int rocker_port_obj_del(struct ne fib4 =SWITCHDEV_OBJ_IPV4_FIB (obj); err =rocker_port_fib_ipv4 (rocker_port,NULL ,htonl (fib4->dst), fib4->dst_len, - &fib4->fi, fib4->tb_id, + fib4->fi, fib4->tb_id,ROCKER_OP_FLAG_REMOVE );break ;case SWITCHDEV_OBJ_ID_PORT_FDB :
include/net/switchdev.h +1 -1
@@ -88,7 +88,7 @@ struct switchdev_obj_ipv4_fib {struct switchdev_obj obj;u32 dst;int dst_len; -struct fib_info fi; +struct fib_info *fi;u8 tos;u8 type;u32 nlflags;
net/switchdev/switchdev.c +2 -4
@@ -1169,6 +1169,7 @@ int switchdev_fib_ipv4_add(u32 dst, int .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB, .dst = dst, .dst_len = dst_len, + .fi = fi, .tos = tos, .type = type, .nlflags = nlflags,
@@ -1177,8 +1178,6 @@ int switchdev_fib_ipv4_add(u32 dst, intstruct net_device *dev;int err =0 ; -memcpy (&ipv4_fib.fi, fi,sizeof (ipv4_fib.fi)); -/* Don't offload route if using custom ip rules or if * IPv4 FIB offloading has been disabled completely. */
@@ -1222,6 +1221,7 @@ int switchdev_fib_ipv4_del(u32 dst, int .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB, .dst = dst, .dst_len = dst_len, + .fi = fi, .tos = tos, .type = type, .nlflags = 0,
@@ -1230,8 +1230,6 @@ int switchdev_fib_ipv4_del(u32 dst, intstruct net_device *dev;int err =0 ; -memcpy (&ipv4_fib.fi, fi,sizeof (ipv4_fib.fi)); -if (!(fi->fib_flags &RTNH_F_OFFLOAD ))return 0 ;
Greg Kroah-Hartman
maintainerPATCH 7/75 tuntap: correctly wake up process during uninit
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Wang <[email protected]>
[ Upstream commit addf8fc4acb1cf79492ac64966f07178793cb3d7 ]
We used to check dev->reg_state against NETREG_REGISTERED after each time we are woke up. But after commit 9e641bdcfa4e ("net-tun:
restructure tun_do_read for better sleep/wakeup efficiency"), it uses skb_recv_datagram() which does not check dev->reg_state. This will result if we delete a tun/tap device after a process is blocked in the reading. The device will wait for the reference count which was held by that process for ever.
Fixes this by using RCV_SHUTDOWN which will be checked during sk_recv_datagram() before trying to wake up the process during uninit.
sleep/wakeup efficiency")
--- drivers/net/tun.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/tun.c +3 -3
@@ -567,11 +567,13 @@ static void tun_detach_all(struct net_defor (i =0 ; i < n; i++) { tfile =rtnl_dereference (tun->tfiles[i]);BUG_ON (!tfile); + tfile->socket.sk->sk_shutdown =RCV_SHUTDOWN ; tfile->socket.sk->sk_data_ready (tfile->socket.sk);RCU_INIT_POINTER (tfile->tun,NULL ); --tun->numqueues; }list_for_each_entry (tfile, &tun->disabled, next) { + tfile->socket.sk->sk_shutdown =RCV_SHUTDOWN ; tfile->socket.sk->sk_data_ready (tfile->socket.sk);RCU_INIT_POINTER (tfile->tun,NULL ); }
@@ -627,6 +629,7 @@ static int tun_attach(struct tun_struct goto out; } tfile->queue_index = tun->numqueues; + tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN ;rcu_assign_pointer (tfile->tun, tun);rcu_assign_pointer (tun->tfiles[tun->numqueues], tfile); tun->numqueues++;
@@ -1408,9 +1411,6 @@ static ssize_t tun_do_read(struct tun_stif (!iov_iter_count (to))return 0 ; -if (tun->dev->reg_state !=NETREG_REGISTERED ) -return -EIO ; -/* Read frames from queue */ skb =__skb_recv_datagram (tfile->socket.sk, noblock ?MSG_DONTWAIT :0 , &peeked, &off, &err);
Greg Kroah-Hartman
maintainerPATCH 8/75 bpf: Use mount_nodev not mount_ns to mount the bpf filesystem
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
[ Upstream commit e27f4a942a0ee4b84567a3c6cfa84f273e55cbb7 ]
While reviewing the filesystems that set FS_USERNS_MOUNT I spotted the bpf filesystem. Looking at the code I saw a broken usage of mount_ns with current->nsproxy->mnt_ns. As the code does not acquire a reference to the mount namespace it can not possibly be correct to store the mount namespace on the superblock as it does.
Replace mount_ns with mount_nodev so that each mount of the bpf filesystem returns a distinct instance, and the code is not buggy.
In discussion with Hannes Frederic Sowa it was reported that the use of mount_ns was an attempt to have one bpf instance per mount namespace, in an attempt to keep resources that pin resources from hiding. That intent simply does not work, the vfs is not built to allow that kind of behavior. Which means that the bpf filesystem really is buggy both semantically and in it's implemenation as it does not nor can it implement the original intent.
This change is userspace visible, but my experience with similar filesystems leads me to believe nothing will break with a model of each mount of the bpf filesystem is distinct from all others.
--- kernel/bpf/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/inode.c +1 -1
@@ -358,7 +358,7 @@ static int bpf_fill_super(struct super_bstatic struct dentry *bpf_mount (struct file_system_type *type,int flags,const char *dev_name,void *data) { -return mount_ns (type, flags, current->nsproxy->mnt_ns, bpf_fill_super); +return mount_nodev (type, flags, data, bpf_fill_super); }static struct file_system_type bpf_fs_type = {
Greg Kroah-Hartman
maintainerPATCH 9/75 udp: prevent skbs lingering in tunnel socket queues
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Frederic Sowa <[email protected]>
[ Upstream commit e5aed006be918af163eb397e45aa5ea6cefd5e01 ]
In case we find a socket with encapsulation enabled we should call the encap_recv function even if just a udp header without payload is available. The callbacks are responsible for correctly verifying and dropping the packets.
Also, in case the header validation fails for geneve and vxlan we shouldn't put the skb back into the socket queue, no one will pick them up there. Instead we can simply discard them in the respective encap_recv functions.
--- drivers/net/geneve.c | 10 +++------- drivers/net/vxlan.c | 10 ++-------- net/ipv4/udp.c | 2 +- net/ipv6/udp.c | 2 +- 4 files changed, 7 insertions(+), 17 deletions(-)
drivers/net/geneve.c +3 -7
@@ -310,15 +310,15 @@ static int geneve_udp_encap_recv(struct/* Need Geneve and inner Ethernet header to be present */ if (unlikely (!pskb_may_pull (skb,GENEVE_BASE_HLEN ))) - goto error; + goto drop;/* Return packets with reserved bits set */ geneveh =geneve_hdr (skb);if (unlikely (geneveh->ver !=GENEVE_VER )) - goto error; + goto drop;if (unlikely (geneveh->proto_type !=htons (ETH_P_TEB ))) - goto error; + goto drop; opts_len = geneveh->opt_len *4 ; if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len,
@@ -336,10 +336,6 @@ drop:/* Consume bad packet */ kfree_skb (skb);return 0 ; - -error: -/* Let the UDP layer deal with the skb */ -return 1 ; } static struct socket *geneve_create_sock(struct net *net, bool ipv6,
drivers/net/vxlan.c +2 -8
@@ -1254,7 +1254,7 @@ static int vxlan_udp_encap_recv(struct s/* Need Vxlan and inner Ethernet header to be present */ if (!pskb_may_pull (skb,VXLAN_HLEN )) - goto error; + goto drop; vxh = (struct vxlanhdr *)(udp_hdr (skb) +1 ); flags =ntohl (vxh->vx_flags);
@@ -1344,13 +1344,7 @@ drop: bad_flags:netdev_dbg (skb->dev,"invalid vxlan flags=%#x vni=%#x\n" ,ntohl (vxh->vx_flags),ntohl (vxh->vx_vni)); - -error: -if (tun_dst) -dst_release ((struct dst_entry *)tun_dst); - -/* Return non vxlan pkt */ -return 1 ; + goto drop; }static int arp_reduce (struct net_device *dev,struct sk_buff *skb)
net/ipv4/udp.c +1 -1
@@ -1531,7 +1531,7 @@ int udp_queue_rcv_skb(struct sock *sk, s/* if we're overly short, let UDP handle it */ encap_rcv =ACCESS_ONCE (up->encap_rcv); -if (skb->len >sizeof (struct udphdr ) && encap_rcv) { +if (encap_rcv) {int ret;/* Verify checksum before giving to encap */
net/ipv6/udp.c +1 -1
@@ -647,7 +647,7 @@ int udpv6_queue_rcv_skb(struct sock *sk,/* if we're overly short, let UDP handle it */ encap_rcv =ACCESS_ONCE (up->encap_rcv); -if (skb->len >sizeof (struct udphdr ) && encap_rcv) { +if (encap_rcv) {int ret;/* Verify checksum before giving to encap */
Greg Kroah-Hartman
maintainerPATCH 10/75 uapi glibc compat: fix compilation when !__USE_MISC in glibc
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Dichtel <[email protected]>
[ Upstream commit f0a3fdca794d1e68ae284ef4caefe681f7c18e89 ]
These structures are defined only if __USE_MISC is set in glibc net/if.h headers, ie when _BSD_SOURCE or _SVID_SOURCE are defined.
--- include/uapi/linux/libc-compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/uapi/linux/libc-compat.h +1 -1
@@ -52,7 +52,7 @@#if defined(__GLIBC__)/* Coordinate with glibc net/if.h header. */ -#if defined(_NET_IF_H) +#if defined(_NET_IF_H) && defined(__USE_MISC)/* GLIBC headers included first so don't define anything * that would already be defined. */
Greg Kroah-Hartman
maintainerPATCH 11/75 bpf, inode: disallow userns mounts
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit 612bacad78ba6d0a91166fc4487af114bac172a8 ]
Follow-up to commit e27f4a942a0e ("bpf: Use mount_nodev not mount_ns to mount the bpf filesystem"), which removes the FS_USERNS_MOUNT flag.
The original idea was to have a per mountns instance instead of a single global fs instance, but that didn't work out and we had to switch to mount_nodev() model. The intent of that middle ground was that we avoid users who don't play nice to create endless instances of bpf fs which are difficult to control and discover from an admin point of view, but at the same time it would have allowed us to be more flexible with regard to namespaces.
Therefore, since we now did the switch to mount_nodev() as a fix where individual instances are created, we also need to remove userns mount flag along with it to avoid running into mentioned situation. I don't expect any breakage at this early point in time with removing the flag and we can revisit this later should the requirement for this come up with future users. This and commit e27f4a942a0e have been split to facilitate tracking should any of them run into the unlikely case of causing a regression.
--- kernel/bpf/inode.c | 1 - 1 file changed, 1 deletion(-)
kernel/bpf/inode.c +0 -1
@@ -366,7 +366,6 @@ static struct file_system_type bpf_fs_ty .name = "bpf", .mount = bpf_mount, .kill_sb = kill_litter_super, - .fs_flags = FS_USERNS_MOUNT, };MODULE_ALIAS_FS ("bpf" );
Greg Kroah-Hartman
maintainerPATCH 12/75 sfc: on MC reset, clear PIO buffer linkage in TXQs
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Cree <[email protected]>
[ Upstream commit c0795bf64cba4d1b796fdc5b74b33772841ed1bb ]
Otherwise, if we fail to allocate new PIO buffers, our TXQs will try to use the old ones, which aren't there any more.
--- drivers/net/ethernet/sfc/ef10.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/net/ethernet/sfc/ef10.c +16 -0
@@ -619,6 +619,17 @@ fail: return rc; } +static void efx_ef10_forget_old_piobufs (struct efx_nic *efx) +{ +struct efx_channel *channel; +struct efx_tx_queue *tx_queue; + +/* All our existing PIO buffers went away */ +efx_for_each_channel (channel, efx) +efx_for_each_channel_tx_queue (tx_queue, channel) + tx_queue->piobuf =NULL ; +} +#else /* !EFX_USE_PIO */ static int efx_ef10_alloc_piobufs (struct efx_nic *efx,unsigned int n)
@@ -635,6 +646,10 @@ static void efx_ef10_free_piobufs(struct { } +static void efx_ef10_forget_old_piobufs (struct efx_nic *efx) +{ +} +#endif /* EFX_USE_PIO */ static void efx_ef10_remove (struct efx_nic *efx)
@@ -1018,6 +1033,7 @@ static void efx_ef10_reset_mc_allocation nic_data->must_realloc_vis = true; nic_data->must_restore_filters = true; nic_data->must_restore_piobufs = true; +efx_ef10_forget_old_piobufs (efx); nic_data->rx_rss_context =EFX_EF10_RSS_CONTEXT_INVALID ;/* Driver-created vswitches and vports must be re-created */
Greg Kroah-Hartman
maintainerPATCH 13/75 team: dont call netdev_change_features under team->lock
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Vecera <[email protected]>
[ Upstream commit f6988cb63a4e698d8a62a1d085d263d1fcc351ea ]
The team_device_event() notifier calls team_compute_features() to fix vlan_features under team->lock to protect team->port_list. The problem is that subsequent __team_compute_features() calls netdev_change_features() to propagate vlan_features to upper vlan devices while team->lock is still taken. This can lead to deadlock when NETIF_F_LRO is modified on lower devices or team device itself.
Example:
The team0 as active backup with eth0 and eth1 NICs. Both eth0 & eth1 are LRO capable and LRO is enabled. Thus LRO is also enabled on team0.
The command 'ethtool -K team0 lro off' now hangs due to this deadlock:
dev_ethtool()
-> ethtool_set_features()
-> __netdev_update_features(team)
-> netdev_sync_lower_features()
-> netdev_update_features(lower_1)
-> __netdev_update_features(lower_1)
-> netdev_features_change(lower_1)
-> call_netdevice_notifiers(...)
-> team_device_event(lower_1)
-> team_compute_features(team) [TAKES team->lock]
-> netdev_change_features(team)
-> __netdev_update_features(team)
-> netdev_sync_lower_features()
-> netdev_update_features(lower_2)
-> __netdev_update_features(lower_2)
-> netdev_features_change(lower_2)
-> call_netdevice_notifiers(...)
-> team_device_event(lower_2)
-> team_compute_features(team) [DEADLOCK]The bug is present in team from the beginning but it appeared after the commit fd867d5 (net/core: generic support for disabling netdev features down stack) that adds synchronization of features with lower devices.
--- drivers/net/team/team.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/team/team.c +7 -2
@@ -969,7 +969,7 @@ static void team_port_disable(struct tea NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ NETIF_F_HIGHDMA | NETIF_F_LRO) -static void __team_compute_features (struct team *team) +static void ___team_compute_features (struct team *team) {struct team_port *port;u32 vlan_features =TEAM_VLAN_FEATURES &NETIF_F_ALL_FOR_ALL ;
@@ -993,15 +993,20 @@ static void __team_compute_features(stru team->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE ;if (dst_release_flag == (IFF_XMIT_DST_RELEASE |IFF_XMIT_DST_RELEASE_PERM )) team->dev->priv_flags |=IFF_XMIT_DST_RELEASE ; +} +static void __team_compute_features (struct team *team) +{ +___team_compute_features (team);netdev_change_features (team->dev); }static void team_compute_features (struct team *team) {mutex_lock (&team->lock); -__team_compute_features (team); +___team_compute_features (team);mutex_unlock (&team->lock); +netdev_change_features (team->dev); }static int team_port_enter (struct team *team,struct team_port *port)
Greg Kroah-Hartman
maintainerPATCH 14/75 vxlan: Accept user specified MTU value when create new vxlan link
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Haiquan <[email protected]>
[ Upstream commit ce577668a426c6a9e2470a09dcd07fbd6e45272a ]
When create a new vxlan link, example:
ip link add vtap mtu 1440 type vxlan vni 1 dev eth0
The argument "mtu" has no effect, because it is not set to conf->mtu. The default value is used in vxlan_dev_configure function.
This problem was introduced by commit 0dfbdf4102b9 (vxlan: Factor out device configuration).
--- drivers/net/vxlan.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/vxlan.c +3 -0
@@ -2985,6 +2985,9 @@ static int vxlan_newlink(struct net *srcif (data[IFLA_VXLAN_REMCSUM_NOPARTIAL ]) conf.flags |=VXLAN_F_REMCSUM_NOPARTIAL ; +if (tb[IFLA_MTU ]) + conf.mtu =nla_get_u32 (tb[IFLA_MTU ]); + err =vxlan_dev_configure (src_net, dev, &conf);switch (err) {case -ENODEV :
Greg Kroah-Hartman
maintainerPATCH 15/75 tcp: record TLP and ER timer stats in v6 stats
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuchung Cheng <[email protected]>
[ Upstream commit ce3cf4ec0305919fc69a972f6c2b2efd35d36abc ]
The v6 tcp stats scan do not provide TLP and ER timer information correctly like the v4 version . This patch fixes that.
--- net/ipv6/tcp_ipv6.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/ipv6/tcp_ipv6.c +3 -1
@@ -1706,7 +1706,9 @@ static void get_tcp6_sock(struct seq_fil destp =ntohs (inet->inet_dport); srcp =ntohs (inet->inet_sport); -if (icsk->icsk_pending ==ICSK_TIME_RETRANS ) { +if (icsk->icsk_pending ==ICSK_TIME_RETRANS || + icsk->icsk_pending ==ICSK_TIME_EARLY_RETRANS || + icsk->icsk_pending ==ICSK_TIME_LOSS_PROBE ) { timer_active =1 ; timer_expires = icsk->icsk_timeout; }else if (icsk->icsk_pending ==ICSK_TIME_PROBE0 ) {
Greg Kroah-Hartman
maintainerPATCH 16/75 bridge: Dont insert unnecessary local fdb entry on changing mac address
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshiaki Makita <[email protected]>
[ Upstream commit 0b148def403153a4d1565f1640356cb78ce5109f ]
The missing br_vlan_should_use() test caused creation of an unneeded local fdb entry on changing mac address of a bridge device when there is a vlan which is configured on a bridge port but not on the bridge device.
--- net/bridge/br_fdb.c | 2 ++ 1 file changed, 2 insertions(+)
net/bridge/br_fdb.c +2 -0
@@ -278,6 +278,8 @@ void br_fdb_change_mac_address(struct ne* change from under us. */ list_for_each_entry (v, &vg->vlan_list, vlist) { +if (!br_vlan_should_use (v)) +continue ; f =__br_fdb_get (br, br->dev->dev_addr, v->vid);if (f && f->is_local && !f->dst)fdb_delete_local (br,NULL , f);
Greg Kroah-Hartman
maintainerPATCH 17/75 l2tp: fix configuration passed to setup_udp_tunnel_sock()
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
[ Upstream commit a5c5e2da8551eb69e5d5d09d51d526140b5db9fb ]
Unused fields of udp_cfg must be all zeros. Otherwise setup_udp_tunnel_sock() fills ->gro_receive and ->gro_complete callbacks with garbage, eventually resulting in panic when used by udp_gro_receive().
[ 72.694123] BUG: unable to handle kernel paging request at ffff880033f87d78 [ 72.695518] IP: [<ffff880033f87d78>] 0xffff880033f87d78 [ 72.696530] PGD 26e2067 PUD 26e3067 PMD 342ed063 PTE 8000000033f87163 [ 72.696530] Oops: 0011 [#1] SMP KASAN [ 72.696530] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core ip6_udp_tunnel udp_tunnel pptp gre pppox ppp_generic slhc crc32c_intel ghash_clmulni_intel jitterentropy_rng sha256_generic hmac drbg ansi_cprng aesni_intel evdev aes_x86_64 ablk_helper cryptd lrw gf128mul glue_helper serio_raw acpi_cpufreq button proc\ essor ext4 crc16 jbd2 mbcache virtio_blk virtio_net virtio_pci virtio_ring virtio [ 72.696530] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.7.0-rc1 #1 [ 72.696530] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Debian-1.8.2-1 04/01/2014 [ 72.696530] task: ffff880035b59700 ti: ffff880035b70000 task.ti: ffff880035b70000 [ 72.696530] RIP: 0010:[<ffff880033f87d78>] [<ffff880033f87d78>] 0xffff880033f87d78 [ 72.696530] RSP: 0018:ffff880035f87bc0 EFLAGS: 00010246 [ 72.696530] RAX: ffffed000698f996 RBX: ffff88003326b840 RCX: ffffffff814cc823 [ 72.696530] RDX: ffff88003326b840 RSI: ffff880033e48038 RDI: ffff880034c7c780 [ 72.696530] RBP: ffff880035f87c18 R08: 000000000000a506 R09: 0000000000000000 [ 72.696530] R10: ffff880035f87b38 R11: ffff880034b9344d R12: 00000000ebfea715 [ 72.696530] R13: 0000000000000000 R14: ffff880034c7c780 R15: 0000000000000000 [ 72.696530] FS: 0000000000000000(0000) GS:ffff880035f80000(0000) knlGS:0000000000000000 [ 72.696530] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 72.696530] CR2: ffff880033f87d78 CR3: 0000000033c98000 CR4: 00000000000406a0 [ 72.696530] Stack: [ 72.696530] ffffffff814cc834 ffff880034b93468 0000001481416818 ffff88003326b874 [ 72.696530] ffff880034c7ccb0 ffff880033e48038 ffff88003326b840 ffff880034b93462 [ 72.696530] ffff88003326b88a ffff88003326b88c ffff880034b93468 ffff880035f87c70 [ 72.696530] Call Trace: [ 72.696530] <IRQ> [ 72.696530] [<ffffffff814cc834>] ? udp_gro_receive+0x1c6/0x1f9 [ 72.696530] [<ffffffff814ccb1c>] udp4_gro_receive+0x2b5/0x310 [ 72.696530] [<ffffffff814d989b>] inet_gro_receive+0x4a3/0x4cd [ 72.696530] [<ffffffff81431b32>] dev_gro_receive+0x584/0x7a3 [ 72.696530] [<ffffffff810adf7a>] ? __lock_is_held+0x29/0x64 [ 72.696530] [<ffffffff814321f7>] napi_gro_receive+0x124/0x21d [ 72.696530] [<ffffffffa000b145>] virtnet_receive+0x8df/0x8f6 [virtio_net] [ 72.696530] [<ffffffffa000b27e>] virtnet_poll+0x1d/0x8d [virtio_net] [ 72.696530] [<ffffffff81431350>] net_rx_action+0x15b/0x3b9 [ 72.696530] [<ffffffff815893d6>] __do_softirq+0x216/0x546 [ 72.696530] [<ffffffff81062392>] irq_exit+0x49/0xb6 [ 72.696530] [<ffffffff81588e9a>] do_IRQ+0xe2/0xfa [ 72.696530] [<ffffffff81587a49>] common_interrupt+0x89/0x89 [ 72.696530] <EOI> [ 72.696530] [<ffffffff810b05df>] ? trace_hardirqs_on_caller+0x229/0x270 [ 72.696530] [<ffffffff8102b3c7>] ? default_idle+0x1c/0x2d [ 72.696530] [<ffffffff8102b3c5>] ? default_idle+0x1a/0x2d [ 72.696530] [<ffffffff8102bb8c>] arch_cpu_idle+0xa/0xc [ 72.696530] [<ffffffff810a6c39>] default_idle_call+0x1a/0x1c [ 72.696530] [<ffffffff810a6d96>] cpu_startup_entry+0x15b/0x20f [ 72.696530] [<ffffffff81039a81>] start_secondary+0x12c/0x133 [ 72.696530] Code: ff ff ff ff ff ff ff ff ff ff 7f ff ff ff ff ff ff ff 7f 00 7e f8 33 00 88 ff ff 6d 61 58 81 ff ff ff ff 5e de 0a 81 ff ff ff ff <00> 5c e2 34 00 88 ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 72.696530] RIP [<ffff880033f87d78>] 0xffff880033f87d78 [ 72.696530] RSP <ffff880035f87bc0> [ 72.696530] CR2: ffff880033f87d78 [ 72.696530] ---[ end trace ad7758b9a1dccf99 ]--- [ 72.696530] Kernel panic - not syncing: Fatal exception in interrupt [ 72.696530] Kernel Offset: disabled [ 72.696530] ---[ end Kernel panic - not syncing: Fatal exception in interrupt
v2: use empty initialiser instead of "{ NULL }" to avoid relying on
first field's type.
--- net/l2tp/l2tp_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/l2tp/l2tp_core.c +1 -1
@@ -1581,7 +1581,7 @@ int l2tp_tunnel_create(struct net *net,/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */ tunnel->encap = encap;if (encap ==L2TP_ENCAPTYPE_UDP ) { -struct udp_tunnel_sock_cfg udp_cfg; +struct udp_tunnel_sock_cfg udp_cfg = { }; udp_cfg.sk_user_data = tunnel; udp_cfg.encap_type =UDP_ENCAP_L2TPINUDP ;
Greg Kroah-Hartman
maintainerPATCH 18/75 ipv6: Skip XFRM lookup if dst_entry in socket cache is valid
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Sitnicki <[email protected]>
[ Upstream commit 00bc0ef5880dc7b82f9c320dead4afaad48e47be ]
At present we perform an xfrm_lookup() for each UDPv6 message we send. The lookup involves querying the flow cache (flow_cache_lookup) and, in case of a cache miss, creating an XFRM bundle.
If we miss the flow cache, we can end up creating a new bundle and deriving the path MTU (xfrm_init_pmtu) from on an already transformed dst_entry, which we pass from the socket cache (sk->sk_dst_cache) down to xfrm_lookup(). This can happen only if we're caching the dst_entry in the socket, that is when we're using a connected UDP socket.
To put it another way, the path MTU shrinks each time we miss the flow cache, which later on leads to incorrectly fragmented payload. It can be observed with ESPv6 in transport mode:
1) Set up a transformation and lower the MTU to trigger fragmentation
# ip xfrm policy add dir out src ::1 dst ::1 \
tmpl src ::1 dst ::1 proto esp spi 1
# ip xfrm state add src ::1 dst ::1 \
proto esp spi 1 enc 'aes' 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
# ip link set dev lo mtu 15002) Monitor the packet flow and set up an UDP sink
# tcpdump -ni lo -ttt &
# socat udp6-listen:12345,fork /dev/null &3) Send a datagram that needs fragmentation with a connected socket
# perl -e 'print "@" x 1470 | socat - udp6:[::1]:12345
2016/06/07 18:52:52 socat[724] E read(3, 0x555bb3d5ba00, 8192): Protocol error
00:00:00.000000 IP6 ::1 > ::1: frag (0|1448) ESP(spi=0x00000001,seq=0x2), length 1448
00:00:00.000014 IP6 ::1 > ::1: frag (1448|32)
00:00:00.000050 IP6 ::1 > ::1: ESP(spi=0x00000001,seq=0x3), length 1272
(^ ICMPv6 Parameter Problem)
00:00:00.000022 IP6 ::1 > ::1: ESP(spi=0x00000001,seq=0x5), length 1364) Compare it to a non-connected socket
# perl -e 'print "@" x 1500' | socat - udp6-sendto:[::1]:12345
00:00:40.535488 IP6 ::1 > ::1: frag (0|1448) ESP(spi=0x00000001,seq=0x6), length 1448
00:00:00.000010 IP6 ::1 > ::1: frag (1448|64)What happens in step (3) is:
1) when connecting the socket in __ip6_datagram_connect(), we perform an XFRM lookup, miss the flow cache, create an XFRM bundle, and cache the destination,
2) afterwards, when sending the datagram, we perform an XFRM lookup, again, miss the flow cache (due to mismatch of flowi6_iif and flowi6_oif, which is an issue of its own), and recreate an XFRM bundle based on the cached (and already transformed) destination.
To prevent the recreation of an XFRM bundle, avoid an XFRM lookup altogether whenever we already have a destination entry cached in the socket. This prevents the path MTU shrinkage and brings us on par with UDPv4.
The fix also benefits connected PINGv6 sockets, another user of ip6_sk_dst_lookup_flow(), who also suffer messages being transformed twice.
Joint work with Hannes Frederic Sowa.
--- net/ipv6/ip6_output.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
net/ipv6/ip6_output.c +3 -8
@@ -1072,17 +1072,12 @@ struct dst_entry *ip6_sk_dst_lookup_flow const struct in6_addr *final_dst) {struct dst_entry *dst =sk_dst_check (sk,inet6_sk (sk)->dst_cookie); -int err; dst =ip6_sk_dst_check (sk, dst, fl6); +if (!dst) + dst =ip6_dst_lookup_flow (sk, fl6, final_dst); - err =ip6_dst_lookup_tail (sock_net (sk), sk, &dst, fl6); -if (err) -return ERR_PTR (err); -if (final_dst) - fl6->daddr = *final_dst; - -return xfrm_lookup_route (sock_net (sk), dst,flowi6_to_flowi (fl6), sk,0 ); +return dst; }EXPORT_SYMBOL_GPL (ip6_sk_dst_lookup_flow);
Greg Kroah-Hartman
maintainerPATCH 19/75 vxlan: Relax MTU constraints
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Wragg <[email protected]>
[ Upstream commit 72564b59ffc438ea103b0727a921aaddce766728 ]
Allow the MTU of vxlan devices without an underlying device to be set to larger values (up to a maximum based on IP packet limits and vxlan overhead).
Previously, their MTUs could not be set to higher than the conventional ethernet value of 1500. This is a very arbitrary value in the context of vxlan, and prevented vxlan devices from being able to take advantage of jumbo frames etc.
The default MTU remains 1500, for compatibility.
--- drivers/net/vxlan.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-)
drivers/net/vxlan.c +25 -11
@@ -2364,29 +2364,43 @@ static void vxlan_set_multicast_list(str { } -static int vxlan_change_mtu (struct net_device *dev,int new_mtu) +static int __vxlan_change_mtu (struct net_device *dev, +struct net_device *lowerdev, +struct vxlan_rdst *dst,int new_mtu,bool strict) { -struct vxlan_dev *vxlan =netdev_priv (dev); -struct vxlan_rdst *dst = &vxlan->default_dst; -struct net_device *lowerdev; -int max_mtu; +int max_mtu =IP_MAX_MTU ; - lowerdev =__dev_get_by_index (vxlan->net, dst->remote_ifindex); -if (lowerdev ==NULL ) -return eth_change_mtu (dev, new_mtu); +if (lowerdev) + max_mtu = lowerdev->mtu;if (dst->remote_ip.sa.sa_family ==AF_INET6 ) - max_mtu = lowerdev->mtu -VXLAN6_HEADROOM ; + max_mtu -=VXLAN6_HEADROOM ;else - max_mtu = lowerdev->mtu -VXLAN_HEADROOM ; + max_mtu -=VXLAN_HEADROOM ; -if (new_mtu <68 || new_mtu > max_mtu) +if (new_mtu <68 )return -EINVAL ; +if (new_mtu > max_mtu) { +if (strict) +return -EINVAL ; + + new_mtu = max_mtu; + } + dev->mtu = new_mtu;return 0 ; } +static int vxlan_change_mtu (struct net_device *dev,int new_mtu) +{ +struct vxlan_dev *vxlan =netdev_priv (dev); +struct vxlan_rdst *dst = &vxlan->default_dst; +struct net_device *lowerdev =__dev_get_by_index (vxlan->net, + dst->remote_ifindex); +return __vxlan_change_mtu (dev, lowerdev, dst, new_mtu, true); +} +static int egress_ipv4_tun_info (struct net_device *dev,struct sk_buff *skb,struct ip_tunnel_info *info,__be16 sport,__be16 dport)
Greg Kroah-Hartman
maintainerPATCH 20/75 geneve: Relax MTU constraints
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Wragg <[email protected]>
[ Upstream commit 55e5bfb53cff286c1c1ff49f51325dc15c7fea63 ]
Allow the MTU of geneve devices to be set to large values, in order to exploit underlying networks with larger frame sizes.
GENEVE does not have a fixed encapsulation overhead (an openvswitch rule can add variable length options), so there is no relevant maximum MTU to enforce. A maximum of IP_MAX_MTU is used instead. Encapsulated packets that are too big for the underlying network will get dropped on the floor.
--- drivers/net/geneve.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/net/geneve.c +12 -1
@@ -994,6 +994,17 @@ static netdev_tx_t geneve_xmit(struct skreturn geneve_xmit_skb (skb, dev, info); } +static int geneve_change_mtu (struct net_device *dev,int new_mtu) +{ +/* GENEVE overhead is not fixed, so we can't enforce a more +* precise max MTU. +*/ +if (new_mtu <68 || new_mtu >IP_MAX_MTU ) +return -EINVAL ; + dev->mtu = new_mtu; +return 0 ; +} +static int geneve_fill_metadata_dst (struct net_device *dev,struct sk_buff *skb) {struct ip_tunnel_info *info =skb_tunnel_info (skb);
@@ -1038,7 +1049,7 @@ static const struct net_device_ops genev .ndo_stop = geneve_stop, .ndo_start_xmit = geneve_xmit, .ndo_get_stats64 = ip_tunnel_get_stats64, - .ndo_change_mtu = eth_change_mtu, + .ndo_change_mtu = geneve_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_fill_metadata_dst = geneve_fill_metadata_dst,
Greg Kroah-Hartman
maintainerPATCH 21/75 vxlan, gre, geneve: Set a large MTU on ovs-created tunnel devices
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Wragg <[email protected]>
[ Upstream commit 7e059158d57b79159eaf1f504825d19866ef2c42 ]
Prior to 4.3, openvswitch tunnel vports (vxlan, gre and geneve) could transmit vxlan packets of any size, constrained only by the ability to send out the resulting packets. 4.3 introduced netdevs corresponding to tunnel vports. These netdevs have an MTU, which limits the size of a packet that can be successfully encapsulated. The default MTU values are low (1500 or less), which is awkwardly small in the context of physical networks supporting jumbo frames, and leads to a conspicuous change in behaviour for userspace.
Instead, set the MTU on openvswitch-created netdevs to be the relevant maximum (i.e. the maximum IP packet size minus any relevant overhead), effectively restoring the behaviour prior to 4.3.
--- drivers/net/geneve.c | 18 ++++++++++++++---- drivers/net/vxlan.c | 11 ++++++++--- include/net/ip_tunnels.h | 1 + net/ipv4/ip_gre.c | 8 ++++++++ net/ipv4/ip_tunnel.c | 20 +++++++++++++++++--- net/openvswitch/vport-vxlan.c | 2 ++ 6 files changed, 50 insertions(+), 10 deletions(-)
drivers/net/geneve.c +14 -4
@@ -1356,11 +1356,21 @@ struct net_device *geneve_dev_create_fb( err =geneve_configure (net, dev, &geneve_remote_unspec,0 ,0 ,0 ,htons (dst_port), true); -if (err) { -free_netdev (dev); -return ERR_PTR (err); - } +if (err) + goto err; + +/* openvswitch users expect packet sizes to be unrestricted, +* so set the largest MTU we can. +*/ + err =geneve_change_mtu (dev,IP_MAX_MTU ); +if (err) + goto err; +return dev; + + err: +free_netdev (dev); +return ERR_PTR (err); }EXPORT_SYMBOL_GPL (geneve_dev_create_fb);
drivers/net/vxlan.c +8 -3
@@ -2776,6 +2776,7 @@ static int vxlan_dev_configure(struct neint err;bool use_ipv6 = false;__be16 default_port = vxlan->cfg.dst_port; +struct net_device *lowerdev =NULL ; vxlan->net = src_net;
@@ -2796,9 +2797,7 @@ static int vxlan_dev_configure(struct ne }if (conf->remote_ifindex) { -struct net_device *lowerdev - =__dev_get_by_index (src_net, conf->remote_ifindex); - + lowerdev =__dev_get_by_index (src_net, conf->remote_ifindex); dst->remote_ifindex = conf->remote_ifindex;if (!lowerdev) {
@@ -2822,6 +2821,12 @@ static int vxlan_dev_configure(struct ne needed_headroom = lowerdev->hard_header_len; } +if (conf->mtu) { + err =__vxlan_change_mtu (dev, lowerdev, dst, conf->mtu, false); +if (err) +return err; + } +if (use_ipv6 || conf->flags &VXLAN_F_COLLECT_METADATA ) needed_headroom +=VXLAN6_HEADROOM ;else
include/net/ip_tunnels.h +1 -0
@@ -230,6 +230,7 @@ void ip_tunnel_xmit(struct sk_buff *skb,int ip_tunnel_ioctl (struct net_device *dev,struct ip_tunnel_parm *p,int cmd);int ip_tunnel_encap (struct sk_buff *skb,struct ip_tunnel *t,u8 *protocol,struct flowi4 *fl4); +int __ip_tunnel_change_mtu (struct net_device *dev,int new_mtu,bool strict);int ip_tunnel_change_mtu (struct net_device *dev,int new_mtu); struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev,
net/ipv4/ip_gre.c +8 -0
@@ -1247,6 +1247,14 @@ struct net_device *gretap_fb_dev_create( err =ipgre_newlink (net, dev, tb,NULL );if (err <0 ) goto out; + +/* openvswitch users expect packet sizes to be unrestricted, +* so set the largest MTU we can. +*/ + err =__ip_tunnel_change_mtu (dev,IP_MAX_MTU , false); +if (err) + goto out; +return dev; out:free_netdev (dev);
net/ipv4/ip_tunnel.c +17 -3
@@ -948,17 +948,31 @@ done: }EXPORT_SYMBOL_GPL (ip_tunnel_ioctl); -int ip_tunnel_change_mtu (struct net_device *dev,int new_mtu) +int __ip_tunnel_change_mtu (struct net_device *dev,int new_mtu,bool strict) {struct ip_tunnel *tunnel =netdev_priv (dev);int t_hlen = tunnel->hlen +sizeof (struct iphdr ); +int max_mtu =0xFFF8 - dev->hard_header_len - t_hlen; -if (new_mtu <68 || - new_mtu >0xFFF8 - dev->hard_header_len - t_hlen) +if (new_mtu <68 )return -EINVAL ; + +if (new_mtu > max_mtu) { +if (strict) +return -EINVAL ; + + new_mtu = max_mtu; + } + dev->mtu = new_mtu;return 0 ; } +EXPORT_SYMBOL_GPL (__ip_tunnel_change_mtu); + +int ip_tunnel_change_mtu (struct net_device *dev,int new_mtu) +{ +return __ip_tunnel_change_mtu (dev, new_mtu, true); +}EXPORT_SYMBOL_GPL (ip_tunnel_change_mtu);static void ip_tunnel_dev_free (struct net_device *dev)
net/openvswitch/vport-vxlan.c +2 -0
@@ -91,6 +91,8 @@ static struct vport *vxlan_tnl_create(costruct vxlan_config conf = { .no_share = true, .flags =VXLAN_F_COLLECT_METADATA |VXLAN_F_UDP_ZERO_CSUM6_RX , +/* Don't restrict the packets that can be sent by MTU */ + .mtu =IP_MAX_MTU , };if (!options) {
Greg Kroah-Hartman
maintainerPATCH 24/75 ALSA: hda - Add PCI ID for Kabylake
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vinod Koul <[email protected]>
commit 35639a0e98391036a4c7f23253c321d6621a8897 upstream.
Kabylake shows up as PCI ID 0xa171. And Kabylake-LP as 0x9d71. Since these are similar to Skylake add these to SKL_PLUS macro
--- sound/pci/hda/hda_intel.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
sound/pci/hda/hda_intel.c +10 -1
@@ -359,8 +359,11 @@ enum {#define IS_SKL (pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)#define IS_SKL_LP (pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70) +#define IS_KBL (pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa171) +#define IS_KBL_LP (pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)#define IS_BXT (pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) -#define IS_SKL_PLUS (pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) +#define IS_SKL_PLUS (pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \ + IS_KBL(pci) || IS_KBL_LP(pci)static char *driver_short_names[] = { [AZX_DRIVER_ICH ] ="HDA Intel" ,
@@ -2204,6 +2207,12 @@ static const struct pci_device_id azx_id/* Sunrise Point-LP */ { PCI_DEVICE(0x8086, 0x9d70), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, + /* Kabylake */ + { PCI_DEVICE(0x8086, 0xa171), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, + /* Kabylake-LP */ + { PCI_DEVICE(0x8086, 0x9d71), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, /* Broxton-P(Apollolake) */ { PCI_DEVICE(0x8086, 0x5a98), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
Greg Kroah-Hartman
maintainerPATCH 25/75 ALSA: hda - Fix headset mic detection problem for Dell machine
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: AceLan Kao <[email protected]>
commit f90d83b301701026b2e4c437a3613f377f63290e upstream.
Add the pin configuration value of this machine into the pin_quirk table to make DELL1_MIC_NO_PRESENCE apply to this machine.
--- sound/pci/hda/patch_realtek.c | 4 ++++ 1 file changed, 4 insertions(+)
sound/pci/hda/patch_realtek.c +4 -0
@@ -5775,6 +5775,10 @@ static const struct snd_hda_pin_quirk al {0x12, 0x90a60180}, {0x14, 0x90170130}, {0x21, 0x02211040}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60180}, + {0x14, 0x90170120}, + {0x21, 0x02211030}), SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, {0x12, 0x90a60160}, {0x14, 0x90170120},
Greg Kroah-Hartman
maintainerPATCH 26/75 ALSA: hda/realtek - ALC256 speaker noise issue
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
commit e69e7e03ed225abf3e1c43545aa3bcb68dc81d5f upstream.
That is some different register for ALC255 and ALC256. ALC256 can't fit with some ALC255 register. This issue is cause from LDO output voltage control. This patch is updated the right LDO register value.
--- sound/pci/hda/patch_realtek.c | 52 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-)
sound/pci/hda/patch_realtek.c +47 -5
@@ -3618,13 +3618,20 @@ static void alc269_fixup_hp_line1_mic1_lstatic void alc_headset_mode_unplugged (struct hda_codec *codec) {static struct coef_fw coef0255[] = { -WRITE_COEF (0x1b ,0x0c0b ),/* LDO and MISC control */ WRITE_COEF (0x45 ,0xd089 ),/* UAJ function set to menual mode */ UPDATE_COEFEX (0x57 ,0x05 ,1 <<14 ,0 ),/* Direct Drive HP Amp control(Set to verb control)*/ WRITE_COEF (0x06 ,0x6104 ),/* Set MIC2 Vref gate with HP */ WRITE_COEFEX (0x57 ,0x03 ,0x8aa6 ),/* Direct Drive HP Amp control */ {} }; +static struct coef_fw coef0255_1[] = { +WRITE_COEF (0x1b ,0x0c0b ),/* LDO and MISC control */ + {} + }; +static struct coef_fw coef0256[] = { +WRITE_COEF (0x1b ,0x0c4b ),/* LDO and MISC control */ + {} + };static struct coef_fw coef0233[] = {WRITE_COEF (0x1b ,0x0c0b ),WRITE_COEF (0x45 ,0xc429 ),
@@ -3677,7 +3684,11 @@ static void alc_headset_mode_unplugged(sswitch (codec->core.vendor_id) {case 0x10ec0255 : +alc_process_coef_fw (codec, coef0255_1); +alc_process_coef_fw (codec, coef0255); +break ;case 0x10ec0256 : +alc_process_coef_fw (codec, coef0256);alc_process_coef_fw (codec, coef0255);break ;case 0x10ec0233 :
@@ -3896,6 +3907,12 @@ static void alc_headset_mode_ctia(struct WRITE_COEFEX(0x57, 0x03, 0x8ea6), {} }; +static struct coef_fw coef0256[] = { +WRITE_COEF (0x45 ,0xd489 ),/* Set to CTIA type */ +WRITE_COEF (0x1b ,0x0c6b ), +WRITE_COEFEX (0x57 ,0x03 ,0x8ea6 ), + {} + };static struct coef_fw coef0233[] = {WRITE_COEF (0x45 ,0xd429 ),WRITE_COEF (0x1b ,0x0c2b ),
@@ -3936,9 +3953,11 @@ static void alc_headset_mode_ctia(structswitch (codec->core.vendor_id) {case 0x10ec0255 : -case 0x10ec0256 :alc_process_coef_fw (codec, coef0255);break ; +case 0x10ec0256 : +alc_process_coef_fw (codec, coef0256); +break ;case 0x10ec0233 :case 0x10ec0283 :alc_process_coef_fw (codec, coef0233);
@@ -3978,6 +3997,12 @@ static void alc_headset_mode_omtp(struct WRITE_COEFEX(0x57, 0x03, 0x8ea6), {} }; +static struct coef_fw coef0256[] = { +WRITE_COEF (0x45 ,0xe489 ),/* Set to OMTP Type */ +WRITE_COEF (0x1b ,0x0c6b ), +WRITE_COEFEX (0x57 ,0x03 ,0x8ea6 ), + {} + };static struct coef_fw coef0233[] = {WRITE_COEF (0x45 ,0xe429 ),WRITE_COEF (0x1b ,0x0c2b ),
@@ -4018,9 +4043,11 @@ static void alc_headset_mode_omtp(structswitch (codec->core.vendor_id) {case 0x10ec0255 : -case 0x10ec0256 :alc_process_coef_fw (codec, coef0255);break ; +case 0x10ec0256 : +alc_process_coef_fw (codec, coef0256); +break ;case 0x10ec0233 :case 0x10ec0283 :alc_process_coef_fw (codec, coef0233);
@@ -4266,7 +4293,7 @@ static void alc_fixup_headset_mode_no_hpstatic void alc255_set_default_jack_type (struct hda_codec *codec) {/* Set to iphone type */ -static struct coef_fw fw[] = { +static struct coef_fw alc255fw[] = {WRITE_COEF (0x1b ,0x880b ),WRITE_COEF (0x45 ,0xd089 ),WRITE_COEF (0x1b ,0x080b ),
@@ -4274,7 +4301,22 @@ static void alc255_set_default_jack_type WRITE_COEF(0x1b, 0x0c0b), {} }; -alc_process_coef_fw (codec, fw); +static struct coef_fw alc256fw[] = { +WRITE_COEF (0x1b ,0x884b ), +WRITE_COEF (0x45 ,0xd089 ), +WRITE_COEF (0x1b ,0x084b ), +WRITE_COEF (0x46 ,0x0004 ), +WRITE_COEF (0x1b ,0x0c4b ), + {} + }; +switch (codec->core.vendor_id) { +case 0x10ec0255 : +alc_process_coef_fw (codec, alc255fw); +break ; +case 0x10ec0256 : +alc_process_coef_fw (codec, alc256fw); +break ; + }msleep (30 ); }
Greg Kroah-Hartman
maintainerPATCH 27/75 ALSA: hda/realtek - Add support for new codecs ALC700/ALC701/ALC703
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
commit 6fbae35a3170c3e2b1b9d7b9cc943cbe48771362 upstream.
Support new codecs for ALC700/ALC701/ALC703.
--- sound/pci/hda/patch_realtek.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
sound/pci/hda/patch_realtek.c +16 -0
@@ -346,6 +346,9 @@ static void alc_fill_eapd_coef(struct hdcase 0x10ec0234 :case 0x10ec0274 :case 0x10ec0294 : +case 0x10ec0700 : +case 0x10ec0701 : +case 0x10ec0703 :alc_update_coef_idx (codec,0x10 ,1 <<15 ,0 );break ;case 0x10ec0662 :
@@ -2655,6 +2658,7 @@ enum {ALC269_TYPE_ALC256 ,ALC269_TYPE_ALC225 ,ALC269_TYPE_ALC294 , + ALC269_TYPE_ALC700, };/*
@@ -2686,6 +2690,7 @@ static int alc269_parse_auto_config(strucase ALC269_TYPE_ALC256 :case ALC269_TYPE_ALC225 :case ALC269_TYPE_ALC294 : +case ALC269_TYPE_ALC700 : ssids = alc269_ssids;break ;default :
@@ -6099,6 +6104,14 @@ static int patch_alc269(struct hda_codeccase 0x10ec0294 : spec->codec_variant =ALC269_TYPE_ALC294 ;break ; +case 0x10ec0700 : +case 0x10ec0701 : +case 0x10ec0703 : + spec->codec_variant =ALC269_TYPE_ALC700 ; + spec->gen.mixer_nid =0 ;/* ALC700 does not have any loopback mixer path */ +alc_update_coef_idx (codec,0x4a ,0 ,1 <<15 );/* Combo jack auto trigger control */ +break ; + }if (snd_hda_codec_read (codec,0x51 ,0 ,AC_VERB_PARAMETERS ,0 ) ==0x10ec5505 ) {
@@ -7054,6 +7067,9 @@ static const struct hda_device_id snd_hdHDA_CODEC_ENTRY (0x10ec0670 ,"ALC670" , patch_alc662),HDA_CODEC_ENTRY (0x10ec0671 ,"ALC671" , patch_alc662),HDA_CODEC_ENTRY (0x10ec0680 ,"ALC680" , patch_alc680), +HDA_CODEC_ENTRY (0x10ec0700 ,"ALC700" , patch_alc269), +HDA_CODEC_ENTRY (0x10ec0701 ,"ALC701" , patch_alc269), +HDA_CODEC_ENTRY (0x10ec0703 ,"ALC703" , patch_alc269),HDA_CODEC_ENTRY (0x10ec0867 ,"ALC891" , patch_alc882),HDA_CODEC_ENTRY (0x10ec0880 ,"ALC880" , patch_alc880), HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
Greg Kroah-Hartman
maintainerPATCH 28/75 ALSA: hda/realtek: Add T560 docking unit fixup
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Torsten Hilbrich <[email protected]>
commit dab38e43b298501a4e8807b56117c029e2e98383 upstream.
Tested with Lenovo Ultradock. Fixes the non-working headphone jack on the docking unit.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -5634,6 +5634,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x17aa ,0x2218 ,"Thinkpad X1 Carbon 2nd" ,ALC292_FIXUP_TPT440_DOCK ),SND_PCI_QUIRK (0x17aa ,0x2223 ,"ThinkPad T550" ,ALC292_FIXUP_TPT440_DOCK ),SND_PCI_QUIRK (0x17aa ,0x2226 ,"ThinkPad X250" ,ALC292_FIXUP_TPT440_DOCK ), +SND_PCI_QUIRK (0x17aa ,0x2231 ,"Thinkpad T560" ,ALC292_FIXUP_TPT460 ),SND_PCI_QUIRK (0x17aa ,0x2233 ,"Thinkpad" ,ALC292_FIXUP_TPT460 ),SND_PCI_QUIRK (0x17aa ,0x30bb ,"ThinkCentre AIO" ,ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY ), SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Greg Kroah-Hartman
maintainerPATCH 29/75 ARM: fix PTRACE_SETVFPREGS on SMP systems
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King <[email protected]>
commit e2dfb4b880146bfd4b6aa8e138c0205407cebbaf upstream.
PTRACE_SETVFPREGS fails to properly mark the VFP register set to be reloaded, because it undoes one of the effects of vfp_flush_hwstate().
Specifically vfp_flush_hwstate() sets thread->vfpstate.hard.cpu to an invalid CPU number, but vfp_set() overwrites this with the original CPU number, thereby rendering the hardware state as apparently "valid", even though the software state is more recent.
Fix this by reverting the previous change.
--- arch/arm/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/ptrace.c +1 -1
@@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *tif (ret)return ret; -vfp_flush_hwstate (thread); thread->vfpstate.hard = new_vfp; +vfp_flush_hwstate (thread);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 30/75 gpio: bcm-kona: fix bcm_kona_gpio_reset() warnings
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Dooks <[email protected]>
commit b66b2a0adf0e48973b582e055758b9907a7eee7c upstream.
The bcm_kona_gpio_reset() calls bcm_kona_gpio_write_lock_regs() with what looks like the wrong parameter. The write_lock_regs function takes a pointer to the registers, not the bcm_kona_gpio structure.
Fix the warning, and probably bug by changing the function to pass reg_base instead of kona_gpio, fixing the following warning:
drivers/gpio/gpio-bcm-kona.c:550:47: warning: incorrect type in argument 1
(different address spaces)
expected void [noderef] <asn:2>*reg_base
got struct bcm_kona_gpio *kona_gpio
warning: incorrect type in argument 1 (different address spaces) expected void [noderef] <asn:2>*reg_base
got struct bcm_kona_gpio *kona_gpio
--- drivers/gpio/gpio-bcm-kona.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpio/gpio-bcm-kona.c +2 -2
@@ -551,11 +551,11 @@ static void bcm_kona_gpio_reset(struct b/* disable interrupts and clear status */ for (i =0 ; i < kona_gpio->num_bank; i++) {/* Unlock the entire bank first */ -bcm_kona_gpio_write_lock_regs (kona_gpio, i,UNLOCK_CODE ); +bcm_kona_gpio_write_lock_regs (reg_base, i,UNLOCK_CODE );writel (0xffffffff , reg_base +GPIO_INT_MASK (i));writel (0xffffffff , reg_base +GPIO_INT_STATUS (i));/* Now re-lock the bank */ -bcm_kona_gpio_write_lock_regs (kona_gpio, i,LOCK_CODE ); +bcm_kona_gpio_write_lock_regs (reg_base, i,LOCK_CODE ); } }
Greg Kroah-Hartman
maintainerPATCH 31/75 s390/bpf: fix recache skb->data/hlen for skb_vlan_push/pop
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Holzheu <[email protected]>
commit 6edf0aa4f8bbdfbb4d6d786892fa02728d05dc36 upstream.
In case of usage of skb_vlan_push/pop, in the prologue we store the SKB pointer on the stack and restore it after BPF_JMP_CALL to skb_vlan_push/pop.
Unfortunately currently there are two bugs in the code:
1) The wrong stack slot (offset 170 instead of 176) is used
2) The wrong register (W1 instead of B1) is saved
So fix this and use correct stack slot and register.
--- arch/s390/net/bpf_jit.h | 4 ++-- arch/s390/net/bpf_jit_comp.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/s390/net/bpf_jit.h +2 -2
@@ -37,7 +37,7 @@ extern u8 sk_load_word[], sk_load_half[]* | | | * +---------------+ | * | 8 byte skbp | | -* R15+170 -> +---------------+ | +* R15+176 -> +---------------+ | * | 8 byte hlen | | * R15+168 -> +---------------+ | * | 4 byte align | |
@@ -58,7 +58,7 @@ extern u8 sk_load_word[], sk_load_half[]#define STK_OFF (STK_SPACE - STK_160_UNUSED)#define STK_OFF_TMP 160/* Offset of tmp buffer on stack */ #define STK_OFF_HLEN 168/* Offset of SKB header length on stack */ -#define STK_OFF_SKBP 170/* Offset of SKB pointer on stack */ +#define STK_OFF_SKBP 176/* Offset of SKB pointer on stack */ #define STK_OFF_R6 (160 - 11 * 8)/* Offset of r6 on stack */ #define STK_OFF_TCCNT (160 - 12 * 8)/* Offset of tail_call_cnt on stack */
arch/s390/net/bpf_jit_comp.c +1 -1
@@ -446,7 +446,7 @@ static void bpf_jit_prologue(struct bpf_emit_load_skb_data_hlen (jit);if (jit->seen &SEEN_SKB_CHANGE )/* stg %b1,ST_OFF_SKBP(%r0,%r15) */ -EMIT6_DISP_LH (0xe3000000 ,0x0024 ,REG_W1 ,REG_0 ,REG_15 , +EMIT6_DISP_LH (0xe3000000 ,0x0024 ,BPF_REG_1 ,REG_0 ,REG_15 ,STK_OFF_SKBP );/* Clear A (%b0) and X (%b7) registers for converted BPF programs */ if (is_classic) {
Greg Kroah-Hartman
maintainerPATCH 32/75 s390/bpf: reduce maximum program size to 64 KB
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Holzheu <[email protected]>
commit 0fa963553a5c28d8f8aabd8878326d3f782045fc upstream.
The s390 BFP compiler currently uses relative branch instructions that only support jumps up to 64 KB. Examples are "j", "jnz", "cgrj", etc. Currently the maximum size of s390 BPF programs is set to 0x7ffff. If branches over 64 KB are generated the, kernel can crash due to incorrect code.
So fix this an reduce the maximum size to 64 KB. Programs larger than that will be interpreted.
--- arch/s390/net/bpf_jit_comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/net/bpf_jit_comp.c +1 -1
@@ -45,7 +45,7 @@ struct bpf_jit {int labels[1 ];/* Labels for local jumps */ }; -#define BPF_SIZE_MAX 0x7ffff/* Max size for program (20 bit signed displ) */ +#define BPF_SIZE_MAX 0xffff/* Max size for program (16 bit branches) */ #define SEEN_SKB 1/* skb access */ #define SEEN_MEM 2/* use mem[] for temporary storage */
Greg Kroah-Hartman
maintainerPATCH 33/75 irqchip/gic-v3: Fix ICC_SGI1R_EL1.INTID decoding mask
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
commit dd5f1b049dc139876801db3cdd0f20d21fd428cc upstream.
The INTID mask is wrong, and is made a signed value, which has nteresting effects in the KVM emulation. Let's sanitize it.
--- include/linux/irqchip/arm-gic-v3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/irqchip/arm-gic-v3.h +1 -1
@@ -301,7 +301,7 @@#define ICC_SGI1R_AFFINITY_1_SHIFT 16#define ICC_SGI1R_AFFINITY_1_MASK (0xff << ICC_SGI1R_AFFINITY_1_SHIFT)#define ICC_SGI1R_SGI_ID_SHIFT 24 -#define ICC_SGI1R_SGI_ID_MASK (0xff << ICC_SGI1R_SGI_ID_SHIFT) +#define ICC_SGI1R_SGI_ID_MASK (0xfULL << ICC_SGI1R_SGI_ID_SHIFT)#define ICC_SGI1R_AFFINITY_2_SHIFT 32#define ICC_SGI1R_AFFINITY_2_MASK (0xffULL << ICC_SGI1R_AFFINITY_1_SHIFT)#define ICC_SGI1R_IRQ_ROUTING_MODE_BIT 40
Greg Kroah-Hartman
maintainerPATCH 34/75 crypto: public_key: select CRYPTO_AKCIPHER
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit bad6a185b4d6f81d0ed2b6e4c16307969f160b95 upstream.
In some rare randconfig builds, we can end up with ASYMMETRIC_PUBLIC_KEY_SUBTYPE enabled but CRYPTO_AKCIPHER disabled, which fails to link because of the reference to crypto_alloc_akcipher:
crypto/built-in.o: In function `public_key_verify_signature':
:(.text+0x110e4): undefined reference to `crypto_alloc_akcipher'
This adds a Kconfig 'select' statement to ensure the dependency is always there.
--- crypto/asymmetric_keys/Kconfig | 1 + 1 file changed, 1 insertion(+)
crypto/asymmetric_keys/Kconfig +1 -0
@@ -14,6 +14,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE select MPILIB select PUBLIC_KEY_ALGO_RSA select CRYPTO_HASH_INFO + select CRYPTO_AKCIPHER help This option provides support for asymmetric public key type handling. If signature generation and/or verification are to be used,
Greg Kroah-Hartman
maintainerPATCH 35/75 crypto: ccp - Fix AES XTS error for request sizes above 4096
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Lendacky <[email protected]>
commit ab6a11a7c8ef47f996974dd3c648c2c0b1a36ab1 upstream.
The ccp-crypto module for AES XTS support has a bug that can allow requests greater than 4096 bytes in size to be passed to the CCP hardware. The CCP hardware does not support request sizes larger than 4096, resulting in incorrect output. The request should actually be handled by the fallback mechanism instantiated by the ccp-crypto module.
Add a check to insure the request size is less than or equal to the maximum supported size and use the fallback mechanism if it is not.
--- drivers/crypto/ccp/ccp-crypto-aes-xts.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/crypto/ccp/ccp-crypto-aes-xts.c +12 -5
@@ -122,6 +122,7 @@ static int ccp_aes_xts_crypt(struct ablkstruct ccp_ctx *ctx =crypto_tfm_ctx (req->base.tfm);struct ccp_aes_req_ctx *rctx =ablkcipher_request_ctx (req);unsigned int unit; +u32 unit_size;int ret;if (!ctx->u.aes.key_len)
@@ -133,11 +134,17 @@ static int ccp_aes_xts_crypt(struct ablkif (!req->info)return -EINVAL ; -for (unit =0 ; unit <ARRAY_SIZE (unit_size_map); unit++) -if (!(req->nbytes & (unit_size_map[unit].size -1 ))) -break ; + unit_size =CCP_XTS_AES_UNIT_SIZE__LAST ; +if (req->nbytes <= unit_size_map[0 ].size) { +for (unit =0 ; unit <ARRAY_SIZE (unit_size_map); unit++) { +if (!(req->nbytes & (unit_size_map[unit].size -1 ))) { + unit_size = unit_size_map[unit].value; +break ; + } + } + } -if ((unit_size_map[unit].value ==CCP_XTS_AES_UNIT_SIZE__LAST ) || +if ((unit_size ==CCP_XTS_AES_UNIT_SIZE__LAST ) || (ctx->u.aes.key_len !=AES_KEYSIZE_128 )) {/* Use the fallback to process the request for any * unsupported unit sizes or key sizes
@@ -158,7 +165,7 @@ static int ccp_aes_xts_crypt(struct ablk rctx->cmd.engine =CCP_ENGINE_XTS_AES_128 ; rctx->cmd.u.xts.action = (encrypt) ?CCP_AES_ACTION_ENCRYPT :CCP_AES_ACTION_DECRYPT ; - rctx->cmd.u.xts.unit_size = unit_size_map[unit].value; + rctx->cmd.u.xts.unit_size = unit_size; rctx->cmd.u.xts.key = &ctx->u.aes.key_sg; rctx->cmd.u.xts.key_len = ctx->u.aes.key_len; rctx->cmd.u.xts.iv = &rctx->iv_sg;
Greg Kroah-Hartman
maintainerPATCH 36/75 arm64: Provide "model name" in /proc/cpuinfo for PER_LINUX32 tasks
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
commit e47b020a323d1b2a7b1e9aac86e99eae19463630 upstream.
This patch brings the PER_LINUX32 /proc/cpuinfo format more in line with the 32-bit ARM one by providing an additional line:
model name : ARMv8 Processor rev X (v8l)
--- arch/arm64/include/asm/elf.h | 4 ++-- arch/arm64/kernel/cpuinfo.c | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-)
arch/arm64/include/asm/elf.h +2 -2
@@ -156,14 +156,14 @@ extern int arch_setup_additional_pages(s#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))#endif -#ifdef CONFIG_COMPAT -#ifdef __AARCH64EB__#define COMPAT_ELF_PLATFORM ("v8b")#else #define COMPAT_ELF_PLATFORM ("v8l")#endif +#ifdef CONFIG_COMPAT +#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)/* AArch32 registers. */
arch/arm64/kernel/cpuinfo.c +7 -1
@@ -22,6 +22,8 @@#include <linux/bitops.h> #include <linux/bug.h> +#include <linux/compat.h> +#include <linux/elf.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/personality.h>
@@ -102,6 +104,7 @@ static const char *const compat_hwcap2_sstatic int c_show (struct seq_file *m,void *v) {int i, j; +bool compat =personality (current->personality) ==PER_LINUX32 ;for_each_online_cpu (i) {struct cpuinfo_arm64 *cpuinfo = &per_cpu (cpu_data, i);
@@ -113,6 +116,9 @@ static int c_show(struct seq_file *m, vo* "processor". Give glibc what it expects. */ seq_printf (m,"processor\t: %d\n" , i); +if (compat) +seq_printf (m,"model name\t: ARMv8 Processor rev %d (%s)\n" , +MIDR_REVISION (midr),COMPAT_ELF_PLATFORM ); seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", loops_per_jiffy / (500000UL/HZ),
@@ -125,7 +131,7 @@ static int c_show(struct seq_file *m, vo* software which does already (at least for 32-bit). */ seq_puts (m,"Features\t:" ); -if (personality (current->personality) ==PER_LINUX32 ) { +if (compat) {#ifdef CONFIG_COMPAT for (j =0 ; compat_hwcap_str[j]; j++)if (compat_elf_hwcap & (1 << j))
Greg Kroah-Hartman
maintainerPATCH 37/75 arm64: mm: always take dirty state from new pte in ptep_set_access_flags
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit 0106d456c4cb1770253fefc0ab23c9ca760b43f7 upstream.
Commit 66dbd6e61a52 ("arm64: Implement ptep_set_access_flags() for hardware AF/DBM") ensured that pte flags are updated atomically in the face of potential concurrent, hardware-assisted updates. However, Alex reports that:
| This patch breaks swapping for me. | In the broken case, you'll see either systemd cpu time spike (because | it's stuck in a page fault loop) or the system hang (because the | application owning the screen is stuck in a page fault loop).
It turns out that this is because the 'dirty' argument to ptep_set_access_flags is always 0 for read faults, and so we can't use it to set PTE_RDONLY. The failing sequence is:
1. We put down a PTE_WRITE | PTE_DIRTY | PTE_AF pte
2. Memory pressure -> pte_mkold(pte) -> clear PTE_AF
3. A read faults due to the missing access flag
4. ptep_set_access_flags is called with dirty = 0, due to the read fault
5. pte is then made PTE_WRITE | PTE_DIRTY | PTE_AF | PTE_RDONLY (!)
6. A write faults, but pte_write is true so we get stuck
The solution is to check the new page table entry (as would be done by the generic, non-atomic definition of ptep_set_access_flags that just calls set_pte_at) to establish the dirty state.
--- arch/arm64/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/mm/fault.c +1 -1
@@ -109,7 +109,7 @@ int ptep_set_access_flags(struct vm_area* PTE_RDONLY is cleared by default in the asm below, so set it in * back if necessary (read-only or clean PTE). */ -if (!pte_write (entry) || !dirty) +if (!pte_write (entry) || !pte_sw_dirty (entry))pte_val (entry) |=PTE_RDONLY ;/*
Greg Kroah-Hartman
maintainerPATCH 38/75 powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell Currey <[email protected]>
commit 871e178e0f2c4fa788f694721a10b4758d494ce1 upstream.
In the "ibm,configure-pe" and "ibm,configure-bridge" RTAS calls, the spec states that values of 9900-9905 can be returned, indicating that software should delay for 10^x (where x is the last digit, i.e. 990x) milliseconds and attempt the call again. Currently, the kernel doesn't know about this, and respecting it fixes some PCI failures when the hypervisor is busy.
The delay is capped at 0.2 seconds.
--- arch/powerpc/platforms/pseries/eeh_pseries.c | 51 +++++++++++++++++++-------- 1 file changed, 36 insertions(+), 15 deletions(-)
arch/powerpc/platforms/pseries/eeh_pseries.c +36 -15
@@ -615,29 +615,50 @@ static int pseries_eeh_configure_bridge( {int config_addr;int ret; +/* Waiting 0.2s maximum before skipping configuration */ +int max_wait =200 ;/* Figure out the PE address */ config_addr = pe->config_addr;if (pe->addr) config_addr = pe->addr; -/* Use new configure-pe function, if supported */ -if (ibm_configure_pe !=RTAS_UNKNOWN_SERVICE ) { - ret =rtas_call (ibm_configure_pe,3 ,1 ,NULL , - config_addr,BUID_HI (pe->phb->buid), -BUID_LO (pe->phb->buid)); - }else if (ibm_configure_bridge !=RTAS_UNKNOWN_SERVICE ) { - ret =rtas_call (ibm_configure_bridge,3 ,1 ,NULL , - config_addr,BUID_HI (pe->phb->buid), -BUID_LO (pe->phb->buid)); - }else { -return -EFAULT ; - } +while (max_wait >0 ) { +/* Use new configure-pe function, if supported */ +if (ibm_configure_pe !=RTAS_UNKNOWN_SERVICE ) { + ret =rtas_call (ibm_configure_pe,3 ,1 ,NULL , + config_addr,BUID_HI (pe->phb->buid), +BUID_LO (pe->phb->buid)); + }else if (ibm_configure_bridge !=RTAS_UNKNOWN_SERVICE ) { + ret =rtas_call (ibm_configure_bridge,3 ,1 ,NULL , + config_addr,BUID_HI (pe->phb->buid), +BUID_LO (pe->phb->buid)); + }else { +return -EFAULT ; + } + +if (!ret) +return ret; + +/* +* If RTAS returns a delay value that's above 100ms, cut it +* down to 100ms in case firmware made a mistake. For more +* on how these delay values work see rtas_busy_delay_time +*/ +if (ret >RTAS_EXTENDED_DELAY_MIN +2 && + ret <=RTAS_EXTENDED_DELAY_MAX ) + ret =RTAS_EXTENDED_DELAY_MIN +2 ; -if (ret) -pr_warn ("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n" , - __func__, pe->phb->global_number, pe->addr, ret); + max_wait -=rtas_busy_delay_time (ret); + +if (max_wait <0 ) +break ; + +rtas_busy_delay (ret); + } +pr_warn ("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n" , + __func__, pe->phb->global_number, pe->addr, ret);return ret; }
Greg Kroah-Hartman
maintainerPATCH 39/75 powerpc: Fix definition of SIAR and SDAR registers
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Huth <[email protected]>
commit d23fac2b27d94aeb7b65536a50d32bfdc21fe01e upstream.
The SIAR and SDAR registers are available twice, one time as SPRs 780 / 781 (unprivileged, but read-only), and one time as the SPRs 796 / 797 (privileged, but read and write). The Linux kernel code currently uses the unprivileged SPRs - while this is OK for reading, writing to that register of course does not work.
Since the KVM code tries to write to this register, too (see the mtspr in book3s_hv_rmhandlers.S), the contents of this register sometimes get lost for the guests, e.g. during migration of a VM.
To fix this issue, simply switch to the privileged SPR numbers instead.
--- arch/powerpc/include/asm/reg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/reg.h +2 -2
@@ -744,13 +744,13 @@#define SPRN_PMC6 792#define SPRN_PMC7 793#define SPRN_PMC8 794 -#define SPRN_SIAR 780 -#define SPRN_SDAR 781#define SPRN_SIER 784#define SIER_SIPR 0x2000000/* Sampled MSR_PR */ #define SIER_SIHV 0x1000000/* Sampled MSR_HV */ #define SIER_SIAR_VALID 0x0400000/* SIAR contents valid */ #define SIER_SDAR_VALID 0x0200000/* SDAR contents valid */ +#define SPRN_SIAR 796 +#define SPRN_SDAR 797#define SPRN_TACR 888#define SPRN_TCSCR 889#define SPRN_CSIGR 890
Greg Kroah-Hartman
maintainerPATCH 40/75 powerpc: Use privileged SPR number for MMCR2
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Huth <[email protected]>
commit 8dd75ccb571f3c92c48014b3dabd3d51a115ab41 upstream.
We are already using the privileged versions of MMCR0, MMCR1 and MMCRA in the kernel, so for MMCR2, we should better use the privileged versions, too, to be consistent.
--- arch/powerpc/include/asm/reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/include/asm/reg.h +1 -1
@@ -707,7 +707,7 @@#define MMCR0_FCWAIT 0x00000002UL/* freeze counter in WAIT state */ #define MMCR0_FCHV 0x00000001UL/* freeze conditions in hypervisor mode */ #define SPRN_MMCR1 798 -#define SPRN_MMCR2 769 +#define SPRN_MMCR2 785#define SPRN_MMCRA 0x312#define MMCRA_SDSYNC 0x80000000UL/* SDAR synced with SIAR */ #define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
Greg Kroah-Hartman
maintainerPATCH 41/75 powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support call
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Huth <[email protected]>
commit 7cc851039d643a2ee7df4d18177150f2c3a484f5 upstream.
If we do not provide the PVR for POWER8NVL, a guest on this system currently ends up in PowerISA 2.06 compatibility mode on KVM, since QEMU does not provide a generic PowerISA 2.07 mode yet. So some new instructions from POWER8 (like "mtvsrd") get disabled for the guest, resulting in crashes when using code compiled explicitly for POWER8 (e.g. with the "-mcpu=power8" option of GCC).
--- arch/powerpc/kernel/prom_init.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/kernel/prom_init.c +1 -0
@@ -655,6 +655,7 @@ unsigned char ibm_architecture_vec[] = {W (0xffff0000 ),W (0x003e0000 ),/* POWER6 */ W (0xffff0000 ),W (0x003f0000 ),/* POWER7 */ W (0xffff0000 ),W (0x004b0000 ),/* POWER8E */ +W (0xffff0000 ),W (0x004c0000 ),/* POWER8NVL */ W (0xffff0000 ),W (0x004d0000 ),/* POWER8 */ W (0xffffffff ),W (0x0f000004 ),/* all 2.07-compliant */ W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
Greg Kroah-Hartman
maintainerPATCH 42/75 pinctrl: mediatek: fix dual-edge code defect
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: hongkun.cao <[email protected]>
commit 5edf673d07fdcb6498be24914f3f38f8d8843199 upstream.
When a dual-edge irq is triggered, an incorrect irq will be reported on condition that the external signal is not stable and this incorrect irq has been registered.
Correct the register offset.
--- drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/pinctrl/mediatek/pinctrl-mtk-common.c +3 -2
@@ -1191,9 +1191,10 @@ static void mtk_eint_irq_handler(structconst struct mtk_desc_pin *pin;chained_irq_enter (chip, desc); -for (eint_num =0 ; eint_num < pctl->devdata->ap_num; eint_num +=32 ) { +for (eint_num =0 ; + eint_num < pctl->devdata->ap_num; + eint_num +=32 , reg +=4 ) { status =readl (reg); - reg +=4 ;while (status) { offset =__ffs (status); index = eint_num + offset;
Greg Kroah-Hartman
maintainerPATCH 43/75 parisc: Fix pagefault crash in unaligned __get_user() call
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 8b78f260887df532da529f225c49195d18fef36b upstream.
One of the debian buildd servers had this crash in the syslog without any other information:
Unaligned handler failed, ret = -2
clock_adjtime (pid 22578): Unaligned data reference (code 28)
CPU: 1 PID: 22578 Comm: clock_adjtime Tainted: G E 4.5.0-2-parisc64-smp #1 Debian 4.5.4-1 task: 000000007d9960f8 ti: 00000001bde7c000 task.ti: 00000001bde7c000
YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI
PSW: 00001000000001001111100000001111 Tainted: G E
r00-03 000000ff0804f80f 00000001bde7c2b0 00000000402d2be8 00000001bde7c2b0 r04-07 00000000409e1fd0 00000000fa6f7fff 00000001bde7c148 00000000fa6f7fff r08-11 0000000000000000 00000000ffffffff 00000000fac9bb7b 000000000002b4d4 r12-15 000000000015241c 000000000015242c 000000000000002d 00000000fac9bb7b r16-19 0000000000028800 0000000000000001 0000000000000070 00000001bde7c218 r20-23 0000000000000000 00000001bde7c210 0000000000000002 0000000000000000 r24-27 0000000000000000 0000000000000000 00000001bde7c148 00000000409e1fd0 r28-31 0000000000000001 00000001bde7c320 00000001bde7c350 00000001bde7c218
sr00-03 0000000001200000 0000000001200000 0000000000000000 0000000001200000 sr04-07 0000000000000000 0000000000000000 0000000000000000 0000000000000000
IASQ: 0000000000000000 0000000000000000 IAOQ: 00000000402d2e84 00000000402d2e88
IIR: 0ca0d089 ISR: 0000000001200000 IOR: 00000000fa6f7fff
CPU: 1 CR30: 00000001bde7c000 CR31: ffffffffffffffff
ORIG_R28: 00000002369fe628
IAOQ[0]: compat_get_timex+0x2dc/0x3c0
IAOQ[1]: compat_get_timex+0x2e0/0x3c0
RP(r2): compat_get_timex+0x40/0x3c0
Backtrace: [<00000000402d4608>] compat_SyS_clock_adjtime+0x40/0xc0 [<0000000040205024>] syscall_exit+0x0/0x14
This means the userspace program clock_adjtime called the clock_adjtime() syscall and then crashed inside the compat_get_timex() function. Syscalls should never crash programs, but instead return EFAULT.
The IIR register contains the executed instruction, which disassebles into "ldw 0(sr3,r5),r9".
This load-word instruction is part of __get_user() which tried to read the word at %r5/IOR (0xfa6f7fff). This means the unaligned handler jumped in. The unaligned handler is able to emulate all ldw instructions, but it fails if it fails to read the source e.g. because of page fault.
The following program reproduces the problem:
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mman.h>
int main(void) {
/* allocate 8k */
char *ptr = mmap(NULL, 2*4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
/* free second half (upper 4k) and make it invalid. */
munmap(ptr+4096, 4096);
/* syscall where first int is unaligned and clobbers into invalid memory region */
/* syscall should return EFAULT */
return syscall(__NR_clock_adjtime, 0, ptr+4095);
}To fix this issue we simply need to check if the faulting instruction address is in the exception fixup table when the unaligned handler failed. If it is, call the fixup routine instead of crashing.
While looking at the unaligned handler I found another issue as well: The target register should not be modified if the handler was unsuccessful.
--- arch/parisc/kernel/unaligned.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
arch/parisc/kernel/unaligned.c +9 -1
@@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *rebreak ; } -if (modify &&R1 (regs->iir)) +if (ret ==0 && modify &&R1 (regs->iir)) regs->gr[R1 (regs->iir)] = newbase;
@@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *reif (ret) { +/* +* The unaligned handler failed. +* If we were called by __get_user() or __put_user() jump +* to it's exception fixup handler instead of crashing. +*/ +if (!user_mode (regs) &&fixup_exception (regs)) +return ; +printk (KERN_CRIT "Unaligned handler failed, ret = %d\n" , ret);die_if_kernel ("Unaligned data reference" , regs,28 );
Greg Kroah-Hartman
maintainerPATCH 44/75 memcg: add RCU locking around css_for_each_descendant_pre() in memcg_offline_kmem()
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit 3a06bb78ceeceacc86a1e31133a7944013f9775b upstream.
memcg_offline_kmem() may be called from memcg_free_kmem() after a css init failure. memcg_free_kmem() is a ->css_free callback which is called without cgroup_mutex and memcg_offline_kmem() ends up using css_for_each_descendant_pre() without any locking. Fix it by adding rcu read locking around it.
mkdir: cannot create directory `65530': No space left on device
===============================
[ INFO: suspicious RCU usage. ]
4.6.0-work+ #321 Not tainted
-------------------------------
kernel/cgroup.c:4008 cgroup_mutex or RCU read lock required!
[ 527.243970] other info that might help us debug this:
[ 527.244715]
rcu_scheduler_active = 1, debug_locks = 0
2 locks held by kworker/0:5/1664:
#0: ("cgroup_destroy"){.+.+..}, at: [<ffffffff81060ab5>] process_one_work+0x165/0x4a0
#1: ((&css->destroy_work)#3){+.+...}, at: [<ffffffff81060ab5>] process_one_work+0x165/0x4a0
[ 527.248098] stack backtrace:
CPU: 0 PID: 1664 Comm: kworker/0:5 Not tainted 4.6.0-work+ #321
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.1-1.fc24 04/01/2014
Workqueue: cgroup_destroy css_free_work_fn
Call Trace:
dump_stack+0x68/0xa1
lockdep_rcu_suspicious+0xd7/0x110
css_next_descendant_pre+0x7d/0xb0
memcg_offline_kmem.part.44+0x4a/0xc0
mem_cgroup_css_free+0x1ec/0x200
css_free_work_fn+0x49/0x5e0
process_one_work+0x1c5/0x4a0
worker_thread+0x49/0x490
kthread+0xea/0x100
ret_from_fork+0x1f/0x40--- mm/memcontrol.c | 3 +++ 1 file changed, 3 insertions(+)
mm/memcontrol.c +3 -0
@@ -3661,6 +3661,7 @@ static void memcg_deactivate_kmem(struct* ordering is imposed by list_lru_node->lock taken by * memcg_drain_all_list_lrus(). */ +rcu_read_lock ();/* can be called from css_free w/o cgroup_mutex */ css_for_each_descendant_pre (css, &memcg->css) { child =mem_cgroup_from_css (css);BUG_ON (child->kmemcg_id != kmemcg_id);
@@ -3668,6 +3669,8 @@ static void memcg_deactivate_kmem(structif (!memcg->use_hierarchy)break ; } +rcu_read_unlock (); +memcg_drain_all_list_lrus (kmemcg_id, parent->kmemcg_id);memcg_free_cache_id (kmemcg_id);
Greg Kroah-Hartman
maintainerPATCH 45/75 ecryptfs: forbid opening files without mmap handler
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 2f36db71009304b3f0b95afacd8eba1f9f046b87 upstream.
This prevents users from triggering a stack overflow through a recursive invocation of pagefault handling that involves mapping procfs files into virtual memory.
--- fs/ecryptfs/kthread.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
fs/ecryptfs/kthread.c +11 -2
@@ -25,6 +25,7 @@#include <linux/slab.h> #include <linux/wait.h> #include <linux/mount.h> +#include <linux/file.h> #include "ecryptfs_kernel.h" struct ecryptfs_open_req {
@@ -147,7 +148,7 @@ int ecryptfs_privileged_open(struct file flags |=IS_RDONLY (d_inode (lower_dentry)) ?O_RDONLY :O_RDWR ; (*lower_file) =dentry_open (&req.path, flags, cred);if (!IS_ERR (*lower_file)) - goto out; + goto have_file;if ((flags &O_ACCMODE ) ==O_RDONLY ) { rc =PTR_ERR ((*lower_file)); goto out;
@@ -165,8 +166,16 @@ int ecryptfs_privileged_open(struct filemutex_unlock (&ecryptfs_kthread_ctl.mux);wake_up (&ecryptfs_kthread_ctl.wait);wait_for_completion (&req.done); -if (IS_ERR (*lower_file)) +if (IS_ERR (*lower_file)) { rc =PTR_ERR (*lower_file); + goto out; + } +have_file: +if ((*lower_file)->f_op->mmap ==NULL ) { +fput (*lower_file); + *lower_file =NULL ; + rc = -EMEDIUMTYPE ; + } out:return rc; }
Greg Kroah-Hartman
maintainerPATCH 46/75 wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prasun Maiti <[email protected]>
commit 3d5fdff46c4b2b9534fa2f9fc78e90a48e0ff724 upstream.
iwpriv app uses iw_point structure to send data to Kernel. The iw_point structure holds a pointer. For compatibility Kernel converts the pointer as required for WEXT IOCTLs (SIOCIWFIRST to SIOCIWLAST). Some drivers may use iw_handler_def.private_args to populate iwpriv commands instead of iw_handler_def.private. For those case, the IOCTLs from SIOCIWFIRSTPRIV to SIOCIWLASTPRIV will follow the path ndo_do_ioctl(). Accordingly when the filled up iw_point structure comes from 32 bit iwpriv to 64 bit Kernel, Kernel will not convert the pointer and sends it to driver. So, the driver may get the invalid data.
The pointer conversion for the IOCTLs (SIOCIWFIRSTPRIV to SIOCIWLASTPRIV), which follow the path ndo_do_ioctl(), is mandatory. This patch adds pointer conversion from 32 bit to 64 bit and vice versa, if the ioctl comes from 32 bit iwpriv to 64 bit Kernel.
--- net/wireless/wext-core.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
net/wireless/wext-core.c +23 -2
@@ -955,8 +955,29 @@ static int wireless_process_ioctl(structreturn private (dev, iwr, cmd, info, handler); }/* Old driver API : call driver ioctl handler */ -if (dev->netdev_ops->ndo_do_ioctl) -return dev->netdev_ops->ndo_do_ioctl (dev, ifr, cmd); +if (dev->netdev_ops->ndo_do_ioctl) { +#ifdef CONFIG_COMPAT +if (info->flags &IW_REQUEST_FLAG_COMPAT ) { +int ret =0 ; +struct iwreq iwr_lcl; +struct compat_iw_point *iwp_compat = (void *) &iwr->u.data; + +memcpy (&iwr_lcl, iwr,sizeof (struct iwreq )); + iwr_lcl.u.data.pointer =compat_ptr (iwp_compat->pointer); + iwr_lcl.u.data.length = iwp_compat->length; + iwr_lcl.u.data.flags = iwp_compat->flags; + + ret = dev->netdev_ops->ndo_do_ioctl (dev, (void *) &iwr_lcl, cmd); + + iwp_compat->pointer =ptr_to_compat (iwr_lcl.u.data.pointer); + iwp_compat->length = iwr_lcl.u.data.length; + iwp_compat->flags = iwr_lcl.u.data.flags; + +return ret; + } else +#endif +return dev->netdev_ops->ndo_do_ioctl (dev, ifr, cmd); + }return -EOPNOTSUPP ; }
Greg Kroah-Hartman
maintainerPATCH 47/75 x86/entry/traps: Dont force in_interrupt() to return true in IST handlers
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski <[email protected]>
commit aaee8c3c5cce2d9107310dd9f3026b4f901d441c upstream.
Forcing in_interrupt() to return true if we're not in a bona fide interrupt confuses the softirq code. This fixes warnings like:
NOHZ: local_softirq_pending 282
... which can happen when running things like selftests/x86.
This will change perf's static percpu buffer usage in IST context. I think this is okay, and it's changing the behavior to match historical (pre-4.0) behavior.
--- arch/x86/kernel/traps.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
arch/x86/kernel/traps.c +10 -10
@@ -109,6 +109,12 @@ static inline void preempt_conditional_cpreempt_count_dec (); } +/* +* In IST context, we explicitly disable preemption. This serves two +* purposes: it makes it much less likely that we would accidentally +* schedule in IST context and it will force a warning if we somehow +* manage to schedule by accident. +*/ void ist_enter (struct pt_regs *regs) {if (user_mode (regs)) {
@@ -123,13 +129,7 @@ void ist_enter(struct pt_regs *regs)rcu_nmi_enter (); } -/* -* We are atomic because we're on the IST stack; or we're on -* x86_32, in which case we still shouldn't schedule; or we're -* on x86_64 and entered from user mode, in which case we're -* still atomic unless ist_begin_non_atomic is called. -*/ -preempt_count_add (HARDIRQ_OFFSET ); +preempt_disable ();/* This code is a bit fragile. Test it. */ RCU_LOCKDEP_WARN (!rcu_is_watching (),"ist_enter didn't work" );
@@ -137,7 +137,7 @@ void ist_enter(struct pt_regs *regs)void ist_exit (struct pt_regs *regs) { -preempt_count_sub (HARDIRQ_OFFSET ); +preempt_enable_no_resched ();if (!user_mode (regs))rcu_nmi_exit ();
@@ -168,7 +168,7 @@ void ist_begin_non_atomic(struct pt_regsBUG_ON ((unsigned long )(current_top_of_stack () -current_stack_pointer ()) >=THREAD_SIZE ); -preempt_count_sub (HARDIRQ_OFFSET ); +preempt_enable_no_resched (); }/**
@@ -178,7 +178,7 @@ void ist_begin_non_atomic(struct pt_regs*/ void ist_end_non_atomic (void ) { -preempt_count_add (HARDIRQ_OFFSET ); +preempt_disable (); }static nokprobe_inline int
Greg Kroah-Hartman
maintainerPATCH 48/75 proc: prevent stacking filesystems on top
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit e54ad7f1ee263ffa5a2de9c609d58dfa27b21cd9 upstream.
This prevents stacking filesystems (ecryptfs and overlayfs) from using procfs as lower filesystem. There is too much magic going on inside procfs, and there is no good reason to stack stuff on top of procfs.
(For example, procfs does access checks in VFS open handlers, and ecryptfs by design calls open handlers from a kernel thread that doesn't drop privileges or so.)
--- fs/proc/root.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/proc/root.c +7 -0
@@ -121,6 +121,13 @@ static struct dentry *proc_mount(structif (IS_ERR (sb))return ERR_CAST (sb); +/* +* procfs isn't actually a stacking filesystem; however, there is +* too much magic going on inside it to permit stacking things on +* top of it +*/ + sb->s_stack_depth =FILESYSTEM_MAX_STACK_DEPTH ; +if (!proc_parse_options (options, ns)) {deactivate_locked_super (sb);return ERR_PTR (-EINVAL );
Greg Kroah-Hartman
maintainerPATCH 49/75 sched: panic on corrupted stack end
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 29d6455178a09e1dc340380c582b13356227e8df upstream.
Until now, hitting this BUG_ON caused a recursive oops (because oops handling involves do_exit(), which calls into the scheduler, which in turn raises an oops), which caused stuff below the stack to be overwritten until a panic happened (e.g. via an oops in interrupt context, caused by the overwritten CPU index in the thread_info).
Just panic directly.
--- kernel/sched/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/sched/core.c +2 -1
@@ -3008,7 +3008,8 @@ static noinline void __schedule_bug(strustatic inline void schedule_debug (struct task_struct *prev) {#ifdef CONFIG_SCHED_STACK_END_CHECK -BUG_ON (task_stack_end_corrupted (prev)); +if (task_stack_end_corrupted (prev)) +panic ("corrupted stack end detected inside scheduler\n" );#endif if (unlikely (in_atomic_preempt_off ())) {
Greg Kroah-Hartman
maintainerPATCH 50/75 fix d_walk()/non-delayed __d_free() race
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 3d56c25e3bb0726a5c5e16fc2d9e38f8ed763085 upstream.
Ascend-to-parent logics in d_walk() depends on all encountered child dentries not getting freed without an RCU delay. Unfortunately, in quite a few cases it is not true, with hard-to-hit oopsable race as the result.
Fortunately, the fix is simiple; right now the rule is "if it ever been hashed, freeing must be delayed" and changing it to "if it ever had a parent, freeing must be delayed" closes that hole and covers all cases the old rule used to cover. Moreover, pipes and sockets remain _not_ covered, so we do not introduce RCU delay in the cases which are the reason for having that delay conditional in the first place.
--- fs/dcache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/dcache.c +2 -2
@@ -1618,7 +1618,7 @@ struct dentry *d_alloc(struct dentry * pstruct dentry *dentry =__d_alloc (parent->d_sb, name);if (!dentry)return NULL ; - + dentry->d_flags |=DCACHE_RCUACCESS ;spin_lock (&parent->d_lock);/* * don't need child lock because it is not subject
@@ -2413,7 +2413,6 @@ static void __d_rehash(struct dentry * e {BUG_ON (!d_unhashed (entry));hlist_bl_lock (b); - entry->d_flags |=DCACHE_RCUACCESS ;hlist_bl_add_head_rcu (&entry->d_hash, b);hlist_bl_unlock (b); }
@@ -2632,6 +2631,7 @@ static void __d_move(struct dentry *dent/* ... and switch them in the tree */ if (IS_ROOT (dentry)) {/* splicing a tree */ + dentry->d_flags |=DCACHE_RCUACCESS ; dentry->d_parent = target->d_parent; target->d_parent = target;list_del_init (&target->d_child);
Greg Kroah-Hartman
maintainerPATCH 51/75 sparc: Fix system call tracing register handling.
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Frysinger <[email protected]>
[ Upstream commit 1a40b95374f680625318ab61d81958e949e0afe3 ]
A system call trace trigger on entry allows the tracing process to inspect and potentially change the traced process's registers.
Account for that by reloading the %g1 (syscall number) and %i0-%i5 (syscall argument) values. We need to be careful to revalidate the range of %g1, and reload the system call table entry it corresponds to into %l7.
--- arch/sparc/kernel/entry.S | 17 +++++++++++++++++ arch/sparc/kernel/syscalls.S | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+)
arch/sparc/kernel/entry.S +17 -0
@@ -948,7 +948,24 @@ linux_syscall_trace: cmp %o0, 0 bne 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ld [%sp + STACKFRAME_SZ + PT_G1], %g1 + sethi %hi(sys_call_table), %l7 + ld [%sp + STACKFRAME_SZ + PT_I0], %i0 + or %l7, %lo(sys_call_table), %l7 + ld [%sp + STACKFRAME_SZ + PT_I1], %i1 + ld [%sp + STACKFRAME_SZ + PT_I2], %i2 + ld [%sp + STACKFRAME_SZ + PT_I3], %i3 + ld [%sp + STACKFRAME_SZ + PT_I4], %i4 + ld [%sp + STACKFRAME_SZ + PT_I5], %i5 + cmp %g1, NR_syscalls + bgeu 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 mov %i0, %o0 + ld [%l7 + %l4], %l7 mov %i1, %o1 mov %i2, %o2 mov %i3, %o3
arch/sparc/kernel/syscalls.S +36 -0
@@ -158,7 +158,25 @@ linux_syscall_trace32: add %sp, PTREGS_OFF, %o0 brnz,pn %o0, 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 + sethi %hi(sys_call_table32), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 + or %l7, %lo(sys_call_table32), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 + ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 + ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 + ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 + + cmp %g1, NR_syscalls + bgeu,pn %xcc, 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 srl %i0, 0, %o0 + lduw [%l7 + %l4], %l7 srl %i4, 0, %o4 srl %i1, 0, %o1 srl %i2, 0, %o2
@@ -170,7 +188,25 @@ linux_syscall_trace: add %sp, PTREGS_OFF, %o0 brnz,pn %o0, 3f mov -ENOSYS, %o0 + + /* Syscall tracing can modify the registers. */ + ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 + sethi %hi(sys_call_table64), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 + or %l7, %lo(sys_call_table64), %l7 + ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 + ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 + ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 + ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 + + cmp %g1, NR_syscalls + bgeu,pn %xcc, 3f + mov -ENOSYS, %o0 + + sll %g1, 2, %l4 mov %i0, %o0 + lduw [%l7 + %l4], %l7 mov %i1, %o1 mov %i2, %o2 mov %i3, %o3
Greg Kroah-Hartman
maintainerPATCH 52/75 sparc64: Fix bootup regressions on some Kconfig combinations.
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: "David S. Miller" <[email protected]>
[ Upstream commit 49fa5230462f9f2c4e97c81356473a6bdf06c422 ]
The system call tracing bug fix mentioned in the Fixes tag below increased the amount of assembler code in the sequence of assembler files included by head_64.S
This caused to total set of code to exceed 0x4000 bytes in size, which overflows the expression in head_64.S that works to place swapper_tsb at address 0x408000.
When this is violated, the TSB is not properly aligned, and also the trap table is not aligned properly either. All of this together results in failed boots.
So, do two things:
1) Simplify some code by using ba,a instead of ba/nop to get those bytes back.
2) Add a linker script assertion to make sure that if this happens again the build will fail.
--- arch/sparc/kernel/cherrs.S | 14 +++++--------- arch/sparc/kernel/fpu_traps.S | 11 +++++------ arch/sparc/kernel/head_64.S | 24 ++++++++---------------- arch/sparc/kernel/misctrap.S | 12 ++++-------- arch/sparc/kernel/spiterrs.S | 18 ++++++------------ arch/sparc/kernel/utrap.S | 3 +-- arch/sparc/kernel/vmlinux.lds.S | 4 ++++ arch/sparc/kernel/winfixup.S | 3 +-- 8 files changed, 34 insertions(+), 55 deletions(-)
arch/sparc/kernel/cherrs.S +5 -9
@@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal: /* Ok we may use i subcc %g1, %g2, %g1 ! Next cacheline bge,pt %icc, 1b nop - ba,pt %xcc, dcpe_icpe_tl1_common - nop + ba,a,pt %xcc, dcpe_icpe_tl1_common do_dcpe_tl1_fatal: sethi %hi(1f), %g7
@@ -224,8 +223,7 @@ do_dcpe_tl1_fatal: mov 0x2, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_dcpe_tl1,.-do_dcpe_tl1 .globl do_icpe_tl1
@@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use i subcc %g1, %g2, %g1 bge,pt %icc, 1b nop - ba,pt %xcc, dcpe_icpe_tl1_common - nop + ba,a,pt %xcc, dcpe_icpe_tl1_common do_icpe_tl1_fatal: sethi %hi(1f), %g7
@@ -269,8 +266,7 @@ do_icpe_tl1_fatal: mov 0x3, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_icpe_tl1,.-do_icpe_tl1 .type dcpe_icpe_tl1_common,#function
@@ -456,7 +452,7 @@ __cheetah_log_error: cmp %g2, 0x63 be c_cee nop - ba,pt %xcc, c_deferred + ba,a,pt %xcc, c_deferred .size __cheetah_log_error,.-__cheetah_log_error /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
arch/sparc/kernel/fpu_traps.S +5 -6
@@ -100,8 +100,8 @@ do_fpdis: fmuld %f0, %f2, %f26 faddd %f0, %f2, %f28 fmuld %f0, %f2, %f30 - b,pt %xcc, fpdis_exit - nop + ba,a,pt %xcc, fpdis_exit + 2: andcc %g5, FPRS_DU, %g0 bne,pt %icc, 3f fzero %f32
@@ -144,8 +144,8 @@ do_fpdis: fmuld %f32, %f34, %f58 faddd %f32, %f34, %f60 fmuld %f32, %f34, %f62 - ba,pt %xcc, fpdis_exit - nop + ba,a,pt %xcc, fpdis_exit + 3: mov SECONDARY_CONTEXT, %g3 add %g6, TI_FPREGS, %g1
@@ -197,8 +197,7 @@ fpdis_exit2: fp_other_bounce: call do_fpother add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size fp_other_bounce,.-fp_other_bounce .align 32
arch/sparc/kernel/head_64.S +8 -16
@@ -461,9 +461,8 @@ sun4v_chip_type: subcc %g3, 1, %g3 bne,pt %xcc, 41b add %g1, 1, %g1 - mov SUN4V_CHIP_SPARC64X, %g4 ba,pt %xcc, 5f - nop + mov SUN4V_CHIP_SPARC64X, %g4 49: mov SUN4V_CHIP_UNKNOWN, %g4
@@ -548,8 +547,7 @@ sun4u_init: stxa %g0, [%g7] ASI_DMMU membar #Sync - ba,pt %xcc, sun4u_continue - nop + ba,a,pt %xcc, sun4u_continue sun4v_init: /* Set ctx 0 */
@@ -560,14 +558,12 @@ sun4v_init: mov SECONDARY_CONTEXT, %g7 stxa %g0, [%g7] ASI_MMU membar #Sync - ba,pt %xcc, niagara_tlb_fixup - nop + ba,a,pt %xcc, niagara_tlb_fixup sun4u_continue: BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup) - ba,pt %xcc, spitfire_tlb_fixup - nop + ba,a,pt %xcc, spitfire_tlb_fixup niagara_tlb_fixup: mov 3, %g2 /* Set TLB type to hypervisor. */
@@ -639,8 +635,7 @@ niagara_patch: call hypervisor_patch_cachetlbops nop - ba,pt %xcc, tlb_fixup_done - nop + ba,a,pt %xcc, tlb_fixup_done cheetah_tlb_fixup: mov 2, %g2 /* Set TLB type to cheetah+. */
@@ -659,8 +654,7 @@ cheetah_tlb_fixup: call cheetah_patch_cachetlbops nop - ba,pt %xcc, tlb_fixup_done - nop + ba,a,pt %xcc, tlb_fixup_done spitfire_tlb_fixup: /* Set TLB type to spitfire. */
@@ -782,8 +776,7 @@ setup_trap_table: call %o1 add %sp, (2047 + 128), %o0 - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f 1: sethi %hi(sparc64_ttable_tl0), %o0 set prom_set_trap_table_name, %g2
@@ -822,8 +815,7 @@ setup_trap_table: BRANCH_IF_ANY_CHEETAH(o2, o3, 1f) - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f /* Disable STICK_INT interrupts. */ 1:
arch/sparc/kernel/misctrap.S +4 -8
@@ -18,8 +18,7 @@ __do_privact: 109: or %g7, %lo(109b), %g7 call do_privact add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __do_privact,.-__do_privact .type do_mna,#function
@@ -46,8 +45,7 @@ do_mna: mov %l5, %o2 call mem_address_unaligned add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_mna,.-do_mna .type do_lddfmna,#function
@@ -65,8 +63,7 @@ do_lddfmna: mov %l5, %o2 call handle_lddfmna add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_lddfmna,.-do_lddfmna .type do_stdfmna,#function
@@ -84,8 +81,7 @@ do_stdfmna: mov %l5, %o2 call handle_stdfmna add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size do_stdfmna,.-do_stdfmna .type breakpoint_trap,#function
arch/sparc/kernel/spiterrs.S +6 -12
@@ -85,8 +85,7 @@ __spitfire_cee_trap_continue: ba,pt %xcc, etraptl1 rd %pc, %g7 - ba,pt %xcc, 2f - nop + ba,a,pt %xcc, 2f 1: ba,pt %xcc, etrap_irq rd %pc, %g7
@@ -100,8 +99,7 @@ __spitfire_cee_trap_continue: mov %l5, %o2 call spitfire_access_error add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_access_error,.-__spitfire_access_error /* This is the trap handler entry point for ECC correctable
@@ -179,8 +177,7 @@ __spitfire_data_access_exception_tl1: mov %l5, %o2 call spitfire_data_access_exception_tl1 add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1 .type __spitfire_data_access_exception,#function
@@ -200,8 +197,7 @@ __spitfire_data_access_exception: mov %l5, %o2 call spitfire_data_access_exception add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_data_access_exception,.-__spitfire_data_access_exception .type __spitfire_insn_access_exception_tl1,#function
@@ -220,8 +216,7 @@ __spitfire_insn_access_exception_tl1: mov %l5, %o2 call spitfire_insn_access_exception_tl1 add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1 .type __spitfire_insn_access_exception,#function
@@ -240,6 +235,5 @@ __spitfire_insn_access_exception: mov %l5, %o2 call spitfire_insn_access_exception add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception
arch/sparc/kernel/utrap.S +1 -2
@@ -11,8 +11,7 @@ utrap_trap: /* %g3=handler,%g4=level */ mov %l4, %o1 call bad_trap add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap invoke_utrap: sllx %g3, 3, %g3
arch/sparc/kernel/vmlinux.lds.S +4 -0
@@ -33,6 +33,10 @@ ENTRY(_start) jiffies = jiffies_64; #endif +#ifdef CONFIG_SPARC64 +ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large") +#endif + SECTIONS { #ifdef CONFIG_SPARC64
arch/sparc/kernel/winfixup.S +1 -2
@@ -32,8 +32,7 @@ fill_fixup: rd %pc, %g7 call do_sparc64_fault add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - nop + ba,a,pt %xcc, rtrap /* Be very careful about usage of the trap globals here. * You cannot touch %g5 as that has the fault information.
Greg Kroah-Hartman
maintainerPATCH 53/75 sparc64: Fix numa node distance initialization
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nitin Gupta <[email protected]>
[ Upstream commit 36beca6571c941b28b0798667608239731f9bc3a ]
Orabug: 22495713
Currently, NUMA node distance matrix is initialized only when a machine descriptor (MD) exists. However, sun4u machines (e.g. Sun Blade 2500) do not have an MD and thus distance values were left uninitialized. The initialization is now moved such that it happens on both sun4u and sun4v.
--- arch/sparc/mm/init_64.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
arch/sparc/mm/init_64.c +8 -7
@@ -1267,13 +1267,6 @@ static int __init numa_parse_mdesc(void)int i, j, err, count;u64 node; -/* Some sane defaults for numa latency values */ -for (i =0 ; i <MAX_NUMNODES ; i++) { -for (j =0 ; j <MAX_NUMNODES ; j++) - numa_latency[i][j] = (i == j) ? -LOCAL_DISTANCE :REMOTE_DISTANCE ; - } - node =mdesc_node_by_name (md,MDESC_NODE_NULL ,"latency-groups" );if (node ==MDESC_NODE_NULL ) {mdesc_release (md);
@@ -1369,10 +1362,18 @@ static int __init numa_parse_sun4u(void)static int __init bootmem_init_numa (void ) { +int i, j;int err =-1 ;numadbg ("bootmem_init_numa()\n" ); +/* Some sane defaults for numa latency values */ +for (i =0 ; i <MAX_NUMNODES ; i++) { +for (j =0 ; j <MAX_NUMNODES ; j++) + numa_latency[i][j] = (i == j) ? +LOCAL_DISTANCE :REMOTE_DISTANCE ; + } +if (numa_enabled) {if (tlb_type == hypervisor) err =numa_parse_mdesc ();
Greg Kroah-Hartman
maintainerPATCH 54/75 sparc64: Fix sparc64_set_context stack handling.
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: "David S. Miller" <[email protected]>
[ Upstream commit 397d1533b6cce0ccb5379542e2e6d079f6936c46 ]
Like a signal return, we should use synchronize_user_stack() rather than flush_user_windows().
--- arch/sparc/kernel/signal_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sparc/kernel/signal_64.c +1 -1
@@ -52,7 +52,7 @@ asmlinkage void sparc64_set_context(struunsigned char fenab;int err; -flush_user_windows (); +synchronize_user_stack ();if (get_thread_wsaved () || (((unsigned long )ucp) & (sizeof (unsigned long )-1 )) || (!__access_ok (ucp,sizeof (*ucp))))
Greg Kroah-Hartman
maintainerPATCH 55/75 sparc/PCI: Fix for panic while enabling SR-IOV
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Babu Moger <[email protected]>
[ Upstream commit d0c31e02005764dae0aab130a57e9794d06b824d ]
We noticed this panic while enabling SR-IOV in sparc.
mlx4_core: Mellanox ConnectX core driver v2.2-1 (Jan 1 2015)mlx4_core: Initializing 0007:01:00.0mlx4_core 0007:01:00.0: Enabling SR-IOV with 5 VFsmlx4_core: Initializing 0007:01:00.1
Unable to handle kernel NULL pointer dereference insmod(10010): Oops [#1] CPU: 391 PID: 10010 Comm: insmod Not tainted 4.1.12-32.el6uek.kdump2.sparc64 #1 TPC: <dma_supported+0x20/0x80> I7: <__mlx4_init_one+0x324/0x500 [mlx4_core]> Call Trace: [00000000104c5ea4] __mlx4_init_one+0x324/0x500 [mlx4_core] [00000000104c613c] mlx4_init_one+0xbc/0x120 [mlx4_core] [0000000000725f14] local_pci_probe+0x34/0xa0 [0000000000726028] pci_call_probe+0xa8/0xe0 [0000000000726310] pci_device_probe+0x50/0x80 [000000000079f700] really_probe+0x140/0x420 [000000000079fa24] driver_probe_device+0x44/0xa0 [000000000079fb5c] __device_attach+0x3c/0x60 [000000000079d85c] bus_for_each_drv+0x5c/0xa0 [000000000079f588] device_attach+0x88/0xc0 [000000000071acd0] pci_bus_add_device+0x30/0x80 [0000000000736090] virtfn_add.clone.1+0x210/0x360 [00000000007364a4] sriov_enable+0x2c4/0x520 [000000000073672c] pci_enable_sriov+0x2c/0x40 [00000000104c2d58] mlx4_enable_sriov+0xf8/0x180 [mlx4_core] [00000000104c49ac] mlx4_load_one+0x42c/0xd40 [mlx4_core]
Disabling lock debugging due to kernel taint Caller[00000000104c5ea4]: __mlx4_init_one+0x324/0x500 [mlx4_core] Caller[00000000104c613c]: mlx4_init_one+0xbc/0x120 [mlx4_core] Caller[0000000000725f14]: local_pci_probe+0x34/0xa0 Caller[0000000000726028]: pci_call_probe+0xa8/0xe0 Caller[0000000000726310]: pci_device_probe+0x50/0x80 Caller[000000000079f700]: really_probe+0x140/0x420 Caller[000000000079fa24]: driver_probe_device+0x44/0xa0 Caller[000000000079fb5c]: __device_attach+0x3c/0x60 Caller[000000000079d85c]: bus_for_each_drv+0x5c/0xa0 Caller[000000000079f588]: device_attach+0x88/0xc0 Caller[000000000071acd0]: pci_bus_add_device+0x30/0x80 Caller[0000000000736090]: virtfn_add.clone.1+0x210/0x360 Caller[00000000007364a4]: sriov_enable+0x2c4/0x520 Caller[000000000073672c]: pci_enable_sriov+0x2c/0x40 Caller[00000000104c2d58]: mlx4_enable_sriov+0xf8/0x180 [mlx4_core] Caller[00000000104c49ac]: mlx4_load_one+0x42c/0xd40 [mlx4_core] Caller[00000000104c5f90]: __mlx4_init_one+0x410/0x500 [mlx4_core] Caller[00000000104c613c]: mlx4_init_one+0xbc/0x120 [mlx4_core] Caller[0000000000725f14]: local_pci_probe+0x34/0xa0 Caller[0000000000726028]: pci_call_probe+0xa8/0xe0 Caller[0000000000726310]: pci_device_probe+0x50/0x80 Caller[000000000079f700]: really_probe+0x140/0x420 Caller[000000000079fa24]: driver_probe_device+0x44/0xa0 Caller[000000000079fb08]: __driver_attach+0x88/0xa0 Caller[000000000079d90c]: bus_for_each_dev+0x6c/0xa0 Caller[000000000079f29c]: driver_attach+0x1c/0x40 Caller[000000000079e35c]: bus_add_driver+0x17c/0x220 Caller[00000000007a02d4]: driver_register+0x74/0x120 Caller[00000000007263fc]: __pci_register_driver+0x3c/0x60 Caller[00000000104f62bc]: mlx4_init+0x60/0xcc [mlx4_core]
Kernel panic - not syncing: Fatal exception Press Stop-A (L1-A) to return to the boot prom ---[ end Kernel panic - not syncing: Fatal exception
Details:
Here is the call sequence virtfn_add->__mlx4_init_one->dma_set_mask->dma_supported
The panic happened at line 760(file arch/sparc/kernel/iommu.c)
758 int dma_supported(struct device *dev, u64 device_mask) 759 {
760 struct iommu *iommu = dev->archdata.iommu;
761 u64 dma_addr_mask = iommu->dma_addr_mask;
762
763 if (device_mask >= (1UL << 32UL))
764 return 0;
765
766 if ((device_mask & dma_addr_mask) == dma_addr_mask)
767 return 1;
768
769 #ifdef CONFIG_PCI
770 if (dev_is_pci(dev))
771 return pci64_dma_supported(to_pci_dev(dev), device_mask);
772 #endif
773
774 return 0;
775 }
776 EXPORT_SYMBOL(dma_supported);
Same panic happened with Intel ixgbe driver also.
SR-IOV code looks for arch specific data while enabling VFs. When VF device is added, driver probe function makes set of calls to initialize the pci device. Because the VF device is added different way than the normal PF device(which happens via of_create_pci_dev for sparc), some of the arch specific initialization does not happen for VF device. That causes panic when archdata is accessed.
To fix this, I have used already defined weak function pcibios_setup_device to copy archdata from PF to VF. Also verified the fix.
--- arch/sparc/kernel/pci.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
arch/sparc/kernel/pci.c +17 -0
@@ -994,6 +994,23 @@ void pcibios_set_master(struct pci_dev */* No special bus mastering setup handling */ } +#ifdef CONFIG_PCI_IOV +int pcibios_add_device (struct pci_dev *dev) +{ +struct pci_dev *pdev; + +/* Add sriov arch specific initialization here. +* Copy dev_archdata from PF to VF +*/ +if (dev->is_virtfn) { + pdev = dev->physfn; +memcpy (&dev->dev.archdata, &pdev->dev.archdata, +sizeof (struct dev_archdata )); + } +return 0 ; +} +#endif /* CONFIG_PCI_IOV */ +static int __init pcibios_init (void ) { pci_dfl_cache_line_size =64 >>2 ;
Greg Kroah-Hartman
maintainerPATCH 56/75 sparc64: Reduce TLB flushes during hugepte changes
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nitin Gupta <[email protected]>
[ Upstream commit 24e49ee3d76b70853a96520e46b8837e5eae65b2 ]
During hugepage map/unmap, TSB and TLB flushes are currently issued at every PAGE_SIZE'd boundary which is unnecessary. We now issue the flush at REAL_HPAGE_SIZE boundaries only.
Without this patch workloads which unmap a large hugepage backed VMA region get CPU lockups due to excessive TLB flush calls.
Orabug: 22365539, 22643230, 22995196
--- arch/sparc/include/asm/pgtable_64.h | 43 ++++++++++++++++++++++++++--------- arch/sparc/include/asm/tlbflush_64.h | 3 +- arch/sparc/mm/hugetlbpage.c | 33 ++++++++++++++++++++++---- arch/sparc/mm/init_64.c | 12 --------- arch/sparc/mm/tlb.c | 25 ++++++++++++++------ arch/sparc/mm/tsb.c | 32 +++++++++++++------------- 6 files changed, 97 insertions(+), 51 deletions(-)
arch/sparc/include/asm/pgtable_64.h +32 -11
@@ -375,7 +375,7 @@ static inline pgprot_t pgprot_noncached(#define pgprot_noncached pgprot_noncached#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -static inline pte_t pte_mkhuge (pte_t pte) +static inline unsigned long __pte_huge_mask (void ) {unsigned long mask;
@@ -390,8 +390,19 @@ static inline pte_t pte_mkhuge(pte_t pte : "=r" (mask) : "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V)); -return __pte (pte_val (pte) | mask); +return mask; +} + +static inline pte_t pte_mkhuge (pte_t pte) +{ +return __pte (pte_val (pte) |__pte_huge_mask ()); +} + +static inline bool is_hugetlb_pte (pte_t pte) +{ +return !!(pte_val (pte) &__pte_huge_mask ()); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE static inline pmd_t pmd_mkhuge (pmd_t pmd) {
@@ -403,6 +414,11 @@ static inline pmd_t pmd_mkhuge(pmd_t pmdreturn __pmd (pte_val (pte)); }#endif +#else +static inline bool is_hugetlb_pte (pte_t pte) +{ +return false; +}#endif static inline pte_t pte_mkdirty (pte_t pte)
@@ -865,6 +881,19 @@ static inline unsigned long pud_pfn(pud_void tlb_batch_add (struct mm_struct *mm,unsigned long vaddr,pte_t *ptep,pte_t orig,int fullmm); +static void maybe_tlb_batch_add (struct mm_struct *mm,unsigned long vaddr, +pte_t *ptep,pte_t orig,int fullmm) +{ +/* It is more efficient to let flush_tlb_kernel_range() +* handle init_mm tlb flushes. +* +* SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U +* and SUN4V pte layout, so this inline test is fine. +*/ +if (likely (mm != &init_mm) &&pte_accessible (mm, orig)) +tlb_batch_add (mm, vaddr, ptep, orig, fullmm); +} +#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long addr,
@@ -881,15 +910,7 @@ static inline void __set_pte_at(struct mpte_t orig = *ptep; *ptep = pte; - -/* It is more efficient to let flush_tlb_kernel_range() -* handle init_mm tlb flushes. -* -* SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U -* and SUN4V pte layout, so this inline test is fine. -*/ -if (likely (mm != &init_mm) &&pte_accessible (mm, orig)) -tlb_batch_add (mm, addr, ptep, orig, fullmm); +maybe_tlb_batch_add (mm, addr, ptep, orig, fullmm); }#define set_pte_at (mm,addr,ptep,pte) \
arch/sparc/include/asm/tlbflush_64.h +2 -1
@@ -8,6 +8,7 @@#define TLB_BATCH_NR 192struct tlb_batch { +bool huge;struct mm_struct *mm;unsigned long tlb_nr;unsigned long active;
@@ -16,7 +17,7 @@ struct tlb_batch {void flush_tsb_kernel_range (unsigned long start,unsigned long end);void flush_tsb_user (struct tlb_batch *tb); -void flush_tsb_user_page (struct mm_struct *mm,unsigned long vaddr); +void flush_tsb_user_page (struct mm_struct *mm,unsigned long vaddr,bool huge);/* TLB flush operations. */
arch/sparc/mm/hugetlbpage.c +28 -5
@@ -176,17 +176,31 @@ void set_huge_pte_at(struct mm_struct *m pte_t *ptep, pte_t entry) { int i; +pte_t orig[2 ]; +unsigned long nptes;if (!pte_present (*ptep) &&pte_present (entry)) mm->context.huge_pte_count++; addr &=HPAGE_MASK ; -for (i =0 ; i < (1 <<HUGETLB_PAGE_ORDER ); i++) { -set_pte_at (mm, addr, ptep, entry); + + nptes =1 <<HUGETLB_PAGE_ORDER ; + orig[0 ] = *ptep; + orig[1 ] = *(ptep + nptes /2 ); +for (i =0 ; i < nptes; i++) { + *ptep = entry; ptep++; addr +=PAGE_SIZE ;pte_val (entry) +=PAGE_SIZE ; } + +/* Issue TLB flush at REAL_HPAGE_SIZE boundaries */ + addr -=REAL_HPAGE_SIZE ; + ptep -= nptes /2 ; +maybe_tlb_batch_add (mm, addr, ptep, orig[1 ],0 ); + addr -=REAL_HPAGE_SIZE ; + ptep -= nptes /2 ; +maybe_tlb_batch_add (mm, addr, ptep, orig[0 ],0 ); } pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
@@ -194,19 +208,28 @@ pte_t huge_ptep_get_and_clear(struct mm_ {pte_t entry;int i; +unsigned long nptes; entry = *ptep;if (pte_present (entry)) mm->context.huge_pte_count--; addr &=HPAGE_MASK ; - -for (i =0 ; i < (1 <<HUGETLB_PAGE_ORDER ); i++) { -pte_clear (mm, addr, ptep); + nptes =1 <<HUGETLB_PAGE_ORDER ; +for (i =0 ; i < nptes; i++) { + *ptep =__pte (0UL ); addr +=PAGE_SIZE ; ptep++; } +/* Issue TLB flush at REAL_HPAGE_SIZE boundaries */ + addr -=REAL_HPAGE_SIZE ; + ptep -= nptes /2 ; +maybe_tlb_batch_add (mm, addr, ptep, entry,0 ); + addr -=REAL_HPAGE_SIZE ; + ptep -= nptes /2 ; +maybe_tlb_batch_add (mm, addr, ptep, entry,0 ); +return entry; }
arch/sparc/mm/init_64.c +0 -12
@@ -324,18 +324,6 @@ static void __update_mmu_tsb_insert(strutsb_insert (tsb, tag, tte); } -#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -static inline bool is_hugetlb_pte (pte_t pte) -{ -if ((tlb_type == hypervisor && - (pte_val (pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) || - (tlb_type != hypervisor && - (pte_val (pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U)) -return true; -return false; -} -#endif -void update_mmu_cache (struct vm_area_struct *vma,unsigned long address,pte_t *ptep) {struct mm_struct *mm;
arch/sparc/mm/tlb.c +18 -7
@@ -67,7 +67,7 @@ void arch_leave_lazy_mmu_mode(void) }static void tlb_batch_add_one (struct mm_struct *mm,unsigned long vaddr, -bool exec) +bool exec,bool huge) {struct tlb_batch *tb = &get_cpu_var (tlb_batch);unsigned long nr;
@@ -84,13 +84,21 @@ static void tlb_batch_add_one(struct mm_ }if (!tb->active) { -flush_tsb_user_page (mm, vaddr); +flush_tsb_user_page (mm, vaddr, huge);global_flush_tlb_page (mm, vaddr); goto out; } -if (nr ==0 ) +if (nr ==0 ) { tb->mm = mm; + tb->huge = huge; + } + +if (tb->huge != huge) { +flush_tlb_pending (); + tb->huge = huge; + nr =0 ; + } tb->vaddrs[nr] = vaddr; tb->tlb_nr = ++nr;
@@ -104,6 +112,8 @@ out:void tlb_batch_add (struct mm_struct *mm,unsigned long vaddr,pte_t *ptep,pte_t orig,int fullmm) { +bool huge =is_hugetlb_pte (orig); +if (tlb_type != hypervisor &&pte_dirty (orig)) {unsigned long paddr, pfn =pte_pfn (orig);
@@ -129,7 +139,7 @@ void tlb_batch_add(struct mm_struct *mm, no_cache_flush:if (!fullmm) -tlb_batch_add_one (mm, vaddr,pte_exec (orig)); +tlb_batch_add_one (mm, vaddr,pte_exec (orig), huge); }#ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -145,7 +155,7 @@ static void tlb_batch_pmd_scan(struct mmif (pte_val (*pte) & _PAGE_VALID) {bool exec =pte_exec (*pte); -tlb_batch_add_one (mm, vaddr, exec); +tlb_batch_add_one (mm, vaddr, exec, false); } pte++; vaddr +=PAGE_SIZE ;
@@ -185,8 +195,9 @@ void set_pmd_at(struct mm_struct *mm, unpte_t orig_pte =__pte (pmd_val (orig));bool exec =pte_exec (orig_pte); -tlb_batch_add_one (mm, addr, exec); -tlb_batch_add_one (mm, addr +REAL_HPAGE_SIZE , exec); +tlb_batch_add_one (mm, addr, exec, true); +tlb_batch_add_one (mm, addr +REAL_HPAGE_SIZE , exec, + true); }else {tlb_batch_pmd_scan (mm, addr, orig); }
arch/sparc/mm/tsb.c +17 -15
@@ -76,14 +76,15 @@ void flush_tsb_user(struct tlb_batch *tbspin_lock_irqsave (&mm->context.lock, flags); - base = (unsigned long ) mm->context.tsb_block[MM_TSB_BASE ].tsb; - nentries = mm->context.tsb_block[MM_TSB_BASE ].tsb_nentries; -if (tlb_type == cheetah_plus || tlb_type == hypervisor) - base =__pa (base); -__flush_tsb_one (tb,PAGE_SHIFT , base, nentries); - +if (!tb->huge) { + base = (unsigned long ) mm->context.tsb_block[MM_TSB_BASE ].tsb; + nentries = mm->context.tsb_block[MM_TSB_BASE ].tsb_nentries; +if (tlb_type == cheetah_plus || tlb_type == hypervisor) + base =__pa (base); +__flush_tsb_one (tb,PAGE_SHIFT , base, nentries); + }#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -if (mm->context.tsb_block[MM_TSB_HUGE ].tsb) { +if (tb->huge && mm->context.tsb_block[MM_TSB_HUGE ].tsb) { base = (unsigned long ) mm->context.tsb_block[MM_TSB_HUGE ].tsb; nentries = mm->context.tsb_block[MM_TSB_HUGE ].tsb_nentries;if (tlb_type == cheetah_plus || tlb_type == hypervisor)
@@ -94,20 +95,21 @@ void flush_tsb_user(struct tlb_batch *tbspin_unlock_irqrestore (&mm->context.lock, flags); } -void flush_tsb_user_page (struct mm_struct *mm,unsigned long vaddr) +void flush_tsb_user_page (struct mm_struct *mm,unsigned long vaddr,bool huge) {unsigned long nentries, base, flags;spin_lock_irqsave (&mm->context.lock, flags); - base = (unsigned long ) mm->context.tsb_block[MM_TSB_BASE ].tsb; - nentries = mm->context.tsb_block[MM_TSB_BASE ].tsb_nentries; -if (tlb_type == cheetah_plus || tlb_type == hypervisor) - base =__pa (base); -__flush_tsb_one_entry (base, vaddr,PAGE_SHIFT , nentries); - +if (!huge) { + base = (unsigned long ) mm->context.tsb_block[MM_TSB_BASE ].tsb; + nentries = mm->context.tsb_block[MM_TSB_BASE ].tsb_nentries; +if (tlb_type == cheetah_plus || tlb_type == hypervisor) + base =__pa (base); +__flush_tsb_one_entry (base, vaddr,PAGE_SHIFT , nentries); + }#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -if (mm->context.tsb_block[MM_TSB_HUGE ].tsb) { +if (huge && mm->context.tsb_block[MM_TSB_HUGE ].tsb) { base = (unsigned long ) mm->context.tsb_block[MM_TSB_HUGE ].tsb; nentries = mm->context.tsb_block[MM_TSB_HUGE ].tsb_nentries;if (tlb_type == cheetah_plus || tlb_type == hypervisor)
Greg Kroah-Hartman
maintainerPATCH 57/75 sparc64: Take ctx_alloc_lock properly in hugetlb_setup().
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: "David S. Miller" <[email protected]>
[ Upstream commit 9ea46abe22550e3366ff7cee2f8391b35b12f730 ]
On cheetahplus chips we take the ctx_alloc_lock in order to modify the TLB lookup parameters for the indexed TLBs, which are stored in the context register.
This is called with interrupts disabled, however ctx_alloc_lock is an IRQ safe lock, therefore we must take acquire/release it properly with spin_{lock,unlock}_irq().
--- arch/sparc/mm/init_64.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
arch/sparc/mm/init_64.c +7 -3
@@ -2821,9 +2821,10 @@ void hugetlb_setup(struct pt_regs *regs)* the Data-TLB for huge pages. */ if (tlb_type == cheetah_plus) { +bool need_context_reload = false;unsigned long ctx; -spin_lock (&ctx_alloc_lock); +spin_lock_irq (&ctx_alloc_lock); ctx = mm->context.sparc64_ctx_val; ctx &= ~CTX_PGSZ_MASK ; ctx |=CTX_PGSZ_BASE <<CTX_PGSZ0_SHIFT ;
@@ -2842,9 +2843,12 @@ void hugetlb_setup(struct pt_regs *regs)* also executing in this address space. */ mm->context.sparc64_ctx_val = ctx; - on_each_cpu(context_reload, mm, 0); + need_context_reload = true; } -spin_unlock (&ctx_alloc_lock); +spin_unlock_irq (&ctx_alloc_lock); + +if (need_context_reload) +on_each_cpu (context_reload, mm,0 ); } }#endif
Greg Kroah-Hartman
maintainerPATCH 58/75 sparc: Harden signal return frame checks.
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: "David S. Miller" <[email protected]>
[ Upstream commit d11c2a0de2824395656cf8ed15811580c9dd38aa ]
All signal frames must be at least 16-byte aligned, because that is the alignment we explicitly create when we build signal return stack frames.
All stack pointers must be at least 8-byte aligned.
--- arch/sparc/kernel/signal32.c | 46 ++++++++++++++++++++++++++--------------- arch/sparc/kernel/signal_32.c | 41 +++++++++++++++++++++++------------- arch/sparc/kernel/signal_64.c | 31 +++++++++++++++++---------- arch/sparc/kernel/sigutil_32.c | 9 +++++++- arch/sparc/kernel/sigutil_64.c | 10 +++++++- 5 files changed, 92 insertions(+), 45 deletions(-)
arch/sparc/kernel/signal32.c +30 -16
@@ -138,12 +138,24 @@ int copy_siginfo_from_user32(siginfo_t *return 0 ; } +/* Checks if the fp is valid. We always build signal frames which are +* 16-byte aligned, therefore we can always enforce that the restore +* frame has that property as well. +*/ +static bool invalid_frame_pointer (void __user *fp,int fplen) +{ +if ((((unsigned long ) fp) &15 ) || + ((unsigned long )fp) >0x100000000ULL - fplen) +return true; +return false; +} +void do_sigreturn32 (struct pt_regs *regs) {struct signal_frame32 __user *sf;compat_uptr_t fpu_save;compat_uptr_t rwin_save; -unsigned int psr; +unsigned int psr, ufp;unsigned pc, npc;sigset_t set;compat_sigset_t seta;
@@ -158,11 +170,16 @@ void do_sigreturn32(struct pt_regs *regs sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP ];/* 1. Make sure we are not getting garbage from the user */ -if (!access_ok (VERIFY_READ , sf,sizeof (*sf)) || - (((unsigned long ) sf) &3 )) +if (invalid_frame_pointer (sf,sizeof (*sf))) + goto segv; + +if (get_user (ufp, &sf->info.si_regs.u_regs[UREG_FP ])) + goto segv; + +if (ufp &0x7 ) goto segv; -if (get_user (pc, &sf->info.si_regs.pc) || +if (__get_user (pc, &sf->info.si_regs.pc) ||__get_user (npc, &sf->info.si_regs.npc)) goto segv;
@@ -227,7 +244,7 @@ segv: asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) {struct rt_signal_frame32 __user *sf; -unsigned int psr, pc, npc; +unsigned int psr, pc, npc, ufp;compat_uptr_t fpu_save;compat_uptr_t rwin_save;sigset_t set;
@@ -242,11 +259,16 @@ asmlinkage void do_rt_sigreturn32(struct sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP ];/* 1. Make sure we are not getting garbage from the user */ -if (!access_ok (VERIFY_READ , sf,sizeof (*sf)) || - (((unsigned long ) sf) &3 )) +if (invalid_frame_pointer (sf,sizeof (*sf))) goto segv; -if (get_user (pc, &sf->regs.pc) || +if (get_user (ufp, &sf->regs.u_regs[UREG_FP ])) + goto segv; + +if (ufp &0x7 ) + goto segv; + +if (__get_user (pc, &sf->regs.pc) ||__get_user (npc, &sf->regs.npc)) goto segv;
@@ -307,14 +329,6 @@ segv:force_sig (SIGSEGV , current); } -/* Checks if the fp is valid */ -static int invalid_frame_pointer (void __user *fp,int fplen) -{ -if ((((unsigned long ) fp) &7 ) || ((unsigned long )fp) >0x100000000ULL - fplen) -return 1 ; -return 0 ; -} -static void __user *get_sigframe (struct ksignal *ksig,struct pt_regs *regs,unsigned long framesize) {unsigned long sp;
arch/sparc/kernel/signal_32.c +26 -15
76 lines not on this page · raw message
arch/sparc/kernel/signal_64.c +20 -11
@@ -234,6 +234,17 @@ do_sigsegv: goto out; } +/* Checks if the fp is valid. We always build rt signal frames which +* are 16-byte aligned, therefore we can always enforce that the +* restore frame has that property as well. +*/ +static bool invalid_frame_pointer (void __user *fp) +{ +if (((unsigned long ) fp) &15 ) +return true; +return false; +} +struct rt_signal_frame {struct sparc_stackf ss;siginfo_t info;
@@ -246,8 +257,8 @@ struct rt_signal_frame {void do_rt_sigreturn (struct pt_regs *regs) { +unsigned long tpc, tnpc, tstate, ufp;struct rt_signal_frame __user *sf; -unsigned long tpc, tnpc, tstate;__siginfo_fpu_t __user *fpu_save;__siginfo_rwin_t __user *rwin_save;sigset_t set;
@@ -261,10 +272,16 @@ void do_rt_sigreturn(struct pt_regs *reg (regs->u_regs [UREG_FP ] +STACK_BIAS );/* 1. Make sure we are not getting garbage from the user */ -if (((unsigned long ) sf) &3 ) +if (invalid_frame_pointer (sf)) + goto segv; + +if (get_user (ufp, &sf->regs.u_regs[UREG_FP ])) goto segv; - err =get_user (tpc, &sf->regs.tpc); +if ((ufp +STACK_BIAS ) &0x7 ) + goto segv; + + err =__get_user (tpc, &sf->regs.tpc); err |=__get_user (tnpc, &sf->regs.tnpc);if (test_thread_flag (TIF_32BIT )) { tpc &=0xffffffff ;
@@ -308,14 +325,6 @@ segv:force_sig (SIGSEGV , current); } -/* Checks if the fp is valid */ -static int invalid_frame_pointer (void __user *fp) -{ -if (((unsigned long ) fp) &15 ) -return 1 ; -return 0 ; -} -static inline void __user *get_sigframe (struct ksignal *ksig,struct pt_regs *regs,unsigned long framesize) {unsigned long sp = regs->u_regs[UREG_FP ] +STACK_BIAS ;
arch/sparc/kernel/sigutil_32.c +8 -1
@@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs,int restore_fpu_state (struct pt_regs *regs,__siginfo_fpu_t __user *fpu) {int err; + +if (((unsigned long ) fpu) &3 ) +return -EFAULT ; +#ifdef CONFIG_SMP if (test_tsk_thread_flag (current,TIF_USEDFPU )) regs->psr &= ~PSR_EF ;
@@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_tstruct thread_info *t =current_thread_info ();int i, wsaved, err; -__get_user (wsaved, &rp->wsaved); +if (((unsigned long ) rp) &3 ) +return -EFAULT ; + +get_user (wsaved, &rp->wsaved);if (wsaved >NSWINS )return -EFAULT ;
arch/sparc/kernel/sigutil_64.c +8 -2
@@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *reunsigned long fprs;int err; - err =__get_user (fprs, &fpu->si_fprs); +if (((unsigned long ) fpu) &7 ) +return -EFAULT ; + + err =get_user (fprs, &fpu->si_fprs);fprs_write (0 ); regs->tstate &= ~TSTATE_PEF ;if (fprs &FPRS_DL )
@@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_tstruct thread_info *t =current_thread_info ();int i, wsaved, err; -__get_user (wsaved, &rp->wsaved); +if (((unsigned long ) rp) &7 ) +return -EFAULT ; + +get_user (wsaved, &rp->wsaved);if (wsaved >NSWINS )return -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 59/75 sparc64: Fix return from trap window fill crashes.
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: "David S. Miller" <[email protected]>
[ Upstream commit 7cafc0b8bf130f038b0ec2dcdd6a9de6dc59b65a ]
We must handle data access exception as well as memory address unaligned exceptions from return from trap window fill faults, not just normal TLB misses.
Otherwise we can get an OOPS that looks like this:
ld-linux.so.2(36808): Kernel bad sw trap 5 [#1]
CPU: 1 PID: 36808 Comm: ld-linux.so.2 Not tainted 4.6.0 #34 task: fff8000303be5c60 ti: fff8000301344000 task.ti: fff8000301344000 TSTATE: 0000004410001601 TPC: 0000000000a1a784 TNPC: 0000000000a1a788 Y: 00000002 Not tainted TPC: <do_sparc64_fault+0x5c4/0x700> g0: fff8000024fc8248 g1: 0000000000db04dc g2: 0000000000000000 g3: 0000000000000001 g4: fff8000303be5c60 g5: fff800030e672000 g6: fff8000301344000 g7: 0000000000000001 o0: 0000000000b95ee8 o1: 000000000000012b o2: 0000000000000000 o3: 0000000200b9b358 o4: 0000000000000000 o5: fff8000301344040 sp: fff80003013475c1 ret_pc: 0000000000a1a77c RPC: <do_sparc64_fault+0x5bc/0x700> l0: 00000000000007ff l1: 0000000000000000 l2: 000000000000005f l3: 0000000000000000 l4: fff8000301347e98 l5: fff8000024ff3060 l6: 0000000000000000 l7: 0000000000000000 i0: fff8000301347f60 i1: 0000000000102400 i2: 0000000000000000 i3: 0000000000000000 i4: 0000000000000000 i5: 0000000000000000 i6: fff80003013476a1 i7: 0000000000404d4c I7: <user_rtt_fill_fixup+0x6c/0x7c> Call Trace: [0000000000404d4c] user_rtt_fill_fixup+0x6c/0x7c
The window trap handlers are slightly clever, the trap table entries for them are composed of two pieces of code. First comes the code that actually performs the window fill or spill trap handling, and then there are three instructions at the end which are for exception processing.
The userland register window fill handler is:
add %sp, STACK_BIAS + 0x00, %g1; \ ldxa [%g1 + %g0] ASI, %l0; \ mov 0x08, %g2; \ mov 0x10, %g3; \ ldxa [%g1 + %g2] ASI, %l1; \ mov 0x18, %g5; \ ldxa [%g1 + %g3] ASI, %l2; \ ldxa [%g1 + %g5] ASI, %l3; \ add %g1, 0x20, %g1; \ ldxa [%g1 + %g0] ASI, %l4; \ ldxa [%g1 + %g2] ASI, %l5; \ ldxa [%g1 + %g3] ASI, %l6; \ ldxa [%g1 + %g5] ASI, %l7; \ add %g1, 0x20, %g1; \ ldxa [%g1 + %g0] ASI, %i0; \ ldxa [%g1 + %g2] ASI, %i1; \ ldxa [%g1 + %g3] ASI, %i2; \ ldxa [%g1 + %g5] ASI, %i3; \ add %g1, 0x20, %g1; \ ldxa [%g1 + %g0] ASI, %i4; \ ldxa [%g1 + %g2] ASI, %i5; \ ldxa [%g1 + %g3] ASI, %i6; \ ldxa [%g1 + %g5] ASI, %i7; \ restored; \ retry; nop; nop; nop; nop; \ b,a,pt %xcc, fill_fixup_dax; \ b,a,pt %xcc, fill_fixup_mna; \ b,a,pt %xcc, fill_fixup;
And the way this works is that if any of those memory accesses generate an exception, the exception handler can revector to one of those final three branch instructions depending upon which kind of exception the memory access took. In this way, the fault handler doesn't have to know if it was a spill or a fill that it's handling the fault for. It just always branches to the last instruction in the parent trap's handler.
For example, for a regular fault, the code goes:
winfix_trampoline:
rdpr %tpc, %g3 or %g3, 0x7c, %g3 wrpr %g3, %tnpc done
All window trap handlers are 0x80 aligned, so if we "or" 0x7c into the trap time program counter, we'll get that final instruction in the trap handler.
On return from trap, we have to pull the register window in but we do this by hand instead of just executing a "restore" instruction for several reasons. The largest being that from Niagara and onward we simply don't have enough levels in the trap stack to fully resolve all possible exception cases of a window fault when we are already at trap level 1 (which we enter to get ready to return from the original trap).
This is executed inline via the FILL_*_RTRAP handlers. rtrap_64.S's code branches directly to these to do the window fill by hand if necessary. Now if you look at them, we'll see at the end:
ba,a,pt %xcc, user_rtt_fill_fixup; ba,a,pt %xcc, user_rtt_fill_fixup; ba,a,pt %xcc, user_rtt_fill_fixup;
And oops, all three cases are handled like a fault.
This doesn't work because each of these trap types (data access exception, memory address unaligned, and faults) store their auxiliary info in different registers to pass on to the C handler which does the real work.
So in the case where the stack was unaligned, the unaligned trap handler sets up the arg registers one way, and then we branched to the fault handler which expects them setup another way.
So the FAULT_TYPE_* value ends up basically being garbage, and randomly would generate the backtrace seen above.
--- arch/sparc/include/asm/head_64.h | 4 + arch/sparc/include/asm/ttable.h | 8 +-- arch/sparc/kernel/Makefile | 1 arch/sparc/kernel/rtrap_64.S | 59 +++-------------------- arch/sparc/kernel/urtt_fill.S | 98 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 53 deletions(-) create mode 100644 arch/sparc/kernel/urtt_fill.S
arch/sparc/include/asm/head_64.h +4 -0
@@ -15,6 +15,10 @@#define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ) +#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE) +#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV) +#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG) +#define __CHEETAH_ID 0x003e0014#define __JALAPENO_ID 0x003e0016#define __SERRANO_ID 0x003e0022
arch/sparc/include/asm/ttable.h +4 -4
@@ -589,8 +589,8 @@ user_rtt_fill_64bit: \ restored; \ nop; nop; nop; nop; nop; nop; \ nop; nop; nop; nop; nop; \ - ba,a,pt %xcc, user_rtt_fill_fixup; \ - ba,a,pt %xcc, user_rtt_fill_fixup; \ + ba,a,pt %xcc, user_rtt_fill_fixup_dax; \ + ba,a,pt %xcc, user_rtt_fill_fixup_mna; \ ba,a,pt %xcc, user_rtt_fill_fixup;
@@ -652,8 +652,8 @@ user_rtt_fill_32bit: \ restored; \ nop; nop; nop; nop; nop; \ nop; nop; nop; \ - ba,a,pt %xcc, user_rtt_fill_fixup; \ - ba,a,pt %xcc, user_rtt_fill_fixup; \ + ba,a,pt %xcc, user_rtt_fill_fixup_dax; \ + ba,a,pt %xcc, user_rtt_fill_fixup_mna; \ ba,a,pt %xcc, user_rtt_fill_fixup;
arch/sparc/kernel/Makefile +1 -0
@@ -21,6 +21,7 @@ CFLAGS_REMOVE_perf_event.o := -pg CFLAGS_REMOVE_pcr.o := -pg endif +obj-$(CONFIG_SPARC64) += urtt_fill.o obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o obj-$(CONFIG_SPARC32) += etrap_32.o obj-$(CONFIG_SPARC32) += rtrap_32.o
arch/sparc/kernel/rtrap_64.S +10 -49
72 lines not on this page · raw message
arch/sparc/kernel/urtt_fill.S new file +98 -0
98 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 60/75 MIPS: Fix 64k page support for 32 bit kernels.
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Baechle <[email protected]>
commit d7de413475f443957a0c1d256e405d19b3a2cb22 upstream.
TASK_SIZE was defined as 0x7fff8000UL which for 64k pages is not a multiple of the page size. Somewhere further down the math fails such that executing an ELF binary fails.
--- arch/mips/include/asm/processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/include/asm/processor.h +1 -1
@@ -45,7 +45,7 @@ extern unsigned int vced_count, vcei_cou* User space process size: 2GB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. */ -#define TASK_SIZE 0x7fff8000UL +#define TASK_SIZE 0x80000000UL#endif #define STACK_TOP_MAX TASK_SIZE
Greg Kroah-Hartman
maintainerPATCH 61/75 netfilter: x_tables: validate e->target_offset early
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit bdf533de6968e9686df777dc178486f600c6e617 upstream.
We should check that e->target_offset is sane before mark_source_chains gets called since it will fetch the target entry for loop detection.
--- net/ipv4/netfilter/arp_tables.c | 17 ++++++++--------- net/ipv4/netfilter/ip_tables.c | 17 ++++++++--------- net/ipv6/netfilter/ip6_tables.c | 17 ++++++++--------- 3 files changed, 24 insertions(+), 27 deletions(-)
net/ipv4/netfilter/arp_tables.c +8 -9
@@ -474,14 +474,12 @@ next:return 1 ; } -static inline int check_entry (const struct arpt_entry *e,const char *name) +static inline int check_entry (const struct arpt_entry *e) {const struct xt_entry_target *t; -if (!arp_checkentry (&e->arp)) { -duprintf ("arp_tables: arp check failed %p %s.\n" , e, name); +if (!arp_checkentry (&e->arp))return -EINVAL ; - }if (e->target_offset +sizeof (struct xt_entry_target ) > e->next_offset)return -EINVAL ;
@@ -522,10 +520,6 @@ find_check_entry(struct arpt_entry *e, cstruct xt_target *target;int ret; - ret =check_entry (e, name); -if (ret) -return ret; - e->counters.pcnt =xt_percpu_counter_alloc ();if (IS_ERR_VALUE (e->counters.pcnt))return -ENOMEM ;
@@ -576,6 +570,7 @@ static inline int check_entry_size_and_h unsigned int valid_hooks) {unsigned int h; +int err;if ((unsigned long )e % __alignof__(struct arpt_entry ) !=0 || (unsigned char *)e +sizeof (struct arpt_entry ) >= limit) {
@@ -590,6 +585,10 @@ static inline int check_entry_size_and_hreturn -EINVAL ; } + err =check_entry (e); +if (err) +return err; +/* Check hooks & underflows */ for (h =0 ; h <NF_ARP_NUMHOOKS ; h++) {if (!(valid_hooks & (1 << h)))
@@ -1246,7 +1245,7 @@ check_compat_entry_size_and_hooks(struct }/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct arpt_entry *)e, name); + ret =check_entry ((struct arpt_entry *)e);if (ret)return ret;
net/ipv4/netfilter/ip_tables.c +8 -9
@@ -569,14 +569,12 @@ static void cleanup_match(struct xt_entr }static int -check_entry (const struct ipt_entry *e,const char *name) +check_entry (const struct ipt_entry *e) {const struct xt_entry_target *t; -if (!ip_checkentry (&e->ip)) { -duprintf ("ip check failed %p %s.\n" , e, name); +if (!ip_checkentry (&e->ip))return -EINVAL ; - }if (e->target_offset +sizeof (struct xt_entry_target ) > e->next_offset)
@@ -666,10 +664,6 @@ find_check_entry(struct ipt_entry *e, ststruct xt_mtchk_param mtpar;struct xt_entry_match *ematch; - ret =check_entry (e, name); -if (ret) -return ret; - e->counters.pcnt =xt_percpu_counter_alloc ();if (IS_ERR_VALUE (e->counters.pcnt))return -ENOMEM ;
@@ -741,6 +735,7 @@ check_entry_size_and_hooks(struct ipt_en unsigned int valid_hooks) {unsigned int h; +int err;if ((unsigned long )e % __alignof__(struct ipt_entry ) !=0 || (unsigned char *)e +sizeof (struct ipt_entry ) >= limit) {
@@ -755,6 +750,10 @@ check_entry_size_and_hooks(struct ipt_enreturn -EINVAL ; } + err =check_entry (e); +if (err) +return err; +/* Check hooks & underflows */ for (h =0 ; h <NF_INET_NUMHOOKS ; h++) {if (!(valid_hooks & (1 << h)))
@@ -1506,7 +1505,7 @@ check_compat_entry_size_and_hooks(struct }/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct ipt_entry *)e, name); + ret =check_entry ((struct ipt_entry *)e);if (ret)return ret;
net/ipv6/netfilter/ip6_tables.c +8 -9
@@ -581,14 +581,12 @@ static void cleanup_match(struct xt_entr }static int -check_entry (const struct ip6t_entry *e,const char *name) +check_entry (const struct ip6t_entry *e) {const struct xt_entry_target *t; -if (!ip6_checkentry (&e->ipv6)) { -duprintf ("ip_tables: ip check failed %p %s.\n" , e, name); +if (!ip6_checkentry (&e->ipv6))return -EINVAL ; - }if (e->target_offset +sizeof (struct xt_entry_target ) > e->next_offset)
@@ -679,10 +677,6 @@ find_check_entry(struct ip6t_entry *e, sstruct xt_mtchk_param mtpar;struct xt_entry_match *ematch; - ret =check_entry (e, name); -if (ret) -return ret; - e->counters.pcnt =xt_percpu_counter_alloc ();if (IS_ERR_VALUE (e->counters.pcnt))return -ENOMEM ;
@@ -753,6 +747,7 @@ check_entry_size_and_hooks(struct ip6t_e unsigned int valid_hooks) {unsigned int h; +int err;if ((unsigned long )e % __alignof__(struct ip6t_entry ) !=0 || (unsigned char *)e +sizeof (struct ip6t_entry ) >= limit) {
@@ -767,6 +762,10 @@ check_entry_size_and_hooks(struct ip6t_ereturn -EINVAL ; } + err =check_entry (e); +if (err) +return err; +/* Check hooks & underflows */ for (h =0 ; h <NF_INET_NUMHOOKS ; h++) {if (!(valid_hooks & (1 << h)))
@@ -1518,7 +1517,7 @@ check_compat_entry_size_and_hooks(struct }/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct ip6t_entry *)e, name); + ret =check_entry ((struct ip6t_entry *)e);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 62/75 netfilter: x_tables: make sure e->next_offset covers remaining blob size
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 6e94e0cfb0887e4013b3b930fa6ab1fe6bb6ba91 upstream.
Otherwise this function may read data beyond the ruleset blob.
--- net/ipv4/netfilter/arp_tables.c | 6 ++++-- net/ipv4/netfilter/ip_tables.c | 6 ++++-- net/ipv6/netfilter/ip6_tables.c | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-)
net/ipv4/netfilter/arp_tables.c +4 -2
@@ -573,7 +573,8 @@ static inline int check_entry_size_and_hint err;if ((unsigned long )e % __alignof__(struct arpt_entry ) !=0 || - (unsigned char *)e +sizeof (struct arpt_entry ) >= limit) { + (unsigned char *)e +sizeof (struct arpt_entry ) >= limit || + (unsigned char *)e + e->next_offset > limit) {duprintf ("Bad offset %p\n" , e);return -EINVAL ; }
@@ -1232,7 +1233,8 @@ check_compat_entry_size_and_hooks(structduprintf ("check_compat_entry_size_and_hooks %p\n" , e);if ((unsigned long )e % __alignof__(struct compat_arpt_entry ) !=0 || - (unsigned char *)e +sizeof (struct compat_arpt_entry ) >= limit) { + (unsigned char *)e +sizeof (struct compat_arpt_entry ) >= limit || + (unsigned char *)e + e->next_offset > limit) {duprintf ("Bad offset %p, limit = %p\n" , e, limit);return -EINVAL ; }
net/ipv4/netfilter/ip_tables.c +4 -2
@@ -738,7 +738,8 @@ check_entry_size_and_hooks(struct ipt_enint err;if ((unsigned long )e % __alignof__(struct ipt_entry ) !=0 || - (unsigned char *)e +sizeof (struct ipt_entry ) >= limit) { + (unsigned char *)e +sizeof (struct ipt_entry ) >= limit || + (unsigned char *)e + e->next_offset > limit) {duprintf ("Bad offset %p\n" , e);return -EINVAL ; }
@@ -1492,7 +1493,8 @@ check_compat_entry_size_and_hooks(structduprintf ("check_compat_entry_size_and_hooks %p\n" , e);if ((unsigned long )e % __alignof__(struct compat_ipt_entry ) !=0 || - (unsigned char *)e +sizeof (struct compat_ipt_entry ) >= limit) { + (unsigned char *)e +sizeof (struct compat_ipt_entry ) >= limit || + (unsigned char *)e + e->next_offset > limit) {duprintf ("Bad offset %p, limit = %p\n" , e, limit);return -EINVAL ; }
net/ipv6/netfilter/ip6_tables.c +4 -2
@@ -750,7 +750,8 @@ check_entry_size_and_hooks(struct ip6t_eint err;if ((unsigned long )e % __alignof__(struct ip6t_entry ) !=0 || - (unsigned char *)e +sizeof (struct ip6t_entry ) >= limit) { + (unsigned char *)e +sizeof (struct ip6t_entry ) >= limit || + (unsigned char *)e + e->next_offset > limit) {duprintf ("Bad offset %p\n" , e);return -EINVAL ; }
@@ -1504,7 +1505,8 @@ check_compat_entry_size_and_hooks(structduprintf ("check_compat_entry_size_and_hooks %p\n" , e);if ((unsigned long )e % __alignof__(struct compat_ip6t_entry ) !=0 || - (unsigned char *)e +sizeof (struct compat_ip6t_entry ) >= limit) { + (unsigned char *)e +sizeof (struct compat_ip6t_entry ) >= limit || + (unsigned char *)e + e->next_offset > limit) {duprintf ("Bad offset %p, limit = %p\n" , e, limit);return -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 63/75 netfilter: x_tables: fix unconditional helper
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 54d83fc74aa9ec72794373cb47432c5f7fb1a309 upstream.
Ben Hawkes says:
In the mark_source_chains function (net/ipv4/netfilter/ip_tables.c) it is possible for a user-supplied ipt_entry structure to have a large next_offset field. This field is not bounds checked prior to writing a counter value at the supplied offset.
Problem is that mark_source_chains should not have been called -- the rule doesn't have a next entry, so its supposed to return an absolute verdict of either ACCEPT or DROP.
However, the function conditional() doesn't work as the name implies. It only checks that the rule is using wildcard address matching.
However, an unconditional rule must also not be using any matches (no -m args).
The underflow validator only checked the addresses, therefore passing the 'unconditional absolute verdict' test, while mark_source_chains also tested for presence of matches, and thus proceeeded to the next (not-existent) rule.
Unify this so that all the callers have same idea of 'unconditional rule'.
--- net/ipv4/netfilter/arp_tables.c | 18 +++++++++--------- net/ipv4/netfilter/ip_tables.c | 23 +++++++++++------------ net/ipv6/netfilter/ip6_tables.c | 23 +++++++++++------------ 3 files changed, 31 insertions(+), 33 deletions(-)
net/ipv4/netfilter/arp_tables.c +9 -9
@@ -359,11 +359,12 @@ unsigned int arpt_do_table(struct sk_buf }/* All zeroes == unconditional rule. */ -static inline bool unconditional (const struct arpt_arp *arp) +static inline bool unconditional (const struct arpt_entry *e) {static const struct arpt_arp uncond; -return memcmp (arp, &uncond,sizeof (uncond)) ==0 ; +return e->target_offset ==sizeof (struct arpt_entry ) && +memcmp (&e->arp, &uncond,sizeof (uncond)) ==0 ; }/* Figures out from what hook each rule can be called: returns 0 if
@@ -402,11 +403,10 @@ static int mark_source_chains(const stru |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS));/* Unconditional return/END. */ -if ((e->target_offset ==sizeof (struct arpt_entry ) && +if ((unconditional (e) && (strcmp (t->target.u.user.name,XT_STANDARD_TARGET ) ==0 ) && - t->verdict <0 &&unconditional (&e->arp)) || - visited) { + t->verdict <0 ) || visited) {unsigned int oldpos, size; if ((strcmp(t->target.u.user.name,
@@ -551,7 +551,7 @@ static bool check_underflow(const structconst struct xt_entry_target *t;unsigned int verdict; -if (!unconditional (&e->arp)) +if (!unconditional (e))return false; t =arpt_get_target_c (e);if (strcmp (t->u.user.name,XT_STANDARD_TARGET ) !=0 )
@@ -598,9 +598,9 @@ static inline int check_entry_size_and_h newinfo->hook_entry[h] = hook_entries[h];if ((unsigned char *)e - base == underflows[h]) {if (!check_underflow (e)) { -pr_err ("Underflows must be unconditional and " -"use the STANDARD target with " -"ACCEPT/DROP\n" ); +pr_debug ("Underflows must be unconditional and " +"use the STANDARD target with " +"ACCEPT/DROP\n" );return -EINVAL ; } newinfo->underflow[h] = underflows[h];
net/ipv4/netfilter/ip_tables.c +11 -12
@@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int/* All zeroes == unconditional rule. */ /* Mildly perf critical (only if packet tracing is on) */ -static inline bool unconditional (const struct ipt_ip *ip) +static inline bool unconditional (const struct ipt_entry *e) {static const struct ipt_ip uncond; -return memcmp (ip, &uncond,sizeof (uncond)) ==0 ; +return e->target_offset ==sizeof (struct ipt_entry ) && +memcmp (&e->ip, &uncond,sizeof (uncond)) ==0 ;#undef FWINV }
@@ -229,11 +230,10 @@ get_chainname_rulenum(const struct ipt_e }else if (s == e) { (*rulenum)++; -if (s->target_offset ==sizeof (struct ipt_entry ) && +if (unconditional (s) &&strcmp (t->target.u.kernel.target->name,XT_STANDARD_TARGET ) ==0 && - t->verdict <0 && -unconditional (&s->ip)) { + t->verdict <0 ) {/* Tail of chains: STANDARD target (return/policy) */ *comment = *chainname == hookname ? comments[NF_IP_TRACE_COMMENT_POLICY]
@@ -476,11 +476,10 @@ mark_source_chains(const struct xt_table e->comefrom |= ((1 << hook) | (1 <<NF_INET_NUMHOOKS ));/* Unconditional return/END. */ -if ((e->target_offset ==sizeof (struct ipt_entry ) && +if ((unconditional (e) && (strcmp (t->target.u.user.name,XT_STANDARD_TARGET ) ==0 ) && - t->verdict <0 &&unconditional (&e->ip)) || - visited) { + t->verdict <0 ) || visited) {unsigned int oldpos, size; if ((strcmp(t->target.u.user.name,
@@ -715,7 +714,7 @@ static bool check_underflow(const structconst struct xt_entry_target *t;unsigned int verdict; -if (!unconditional (&e->ip)) +if (!unconditional (e))return false; t =ipt_get_target_c (e);if (strcmp (t->u.user.name,XT_STANDARD_TARGET ) !=0 )
@@ -763,9 +762,9 @@ check_entry_size_and_hooks(struct ipt_en newinfo->hook_entry[h] = hook_entries[h];if ((unsigned char *)e - base == underflows[h]) {if (!check_underflow (e)) { -pr_err ("Underflows must be unconditional and " -"use the STANDARD target with " -"ACCEPT/DROP\n" ); +pr_debug ("Underflows must be unconditional and " +"use the STANDARD target with " +"ACCEPT/DROP\n" );return -EINVAL ; } newinfo->underflow[h] = underflows[h];
net/ipv6/netfilter/ip6_tables.c +11 -12
@@ -198,11 +198,12 @@ get_entry(const void *base, unsigned int/* All zeroes == unconditional rule. */ /* Mildly perf critical (only if packet tracing is on) */ -static inline bool unconditional (const struct ip6t_ip6 *ipv6) +static inline bool unconditional (const struct ip6t_entry *e) {static const struct ip6t_ip6 uncond; -return memcmp (ipv6, &uncond,sizeof (uncond)) ==0 ; +return e->target_offset ==sizeof (struct ip6t_entry ) && +memcmp (&e->ipv6, &uncond,sizeof (uncond)) ==0 ; } static inline const struct xt_entry_target *
@@ -258,11 +259,10 @@ get_chainname_rulenum(const struct ip6t_ }else if (s == e) { (*rulenum)++; -if (s->target_offset ==sizeof (struct ip6t_entry ) && +if (unconditional (s) &&strcmp (t->target.u.kernel.target->name,XT_STANDARD_TARGET ) ==0 && - t->verdict <0 && -unconditional (&s->ipv6)) { + t->verdict <0 ) {/* Tail of chains: STANDARD target (return/policy) */ *comment = *chainname == hookname ? comments[NF_IP6_TRACE_COMMENT_POLICY]
@@ -488,11 +488,10 @@ mark_source_chains(const struct xt_table e->comefrom |= ((1 << hook) | (1 <<NF_INET_NUMHOOKS ));/* Unconditional return/END. */ -if ((e->target_offset ==sizeof (struct ip6t_entry ) && +if ((unconditional (e) && (strcmp (t->target.u.user.name,XT_STANDARD_TARGET ) ==0 ) && - t->verdict <0 && -unconditional (&e->ipv6)) || visited) { + t->verdict <0 ) || visited) {unsigned int oldpos, size; if ((strcmp(t->target.u.user.name,
@@ -727,7 +726,7 @@ static bool check_underflow(const structconst struct xt_entry_target *t;unsigned int verdict; -if (!unconditional (&e->ipv6)) +if (!unconditional (e))return false; t =ip6t_get_target_c (e);if (strcmp (t->u.user.name,XT_STANDARD_TARGET ) !=0 )
@@ -775,9 +774,9 @@ check_entry_size_and_hooks(struct ip6t_e newinfo->hook_entry[h] = hook_entries[h];if ((unsigned char *)e - base == underflows[h]) {if (!check_underflow (e)) { -pr_err ("Underflows must be unconditional and " -"use the STANDARD target with " -"ACCEPT/DROP\n" ); +pr_debug ("Underflows must be unconditional and " +"use the STANDARD target with " +"ACCEPT/DROP\n" );return -EINVAL ; } newinfo->underflow[h] = underflows[h];
Greg Kroah-Hartman
maintainerPATCH 64/75 crypto: qat - fix adf_ctl_drv.c:undefined reference to adf_init_pf_wq
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tadeusz Struk <[email protected]>
commit 6dc5df71ee5c8b44607928bfe27be50314dcf848 upstream.
Fix undefined reference issue reported by kbuild test robot.
--- drivers/crypto/qat/qat_common/adf_common_drv.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/crypto/qat/qat_common/adf_common_drv.h +11 -2
@@ -108,6 +108,8 @@ void adf_dev_shutdown(struct adf_accel_dvoid adf_enable_pf2vf_interrupts (struct adf_accel_dev *accel_dev);void adf_disable_pf2vf_interrupts (struct adf_accel_dev *accel_dev); +int adf_init_pf_wq (void ); +void adf_exit_pf_wq (void );int adf_iov_putmsg (struct adf_accel_dev *accel_dev,u32 msg,u8 vf_nr);void adf_pf2vf_notify_restarting (struct adf_accel_dev *accel_dev);int adf_enable_vf2pf_comms (struct adf_accel_dev *accel_dev);
@@ -145,8 +147,6 @@ int adf_enable_aer(struct adf_accel_devvoid adf_disable_aer (struct adf_accel_dev *accel_dev);int adf_init_aer (void );void adf_exit_aer (void ); -int adf_init_pf_wq (void ); -void adf_exit_pf_wq (void );int adf_init_admin_comms (struct adf_accel_dev *accel_dev);void adf_exit_admin_comms (struct adf_accel_dev *accel_dev);int adf_send_admin_init (struct adf_accel_dev *accel_dev);
@@ -238,5 +238,14 @@ static inline int adf_sriov_configure(ststatic inline void adf_disable_sriov (struct adf_accel_dev *accel_dev) { } + +static inline int adf_init_pf_wq (void ) +{ +return 0 ; +} + +static inline void adf_exit_pf_wq (void ) +{ +}#endif #endif
Greg Kroah-Hartman
maintainerPATCH 65/75 drm/core: Do not preserve framebuffer on rmfb, v4.
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maarten Lankhorst <[email protected]>
commit f2d580b9a8149735cbc4b59c4a8df60173658140 upstream.
It turns out that preserving framebuffers after the rmfb call breaks vmwgfx userspace. This was originally introduced because it was thought nobody relied on the behavior, but unfortunately it seems there are exceptions.
drm_framebuffer_remove may fail with -EINTR now, so a straight revert is impossible. There is no way to remove the framebuffer from the lists and active planes without introducing a race because of the different locking requirements. Instead call drm_framebuffer_remove from a workqueue, which is unaffected by signals.
Changes since v1:
- Add comment.
Changes since v2:
- Add fastpath for refcount = 1. (danvet)
Changes since v3:
- Rebased.
- Restore lastclose framebuffer removal too.
Testcase: kms_rmfb_basic
References: https://lists.freedesktop.org/archives/dri-devel/2016-March/102876.html
--- drivers/gpu/drm/drm_crtc.c | 60 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-)
drivers/gpu/drm/drm_crtc.c +55 -5
@@ -3316,6 +3316,24 @@ int drm_mode_addfb2(struct drm_device *dreturn 0 ; } +struct drm_mode_rmfb_work { +struct work_struct work; +struct list_head fbs; +}; + +static void drm_mode_rmfb_work_fn (struct work_struct *w) +{ +struct drm_mode_rmfb_work *arg =container_of (w,typeof (*arg), work); + +while (!list_empty (&arg->fbs)) { +struct drm_framebuffer *fb = +list_first_entry (&arg->fbs,typeof (*fb), filp_head); + +list_del_init (&fb->filp_head); +drm_framebuffer_remove (fb); + } +} +/** * drm_mode_rmfb - remove an FB from the configuration * @dev: drm device for the ioctl
@@ -3356,7 +3374,25 @@ int drm_mode_rmfb(struct drm_device *devmutex_unlock (&dev->mode_config.fb_lock);mutex_unlock (&file_priv->fbs_lock); -drm_framebuffer_unreference (fb); +/* +* we now own the reference that was stored in the fbs list +* +* drm_framebuffer_remove may fail with -EINTR on pending signals, +* so run this in a separate stack as there's no way to correctly +* handle this after the fb is already removed from the lookup table. +*/ +if (atomic_read (&fb->refcount.refcount) >1 ) { +struct drm_mode_rmfb_work arg; + +INIT_WORK_ONSTACK (&arg.work, drm_mode_rmfb_work_fn); +INIT_LIST_HEAD (&arg.fbs); +list_add_tail (&fb->filp_head, &arg.fbs); + +schedule_work (&arg.work); +flush_work (&arg.work); +destroy_work_on_stack (&arg.work); + }else +drm_framebuffer_unreference (fb);return 0 ;
@@ -3509,7 +3545,6 @@ out_err1:return ret; } -/** * drm_fb_release - remove and free the FBs on this file * @priv: drm file for the ioctl
@@ -3524,6 +3559,9 @@ out_err1:void drm_fb_release (struct drm_file *priv) {struct drm_framebuffer *fb, *tfb; +struct drm_mode_rmfb_work arg; + +INIT_LIST_HEAD (&arg.fbs);/* * When the file gets released that means no one else can access the fb
@@ -3536,10 +3574,22 @@ void drm_fb_release(struct drm_file *pri* at it any more. */ list_for_each_entry_safe (fb, tfb, &priv->fbs, filp_head) { -list_del_init (&fb->filp_head); +if (atomic_read (&fb->refcount.refcount) >1 ) { +list_move_tail (&fb->filp_head, &arg.fbs); + }else { +list_del_init (&fb->filp_head); -/* This drops the fpriv->fbs reference. */ -drm_framebuffer_unreference (fb); +/* This drops the fpriv->fbs reference. */ +drm_framebuffer_unreference (fb); + } + } + +if (!list_empty (&arg.fbs)) { +INIT_WORK_ONSTACK (&arg.work, drm_mode_rmfb_work_fn); + +schedule_work (&arg.work); +flush_work (&arg.work); +destroy_work_on_stack (&arg.work); } }
Greg Kroah-Hartman
maintainerPATCH 66/75 netfilter: x_tables: dont move to non-existent next rule
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit f24e230d257af1ad7476c6e81a8dc3127a74204e upstream.
Ben Hawkes says:
In the mark_source_chains function (net/ipv4/netfilter/ip_tables.c) it is possible for a user-supplied ipt_entry structure to have a large next_offset field. This field is not bounds checked prior to writing a counter value at the supplied offset.
Base chains enforce absolute verdict.
User defined chains are supposed to end with an unconditional return, xtables userspace adds them automatically.
But if such return is missing we will move to non-existent next rule.
--- net/ipv4/netfilter/arp_tables.c | 8 +++++--- net/ipv4/netfilter/ip_tables.c | 4 ++++ net/ipv6/netfilter/ip6_tables.c | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-)
net/ipv4/netfilter/arp_tables.c +5 -3
@@ -439,6 +439,8 @@ static int mark_source_chains(const stru size = e->next_offset; e = (struct arpt_entry *) (entry0 + pos + size); +if (pos + size >= newinfo->size) +return 0 ; e->counters.pcnt = pos; pos += size; }else {
@@ -461,6 +463,8 @@ static int mark_source_chains(const stru }else {/* ... this is a fallthru */ newpos = pos + e->next_offset; +if (newpos >= newinfo->size) +return 0 ; } e = (struct arpt_entry *) (entry0 + newpos);
@@ -691,10 +695,8 @@ static int translate_table(struct xt_tab } } -if (!mark_source_chains (newinfo, repl->valid_hooks, entry0)) { -duprintf ("Looping hook\n" ); +if (!mark_source_chains (newinfo, repl->valid_hooks, entry0))return -ELOOP ; - }/* Finally, each sanity check must pass */ i =0 ;
net/ipv4/netfilter/ip_tables.c +4 -0
@@ -520,6 +520,8 @@ mark_source_chains(const struct xt_table size = e->next_offset; e = (struct ipt_entry *) (entry0 + pos + size); +if (pos + size >= newinfo->size) +return 0 ; e->counters.pcnt = pos; pos += size; }else {
@@ -541,6 +543,8 @@ mark_source_chains(const struct xt_table }else {/* ... this is a fallthru */ newpos = pos + e->next_offset; +if (newpos >= newinfo->size) +return 0 ; } e = (struct ipt_entry *) (entry0 + newpos);
net/ipv6/netfilter/ip6_tables.c +4 -0
@@ -532,6 +532,8 @@ mark_source_chains(const struct xt_table size = e->next_offset; e = (struct ip6t_entry *) (entry0 + pos + size); +if (pos + size >= newinfo->size) +return 0 ; e->counters.pcnt = pos; pos += size; }else {
@@ -553,6 +555,8 @@ mark_source_chains(const struct xt_table }else {/* ... this is a fallthru */ newpos = pos + e->next_offset; +if (newpos >= newinfo->size) +return 0 ; } e = (struct ip6t_entry *) (entry0 + newpos);
Greg Kroah-Hartman
maintainerPATCH 67/75 netfilter: x_tables: validate targets of jumps
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 36472341017529e2b12573093cc0f68719300997 upstream.
When we see a jump also check that the offset gets us to beginning of a rule (an ipt_entry).
The extra overhead is negible, even with absurd cases.
300k custom rules, 300k jumps to 'next' user chain:
[ plus one jump from INPUT to first userchain ]:
Before:
real 0m24.874s user 0m7.532s sys 0m16.076s
After:
real 0m27.464s user 0m7.436s sys 0m18.840s
--- net/ipv4/netfilter/arp_tables.c | 16 ++++++++++++++++ net/ipv4/netfilter/ip_tables.c | 16 ++++++++++++++++ net/ipv6/netfilter/ip6_tables.c | 16 ++++++++++++++++ 3 files changed, 48 insertions(+)
net/ipv4/netfilter/arp_tables.c +16 -0
@@ -367,6 +367,18 @@ static inline bool unconditional(const smemcmp (&e->arp, &uncond,sizeof (uncond)) ==0 ; } +static bool find_jump_target (const struct xt_table_info *t, +const struct arpt_entry *target) +{ +struct arpt_entry *iter; + + xt_entry_foreach(iter, t->entries, t->size) { +if (iter == target) +return true; + } +return false; +} +/* Figures out from what hook each rule can be called: returns 0 if * there are loops. Puts hook bitmask in comefrom. */
@@ -460,6 +472,10 @@ static int mark_source_chains(const stru/* This a jump; chase it. */ duprintf ("Jump rule %u -> %u\n" , pos, newpos); + e = (struct arpt_entry *) + (entry0 + newpos); +if (!find_jump_target (newinfo, e)) +return 0 ; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
net/ipv4/netfilter/ip_tables.c +16 -0
@@ -443,6 +443,18 @@ ipt_do_table(struct sk_buff *skb,#endif } +static bool find_jump_target (const struct xt_table_info *t, +const struct ipt_entry *target) +{ +struct ipt_entry *iter; + + xt_entry_foreach(iter, t->entries, t->size) { +if (iter == target) +return true; + } +return false; +} +/* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int
@@ -540,6 +552,10 @@ mark_source_chains(const struct xt_table/* This a jump; chase it. */ duprintf ("Jump rule %u -> %u\n" , pos, newpos); + e = (struct ipt_entry *) + (entry0 + newpos); +if (!find_jump_target (newinfo, e)) +return 0 ; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
net/ipv6/netfilter/ip6_tables.c +16 -0
@@ -455,6 +455,18 @@ ip6t_do_table(struct sk_buff *skb,#endif } +static bool find_jump_target (const struct xt_table_info *t, +const struct ip6t_entry *target) +{ +struct ip6t_entry *iter; + + xt_entry_foreach(iter, t->entries, t->size) { +if (iter == target) +return true; + } +return false; +} +/* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int
@@ -552,6 +564,10 @@ mark_source_chains(const struct xt_table/* This a jump; chase it. */ duprintf ("Jump rule %u -> %u\n" , pos, newpos); + e = (struct ip6t_entry *) + (entry0 + newpos); +if (!find_jump_target (newinfo, e)) +return 0 ; }else {/* ... this is a fallthru */ newpos = pos + e->next_offset;
Greg Kroah-Hartman
maintainerPATCH 68/75 netfilter: x_tables: add and use xt_check_entry_offsets
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 7d35812c3214afa5b37a675113555259cfd67b98 upstream.
Currently arp/ip and ip6tables each implement a short helper to check that the target offset is large enough to hold one xt_entry_target struct and that t->u.target_size fits within the current rule.
Unfortunately these checks are not sufficient.
To avoid adding new tests to all of ip/ip6/arptables move the current checks into a helper, then extend this helper in followup patches.
--- include/linux/netfilter/x_tables.h | 4 ++++ net/ipv4/netfilter/arp_tables.c | 11 +---------- net/ipv4/netfilter/ip_tables.c | 12 +----------- net/ipv6/netfilter/ip6_tables.c | 12 +----------- net/netfilter/x_tables.c | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 32 deletions(-)
include/linux/netfilter/x_tables.h +4 -0
@@ -239,6 +239,10 @@ void xt_unregister_match(struct xt_matchint xt_register_matches (struct xt_match *match,unsigned int n);void xt_unregister_matches (struct xt_match *match,unsigned int n); +int xt_check_entry_offsets (const void *base, +unsigned int target_offset, +unsigned int next_offset); +int xt_check_match (struct xt_mtchk_param *,unsigned int size,u_int8_t proto,bool inv_proto); int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto,
net/ipv4/netfilter/arp_tables.c +1 -10
@@ -496,19 +496,10 @@ next:static inline int check_entry (const struct arpt_entry *e) { -const struct xt_entry_target *t; -if (!arp_checkentry (&e->arp))return -EINVAL ; -if (e->target_offset +sizeof (struct xt_entry_target ) > e->next_offset) -return -EINVAL ; - - t =arpt_get_target_c (e); -if (e->target_offset + t->u.target_size > e->next_offset) -return -EINVAL ; - -return 0 ; +return xt_check_entry_offsets (e, e->target_offset, e->next_offset); }static inline int check_target (struct arpt_entry *e,const char *name)
net/ipv4/netfilter/ip_tables.c +1 -11
@@ -590,20 +590,10 @@ static void cleanup_match(struct xt_entrstatic int check_entry (const struct ipt_entry *e) { -const struct xt_entry_target *t; -if (!ip_checkentry (&e->ip))return -EINVAL ; -if (e->target_offset +sizeof (struct xt_entry_target ) > - e->next_offset) -return -EINVAL ; - - t =ipt_get_target_c (e); -if (e->target_offset + t->u.target_size > e->next_offset) -return -EINVAL ; - -return 0 ; +return xt_check_entry_offsets (e, e->target_offset, e->next_offset); } static int
net/ipv6/netfilter/ip6_tables.c +1 -11
@@ -602,20 +602,10 @@ static void cleanup_match(struct xt_entrstatic int check_entry (const struct ip6t_entry *e) { -const struct xt_entry_target *t; -if (!ip6_checkentry (&e->ipv6))return -EINVAL ; -if (e->target_offset +sizeof (struct xt_entry_target ) > - e->next_offset) -return -EINVAL ; - - t =ip6t_get_target_c (e); -if (e->target_offset + t->u.target_size > e->next_offset) -return -EINVAL ; - -return 0 ; +return xt_check_entry_offsets (e, e->target_offset, e->next_offset); }static int check_match (struct xt_entry_match *m,struct xt_mtchk_param *par)
net/netfilter/x_tables.c +34 -0
@@ -540,6 +540,40 @@ int xt_compat_match_to_user(const structEXPORT_SYMBOL_GPL (xt_compat_match_to_user);#endif /* CONFIG_COMPAT */ +/** +* xt_check_entry_offsets - validate arp/ip/ip6t_entry +* +* @base: pointer to arp/ip/ip6t_entry +* @target_offset: the arp/ip/ip6_t->target_offset +* @next_offset: the arp/ip/ip6_t->next_offset +* +* validates that target_offset and next_offset are sane. +* +* The arp/ip/ip6t_entry structure @base must have passed following tests: +* - it must point to a valid memory location +* - base to base + next_offset must be accessible, i.e. not exceed allocated +* length. +* +* Return: 0 on success, negative errno on failure. +*/ +int xt_check_entry_offsets (const void *base, +unsigned int target_offset, +unsigned int next_offset) +{ +const struct xt_entry_target *t; +const char *e = base; + +if (target_offset +sizeof (*t) > next_offset) +return -EINVAL ; + + t = (void *)(e + target_offset); +if (target_offset + t->u.target_size > next_offset) +return -EINVAL ; + +return 0 ; +} +EXPORT_SYMBOL (xt_check_entry_offsets); +int xt_check_target (struct xt_tgchk_param *par,unsigned int size,u_int8_t proto,bool inv_proto) {
Greg Kroah-Hartman
maintainerPATCH 69/75 netfilter: x_tables: kill check_entry helper
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit aa412ba225dd3bc36d404c28cdc3d674850d80d0 upstream.
Once we add more sanity testing to xt_check_entry_offsets it becomes relvant if we're expecting a 32bit 'config_compat' blob or a normal one.
Since we already have a lot of similar-named functions (check_entry, compat_check_entry, find_and_check_entry, etc.) and the current incarnation is short just fold its contents into the callers.
--- net/ipv4/netfilter/arp_tables.c | 19 ++++++++----------- net/ipv4/netfilter/ip_tables.c | 20 ++++++++------------ net/ipv6/netfilter/ip6_tables.c | 20 ++++++++------------ 3 files changed, 24 insertions(+), 35 deletions(-)
net/ipv4/netfilter/arp_tables.c +8 -11
@@ -494,14 +494,6 @@ next:return 1 ; } -static inline int check_entry (const struct arpt_entry *e) -{ -if (!arp_checkentry (&e->arp)) -return -EINVAL ; - -return xt_check_entry_offsets (e, e->target_offset, e->next_offset); -} -static inline int check_target (struct arpt_entry *e,const char *name) {struct xt_entry_target *t =arpt_get_target (e);
@@ -597,7 +589,10 @@ static inline int check_entry_size_and_hreturn -EINVAL ; } - err =check_entry (e); +if (!arp_checkentry (&e->arp)) +return -EINVAL ; + + err =xt_check_entry_offsets (e, e->target_offset, e->next_offset);if (err)return err;
@@ -1255,8 +1250,10 @@ check_compat_entry_size_and_hooks(structreturn -EINVAL ; } -/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct arpt_entry *)e); +if (!arp_checkentry (&e->arp)) +return -EINVAL ; + + ret =xt_check_entry_offsets (e, e->target_offset, e->next_offset);if (ret)return ret;
net/ipv4/netfilter/ip_tables.c +8 -12
@@ -588,15 +588,6 @@ static void cleanup_match(struct xt_entr }static int -check_entry (const struct ipt_entry *e) -{ -if (!ip_checkentry (&e->ip)) -return -EINVAL ; - -return xt_check_entry_offsets (e, e->target_offset, e->next_offset); -} - -static int check_match (struct xt_entry_match *m,struct xt_mtchk_param *par) {const struct ipt_ip *ip = par->entryinfo;
@@ -760,7 +751,10 @@ check_entry_size_and_hooks(struct ipt_enreturn -EINVAL ; } - err =check_entry (e); +if (!ip_checkentry (&e->ip)) +return -EINVAL ; + + err =xt_check_entry_offsets (e, e->target_offset, e->next_offset);if (err)return err;
@@ -1515,8 +1509,10 @@ check_compat_entry_size_and_hooks(structreturn -EINVAL ; } -/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct ipt_entry *)e); +if (!ip_checkentry (&e->ip)) +return -EINVAL ; + + ret =xt_check_entry_offsets (e, e->target_offset, e->next_offset);if (ret)return ret;
net/ipv6/netfilter/ip6_tables.c +8 -12
@@ -599,15 +599,6 @@ static void cleanup_match(struct xt_entrmodule_put (par.match->me); } -static int -check_entry (const struct ip6t_entry *e) -{ -if (!ip6_checkentry (&e->ipv6)) -return -EINVAL ; - -return xt_check_entry_offsets (e, e->target_offset, e->next_offset); -} -static int check_match (struct xt_entry_match *m,struct xt_mtchk_param *par) {const struct ip6t_ip6 *ipv6 = par->entryinfo;
@@ -772,7 +763,10 @@ check_entry_size_and_hooks(struct ip6t_ereturn -EINVAL ; } - err =check_entry (e); +if (!ip6_checkentry (&e->ipv6)) +return -EINVAL ; + + err =xt_check_entry_offsets (e, e->target_offset, e->next_offset);if (err)return err;
@@ -1527,8 +1521,10 @@ check_compat_entry_size_and_hooks(structreturn -EINVAL ; } -/* For purposes of check_entry casting the compat entry is fine */ - ret =check_entry ((struct ip6t_entry *)e); +if (!ip6_checkentry (&e->ipv6)) +return -EINVAL ; + + ret =xt_check_entry_offsets (e, e->target_offset, e->next_offset);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 70/75 netfilter: x_tables: assert minimum target size
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit a08e4e190b866579896c09af59b3bdca821da2cd upstream.
The target size includes the size of the xt_entry_target struct.
--- net/netfilter/x_tables.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/x_tables.c +3 -0
@@ -567,6 +567,9 @@ int xt_check_entry_offsets(const void *breturn -EINVAL ; t = (void *)(e + target_offset); +if (t->u.target_size <sizeof (*t)) +return -EINVAL ; +if (target_offset + t->u.target_size > next_offset)return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 71/75 netfilter: x_tables: add compat version of xt_check_entry_offsets
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit fc1221b3a163d1386d1052184202d5dc50d302d1 upstream.
32bit rulesets have different layout and alignment requirements, so once more integrity checks get added to xt_check_entry_offsets it will reject well-formed 32bit rulesets.
--- include/linux/netfilter/x_tables.h | 3 +++ net/ipv4/netfilter/arp_tables.c | 3 ++- net/ipv4/netfilter/ip_tables.c | 3 ++- net/ipv6/netfilter/ip6_tables.c | 3 ++- net/netfilter/x_tables.c | 22 ++++++++++++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-)
include/linux/netfilter/x_tables.h +3 -0
@@ -492,6 +492,9 @@ void xt_compat_target_from_user(struct x unsigned int *size);int xt_compat_target_to_user (const struct xt_entry_target *t,void __user **dstptr,unsigned int *size); +int xt_compat_check_entry_offsets (const void *base, +unsigned int target_offset, +unsigned int next_offset);#endif /* CONFIG_COMPAT */ #endif /* _X_TABLES_H */
net/ipv4/netfilter/arp_tables.c +2 -1
@@ -1253,7 +1253,8 @@ check_compat_entry_size_and_hooks(structif (!arp_checkentry (&e->arp))return -EINVAL ; - ret =xt_check_entry_offsets (e, e->target_offset, e->next_offset); + ret =xt_compat_check_entry_offsets (e, e->target_offset, + e->next_offset);if (ret)return ret;
net/ipv4/netfilter/ip_tables.c +2 -1
@@ -1512,7 +1512,8 @@ check_compat_entry_size_and_hooks(structif (!ip_checkentry (&e->ip))return -EINVAL ; - ret =xt_check_entry_offsets (e, e->target_offset, e->next_offset); + ret =xt_compat_check_entry_offsets (e, + e->target_offset, e->next_offset);if (ret)return ret;
net/ipv6/netfilter/ip6_tables.c +2 -1
@@ -1524,7 +1524,8 @@ check_compat_entry_size_and_hooks(structif (!ip6_checkentry (&e->ipv6))return -EINVAL ; - ret =xt_check_entry_offsets (e, e->target_offset, e->next_offset); + ret =xt_compat_check_entry_offsets (e, + e->target_offset, e->next_offset);if (ret)return ret;
net/netfilter/x_tables.c +22 -0
@@ -538,6 +538,27 @@ int xt_compat_match_to_user(const struct return 0; }EXPORT_SYMBOL_GPL (xt_compat_match_to_user); + +int xt_compat_check_entry_offsets (const void *base, +unsigned int target_offset, +unsigned int next_offset) +{ +const struct compat_xt_entry_target *t; +const char *e = base; + +if (target_offset +sizeof (*t) > next_offset) +return -EINVAL ; + + t = (void *)(e + target_offset); +if (t->u.target_size <sizeof (*t)) +return -EINVAL ; + +if (target_offset + t->u.target_size > next_offset) +return -EINVAL ; + +return 0 ; +} +EXPORT_SYMBOL (xt_compat_check_entry_offsets);#endif /* CONFIG_COMPAT */ /**
@@ -548,6 +569,7 @@ EXPORT_SYMBOL_GPL(xt_compat_match_to_use* @next_offset: the arp/ip/ip6_t->next_offset * * validates that target_offset and next_offset are sane. +* Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version. * * The arp/ip/ip6t_entry structure @base must have passed following tests: * - it must point to a valid memory location
Greg Kroah-Hartman
maintainerPATCH 72/75 netfilter: x_tables: check standard target size too
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 7ed2abddd20cf8f6bd27f65bd218f26fa5bf7f44 upstream.
We have targets and standard targets -- the latter carries a verdict.
The ip/ip6tables validation functions will access t->verdict for the standard targets to fetch the jump offset or verdict for chainloop detection, but this happens before the targets get checked/validated.
Thus we also need to check for verdict presence here, else t->verdict can point right after a blob.
Spotted with UBSAN while testing malformed blobs.
--- net/netfilter/x_tables.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
net/netfilter/x_tables.c +15 -0
@@ -539,6 +539,13 @@ int xt_compat_match_to_user(const struct }EXPORT_SYMBOL_GPL (xt_compat_match_to_user); +/* non-compat version may have padding after verdict */ +struct compat_xt_standard_target { +struct compat_xt_entry_target t; +compat_uint_t verdict; +}; + +/* see xt_check_entry_offsets */ int xt_compat_check_entry_offsets (const void *base,unsigned int target_offset,unsigned int next_offset)
@@ -556,6 +563,10 @@ int xt_compat_check_entry_offsets(constif (target_offset + t->u.target_size > next_offset)return -EINVAL ; +if (strcmp (t->u.user.name,XT_STANDARD_TARGET ) ==0 && + target_offset +sizeof (struct compat_xt_standard_target ) != next_offset) +return -EINVAL ; +return 0 ; }EXPORT_SYMBOL (xt_compat_check_entry_offsets);
@@ -595,6 +606,10 @@ int xt_check_entry_offsets(const void *bif (target_offset + t->u.target_size > next_offset)return -EINVAL ; +if (strcmp (t->u.user.name,XT_STANDARD_TARGET ) ==0 && + target_offset +sizeof (struct xt_standard_target ) != next_offset) +return -EINVAL ; +return 0 ; }EXPORT_SYMBOL (xt_check_entry_offsets);
Greg Kroah-Hartman
maintainerPATCH 73/75 netfilter: x_tables: check for bogus target offset
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit ce683e5f9d045e5d67d1312a42b359cb2ab2a13c upstream.
We're currently asserting that targetoff + targetsize <= nextoff.
Extend it to also check that targetoff is >= sizeof(xt_entry). Since this is generic code, add an argument pointing to the start of the match/target, we can then derive the base structure size from the delta.
We also need the e->elems pointer in a followup change to validate matches.
--- include/linux/netfilter/x_tables.h | 4 ++-- net/ipv4/netfilter/arp_tables.c | 5 +++-- net/ipv4/netfilter/ip_tables.c | 5 +++-- net/ipv6/netfilter/ip6_tables.c | 5 +++-- net/netfilter/x_tables.c | 17 +++++++++++++++-- 5 files changed, 26 insertions(+), 10 deletions(-)
include/linux/netfilter/x_tables.h +2 -2
@@ -239,7 +239,7 @@ void xt_unregister_match(struct xt_matchint xt_register_matches (struct xt_match *match,unsigned int n);void xt_unregister_matches (struct xt_match *match,unsigned int n); -int xt_check_entry_offsets (const void *base, +int xt_check_entry_offsets (const void *base,const char *elems,unsigned int target_offset,unsigned int next_offset);
@@ -492,7 +492,7 @@ void xt_compat_target_from_user(struct x unsigned int *size);int xt_compat_target_to_user (const struct xt_entry_target *t,void __user **dstptr,unsigned int *size); -int xt_compat_check_entry_offsets (const void *base, +int xt_compat_check_entry_offsets (const void *base,const char *elems,unsigned int target_offset,unsigned int next_offset);
net/ipv4/netfilter/arp_tables.c +3 -2
@@ -592,7 +592,8 @@ static inline int check_entry_size_and_hif (!arp_checkentry (&e->arp))return -EINVAL ; - err =xt_check_entry_offsets (e, e->target_offset, e->next_offset); + err =xt_check_entry_offsets (e, e->elems, e->target_offset, + e->next_offset);if (err)return err;
@@ -1253,7 +1254,7 @@ check_compat_entry_size_and_hooks(structif (!arp_checkentry (&e->arp))return -EINVAL ; - ret =xt_compat_check_entry_offsets (e, e->target_offset, + ret =xt_compat_check_entry_offsets (e, e->elems, e->target_offset, e->next_offset);if (ret)return ret;
net/ipv4/netfilter/ip_tables.c +3 -2
@@ -754,7 +754,8 @@ check_entry_size_and_hooks(struct ipt_enif (!ip_checkentry (&e->ip))return -EINVAL ; - err =xt_check_entry_offsets (e, e->target_offset, e->next_offset); + err =xt_check_entry_offsets (e, e->elems, e->target_offset, + e->next_offset);if (err)return err;
@@ -1512,7 +1513,7 @@ check_compat_entry_size_and_hooks(structif (!ip_checkentry (&e->ip))return -EINVAL ; - ret =xt_compat_check_entry_offsets (e, + ret =xt_compat_check_entry_offsets (e, e->elems, e->target_offset, e->next_offset);if (ret)return ret;
net/ipv6/netfilter/ip6_tables.c +3 -2
@@ -766,7 +766,8 @@ check_entry_size_and_hooks(struct ip6t_eif (!ip6_checkentry (&e->ipv6))return -EINVAL ; - err =xt_check_entry_offsets (e, e->target_offset, e->next_offset); + err =xt_check_entry_offsets (e, e->elems, e->target_offset, + e->next_offset);if (err)return err;
@@ -1524,7 +1525,7 @@ check_compat_entry_size_and_hooks(structif (!ip6_checkentry (&e->ipv6))return -EINVAL ; - ret =xt_compat_check_entry_offsets (e, + ret =xt_compat_check_entry_offsets (e, e->elems, e->target_offset, e->next_offset);if (ret)return ret;
net/netfilter/x_tables.c +15 -2
@@ -545,14 +545,17 @@ struct compat_xt_standard_target {compat_uint_t verdict; }; -/* see xt_check_entry_offsets */ -int xt_compat_check_entry_offsets (const void *base, +int xt_compat_check_entry_offsets (const void *base,const char *elems,unsigned int target_offset,unsigned int next_offset) { +long size_of_base_struct = elems - (const char *)base;const struct compat_xt_entry_target *t;const char *e = base; +if (target_offset < size_of_base_struct) +return -EINVAL ; +if (target_offset +sizeof (*t) > next_offset)return -EINVAL ;
@@ -576,12 +579,16 @@ EXPORT_SYMBOL(xt_compat_check_entry_offs* xt_check_entry_offsets - validate arp/ip/ip6t_entry * * @base: pointer to arp/ip/ip6t_entry +* @elems: pointer to first xt_entry_match, i.e. ip(6)t_entry->elems * @target_offset: the arp/ip/ip6_t->target_offset * @next_offset: the arp/ip/ip6_t->next_offset * * validates that target_offset and next_offset are sane. * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version. * +* This function does not validate the targets or matches themselves, it +* only tests that all the offsets and sizes are correct. +* * The arp/ip/ip6t_entry structure @base must have passed following tests: * - it must point to a valid memory location * - base to base + next_offset must be accessible, i.e. not exceed allocated
@@ -590,12 +597,18 @@ EXPORT_SYMBOL(xt_compat_check_entry_offs* Return: 0 on success, negative errno on failure. */ int xt_check_entry_offsets (const void *base, +const char *elems,unsigned int target_offset,unsigned int next_offset) { +long size_of_base_struct = elems - (const char *)base;const struct xt_entry_target *t;const char *e = base; +/* target start is within the ip/ip6/arpt_entry struct */ +if (target_offset < size_of_base_struct) +return -EINVAL ; +if (target_offset +sizeof (*t) > next_offset)return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 74/75 netfilter: x_tables: validate all offsets and sizes in a rule
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 13631bfc604161a9d69cd68991dff8603edd66f9 upstream.
Validate that all matches (if any) add up to the beginning of the target and that each match covers at least the base structure size.
The compat path should be able to safely re-use the function as the structures only differ in alignment; added a BUILD_BUG_ON just in case we have an arch that adds padding as well.
--- net/netfilter/x_tables.c | 81 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 5 deletions(-)
net/netfilter/x_tables.c +76 -5
@@ -415,6 +415,47 @@ int xt_check_match(struct xt_mtchk_param }EXPORT_SYMBOL_GPL (xt_check_match); +/** xt_check_entry_match - check that matches end before start of target +* +* @match: beginning of xt_entry_match +* @target: beginning of this rules target (alleged end of matches) +* @alignment: alignment requirement of match structures +* +* Validates that all matches add up to the beginning of the target, +* and that each match covers at least the base structure size. +* +* Return: 0 on success, negative errno on failure. +*/ +static int xt_check_entry_match (const char *match,const char *target, +const size_t alignment) +{ +const struct xt_entry_match *pos; +int length = target - match; + +if (length ==0 )/* no matches */ +return 0 ; + + pos = (struct xt_entry_match *)match; +do { +if ((unsigned long )pos % alignment) +return -EINVAL ; + +if (length < (int )sizeof (struct xt_entry_match )) +return -EINVAL ; + +if (pos->u.match_size <sizeof (struct xt_entry_match )) +return -EINVAL ; + +if (pos->u.match_size > length) +return -EINVAL ; + + length -= pos->u.match_size; + pos = ((void *)((char *)(pos) + (pos)->u.match_size)); + }while (length >0 ); + +return 0 ; +} +#ifdef CONFIG_COMPAT int xt_compat_add_offset (u_int8_t af,unsigned int offset,int delta) {
@@ -570,7 +611,14 @@ int xt_compat_check_entry_offsets(const target_offset + sizeof(struct compat_xt_standard_target) != next_offset) return -EINVAL; - return 0; +/* compat_xt_entry match has less strict aligment requirements, +* otherwise they are identical. In case of padding differences +* we need to add compat version of xt_check_entry_match. +*/ +BUILD_BUG_ON (sizeof (struct compat_xt_entry_match ) !=sizeof (struct xt_entry_match )); + +return xt_check_entry_match (elems, base + target_offset, + __alignof__(struct compat_xt_entry_match)); }EXPORT_SYMBOL (xt_compat_check_entry_offsets);#endif /* CONFIG_COMPAT */
@@ -583,17 +631,39 @@ EXPORT_SYMBOL(xt_compat_check_entry_offs* @target_offset: the arp/ip/ip6_t->target_offset * @next_offset: the arp/ip/ip6_t->next_offset * -* validates that target_offset and next_offset are sane. -* Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version. +* validates that target_offset and next_offset are sane and that all +* match sizes (if any) align with the target offset. * * This function does not validate the targets or matches themselves, it -* only tests that all the offsets and sizes are correct. +* only tests that all the offsets and sizes are correct, that all +* match structures are aligned, and that the last structure ends where +* the target structure begins. +* +* Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version. * * The arp/ip/ip6t_entry structure @base must have passed following tests: * - it must point to a valid memory location * - base to base + next_offset must be accessible, i.e. not exceed allocated * length. * +* A well-formed entry looks like this: +* +* ip(6)t_entry match [mtdata] match [mtdata] target [tgdata] ip(6)t_entry +* e->elems[]-----' | | +* matchsize | | +* matchsize | | +* | | +* target_offset---------------------------------' | +* next_offset---------------------------------------------------' +* +* elems[]: flexible array member at end of ip(6)/arpt_entry struct. +* This is where matches (if any) and the target reside. +* target_offset: beginning of target. +* next_offset: start of the next rule; also: size of this rule. +* Since targets have a minimum size, target_offset + minlen <= next_offset. +* +* Every match stores its size, sum of sizes must not exceed target_offset. +* * Return: 0 on success, negative errno on failure. */ int xt_check_entry_offsets(const void *base,
@@ -623,7 +693,8 @@ int xt_check_entry_offsets(const void *b target_offset + sizeof(struct xt_standard_target) != next_offset) return -EINVAL; -return 0 ; +return xt_check_entry_match (elems, base + target_offset, + __alignof__(struct xt_entry_match )); }EXPORT_SYMBOL (xt_check_entry_offsets);
Greg Kroah-Hartman
maintainerPATCH 75/75 netfilter: x_tables: dont reject valid target size on some architectures
In reply to Greg Kroah-Hartman4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 7b7eba0f3515fca3296b8881d583f7c1042f5226 upstream.
Quoting John Stultz:
In updating a 32bit arm device from 4.6 to Linus' current HEAD, I noticed I was having some trouble with networking, and realized that /proc/net/ip_tables_names was suddenly empty.
Digging through the registration process, it seems we're catching on the:
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
target_offset + sizeof(struct xt_standard_target) != next_offset)
return -EINVAL; Where next_offset seems to be 4 bytes larger then the offset + standard_target struct size.
next_offset needs to be aligned via XT_ALIGN (so we can access all members of ip(6)t_entry struct).
This problem didn't show up on i686 as it only needs 4-byte alignment for u64, but iptables userspace on other 32bit arches does insert extra padding.
--- net/netfilter/x_tables.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/netfilter/x_tables.c +2 -2
@@ -608,7 +608,7 @@ int xt_compat_check_entry_offsets(constreturn -EINVAL ;if (strcmp (t->u.user.name,XT_STANDARD_TARGET ) ==0 && - target_offset +sizeof (struct compat_xt_standard_target ) != next_offset) +COMPAT_XT_ALIGN (target_offset +sizeof (struct compat_xt_standard_target )) != next_offset)return -EINVAL ;/* compat_xt_entry match has less strict aligment requirements,
@@ -690,7 +690,7 @@ int xt_check_entry_offsets(const void *breturn -EINVAL ;if (strcmp (t->u.user.name,XT_STANDARD_TARGET ) ==0 && - target_offset +sizeof (struct xt_standard_target ) != next_offset) +XT_ALIGN (target_offset +sizeof (struct xt_standard_target )) != next_offset)return -EINVAL ; return xt_check_entry_match(elems, base + target_offset,
Greg Kroah-Hartman
maintainerRe: [PATCH 4.4 00/75] 4.4.14-stable review -rc2
In reply to Greg Kroah-Hartman-rc2!
This is the start of the stable review cycle for the 4.4.14 release. There are 81 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat Jun 25 04:51:37 UTC 2016. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.14-rc2.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.4.14-rc2
Florian Westphal <[email protected]>
netfilter: x_tables: introduce and use xt_copy_counters_from_user
Florian Westphal <[email protected]>
netfilter: x_tables: do compat validation via translate_table
Florian Westphal <[email protected]>
netfilter: x_tables: xt_compat_match_from_user doesn't need a retval
Florian Westphal <[email protected]>
netfilter: ip6_tables: simplify translate_compat_table args
Florian Westphal <[email protected]>
netfilter: ip_tables: simplify translate_compat_table args
Florian Westphal <[email protected]>
netfilter: arp_tables: simplify translate_compat_table args
Florian Westphal <[email protected]>
netfilter: x_tables: don't reject valid target size on some architectures
Florian Westphal <[email protected]>
netfilter: x_tables: validate all offsets and sizes in a rule
Florian Westphal <[email protected]>
netfilter: x_tables: check for bogus target offset
Florian Westphal <[email protected]>
netfilter: x_tables: check standard target size too
Florian Westphal <[email protected]>
netfilter: x_tables: add compat version of xt_check_entry_offsets
Florian Westphal <[email protected]>
netfilter: x_tables: assert minimum target size
Florian Westphal <[email protected]>
netfilter: x_tables: kill check_entry helper
Florian Westphal <[email protected]>
netfilter: x_tables: add and use xt_check_entry_offsets
Florian Westphal <[email protected]>
netfilter: x_tables: validate targets of jumps
Florian Westphal <[email protected]>
netfilter: x_tables: don't move to non-existent next rule
Maarten Lankhorst <[email protected]>
drm/core: Do not preserve framebuffer on rmfb, v4.
Tadeusz Struk <[email protected]>
crypto: qat - fix adf_ctl_drv.c:undefined reference to adf_init_pf_wq
Florian Westphal <[email protected]>
netfilter: x_tables: fix unconditional helper
Florian Westphal <[email protected]>
netfilter: x_tables: make sure e->next_offset covers remaining blob size
Florian Westphal <[email protected]>
netfilter: x_tables: validate e->target_offset early
Ralf Baechle <[email protected]>
MIPS: Fix 64k page support for 32 bit kernels.
David S. Miller <[email protected]>
sparc64: Fix return from trap window fill crashes.
David S. Miller <[email protected]>
sparc: Harden signal return frame checks.
David S. Miller <[email protected]>
sparc64: Take ctx_alloc_lock properly in hugetlb_setup().
Nitin Gupta <[email protected]>
sparc64: Reduce TLB flushes during hugepte changes
Babu Moger <[email protected]>
sparc/PCI: Fix for panic while enabling SR-IOV
David S. Miller <[email protected]>
sparc64: Fix sparc64_set_context stack handling.
Nitin Gupta <[email protected]>
sparc64: Fix numa node distance initialization
David S. Miller <[email protected]>
sparc64: Fix bootup regressions on some Kconfig combinations.
Mike Frysinger <[email protected]>
sparc: Fix system call tracing register handling.
Al Viro <[email protected]>
fix d_walk()/non-delayed __d_free() race
Jann Horn <[email protected]>
sched: panic on corrupted stack end
Jann Horn <[email protected]>
proc: prevent stacking filesystems on top
Andy Lutomirski <[email protected]>
x86/entry/traps: Don't force in_interrupt() to return true in IST handlers
Prasun Maiti <[email protected]>
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel
Jann Horn <[email protected]>
ecryptfs: forbid opening files without mmap handler
Tejun Heo <[email protected]>
memcg: add RCU locking around css_for_each_descendant_pre() in memcg_offline_kmem()
Helge Deller <[email protected]>
parisc: Fix pagefault crash in unaligned __get_user() call
hongkun.cao <[email protected]>
pinctrl: mediatek: fix dual-edge code defect
Thomas Huth <[email protected]>
powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support call
Thomas Huth <[email protected]>
powerpc: Use privileged SPR number for MMCR2
Thomas Huth <[email protected]>
powerpc: Fix definition of SIAR and SDAR registers
Russell Currey <[email protected]>
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge
Will Deacon <[email protected]>
arm64: mm: always take dirty state from new pte in ptep_set_access_flags
Catalin Marinas <[email protected]>
arm64: Provide "model name" in /proc/cpuinfo for PER_LINUX32 tasks
Tom Lendacky <[email protected]>
crypto: ccp - Fix AES XTS error for request sizes above 4096
Arnd Bergmann <[email protected]>
crypto: public_key: select CRYPTO_AKCIPHER
Marc Zyngier <[email protected]>
irqchip/gic-v3: Fix ICC_SGI1R_EL1.INTID decoding mask
Michael Holzheu <[email protected]>
s390/bpf: reduce maximum program size to 64 KB
Michael Holzheu <[email protected]>
s390/bpf: fix recache skb->data/hlen for skb_vlan_push/pop
Ben Dooks <[email protected]>
gpio: bcm-kona: fix bcm_kona_gpio_reset() warnings
Russell King <[email protected]>
ARM: fix PTRACE_SETVFPREGS on SMP systems
Torsten Hilbrich <[email protected]>
ALSA: hda/realtek: Add T560 docking unit fixup
Kailang Yang <[email protected]>
ALSA: hda/realtek - Add support for new codecs ALC700/ALC701/ALC703
Kailang Yang <[email protected]>
ALSA: hda/realtek - ALC256 speaker noise issue
AceLan Kao <[email protected]>
ALSA: hda - Fix headset mic detection problem for Dell machine
Vinod Koul <[email protected]>
ALSA: hda - Add PCI ID for Kabylake
Paolo Bonzini <[email protected]>
KVM: irqfd: fix NULL pointer dereference in kvm_irq_map_gsi
Paolo Bonzini <[email protected]>
KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS
David Wragg <[email protected]>
vxlan, gre, geneve: Set a large MTU on ovs-created tunnel devices
David Wragg <[email protected]>
geneve: Relax MTU constraints
David Wragg <[email protected]>
vxlan: Relax MTU constraints
Jakub Sitnicki <[email protected]>
ipv6: Skip XFRM lookup if dst_entry in socket cache is valid
Guillaume Nault <[email protected]>
l2tp: fix configuration passed to setup_udp_tunnel_sock()
Toshiaki Makita <[email protected]>
bridge: Don't insert unnecessary local fdb entry on changing mac address
Yuchung Cheng <[email protected]>
tcp: record TLP and ER timer stats in v6 stats
Chen Haiquan <[email protected]>
vxlan: Accept user specified MTU value when create new vxlan link
Ivan Vecera <[email protected]>
team: don't call netdev_change_features under team->lock
Edward Cree <[email protected]>
sfc: on MC reset, clear PIO buffer linkage in TXQs
Daniel Borkmann <[email protected]>
bpf, inode: disallow userns mounts
Nicolas Dichtel <[email protected]>
uapi glibc compat: fix compilation when !__USE_MISC in glibc
Hannes Frederic Sowa <[email protected]>
udp: prevent skbs lingering in tunnel socket queues
Eric W. Biederman <[email protected]>
bpf: Use mount_nodev not mount_ns to mount the bpf filesystem
Jason Wang <[email protected]>
tuntap: correctly wake up process during uninit
Jiri Pirko <[email protected]>
switchdev: pass pointer to fib_info instead of copy
Richard Alpe <[email protected]>
tipc: fix nametable publication field in nl compat
Herbert Xu <[email protected]>
netlink: Fix dump skb leak/double free
Richard Alpe <[email protected]>
tipc: check nl sock before parsing nested attributes
Ewan D. Milne <[email protected]>
scsi: Add QEMU CD-ROM to VPD Inquiry Blacklist
James Bottomley <[email protected]>
scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands
-------------
Diffstat:
Makefile | 4 +- arch/arm/kernel/ptrace.c | 2 +- arch/arm64/include/asm/elf.h | 4 +- arch/arm64/kernel/cpuinfo.c | 8 +- arch/arm64/mm/fault.c | 2 +- arch/mips/include/asm/processor.h | 2 +- arch/parisc/kernel/unaligned.c | 10 +- arch/powerpc/include/asm/reg.h | 6 +- arch/powerpc/kernel/prom_init.c | 1 + arch/powerpc/platforms/pseries/eeh_pseries.c | 51 ++-- arch/s390/net/bpf_jit.h | 4 +- arch/s390/net/bpf_jit_comp.c | 4 +- arch/sparc/include/asm/head_64.h | 4 + arch/sparc/include/asm/pgtable_64.h | 43 ++- arch/sparc/include/asm/tlbflush_64.h | 3 +- arch/sparc/include/asm/ttable.h | 8 +- arch/sparc/kernel/Makefile | 1 + arch/sparc/kernel/cherrs.S | 14 +- arch/sparc/kernel/entry.S | 17 ++ arch/sparc/kernel/fpu_traps.S | 11 +- arch/sparc/kernel/head_64.S | 24 +- arch/sparc/kernel/misctrap.S | 12 +- arch/sparc/kernel/pci.c | 17 ++ arch/sparc/kernel/rtrap_64.S | 57 +--- arch/sparc/kernel/signal32.c | 46 ++-- arch/sparc/kernel/signal_32.c | 41 +-- arch/sparc/kernel/signal_64.c | 33 ++- arch/sparc/kernel/sigutil_32.c | 9 +- arch/sparc/kernel/sigutil_64.c | 10 +- arch/sparc/kernel/spiterrs.S | 18 +- arch/sparc/kernel/syscalls.S | 36 +++ arch/sparc/kernel/urtt_fill.S | 98 +++++++ arch/sparc/kernel/utrap.S | 3 +- arch/sparc/kernel/vmlinux.lds.S | 4 + arch/sparc/kernel/winfixup.S | 3 +- arch/sparc/mm/hugetlbpage.c | 33 ++- arch/sparc/mm/init_64.c | 37 ++- arch/sparc/mm/tlb.c | 25 +- arch/sparc/mm/tsb.c | 32 +-- arch/x86/kernel/traps.c | 20 +- arch/x86/kvm/x86.c | 5 + crypto/asymmetric_keys/Kconfig | 1 + drivers/crypto/ccp/ccp-crypto-aes-xts.c | 17 +- drivers/crypto/qat/qat_common/adf_common_drv.h | 13 +- drivers/gpio/gpio-bcm-kona.c | 4 +- drivers/gpu/drm/drm_crtc.c | 60 ++++- drivers/net/ethernet/rocker/rocker.c | 4 +- drivers/net/ethernet/sfc/ef10.c | 16 ++ drivers/net/geneve.c | 41 ++- drivers/net/team/team.c | 9 +- drivers/net/tun.c | 6 +- drivers/net/vxlan.c | 60 +++-- drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 5 +- drivers/scsi/scsi_devinfo.c | 1 + drivers/scsi/scsi_lib.c | 7 +- fs/dcache.c | 4 +- fs/ecryptfs/kthread.c | 13 +- fs/proc/root.c | 7 + include/linux/irqchip/arm-gic-v3.h | 2 +- include/linux/netfilter/x_tables.h | 12 +- include/net/ip_tunnels.h | 1 + include/net/switchdev.h | 2 +- include/uapi/linux/libc-compat.h | 2 +- kernel/bpf/inode.c | 3 +- kernel/sched/core.c | 3 +- mm/memcontrol.c | 3 + net/bridge/br_fdb.c | 2 + net/ipv4/ip_gre.c | 8 + net/ipv4/ip_tunnel.c | 20 +- net/ipv4/netfilter/arp_tables.c | 326 ++++++++-------------- net/ipv4/netfilter/ip_tables.c | 356 ++++++++----------------- net/ipv4/udp.c | 2 +- net/ipv6/ip6_output.c | 11 +- net/ipv6/netfilter/ip6_tables.c | 349 +++++++----------------- net/ipv6/tcp_ipv6.c | 4 +- net/ipv6/udp.c | 2 +- net/l2tp/l2tp_core.c | 2 +- net/netfilter/x_tables.c | 245 ++++++++++++++++- net/netlink/af_netlink.c | 7 +- net/openvswitch/vport-vxlan.c | 2 + net/switchdev/switchdev.c | 6 +- net/tipc/netlink_compat.c | 2 +- net/tipc/socket.c | 3 + net/wireless/wext-core.c | 25 +- sound/pci/hda/hda_intel.c | 11 +- sound/pci/hda/patch_realtek.c | 73 ++++- virt/kvm/irqchip.c | 2 +- 87 files changed, 1435 insertions(+), 1081 deletions(-)
Re: [PATCH 4.4 00/75] 4.4.14-stable review -rc2
[trimmed cc]
Hi Greg,
Quoted 5 lines · Greg Kroah-Hartman
-rc2!
This is the start of the stable review cycle for the 4.4.14 release. There are 81 patches in this series, all will be posted as a response to this one.
Here's an example of why we'd like the patch count (or better, the "git describe" value) in the header. Notice that the patch count in the subject is different than the patch count in the body.
Kevin
Greg Kroah-Hartman
maintainerRe: [PATCH 4.4 00/75] 4.4.14-stable review -rc2
Quoted 8 lines · Kevin Hilman
[trimmed cc]
Hi Greg,
Quoted 2 lines · Greg Kroah-Hartman
-rc2!
Quoted 7 lines
Quoted 3 lines
This is the start of the stable review cycle for the 4.4.14 release. There are 81 patches in this series, all will be posted as a response to this one.
Here's an example of why we'd like the patch count (or better, the "git describe" value) in the header. Notice that the patch count in the subject is different than the patch count in the body.
Yeah, but this was a really "odd" -rc series, with tons of problems, it's normally not this hard :)
I'll work on this, thanks.
greg k-h
Re: [PATCH 4.4 00/75] 4.4.14-stable review -rc2
In reply to Greg Kroah-HartmanQuoted 10 lines · Greg Kroah-Hartman
-rc2!
This is the start of the stable review cycle for the 4.4.14 release. There are 81 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat Jun 25 04:51:37 UTC 2016. Anything received after that time might be too late.
Build results:
total: 148 pass: 148 fail: 0 Qemu test results: total: 101 pass: 101 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
Re: [PATCH 4.4 00/75] 4.4.14-stable review -rc2
In reply to Greg Kroah-HartmanQuoted 7 lines · Greg Kroah-Hartman
-rc2!
This is the start of the stable review cycle for the 4.4.14 release. There are 81 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 9 lines
Responses should be made by Sat Jun 25 04:51:37 UTC 2016. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.14-rc2.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.4.y
and the diffstat can be found below.
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah