4.6.7-stable review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 4.6.7-stable review
*********************************************************************
NOTE
This is the LAST 4.6.y kernel that will be released. After this release, it is end-of-life. You should be moving on to 4.7.y at this point in time. You have been warned.
*********************************************************************
This is the start of the stable review cycle for the 4.6.7 release. There are 56 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 Tue Aug 16 20:24:52 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.6.7-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.6.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.6.7-rc1
Vegard Nossum <[email protected]>
ext4: fix reference counting bug on block allocation error
Vegard Nossum <[email protected]>
ext4: short-cut orphan cleanup on error
Theodore Ts'o <[email protected]>
ext4: validate s_reserved_gdt_blocks on mount
Vegard Nossum <[email protected]>
ext4: don't call ext4_should_journal_data() on the journal inode
Jan Kara <[email protected]>
ext4: fix deadlock during page writeback
Vegard Nossum <[email protected]>
ext4: check for extents that wrap around
Thomas Petazzoni <[email protected]>
serial: mvebu-uart: free the IRQ in ->shutdown()
Herbert Xu <[email protected]>
crypto: scatterwalk - Fix test in scatterwalk_done
Herbert Xu <[email protected]>
crypto: gcm - Filter out async ghash if necessary
Andreas Herrmann <[email protected]>
Revert "cpufreq: pcc-cpufreq: update default value of cpuinfo_transition_latency"
Wei Fang <[email protected]>
fs/dcache.c: avoid soft-lockup in dput()
Michal Hocko <[email protected]>
Revert "mm, mempool: only set __GFP_NOMEMALLOC if there are free elements"
Wei Fang <[email protected]>
fuse: fix wrong assignment of ->flags in fuse_send_init()
Maxim Patlasov <[email protected]>
fuse: fuse_flush must check mapping->flags for errors
Alexey Kuznetsov <[email protected]>
fuse: fsync() did not return IO errors
Josh Poimboeuf <[email protected]>
x86/power/64: Fix hibernation return address corruption
Borislav Petkov <[email protected]>
x86/microcode: Fix suspend to RAM with builtin microcode
Vladimir Davydov <[email protected]>
radix-tree: account nodes to memcg only if explicitly requested
Fabian Frederick <[email protected]>
sysv, ipc: fix security-layer leaking
Vegard Nossum <[email protected]>
block: fix use-after-free in seq file
David Howells <[email protected]>
x86/syscalls/64: Add compat_sys_keyctl for 32-bit userspace
Vladimir Davydov <[email protected]>
mm: memcontrol: fix memcg id ref counter on swap charge move
Vladimir Davydov <[email protected]>
mm: memcontrol: fix swap counter leak on swapout from offline cgroup
Naveen N. Rao <[email protected]>
powerpc/bpf/jit: Disable classic BPF JIT on ppc64le
Gavin Shan <[email protected]>
powerpc/eeh: Fix invalid cached PE primary bus
Alden Tondettar <[email protected]>
udf: Prevent stack overflow on corrupted filesystem mount
Toshi Kani <[email protected]>
x86/mm/pat: Fix BUG_ON() in mmap_mem() on QEMU/i386
Toshi Kani <[email protected]>
x86/pat: Document the PAT initialization sequence
Toshi Kani <[email protected]>
x86/xen, pat: Remove PAT table init code from Xen
Toshi Kani <[email protected]>
x86/mtrr: Fix PAT init handling when MTRR is disabled
Toshi Kani <[email protected]>
x86/mtrr: Fix Xorg crashes in Qemu sessions
Toshi Kani <[email protected]>
x86/mm/pat: Replace cpu_has_pat with boot_cpu_has()
Toshi Kani <[email protected]>
x86/mm/pat: Add pat_disable() interface
Toshi Kani <[email protected]>
x86/mm/pat: Add support of non-default PAT MSR setting
Theodore Ts'o <[email protected]>
random: strengthen input validation for RNDADDTOENTCNT
Axel Lin <[email protected]>
regulator: qcom_smd: Remove list_voltage callback for rpm_smps_ldo_ops_fixed
John Johansen <[email protected]>
apparmor: fix ref count leak when profile sha1 hash is read
Mike Marciniszyn <[email protected]>
IB/hfi1: Fix deadlock with txreq allocation slow path
Mike Marciniszyn <[email protected]>
IB/hfi1: Correct issues with sc5 computation
David Howells <[email protected]>
KEYS: 64-bit MIPS needs to use compat_sys_keyctl for 32-bit userspace
Dave Weinstein <[email protected]>
arm: oabi compat: add missing access checks
Mika Westerberg <[email protected]>
i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
Soheil Hassas Yeganeh <[email protected]>
tcp: consider recv buf for the initial window scale
Beniamino Galvani <[email protected]>
macsec: ensure rx_sa is set when validation is disabled
Manish Chopra <[email protected]>
qed: Fix setting/clearing bit in completion bitmap
Vegard Nossum <[email protected]>
net/irda: fix NULL pointer dereference on memory allocation failure
Mike Manning <[email protected]>
net: ipv6: Always leave anycast and multicast groups on link down
Ido Schimmel <[email protected]>
bridge: Fix incorrect re-injection of LLDP packets
Paolo Abeni <[email protected]>
vlan: use a valid default mtu value for vlan over macsec
Florian Fainelli <[email protected]>
net: bgmac: Fix infinite loop in bgmac_dma_tx_add()
Beniamino Galvani <[email protected]>
bonding: set carrier off for devices created through netlink
Jason Baron <[email protected]>
tcp: enable per-socket rate limiting of all 'challenge acks'
Eric Dumazet <[email protected]>
tcp: make challenge acks less predictable
WANG Cong <[email protected]>
ppp: defer netns reference release for ppp channel
Dan Williams <[email protected]>
libnvdimm, pfn, dax: fix initialization vs autodetect for mode + alignment
Dan Williams <[email protected]>
libnvdimm, dax: record the specified alignment of a dax-device instance
-------------
Diffstat:
Documentation/cpu-freq/pcc-cpufreq.txt | 4 +- Documentation/x86/pat.txt | 32 +++++++++ Makefile | 4 +- arch/arm/kernel/sys_oabi-compat.c | 8 ++- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- arch/powerpc/Kconfig | 2 +- arch/powerpc/kernel/eeh_driver.c | 7 +- arch/x86/entry/syscalls/syscall_32.tbl | 2 +- arch/x86/include/asm/microcode.h | 2 - arch/x86/include/asm/mtrr.h | 6 +- arch/x86/include/asm/pat.h | 2 +- arch/x86/kernel/cpu/microcode/core.c | 3 +- arch/x86/kernel/cpu/mtrr/generic.c | 24 ++++--- arch/x86/kernel/cpu/mtrr/main.c | 13 +++- arch/x86/kernel/cpu/mtrr/mtrr.h | 1 + arch/x86/mm/init.c | 7 -- arch/x86/mm/pat.c | 109 ++++++++++++++++++------------ arch/x86/power/hibernate_asm_64.S | 4 +- arch/x86/xen/enlighten.c | 9 --- block/genhd.c | 1 + crypto/gcm.c | 4 +- crypto/scatterwalk.c | 3 +- drivers/char/random.c | 13 ++-- drivers/cpufreq/pcc-cpufreq.c | 2 - drivers/i2c/busses/i2c-i801.c | 103 +++++++++++++++++++++++++--- drivers/net/bonding/bond_netlink.c | 6 +- drivers/net/ethernet/broadcom/bgmac.c | 2 +- drivers/net/ethernet/qlogic/qed/qed_spq.c | 7 +- drivers/net/macsec.c | 3 +- drivers/net/ppp/ppp_generic.c | 5 +- drivers/nvdimm/pfn.h | 4 +- drivers/nvdimm/pfn_devs.c | 53 ++++++++++++--- drivers/nvdimm/pmem.c | 4 +- drivers/regulator/qcom_smd-regulator.c | 1 - drivers/staging/rdma/hfi1/ud.c | 23 +------ drivers/staging/rdma/hfi1/verbs_txreq.c | 4 +- drivers/staging/rdma/hfi1/verbs_txreq.h | 1 + drivers/tty/serial/mvebu-uart.c | 2 + fs/dcache.c | 7 +- fs/ext4/balloc.c | 3 + fs/ext4/extents.c | 8 ++- fs/ext4/inode.c | 35 ++++++++-- fs/ext4/mballoc.c | 17 +---- fs/ext4/super.c | 17 +++++ fs/fuse/file.c | 24 +++++++ fs/fuse/inode.c | 2 +- fs/inode.c | 2 +- fs/udf/super.c | 67 +++++++++++------- include/linux/netdevice.h | 7 ++ ipc/msg.c | 2 +- ipc/sem.c | 12 ++-- lib/radix-tree.c | 14 ++-- mm/memcontrol.c | 68 +++++++++++++++---- mm/mempool.c | 18 +---- net/8021q/vlan_dev.c | 10 +-- net/8021q/vlan_netlink.c | 7 +- net/bridge/br_input.c | 18 +++++ net/ipv4/tcp_input.c | 54 +++++++++------ net/ipv4/tcp_output.c | 3 +- net/ipv6/addrconf.c | 4 ++ net/irda/af_irda.c | 7 +- security/apparmor/apparmorfs.c | 1 + 63 files changed, 619 insertions(+), 272 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/56 libnvdimm, dax: record the specified alignment of a dax-device instance
4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit 45a0dac0451136fa7ae34a6fea53ef6a136287ce upstream.
We want to use the alignment as the allocation and mapping unit. Previously this information was only useful for establishing the data offset, but now it is important to remember the granularity for the later use.
--- drivers/nvdimm/pfn.h | 4 +++- drivers/nvdimm/pfn_devs.c | 5 ++++- drivers/nvdimm/pmem.c | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-)
drivers/nvdimm/pfn.h +3 -1
@@ -33,7 +33,9 @@ struct nd_pfn_sb {/* minor-version-1 additions for section alignment */ __le32 start_pad;__le32 end_trunc; -u8 padding[4004 ]; +/* minor-version-2 record the base alignment of the mapping */ +__le32 align; +u8 padding[4000 ];__le64 checksum; };
drivers/nvdimm/pfn_devs.c +4 -1
@@ -360,6 +360,9 @@ int nd_pfn_validate(struct nd_pfn *nd_pf pfn_sb->end_trunc =0 ; } +if (__le16_to_cpu (pfn_sb->version_minor) <2 ) + pfn_sb->align =0 ; +switch (le32_to_cpu (pfn_sb->mode)) {case PFN_MODE_RAM :case PFN_MODE_PMEM :
@@ -399,7 +402,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfreturn -EBUSY ; } - nd_pfn->align =1UL <<ilog2 (offset); + nd_pfn->align =le32_to_cpu (pfn_sb->align);if (!is_power_of_2 (offset) || offset <PAGE_SIZE ) {dev_err (&nd_pfn->dev,"bad offset: %#llx dax disabled\n" , offset);
drivers/nvdimm/pmem.c +2 -1
@@ -426,9 +426,10 @@ static int nd_pfn_init(struct nd_pfn *ndmemcpy (pfn_sb->uuid, nd_pfn->uuid,16 );memcpy (pfn_sb->parent_uuid,nd_dev_to_uuid (&ndns->dev),16 ); pfn_sb->version_major =cpu_to_le16 (1 ); - pfn_sb->version_minor =cpu_to_le16 (1 ); + pfn_sb->version_minor =cpu_to_le16 (2 ); pfn_sb->start_pad =cpu_to_le32 (start_pad); pfn_sb->end_trunc =cpu_to_le32 (end_trunc); + pfn_sb->align =cpu_to_le32 (nd_pfn->align); checksum =nd_sb_checksum ((struct nd_gen_sb *) pfn_sb); pfn_sb->checksum =cpu_to_le64 (checksum);
Greg Kroah-Hartman
maintainerPATCH 2/56 libnvdimm, pfn, dax: fix initialization vs autodetect for mode + alignment
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit 1ee6667cd8d183b2fed12f97285f184431d2caf9 upstream.
The updated ndctl unit tests discovered that if a pfn configuration with a 4K alignment is read from the namespace, that alignment will be ignored in favor of the default 2M alignment. The result is that the configuration will fail initialization with a message like:
dax6.1: bad offset: 0x22000 dax disabled align: 0x200000
Fix this by allowing the alignment read from the info block to override the default which is 2M not 0 in the autodetect path. This also fixes a similar problem with the mode and alignment settings silently being overwritten by the kernel when userspace has changed it. We now will either overwrite the info block if userspace changes the uuid or fail and warn if a live setting disagrees with the info block.
--- drivers/nvdimm/pfn_devs.c | 50 +++++++++++++++++++++++++++++++++++++--------- drivers/nvdimm/pmem.c | 1 2 files changed, 41 insertions(+), 10 deletions(-)
drivers/nvdimm/pfn_devs.c +41 -9
@@ -329,6 +329,8 @@ struct device *nd_pfn_create(struct nd_rint nd_pfn_validate (struct nd_pfn *nd_pfn) {u64 checksum, offset; +unsigned long align; +enum nd_pfn_mode mode;struct nd_namespace_io *nsio;struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;struct nd_namespace_common *ndns = nd_pfn->ndns;
@@ -371,20 +373,50 @@ int nd_pfn_validate(struct nd_pfn *nd_pfreturn -ENXIO ; } + align =le32_to_cpu (pfn_sb->align); + offset =le64_to_cpu (pfn_sb->dataoff); +if (align ==0 ) + align =1UL <<ilog2 (offset); + mode =le32_to_cpu (pfn_sb->mode); +if (!nd_pfn->uuid) { -/* from probe we allocate */ +/* +* When probing a namepace via nd_pfn_probe() the uuid +* is NULL (see: nd_pfn_devinit()) we init settings from +* pfn_sb +*/ nd_pfn->uuid =kmemdup (pfn_sb->uuid,16 ,GFP_KERNEL );if (!nd_pfn->uuid)return -ENOMEM ; + nd_pfn->align = align; + nd_pfn->mode = mode; }else { -/* from init we validate */ +/* +* When probing a pfn / dax instance we validate the +* live settings against the pfn_sb +*/ if (memcmp (nd_pfn->uuid, pfn_sb->uuid,16 ) !=0 )return -ENODEV ; + +/* +* If the uuid validates, but other settings mismatch +* return EINVAL because userspace has managed to change +* the configuration without specifying new +* identification. +*/ +if (nd_pfn->align != align || nd_pfn->mode != mode) { +dev_err (&nd_pfn->dev, +"init failed, settings mismatch\n" ); +dev_dbg (&nd_pfn->dev,"align: %lx:%lx mode: %d:%d\n" , + nd_pfn->align, align, nd_pfn->mode, + mode); +return -EINVAL ; + } } -if (nd_pfn->align >nvdimm_namespace_capacity (ndns)) { +if (align >nvdimm_namespace_capacity (ndns)) {dev_err (&nd_pfn->dev,"alignment: %lx exceeds capacity %llx\n" , - nd_pfn->align,nvdimm_namespace_capacity (ndns)); + align,nvdimm_namespace_capacity (ndns));return -EINVAL ; }
@@ -394,7 +426,6 @@ int nd_pfn_validate(struct nd_pfn *nd_pf* namespace has changed since the pfn superblock was * established. */ - offset =le64_to_cpu (pfn_sb->dataoff); nsio =to_nd_namespace_io (&ndns->dev);if (offset >=resource_size (&nsio->res)) { dev_err(&nd_pfn->dev, "pfn array size exceeds capacity of %s\n",
@@ -402,10 +433,11 @@ int nd_pfn_validate(struct nd_pfn *nd_pfreturn -EBUSY ; } - nd_pfn->align =le32_to_cpu (pfn_sb->align); -if (!is_power_of_2 (offset) || offset <PAGE_SIZE ) { -dev_err (&nd_pfn->dev,"bad offset: %#llx dax disabled\n" , - offset); +if ((align && !IS_ALIGNED (offset, align)) + || !IS_ALIGNED (offset,PAGE_SIZE )) { +dev_err (&nd_pfn->dev, +"bad offset: %#llx dax disabled align: %#lx\n" , + offset, align);return -ENXIO ; }
drivers/nvdimm/pmem.c +0 -1
@@ -502,7 +502,6 @@ static int __nvdimm_namespace_attach_pfn pmem =dev_get_drvdata (dev); pmem->data_offset =le64_to_cpu (pfn_sb->dataoff); pmem->pfn_pad = start_pad + end_trunc; - nd_pfn->mode =le32_to_cpu (nd_pfn->pfn_sb->mode);if (nd_pfn->mode ==PFN_MODE_RAM ) {if (pmem->data_offset <SZ_8K )return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 3/56 ppp: defer netns reference release for ppp channel
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: WANG Cong <[email protected]>
[ Upstream commit 205e1e255c479f3fd77446415706463b282f94e4 ]
Matt reported that we have a NULL pointer dereference in ppp_pernet() from ppp_connect_channel(), i.e. pch->chan_net is NULL.
This is due to that a parallel ppp_unregister_channel() could happen while we are in ppp_connect_channel(), during which pch->chan_net set to NULL. Since we need a reference to net per channel, it makes sense to sync the refcnt with the life time of the channel, therefore we should release this reference when we destroy it.
--- drivers/net/ppp/ppp_generic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ppp/ppp_generic.c +3 -2
@@ -2404,8 +2404,6 @@ ppp_unregister_channel(struct ppp_channespin_lock_bh (&pn->all_channels_lock);list_del (&pch->list);spin_unlock_bh (&pn->all_channels_lock); -put_net (pch->chan_net); - pch->chan_net =NULL ; pch->file.dead =1 ;wake_up_interruptible (&pch->file.rwait);
@@ -2999,6 +2997,9 @@ ppp_disconnect_channel(struct channel *p*/ static void ppp_destroy_channel (struct channel *pch) { +put_net (pch->chan_net); + pch->chan_net =NULL ; +atomic_dec (&channel_count);if (!pch->file.dead) {
Greg Kroah-Hartman
maintainerPATCH 4/56 tcp: make challenge acks less predictable
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 75ff39ccc1bd5d3c455b6822ab09e533c551f758 ]
Yue Cao claims that current host rate limiting of challenge ACKS (RFC 5961) could leak enough information to allow a patient attacker to hijack TCP sessions. He will soon provide details in an academic paper.
This patch increases the default limit from 100 to 1000, and adds some randomization so that the attacker can no longer hijack sessions without spending a considerable amount of probes.
Based on initial analysis and patch from Linus.
Note that we also have per socket rate limiting, so it is tempting to remove the host limit in the future.
v2: randomize the count of challenge acks per second, not the period.
--- net/ipv4/tcp_input.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
net/ipv4/tcp_input.c +10 -5
@@ -87,7 +87,7 @@ int sysctl_tcp_adv_win_scale __read_mostEXPORT_SYMBOL (sysctl_tcp_adv_win_scale);/* rfc5961 challenge ack rate limiting */ -int sysctl_tcp_challenge_ack_limit =100 ; +int sysctl_tcp_challenge_ack_limit =1000 ;int sysctl_tcp_stdurg__read_mostly ;int sysctl_tcp_rfc1337__read_mostly ;
@@ -3460,7 +3460,7 @@ static void tcp_send_challenge_ack(strucstatic u32 challenge_timestamp;static unsigned int challenge_count;struct tcp_sock *tp =tcp_sk (sk); -u32 now; +u32 count, now;/* First check our per-socket dupack rate limit. */ if (tcp_oow_rate_limited(sock_net(sk), skb,
@@ -3468,13 +3468,18 @@ static void tcp_send_challenge_ack(struc &tp->last_oow_ack_time))return ; -/* Then check the check host-wide RFC 5961 rate limit. */ +/* Then check host-wide RFC 5961 rate limit. */ now = jiffies /HZ ;if (now != challenge_timestamp) { +u32 half = (sysctl_tcp_challenge_ack_limit +1 ) >>1 ; + challenge_timestamp = now; - challenge_count =0 ; +WRITE_ONCE (challenge_count, half + +prandom_u32_max (sysctl_tcp_challenge_ack_limit)); } -if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { + count =READ_ONCE (challenge_count); +if (count >0 ) { +WRITE_ONCE (challenge_count, count -1 );NET_INC_STATS_BH (sock_net (sk),LINUX_MIB_TCPCHALLENGEACK );tcp_send_ack (sk); }
Greg Kroah-Hartman
maintainerPATCH 5/56 tcp: enable per-socket rate limiting of all challenge acks
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Baron <[email protected]>
[ Upstream commit 083ae308280d13d187512b9babe3454342a7987e ]
The per-socket rate limit for 'challenge acks' was introduced in the context of limiting ack loops:
commit f2b2c582e824 ("tcp: mitigate ACK loops for connections as tcp_sock")
And I think it can be extended to rate limit all 'challenge acks' on a per-socket basis.
Since we have the global tcp_challenge_ack_limit, this patch allows for tcp_challenge_ack_limit to be set to a large value and effectively rely on the per-socket limit, or set tcp_challenge_ack_limit to a lower value and still prevents a single connections from consuming the entire challenge ack quota.
It further moves in the direction of eliminating the global limit at some point, as Eric Dumazet has suggested. This a follow-up to:
Subject: [PATCH 4.6 05/56] tcp: make challenge acks less predictable
--- net/ipv4/tcp_input.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-)
net/ipv4/tcp_input.c +22 -17
@@ -3423,6 +3423,23 @@ static int tcp_ack_update_window(structreturn flag; } +static bool __tcp_oow_rate_limited (struct net *net,int mib_idx, +u32 *last_oow_ack_time) +{ +if (*last_oow_ack_time) { +s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time); + +if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) { +NET_INC_STATS_BH (net, mib_idx); +return true;/* rate-limited: don't send yet! */ + } + } + + *last_oow_ack_time = tcp_time_stamp; + +return false;/* not rate-limited: go ahead, send dupack now! */ +} +/* Return true if we're currently rate-limiting out-of-window ACKs and * thus shouldn't send a dupack right now. We rate-limit dupacks in * response to out-of-window SYNs or ACKs to mitigate ACK loops or DoS
@@ -3436,21 +3453,9 @@ bool tcp_oow_rate_limited(struct net *ne/* Data packets without SYNs are not likely part of an ACK loop. */ if ((TCP_SKB_CB (skb)->seq !=TCP_SKB_CB (skb)->end_seq) && !tcp_hdr (skb)->syn) - goto not_rate_limited; - -if (*last_oow_ack_time) { -s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time); +return false; -if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) { -NET_INC_STATS_BH (net, mib_idx); -return true;/* rate-limited: don't send yet! */ - } - } - - *last_oow_ack_time = tcp_time_stamp; - -not_rate_limited: -return false;/* not rate-limited: go ahead, send dupack now! */ +return __tcp_oow_rate_limited (net, mib_idx, last_oow_ack_time); }/* RFC 5961 7 [ACK Throttling] */
@@ -3463,9 +3468,9 @@ static void tcp_send_challenge_ack(strucu32 count, now;/* First check our per-socket dupack rate limit. */ -if (tcp_oow_rate_limited (sock_net (sk), skb, -LINUX_MIB_TCPACKSKIPPEDCHALLENGE , - &tp->last_oow_ack_time)) +if (__tcp_oow_rate_limited (sock_net (sk), +LINUX_MIB_TCPACKSKIPPEDCHALLENGE , + &tp->last_oow_ack_time))return ;/* Then check host-wide RFC 5961 rate limit. */
Greg Kroah-Hartman
maintainerPATCH 6/56 bonding: set carrier off for devices created through netlink
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Beniamino Galvani <[email protected]>
[ Upstream commit 005db31d5f5f7c31cfdc43505d77eb3ca5cf8ec6 ]
Commit e826eafa65c6 ("bonding: Call netif_carrier_off after register_netdevice") moved netif_carrier_off() from bond_init() to bond_create(), but the latter is called only for initial default devices and ones created through sysfs:
$ modprobe bonding $ echo +bond1 > /sys/class/net/bonding_masters $ ip link add bond2 type bond $ grep "MII Status" /proc/net/bonding/* /proc/net/bonding/bond0:MII Status: down /proc/net/bonding/bond1:MII Status: down /proc/net/bonding/bond2:MII Status: up
Ensure that carrier is initially off also for devices created through netlink.
--- drivers/net/bonding/bond_netlink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/bonding/bond_netlink.c +5 -1
@@ -446,7 +446,11 @@ static int bond_newlink(struct net *src_if (err <0 )return err; -return register_netdevice (bond_dev); + err =register_netdevice (bond_dev); + +netif_carrier_off (bond_dev); + +return err; }static size_t bond_get_size (const struct net_device *bond_dev)
Greg Kroah-Hartman
maintainerPATCH 7/56 net: bgmac: Fix infinite loop in bgmac_dma_tx_add()
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <[email protected]>
[ Upstream commit e86663c475d384ab5f46cb5637e9b7ad08c5c505 ]
Nothing is decrementing the index "i" while we are cleaning up the fragments we could not successful transmit.
--- drivers/net/ethernet/broadcom/bgmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bgmac.c +1 -1
@@ -231,7 +231,7 @@ err_dma:dma_unmap_single (dma_dev, slot->dma_addr,skb_headlen (skb),DMA_TO_DEVICE ); -while (i >0 ) { +while (i-- >0 ) {int index = (ring->end + i) %BGMAC_TX_RING_SLOTS ;struct bgmac_slot_info *slot = &ring->slots[index];u32 ctl1 =le32_to_cpu (ring->cpu_base[index].ctl1);
Greg Kroah-Hartman
maintainerPATCH 8/56 vlan: use a valid default mtu value for vlan over macsec
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit 18d3df3eab23796d7f852f9c6bb60962b8372ced ]
macsec can't cope with mtu frames which need vlan tag insertion, and vlan device set the default mtu equal to the underlying dev's one. By default vlan over macsec devices use invalid mtu, dropping all the large packets.
This patch adds a netif helper to check if an upper vlan device needs mtu reduction. The helper is used during vlan devices initialization to set a valid default and during mtu updating to forbid invalid, too bit, mtu values.
The helper currently only check if the lower dev is a macsec device, if we get more users, we need to update only the helper (possibly reserving an additional IFF bit).
--- include/linux/netdevice.h | 7 +++++++ net/8021q/vlan_dev.c | 10 ++++++---- net/8021q/vlan_netlink.c | 7 +++++-- 3 files changed, 18 insertions(+), 6 deletions(-)
include/linux/netdevice.h +7 -0
@@ -4156,6 +4156,13 @@ static inline void netif_keep_dst(struct dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE |IFF_XMIT_DST_RELEASE_PERM ); } +/* return true if dev can't cope with mtu frames that need vlan tag insertion */ +static inline bool netif_reduces_vlan_mtu (struct net_device *dev) +{ +/* TODO: reserve and use an additional IFF bit, if we get more users */ +return dev->priv_flags &IFF_MACSEC ; +} +extern struct pernet_operations __net_initdata loopback_net_ops;/* Logging, debugging and troubleshooting/diagnostic helpers. */
net/8021q/vlan_dev.c +6 -4
@@ -146,10 +146,12 @@ static netdev_tx_t vlan_dev_hard_start_xstatic int vlan_dev_change_mtu (struct net_device *dev,int new_mtu) { -/* TODO: gotta make sure the underlying layer can handle it, -* maybe an IFF_VLAN_CAPABLE flag for devices? -*/ -if (vlan_dev_priv (dev)->real_dev->mtu < new_mtu) +struct net_device *real_dev =vlan_dev_priv (dev)->real_dev; +unsigned int max_mtu = real_dev->mtu; + +if (netif_reduces_vlan_mtu (real_dev)) + max_mtu -=VLAN_HLEN ; +if (max_mtu < new_mtu)return -ERANGE ; dev->mtu = new_mtu;
net/8021q/vlan_netlink.c +5 -2
@@ -118,6 +118,7 @@ static int vlan_newlink(struct net *src_ {struct vlan_dev_priv *vlan =vlan_dev_priv (dev);struct net_device *real_dev; +unsigned int max_mtu;__be16 proto;int err;
@@ -144,9 +145,11 @@ static int vlan_newlink(struct net *src_if (err <0 )return err; + max_mtu =netif_reduces_vlan_mtu (real_dev) ? real_dev->mtu -VLAN_HLEN : + real_dev->mtu;if (!tb[IFLA_MTU ]) - dev->mtu = real_dev->mtu; -else if (dev->mtu > real_dev->mtu) + dev->mtu = max_mtu; +else if (dev->mtu > max_mtu)return -EINVAL ; err =vlan_changelink (dev, tb, data);
Greg Kroah-Hartman
maintainerPATCH 9/56 bridge: Fix incorrect re-injection of LLDP packets
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit baedbe55884c003819f5c8c063ec3d2569414296 ]
Commit 8626c56c8279 ("bridge: fix potential use-after-free when hook returns QUEUE or STOLEN verdict") caused LLDP packets arriving through a bridge port to be re-injected to the Rx path with skb->dev set to the bridge device, but this breaks the lldpad daemon.
The lldpad daemon opens a packet socket with protocol set to ETH_P_LLDP for any valid device on the system, which doesn't not include soft devices such as bridge and VLAN.
Since packet sockets (ptype_base) are processed in the Rx path after the Rx handler, LLDP packets with skb->dev set to the bridge device never reach the lldpad daemon.
Fix this by making the bridge's Rx handler re-inject LLDP packets with RX_HANDLER_PASS, which effectively restores the behaviour prior to the mentioned commit.
This means netfilter will never receive LLDP packets coming through a bridge port, as I don't see a way in which we can have okfn() consume the packet without breaking existing behaviour. I've already carried out a similar fix for STP packets in commit 56fae404fb2c ("bridge: Fix incorrect re-injection of STP packets").
--- net/bridge/br_input.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
net/bridge/br_input.c +18 -0
@@ -213,6 +213,16 @@ drop: }EXPORT_SYMBOL_GPL (br_handle_frame_finish); +static void __br_handle_local_finish (struct sk_buff *skb) +{ +struct net_bridge_port *p =br_port_get_rcu (skb->dev); +u16 vid =0 ; + +/* check if vlan is allowed, to avoid spoofing */ +if (p->flags &BR_LEARNING &&br_should_learn (p, skb, &vid)) +br_fdb_update (p->br, p,eth_hdr (skb)->h_source, vid, false); +} +/* note: already called with rcu_read_lock */ static int br_handle_local_finish (struct net *net,struct sock *sk,struct sk_buff *skb) {
@@ -279,6 +289,14 @@ rx_handler_result_t br_handle_frame(strucase 0x01 :/* IEEE MAC (Pause) */ goto drop; +case 0x0E :/* 802.1AB LLDP */ + fwd_mask |= p->br->group_fwd_mask; +if (fwd_mask & (1u << dest[5 ])) + goto forward; + *pskb = skb; +__br_handle_local_finish (skb); +return RX_HANDLER_PASS ; +default :/* Allow selective forwarding for most other protocols */ fwd_mask |= p->br->group_fwd_mask;
Greg Kroah-Hartman
maintainerPATCH 10/56 net: ipv6: Always leave anycast and multicast groups on link down
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Manning <[email protected]>
[ Upstream commit ea06f7176413e2538d13bb85b65387d0917943d9 ]
Default kernel behavior is to delete IPv6 addresses on link down, which entails deletion of the multicast and the subnet-router anycast addresses. These deletions do not happen with sysctl setting to keep global IPv6 addresses on link down, so every link down/up causes an increment of the anycast and multicast refcounts. These bogus refcounts may stop these addrs from being removed on subsequent calls to delete them. The solution is to leave the groups for the multicast and subnet anycast on link down for the callflow when global IPv6 addresses are kept.
--- net/ipv6/addrconf.c | 4 ++++ 1 file changed, 4 insertions(+)
net/ipv6/addrconf.c +4 -0
@@ -3563,6 +3563,10 @@ restart:if (state !=INET6_IFADDR_STATE_DEAD ) {__ipv6_ifa_notify (RTM_DELADDR , ifa);inet6addr_notifier_call_chain (NETDEV_DOWN , ifa); + }else { +if (idev->cnf.forwarding) +addrconf_leave_anycast (ifa); +addrconf_leave_solict (ifa->idev, &ifa->addr); }write_lock_bh (&idev->lock);
Greg Kroah-Hartman
maintainerPATCH 11/56 net/irda: fix NULL pointer dereference on memory allocation failure
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vegard Nossum <[email protected]>
[ Upstream commit d3e6952cfb7ba5f4bfa29d4803ba91f96ce1204d ]
I ran into this:
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN
CPU: 2 PID: 2012 Comm: trinity-c3 Not tainted 4.7.0-rc7+ #19
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
task: ffff8800b745f2c0 ti: ffff880111740000 task.ti: ffff880111740000
RIP: 0010:[<ffffffff82bbf066>] [<ffffffff82bbf066>] irttp_connect_request+0x36/0x710
RSP: 0018:ffff880111747bb8 EFLAGS: 00010286
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000069dd8358
RDX: 0000000000000009 RSI: 0000000000000027 RDI: 0000000000000048
RBP: ffff880111747c00 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000069dd8358 R11: 1ffffffff0759723 R12: 0000000000000000
R13: ffff88011a7e4780 R14: 0000000000000027 R15: 0000000000000000
FS: 00007fc738404700(0000) GS:ffff88011af00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fc737fdfb10 CR3: 0000000118087000 CR4: 00000000000006e0
Stack:
0000000000000200 ffff880111747bd8 ffffffff810ee611 ffff880119f1f220
ffff880119f1f4f8 ffff880119f1f4f0 ffff88011a7e4780 ffff880119f1f232
ffff880119f1f220 ffff880111747d58 ffffffff82bca542 0000000000000000
Call Trace:
[<ffffffff82bca542>] irda_connect+0x562/0x1190
[<ffffffff825ae582>] SYSC_connect+0x202/0x2a0
[<ffffffff825b4489>] SyS_connect+0x9/0x10
[<ffffffff8100334c>] do_syscall_64+0x19c/0x410
[<ffffffff83295ca5>] entry_SYSCALL64_slow_path+0x25/0x25
Code: 41 89 ca 48 89 e5 41 57 41 56 41 55 41 54 41 89 d7 53 48 89 fb 48 83 c7 48 48 89 fa 41 89 f6 48 c1 ea 03 48 83 ec 20 4c 8b 65 10 <0f> b6 04 02 84 c0 74 08 84 c0 0f 8e 4c 04 00 00 80 7b 48 00 74
RIP [<ffffffff82bbf066>] irttp_connect_request+0x36/0x710
RSP <ffff880111747bb8>
---[ end trace 4cda2588bc055b30 ]---The problem is that irda_open_tsap() can fail and leave self->tsap = NULL, and then irttp_connect_request() almost immediately dereferences it.
--- net/irda/af_irda.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/irda/af_irda.c +5 -2
@@ -1024,8 +1024,11 @@ static int irda_connect(struct socket *s }/* Check if we have opened a local TSAP */ -if (!self->tsap) -irda_open_tsap (self,LSAP_ANY , addr->sir_name); +if (!self->tsap) { + err =irda_open_tsap (self,LSAP_ANY , addr->sir_name); +if (err) + goto out; + }/* Move to connecting socket, start sending Connect Requests */ sock->state =SS_CONNECTING ;
Greg Kroah-Hartman
maintainerPATCH 12/56 qed: Fix setting/clearing bit in completion bitmap
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manish Chopra <[email protected]>
[ Upstream commit 59d3f1ceb69b54569685d0c34dff16a1e0816b19 ]
Slowpath completion handling is incorrectly changing SPQ_RING_SIZE bits instead of a single one.
--- drivers/net/ethernet/qlogic/qed/qed_spq.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/net/ethernet/qlogic/qed/qed_spq.c +3 -4
@@ -791,13 +791,12 @@ int qed_spq_completion(struct qed_hwfn ** in a bitmap and increasing the chain consumer only * for the first successive completed entries. */ -bitmap_set (p_spq->p_comp_bitmap, pos,SPQ_RING_SIZE ); +__set_bit (pos, p_spq->p_comp_bitmap);while (test_bit (p_spq->comp_bitmap_idx, p_spq->p_comp_bitmap)) { -bitmap_clear (p_spq->p_comp_bitmap, - p_spq->comp_bitmap_idx, -SPQ_RING_SIZE ); +__clear_bit (p_spq->comp_bitmap_idx, + p_spq->p_comp_bitmap); p_spq->comp_bitmap_idx++;qed_chain_return_produced (&p_spq->chain); }
Greg Kroah-Hartman
maintainerPATCH 13/56 macsec: ensure rx_sa is set when validation is disabled
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Beniamino Galvani <[email protected]>
[ Upstream commit e3a3b626010a14fe067f163c2c43409d5afcd2a9 ]
macsec_decrypt() is not called when validation is disabled and so macsec_skb_cb(skb)->rx_sa is not set; but it is used later in macsec_post_decrypt(), ensure that it's always initialized.
--- drivers/net/macsec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/macsec.c +2 -1
@@ -914,7 +914,6 @@ static struct sk_buff *macsec_decrypt(st }macsec_skb_cb (skb)->req = req; -macsec_skb_cb (skb)->rx_sa = rx_sa; skb->dev = dev;aead_request_set_callback (req,0 , macsec_decrypt_done, skb);
@@ -1141,6 +1140,8 @@ static rx_handler_result_t macsec_handle } } +macsec_skb_cb (skb)->rx_sa = rx_sa; +/* Disabled && !changed text => skip validation */ if (hdr->tci_an &MACSEC_TCI_C || secy->validate_frames !=MACSEC_VALIDATE_DISABLED )
Greg Kroah-Hartman
maintainerPATCH 14/56 tcp: consider recv buf for the initial window scale
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Soheil Hassas Yeganeh <[email protected]>
[ Upstream commit f626300a3e776ccc9671b0dd94698fb3aa315966 ]
tcp_select_initial_window() intends to advertise a window scaling for the maximum possible window size. To do so, it considers the maximum of net.ipv4.tcp_rmem[2] and net.core.rmem_max as the only possible upper-bounds. However, users with CAP_NET_ADMIN can use SO_RCVBUFFORCE to set the socket's receive buffer size to values larger than net.ipv4.tcp_rmem[2] and net.core.rmem_max. Thus, SO_RCVBUFFORCE is effectively ignored by tcp_select_initial_window().
To fix this, consider the maximum of net.ipv4.tcp_rmem[2], net.core.rmem_max and socket's initial buffer space.
--- net/ipv4/tcp_output.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv4/tcp_output.c +2 -1
@@ -236,7 +236,8 @@ void tcp_select_initial_window(int __spa/* Set window scaling on max possible window * See RFC1323 for an explanation of the limit to 14 */ - space =max_t (u32, sysctl_tcp_rmem[2 ], sysctl_rmem_max); + space =max_t (u32, space, sysctl_tcp_rmem[2 ]); + space =max_t (u32, space, sysctl_rmem_max); space =min_t (u32, space, *window_clamp);while (space >65535 && (*rcv_wscale) <14 ) { space >>=1 ;
Greg Kroah-Hartman
maintainerPATCH 16/56 arm: oabi compat: add missing access checks
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Weinstein <[email protected]>
commit 7de249964f5578e67b99699c5f0b405738d820a2 upstream.
Add access checks to sys_oabi_epoll_wait() and sys_oabi_semtimedop(). This fixes CVE-2016-3857, a local privilege escalation under CONFIG_OABI_COMPAT.
--- arch/arm/kernel/sys_oabi-compat.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm/kernel/sys_oabi-compat.c +7 -1
@@ -279,8 +279,12 @@ asmlinkage long sys_oabi_epoll_wait(intmm_segment_t fs;long ret, err, i; -if (maxevents <=0 || maxevents > (INT_MAX /sizeof (struct epoll_event ))) +if (maxevents <=0 || + maxevents > (INT_MAX /sizeof (*kbuf)) || + maxevents > (INT_MAX /sizeof (*events)))return -EINVAL ; +if (!access_ok (VERIFY_WRITE , events,sizeof (*events) * maxevents)) +return -EFAULT ; kbuf =kmalloc (sizeof (*kbuf) * maxevents,GFP_KERNEL );if (!kbuf)return -ENOMEM ;
@@ -317,6 +321,8 @@ asmlinkage long sys_oabi_semtimedop(intif (nsops <1 || nsops >SEMOPM )return -EINVAL ; +if (!access_ok (VERIFY_READ , tsops,sizeof (*tsops) * nsops)) +return -EFAULT ; sops =kmalloc (sizeof (*sops) * nsops,GFP_KERNEL );if (!sops)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 17/56 KEYS: 64-bit MIPS needs to use compat_sys_keyctl for 32-bit userspace
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit 20f06ed9f61a185c6dabd662c310bed6189470df upstream.
MIPS64 needs to use compat_sys_keyctl for 32-bit userspace rather than calling sys_keyctl. The latter will work in a lot of cases, thereby hiding the issue.
Patchwork: https://patchwork.linux-mips.org/patch/13832/
--- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/mips/kernel/scall64-n32.S +1 -1
@@ -344,7 +344,7 @@ EXPORT(sysn32_call_table) PTR sys_ni_syscall /* available, was setaltroot */ PTR sys_add_key PTR sys_request_key - PTR sys_keyctl /* 6245 */ + PTR compat_sys_keyctl /* 6245 */ PTR sys_set_thread_area PTR sys_inotify_init PTR sys_inotify_add_watch
arch/mips/kernel/scall64-o32.S +1 -1
@@ -500,7 +500,7 @@ EXPORT(sys32_call_table) PTR sys_ni_syscall /* available, was setaltroot */ PTR sys_add_key /* 4280 */ PTR sys_request_key - PTR sys_keyctl + PTR compat_sys_keyctl PTR sys_set_thread_area PTR sys_inotify_init PTR sys_inotify_add_watch /* 4285 */
Greg Kroah-Hartman
maintainerPATCH 18/56 IB/hfi1: Correct issues with sc5 computation
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Marciniszyn <[email protected]>
commit 896ce45da2c2f4abc508d443fdecde7de0b3fa7e upstream.
There are several computatations of the sc in the
ud receive routine.
Besides the code duplication, all are wrong when the
sc is greater than 15. In that case the code incorrectly
or's a 1 into the computed sc instead of 1 shifted left by 4.
Fix precomputed sc5 by using an already implemented routine hdr2sc() and deleting flawed duplicated code.
--- drivers/staging/rdma/hfi1/ud.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-)
drivers/staging/rdma/hfi1/ud.c +3 -20
@@ -678,8 +678,7 @@ void hfi1_ud_rcv(struct hfi1_packet *pacu32 tlen = packet->tlen;struct rvt_qp *qp = packet->qp;bool has_grh = rcv_flags &HFI1_HAS_GRH ; -bool sc4_bit =has_sc4_bit (packet); -u8 sc; +u8 sc5 =hdr2sc ((struct hfi1_message_header *)hdr, packet->rhf);u32 bth1;int is_mcast;struct ib_grh *grh =NULL ;
@@ -697,10 +696,8 @@ void hfi1_ud_rcv(struct hfi1_packet *pac*/ struct hfi1_pportdata *ppd =ppd_from_ibp (ibp);u32 lqpn =be32_to_cpu (ohdr->bth[1 ]) &RVT_QPN_MASK ; -u8 sl, sc5; +u8 sl; - sc5 = (be16_to_cpu (hdr->lrh[0 ]) >>12 ) &0xf ; - sc5 |= sc4_bit; sl = ibp->sc_to_sl[sc5];process_becn (ppd, sl,0 , lqpn,0 ,IB_CC_SVCTYPE_UD );
@@ -717,10 +714,6 @@ void hfi1_ud_rcv(struct hfi1_packet *pacif (!is_mcast && (opcode !=IB_OPCODE_CNP ) && bth1 &HFI1_FECN_SMASK ) {u16 slid =be16_to_cpu (hdr->lrh[3 ]); -u8 sc5; - - sc5 = (be16_to_cpu (hdr->lrh[0 ]) >>12 ) &0xf ; - sc5 |= sc4_bit;return_cnp (ibp, qp, src_qp, pkey, dlid, slid, sc5, grh); }
@@ -745,10 +738,6 @@ void hfi1_ud_rcv(struct hfi1_packet *pacif (qp->ibqp.qp_num >1 ) {struct hfi1_pportdata *ppd =ppd_from_ibp (ibp);u16 slid; -u8 sc5; - - sc5 = (be16_to_cpu (hdr->lrh[0 ]) >>12 ) &0xf ; - sc5 |= sc4_bit; slid =be16_to_cpu (hdr->lrh[3 ]);if (unlikely (rcv_pkey_check (ppd, pkey, sc5, slid))) {
@@ -790,10 +779,6 @@ void hfi1_ud_rcv(struct hfi1_packet *pac/* Received on QP0, and so by definition, this is an SMP */ struct opa_smp *smp = (struct opa_smp *)data;u16 slid =be16_to_cpu (hdr->lrh[3 ]); -u8 sc5; - - sc5 = (be16_to_cpu (hdr->lrh[0 ]) >>12 ) &0xf ; - sc5 |= sc4_bit;if (opa_smp_check (ibp, pkey, sc5, qp, slid, smp)) goto drop;
@@ -890,9 +875,7 @@ void hfi1_ud_rcv(struct hfi1_packet *pac } wc.slid =be16_to_cpu (hdr->lrh[3 ]); - sc = (be16_to_cpu (hdr->lrh[0 ]) >>12 ) &0xf ; - sc |= sc4_bit; - wc.sl = ibp->sc_to_sl[sc]; + wc.sl = ibp->sc_to_sl[sc5];/* * Save the LMC lower bits if the destination LID is a unicast LID.
Greg Kroah-Hartman
maintainerPATCH 19/56 IB/hfi1: Fix deadlock with txreq allocation slow path
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Marciniszyn <[email protected]>
commit 2aee309d3e01447c55fdf89cef05a0e2be372655 upstream.
A failure in the get_txreq() inline will result in a slow path retry using __get_txreq().
__get_txreq() attempts to procure the qp s_lock, which is already held in all callers.
Fix by deleting the s_lock maintenance in __get_txreq() and add sparse syntax hooks to future proof the code.
--- drivers/staging/rdma/hfi1/verbs_txreq.c | 4 +--- drivers/staging/rdma/hfi1/verbs_txreq.h | 1 + 2 files changed, 2 insertions(+), 3 deletions(-)
drivers/staging/rdma/hfi1/verbs_txreq.c +1 -3
@@ -92,11 +92,10 @@ void hfi1_put_txreq(struct verbs_txreq *struct verbs_txreq *__get_txreq (struct hfi1_ibdev *dev,struct rvt_qp *qp) + __must_hold(&qp->s_lock) {struct verbs_txreq *tx =ERR_PTR (-EBUSY ); -unsigned long flags; -spin_lock_irqsave (&qp->s_lock, flags);write_seqlock (&dev->iowait_lock);if (ib_rvt_state_ops[qp->state] &RVT_PROCESS_RECV_OK ) {struct hfi1_qp_priv *priv;
@@ -116,7 +115,6 @@ struct verbs_txreq *__get_txreq(struct h } out:write_sequnlock (&dev->iowait_lock); -spin_unlock_irqrestore (&qp->s_lock, flags);return tx; }
drivers/staging/rdma/hfi1/verbs_txreq.h +1 -0
@@ -73,6 +73,7 @@ struct verbs_txreq *__get_txreq(struct hstatic inline struct verbs_txreq *get_txreq (struct hfi1_ibdev *dev,struct rvt_qp *qp) + __must_hold(&qp->slock) {struct verbs_txreq *tx;struct hfi1_qp_priv *priv = qp->priv;
Greg Kroah-Hartman
maintainerPATCH 20/56 apparmor: fix ref count leak when profile sha1 hash is read
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Johansen <[email protected]>
commit 0b938a2e2cf0b0a2c8bac9769111545aff0fee97 upstream.
--- security/apparmor/apparmorfs.c | 1 + 1 file changed, 1 insertion(+)
security/apparmor/apparmorfs.c +1 -0
@@ -331,6 +331,7 @@ static int aa_fs_seq_hash_show(struct seseq_printf (seq,"%.2x" , profile->hash[i]);seq_puts (seq,"\n" ); } +aa_put_profile (profile);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 21/56 regulator: qcom_smd: Remove list_voltage callback for rpm_smps_ldo_ops_fixed
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Axel Lin <[email protected]>
commit 43160ffd12c8d1d331362362eea3c70e04b6f9c4 upstream.
Use regulator_list_voltage_linear_range in rpm_smps_ldo_ops_fixed is wrong because it is used for fixed regulator without any linear range. The rpm_smps_ldo_ops_fixed is used for pm8941_lnldo which has fixed_uV set and n_voltages = 1. In this case, regulator_list_voltage() can return rdev->desc->fixed_uV without .list_voltage implementation.
--- drivers/regulator/qcom_smd-regulator.c | 1 - 1 file changed, 1 deletion(-)
drivers/regulator/qcom_smd-regulator.c +0 -1
@@ -140,7 +140,6 @@ static const struct regulator_ops rpm_sm .enable = rpm_reg_enable, .disable = rpm_reg_disable, .is_enabled = rpm_reg_is_enabled, - .list_voltage = regulator_list_voltage_linear_range, .get_voltage = rpm_reg_get_voltage, .set_voltage = rpm_reg_set_voltage,
Greg Kroah-Hartman
maintainerPATCH 22/56 random: strengthen input validation for RNDADDTOENTCNT
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 86a574de4590ffe6fd3f3ca34cdcf655a78e36ec upstream.
Don't allow RNDADDTOENTCNT or RNDADDENTROPY to accept a negative entropy value. It doesn't make any sense to subtract from the entropy counter, and it can trigger a warning:
random: negative entropy/overflow: pool input count -40000
------------[ cut here ]------------ WARNING: CPU: 3 PID: 6828 at drivers/char/random.c:670[< none >] credit_entropy_bits+0x21e/0xad0 drivers/char/random.c:670 Modules linked in: CPU: 3 PID: 6828 Comm: a.out Not tainted 4.7.0-rc4+ #4 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 ffffffff880b58e0 ffff88005dd9fcb0 ffffffff82cc838f ffffffff87158b40 fffffbfff1016b1c 0000000000000000 0000000000000000 ffffffff87158b40 ffffffff83283dae 0000000000000009 ffff88005dd9fcf8 ffffffff8136d27f Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [<ffffffff82cc838f>] dump_stack+0x12e/0x18f lib/dump_stack.c:51 [<ffffffff8136d27f>] __warn+0x19f/0x1e0 kernel/panic.c:516 [<ffffffff8136d48c>] warn_slowpath_null+0x2c/0x40 kernel/panic.c:551 [<ffffffff83283dae>] credit_entropy_bits+0x21e/0xad0 drivers/char/random.c:670 [< inline >] credit_entropy_bits_safe drivers/char/random.c:734 [<ffffffff8328785d>] random_ioctl+0x21d/0x250 drivers/char/random.c:1546 [< inline >] vfs_ioctl fs/ioctl.c:43 [<ffffffff8185316c>] do_vfs_ioctl+0x18c/0xff0 fs/ioctl.c:674 [< inline >] SYSC_ioctl fs/ioctl.c:689 [<ffffffff8185405f>] SyS_ioctl+0x8f/0xc0 fs/ioctl.c:680 [<ffffffff86a995c0>] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207 ---[ end trace 5d4902b2ba842f1f ]---
This was triggered using the test program:
// autogenerated by syzkaller (http://github.com/google/syzkaller)
int main() {
int fd = open("/dev/random", O_RDWR);
int val = -5000;
ioctl(fd, RNDADDTOENTCNT, &val);
return 0;
}It's harmless in that (a) only root can trigger it, and (b) after complaining the code never does let the entropy count go negative, but it's better to simply not allow this userspace from passing in a negative entropy value altogether.
Google-Bug-Id: #29575089
--- drivers/char/random.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/char/random.c +7 -6
@@ -722,15 +722,18 @@ retry: } } -static void credit_entropy_bits_safe (struct entropy_store *r,int nbits) +static int credit_entropy_bits_safe (struct entropy_store *r,int nbits) {const int nbits_max = (int )(~0U >> (ENTROPY_SHIFT +1 )); +if (nbits <0 ) +return -EINVAL ; +/* Cap the value to avoid overflows */ nbits =min (nbits, nbits_max); - nbits =max (nbits, -nbits_max);credit_entropy_bits (r, nbits); +return 0 ; }/*********************************************************************
@@ -1542,8 +1545,7 @@ static long random_ioctl(struct file *f,return -EPERM ;if (get_user (ent_count, p))return -EFAULT ; -credit_entropy_bits_safe (&input_pool, ent_count); -return 0 ; +return credit_entropy_bits_safe (&input_pool, ent_count);case RNDADDENTROPY :if (!capable (CAP_SYS_ADMIN ))return -EPERM ;
@@ -1557,8 +1559,7 @@ static long random_ioctl(struct file *f, size);if (retval <0 )return retval; -credit_entropy_bits_safe (&input_pool, ent_count); -return 0 ; +return credit_entropy_bits_safe (&input_pool, ent_count);case RNDZAPENTCNT :case RNDCLEARPOOL :/*
Greg Kroah-Hartman
maintainerPATCH 23/56 x86/mm/pat: Add support of non-default PAT MSR setting
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit 02f037d641dc6672be5cfe7875a48ab99b95b154 upstream.
In preparation for fixing a regression caused by:
9cd25aac1f44 ("x86/mm/pat: Emulate PAT when it is disabled")'
... PAT needs to support a case that PAT MSR is initialized with a non-default value.
When pat_init() is called and PAT is disabled, it initializes the PAT table with the BIOS default value. Xen, however, sets PAT MSR with a non-default value to enable WC. This causes inconsistency between the PAT table and PAT MSR when PAT is set to disable on Xen.
Change pat_init() to handle the PAT disable cases properly. Add init_cache_modes() to handle two cases when PAT is set to disable.
1. CPU supports PAT: Set PAT table to be consistent with PAT MSR.
2. CPU does not support PAT: Set PAT table to be consistent with PWT and PCD bits in a PTE.
Note, __init_cache_modes(), renamed from pat_init_cache_modes(), will be changed to a static function in a later patch.
--- arch/x86/include/asm/pat.h | 2 - arch/x86/mm/pat.c | 73 ++++++++++++++++++++++++++++++++------------- arch/x86/xen/enlighten.c | 2 - 3 files changed, 55 insertions(+), 22 deletions(-)
arch/x86/include/asm/pat.h +1 -1
@@ -6,7 +6,7 @@bool pat_enabled (void );extern void pat_init (void ); -void pat_init_cache_modes (u64 ); +void __init_cache_modes (u64 );extern int reserve_memtype (u64 start,u64 end,enum page_cache_mode req_pcm,enum page_cache_mode *ret_pcm);
arch/x86/mm/pat.c +53 -20
112 lines not on this page · raw message
arch/x86/xen/enlighten.c +1 -1
@@ -1623,7 +1623,7 @@ asmlinkage __visible void __init xen_sta* configuration. */ rdmsrl (MSR_IA32_CR_PAT , pat); -pat_init_cache_modes (pat); +__init_cache_modes (pat);/* keep using Xen gdt for now; no urgent need to change it */
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Greg Kroah-Hartman
maintainerPATCH 24/56 x86/mm/pat: Add pat_disable() interface
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit 224bb1e5d67ba0f2872c98002d6a6f991ac6fd4a upstream.
In preparation for fixing a regression caused by:
9cd25aac1f44 ("x86/mm/pat: Emulate PAT when it is disabled")
... PAT needs to provide an interface that prevents the OS from initializing the PAT MSR.
PAT MSR initialization must be done on all CPUs using the specific sequence of operations defined in the Intel SDM. This requires MTRRs to be enabled since pat_init() is called as part of MTRR init from mtrr_rendezvous_handler().
Make pat_disable() as the interface that prevents the OS from initializing the PAT MSR. MTRR will call this interface when it cannot provide the SDM-defined sequence to initialize PAT.
This also assures that pat_disable() called from pat_bsp_init() will set the PAT table properly when CPU does not support PAT.
--- arch/x86/include/asm/pat.h | 1 + arch/x86/mm/pat.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-)
arch/x86/include/asm/pat.h +1 -0
@@ -5,6 +5,7 @@#include <asm/pgtable_types.h> bool pat_enabled (void ); +void pat_disable (const char *reason);extern void pat_init (void );void __init_cache_modes (u64 );
arch/x86/mm/pat.c +12 -1
@@ -40,11 +40,22 @@static bool boot_cpu_done;static int __read_mostly __pat_enabled =IS_ENABLED (CONFIG_X86_PAT ); +static void init_cache_modes (void ); -static inline void pat_disable (const char *reason) +void pat_disable (const char *reason) { +if (!__pat_enabled) +return ; + +if (boot_cpu_done) { +WARN_ONCE (1 ,"x86/PAT: PAT cannot be disabled after initialization\n" ); +return ; + } + __pat_enabled =0 ;pr_info ("x86/PAT: %s\n" , reason); + +init_cache_modes (); }static int __init nopat (char *str)
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Greg Kroah-Hartman
maintainerPATCH 25/56 x86/mm/pat: Replace cpu_has_pat with boot_cpu_has()
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit d63dcf49cf5ae5605f4d14229e3888e104f294b1 upstream.
Borislav Petkov suggested:
Quoted 3 lines
Please use on init paths
boot_cpu_has(X86_FEATURE_PAT)and on fast pathsstatic_cpu_has(X86_FEATURE_PAT). No more of thatcpu_has_XXXugliness.
Replace the use of cpu_has_pat on init paths with boot_cpu_has().
--- arch/x86/mm/pat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/mm/pat.c +2 -2
@@ -213,7 +213,7 @@ static void pat_bsp_init(u64 pat) {u64 tmp_pat; -if (!cpu_has_pat) { +if (!boot_cpu_has (X86_FEATURE_PAT )) {pat_disable ("PAT not supported by CPU." );return ; }
@@ -231,7 +231,7 @@ static void pat_bsp_init(u64 pat)static void pat_ap_init (u64 pat) { -if (!cpu_has_pat) { +if (!boot_cpu_has (X86_FEATURE_PAT )) {/* * If this happens we are on a secondary CPU, but switched to * PAT on the boot CPU. We have no way to undo PAT.
Greg Kroah-Hartman
maintainerPATCH 25/56 x86/mm/pat: Replace cpu_has_pat with boot_cpu_has()
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit d63dcf49cf5ae5605f4d14229e3888e104f294b1 upstream.
Borislav Petkov suggested:
Quoted 3 lines
Please use on init paths
boot_cpu_has(X86_FEATURE_PAT)and on fast pathsstatic_cpu_has(X86_FEATURE_PAT). No more of thatcpu_has_XXXugliness.
Replace the use of cpu_has_pat on init paths with boot_cpu_has().
--- arch/x86/mm/pat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/mm/pat.c +2 -2
@@ -213,7 +213,7 @@ static void pat_bsp_init(u64 pat) {u64 tmp_pat; -if (!cpu_has_pat) { +if (!boot_cpu_has (X86_FEATURE_PAT )) {pat_disable ("PAT not supported by CPU." );return ; }
@@ -231,7 +231,7 @@ static void pat_bsp_init(u64 pat)static void pat_ap_init (u64 pat) { -if (!cpu_has_pat) { +if (!boot_cpu_has (X86_FEATURE_PAT )) {/* * If this happens we are on a secondary CPU, but switched to * PAT on the boot CPU. We have no way to undo PAT.
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Greg Kroah-Hartman
maintainerPATCH 26/56 x86/mtrr: Fix Xorg crashes in Qemu sessions
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit edfe63ec97ed8d4496225f7ba54c9ce4207c5431 upstream.
A Xorg failure on qemu32 was reported as a regression [1] caused by commit 9cd25aac1f44 ("x86/mm/pat: Emulate PAT when it is disabled").
This patch fixes the Xorg crash.
Negative effects of this regression were the following two failures [2] in Xorg on QEMU with QEMU CPU model "qemu32" (-cpu qemu32), which were triggered by the fact that its virtual CPU does not support MTRRs.
#1. copy_process() failed in the check in reserve_pfn_range()
copy_process
copy_mm
dup_mm
dup_mmap
copy_page_range
track_pfn_copy
reserve_pfn_range
A WC map request was tracked as WC in memtype, which set a PTE as UC (pgprot) per __cachemode2pte_tbl[]. This led to this error in reserve_pfn_range() called from track_pfn_copy(), which obtained a pgprot from a PTE. It converts pgprot to page_cache_mode, which does not necessarily result in the original page_cache_mode since __cachemode2pte_tbl[] redirects multiple types to UC.
#2. error path in copy_process() then hit WARN_ON_ONCE in
untrack_pfn().
x86/PAT: Xorg:509 map pfn expected mapping type uncached-
minus for [mem 0xfd000000-0xfdffffff], got write-combining
Call Trace:
dump_stack
warn_slowpath_common
? untrack_pfn
? untrack_pfn
warn_slowpath_null
untrack_pfn
? __kunmap_atomic
unmap_single_vma
? pagevec_move_tail_fn
unmap_vmas
exit_mmap
mmput
copy_process.part.47
_do_fork
SyS_clone
do_syscall_32_irqs_on
entry_INT80_32These negative effects are caused by two separate bugs, but they can be addressed in separate patches. Fixing the pat_init() issue described below addresses the root cause, and avoids Xorg to hit these cases.
When the CPU does not support MTRRs, MTRR does not call pat_init(), which leaves PAT enabled without initializing PAT. This pat_init() issue is a long-standing issue, but manifested as issue #1 (and then hit issue #2) with the above-mentioned commit because the memtype now tracks cache attribute with 'page_cache_mode'.
This pat_init() issue existed before the commit, but we used pgprot in memtype. Hence, we did not have issue #1 before. But WC request resulted in WT in effect because WC pgrot is actually WT when PAT is not initialized. This is not how it was designed to work. When PAT is set to disable properly, WC is converted to UC. The use of WT can result in a system crash if the target range does not support WT. Fortunately, nobody ran into such issue before.
To fix this pat_init() issue, PAT code has been enhanced to provide pat_disable() interface. Call this interface when MTRRs are disabled. By setting PAT to disable properly, PAT bypasses the memtype check, and avoids issue #1.
[1]: https://lkml.org/lkml/2016/3/3/828
[2]: https://lkml.org/lkml/2016/3/4/775
--- arch/x86/include/asm/mtrr.h | 6 +++++- arch/x86/kernel/cpu/mtrr/main.c | 10 +++++++++- 2 files changed, 14 insertions(+), 2 deletions(-)
arch/x86/include/asm/mtrr.h +5 -1
@@ -24,6 +24,7 @@#define _ASM_X86_MTRR_H#include <uapi/asm/mtrr.h> +#include <asm/pat.h> /*
@@ -83,9 +84,12 @@ static inline int mtrr_trim_uncached_memstatic inline void mtrr_centaur_report_mcr (int mcr,u32 lo,u32 hi) { } +static inline void mtrr_bp_init (void ) +{ +pat_disable ("MTRRs disabled, skipping PAT initialization too." ); +}#define mtrr_ap_init () do {} while (0) -#define mtrr_bp_init () do {} while (0)#define set_mtrr_aps_delayed_init () do {} while (0)#define mtrr_aps_init () do {} while (0)#define mtrr_bp_restore () do {} while (0)
arch/x86/kernel/cpu/mtrr/main.c +9 -1
@@ -759,8 +759,16 @@ void __init mtrr_bp_init(void) } } -if (!mtrr_enabled ()) +if (!mtrr_enabled ()) {pr_info ("MTRR: Disabled\n" ); + +/* +* PAT initialization relies on MTRR's rendezvous handler. +* Skip PAT init until the handler can initialize both +* features independently. +*/ +pat_disable ("MTRRs disabled, skipping PAT initialization too." ); + } }void mtrr_ap_init (void )
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Greg Kroah-Hartman
maintainerPATCH 27/56 x86/mtrr: Fix PAT init handling when MTRR is disabled
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit ad025a73f0e9344ac73ffe1b74c184033e08e7d5 upstream.
get_mtrr_state() calls pat_init() on BSP even if MTRR is disabled. This results in calling pat_init() on BSP only since APs do not call pat_init() when MTRR is disabled. This inconsistency between BSP and APs leads to undefined behavior.
Make BSP's calling condition to pat_init() consistent with AP's, mtrr_ap_init() and mtrr_aps_init().
--- arch/x86/kernel/cpu/mtrr/generic.c | 24 ++++++++++++++---------- arch/x86/kernel/cpu/mtrr/main.c | 3 +++ arch/x86/kernel/cpu/mtrr/mtrr.h | 1 + 3 files changed, 18 insertions(+), 10 deletions(-)
arch/x86/kernel/cpu/mtrr/generic.c +14 -10
@@ -444,11 +444,24 @@ static void __init print_mtrr_state(voidpr_debug ("TOM2: %016llx aka %lldM\n" , mtrr_tom2, mtrr_tom2>>20 ); } +/* PAT setup for BP. We need to go through sync steps here */ +void __init mtrr_bp_pat_init (void ) +{ +unsigned long flags; + +local_irq_save (flags); +prepare_set (); + +pat_init (); + +post_set (); +local_irq_restore (flags); +} +/* Grab all of the MTRR state for this CPU into *state */ bool __init get_mtrr_state (void ) {struct mtrr_var_range *vrs; -unsigned long flags;unsigned lo, dummy;unsigned int i;
@@ -481,15 +494,6 @@ bool __init get_mtrr_state(void) mtrr_state_set =1 ; -/* PAT setup for BP. We need to go through sync steps here */ -local_irq_save (flags); -prepare_set (); - -pat_init (); - -post_set (); -local_irq_restore (flags); -return !!(mtrr_state.enabled &MTRR_STATE_MTRR_ENABLED ); }
arch/x86/kernel/cpu/mtrr/main.c +3 -0
@@ -752,6 +752,9 @@ void __init mtrr_bp_init(void)/* BIOS may override */ __mtrr_enabled =get_mtrr_state (); +if (mtrr_enabled ()) +mtrr_bp_pat_init (); +if (mtrr_cleanup (phys_addr)) { changed_by_mtrr_cleanup =1 ; mtrr_if->set_all ();
arch/x86/kernel/cpu/mtrr/mtrr.h +1 -0
@@ -52,6 +52,7 @@ void set_mtrr_prepare_save(struct set_mtvoid fill_mtrr_var_range (unsigned int index,u32 base_lo,u32 base_hi,u32 mask_lo,u32 mask_hi);bool get_mtrr_state (void ); +void mtrr_bp_pat_init (void );extern void set_mtrr_ops (const struct mtrr_ops *ops);
Greg Kroah-Hartman
maintainerPATCH 27/56 x86/mtrr: Fix PAT init handling when MTRR is disabled
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit ad025a73f0e9344ac73ffe1b74c184033e08e7d5 upstream.
get_mtrr_state() calls pat_init() on BSP even if MTRR is disabled. This results in calling pat_init() on BSP only since APs do not call pat_init() when MTRR is disabled. This inconsistency between BSP and APs leads to undefined behavior.
Make BSP's calling condition to pat_init() consistent with AP's, mtrr_ap_init() and mtrr_aps_init().
--- arch/x86/kernel/cpu/mtrr/generic.c | 24 ++++++++++++++---------- arch/x86/kernel/cpu/mtrr/main.c | 3 +++ arch/x86/kernel/cpu/mtrr/mtrr.h | 1 + 3 files changed, 18 insertions(+), 10 deletions(-)
arch/x86/kernel/cpu/mtrr/generic.c +14 -10
@@ -444,11 +444,24 @@ static void __init print_mtrr_state(voidpr_debug ("TOM2: %016llx aka %lldM\n" , mtrr_tom2, mtrr_tom2>>20 ); } +/* PAT setup for BP. We need to go through sync steps here */ +void __init mtrr_bp_pat_init (void ) +{ +unsigned long flags; + +local_irq_save (flags); +prepare_set (); + +pat_init (); + +post_set (); +local_irq_restore (flags); +} +/* Grab all of the MTRR state for this CPU into *state */ bool __init get_mtrr_state (void ) {struct mtrr_var_range *vrs; -unsigned long flags;unsigned lo, dummy;unsigned int i;
@@ -481,15 +494,6 @@ bool __init get_mtrr_state(void) mtrr_state_set =1 ; -/* PAT setup for BP. We need to go through sync steps here */ -local_irq_save (flags); -prepare_set (); - -pat_init (); - -post_set (); -local_irq_restore (flags); -return !!(mtrr_state.enabled &MTRR_STATE_MTRR_ENABLED ); }
arch/x86/kernel/cpu/mtrr/main.c +3 -0
@@ -752,6 +752,9 @@ void __init mtrr_bp_init(void)/* BIOS may override */ __mtrr_enabled =get_mtrr_state (); +if (mtrr_enabled ()) +mtrr_bp_pat_init (); +if (mtrr_cleanup (phys_addr)) { changed_by_mtrr_cleanup =1 ; mtrr_if->set_all ();
arch/x86/kernel/cpu/mtrr/mtrr.h +1 -0
@@ -52,6 +52,7 @@ void set_mtrr_prepare_save(struct set_mtvoid fill_mtrr_var_range (unsigned int index,u32 base_lo,u32 base_hi,u32 mask_lo,u32 mask_hi);bool get_mtrr_state (void ); +void mtrr_bp_pat_init (void );extern void set_mtrr_ops (const struct mtrr_ops *ops);
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Greg Kroah-Hartman
maintainerPATCH 28/56 x86/xen, pat: Remove PAT table init code from Xen
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit 88ba281108ed0c25c9d292b48bd3f272fcb90dd0 upstream.
Xen supports PAT without MTRRs for its guests. In order to enable WC attribute, it was necessary for xen_start_kernel() to call pat_init_cache_modes() to update PAT table before starting guest kernel.
Now that the kernel initializes PAT table to the BIOS handoff state when MTRR is disabled, this Xen-specific PAT init code is no longer necessary. Delete it from xen_start_kernel().
Also change __init_cache_modes() to a static function since PAT table should not be tweaked by other modules.
--- arch/x86/include/asm/pat.h | 1 - arch/x86/mm/pat.c | 2 +- arch/x86/xen/enlighten.c | 9 --------- 3 files changed, 1 insertion(+), 11 deletions(-)
arch/x86/include/asm/pat.h +0 -1
@@ -7,7 +7,6 @@bool pat_enabled (void );void pat_disable (const char *reason);extern void pat_init (void ); -void __init_cache_modes (u64 );extern int reserve_memtype (u64 start,u64 end,enum page_cache_mode req_pcm,enum page_cache_mode *ret_pcm);
arch/x86/mm/pat.c +1 -1
@@ -192,7 +192,7 @@ static enum page_cache_mode pat_get_cach* configuration. * Using lower indices is preferred, so we start with highest index. */ -void __init_cache_modes (u64 pat) +static void __init_cache_modes (u64 pat) {enum page_cache_mode cache;char pat_msg[33 ];
arch/x86/xen/enlighten.c +0 -9
@@ -75,7 +75,6 @@#include <asm/mach_traps.h> #include <asm/mwait.h> #include <asm/pci_x86.h> -#include <asm/pat.h> #include <asm/cpu.h> #ifdef CONFIG_ACPI
@@ -1511,7 +1510,6 @@ asmlinkage __visible void __init xen_sta {struct physdev_set_iopl set_iopl;unsigned long initrd_start =0 ; -u64 pat;int rc;if (!xen_start_info)
@@ -1618,13 +1616,6 @@ asmlinkage __visible void __init xen_sta xen_start_info->nr_pages);xen_reserve_special_pages (); -/* -* Modify the cache mode translation tables to match Xen's PAT -* configuration. -*/ -rdmsrl (MSR_IA32_CR_PAT , pat); -__init_cache_modes (pat); -/* keep using Xen gdt for now; no urgent need to change it */ #ifdef CONFIG_X86_32
Greg Kroah-Hartman
maintainerPATCH 28/56 x86/xen, pat: Remove PAT table init code from Xen
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit 88ba281108ed0c25c9d292b48bd3f272fcb90dd0 upstream.
Xen supports PAT without MTRRs for its guests. In order to enable WC attribute, it was necessary for xen_start_kernel() to call pat_init_cache_modes() to update PAT table before starting guest kernel.
Now that the kernel initializes PAT table to the BIOS handoff state when MTRR is disabled, this Xen-specific PAT init code is no longer necessary. Delete it from xen_start_kernel().
Also change __init_cache_modes() to a static function since PAT table should not be tweaked by other modules.
--- arch/x86/include/asm/pat.h | 1 - arch/x86/mm/pat.c | 2 +- arch/x86/xen/enlighten.c | 9 --------- 3 files changed, 1 insertion(+), 11 deletions(-)
arch/x86/include/asm/pat.h +0 -1
@@ -7,7 +7,6 @@bool pat_enabled (void );void pat_disable (const char *reason);extern void pat_init (void ); -void __init_cache_modes (u64 );extern int reserve_memtype (u64 start,u64 end,enum page_cache_mode req_pcm,enum page_cache_mode *ret_pcm);
arch/x86/mm/pat.c +1 -1
@@ -192,7 +192,7 @@ static enum page_cache_mode pat_get_cach* configuration. * Using lower indices is preferred, so we start with highest index. */ -void __init_cache_modes (u64 pat) +static void __init_cache_modes (u64 pat) {enum page_cache_mode cache;char pat_msg[33 ];
arch/x86/xen/enlighten.c +0 -9
@@ -75,7 +75,6 @@#include <asm/mach_traps.h> #include <asm/mwait.h> #include <asm/pci_x86.h> -#include <asm/pat.h> #include <asm/cpu.h> #ifdef CONFIG_ACPI
@@ -1511,7 +1510,6 @@ asmlinkage __visible void __init xen_sta {struct physdev_set_iopl set_iopl;unsigned long initrd_start =0 ; -u64 pat;int rc;if (!xen_start_info)
@@ -1618,13 +1616,6 @@ asmlinkage __visible void __init xen_sta xen_start_info->nr_pages);xen_reserve_special_pages (); -/* -* Modify the cache mode translation tables to match Xen's PAT -* configuration. -*/ -rdmsrl (MSR_IA32_CR_PAT , pat); -__init_cache_modes (pat); -/* keep using Xen gdt for now; no urgent need to change it */ #ifdef CONFIG_X86_32
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Greg Kroah-Hartman
maintainerPATCH 29/56 x86/pat: Document the PAT initialization sequence
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit b6350c21cfe8aa9d65e189509a23c0ea4b8362c2 upstream.
Update PAT documentation to describe how PAT is initialized under various configurations.
--- Documentation/x86/pat.txt | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
Documentation/x86/pat.txt +32 -0
@@ -196,3 +196,35 @@ Another, more verbose way of getting PAT "debugpat" boot parameter. With this parameter, various debug messages are printed to dmesg log. +PAT Initialization +------------------ + +The following table describes how PAT is initialized under various +configurations. The PAT MSR must be updated by Linux in order to support WC +and WT attributes. Otherwise, the PAT MSR has the value programmed in it +by the firmware. Note, Xen enables WC attribute in the PAT MSR for guests. + + MTRR PAT Call Sequence PAT State PAT MSR + ========================================================= + E E MTRR -> PAT init Enabled OS + E D MTRR -> PAT init Disabled - + D E MTRR -> PAT disable Disabled BIOS + D D MTRR -> PAT disable Disabled - + - np/E PAT -> PAT disable Disabled BIOS + - np/D PAT -> PAT disable Disabled - + E !P/E MTRR -> PAT init Disabled BIOS + D !P/E MTRR -> PAT disable Disabled BIOS + !M !P/E MTRR stub -> PAT disable Disabled BIOS + + Legend + ------------------------------------------------ + E Feature enabled in CPU + D Feature disabled/unsupported in CPU + np "nopat" boot option specified + !P CONFIG_X86_PAT option unset + !M CONFIG_MTRR option unset + Enabled PAT state set to enabled + Disabled PAT state set to disabled + OS PAT initializes PAT MSR with OS setting + BIOS PAT keeps PAT MSR with BIOS setting +
Greg Kroah-Hartman
maintainerPATCH 30/56 x86/mm/pat: Fix BUG_ON() in mmap_mem() on QEMU/i386
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit 1886297ce0c8d563a08c8a8c4c0b97743e06cd37 upstream.
The following BUG_ON() crash was reported on QEMU/i386:
kernel BUG at arch/x86/mm/physaddr.c:79!
Call Trace: phys_mem_access_prot_allowed mmap_mem ? mmap_region mmap_region do_mmap vm_mmap_pgoff SyS_mmap_pgoff do_int80_syscall_32 entry_INT80_32
after commit:
edfe63ec97ed ("x86/mtrr: Fix Xorg crashes in Qemu sessions")
PAT is now set to disabled state when MTRRs are disabled. Thus, reactivating the __pa(high_memory) check in phys_mem_access_prot_allowed().
When CONFIG_DEBUG_VIRTUAL is set, __pa() calls __phys_addr(), which in turn calls slow_virt_to_phys() for 'high_memory'. Because 'high_memory' is set to (the max direct mapped virt addr + 1), it is not a valid virtual address. Hence, slow_virt_to_phys() returns 0 and hit the BUG_ON. Using __pa_nodebug() instead of __pa() will fix this BUG_ON.
However, this code block, originally written for Pentiums and earlier, is no longer adequate since a 32-bit Xen guest has MTRRs disabled and supports ZONE_HIGHMEM. In this setup, this code sets UC attribute for accessing RAM in high memory range.
Delete this code block as it has been unused for a long time.
--- arch/x86/mm/pat.c | 19 ------------------- 1 file changed, 19 deletions(-)
arch/x86/mm/pat.c +0 -19
@@ -778,25 +778,6 @@ int phys_mem_access_prot_allowed(structif (file->f_flags &O_DSYNC ) pcm = _PAGE_CACHE_MODE_UC_MINUS; -#ifdef CONFIG_X86_32 -/* -* On the PPro and successors, the MTRRs are used to set -* memory types for physical addresses outside main memory, -* so blindly setting UC or PWT on those pages is wrong. -* For Pentiums and earlier, the surround logic should disable -* caching for the high addresses through the KEN pin, but -* we maintain the tradition of paranoia in this code. -*/ -if (!pat_enabled () && - !(boot_cpu_has (X86_FEATURE_MTRR ) || -boot_cpu_has (X86_FEATURE_K6_MTRR ) || -boot_cpu_has (X86_FEATURE_CYRIX_ARR ) || -boot_cpu_has (X86_FEATURE_CENTAUR_MCR )) && - (pfn <<PAGE_SHIFT ) >=__pa (high_memory)) { - pcm = _PAGE_CACHE_MODE_UC; - } -#endif - *vma_prot =__pgprot ((pgprot_val (*vma_prot) & ~_PAGE_CACHE_MASK) |cachemode2protval (pcm));return 1 ;
Greg Kroah-Hartman
maintainerPATCH 30/56 x86/mm/pat: Fix BUG_ON() in mmap_mem() on QEMU/i386
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toshi Kani <[email protected]>
commit 1886297ce0c8d563a08c8a8c4c0b97743e06cd37 upstream.
The following BUG_ON() crash was reported on QEMU/i386:
kernel BUG at arch/x86/mm/physaddr.c:79!
Call Trace: phys_mem_access_prot_allowed mmap_mem ? mmap_region mmap_region do_mmap vm_mmap_pgoff SyS_mmap_pgoff do_int80_syscall_32 entry_INT80_32
after commit:
edfe63ec97ed ("x86/mtrr: Fix Xorg crashes in Qemu sessions")
PAT is now set to disabled state when MTRRs are disabled. Thus, reactivating the __pa(high_memory) check in phys_mem_access_prot_allowed().
When CONFIG_DEBUG_VIRTUAL is set, __pa() calls __phys_addr(), which in turn calls slow_virt_to_phys() for 'high_memory'. Because 'high_memory' is set to (the max direct mapped virt addr + 1), it is not a valid virtual address. Hence, slow_virt_to_phys() returns 0 and hit the BUG_ON. Using __pa_nodebug() instead of __pa() will fix this BUG_ON.
However, this code block, originally written for Pentiums and earlier, is no longer adequate since a 32-bit Xen guest has MTRRs disabled and supports ZONE_HIGHMEM. In this setup, this code sets UC attribute for accessing RAM in high memory range.
Delete this code block as it has been unused for a long time.
--- arch/x86/mm/pat.c | 19 ------------------- 1 file changed, 19 deletions(-)
arch/x86/mm/pat.c +0 -19
@@ -778,25 +778,6 @@ int phys_mem_access_prot_allowed(structif (file->f_flags &O_DSYNC ) pcm = _PAGE_CACHE_MODE_UC_MINUS; -#ifdef CONFIG_X86_32 -/* -* On the PPro and successors, the MTRRs are used to set -* memory types for physical addresses outside main memory, -* so blindly setting UC or PWT on those pages is wrong. -* For Pentiums and earlier, the surround logic should disable -* caching for the high addresses through the KEN pin, but -* we maintain the tradition of paranoia in this code. -*/ -if (!pat_enabled () && - !(boot_cpu_has (X86_FEATURE_MTRR ) || -boot_cpu_has (X86_FEATURE_K6_MTRR ) || -boot_cpu_has (X86_FEATURE_CYRIX_ARR ) || -boot_cpu_has (X86_FEATURE_CENTAUR_MCR )) && - (pfn <<PAGE_SHIFT ) >=__pa (high_memory)) { - pcm = _PAGE_CACHE_MODE_UC; - } -#endif - *vma_prot =__pgprot ((pgprot_val (*vma_prot) & ~_PAGE_CACHE_MASK) |cachemode2protval (pcm));return 1 ;
_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xen.org/xen-devel
Greg Kroah-Hartman
maintainerPATCH 31/56 udf: Prevent stack overflow on corrupted filesystem mount
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alden Tondettar <[email protected]>
commit a47241cdeee2689ee7089ec95cadfcf66588fbdb upstream.
Presently, a corrupted or malicious UDF filesystem containing a very large number (or cycle) of Logical Volume Integrity Descriptor extent indirections may trigger a stack overflow and kernel panic in udf_load_logicalvolint() on mount.
Replace the unnecessary recursion in udf_load_logicalvolint() with simple iteration. Set an arbitrary limit of 1000 indirections (which would have almost certainly overflowed the stack without this fix), and treat such cases as if there were no LVID.
--- fs/udf/super.c | 69 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 25 deletions(-)
fs/udf/super.c +44 -25
@@ -78,6 +78,15 @@#define VSD_FIRST_SECTOR_OFFSET 32768#define VSD_MAX_SECTOR_OFFSET 0x800000 +/* +* Maximum number of Terminating Descriptor / Logical Volume Integrity +* Descriptor redirections. The chosen numbers are arbitrary - just that we +* hopefully don't limit any real use of rewritten inode on write-once media +* but avoid looping for too long on corrupted media. +*/ +#define UDF_MAX_TD_NESTING 64 +#define UDF_MAX_LVID_NESTING 1000 +enum {UDF_MAX_LINKS =0xffff };/* These are the "meat" - everything else is stuffing */
@@ -1541,42 +1550,52 @@ out_bh: }/* -* udf_load_logicalvolint -* +* Find the prevailing Logical Volume Integrity Descriptor. */ static void udf_load_logicalvolint (struct super_block *sb,struct kernel_extent_ad loc) { -struct buffer_head *bh =NULL ; +struct buffer_head *bh, *final_bh;uint16_t ident;struct udf_sb_info *sbi =UDF_SB (sb);struct logicalVolIntegrityDesc *lvid; +int indirections =0 ; -while (loc.extLength >0 && - (bh =udf_read_tagged (sb, loc.extLocation, - loc.extLocation, &ident)) && - ident ==TAG_IDENT_LVID ) { - sbi->s_lvid_bh = bh; - lvid = (struct logicalVolIntegrityDesc *)bh->b_data; - -if (lvid->nextIntegrityExt.extLength) -udf_load_logicalvolint (sb, -leea_to_cpu (lvid->nextIntegrityExt)); +while (++indirections <=UDF_MAX_LVID_NESTING ) { + final_bh =NULL ; +while (loc.extLength >0 && + (bh =udf_read_tagged (sb, loc.extLocation, + loc.extLocation, &ident))) { +if (ident !=TAG_IDENT_LVID ) { +brelse (bh); +break ; + } -if (sbi->s_lvid_bh != bh) -brelse (bh); - loc.extLength -= sb->s_blocksize; - loc.extLocation++; +brelse (final_bh); + final_bh = bh; + + loc.extLength -= sb->s_blocksize; + loc.extLocation++; + } + +if (!final_bh) +return ; + +brelse (sbi->s_lvid_bh); + sbi->s_lvid_bh = final_bh; + + lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data; +if (lvid->nextIntegrityExt.extLength ==0 ) +return ; + + loc =leea_to_cpu (lvid->nextIntegrityExt); } -if (sbi->s_lvid_bh != bh) -brelse (bh); + +udf_warn (sb,"Too many LVID indirections (max %u), ignoring.\n" , +UDF_MAX_LVID_NESTING ); +brelse (sbi->s_lvid_bh); + sbi->s_lvid_bh =NULL ; } -/* -* Maximum number of Terminating Descriptor redirections. The chosen number is -* arbitrary - just that we hopefully don't limit any real use of rewritten -* inode on write-once media but avoid looping for too long on corrupted media. -*/ -#define UDF_MAX_TD_NESTING 64/* * Process a main/reserve volume descriptor sequence.
Greg Kroah-Hartman
maintainerPATCH 32/56 powerpc/eeh: Fix invalid cached PE primary bus
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gavin Shan <[email protected]>
commit a3aa256b7258b3d19f8b44557cc64525a993b941 upstream.
The PE primary bus cannot be got from its child devices when having full hotplug in error recovery. The PE primary bus is cached, which is done in commit <05ba75f84864> ("powerpc/eeh: Fix stale cached primary bus"). In eeh_reset_device(), the flag (EEH_PE_PRI_BUS) is cleared before the PCI hot remove. eeh_pe_bus_get() then returns NULL as the PE primary bus in pnv_eeh_reset() and it crashes the kernel eventually.
This fixes the issue by clearing the flag (EEH_PE_PRI_BUS) before the PCI hot add. With it, the PowerNV EEH reset backend (pnv_eeh_reset()) can get valid PE primary bus through eeh_pe_bus_get().
--- arch/powerpc/kernel/eeh_driver.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
arch/powerpc/kernel/eeh_driver.c +4 -3
@@ -648,7 +648,6 @@ static int eeh_reset_device(struct eeh_pif (pe->type &EEH_PE_VF ) {eeh_pe_dev_traverse (pe, eeh_rmv_device,NULL ); }else { -eeh_pe_state_clear (pe,EEH_PE_PRI_BUS );pci_lock_rescan_remove ();pcibios_remove_pci_devices (bus);pci_unlock_rescan_remove ();
@@ -698,10 +697,12 @@ static int eeh_reset_device(struct eeh_p*/ edev = list_first_entry(&pe->edevs, struct eeh_dev, list);eeh_pe_traverse (pe, eeh_pe_detach_dev,NULL ); -if (pe->type &EEH_PE_VF ) +if (pe->type &EEH_PE_VF ) {eeh_add_virt_device (edev,NULL ); -else + }else { +eeh_pe_state_clear (pe,EEH_PE_PRI_BUS );pcibios_add_pci_devices (bus); + } }else if (frozen_bus && rmv_data->removed) {pr_info ("EEH: Sleep 5s ahead of partial hotplug\n" );ssleep (5 );
Greg Kroah-Hartman
maintainerPATCH 33/56 powerpc/bpf/jit: Disable classic BPF JIT on ppc64le
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naveen N. Rao <[email protected]>
commit 844e3be47693f92a108cb1fb3b0606bf25e9c7a6 upstream.
Classic BPF JIT was never ported completely to work on little endian powerpc. However, it can be enabled and will crash the system when used. As such, disable use of BPF JIT on ppc64le.
--- arch/powerpc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/Kconfig +1 -1
@@ -126,7 +126,7 @@ config PPC select IRQ_FORCED_THREADING select HAVE_RCU_TABLE_FREE if SMP select HAVE_SYSCALL_TRACEPOINTS - select HAVE_BPF_JIT + select HAVE_BPF_JIT if CPU_BIG_ENDIAN select HAVE_ARCH_JUMP_LABEL select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_HAS_GCOV_PROFILE_ALL
Greg Kroah-Hartman
maintainerPATCH 34/56 mm: memcontrol: fix swap counter leak on swapout from offline cgroup
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Davydov <[email protected]>
commit 1f47b61fb4077936465dcde872a4e5cc4fe708da upstream.
An offline memory cgroup might have anonymous memory or shmem left charged to it and no swap. Since only swap entries pin the id of an offline cgroup, such a cgroup will have no id and so an attempt to swapout its anon/shmem will not store memory cgroup info in the swap cgroup map. As a result, memcg->swap or memcg->memsw will never get uncharged from it and any of its ascendants.
Fix this by always charging swapout to the first ancestor cgroup that hasn't released its id yet.
--- mm/memcontrol.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-)
mm/memcontrol.c +38 -6
@@ -4069,6 +4069,24 @@ static void mem_cgroup_id_get(struct mematomic_inc (&memcg->id.ref); } +static struct mem_cgroup *mem_cgroup_id_get_online (struct mem_cgroup *memcg) +{ +while (!atomic_inc_not_zero (&memcg->id.ref)) { +/* +* The root cgroup cannot be destroyed, so it's refcount must +* always be >= 1. +*/ +if (WARN_ON_ONCE (memcg == root_mem_cgroup)) { +VM_BUG_ON (1 ); +break ; + } + memcg =parent_mem_cgroup (memcg); +if (!memcg) + memcg = root_mem_cgroup; + } +return memcg; +} +static void mem_cgroup_id_put (struct mem_cgroup *memcg) {if (atomic_dec_and_test (&memcg->id.ref)) {
@@ -5785,7 +5803,7 @@ subsys_initcall(mem_cgroup_init);*/ void mem_cgroup_swapout (struct page *page,swp_entry_t entry) { -struct mem_cgroup *memcg; +struct mem_cgroup *memcg, *swap_memcg;unsigned short oldid;VM_BUG_ON_PAGE (PageLRU (page), page);
@@ -5800,16 +5818,27 @@ void mem_cgroup_swapout(struct page *pagif (!memcg)return ; -mem_cgroup_id_get (memcg); - oldid =swap_cgroup_record (entry,mem_cgroup_id (memcg)); +/* +* In case the memcg owning these pages has been offlined and doesn't +* have an ID allocated to it anymore, charge the closest online +* ancestor for the swap instead and transfer the memory+swap charge. +*/ + swap_memcg =mem_cgroup_id_get_online (memcg); + oldid =swap_cgroup_record (entry,mem_cgroup_id (swap_memcg));VM_BUG_ON_PAGE (oldid, page); -mem_cgroup_swap_statistics (memcg, true); +mem_cgroup_swap_statistics (swap_memcg, true); page->mem_cgroup =NULL ;if (!mem_cgroup_is_root (memcg))page_counter_uncharge (&memcg->memory,1 ); +if (memcg != swap_memcg) { +if (!mem_cgroup_is_root (swap_memcg)) +page_counter_charge (&swap_memcg->memsw,1 ); +page_counter_uncharge (&memcg->memsw,1 ); + } +/* * Interrupts should be disabled here because the caller holds the * mapping->tree_lock lock which is taken with interrupts-off. It is
@@ -5848,11 +5877,14 @@ int mem_cgroup_try_charge_swap(struct paif (!memcg)return 0 ; + memcg =mem_cgroup_id_get_online (memcg); +if (!mem_cgroup_is_root (memcg) && - !page_counter_try_charge (&memcg->swap,1 , &counter)) + !page_counter_try_charge (&memcg->swap,1 , &counter)) { +mem_cgroup_id_put (memcg);return -ENOMEM ; + } -mem_cgroup_id_get (memcg); oldid =swap_cgroup_record (entry,mem_cgroup_id (memcg));VM_BUG_ON_PAGE (oldid, page);mem_cgroup_swap_statistics (memcg, true);
Greg Kroah-Hartman
maintainerPATCH 35/56 mm: memcontrol: fix memcg id ref counter on swap charge move
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Davydov <[email protected]>
commit 615d66c37c755c49ce022c9e5ac0875d27d2603d upstream.
Since commit 73f576c04b94 ("mm: memcontrol: fix cgroup creation failure after many small jobs") swap entries do not pin memcg->css.refcnt directly. Instead, they pin memcg->id.ref. So we should adjust the reference counters accordingly when moving swap charges between cgroups.
--- mm/memcontrol.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
mm/memcontrol.c +18 -6
@@ -4064,9 +4064,9 @@ static struct cftype mem_cgroup_legacy_fstatic DEFINE_IDR (mem_cgroup_idr); -static void mem_cgroup_id_get (struct mem_cgroup *memcg) +static void mem_cgroup_id_get_many (struct mem_cgroup *memcg,unsigned int n) { -atomic_inc (&memcg->id.ref); +atomic_add (n, &memcg->id.ref); }static struct mem_cgroup *mem_cgroup_id_get_online (struct mem_cgroup *memcg)
@@ -4087,9 +4087,9 @@ static struct mem_cgroup *mem_cgroup_id_return memcg; } -static void mem_cgroup_id_put (struct mem_cgroup *memcg) +static void mem_cgroup_id_put_many (struct mem_cgroup *memcg,unsigned int n) { -if (atomic_dec_and_test (&memcg->id.ref)) { +if (atomic_sub_and_test (n, &memcg->id.ref)) {idr_remove (&mem_cgroup_idr, memcg->id.id); memcg->id.id =0 ;
@@ -4098,6 +4098,16 @@ static void mem_cgroup_id_put(struct mem } } +static inline void mem_cgroup_id_get (struct mem_cgroup *memcg) +{ +mem_cgroup_id_get_many (memcg,1 ); +} + +static inline void mem_cgroup_id_put (struct mem_cgroup *memcg) +{ +mem_cgroup_id_put_many (memcg,1 ); +} +/** * mem_cgroup_from_id - look up a memcg from a memcg id * @id: the memcg id to look up
@@ -4734,6 +4744,8 @@ static void __mem_cgroup_clear_mc(void)if (!mem_cgroup_is_root (mc.from))page_counter_uncharge (&mc.from->memsw, mc.moved_swap); +mem_cgroup_id_put_many (mc.from, mc.moved_swap); +/* * we charged both to->memory and to->memsw, so we * should uncharge to->memory.
@@ -4741,9 +4753,9 @@ static void __mem_cgroup_clear_mc(void)if (!mem_cgroup_is_root (mc.to))page_counter_uncharge (&mc.to->memory, mc.moved_swap); -css_put_many (&mc.from->css, mc.moved_swap); +mem_cgroup_id_get_many (mc.to, mc.moved_swap); +css_put_many (&mc.to->css, mc.moved_swap); -/* we've already done css_get(mc.to) */ mc.moved_swap =0 ; }memcg_oom_recover (from);
Greg Kroah-Hartman
maintainerPATCH 36/56 x86/syscalls/64: Add compat_sys_keyctl for 32-bit userspace
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit f7d665627e103e82d34306c7d3f6f46f387c0d8b upstream.
x86_64 needs to use compat_sys_keyctl for 32-bit userspace rather than calling sys_keyctl(). The latter will work in a lot of cases, thereby hiding the issue.
--- arch/x86/entry/syscalls/syscall_32.tbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/entry/syscalls/syscall_32.tbl +1 -1
@@ -294,7 +294,7 @@ # 285 sys_setaltroot 286 i386 add_key sys_add_key 287 i386 request_key sys_request_key -288 i386 keyctl sys_keyctl +288 i386 keyctl sys_keyctl compat_sys_keyctl 289 i386 ioprio_set sys_ioprio_set 290 i386 ioprio_get sys_ioprio_get 291 i386 inotify_init sys_inotify_init
Greg Kroah-Hartman
maintainerPATCH 37/56 block: fix use-after-free in seq file
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vegard Nossum <[email protected]>
commit 77da160530dd1dc94f6ae15a981f24e5f0021e84 upstream.
I got a KASAN report of use-after-free:
==================================================================
BUG: KASAN: use-after-free in klist_iter_exit+0x61/0x70 at addr ffff8800b6581508
Read of size 8 by task trinity-c1/315
=============================================================================
BUG kmalloc-32 (Not tainted): kasan: bad access detected
-----------------------------------------------------------------------------
Disabling lock debugging due to kernel taint
INFO: Allocated in disk_seqf_start+0x66/0x110 age=144 cpu=1 pid=315
___slab_alloc+0x4f1/0x520
__slab_alloc.isra.58+0x56/0x80
kmem_cache_alloc_trace+0x260/0x2a0
disk_seqf_start+0x66/0x110
traverse+0x176/0x860
seq_read+0x7e3/0x11a0
proc_reg_read+0xbc/0x180
do_loop_readv_writev+0x134/0x210
do_readv_writev+0x565/0x660
vfs_readv+0x67/0xa0
do_preadv+0x126/0x170
SyS_preadv+0xc/0x10
do_syscall_64+0x1a1/0x460
return_from_SYSCALL_64+0x0/0x6a
INFO: Freed in disk_seqf_stop+0x42/0x50 age=160 cpu=1 pid=315
__slab_free+0x17a/0x2c0
kfree+0x20a/0x220
disk_seqf_stop+0x42/0x50
traverse+0x3b5/0x860
seq_read+0x7e3/0x11a0
proc_reg_read+0xbc/0x180
do_loop_readv_writev+0x134/0x210
do_readv_writev+0x565/0x660
vfs_readv+0x67/0xa0
do_preadv+0x126/0x170
SyS_preadv+0xc/0x10
do_syscall_64+0x1a1/0x460
return_from_SYSCALL_64+0x0/0x6a
CPU: 1 PID: 315 Comm: trinity-c1 Tainted: G B 4.7.0+ #62
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
ffffea0002d96000 ffff880119b9f918 ffffffff81d6ce81 ffff88011a804480
ffff8800b6581500 ffff880119b9f948 ffffffff8146c7bd ffff88011a804480
ffffea0002d96000 ffff8800b6581500 fffffffffffffff4 ffff880119b9f970
Call Trace:
[<ffffffff81d6ce81>] dump_stack+0x65/0x84
[<ffffffff8146c7bd>] print_trailer+0x10d/0x1a0
[<ffffffff814704ff>] object_err+0x2f/0x40
[<ffffffff814754d1>] kasan_report_error+0x221/0x520
[<ffffffff8147590e>] __asan_report_load8_noabort+0x3e/0x40
[<ffffffff83888161>] klist_iter_exit+0x61/0x70
[<ffffffff82404389>] class_dev_iter_exit+0x9/0x10
[<ffffffff81d2e8ea>] disk_seqf_stop+0x3a/0x50
[<ffffffff8151f812>] seq_read+0x4b2/0x11a0
[<ffffffff815f8fdc>] proc_reg_read+0xbc/0x180
[<ffffffff814b24e4>] do_loop_readv_writev+0x134/0x210
[<ffffffff814b4c45>] do_readv_writev+0x565/0x660
[<ffffffff814b8a17>] vfs_readv+0x67/0xa0
[<ffffffff814b8de6>] do_preadv+0x126/0x170
[<ffffffff814b92ec>] SyS_preadv+0xc/0x10This problem can occur in the following situation:
open()
- pread()
- .seq_start()
- iter = kmalloc() // succeeds
- seqf->private = iter
- .seq_stop()
- kfree(seqf->private)
- pread()
- .seq_start()
- iter = kmalloc() // fails
- .seq_stop()
- class_dev_iter_exit(seqf->private) // boom! old pointer
As the comment in disk_seqf_stop() says, stop is called even if start failed, so we need to reinitialise the private pointer to NULL when seq iteration stops.
An alternative would be to set the private pointer to NULL when the kmalloc() in disk_seqf_start() fails.
--- block/genhd.c | 1 + 1 file changed, 1 insertion(+)
block/genhd.c +1 -0
@@ -856,6 +856,7 @@ static void disk_seqf_stop(struct seq_fiif (iter) {class_dev_iter_exit (iter);kfree (iter); + seqf->private =NULL ; } }
Greg Kroah-Hartman
maintainerPATCH 38/56 sysv, ipc: fix security-layer leaking
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabian Frederick <[email protected]>
commit 9b24fef9f0410fb5364245d6cc2bd044cc064007 upstream.
Commit 53dad6d3a8e5 ("ipc: fix race with LSMs") updated ipc_rcu_putref() to receive rcu freeing function but used generic ipc_rcu_free() instead of msg_rcu_free() which does security cleaning.
Running LTP msgsnd06 with kmemleak gives the following:
cat /sys/kernel/debug/kmemleak
unreferenced object 0xffff88003c0a11f8 (size 8):
comm "msgsnd06", pid 1645, jiffies 4294672526 (age 6.549s)
hex dump (first 8 bytes):
1b 00 00 00 01 00 00 00 ........
backtrace:
kmemleak_alloc+0x23/0x40
kmem_cache_alloc_trace+0xe1/0x180
selinux_msg_queue_alloc_security+0x3f/0xd0
security_msg_queue_alloc+0x2e/0x40
newque+0x4e/0x150
ipcget+0x159/0x1b0
SyS_msgget+0x39/0x40
entry_SYSCALL_64_fastpath+0x13/0x8fManfred Spraul suggested to fix sem.c as well and Davidlohr Bueso to only use ipc_rcu_free in case of security allocation failure in newary()
--- ipc/msg.c | 2 +- ipc/sem.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
ipc/msg.c +1 -1
@@ -680,7 +680,7 @@ long do_msgsnd(int msqid, long mtype, vorcu_read_lock ();ipc_lock_object (&msq->q_perm); -ipc_rcu_putref (msq, ipc_rcu_free); +ipc_rcu_putref (msq, msg_rcu_free);/* raced with RMID? */ if (!ipc_valid_object (&msq->q_perm)) { err = -EIDRM ;
ipc/sem.c +6 -6
@@ -449,7 +449,7 @@ static inline struct sem_array *sem_obtastatic inline void sem_lock_and_putref (struct sem_array *sma) {sem_lock (sma,NULL ,-1 ); -ipc_rcu_putref (sma, ipc_rcu_free); +ipc_rcu_putref (sma, sem_rcu_free); }static inline void sem_rmid (struct ipc_namespace *ns,struct sem_array *s)
@@ -1392,7 +1392,7 @@ static int semctl_main(struct ipc_namesprcu_read_unlock (); sem_io =ipc_alloc (sizeof (ushort)*nsems);if (sem_io ==NULL ) { -ipc_rcu_putref (sma, ipc_rcu_free); +ipc_rcu_putref (sma, sem_rcu_free);return -ENOMEM ; }
@@ -1426,20 +1426,20 @@ static int semctl_main(struct ipc_namespif (nsems >SEMMSL_FAST ) { sem_io =ipc_alloc (sizeof (ushort)*nsems);if (sem_io ==NULL ) { -ipc_rcu_putref (sma, ipc_rcu_free); +ipc_rcu_putref (sma, sem_rcu_free);return -ENOMEM ; } }if (copy_from_user (sem_io, p, nsems*sizeof (ushort))) { -ipc_rcu_putref (sma, ipc_rcu_free); +ipc_rcu_putref (sma, sem_rcu_free); err = -EFAULT ; goto out_free; }for (i =0 ; i < nsems; i++) {if (sem_io[i] >SEMVMX ) { -ipc_rcu_putref (sma, ipc_rcu_free); +ipc_rcu_putref (sma, sem_rcu_free); err = -ERANGE ; goto out_free; }
@@ -1731,7 +1731,7 @@ static struct sem_undo *find_alloc_undo(/* step 2: allocate new undo structure */ new =kzalloc (sizeof (struct sem_undo ) +sizeof (short )*nsems,GFP_KERNEL );if (!new) { -ipc_rcu_putref (sma, ipc_rcu_free); +ipc_rcu_putref (sma, sem_rcu_free);return ERR_PTR (-ENOMEM ); }
Greg Kroah-Hartman
maintainerPATCH 39/56 radix-tree: account nodes to memcg only if explicitly requested
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Davydov <[email protected]>
commit 05eb6e7263185a6bb0de9501ccf2addc52429414 upstream.
Radix trees may be used not only for storing page cache pages, so unconditionally accounting radix tree nodes to the current memory cgroup is bad: if a radix tree node is used for storing data shared among different cgroups we risk pinning dead memory cgroups forever.
So let's only account radix tree nodes if it was explicitly requested by passing __GFP_ACCOUNT to INIT_RADIX_TREE. Currently, we only want to account page cache entries, so mark mapping->page_tree so.
--- fs/inode.c | 2 +- lib/radix-tree.c | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-)
fs/inode.c +1 -1
@@ -344,7 +344,7 @@ EXPORT_SYMBOL(inc_nlink);void address_space_init_once (struct address_space *mapping) {memset (mapping,0 ,sizeof (*mapping)); -INIT_RADIX_TREE (&mapping->page_tree,GFP_ATOMIC ); +INIT_RADIX_TREE (&mapping->page_tree,GFP_ATOMIC | __GFP_ACCOUNT);spin_lock_init (&mapping->tree_lock);init_rwsem (&mapping->i_mmap_rwsem);INIT_LIST_HEAD (&mapping->private_list);
lib/radix-tree.c +10 -4
@@ -228,10 +228,11 @@ radix_tree_node_alloc(struct radix_tree_/* * Even if the caller has preloaded, try to allocate from the -* cache first for the new node to get accounted. +* cache first for the new node to get accounted to the memory +* cgroup. */ ret =kmem_cache_alloc (radix_tree_node_cachep, - gfp_mask | __GFP_ACCOUNT | __GFP_NOWARN); + gfp_mask | __GFP_NOWARN);if (ret) goto out;
@@ -254,8 +255,7 @@ radix_tree_node_alloc(struct radix_tree_kmemleak_update_trace (ret); goto out; } - ret =kmem_cache_alloc (radix_tree_node_cachep, - gfp_mask | __GFP_ACCOUNT); + ret =kmem_cache_alloc (radix_tree_node_cachep, gfp_mask); out:BUG_ON (radix_tree_is_indirect_ptr (ret));return ret;
@@ -302,6 +302,12 @@ static int __radix_tree_preload(gfp_t gfstruct radix_tree_node *node;int ret = -ENOMEM ; +/* +* Nodes preloaded by one cgroup can be be used by another cgroup, so +* they should never be accounted to any particular memory cgroup. +*/ + gfp_mask &= ~__GFP_ACCOUNT; +preempt_disable (); rtp =this_cpu_ptr (&radix_tree_preloads);while (rtp->nr <RADIX_TREE_PRELOAD_SIZE ) {
Greg Kroah-Hartman
maintainerPATCH 40/56 x86/microcode: Fix suspend to RAM with builtin microcode
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Borislav Petkov <[email protected]>
commit 4b703305d98bf7350d4b2953ee39a3aa2eeb1778 upstream.
Usually, after we have found the proper microcode blob for the current machine, we stash it away for later use with save_microcode_in_initrd().
However, with builtin microcode which doesn't come from the initrd, we don't call that function because CONFIG_BLK_DEV_INITRD=n and even if set, we don't have a valid initrd.
In order to fix this, let's make save_microcode_in_initrd() an fs_initcall which runs before rootfs_initcall() as this was the time it was called previously through:
rootfs_initcall(populate_rootfs)
|-> free_initrd()
|-> free_initrd_mem()
|-> save_microcode_in_initrd()Also, we make it run independently from initrd functionality being present or not.
And since it is called in the microcode loader only now, we can also make it static.
--- arch/x86/include/asm/microcode.h | 2 -- arch/x86/kernel/cpu/microcode/core.c | 3 ++- arch/x86/mm/init.c | 7 ------- 3 files changed, 2 insertions(+), 10 deletions(-)
arch/x86/include/asm/microcode.h +0 -2
@@ -133,13 +133,11 @@ static inline unsigned int x86_cpuid_fam#ifdef CONFIG_MICROCODE extern void __init load_ucode_bsp (void );extern void load_ucode_ap (void ); -extern int __init save_microcode_in_initrd (void );void reload_early_microcode (void );extern bool get_builtin_firmware (struct cpio_data *cd,const char *name);#else static inline void __init load_ucode_bsp (void ) { }static inline void load_ucode_ap (void ) { } -static inline int __init save_microcode_in_initrd (void ) {return 0 ; }static inline void reload_early_microcode (void ) { }static inline bool get_builtin_firmware (struct cpio_data *cd,const char *name) {return false; }
arch/x86/kernel/cpu/microcode/core.c +2 -1
@@ -175,7 +175,7 @@ void load_ucode_ap(void) } } -int __init save_microcode_in_initrd (void ) +static int __init save_microcode_in_initrd (void ) {struct cpuinfo_x86 *c = &boot_cpu_data;
@@ -691,4 +691,5 @@ int __init microcode_init(void)return error; } +fs_initcall (save_microcode_in_initrd);late_initcall (microcode_init);
arch/x86/mm/init.c +0 -7
@@ -696,13 +696,6 @@ void free_initmem(void)void __init free_initrd_mem (unsigned long start,unsigned long end) {/* -* Remember, initrd memory may contain microcode or other useful things. -* Before we lose initrd mem, we need to find a place to hold them -* now that normal virtual memory is enabled. -*/ -save_microcode_in_initrd (); - -/* * end could be not aligned, and We can not align that, * decompresser could be confused by aligned initrd_end * We already reserve the end partial page before in
Greg Kroah-Hartman
maintainerPATCH 41/56 x86/power/64: Fix hibernation return address corruption
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf <[email protected]>
commit 4ce827b4cc58bec7952591b96cce2b28553e4d5b upstream.
In kernel bug 150021, a kernel panic was reported when restoring a hibernate image. Only a picture of the oops was reported, so I can't paste the whole thing here. But here are the most interesting parts:
kernel tried to execute NX-protected page - exploit attempt? (uid: 0)
BUG: unable to handle kernel paging request at ffff8804615cfd78 ... RIP: ffff8804615cfd78 RSP: ffff8804615f0000 RBP: ffff8804615cfdc0 ... Call Trace: do_signal+0x23 exit_to_usermode_loop+0x64 ...
The RIP is on the same page as RBP, so it apparently started executing on the stack.
The bug was bisected to commit ef0f3ed5a4ac (x86/asm/power: Create stack frames in hibernate_asm_64.S), which in retrospect seems quite dangerous, since that code saves and restores the stack pointer from a global variable ('saved_context').
There are a lot of moving parts in the hibernate save and restore paths, so I don't know exactly what caused the panic. Presumably, a FRAME_END was executed without the corresponding FRAME_BEGIN, or vice versa. That would corrupt the return address on the stack and would be consistent with the details of the above panic.
[ rjw: One major problem is that by the time the FRAME_BEGIN in
restore_registers() is executed, the stack pointer value may not be valid any more. Namely, the stack area pointed to by it previously may have been overwritten by some image memory contents and that page frame may now be used for whatever different purpose it had been allocated for before hibernation. In that case, the FRAME_BEGIN will corrupt that memory. ]
Instead of doing the frame pointer save/restore around the bounds of the affected functions, just do it around the call to swsusp_save().
That has the same effect of ensuring that if swsusp_save() sleeps, the frame pointers will be correct. It's also a much more obviously safe way to do it than the original patch. And objtool still doesn't report any warnings.
--- arch/x86/power/hibernate_asm_64.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
arch/x86/power/hibernate_asm_64.S +1 -3
@@ -24,7 +24,6 @@ #include <asm/frame.h> ENTRY(swsusp_arch_suspend) - FRAME_BEGIN movq $saved_context, %rax movq %rsp, pt_regs_sp(%rax) movq %rbp, pt_regs_bp(%rax)
@@ -51,6 +50,7 @@ ENTRY(swsusp_arch_suspend) movq %cr3, %rax movq %rax, restore_cr3(%rip) + FRAME_BEGIN call swsusp_save FRAME_END ret
@@ -111,7 +111,6 @@ ENTRY(core_restore_code) */ ENTRY(restore_registers) - FRAME_BEGIN /* go back to the original page tables */ movq %rbx, %cr3
@@ -152,6 +151,5 @@ ENTRY(restore_registers) /* tell the hibernation core that we've just restored the memory */ movq %rax, in_suspend(%rip) - FRAME_END ret ENDPROC(restore_registers)
Greg Kroah-Hartman
maintainerPATCH 42/56 fuse: fsync() did not return IO errors
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Kuznetsov <[email protected]>
commit ac7f052b9e1534c8248f814b6f0068ad8d4a06d2 upstream.
Due to implementation of fuse writeback filemap_write_and_wait_range() does not catch errors. We have to do this directly after fuse_sync_writes()
--- fs/fuse/file.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
fs/fuse/file.c +15 -0
@@ -462,6 +462,21 @@ int fuse_fsync_common(struct file *file, goto out;fuse_sync_writes (inode); + +/* +* Due to implementation of fuse writeback +* filemap_write_and_wait_range() does not catch errors. +* We have to do this directly after fuse_sync_writes() +*/ +if (test_bit (AS_ENOSPC , &file->f_mapping->flags) && +test_and_clear_bit (AS_ENOSPC , &file->f_mapping->flags)) + err = -ENOSPC ; +if (test_bit (AS_EIO , &file->f_mapping->flags) && +test_and_clear_bit (AS_EIO , &file->f_mapping->flags)) + err = -EIO ; +if (err) + goto out; + err =sync_inode_metadata (inode,1 );if (err) goto out;
Greg Kroah-Hartman
maintainerPATCH 43/56 fuse: fuse_flush must check mapping->flags for errors
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxim Patlasov <[email protected]>
commit 9ebce595f63a407c5cec98f98f9da8459b73740a upstream.
fuse_flush() calls write_inode_now() that triggers writeback, but actual writeback will happen later, on fuse_sync_writes(). If an error happens, fuse_writepage_end() will set error bit in mapping->flags. So, we have to check mapping->flags after fuse_sync_writes().
--- fs/fuse/file.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/fuse/file.c +9 -0
@@ -417,6 +417,15 @@ static int fuse_flush(struct file *file,fuse_sync_writes (inode);inode_unlock (inode); +if (test_bit (AS_ENOSPC , &file->f_mapping->flags) && +test_and_clear_bit (AS_ENOSPC , &file->f_mapping->flags)) + err = -ENOSPC ; +if (test_bit (AS_EIO , &file->f_mapping->flags) && +test_and_clear_bit (AS_EIO , &file->f_mapping->flags)) + err = -EIO ; +if (err) +return err; + req =fuse_get_req_nofail_nopages (fc, file);memset (&inarg,0 ,sizeof (inarg)); inarg.fh = ff->fh;
Greg Kroah-Hartman
maintainerPATCH 44/56 fuse: fix wrong assignment of ->flags in fuse_send_init()
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Fang <[email protected]>
commit 9446385f05c9af25fed53dbed3cc75763730be52 upstream.
FUSE_HAS_IOCTL_DIR should be assigned to ->flags, it may be a typo.
--- fs/fuse/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/fuse/inode.c +1 -1
@@ -926,7 +926,7 @@ static void fuse_send_init(struct fuse_c arg->flags |=FUSE_ASYNC_READ |FUSE_POSIX_LOCKS |FUSE_ATOMIC_O_TRUNC |FUSE_EXPORT_SUPPORT |FUSE_BIG_WRITES |FUSE_DONT_MASK |FUSE_SPLICE_WRITE |FUSE_SPLICE_MOVE |FUSE_SPLICE_READ | -FUSE_FLOCK_LOCKS |FUSE_IOCTL_DIR |FUSE_AUTO_INVAL_DATA | +FUSE_FLOCK_LOCKS |FUSE_HAS_IOCTL_DIR |FUSE_AUTO_INVAL_DATA |FUSE_DO_READDIRPLUS |FUSE_READDIRPLUS_AUTO |FUSE_ASYNC_DIO |FUSE_WRITEBACK_CACHE |FUSE_NO_OPEN_SUPPORT ; req->in.h.opcode =FUSE_INIT ;
Greg Kroah-Hartman
maintainerPATCH 45/56 Revert "mm, mempool: only set __GFP_NOMEMALLOC if there are free elements"
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Hocko <[email protected]>
commit 4e390b2b2f34b8daaabf2df1df0cf8f798b87ddb upstream.
This reverts commit f9054c70d28b ("mm, mempool: only set __GFP_NOMEMALLOC if there are free elements").
There has been a report about OOM killer invoked when swapping out to a dm-crypt device. The primary reason seems to be that the swapout out IO managed to completely deplete memory reserves. Ondrej was able to bisect and explained the issue by pointing to f9054c70d28b ("mm,
mempool: only set __GFP_NOMEMALLOC if there are free elements").
The reason is that the swapout path is not throttled properly because the md-raid layer needs to allocate from the generic_make_request path which means it allocates from the PF_MEMALLOC context. dm layer uses mempool_alloc in order to guarantee a forward progress which used to inhibit access to memory reserves when using page allocator. This has changed by f9054c70d28b ("mm, mempool: only set __GFP_NOMEMALLOC if there are free elements") which has dropped the __GFP_NOMEMALLOC protection when the memory pool is depleted.
If we are running out of memory and the only way forward to free memory is to perform swapout we just keep consuming memory reserves rather than throttling the mempool allocations and allowing the pending IO to complete up to a moment when the memory is depleted completely and there is no way forward but invoking the OOM killer. This is less than optimal.
The original intention of f9054c70d28b was to help with the OOM situations where the oom victim depends on mempool allocation to make a forward progress. David has mentioned the following backtrace:
schedule
schedule_timeout
io_schedule_timeout
mempool_alloc
__split_and_process_bio
dm_request
generic_make_request
submit_bio
mpage_readpages
ext4_readpages
__do_page_cache_readahead
ra_submit
filemap_fault
handle_mm_fault
__do_page_fault
do_page_fault
page_fault
We do not know more about why the mempool is depleted without being replenished in time, though. In any case the dm layer shouldn't depend on any allocations outside of the dedicated pools so a forward progress should be guaranteed. If this is not the case then the dm should be fixed rather than papering over the problem and postponing it to later by accessing more memory reserves.
mempools are a mechanism to maintain dedicated memory reserves to guaratee forward progress. Allowing them an unbounded access to the page allocator memory reserves is going against the whole purpose of this mechanism.
Bisected by Ondrej Kozina.
--- mm/mempool.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)
mm/mempool.c +3 -15
@@ -310,7 +310,7 @@ EXPORT_SYMBOL(mempool_resize);* returns NULL. Note that due to preallocation, this function * *never* fails when called from process contexts. (it might * fail if called from an IRQ context.) -* Note: neither __GFP_NOMEMALLOC nor __GFP_ZERO are supported. +* Note: using __GFP_ZERO is not supported. */ void *mempool_alloc (mempool_t *pool,gfp_t gfp_mask) {
@@ -319,27 +319,16 @@ void *mempool_alloc(mempool_t *pool, gfpwait_queue_t wait;gfp_t gfp_temp; -/* If oom killed, memory reserves are essential to prevent livelock */ -VM_WARN_ON_ONCE (gfp_mask & __GFP_NOMEMALLOC); -/* No element size to zero on allocation */ VM_WARN_ON_ONCE (gfp_mask & __GFP_ZERO); -might_sleep_if (gfp_mask & __GFP_DIRECT_RECLAIM); + gfp_mask |= __GFP_NOMEMALLOC;/* don't allocate emergency reserves */ gfp_mask |= __GFP_NORETRY;/* don't loop in __alloc_pages */ gfp_mask |= __GFP_NOWARN;/* failures are OK */ gfp_temp = gfp_mask & ~(__GFP_DIRECT_RECLAIM|__GFP_IO); repeat_alloc: -if (likely (pool->curr_nr)) { -/* -* Don't allocate from emergency reserves if there are -* elements available. This check is racy, but it will -* be rechecked each loop. -*/ - gfp_temp |= __GFP_NOMEMALLOC; - } element = pool->alloc (gfp_temp, pool->pool_data);if (likely (element !=NULL ))
@@ -363,12 +352,11 @@ repeat_alloc:* We use gfp mask w/o direct reclaim or IO for the first round. If * alloc failed with that and @pool was empty, retry immediately. */ -if ((gfp_temp & ~__GFP_NOMEMALLOC) != gfp_mask) { +if (gfp_temp != gfp_mask) {spin_unlock_irqrestore (&pool->lock, flags); gfp_temp = gfp_mask; goto repeat_alloc; } - gfp_temp = gfp_mask;/* We must not sleep if !__GFP_DIRECT_RECLAIM */ if (!(gfp_mask & __GFP_DIRECT_RECLAIM)) {
Greg Kroah-Hartman
maintainerPATCH 46/56 fs/dcache.c: avoid soft-lockup in dput()
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Fang <[email protected]>
commit 47be61845c775643f1aa4d2a54343549f943c94c upstream.
We triggered soft-lockup under stress test which open/access/write/close one file concurrently on more than five different CPUs:
WARN: soft lockup - CPU#0 stuck for 11s! [who:30631]
...
[<ffffffc0003986f8>] dput+0x100/0x298 [<ffffffc00038c2dc>] terminate_walk+0x4c/0x60 [<ffffffc00038f56c>] path_lookupat+0x5cc/0x7a8 [<ffffffc00038f780>] filename_lookup+0x38/0xf0 [<ffffffc000391180>] user_path_at_empty+0x78/0xd0 [<ffffffc0003911f4>] user_path_at+0x1c/0x28 [<ffffffc00037d4fc>] SyS_faccessat+0xb4/0x230
->d_lock trylock may failed many times because of concurrently operations, and dput() may execute a long time.
Fix this by replacing cpu_relax() with cond_resched(). dput() used to be sleepable, so make it sleepable again should be safe.
--- fs/dcache.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/dcache.c +5 -2
@@ -578,7 +578,6 @@ static struct dentry *dentry_kill(struct failed:spin_unlock (&dentry->d_lock); -cpu_relax ();return dentry;/* try again with same dentry */ }
@@ -752,6 +751,8 @@ void dput(struct dentry *dentry)return ; repeat: +might_sleep (); +rcu_read_lock ();if (likely (fast_dput (dentry))) {rcu_read_unlock ();
@@ -783,8 +784,10 @@ repeat: kill_it: dentry =dentry_kill (dentry); -if (dentry) +if (dentry) { +cond_resched (); goto repeat; + } }EXPORT_SYMBOL (dput);
Greg Kroah-Hartman
maintainerPATCH 47/56 Revert "cpufreq: pcc-cpufreq: update default value of cpuinfo_transition_latency"
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Herrmann <[email protected]>
commit da7d3abe1c9e5ebac2cf86f97e9e89888a5e2094 upstream.
This reverts commit 790d849bf811a8ab5d4cd2cce0f6fda92f6aebf2.
Using a v4.7-rc7 kernel on a HP ProLiant triggered following messages
pcc-cpufreq: (v1.10.00) driver loaded with frequency limits: 1200 MHz, 2800 MHz
cpufreq: ondemand governor failed, too long transition latency of HW, fallback to performance governor
The last line was shown for each CPU in the system. Testing v4.5 (where commit 790d849b was integrated) triggered similar messages. Same behaviour on a 2nd HP Proliant system.
So commit 790d849bf (cpufreq: pcc-cpufreq: update default value of cpuinfo_transition_latency) causes the system to use performance governor which, I guess, was not the intention of the patch.
Enabling debug output in pcc-cpufreq provides following verbose output:
pcc-cpufreq: (v1.10.00) driver loaded with frequency limits: 1200 MHz, 2800 MHz
pcc_get_offset: for CPU 0: pcc_cpu_data input_offset: 0x44, pcc_cpu_data output_offset: 0x48
init: policy->max is 2800000, policy->min is 1200000
get: get_freq for CPU 0
get: SUCCESS: (virtual) output_offset for cpu 0 is 0xffffc9000d7c0048, contains a value of: 0xff06. Speed is: 168000 MHz
cpufreq: ondemand governor failed, too long transition latency of HW, fallback to performance governor
target: CPU 0 should go to target freq: 2800000 (virtual) input_offset is 0xffffc9000d7c0044
target: was SUCCESSFUL for cpu 0
I am asking to revert 790d849bf to re-enable usage of ondemand governor with pcc-cpufreq.
--- Documentation/cpu-freq/pcc-cpufreq.txt | 4 ++-- drivers/cpufreq/pcc-cpufreq.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-)
Documentation/cpu-freq/pcc-cpufreq.txt +2 -2
@@ -159,8 +159,8 @@ to be strictly associated with a P-state 2.2 cpuinfo_transition_latency: ------------------------------- -The cpuinfo_transition_latency field is CPUFREQ_ETERNAL. The PCC specification -does not include a field to expose this value currently. +The cpuinfo_transition_latency field is 0. The PCC specification does +not include a field to expose this value currently. 2.3 cpuinfo_cur_freq: ---------------------
drivers/cpufreq/pcc-cpufreq.c +0 -2
@@ -555,8 +555,6 @@ static int pcc_cpufreq_cpu_init(struct c policy->min = policy->cpuinfo.min_freq =ioread32 (&pcch_hdr->minimum_frequency) *1000 ; - policy->cpuinfo.transition_latency =CPUFREQ_ETERNAL ; -pr_debug ("init: policy->max is %d, policy->min is %d\n" , policy->max, policy->min); out:
Greg Kroah-Hartman
maintainerPATCH 48/56 crypto: gcm - Filter out async ghash if necessary
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit b30bdfa86431afbafe15284a3ad5ac19b49b88e3 upstream.
As it is if you ask for a sync gcm you may actually end up with an async one because it does not filter out async implementations of ghash.
This patch fixes this by adding the necessary filter when looking for ghash.
--- crypto/gcm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
crypto/gcm.c +3 -1
@@ -639,7 +639,9 @@ static int crypto_gcm_create_common(stru ghash_alg =crypto_find_alg (ghash_name, &crypto_ahash_type,CRYPTO_ALG_TYPE_HASH , -CRYPTO_ALG_TYPE_AHASH_MASK ); +CRYPTO_ALG_TYPE_AHASH_MASK | +crypto_requires_sync (algt->type, + algt->mask));if (IS_ERR (ghash_alg))return PTR_ERR (ghash_alg);
Greg Kroah-Hartman
maintainerPATCH 49/56 crypto: scatterwalk - Fix test in scatterwalk_done
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit 5f070e81bee35f1b7bd1477bb223a873ff657803 upstream.
When there is more data to be processed, the current test in scatterwalk_done may prevent us from calling pagedone even when we should.
In particular, if we're on an SG entry spanning multiple pages where the last page is not a full page, we will incorrectly skip calling pagedone on the second last page.
This patch fixes this by adding a separate test for whether we've reached the end of a page.
--- crypto/scatterwalk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
crypto/scatterwalk.c +2 -1
@@ -72,7 +72,8 @@ static void scatterwalk_pagedone(structvoid scatterwalk_done (struct scatter_walk *walk,int out,int more) { -if (!(scatterwalk_pagelen (walk) & (PAGE_SIZE -1 )) || !more) +if (!more || walk->offset >= walk->sg->offset + walk->sg->length || + !(walk->offset & (PAGE_SIZE -1 )))scatterwalk_pagedone (walk, out, more); }EXPORT_SYMBOL_GPL (scatterwalk_done);
Greg Kroah-Hartman
maintainerPATCH 50/56 serial: mvebu-uart: free the IRQ in ->shutdown()
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Petazzoni <[email protected]>
commit c2c1659b4f8f9e19fe82a4fd06cca4b3d59090ce upstream.
As suggested by the serial port infrastructure documentation, the IRQ is requested in ->startup(). However, it is never freed in the ->shutdown() hook.
With simple systems that open the serial port once for all and always have at least one process that keep the serial port opened, there was no problem. But with a more complicated system (*cough* systemd *cough*), the serial port is opened/closed many times, which at some point no processes having the serial port open at all. Due to this ->startup() gets called again, tries to request_irq() again, which fails.
--- drivers/tty/serial/mvebu-uart.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/tty/serial/mvebu-uart.c +2 -0
@@ -299,6 +299,8 @@ static int mvebu_uart_startup(struct uarstatic void mvebu_uart_shutdown (struct uart_port *port) {writel (0 , port->membase +UART_CTRL ); + +free_irq (port->irq, port); } static void mvebu_uart_set_termios(struct uart_port *port,
Greg Kroah-Hartman
maintainerPATCH 51/56 ext4: check for extents that wrap around
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vegard Nossum <[email protected]>
commit f70749ca42943faa4d4dcce46dfdcaadb1d0c4b6 upstream.
An extent with lblock = 4294967295 and len = 1 will pass the ext4_valid_extent() test:
ext4_lblk_t last = lblock + len - 1; if (len == 0 || lblock > last) return 0;
since last = 4294967295 + 1 - 1 = 4294967295. This would later trigger the BUG_ON(es->es_lblk + es->es_len < es->es_lblk) in ext4_es_end().
We can simplify it by removing the - 1 altogether and changing the test to use lblock + len <= lblock, since now if len = 0, then lblock + 0 == lblock and it fails, and if len > 0 then lblock + len > lblock in order to pass (i.e. it doesn't overflow).
--- fs/ext4/extents.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/ext4/extents.c +6 -2
@@ -376,9 +376,13 @@ static int ext4_valid_extent(struct inodext4_fsblk_t block =ext4_ext_pblock (ext);int len =ext4_ext_get_actual_len (ext);ext4_lblk_t lblock =le32_to_cpu (ext->ee_block); -ext4_lblk_t last = lblock + len -1 ; -if (len ==0 || lblock > last) +/* +* We allow neither: +* - zero length +* - overflow/wrap-around +*/ +if (lblock + len <= lblock)return 0 ;return ext4_data_block_valid (EXT4_SB (inode->i_sb), block, len); }
Greg Kroah-Hartman
maintainerPATCH 52/56 ext4: fix deadlock during page writeback
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 646caa9c8e196880b41cd3e3d33a2ebc752bdb85 upstream.
Commit 06bd3c36a733 (ext4: fix data exposure after a crash) uncovered a deadlock in ext4_writepages() which was previously much harder to hit. After this commit xfstest generic/130 reproduces the deadlock on small filesystems.
The problem happens when ext4_do_update_inode() sets LARGE_FILE feature and marks current inode handle as synchronous. That subsequently results in ext4_journal_stop() called from ext4_writepages() to block waiting for transaction commit while still holding page locks, reference to io_end, and some prepared bio in mpd structure each of which can possibly block transaction commit from completing and thus results in deadlock.
Fix the problem by releasing page locks, io_end reference, and submitting prepared bio before calling ext4_journal_stop().
[ Changed to defer the call to ext4_journal_stop() only if the handle
is synchronous. --tytso ]
--- fs/ext4/inode.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-)
fs/ext4/inode.c +26 -3
@@ -2741,13 +2741,36 @@ retry: done = true; } } -ext4_journal_stop (handle); +/* +* Caution: If the handle is synchronous, +* ext4_journal_stop() can wait for transaction commit +* to finish which may depend on writeback of pages to +* complete or on page lock to be released. In that +* case, we have to wait until after after we have +* submitted all the IO, released page locks we hold, +* and dropped io_end reference (for extent conversion +* to be able to complete) before stopping the handle. +*/ +if (!ext4_handle_valid (handle) || handle->h_sync ==0 ) { +ext4_journal_stop (handle); + handle =NULL ; + }/* Submit prepared bio */ ext4_io_submit (&mpd.io_submit);/* Unlock pages we didn't use */ mpage_release_unused_pages (&mpd, give_up_on_write); -/* Drop our io_end reference we got from init */ -ext4_put_io_end (mpd.io_submit.io_end); +/* +* Drop our io_end reference we got from init. We have +* to be careful and use deferred io_end finishing if +* we are still holding the transaction as we can +* release the last reference to io_end which may end +* up doing unwritten extent conversion. +*/ +if (handle) { +ext4_put_io_end_defer (mpd.io_submit.io_end); +ext4_journal_stop (handle); + }else +ext4_put_io_end (mpd.io_submit.io_end);if (ret == -ENOSPC && sbi->s_journal) {/*
Greg Kroah-Hartman
maintainerPATCH 53/56 ext4: dont call ext4_should_journal_data() on the journal inode
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vegard Nossum <[email protected]>
commit 6a7fd522a7c94cdef0a3b08acf8e6702056e635c upstream.
If ext4_fill_super() fails early, it's possible for ext4_evict_inode() to call ext4_should_journal_data() before superblock options and flags are fully set up. In that case, the iput() on the journal inode can end up causing a BUG().
Work around this problem by reordering the tests so we only call ext4_should_journal_data() after we know it's not the journal inode.
--- fs/ext4/inode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ext4/inode.c +3 -3
@@ -205,9 +205,9 @@ void ext4_evict_inode(struct inode *inod* Note that directories do not have this problem because they * don't use page cache. */ -if (ext4_should_journal_data (inode) && - (S_ISLNK (inode->i_mode) ||S_ISREG (inode->i_mode)) && - inode->i_ino !=EXT4_JOURNAL_INO ) { +if (inode->i_ino !=EXT4_JOURNAL_INO && +ext4_should_journal_data (inode) && + (S_ISLNK (inode->i_mode) ||S_ISREG (inode->i_mode))) {journal_t *journal =EXT4_SB (inode->i_sb)->s_journal;tid_t commit_tid =EXT4_I (inode)->i_datasync_tid;
Greg Kroah-Hartman
maintainerPATCH 54/56 ext4: validate s_reserved_gdt_blocks on mount
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 5b9554dc5bf008ae7f68a52e3d7e76c0920938a2 upstream.
If s_reserved_gdt_blocks is extremely large, it's possible for ext4_init_block_bitmap(), which is called when ext4 sets up an uninitialized block bitmap, to corrupt random kernel memory. Add the same checks which e2fsck has --- it must never be larger than blocksize / sizeof(__u32) --- and then add a backup check in ext4_init_block_bitmap() in case the superblock gets modified after the file system is mounted.
--- fs/ext4/balloc.c | 3 +++ fs/ext4/super.c | 7 +++++++ 2 files changed, 10 insertions(+)
fs/ext4/balloc.c +3 -0
@@ -208,6 +208,9 @@ static int ext4_init_block_bitmap(structmemset (bh->b_data,0 , sb->s_blocksize); bit_max =ext4_num_base_meta_clusters (sb, block_group); +if ((bit_max >>3 ) >= bh->b_size) +return -EFSCORRUPTED ; +for (bit =0 ; bit < bit_max; bit++)ext4_set_bit (bit, bh->b_data);
fs/ext4/super.c +7 -0
@@ -3415,6 +3415,13 @@ static int ext4_fill_super(struct super_ goto failed_mount; } +if (le16_to_cpu (sbi->s_es->s_reserved_gdt_blocks) > (blocksize /4 )) { +ext4_msg (sb,KERN_ERR , +"Number of reserved GDT blocks insanely large: %d" , +le16_to_cpu (sbi->s_es->s_reserved_gdt_blocks)); + goto failed_mount; + } +if (sbi->s_mount_opt &EXT4_MOUNT_DAX ) {if (blocksize !=PAGE_SIZE ) { ext4_msg(sb, KERN_ERR,
Greg Kroah-Hartman
maintainerPATCH 55/56 ext4: short-cut orphan cleanup on error
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vegard Nossum <[email protected]>
commit c65d5c6c81a1f27dec5f627f67840726fcd146de upstream.
If we encounter a filesystem error during orphan cleanup, we should stop. Otherwise, we may end up in an infinite loop where the same inode is processed again and again.
EXT4-fs (loop0): warning: checktime reached, running e2fsck is recommended
EXT4-fs error (device loop0): ext4_mb_generate_buddy:758: group 2, block bitmap and bg descriptor inconsistent: 6117 vs 0 free clusters Aborting journal on device loop0-8.
EXT4-fs (loop0): Remounting filesystem read-only
EXT4-fs error (device loop0) in ext4_free_blocks:4895: Journal has aborted
EXT4-fs error (device loop0) in ext4_do_update_inode:4893: Journal has aborted
EXT4-fs error (device loop0) in ext4_do_update_inode:4893: Journal has aborted
EXT4-fs error (device loop0) in ext4_ext_remove_space:3068: IO failure
EXT4-fs error (device loop0) in ext4_ext_truncate:4667: Journal has aborted
EXT4-fs error (device loop0) in ext4_orphan_del:2927: Journal has aborted
EXT4-fs error (device loop0) in ext4_do_update_inode:4893: Journal has aborted
EXT4-fs (loop0): Inode 16 (00000000618192a0): orphan list check failed!
[...]
EXT4-fs (loop0): Inode 16 (0000000061819748): orphan list check failed!
[...]
EXT4-fs (loop0): Inode 16 (0000000061819bf0): orphan list check failed!
[...]
See-also: c9eb13a9105 ("ext4: fix hang when processing corrupted orphaned inode list")
--- fs/ext4/super.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
fs/ext4/super.c +10 -0
@@ -2277,6 +2277,16 @@ static void ext4_orphan_cleanup(struct swhile (es->s_last_orphan) {struct inode *inode; +/* +* We may have encountered an error during cleanup; if +* so, skip the rest. +*/ +if (EXT4_SB (sb)->s_mount_state &EXT4_ERROR_FS ) { +jbd_debug (1 ,"Skipping orphan recovery on fs with errors.\n" ); + es->s_last_orphan =0 ; +break ; + } + inode =ext4_orphan_get (sb,le32_to_cpu (es->s_last_orphan));if (IS_ERR (inode)) { es->s_last_orphan =0 ;
Greg Kroah-Hartman
maintainerPATCH 56/56 ext4: fix reference counting bug on block allocation error
In reply to Greg Kroah-Hartman4.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vegard Nossum <[email protected]>
commit 554a5ccc4e4a20c5f3ec859de0842db4b4b9c77e upstream.
If we hit this error when mounted with errors=continue or errors=remount-ro:
EXT4-fs error (device loop0): ext4_mb_mark_diskspace_used:2940: comm ext4.exe: Allocating blocks 5090-6081 which overlap fs metadata
then ext4_mb_new_blocks() will call ext4_mb_release_context() and try to continue. However, ext4_mb_release_context() is the wrong thing to call here since we are still actually using the allocation context.
Instead, just error out. We could retry the allocation, but there is a possibility of getting stuck in an infinite loop instead, so this seems safer.
[ Fixed up so we don't return EAGAIN to userspace. --tytso ]
--- fs/ext4/mballoc.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-)
fs/ext4/mballoc.c +3 -14
@@ -2939,7 +2939,7 @@ ext4_mb_mark_diskspace_used(struct ext4_ext4_error (sb,"Allocating blocks %llu-%llu which overlap " "fs metadata" , block, block+len);/* File system mounted not to panic on error -* Fix the bitmap and repeat the block allocation +* Fix the bitmap and return EFSCORRUPTED * We leak some of the blocks here. */ ext4_lock_group (sb, ac->ac_b_ex.fe_group);
@@ -2948,7 +2948,7 @@ ext4_mb_mark_diskspace_used(struct ext4_ext4_unlock_group (sb, ac->ac_b_ex.fe_group); err =ext4_handle_dirty_metadata (handle,NULL , bitmap_bh);if (!err) - err = -EAGAIN ; + err = -EFSCORRUPTED ; goto out_err; }
@@ -4513,18 +4513,7 @@ repeat: }if (likely (ac->ac_status ==AC_STATUS_FOUND )) { *errp =ext4_mb_mark_diskspace_used (ac, handle, reserv_clstrs); -if (*errp == -EAGAIN ) { -/* -* drop the reference that we took -* in ext4_mb_use_best_found -*/ -ext4_mb_release_context (ac); - ac->ac_b_ex.fe_group =0 ; - ac->ac_b_ex.fe_start =0 ; - ac->ac_b_ex.fe_len =0 ; - ac->ac_status =AC_STATUS_CONTINUE ; - goto repeat; - }else if (*errp) { +if (*errp) {ext4_discard_allocated_blocks (ac); goto errout; }else {
Quoted 7 lines · Greg Kroah-Hartman
*********************************************************************
NOTE
This is the LAST 4.6.y kernel that will be released. After this release, it is end-of-life. You should be moving on to 4.7.y at this point in time. You have been warned.
*********************************************************************
Quoted 8 lines
This is the start of the stable review cycle for the 4.6.7 release. There are 56 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 Tue Aug 16 20:24:52 UTC 2016. Anything received after that time might be too late.
Build results:
total: 148 pass: 146 fail: 2
Failed builds:
unicore32:defconfig
unicore32:allnoconfig
Qemu test results:
total: 107 pass: 107 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
Quoted 12 lines · Greg Kroah-Hartman
*********************************************************************
NOTE
This is the LAST 4.6.y kernel that will be released. After this release, it is end-of-life. You should be moving on to 4.7.y at this point in time. You have been warned.
*********************************************************************This is the start of the stable review cycle for the 4.6.7 release. There are 56 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 Tue Aug 16 20:24:52 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.6.7-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.6.y
and the diffstat can be found below.
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Signature · 5 lines
Shuah Khan Sr. Linux Kernel Developer Open Source Innovation Group Samsung Research America(Silicon Valley) [email protected]