3.12.27-stable review
cover 3.12.27-stable review
This is the start of the stable review cycle for the 3.12.27 release. There are 104 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Aug 22 13:43:20 CEST 2014. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.27-rc1.xz
and the diffstat can be found below.
thanks,
js
===============
Akeem G Abodunrin (1):
igb: Fixed Wake On LAN support
Ales Novak (1):
drivers/rtc/interface.c: fix infinite loop in initializing the alarm
Alexandre Bounine (1):
rapidio/tsi721_dma: fix failure to obtain transaction descriptor
Andrey Ryabinin (1):
net: sendmsg: fix NULL pointer dereference
Andrey Utkin (1):
arch/sparc/math-emu/math_32.c: drop stray break operator
Andy Lutomirski (1):
x86_64/entry/xen: Do not invoke espfix64 on Xen
Anssi Hannula (1):
dm cache: fix race affecting dirty block count
Benjamin Tisssoires (1):
HID: logitech-dj: Fix USB 3.0 issue
Boris Ostrovsky (1):
x86/espfix/xen: Fix allocation of pages for paravirt page tables
Carolyn Wyborny (1):
igb: Fix master/slave mode for all m88 i354 PHY's
Cedric Le Goater (1):
offb: Little endian fixes
Christoph Paasch (2):
tcp: Fix integer-overflows in TCP veno
tcp: Fix integer-overflow in TCP vegas
Christopher Alexander Tobias Schulze (2):
bbc-i2c: Fix BBC I2C envctrl on SunBlade 2000
sunsab: Fix detection of BREAK on sunsab serial console
Dan Carpenter (2):
igbvf: integer wrapping bug setting the mtu RDMA/cxgb3: Fix information leak in send_abort()
Daniel Borkmann (1):
net: sctp: inherit auth_capable on INIT collisions
David Ertman (1):
e1000e: Fix a compile flag mis-match for suspend/resume
David Gibson (1):
netxen: Correct off-by-one errors in bounds checks
David Rientjes (1):
mm, thp: do not allow thp faults to avoid cpuset restrictions
David S. Miller (11):
sparc64: Fix argument sign extension for compat_sys_futex().
sparc64: Fix executable bit testing in set_pmd_at() paths.
sparc64: Handle 32-bit tasks properly in compute_effective_address().
sparc64: Fix top-level fault handling bugs.
sparc64: Add basic validations to {pud,pmd}_bad().
sparc64: Give more detailed information in {pgd,pmd}_ERROR() and kill
pte_ERROR().
sparc64: Don't bark so loudly about 32-bit tasks generating 64-bit
fault addresses.
sparc64: Fix huge TSB mapping on pre-UltraSPARC-III cpus.
sparc64: Add membar to Niagara2 memcpy code.
sparc64: Do not insert non-valid PTEs into the TSB hash table.
sparc64: Guard against flushing openfirmware mappings.
Dmitry Kravkov (1):
bnx2x: fix crash during TSO tunneling
Don Skidmore (1):
ixgbevf: cleanup redundant mailbox read failure check
Eliad Peller (2):
cfg80211: fix mic_failure tracing
mac80211: reset probe_send_count also in HW_CONNECTION_MONITOR case
Emil Tantilov (2):
ixgbe: fix rx-usecs range checks for BQL
ixgbe: fix inconsistent clearing of the multicast table
Eric Dumazet (3):
inetpeer: get rid of ip_id_count
ip: make IP identifiers less predictable
sctp: fix possible seqlock seadlock in sctp_packet_transmit()
Eric W. Biederman (3):
mnt: Only change user settable mount flags in remount
mnt: Move the test for MNT_LOCK_READONLY from change_mount_flags into
do_remount
mnt: Correct permission checks in do_remount
Felix Fietkau (1):
ath9k: fix aggregation session lockup
Fujinaka, Todd (2):
igb: Add ethtool offline tests for i354
igb: Don't let ethtool try to write to iNVM in i210/i211
Greg Thelen (1):
dm bufio: fully initialize shrinker
H. Peter Anvin (6):
Revert "x86-64, modify_ldt: Make support for 16-bit segments a runtime
option"
x86-64, espfix: Don't leak bits 31:16 of %esp returning to 16-bit
stack
x86, espfix: Move espfix definitions into a separate header file x86, espfix: Fix broken header guard
x86, espfix: Make espfix64 a Kconfig option, fix UML
x86, espfix: Make it possible to disable 16-bit support
Hong Zhiguo (1):
e1000: fix wrong queue idx calculation
Ilan Peer (1):
iwlwifi: mvm: Add a missed beacons threshold
Jacob Keller (1):
ixgbe: fix qv_lock_napi call in ixgbe_napi_disable_all
James Bottomley (1):
scsi: handle flush errors properly
Jan Beulich (1):
drivers/rtc/rtc-efi.c: check for invalid data coming back from UEFI
Jan Kara (2):
timer: Fix lock inversion between hrtimer_bases.lock and scheduler
locks
ext4: Fix block zeroing when punching holes in indirect block files
Jiri Kosina (1):
Input: i8042 - add Acer Aspire 5710 to nomux blacklist
Johannes Berg (1):
Revert "mac80211: move "bufferable MMPDU" check to fix AP mode scan"
John Stultz (1):
printk: rename printk_sched to printk_deferred
Keith Packard (1):
fbcon: Clean up fbcon data in fb_info on FB_EVENT_FB_UNBIND with 0 fbs
Kirill Tkhai (1):
sparc64: Make itc_sync_lock raw
Konstantin Khlebnikov (1):
ARM: 8115/1: LPAE: reduce damage caused by idmap to virtual memory
layout
Lars-Peter Clausen (1):
iio: buffer: Fix demux table creation
Laurent Dufour (1):
PCI: rphahp: Fix endianess issues
Lee, Chun-Yi (1):
drivers/rtc/rtc-efi.c: avoid subtracting day twice when computing year
days
Malcolm Priestley (2):
staging: vt6655: Fix disassociated messages every 10 seconds
staging: vt6655: Fix Warning on boot handle_irq_event_percpu.
Martin Schwidefsky (1):
s390/ptrace: fix PSW mask check
Maurizio Lombardi (1):
bnx2fc: fix memory leak in bnx2fc_allocate_hash_table()
Max Filippov (1):
xtensa: add fixup for double exception raised in window overflow
Maxim Patlasov (1):
mm/page-writeback.c: fix divide by zero in bdi_dirty_limits()
Michal Hocko (1):
memcg: oom_notify use-after-free fix
Mika Westerberg (1):
e1000e: Fix compilation warning when !CONFIG_PM_SLEEP
Milan Broz (1):
crypto: af_alg - properly label AF_ALG socket
Minfei Huang (1):
lib/btree.c: fix leak of whole btree nodes
Naoya Horiguchi (2):
hugetlb: fix copy_hugetlb_page_range() to handle migration/hwpoisoned
entry
mm: hugetlb: fix copy_hugetlb_page_range()
Nithin Sujir (1):
tg3: Add support for new 577xx device ids
Peter Meerwald (2):
iio:bma180: Fix scale factors to report correct acceleration units iio:bma180: Missing check for frequency fractional part
Russell King (7):
DMA-API: provide a helper to set both DMA and coherent DMA masks
DMA-API: net: intel/e1000e: fix 32-bit DMA mask handling
DMA-API: net: intel/ixgbe: fix 32-bit DMA mask handling
DMA-API: net: intel/ixgbevf: fix 32-bit DMA mask handling
DMA-API: net: intel/igb: fix 32-bit DMA mask handling
DMA-API: net: intel/igbvf: fix 32-bit DMA mask handling
DMA-API: net: brocade/bna/bnad.c: fix 32-bit DMA mask handling
Sasha Levin (2):
net/l2tp: don't fall back on UDP [get|set]sockopt
iovec: make sure the caller actually wants anything in
memcpy_fromiovecend
Sowmini Varadhan (1):
sparc64: ldc_connect() should not return EINVAL when handshake is in
progress.
Stefan Assmann (1):
igb: fix driver reload with VF assigned to guest
Vitaliy Kulikov (1):
ALSA: hda - load EQ params into IDT codec on HP bNB13 systems
Vlad Yasevich (2):
macvlan: Initialize vlan_features to turn on offload support.
net: Correctly set segment mac_len in skb_segment().
Vladimir Davydov (1):
e1000: fix possible reset_task running after adapter down
Wei Yongjun (1):
igbvf: add missing iounmap() on error in igbvf_probe()
Ying Xue (1):
tipc: don't use memcpy to copy from user space
Yuval Mintz (1):
bnx2x: Test nvram when interface is down
yzhu1 (1):
e1000: prevent oops when adapter is being closed and reset
simultaneously
Documentation/DMA-API-HOWTO.txt | 37 +- Documentation/DMA-API.txt | 8 + Documentation/x86/x86_64/mm.txt | 2 + arch/arm/mm/idmap.c | 7 + arch/s390/kernel/ptrace.c | 9 +- arch/sparc/include/asm/pgtable_64.h | 61 ++- arch/sparc/include/asm/tlbflush_64.h | 12 +- arch/sparc/kernel/ldc.c | 2 +- arch/sparc/kernel/smp_64.c | 6 +- arch/sparc/kernel/sys32.S | 2 +- arch/sparc/kernel/unaligned_64.c | 12 +- arch/sparc/lib/NG2memcpy.S | 1 + arch/sparc/math-emu/math_32.c | 2 +- arch/sparc/mm/fault_64.c | 98 ++-- arch/sparc/mm/init_64.c | 27 ++ arch/sparc/mm/tlb.c | 17 +- arch/sparc/mm/tsb.c | 14 +- arch/x86/Kconfig | 25 +- arch/x86/include/asm/espfix.h | 16 + arch/x86/include/asm/irqflags.h | 2 +- arch/x86/include/asm/pgtable_64_types.h | 2 + arch/x86/include/asm/setup.h | 2 + arch/x86/kernel/Makefile | 1 + arch/x86/kernel/entry_32.S | 12 + arch/x86/kernel/entry_64.S | 77 ++- arch/x86/kernel/espfix_64.c | 208 ++++++++ arch/x86/kernel/ldt.c | 10 +- arch/x86/kernel/paravirt_patch_64.c | 2 - arch/x86/kernel/smpboot.c | 7 + arch/x86/mm/dump_pagetables.c | 31 +- arch/x86/vdso/vdso32-setup.c | 8 - arch/xtensa/kernel/vectors.S | 158 +++++- arch/xtensa/kernel/vmlinux.lds.S | 4 +- crypto/af_alg.c | 2 + drivers/hid/hid-logitech-dj.c | 8 + drivers/iio/accel/bma180.c | 8 +- drivers/iio/industrialio-buffer.c | 2 +- drivers/infiniband/hw/cxgb3/iwch_cm.c | 1 + drivers/input/serio/i8042-x86ia64io.h | 7 + drivers/md/dm-bufio.c | 2 +- drivers/md/dm-cache-target.c | 13 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 + drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 9 + .../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 19 +- drivers/net/ethernet/broadcom/tg3.c | 15 +- drivers/net/ethernet/broadcom/tg3.h | 3 + drivers/net/ethernet/brocade/bna/bnad.c | 13 +- drivers/net/ethernet/intel/e1000/e1000.h | 5 + drivers/net/ethernet/intel/e1000/e1000_main.c | 27 +- drivers/net/ethernet/intel/e1000e/netdev.c | 22 +- drivers/net/ethernet/intel/igb/e1000_phy.c | 8 +- drivers/net/ethernet/intel/igb/igb_ethtool.c | 17 +- drivers/net/ethernet/intel/igb/igb_main.c | 55 +-- drivers/net/ethernet/intel/igbvf/netdev.c | 26 +- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 48 +- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 6 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 36 +- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 44 +- .../net/ethernet/qlogic/netxen/netxen_nic_init.c | 4 +- drivers/net/macvlan.c | 1 + drivers/net/ppp/pptp.c | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 9 + drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 25 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + drivers/pci/hotplug/rpaphp_core.c | 15 +- drivers/rapidio/devices/tsi721_dma.c | 8 +- drivers/rtc/interface.c | 14 +- drivers/rtc/rtc-efi.c | 34 +- drivers/sbus/char/bbc_envctrl.c | 6 + drivers/sbus/char/bbc_i2c.c | 11 +- drivers/scsi/bnx2fc/bnx2fc_hwi.c | 31 +- drivers/scsi/scsi_lib.c | 8 + drivers/staging/vt6655/bssdb.c | 2 +- drivers/staging/vt6655/device_main.c | 7 +- drivers/tty/serial/sunsab.c | 9 + drivers/video/console/fbcon.c | 27 +- drivers/video/offb.c | 18 +- fs/ext4/indirect.c | 4 +- fs/namespace.c | 51 +- include/linux/dma-mapping.h | 14 + include/linux/mount.h | 9 +- include/linux/printk.h | 6 +- include/net/inetpeer.h | 16 +- include/net/ip.h | 31 +- include/net/ipv6.h | 11 +- include/net/mac80211.h | 2 - include/net/secure_seq.h | 2 - init/main.c | 4 + kernel/printk/printk.c | 2 +- kernel/sched/core.c | 2 +- kernel/sched/rt.c | 2 +- kernel/time/clockevents.c | 10 +- lib/btree.c | 1 + mm/hugetlb.c | 70 +-- mm/memcontrol.c | 4 + mm/page-writeback.c | 6 +- mm/page_alloc.c | 16 +- net/compat.c | 9 +- net/core/iovec.c | 10 +- net/core/secure_seq.c | 25 - net/core/skbuff.c | 2 +- net/ipv4/igmp.c | 4 +- net/ipv4/inetpeer.c | 18 - net/ipv4/ip_output.c | 7 +- net/ipv4/ip_tunnel_core.c | 2 +- net/ipv4/ipmr.c | 2 +- net/ipv4/raw.c | 2 +- net/ipv4/route.c | 69 ++- net/ipv4/tcp_vegas.c | 3 +- net/ipv4/tcp_veno.c | 2 +- net/ipv4/xfrm4_mode_tunnel.c | 2 +- net/ipv6/ip6_output.c | 17 + net/ipv6/output_core.c | 23 - net/l2tp/l2tp_ppp.c | 4 +- net/mac80211/mlme.c | 4 +- net/mac80211/tx.c | 27 +- net/netfilter/ipvs/ip_vs_xmit.c | 2 +- net/sctp/associola.c | 1 + net/sctp/output.c | 2 +- net/tipc/msg.c | 22 +- net/wireless/trace.h | 3 +- sound/pci/hda/patch_sigmatel.c | 532 ++++++++++++++++++++- 122 files changed, 1915 insertions(+), 653 deletions(-) create mode 100644 arch/x86/include/asm/espfix.h create mode 100644 arch/x86/kernel/espfix_64.c
Signature · 1 line
2.0.4
PATCH 1/104 s390/ptrace: fix PSW mask check
From: Martin Schwidefsky <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dab6cf55f81a6e16b8147aed9a843e1691dcd318 upstream.
The PSW mask check of the PTRACE_POKEUSR_AREA command is incorrect. The PSW_MASK_USER define contains the PSW_MASK_ASC bits, the ptrace interface accepts all combinations for the address-space-control bits. To protect the kernel space the PSW mask check in ptrace needs to reject the address-space-control bit combination for home space.
Fixes CVE-2014-3534
--- arch/s390/kernel/ptrace.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/s390/kernel/ptrace.c +7 -2
@@ -322,7 +322,9 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)* psw and gprs are stored on the stack */ if (addr == (addr_t) &dummy->regs.psw.mask && - ((data & ~PSW_MASK_USER ) != psw_user_bits || + (((data^psw_user_bits) & ~PSW_MASK_USER ) || + (((data^psw_user_bits) &PSW_MASK_ASC ) && + ((data|psw_user_bits) &PSW_MASK_ASC ) ==PSW_MASK_ASC ) || ((data &PSW_MASK_EA ) && !(data &PSW_MASK_BA ))))/* Invalid psw mask. */ return -EINVAL ;
@@ -655,7 +657,10 @@ static int __poke_user_compat(struct task_struct *child,*/ if (addr == (addr_t) &dummy32->regs.psw.mask) {/* Build a 64 bit psw mask from 31 bit mask. */ -if ((tmp & ~PSW32_MASK_USER ) != psw32_user_bits) +if (((tmp^psw32_user_bits) & ~PSW32_MASK_USER ) || + (((tmp^psw32_user_bits) &PSW32_MASK_ASC ) && + ((tmp|psw32_user_bits) &PSW32_MASK_ASC ) + ==PSW32_MASK_ASC ))/* Invalid psw mask. */ return -EINVAL ; regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
Signature · 1 line
2.0.4
PATCH 2/104 crypto: af_alg - properly label AF_ALG socket
From: Milan Broz <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4c63f83c2c2e16a13ce274ee678e28246bd33645 upstream.
Th AF_ALG socket was missing a security label (e.g. SELinux) which means that socket was in "unlabeled" state.
This was recently demonstrated in the cryptsetup package (cryptsetup v1.6.5 and later.)
See https://bugzilla.redhat.com/show_bug.cgi?id=1115120
This patch clones the sock's label from the parent sock and resolves the issue (similar to AF_BLUETOOTH protocol family).
--- crypto/af_alg.c | 2 ++ 1 file changed, 2 insertions(+)
crypto/af_alg.c +2 -0
@@ -21,6 +21,7 @@#include <linux/module.h> #include <linux/net.h> #include <linux/rwsem.h> +#include <linux/security.h> struct alg_type_list {const struct af_alg_type *type;
@@ -243,6 +244,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)sock_init_data (newsock, sk2);sock_graft (sk2, newsock); +security_sk_clone (sk, sk2); err = type->accept (ask->private, sk2);if (err) {
Signature · 1 line
2.0.4
PATCH 3/104 ARM: 8115/1: LPAE: reduce damage caused by idmap to virtual memory layout
In reply to Jiri SlabyFrom: Konstantin Khlebnikov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 811a2407a3cf7bbd027fbe92d73416f17485a3d8 upstream.
On LPAE, each level 1 (pgd) page table entry maps 1GiB, and the level 2 (pmd) entries map 2MiB.
When the identity mapping is created on LPAE, the pgd pointers are copied from the swapper_pg_dir. If we find that we need to modify the contents of a pmd, we allocate a new empty pmd table and insert it into the appropriate 1GB slot, before then filling it with the identity mapping.
However, if the 1GB slot covers the kernel lowmem mappings, we obliterate those mappings.
When replacing a PMD, first copy the old PMD contents to the new PMD, so that we preserve the existing mappings, particularly the mappings of the kernel itself.
[rewrote commit message and added code comment -- rmk]
--- arch/arm/mm/idmap.c | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm/mm/idmap.c +7 -0
@@ -24,6 +24,13 @@ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,pr_warning ("Failed to allocate identity pmd.\n" );return ; } +/* +* Copy the original PMD to ensure that the PMD entries for +* the kernel image are preserved. +*/ +if (!pud_none (*pud)) +memcpy (pmd,pmd_offset (pud,0 ), +PTRS_PER_PMD *sizeof (pmd_t));pud_populate (&init_mm, pud, pmd); pmd +=pmd_index (addr); }else
Signature · 1 line
2.0.4
PATCH 4/104 ath9k: fix aggregation session lockup
In reply to Jiri SlabyFrom: Felix Fietkau <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c01fac1c77a00227f706a1654317023e3f4ac7f0 upstream.
If an aggregation session fails, frames still end up in the driver queue with IEEE80211_TX_CTL_AMPDU set.
This causes tx for the affected station/tid to stall, since ath_tx_get_tid_subframe returning packets to send.
Fix this by clearing IEEE80211_TX_CTL_AMPDU as long as no aggregation session is running.
--- drivers/net/wireless/ath/ath9k/xmit.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/net/wireless/ath/ath9k/xmit.c +9 -0
@@ -904,6 +904,15 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, tx_info =IEEE80211_SKB_CB (skb); tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT ; + +/* +* No aggregation session is running, but there may be frames +* from a previous session or a failed attempt in the queue. +* Send them out as normal data frames +*/ +if (!tid->active) + tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU ; +if (!(tx_info->flags &IEEE80211_TX_CTL_AMPDU )) { bf->bf_state.bf_type =0 ;return bf;
Signature · 1 line
2.0.4
PATCH 5/104 cfg80211: fix mic_failure tracing
In reply to Jiri SlabyFrom: Eliad Peller <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8c26d458394be44e135d1c6bd4557e1c4e1a0535 upstream.
tsc can be NULL (mac80211 currently always passes NULL), resulting in NULL-dereference. check before copying it.
--- net/wireless/trace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/wireless/trace.h +2 -1
@@ -2029,7 +2029,8 @@ TRACE_EVENT(cfg80211_michael_mic_failure,MAC_ASSIGN (addr, addr); __entry->key_type = key_type; __entry->key_id = key_id; -memcpy (__entry->tsc, tsc,6 ); +if (tsc) +memcpy (__entry->tsc, tsc,6 ); ), TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm", NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type,
Signature · 1 line
2.0.4
PATCH 6/104 rapidio/tsi721_dma: fix failure to obtain transaction descriptor
In reply to Jiri SlabyFrom: Alexandre Bounine <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0193ed8225e1a79ed64632106ec3cc81798cb13c upstream.
This is a bug fix for the situation when function tsi721_desc_get() fails to obtain a free transaction descriptor.
The bug usually results in a memory access crash dump when data transfer scatter-gather list has more entries than size of hardware buffer descriptors ring. This fix ensures that error is properly returned to a caller instead of an invalid entry.
This patch is applicable to kernel versions starting from v3.5.
--- drivers/rapidio/devices/tsi721_dma.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/rapidio/devices/tsi721_dma.c +7 -1
@@ -287,6 +287,12 @@ struct tsi721_tx_desc *tsi721_desc_get(struct tsi721_bdma_chan *bdma_chan) "desc %p not ACKed\n", tx_desc); } +if (ret ==NULL ) { +dev_dbg (bdma_chan->dchan.device->dev, +"%s: unable to obtain tx descriptor\n" , __func__); + goto err_out; + } + i = bdma_chan->wr_count_next % bdma_chan->bd_num;if (i == bdma_chan->bd_num -1 ) { i =0 ;
@@ -297,7 +303,7 @@ struct tsi721_tx_desc *tsi721_desc_get(struct tsi721_bdma_chan *bdma_chan) tx_desc->txd.phys = bdma_chan->bd_phys + i *sizeof (struct tsi721_dma_desc ); tx_desc->hw_desc = &((struct tsi721_dma_desc *)bdma_chan->bd_base)[i]; - +err_out:spin_unlock_bh (&bdma_chan->lock);return ret;
Signature · 1 line
2.0.4
PATCH 7/104 scsi: handle flush errors properly
In reply to Jiri SlabyFrom: James Bottomley <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 89fb4cd1f717a871ef79fa7debbe840e3225cd54 upstream.
Flush commands don't transfer data and thus need to be special cased in the I/O completion handler so that we can propagate errors to the block layer and filesystem.
--- drivers/scsi/scsi_lib.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/scsi/scsi_lib.c +8 -0
@@ -831,6 +831,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)scsi_next_command (cmd);return ; } + }else if (blk_rq_bytes (req) ==0 && result && !sense_deferred) { +/* +* Certain non BLOCK_PC requests are commands that don't +* actually transfer anything (FLUSH), so cannot use +* good_bytes != blk_rq_bytes(req) as the signal for an error. +* This sets the error explicitly for the problem case. +*/ + error =__scsi_error_from_host_byte (cmd, result); }/* no bidi support for !REQ_TYPE_BLOCK_PC yet */
Signature · 1 line
2.0.4
PATCH 8/104 mm/page-writeback.c: fix divide by zero in bdi_dirty_limits()
In reply to Jiri SlabyFrom: Maxim Patlasov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f6789593d5cea42a4ecb1cbeab6a23ade5ebbba7 upstream.
Under memory pressure, it is possible for dirty_thresh, calculated by global_dirty_limits() in balance_dirty_pages(), to equal zero. Then, if strictlimit is true, bdi_dirty_limits() tries to resolve the proportion:
bdi_bg_thresh : bdi_thresh = background_thresh : dirty_thresh
by dividing by zero.
--- mm/page-writeback.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
mm/page-writeback.c +3 -3
@@ -1324,9 +1324,9 @@ static inline void bdi_dirty_limits(struct backing_dev_info *bdi, *bdi_thresh =bdi_dirty_limit (bdi, dirty_thresh);if (bdi_bg_thresh) - *bdi_bg_thresh =div_u64 ((u64)*bdi_thresh * - background_thresh, - dirty_thresh); + *bdi_bg_thresh = dirty_thresh ?div_u64 ((u64)*bdi_thresh * + background_thresh, + dirty_thresh) :0 ;/* * In order to avoid the stacked BDI deadlock we need
Signature · 1 line
2.0.4
PATCH 9/104 mm, thp: do not allow thp faults to avoid cpuset restrictions
In reply to Jiri SlabyFrom: David Rientjes <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b104a35d32025ca740539db2808aa3385d0f30eb upstream.
The page allocator relies on __GFP_WAIT to determine if ALLOC_CPUSET should be set in allocflags. ALLOC_CPUSET controls if a page allocation should be restricted only to the set of allowed cpuset mems.
Transparent hugepages clears __GFP_WAIT when defrag is disabled to prevent the fault path from using memory compaction or direct reclaim. Thus, it is unfairly able to allocate outside of its cpuset mems restriction as a side-effect.
This patch ensures that ALLOC_CPUSET is only cleared when the gfp mask is truly GFP_ATOMIC by verifying it is also not a thp allocation.
--- mm/page_alloc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
mm/page_alloc.c +8 -8
@@ -2425,7 +2425,7 @@ static inline int gfp_to_alloc_flags(gfp_t gfp_mask) {int alloc_flags =ALLOC_WMARK_MIN |ALLOC_CPUSET ; -const gfp_t wait = gfp_mask & __GFP_WAIT; +const bool atomic = !(gfp_mask & (__GFP_WAIT | __GFP_NO_KSWAPD));/* __GFP_HIGH is assumed to be the same as ALLOC_HIGH to save a branch. */ BUILD_BUG_ON (__GFP_HIGH != (__force gfp_t )ALLOC_HIGH );
@@ -2434,20 +2434,20 @@ gfp_to_alloc_flags(gfp_t gfp_mask)* The caller may dip into page reserves a bit more if the caller * cannot run direct reclaim, or if the caller has realtime scheduling * policy or is asking for __GFP_HIGH memory. GFP_ATOMIC requests will -* set both ALLOC_HARDER (!wait) and ALLOC_HIGH (__GFP_HIGH). +* set both ALLOC_HARDER (atomic == true) and ALLOC_HIGH (__GFP_HIGH). */ alloc_flags |= (__force int ) (gfp_mask & __GFP_HIGH); -if (!wait) { +if (atomic) {/* -* Not worth trying to allocate harder for -* __GFP_NOMEMALLOC even if it can't schedule. +* Not worth trying to allocate harder for __GFP_NOMEMALLOC even +* if it can't schedule. */ -if (!(gfp_mask & __GFP_NOMEMALLOC)) +if (!(gfp_mask & __GFP_NOMEMALLOC)) alloc_flags |=ALLOC_HARDER ;/* -* Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc. -* See also cpuset_zone_allowed() comment in kernel/cpuset.c. +* Ignore cpuset mems for GFP_ATOMIC rather than fail, see the +* comment for __cpuset_node_allowed_softwall(). */ alloc_flags &= ~ALLOC_CPUSET ; }else if (unlikely (rt_task (current)) && !in_interrupt ())
Signature · 1 line
2.0.4
PATCH 10/104 memcg: oom_notify use-after-free fix
In reply to Jiri SlabyFrom: Michal Hocko <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2bcf2e92c3918ce62ab4e934256e47e9a16d19c3 upstream.
Paul Furtado has reported the following GPF:
general protection fault: 0000 [#1] SMP
Modules linked in: ipv6 dm_mod xen_netfront coretemp hwmon x86_pkg_temp_thermal crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel ablk_helper cryptd lrw gf128mul glue_helper aes_x86_64 microcode pcspkr ext4 jbd2 mbcache raid0 xen_blkfront
CPU: 3 PID: 3062 Comm: java Not tainted 3.16.0-rc5 #1
task: ffff8801cfe8f170 ti: ffff8801d2ec4000 task.ti: ffff8801d2ec4000
RIP: e030:mem_cgroup_oom_synchronize+0x140/0x240
RSP: e02b:ffff8801d2ec7d48 EFLAGS: 00010283
RAX: 0000000000000001 RBX: ffff88009d633800 RCX: 000000000000000e
RDX: fffffffffffffffe RSI: ffff88009d630200 RDI: ffff88009d630200
RBP: ffff8801d2ec7da8 R08: 0000000000000012 R09: 00000000fffffffe
R10: 0000000000000000 R11: 0000000000000000 R12: ffff88009d633800
R13: ffff8801d2ec7d48 R14: dead000000100100 R15: ffff88009d633a30
FS: 00007f1748bb4700(0000) GS:ffff8801def80000(0000) knlGS:0000000000000000
CS: e033 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007f4110300308 CR3: 00000000c05f7000 CR4: 0000000000002660
Call Trace:
pagefault_out_of_memory+0x18/0x90
mm_fault_error+0xa9/0x1a0
__do_page_fault+0x478/0x4c0
do_page_fault+0x2c/0x40
page_fault+0x28/0x30
Code: 44 00 00 48 89 df e8 40 ca ff ff 48 85 c0 49 89 c4 74 35 4c 8b b0 30 02 00 00 4c 8d b8 30 02 00 00 4d 39 fe 74 1b 0f 1f 44 00 00 <49> 8b 7e 10 be 01 00 00 00 e8 42 d2 04 00 4d 8b 36 4d 39 fe 75
RIP mem_cgroup_oom_synchronize+0x140/0x240Commit fb2a6fc56be6 ("mm: memcg: rework and document OOM waiting and wakeup") has moved mem_cgroup_oom_notify outside of memcg_oom_lock assuming it is protected by the hierarchical OOM-lock.
Although this is true for the notification part the protection doesn't cover unregistration of event which can happen in parallel now so mem_cgroup_oom_notify can see already unlinked and/or freed mem_cgroup_eventfd_list.
Fix this by using memcg_oom_lock also in mem_cgroup_oom_notify.
Addresses https://bugzilla.kernel.org/show_bug.cgi?id=80881
--- mm/memcontrol.c | 4 ++++ 1 file changed, 4 insertions(+)
mm/memcontrol.c +4 -0
@@ -5648,8 +5648,12 @@ static int mem_cgroup_oom_notify_cb(struct mem_cgroup *memcg) {struct mem_cgroup_eventfd_list *ev; +spin_lock (&memcg_oom_lock); +list_for_each_entry (ev, &memcg->oom_notify, list)eventfd_signal (ev->eventfd,1 ); + +spin_unlock (&memcg_oom_lock);return 0 ; }
Signature · 1 line
2.0.4
PATCH 11/104 staging: vt6655: Fix disassociated messages every 10 seconds
In reply to Jiri SlabyFrom: Malcolm Priestley <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4aa0abed3a2a11b7d71ad560c1a3e7631c5a31cd upstream.
byReAssocCount is incremented every second resulting in disassociated message being send every 10 seconds whether connection or not.
byReAssocCount should only advance while eCommandState is in WLAN_ASSOCIATE_WAIT
Change existing scope to if condition.
--- drivers/staging/vt6655/bssdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/vt6655/bssdb.c +1 -1
@@ -1026,7 +1026,7 @@ start: pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION (1 )); } - { +if (pDevice->eCommandState ==WLAN_ASSOCIATE_WAIT ) { pDevice->byReAssocCount++;if ((pDevice->byReAssocCount >10 ) && (pDevice->bLinkPass != true)) {//10 sec timeout printk ("Re-association timeout!!!\n" );
Signature · 1 line
2.0.4
PATCH 12/104 iio:bma180: Fix scale factors to report correct acceleration units
In reply to Jiri SlabyFrom: Peter Meerwald <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 381676d5e86596b11e22a62f196e192df6091373 upstream.
The userspace interface for acceleration sensors is documented as using m/s^2 units [Documentation/ABI/testing/sysfs-bus-iio]
The fullscale raw values for the BMA80 corresponds to -/+ 1, 1.5, 2, etc G depending on the selected mode.
The scale table was converting to G rather than m/s^2. Change the scaling table to match the documented interface.
See commit 71702e6e, iio: mma8452: Use correct acceleration units, for a related fix.
--- drivers/iio/accel/bma180.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iio/accel/bma180.c +3 -3
@@ -68,13 +68,13 @@/* Defaults values */ #define BMA180_DEF_PMODE 0#define BMA180_DEF_BW 20 -#define BMA180_DEF_SCALE 250 +#define BMA180_DEF_SCALE 2452/* Available values for sysfs */ #define BMA180_FLP_FREQ_AVAILABLE \ "10 20 40 75 150 300"#define BMA180_SCALE_AVAILABLE \ - "0.000130 0.000190 0.000250 0.000380 0.000500 0.000990 0.001980" + "0.001275 0.001863 0.002452 0.003727 0.004903 0.009709 0.019417"struct bma180_data {struct i2c_client *client;
@@ -94,7 +94,7 @@ enum bma180_axis { };static int bw_table[] = {10 ,20 ,40 ,75 ,150 ,300 };/* Hz */ -static int scale_table[] = {130 ,190 ,250 ,380 ,500 ,990 ,1980 }; +static int scale_table[] = {1275 ,1863 ,2452 ,3727 ,4903 ,9709 ,19417 };static int bma180_get_acc_reg (struct bma180_data *data,enum bma180_axis axis) {
Signature · 1 line
2.0.4
PATCH 13/104 iio:bma180: Missing check for frequency fractional part
In reply to Jiri SlabyFrom: Peter Meerwald <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9b2a4d35a6ceaf217be61ed8eb3c16986244f640 upstream.
val2 should be zero
This will make no difference for correct inputs but will reject incorrect ones with a decimal part in the value written to the sysfs interface.
--- drivers/iio/accel/bma180.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iio/accel/bma180.c +2 -0
@@ -376,6 +376,8 @@ static int bma180_write_raw(struct iio_dev *indio_dev,mutex_unlock (&data->mutex);return ret;case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY : +if (val2) +return -EINVAL ;mutex_lock (&data->mutex); ret =bma180_set_bw (data, val);mutex_unlock (&data->mutex);
Signature · 1 line
2.0.4
PATCH 14/104 iio: buffer: Fix demux table creation
In reply to Jiri SlabyFrom: Lars-Peter Clausen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 61bd55ce1667809f022be88da77db17add90ea4e upstream.
When creating the demux table we need to iterate over the selected scan mask for the buffer to get the samples which should be copied to destination buffer. Right now the code uses the mask which contains all active channels, which means the demux table contains entries which causes it to copy all the samples from source to destination buffer one by one without doing any demuxing.
--- drivers/iio/industrialio-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/industrialio-buffer.c +1 -1
@@ -876,7 +876,7 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev,/* Now we have the two masks, work from least sig and build up sizes */ for_each_set_bit (out_ind, - indio_dev->active_scan_mask, + buffer->scan_mask, indio_dev->masklength) { in_ind = find_next_bit(indio_dev->active_scan_mask, indio_dev->masklength,
Signature · 1 line
2.0.4
PATCH 15/104 dm bufio: fully initialize shrinker
In reply to Jiri SlabyFrom: Greg Thelen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d8c712ea471ce7a4fd1734ad2211adf8469ddddc upstream.
1d3d4437eae1 ("vmscan: per-node deferred work") added a flags field to struct shrinker assuming that all shrinkers were zero filled. The dm bufio shrinker is not zero filled, which leaves arbitrary kmalloc() data in flags. So far the only defined flags bit is SHRINKER_NUMA_AWARE. But there are proposed patches which add other bits to shrinker.flags (e.g. memcg awareness).
Rather than simply initializing the shrinker, this patch uses kzalloc() when allocating the dm_bufio_client to ensure that the embedded shrinker and any other similar structures are zeroed.
This fixes theoretical over aggressive shrinking of dm bufio objects. If the uninitialized dm_bufio_client.shrinker.flags contains SHRINKER_NUMA_AWARE then shrink_slab() would call the dm shrinker for each numa node rather than just once. This has been broken since 3.12.
--- drivers/md/dm-bufio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm-bufio.c +1 -1
@@ -1511,7 +1511,7 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsignBUG_ON (block_size <1 <<SECTOR_SHIFT || (block_size & (block_size -1 ))); - c =kmalloc (sizeof (*c),GFP_KERNEL ); + c =kzalloc (sizeof (*c),GFP_KERNEL );if (!c) { r = -ENOMEM ; goto bad_client;
Signature · 1 line
2.0.4
PATCH 16/104 dm cache: fix race affecting dirty block count
In reply to Jiri SlabyFrom: Anssi Hannula <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 44fa816bb778edbab6b6ddaaf24908dd6295937e upstream.
nr_dirty is updated without locking, causing it to drift so that it is non-zero (either a small positive integer, or a very large one when an underflow occurs) even when there are no actual dirty blocks. This was due to a race between the workqueue and map function accessing nr_dirty in parallel without proper protection.
People were seeing under runs due to a race on increment/decrement of nr_dirty, see: https://lkml.org/lkml/2014/6/3/648
Fix this by using an atomic_t for nr_dirty.
--- drivers/md/dm-cache-target.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/md/dm-cache-target.c +6 -7
@@ -154,7 +154,7 @@ struct cache {/* * cache_size entries, dirty if set */ -dm_cblock_t nr_dirty; +atomic_t nr_dirty;unsigned long *dirty_bitset;/*
@@ -408,7 +408,7 @@ static bool is_dirty(struct cache *cache, dm_cblock_t b)static void set_dirty (struct cache *cache,dm_oblock_t oblock,dm_cblock_t cblock) {if (!test_and_set_bit (from_cblock (cblock), cache->dirty_bitset)) { - cache->nr_dirty =to_cblock (from_cblock (cache->nr_dirty) +1 ); +atomic_inc (&cache->nr_dirty);policy_set_dirty (cache->policy, oblock); } }
@@ -417,8 +417,7 @@ static void clear_dirty(struct cache *cache, dm_oblock_t oblock, dm_cblock_t cbl {if (test_and_clear_bit (from_cblock (cblock), cache->dirty_bitset)) {policy_clear_dirty (cache->policy, oblock); - cache->nr_dirty =to_cblock (from_cblock (cache->nr_dirty) -1 ); -if (!from_cblock (cache->nr_dirty)) +if (atomic_dec_return (&cache->nr_dirty) ==0 )dm_table_event (cache->ti->table); } }
@@ -2006,7 +2005,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)atomic_set (&cache->quiescing_ack,0 ); r = -ENOMEM ; - cache->nr_dirty =0 ; +atomic_set (&cache->nr_dirty,0 ); cache->dirty_bitset =alloc_bitset (from_cblock (cache->cache_size));if (!cache->dirty_bitset) { *error ="could not allocate dirty bitset" ;
@@ -2502,7 +2501,7 @@ static void cache_status(struct dm_target *ti, status_type_t type, residency =policy_residency (cache->policy); - DMEMIT("%llu/%llu %u %u %u %u %u %u %llu %u ", + DMEMIT("%llu/%llu %u %u %u %u %u %u %llu %lu ", (unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata), (unsigned long long)nr_blocks_metadata, (unsigned) atomic_read(&cache->stats.read_hit),
@@ -2512,7 +2511,7 @@ static void cache_status(struct dm_target *ti, status_type_t type, (unsigned )atomic_read (&cache->stats.demotion), (unsigned )atomic_read (&cache->stats.promotion), (unsigned long long )from_cblock (residency), - cache->nr_dirty); + (unsigned long) atomic_read(&cache->nr_dirty));if (cache->features.write_through)DMEMIT ("1 writethrough " );
Signature · 1 line
2.0.4
PATCH 17/104 printk: rename printk_sched to printk_deferred
In reply to Jiri SlabyFrom: John Stultz <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit aac74dc495456412c4130a1167ce4beb6c1f0b38 upstream.
After learning we'll need some sort of deferred printk functionality in the timekeeping core, Peter suggested we rename the printk_sched function so it can be reused by needed subsystems.
This only changes the function name. No logic changes.
--- include/linux/printk.h | 6 +++--- kernel/printk/printk.c | 2 +- kernel/sched/core.c | 2 +- kernel/sched/rt.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-)
include/linux/printk.h +3 -3
@@ -124,9 +124,9 @@ asmlinkage __printf(1, 2) __coldint printk (const char *fmt, ...);/* -* Special printk facility for scheduler use only, _DO_NOT_USE_ ! +* Special printk facility for scheduler/timekeeping use only, _DO_NOT_USE_ ! */ -__printf(1, 2) __cold int printk_sched(const char *fmt, ...); +__printf(1, 2) __cold int printk_deferred(const char *fmt, ...);/* * Please don't use printk_ratelimit(), because it shares ratelimiting state
@@ -161,7 +161,7 @@ int printk(const char *s, ...)return 0 ; } static inline __printf(1, 2) __cold -int printk_sched(const char *s, ...) +int printk_deferred(const char *s, ...) {return 0 ; }
kernel/printk/printk.c +1 -1
@@ -2470,7 +2470,7 @@ void wake_up_klogd(void)preempt_enable (); } -int printk_sched (const char *fmt, ...) +int printk_deferred (const char *fmt, ...) {unsigned long flags;va_list args;
kernel/sched/core.c +1 -1
@@ -1224,7 +1224,7 @@ out:* leave kernel. */ if (p->mm &&printk_ratelimit ()) { -printk_sched ("process %d (%s) no longer affine to cpu%d\n" , +printk_deferred ("process %d (%s) no longer affine to cpu%d\n" ,task_pid_nr (p), p->comm, cpu); } }
kernel/sched/rt.c +1 -1
@@ -829,7 +829,7 @@ static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)if (!once) { once = true; -printk_sched ("sched: RT throttling activated\n" ); +printk_deferred ("sched: RT throttling activated\n" ); } }else {/*
Signature · 1 line
2.0.4
PATCH 18/104 timer: Fix lock inversion between hrtimer_bases.lock and scheduler locks
In reply to Jiri SlabyFrom: Jan Kara <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 504d58745c9ca28d33572e2d8a9990b43e06075d upstream.
clockevents_increase_min_delta() calls printk() from under hrtimer_bases.lock. That causes lock inversion on scheduler locks because printk() can call into the scheduler. Lockdep puts it as:
======================================================
[ INFO: possible circular locking dependency detected ] 3.15.0-rc8-06195-g939f04b #2 Not tainted
-------------------------------------------------------
trinity-main/74 is trying to acquire lock:
(&port_lock_key){-.....}, at: [<811c60be>] serial8250_console_write+0x8c/0x10c
but task is already holding lock:
(hrtimer_bases.lock){-.-...}, at: [<8103caeb>] hrtimer_try_to_cancel+0x13/0x66
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #5 (hrtimer_bases.lock){-.-...}:
[<8104a942>] lock_acquire+0x92/0x101
[<8142f11d>] _raw_spin_lock_irqsave+0x2e/0x3e
[<8103c918>] __hrtimer_start_range_ns+0x1c/0x197
[<8107ec20>] perf_swevent_start_hrtimer.part.41+0x7a/0x85
[<81080792>] task_clock_event_start+0x3a/0x3f
[<810807a4>] task_clock_event_add+0xd/0x14
[<8108259a>] event_sched_in+0xb6/0x17a
[<810826a2>] group_sched_in+0x44/0x122
[<81082885>] ctx_sched_in.isra.67+0x105/0x11f
[<810828e6>] perf_event_sched_in.isra.70+0x47/0x4b
[<81082bf6>] __perf_install_in_context+0x8b/0xa3
[<8107eb8e>] remote_function+0x12/0x2a
[<8105f5af>] smp_call_function_single+0x2d/0x53
[<8107e17d>] task_function_call+0x30/0x36
[<8107fb82>] perf_install_in_context+0x87/0xbb
[<810852c9>] SYSC_perf_event_open+0x5c6/0x701
[<810856f9>] SyS_perf_event_open+0x17/0x19
[<8142f8ee>] syscall_call+0x7/0xb-> #4 (&ctx->lock){......}:
[<8104a942>] lock_acquire+0x92/0x101
[<8142f04c>] _raw_spin_lock+0x21/0x30
[<81081df3>] __perf_event_task_sched_out+0x1dc/0x34f
[<8142cacc>] __schedule+0x4c6/0x4cb
[<8142cae0>] schedule+0xf/0x11
[<8142f9a6>] work_resched+0x5/0x30-> #3 (&rq->lock){-.-.-.}:
[<8104a942>] lock_acquire+0x92/0x101
[<8142f04c>] _raw_spin_lock+0x21/0x30
[<81040873>] __task_rq_lock+0x33/0x3a
[<8104184c>] wake_up_new_task+0x25/0xc2
[<8102474b>] do_fork+0x15c/0x2a0
[<810248a9>] kernel_thread+0x1a/0x1f
[<814232a2>] rest_init+0x1a/0x10e
[<817af949>] start_kernel+0x303/0x308
[<817af2ab>] i386_start_kernel+0x79/0x7d-> #2 (&p->pi_lock){-.-...}:
[<8104a942>] lock_acquire+0x92/0x101
[<8142f11d>] _raw_spin_lock_irqsave+0x2e/0x3e
[<810413dd>] try_to_wake_up+0x1d/0xd6
[<810414cd>] default_wake_function+0xb/0xd
[<810461f3>] __wake_up_common+0x39/0x59
[<81046346>] __wake_up+0x29/0x3b
[<811b8733>] tty_wakeup+0x49/0x51
[<811c3568>] uart_write_wakeup+0x17/0x19
[<811c5dc1>] serial8250_tx_chars+0xbc/0xfb
[<811c5f28>] serial8250_handle_irq+0x54/0x6a
[<811c5f57>] serial8250_default_handle_irq+0x19/0x1c
[<811c56d8>] serial8250_interrupt+0x38/0x9e
[<810510e7>] handle_irq_event_percpu+0x5f/0x1e2
[<81051296>] handle_irq_event+0x2c/0x43
[<81052cee>] handle_level_irq+0x57/0x80
[<81002a72>] handle_irq+0x46/0x5c
[<810027df>] do_IRQ+0x32/0x89
[<8143036e>] common_interrupt+0x2e/0x33
[<8142f23c>] _raw_spin_unlock_irqrestore+0x3f/0x49
[<811c25a4>] uart_start+0x2d/0x32
[<811c2c04>] uart_write+0xc7/0xd6
[<811bc6f6>] n_tty_write+0xb8/0x35e
[<811b9beb>] tty_write+0x163/0x1e4
[<811b9cd9>] redirected_tty_write+0x6d/0x75
[<810b6ed6>] vfs_write+0x75/0xb0
[<810b7265>] SyS_write+0x44/0x77
[<8142f8ee>] syscall_call+0x7/0xb-> #1 (&tty->write_wait){-.....}:
[<8104a942>] lock_acquire+0x92/0x101
[<8142f11d>] _raw_spin_lock_irqsave+0x2e/0x3e
[<81046332>] __wake_up+0x15/0x3b
[<811b8733>] tty_wakeup+0x49/0x51
[<811c3568>] uart_write_wakeup+0x17/0x19
[<811c5dc1>] serial8250_tx_chars+0xbc/0xfb
[<811c5f28>] serial8250_handle_irq+0x54/0x6a
[<811c5f57>] serial8250_default_handle_irq+0x19/0x1c
[<811c56d8>] serial8250_interrupt+0x38/0x9e
[<810510e7>] handle_irq_event_percpu+0x5f/0x1e2
[<81051296>] handle_irq_event+0x2c/0x43
[<81052cee>] handle_level_irq+0x57/0x80
[<81002a72>] handle_irq+0x46/0x5c
[<810027df>] do_IRQ+0x32/0x89
[<8143036e>] common_interrupt+0x2e/0x33
[<8142f23c>] _raw_spin_unlock_irqrestore+0x3f/0x49
[<811c25a4>] uart_start+0x2d/0x32
[<811c2c04>] uart_write+0xc7/0xd6
[<811bc6f6>] n_tty_write+0xb8/0x35e
[<811b9beb>] tty_write+0x163/0x1e4
[<811b9cd9>] redirected_tty_write+0x6d/0x75
[<810b6ed6>] vfs_write+0x75/0xb0
[<810b7265>] SyS_write+0x44/0x77
[<8142f8ee>] syscall_call+0x7/0xb-> #0 (&port_lock_key){-.....}:
[<8104a62d>] __lock_acquire+0x9ea/0xc6d
[<8104a942>] lock_acquire+0x92/0x101
[<8142f11d>] _raw_spin_lock_irqsave+0x2e/0x3e
[<811c60be>] serial8250_console_write+0x8c/0x10c
[<8104e402>] call_console_drivers.constprop.31+0x87/0x118
[<8104f5d5>] console_unlock+0x1d7/0x398
[<8104fb70>] vprintk_emit+0x3da/0x3e4
[<81425f76>] printk+0x17/0x19
[<8105bfa0>] clockevents_program_min_delta+0x104/0x116
[<8105c548>] clockevents_program_event+0xe7/0xf3
[<8105cc1c>] tick_program_event+0x1e/0x23
[<8103c43c>] hrtimer_force_reprogram+0x88/0x8f
[<8103c49e>] __remove_hrtimer+0x5b/0x79
[<8103cb21>] hrtimer_try_to_cancel+0x49/0x66
[<8103cb4b>] hrtimer_cancel+0xd/0x18
[<8107f102>] perf_swevent_cancel_hrtimer.part.60+0x2b/0x30
[<81080705>] task_clock_event_stop+0x20/0x64
[<81080756>] task_clock_event_del+0xd/0xf
[<81081350>] event_sched_out+0xab/0x11e
[<810813e0>] group_sched_out+0x1d/0x66
[<81081682>] ctx_sched_out+0xaf/0xbf
[<81081e04>] __perf_event_task_sched_out+0x1ed/0x34f
[<8142cacc>] __schedule+0x4c6/0x4cb
[<8142cae0>] schedule+0xf/0x11
[<8142f9a6>] work_resched+0x5/0x30other info that might help us debug this:
Chain exists of: &port_lock_key --> &ctx->lock --> hrtimer_bases.lock Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(hrtimer_bases.lock);
lock(&ctx->lock);
lock(hrtimer_bases.lock); lock(&port_lock_key);
*** DEADLOCK ***
4 locks held by trinity-main/74:
#0: (&rq->lock){-.-.-.}, at: [<8142c6f3>] __schedule+0xed/0x4cb
#1: (&ctx->lock){......}, at: [<81081df3>] __perf_event_task_sched_out+0x1dc/0x34f
#2: (hrtimer_bases.lock){-.-...}, at: [<8103caeb>] hrtimer_try_to_cancel+0x13/0x66
#3: (console_lock){+.+...}, at: [<8104fb5d>] vprintk_emit+0x3c7/0x3e4stack backtrace: CPU: 0 PID: 74 Comm: trinity-main Not tainted 3.15.0-rc8-06195-g939f04b #2 00000000 81c3a310 8b995c14 81426f69 8b995c44 81425a99 8161f671 8161f570 8161f538 8161f559 8161f538 8b995c78 8b142bb0 00000004 8b142fdc 8b142bb0 8b995ca8 8104a62d 8b142fac 000016f2 81c3a310 00000001 00000001 00000003 Call Trace: [<81426f69>] dump_stack+0x16/0x18 [<81425a99>] print_circular_bug+0x18f/0x19c [<8104a62d>] __lock_acquire+0x9ea/0xc6d [<8104a942>] lock_acquire+0x92/0x101 [<811c60be>] ? serial8250_console_write+0x8c/0x10c [<811c6032>] ? wait_for_xmitr+0x76/0x76 [<8142f11d>] _raw_spin_lock_irqsave+0x2e/0x3e [<811c60be>] ? serial8250_console_write+0x8c/0x10c [<811c60be>] serial8250_console_write+0x8c/0x10c [<8104af87>] ? lock_release+0x191/0x223 [<811c6032>] ? wait_for_xmitr+0x76/0x76 [<8104e402>] call_console_drivers.constprop.31+0x87/0x118 [<8104f5d5>] console_unlock+0x1d7/0x398 [<8104fb70>] vprintk_emit+0x3da/0x3e4 [<81425f76>] printk+0x17/0x19 [<8105bfa0>] clockevents_program_min_delta+0x104/0x116 [<8105cc1c>] tick_program_event+0x1e/0x23 [<8103c43c>] hrtimer_force_reprogram+0x88/0x8f [<8103c49e>] __remove_hrtimer+0x5b/0x79 [<8103cb21>] hrtimer_try_to_cancel+0x49/0x66 [<8103cb4b>] hrtimer_cancel+0xd/0x18 [<8107f102>] perf_swevent_cancel_hrtimer.part.60+0x2b/0x30 [<81080705>] task_clock_event_stop+0x20/0x64 [<81080756>] task_clock_event_del+0xd/0xf [<81081350>] event_sched_out+0xab/0x11e [<810813e0>] group_sched_out+0x1d/0x66 [<81081682>] ctx_sched_out+0xaf/0xbf [<81081e04>] __perf_event_task_sched_out+0x1ed/0x34f [<8104416d>] ? __dequeue_entity+0x23/0x27 [<81044505>] ? pick_next_task_fair+0xb1/0x120 [<8142cacc>] __schedule+0x4c6/0x4cb [<81047574>] ? trace_hardirqs_off_caller+0xd7/0x108 [<810475b0>] ? trace_hardirqs_off+0xb/0xd [<81056346>] ? rcu_irq_exit+0x64/0x77
Fix the problem by using printk_deferred() which does not call into the scheduler.
--- kernel/time/clockevents.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
kernel/time/clockevents.c +6 -4
@@ -146,7 +146,8 @@ static int clockevents_increase_min_delta(struct clock_event_device *dev) {/* Nothing to do if we already reached the limit */ if (dev->min_delta_ns >=MIN_DELTA_LIMIT ) { -printk (KERN_WARNING "CE: Reprogramming failure. Giving up\n" ); +printk_deferred (KERN_WARNING +"CE: Reprogramming failure. Giving up\n" ); dev->next_event.tv64 =KTIME_MAX ;return -ETIME ; }
@@ -159,9 +160,10 @@ static int clockevents_increase_min_delta(struct clock_event_device *dev)if (dev->min_delta_ns >MIN_DELTA_LIMIT ) dev->min_delta_ns =MIN_DELTA_LIMIT ; -printk (KERN_WARNING "CE: %s increased min_delta_ns to %llu nsec\n" , - dev->name ? dev->name :"?" , - (unsigned long long ) dev->min_delta_ns); +printk_deferred (KERN_WARNING +"CE: %s increased min_delta_ns to %llu nsec\n" , + dev->name ? dev->name :"?" , + (unsigned long long ) dev->min_delta_ns);return 0 ; }
Signature · 1 line
2.0.4
PATCH 19/104 Revert "x86-64, modify_ldt: Make support for 16-bit segments a runtime option"
In reply to Jiri SlabyFrom: "H. Peter Anvin" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7ed6fb9b5a5510e4ef78ab27419184741169978a upstream.
This reverts commit fa81511bb0bbb2b1aace3695ce869da9762624ff in preparation of merging in the proper fix (espfix64).
--- arch/x86/kernel/ldt.c | 4 +--- arch/x86/vdso/vdso32-setup.c | 8 -------- 2 files changed, 1 insertion(+), 11 deletions(-)
arch/x86/kernel/ldt.c +1 -3
@@ -20,8 +20,6 @@#include <asm/mmu_context.h> #include <asm/syscalls.h> -int sysctl_ldt16 =0 ; -#ifdef CONFIG_SMP static void flush_ldt (void *current_mm) {
@@ -236,7 +234,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)* IRET leaking the high bits of the kernel stack address. */ #ifdef CONFIG_X86_64 -if (!ldt_info.seg_32bit && !sysctl_ldt16) { +if (!ldt_info.seg_32bit) { error = -EINVAL ; goto out_unlock; }
arch/x86/vdso/vdso32-setup.c +0 -8
@@ -41,7 +41,6 @@ enum {#ifdef CONFIG_X86_64 #define vdso_enabled sysctl_vsyscall32#define arch_setup_additional_pages syscall32_setup_pages -extern int sysctl_ldt16;#endif /*
@@ -381,13 +380,6 @@ static struct ctl_table abi_table2[] = { .mode = 0644, .proc_handler = proc_dointvec }, - { - .procname = "ldt16", - .data = &sysctl_ldt16, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec - }, {} };
Signature · 1 line
2.0.4
PATCH 20/104 x86-64, espfix: Don't leak bits 31:16 of %esp returning to 16-bit stack
In reply to Jiri SlabyFrom: "H. Peter Anvin" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3891a04aafd668686239349ea58f3314ea2af86b upstream.
The IRET instruction, when returning to a 16-bit segment, only restores the bottom 16 bits of the user space stack pointer. This causes some 16-bit software to break, but it also leaks kernel state to user space. We have a software workaround for that ("espfix") for the 32-bit kernel, but it relies on a nonzero stack segment base which is not available in 64-bit mode.
In checkin:
b3b42ac2cbae x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels
we "solved" this by forbidding 16-bit segments on 64-bit kernels, with the logic that 16-bit support is crippled on 64-bit kernels anyway (no V86 support), but it turns out that people are doing stuff like running old Win16 binaries under Wine and expect it to work.
This works around this by creating percpu "ministacks", each of which is mapped 2^16 times 64K apart. When we detect that the return SS is on the LDT, we copy the IRET frame to the ministack and use the relevant alias to return to userspace. The ministacks are mapped readonly, so if IRET faults we promote #GP to #DF which is an IST vector and thus has its own stack; we then do the fixup in the #DF handler.
(Making #GP an IST exception would make the msr_safe functions unsafe in NMI/MC context, and quite possibly have other effects.)
Special thanks to:
- Andy Lutomirski, for the suggestion of using very small stack slots and copy (as opposed to map) the IRET frame there, and for the suggestion to mark them readonly and let the fault promote to #DF.
- Konrad Wilk for paravirt fixup and testing.
- Borislav Petkov for testing help and useful comments.
--- Documentation/x86/x86_64/mm.txt | 2 + arch/x86/include/asm/pgtable_64_types.h | 2 + arch/x86/include/asm/setup.h | 3 + arch/x86/kernel/Makefile | 1 + arch/x86/kernel/entry_64.S | 73 ++++++++++- arch/x86/kernel/espfix_64.c | 208 ++++++++++++++++++++++++++++++++ arch/x86/kernel/ldt.c | 11 -- arch/x86/kernel/smpboot.c | 7 ++ arch/x86/mm/dump_pagetables.c | 31 +++-- init/main.c | 4 + 10 files changed, 316 insertions(+), 26 deletions(-) create mode 100644 arch/x86/kernel/espfix_64.c
Documentation/x86/x86_64/mm.txt +2 -0
@@ -12,6 +12,8 @@ ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB) ... unused hole ... +ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks +... unused hole ... ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0 ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
arch/x86/include/asm/pgtable_64_types.h +2 -0
@@ -61,6 +61,8 @@ typedef struct { pteval_t pte; } pte_t;#define MODULES_VADDR _AC(0xffffffffa0000000, UL)#define MODULES_END _AC(0xffffffffff000000, UL)#define MODULES_LEN (MODULES_END - MODULES_VADDR) +#define ESPFIX_PGD_ENTRY _AC(-2, UL) +#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)#define EARLY_DYNAMIC_PAGE_TABLES 64
arch/x86/include/asm/setup.h +3 -0
@@ -62,6 +62,9 @@ extern void x86_ce4100_early_setup(void);static inline void x86_ce4100_early_setup (void ) { }#endif +extern void init_espfix_bsp (void ); +extern void init_espfix_ap (void ); +#ifndef _SETUP/*
arch/x86/kernel/Makefile +1 -0
@@ -29,6 +29,7 @@ obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o obj-y += syscall_$(BITS).o obj-$(CONFIG_X86_64) += vsyscall_64.o obj-$(CONFIG_X86_64) += vsyscall_emu_64.o +obj-$(CONFIG_X86_64) += espfix_64.o obj-y += bootflag.o e820.o obj-y += pci-dma.o quirks.o topology.o kdebugfs.o obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
arch/x86/kernel/entry_64.S +69 -4
112 lines not on this page · raw message
arch/x86/kernel/espfix_64.c new file +208 -0
208 lines not on this page · raw message
arch/x86/kernel/ldt.c +0 -11
@@ -229,17 +229,6 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) } } -/* -* On x86-64 we do not support 16-bit segments due to -* IRET leaking the high bits of the kernel stack address. -*/ -#ifdef CONFIG_X86_64 -if (!ldt_info.seg_32bit) { - error = -EINVAL ; - goto out_unlock; - } -#endif -fill_ldt (&ldt, &ldt_info);if (oldmode) ldt.avl =0 ;
arch/x86/kernel/smpboot.c +7 -0
@@ -265,6 +265,13 @@ static void notrace start_secondary(void *unused)check_tsc_sync_target ();/* +* Enable the espfix hack for this CPU +*/ +#ifdef CONFIG_X86_64 +init_espfix_ap (); +#endif + +/* * We need to hold vector_lock so there the set of online cpus * does not change while we are assigning vectors to cpus. Holding * this lock ensures we don't half assign or remove an irq from a cpu.
arch/x86/mm/dump_pagetables.c +20 -11
@@ -30,11 +30,13 @@ struct pg_state {unsigned long start_address;unsigned long current_address;const struct addr_marker *marker; +unsigned long lines; };struct addr_marker {unsigned long start_address;const char *name; +unsigned long max_lines; };/* indices for address_markers; keep sync'd w/ address_markers below */
@@ -45,6 +47,7 @@ enum address_markers_idx {LOW_KERNEL_NR ,VMALLOC_START_NR ,VMEMMAP_START_NR , +ESPFIX_START_NR ,HIGH_KERNEL_NR ,MODULES_VADDR_NR , MODULES_END_NR,
@@ -67,6 +70,7 @@ static struct addr_marker address_markers[] = { { PAGE_OFFSET, "Low Kernel Mapping" }, { VMALLOC_START, "vmalloc() Area" }, { VMEMMAP_START, "Vmemmap" }, + { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, { __START_KERNEL_map, "High Kernel Mapping" }, { MODULES_VADDR, "Modules" }, { MODULES_END, "End Modules" },
@@ -163,7 +167,7 @@ static void note_page(struct seq_file *m, struct pg_state *st, pgprot_t new_prot, int level) {pgprotval_t prot, cur; -static const char units[] ="KMGTPE" ; +static const char units[] ="BKMGTPE" ;/* * If we have a "break" in the series, we need to flush the state that
@@ -178,6 +182,7 @@ static void note_page(struct seq_file *m, struct pg_state *st, st->current_prot = new_prot; st->level = level; st->marker = address_markers; + st->lines =0 ;seq_printf (m,"---[ %s ]---\n" , st->marker->name); }else if (prot != cur || level != st->level || st->current_address >= st->marker[1 ].start_address) {
@@ -188,17 +193,21 @@ static void note_page(struct seq_file *m, struct pg_state *st,/* * Now print the actual finished series */ -seq_printf (m,"0x%0*lx-0x%0*lx " , - width, st->start_address, - width, st->current_address); - - delta = (st->current_address - st->start_address) >>10 ; -while (!(delta &1023 ) && unit[1 ]) { - delta >>=10 ; - unit++; +if (!st->marker->max_lines || + st->lines < st->marker->max_lines) { +seq_printf (m,"0x%0*lx-0x%0*lx " , + width, st->start_address, + width, st->current_address); + + delta = (st->current_address - st->start_address) >>10 ; +while (!(delta &1023 ) && unit[1 ]) { + delta >>=10 ; + unit++; + } +seq_printf (m,"%9lu%c " , delta, *unit); +printk_prot (m, st->current_prot, st->level); } -seq_printf (m,"%9lu%c " , delta, *unit); -printk_prot (m, st->current_prot, st->level); + st->lines++;/* * We print markers for special areas of address space,
init/main.c +4 -0
@@ -610,6 +610,10 @@ asmlinkage void __init start_kernel(void)if (efi_enabled (EFI_RUNTIME_SERVICES ))efi_enter_virtual_mode ();#endif +#ifdef CONFIG_X86_64 +/* Should be run before the first non-init thread is created */ +init_espfix_bsp (); +#endif thread_info_cache_init ();cred_init ();fork_init (totalram_pages);
Signature · 1 line
2.0.4
PATCH 21/104 x86, espfix: Move espfix definitions into a separate header file
In reply to Jiri SlabyFrom: "H. Peter Anvin" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e1fe9ed8d2a4937510d0d60e20705035c2609aea upstream.
Sparse warns that the percpu variables aren't declared before they are defined. Rather than hacking around it, move espfix definitions into a proper header file.
--- arch/x86/include/asm/espfix.h | 16 ++++++++++++++++ arch/x86/include/asm/setup.h | 5 ++--- arch/x86/kernel/espfix_64.c | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 arch/x86/include/asm/espfix.h
arch/x86/include/asm/espfix.h new file +16 -0
@@ -0,0 +1,16 @@ +#ifdef _ASM_X86_ESPFIX_H +#define _ASM_X86_ESPFIX_H + +#ifdef CONFIG_X86_64 + +#include <asm/percpu.h> + +DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack); +DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr); + +extern void init_espfix_bsp (void ); +extern void init_espfix_ap (void ); + +#endif /* CONFIG_X86_64 */ + +#endif /* _ASM_X86_ESPFIX_H */
arch/x86/include/asm/setup.h +2 -3
@@ -62,11 +62,10 @@ extern void x86_ce4100_early_setup(void);static inline void x86_ce4100_early_setup (void ) { }#endif -extern void init_espfix_bsp (void ); -extern void init_espfix_ap (void ); -#ifndef _SETUP +#include <asm/espfix.h> +/* * This is set up by the setup-routine at boot-time */
arch/x86/kernel/espfix_64.c +1 -0
@@ -40,6 +40,7 @@#include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/setup.h> +#include <asm/espfix.h> /* * Note: we only need 6*8 = 48 bytes for the espfix stack, but round
Signature · 1 line
2.0.4
PATCH 22/104 x86, espfix: Fix broken header guard
In reply to Jiri SlabyFrom: "H. Peter Anvin" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 20b68535cd27183ebd3651ff313afb2b97dac941 upstream.
Header guard is #ifndef, not #ifdef...
--- arch/x86/include/asm/espfix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/espfix.h +1 -1
@@ -1,4 +1,4 @@ -#ifdef _ASM_X86_ESPFIX_H +#ifndef _ASM_X86_ESPFIX_H#define _ASM_X86_ESPFIX_H#ifdef CONFIG_X86_64
Signature · 1 line
2.0.4
PATCH 23/104 x86, espfix: Make espfix64 a Kconfig option, fix UML
In reply to Jiri SlabyFrom: "H. Peter Anvin" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 197725de65477bc8509b41388157c1a2283542bb upstream.
Make espfix64 a hidden Kconfig option. This fixes the x86-64 UML build which had broken due to the non-existence of init_espfix_bsp() in UML: since UML uses its own Kconfig, this option does not appear in the UML build.
This also makes it possible to make support for 16-bit segments a configuration option, for the people who want to minimize the size of the kernel.
--- arch/x86/Kconfig | 4 ++++ arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/smpboot.c | 2 +- init/main.c | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-)
arch/x86/Kconfig +4 -0
@@ -978,6 +978,10 @@ config VM86 XFree86 to initialize some video cards via BIOS. Disabling this option saves about 6k. +config X86_ESPFIX64 + def_bool y + depends on X86_64 + config TOSHIBA tristate "Toshiba Laptop support" depends on X86_32
arch/x86/kernel/Makefile +1 -1
@@ -29,7 +29,7 @@ obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o obj-y += syscall_$(BITS).o obj-$(CONFIG_X86_64) += vsyscall_64.o obj-$(CONFIG_X86_64) += vsyscall_emu_64.o -obj-$(CONFIG_X86_64) += espfix_64.o +obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o obj-y += bootflag.o e820.o obj-y += pci-dma.o quirks.o topology.o kdebugfs.o obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
arch/x86/kernel/smpboot.c +1 -1
@@ -267,7 +267,7 @@ static void notrace start_secondary(void *unused)/* * Enable the espfix hack for this CPU */ -#ifdef CONFIG_X86_64 +#ifdef CONFIG_X86_ESPFIX64 init_espfix_ap ();#endif
init/main.c +1 -1
@@ -610,7 +610,7 @@ asmlinkage void __init start_kernel(void)if (efi_enabled (EFI_RUNTIME_SERVICES ))efi_enter_virtual_mode ();#endif -#ifdef CONFIG_X86_64 +#ifdef CONFIG_X86_ESPFIX64 /* Should be run before the first non-init thread is created */ init_espfix_bsp ();#endif
Signature · 1 line
2.0.4
PATCH 24/104 x86, espfix: Make it possible to disable 16-bit support
In reply to Jiri SlabyFrom: "H. Peter Anvin" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 34273f41d57ee8d854dcd2a1d754cbb546cb548f upstream.
Embedded systems, which may be very memory-size-sensitive, are extremely unlikely to ever encounter any 16-bit software, so make it a CONFIG_EXPERT option to turn off support for any 16-bit software whatsoever.
--- arch/x86/Kconfig | 23 ++++++++++++++++++----- arch/x86/kernel/entry_32.S | 12 ++++++++++++ arch/x86/kernel/entry_64.S | 8 ++++++++ arch/x86/kernel/ldt.c | 5 +++++ 4 files changed, 43 insertions(+), 5 deletions(-)
arch/x86/Kconfig +18 -5
@@ -973,14 +973,27 @@ config VM86 default y depends on X86_32 ---help--- - This option is required by programs like DOSEMU to run 16-bit legacy - code on X86 processors. It also may be needed by software like - XFree86 to initialize some video cards via BIOS. Disabling this - option saves about 6k. + This option is required by programs like DOSEMU to run + 16-bit real mode legacy code on x86 processors. It also may + be needed by software like XFree86 to initialize some video + cards via BIOS. Disabling this option saves about 6K. + +config X86_16BIT + bool "Enable support for 16-bit segments" if EXPERT + default y + ---help--- + This option is required by programs like Wine to run 16-bit + protected mode legacy code on x86 processors. Disabling + this option saves about 300 bytes on i386, or around 6K text + plus 16K runtime memory on x86-64, + +config X86_ESPFIX32 + def_bool y + depends on X86_16BIT && X86_32 config X86_ESPFIX64 def_bool y - depends on X86_64 + depends on X86_16BIT && X86_64 config TOSHIBA tristate "Toshiba Laptop support"
arch/x86/kernel/entry_32.S +12 -0
@@ -532,6 +532,7 @@ syscall_exit: restore_all: TRACE_IRQS_IRET restore_all_notrace: +#ifdef CONFIG_X86_ESPFIX32 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS # Warning: PT_OLDSS(%esp) contains the wrong/random values if we # are returning to the kernel.
@@ -542,6 +543,7 @@ restore_all_notrace: cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax CFI_REMEMBER_STATE je ldt_ss # returning to user-space with LDT SS +#endif restore_nocheck: RESTORE_REGS 4 # skip orig_eax/error_code irq_return:
@@ -554,6 +556,7 @@ ENTRY(iret_exc) .previous _ASM_EXTABLE(irq_return,iret_exc) +#ifdef CONFIG_X86_ESPFIX32 CFI_RESTORE_STATE ldt_ss: #ifdef CONFIG_PARAVIRT
@@ -597,6 +600,7 @@ ldt_ss: lss (%esp), %esp /* switch to espfix segment */ CFI_ADJUST_CFA_OFFSET -8 jmp restore_nocheck +#endif CFI_ENDPROC ENDPROC(system_call)
@@ -709,6 +713,7 @@ END(syscall_badsys) * the high word of the segment base from the GDT and swiches to the * normal stack and adjusts ESP with the matching offset. */ +#ifdef CONFIG_X86_ESPFIX32 /* fixup the stack */ mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */ mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
@@ -718,8 +723,10 @@ END(syscall_badsys) pushl_cfi %eax lss (%esp), %esp /* switch to the normal stack segment */ CFI_ADJUST_CFA_OFFSET -8 +#endif .endm .macro UNWIND_ESPFIX_STACK +#ifdef CONFIG_X86_ESPFIX32 movl %ss, %eax /* see if on espfix stack */ cmpw $__ESPFIX_SS, %ax
@@ -730,6 +737,7 @@ END(syscall_badsys) /* switch to normal stack */ FIXUP_ESPFIX_STACK 27: +#endif .endm /*
@@ -1350,11 +1358,13 @@ END(debug) ENTRY(nmi) RING0_INT_FRAME ASM_CLAC +#ifdef CONFIG_X86_ESPFIX32 pushl_cfi %eax movl %ss, %eax cmpw $__ESPFIX_SS, %ax popl_cfi %eax je nmi_espfix_stack +#endif cmpl $ia32_sysenter_target,(%esp) je nmi_stack_fixup pushl_cfi %eax
@@ -1394,6 +1404,7 @@ nmi_debug_stack_check: FIX_STACK 24, nmi_stack_correct, 1 jmp nmi_stack_correct +#ifdef CONFIG_X86_ESPFIX32 nmi_espfix_stack: /* We have a RING0_INT_FRAME here. *
@@ -1415,6 +1426,7 @@ nmi_espfix_stack: lss 12+4(%esp), %esp # back to espfix stack CFI_ADJUST_CFA_OFFSET -24 jmp irq_return +#endif CFI_ENDPROC END(nmi)
arch/x86/kernel/entry_64.S +8 -0
@@ -1045,8 +1045,10 @@ irq_return: * Are we returning to a stack segment from the LDT? Note: in * 64-bit mode SS:RSP on the exception stack is always valid. */ +#ifdef CONFIG_X86_ESPFIX64 testb $4,(SS-RIP)(%rsp) jnz irq_return_ldt +#endif irq_return_iret: INTERRUPT_RETURN
@@ -1058,6 +1060,7 @@ ENTRY(native_iret) _ASM_EXTABLE(native_iret, bad_iret) #endif +#ifdef CONFIG_X86_ESPFIX64 irq_return_ldt: pushq_cfi %rax pushq_cfi %rdi
@@ -1081,6 +1084,7 @@ irq_return_ldt: movq %rax,%rsp popq_cfi %rax jmp irq_return_iret +#endif .section .fixup,"ax" bad_iret:
@@ -1154,6 +1158,7 @@ END(common_interrupt) * modify the stack to make it look like we just entered * the #GP handler from user space, similar to bad_iret. */ +#ifdef CONFIG_X86_ESPFIX64 ALIGN __do_double_fault: XCPT_FRAME 1 RDI+8
@@ -1179,6 +1184,9 @@ __do_double_fault: retq CFI_ENDPROC END(__do_double_fault) +#else +# define __do_double_fault do_double_fault +#endif /* * End of kprobes section
arch/x86/kernel/ldt.c +5 -0
@@ -229,6 +229,11 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) } } +if (!IS_ENABLED (CONFIG_X86_16BIT ) && !ldt_info.seg_32bit) { + error = -EINVAL ; + goto out_unlock; + } +fill_ldt (&ldt, &ldt_info);if (oldmode) ldt.avl =0 ;
Signature · 1 line
2.0.4
PATCH 25/104 x86_64/entry/xen: Do not invoke espfix64 on Xen
In reply to Jiri SlabyFrom: Andy Lutomirski <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7209a75d2009dbf7745e2fd354abf25c3deb3ca3 upstream.
This moves the espfix64 logic into native_iret. To make this work, it gets rid of the native patch for INTERRUPT_RETURN:INTERRUPT_RETURN on native kernels is now 'jmp native_iret'.
This changes the 16-bit SS behavior on Xen from OOPSing to leaking some bits of the Xen hypervisor's RSP (I think).
[ hpa: this is a nonzero cost on native, but probably not enough to
measure. Xen needs to fix this in their own code, probably doing something equivalent to espfix64. ]
--- arch/x86/include/asm/irqflags.h | 2 +- arch/x86/kernel/entry_64.S | 28 ++++++++++------------------ arch/x86/kernel/paravirt_patch_64.c | 2 -- 3 files changed, 11 insertions(+), 21 deletions(-)
arch/x86/include/asm/irqflags.h +1 -1
@@ -129,7 +129,7 @@ static inline notrace unsigned long arch_local_irq_save(void)#define PARAVIRT_ADJUST_EXCEPTION_FRAME /* */ -#define INTERRUPT_RETURN iretq +#define INTERRUPT_RETURN jmp native_iret#define USERGS_SYSRET64 \ swapgs; \ sysretq;
arch/x86/kernel/entry_64.S +10 -18
@@ -1041,27 +1041,24 @@ restore_args: RESTORE_ARGS 1,8,1 irq_return: + INTERRUPT_RETURN + +ENTRY(native_iret) /* * Are we returning to a stack segment from the LDT? Note: in * 64-bit mode SS:RSP on the exception stack is always valid. */ #ifdef CONFIG_X86_ESPFIX64 testb $4,(SS-RIP)(%rsp) - jnz irq_return_ldt + jnz native_irq_return_ldt #endif -irq_return_iret: - INTERRUPT_RETURN - _ASM_EXTABLE(irq_return_iret, bad_iret) - -#ifdef CONFIG_PARAVIRT -ENTRY(native_iret) +native_irq_return_iret: iretq - _ASM_EXTABLE(native_iret, bad_iret) -#endif + _ASM_EXTABLE(native_irq_return_iret, bad_iret) #ifdef CONFIG_X86_ESPFIX64 -irq_return_ldt: +native_irq_return_ldt: pushq_cfi %rax pushq_cfi %rdi SWAPGS
@@ -1083,7 +1080,7 @@ irq_return_ldt: SWAPGS movq %rax,%rsp popq_cfi %rax - jmp irq_return_iret + jmp native_irq_return_iret #endif .section .fixup,"ax"
@@ -1169,13 +1166,8 @@ __do_double_fault: cmpl $__KERNEL_CS,CS(%rdi) jne do_double_fault movq RIP(%rdi),%rax - cmpq $irq_return_iret,%rax -#ifdef CONFIG_PARAVIRT - je 1f - cmpq $native_iret,%rax -#endif + cmpq $native_irq_return_iret,%rax jne do_double_fault /* This shouldn't happen... */ -1: movq PER_CPU_VAR(kernel_stack),%rax subq $(6*8-KERNEL_STACK_OFFSET),%rax /* Reset to original stack */ movq %rax,RSP(%rdi)
@@ -1665,7 +1657,7 @@ error_sti: */ error_kernelspace: incl %ebx - leaq irq_return_iret(%rip),%rcx + leaq native_irq_return_iret(%rip),%rcx cmpq %rcx,RIP+8(%rsp) je error_swapgs movl %ecx,%eax /* zero extend */
arch/x86/kernel/paravirt_patch_64.c +0 -2
@@ -6,7 +6,6 @@ DEF_NATIVE(pv_irq_ops, irq_disable, "cli");DEF_NATIVE (pv_irq_ops, irq_enable,"sti" );DEF_NATIVE (pv_irq_ops, restore_fl,"pushq %rdi; popfq" );DEF_NATIVE (pv_irq_ops, save_fl,"pushfq; popq %rax" ); -DEF_NATIVE (pv_cpu_ops, iret,"iretq" );DEF_NATIVE (pv_mmu_ops, read_cr2,"movq %cr2, %rax" );DEF_NATIVE (pv_mmu_ops, read_cr3,"movq %cr3, %rax" );DEF_NATIVE (pv_mmu_ops, write_cr3,"movq %rdi, %cr3" );
@@ -50,7 +49,6 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,PATCH_SITE (pv_irq_ops, save_fl);PATCH_SITE (pv_irq_ops, irq_enable);PATCH_SITE (pv_irq_ops, irq_disable); -PATCH_SITE (pv_cpu_ops, iret);PATCH_SITE (pv_cpu_ops, irq_enable_sysexit);PATCH_SITE (pv_cpu_ops, usergs_sysret32);PATCH_SITE (pv_cpu_ops, usergs_sysret64);
Signature · 1 line
2.0.4
PATCH 26/104 staging: vt6655: Fix Warning on boot handle_irq_event_percpu.
In reply to Jiri SlabyFrom: Malcolm Priestley <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6cff1f6ad4c615319c1a146b2aa0af1043c5e9f5 upstream.
WARNING: CPU: 0 PID: 929 at /home/apw/COD/linux/kernel/irq/handle.c:147 handle_irq_event_percpu+0x1d1/0x1e0() irq 17 handler device_intr+0x0/0xa80 [vt6655_stage] enabled interrupts
Using spin_lock_irqsave appears to fix this.
--- drivers/staging/vt6655/device_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/staging/vt6655/device_main.c +5 -2
@@ -2434,6 +2434,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) {int handled =0 ;unsigned char byData =0 ;int ii =0 ; +unsigned long flags;// unsigned char byRSSI; MACvReadISR (pDevice->PortOffset, &pDevice->dwIsr);
@@ -2459,7 +2460,8 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { handled =1 ;MACvIntDisable (pDevice->PortOffset); -spin_lock_irq (&pDevice->lock); + +spin_lock_irqsave (&pDevice->lock, flags);//Make sure current page is 0 VNSvInPortB (pDevice->PortOffset +MAC_REG_PAGE1SEL , &byOrgPageSel);
@@ -2700,7 +2702,8 @@ static irqreturn_t device_intr(int irq, void *dev_instance) {MACvSelectPage1 (pDevice->PortOffset); } -spin_unlock_irq (&pDevice->lock); +spin_unlock_irqrestore (&pDevice->lock, flags); +MACvIntEnable (pDevice->PortOffset,IMR_MASK_VALUE );return IRQ_RETVAL (handled);
Signature · 1 line
2.0.4
PATCH 27/104 Revert "mac80211: move "bufferable MMPDU" check to fix AP mode scan"
In reply to Jiri SlabyFrom: Johannes Berg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 08b9939997df30e42a228e1ecb97f99e9c8ea84e upstream.
This reverts commit 277d916fc2e959c3f106904116bb4f7b1148d47a as it was at least breaking iwlwifi by setting the IEEE80211_TX_CTL_NO_PS_BUFFER flag in all kinds of interface modes, not only for AP mode where it is appropriate.
To avoid reintroducing the original problem, explicitly check for probe request frames in the multicast buffering code.
--- net/mac80211/tx.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
net/mac80211/tx.c +13 -14
@@ -413,6 +413,9 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)if (ieee80211_has_order (hdr->frame_control))return TX_CONTINUE ; +if (ieee80211_is_probe_req (hdr->frame_control)) +return TX_CONTINUE ; +if (tx->local->hw.flags &IEEE80211_HW_QUEUE_CONTROL ) info->hw_queue = tx->sdata->vif.cab_queue;
@@ -463,6 +466,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) {struct sta_info *sta = tx->sta;struct ieee80211_tx_info *info =IEEE80211_SKB_CB (tx->skb); +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;struct ieee80211_local *local = tx->local;if (unlikely (!sta))
@@ -473,6 +477,15 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {int ac =skb_get_queue_mapping (tx->skb); +/* only deauth, disassoc and action are bufferable MMPDUs */ +if (ieee80211_is_mgmt (hdr->frame_control) && + !ieee80211_is_deauth (hdr->frame_control) && + !ieee80211_is_disassoc (hdr->frame_control) && + !ieee80211_is_action (hdr->frame_control)) { + info->flags |=IEEE80211_TX_CTL_NO_PS_BUFFER ; +return TX_CONTINUE ; + } +ps_dbg (sta->sdata,"STA %pM aid %d: PS buffer for AC %d\n" , sta->sta.addr, sta->sta.aid, ac);if (tx->local->total_ps_buffered >=TOTAL_MAX_TX_BUFFER )
@@ -530,22 +543,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) static ieee80211_tx_result debug_noinlineieee80211_tx_h_ps_buf (struct ieee80211_tx_data *tx) { -struct ieee80211_tx_info *info =IEEE80211_SKB_CB (tx->skb); -struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; -if (unlikely (tx->flags &IEEE80211_TX_PS_BUFFERED ))return TX_CONTINUE ; - -/* only deauth, disassoc and action are bufferable MMPDUs */ -if (ieee80211_is_mgmt (hdr->frame_control) && - !ieee80211_is_deauth (hdr->frame_control) && - !ieee80211_is_disassoc (hdr->frame_control) && - !ieee80211_is_action (hdr->frame_control)) { -if (tx->flags &IEEE80211_TX_UNICAST ) - info->flags |=IEEE80211_TX_CTL_NO_PS_BUFFER ; -return TX_CONTINUE ; - } -if (tx->flags &IEEE80211_TX_UNICAST )return ieee80211_tx_h_unicast_ps_buf (tx);else
Signature · 1 line
2.0.4
PATCH 28/104 xtensa: add fixup for double exception raised in window overflow
In reply to Jiri SlabyFrom: Max Filippov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 17290231df16eeee5dfc198dbf5ee4b419996dcd upstream.
There are two FIXMEs in the double exception handler 'for the extremely unlikely case'. This case gets hit by gcc during kernel build once in a few hours, resulting in an unrecoverable exception condition.
Provide missing fixup routine to handle this case. Double exception literals now need 8 more bytes, add them to the linker script.
Also replace bbsi instructions with bbsi.l as we're branching depending on 8th and 7th LSB-based bits of exception address.
This may be tested by adding the explicit DTLB invalidation to window overflow handlers, like the following:
# --- a/arch/xtensa/kernel/vectors.S # +++ b/arch/xtensa/kernel/vectors.S # @@ -592,6 +592,14 @@ ENDPROC(_WindowUnderflow4) # ENTRY_ALIGN64(_WindowOverflow8) # # s32e a0, a9, -16 # + bbsi.l a9, 31, 1f # + rsr a0, ccount # + bbsi.l a0, 4, 1f # + pdtlb a0, a9 # + idtlb a0 # + movi a0, 9 # + idtlb a0 # +1: # l32e a0, a1, -12 # s32e a2, a9, -8 # s32e a1, a9, -12
--- arch/xtensa/kernel/vectors.S | 158 +++++++++++++++++++++++++++++++++------ arch/xtensa/kernel/vmlinux.lds.S | 4 +- 2 files changed, 138 insertions(+), 24 deletions(-)
arch/xtensa/kernel/vectors.S +136 -22
@@ -376,38 +376,42 @@ _DoubleExceptionVector_WindowOverflow: beqz a2, 1f # if at start of vector, don't restore addi a0, a0, -128 - bbsi a0, 8, 1f # don't restore except for overflow 8 and 12 - bbsi a0, 7, 2f + bbsi.l a0, 8, 1f # don't restore except for overflow 8 and 12 + + /* + * This fixup handler is for the extremely unlikely case where the + * overflow handler's reference thru a0 gets a hardware TLB refill + * that bumps out the (distinct, aliasing) TLB entry that mapped its + * prior references thru a9/a13, and where our reference now thru + * a9/a13 gets a 2nd-level miss exception (not hardware TLB refill). + */ + movi a2, window_overflow_restore_a0_fixup + s32i a2, a3, EXC_TABLE_FIXUP + l32i a2, a3, EXC_TABLE_DOUBLE_SAVE + xsr a3, excsave1 + + bbsi.l a0, 7, 2f /* * Restore a0 as saved by _WindowOverflow8(). - * - * FIXME: we really need a fixup handler for this L32E, - * for the extremely unlikely case where the overflow handler's - * reference thru a0 gets a hardware TLB refill that bumps out - * the (distinct, aliasing) TLB entry that mapped its prior - * references thru a9, and where our reference now thru a9 - * gets a 2nd-level miss exception (not hardware TLB refill). */ - l32e a2, a9, -16 - wsr a2, depc # replace the saved a0 - j 1f + l32e a0, a9, -16 + wsr a0, depc # replace the saved a0 + j 3f 2: /* * Restore a0 as saved by _WindowOverflow12(). - * - * FIXME: we really need a fixup handler for this L32E, - * for the extremely unlikely case where the overflow handler's - * reference thru a0 gets a hardware TLB refill that bumps out - * the (distinct, aliasing) TLB entry that mapped its prior - * references thru a13, and where our reference now thru a13 - * gets a 2nd-level miss exception (not hardware TLB refill). */ - l32e a2, a13, -16 - wsr a2, depc # replace the saved a0 + l32e a0, a13, -16 + wsr a0, depc # replace the saved a0 +3: + xsr a3, excsave1 + movi a0, 0 + s32i a0, a3, EXC_TABLE_FIXUP + s32i a2, a3, EXC_TABLE_DOUBLE_SAVE 1: /* * Restore WindowBase while leaving all address registers restored.
@@ -449,6 +453,7 @@ _DoubleExceptionVector_WindowOverflow: s32i a0, a2, PT_DEPC +_DoubleExceptionVector_handle_exception: addx4 a0, a0, a3 l32i a0, a0, EXC_TABLE_FAST_USER xsr a3, excsave1
@@ -464,11 +469,120 @@ _DoubleExceptionVector_WindowOverflow: rotw -3 j 1b - .end literal_prefix ENDPROC(_DoubleExceptionVector) /* + * Fixup handler for TLB miss in double exception handler for window owerflow. + * We get here with windowbase set to the window that was being spilled and + * a0 trashed. a0 bit 7 determines if this is a call8 (bit clear) or call12 + * (bit set) window. + * + * We do the following here: + * - go to the original window retaining a0 value; + * - set up exception stack to return back to appropriate a0 restore code + * (we'll need to rotate window back and there's no place to save this + * information, use different return address for that); + * - handle the exception; + * - go to the window that was being spilled; + * - set up window_overflow_restore_a0_fixup as a fixup routine; + * - reload a0; + * - restore the original window; + * - reset the default fixup routine; + * - return to user. By the time we get to this fixup handler all information + * about the conditions of the original double exception that happened in + * the window overflow handler is lost, so we just return to userspace to + * retry overflow from start. + * + * a0: value of depc, original value in depc + * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE + * a3: exctable, original value in excsave1 + */ + +ENTRY(window_overflow_restore_a0_fixup) + + rsr a0, ps + extui a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH + rsr a2, windowbase + sub a0, a2, a0 + extui a0, a0, 0, 3 + l32i a2, a3, EXC_TABLE_DOUBLE_SAVE + xsr a3, excsave1 + + _beqi a0, 1, .Lhandle_1 + _beqi a0, 3, .Lhandle_3 + + .macro overflow_fixup_handle_exception_pane n + + rsr a0, depc + rotw -\n + + xsr a3, excsave1 + wsr a2, depc + l32i a2, a3, EXC_TABLE_KSTK + s32i a0, a2, PT_AREG0 + + movi a0, .Lrestore_\n + s32i a0, a2, PT_DEPC + rsr a0, exccause + j _DoubleExceptionVector_handle_exception + + .endm + + overflow_fixup_handle_exception_pane 2 +.Lhandle_1: + overflow_fixup_handle_exception_pane 1 +.Lhandle_3: + overflow_fixup_handle_exception_pane 3 + + .macro overflow_fixup_restore_a0_pane n + + rotw \n + /* Need to preserve a0 value here to be able to handle exception + * that may occur on a0 reload from stack. It may occur because + * TLB miss handler may not be atomic and pointer to page table + * may be lost before we get here. There are no free registers, + * so we need to use EXC_TABLE_DOUBLE_SAVE area. + */ + xsr a3, excsave1 + s32i a2, a3, EXC_TABLE_DOUBLE_SAVE + movi a2, window_overflow_restore_a0_fixup + s32i a2, a3, EXC_TABLE_FIXUP + l32i a2, a3, EXC_TABLE_DOUBLE_SAVE + xsr a3, excsave1 + bbsi.l a0, 7, 1f + l32e a0, a9, -16 + j 2f +1: + l32e a0, a13, -16 +2: + rotw -\n + + .endm + +.Lrestore_2: + overflow_fixup_restore_a0_pane 2 + +.Lset_default_fixup: + xsr a3, excsave1 + s32i a2, a3, EXC_TABLE_DOUBLE_SAVE + movi a2, 0 + s32i a2, a3, EXC_TABLE_FIXUP + l32i a2, a3, EXC_TABLE_DOUBLE_SAVE + xsr a3, excsave1 + rfe + +.Lrestore_1: + overflow_fixup_restore_a0_pane 1 + j .Lset_default_fixup +.Lrestore_3: + overflow_fixup_restore_a0_pane 3 + j .Lset_default_fixup + +ENDPROC(window_overflow_restore_a0_fixup) + + .end literal_prefix +/* * Debug interrupt vector * * There is not much space here, so simply jump to another handler.
arch/xtensa/kernel/vmlinux.lds.S +2 -2
@@ -262,13 +262,13 @@ SECTIONS .UserExceptionVector.literal) SECTION_VECTOR (_DoubleExceptionVector_literal, .DoubleExceptionVector.literal, - DOUBLEEXC_VECTOR_VADDR - 16, + DOUBLEEXC_VECTOR_VADDR - 40, SIZEOF(.UserExceptionVector.text), .UserExceptionVector.text) SECTION_VECTOR (_DoubleExceptionVector_text, .DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR, - 32, + 40, .DoubleExceptionVector.literal) . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
Signature · 1 line
2.0.4
PATCH 29/104 net/l2tp: don't fall back on UDP [get|set]sockopt
In reply to Jiri SlabyFrom: Sasha Levin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3cf521f7dc87c031617fd47e4b7aa2593c2f3daf upstream.
The l2tp [get|set]sockopt() code has fallen back to the UDP functions for socket option levels != SOL_PPPOL2TP since day one, but that has never actually worked, since the l2tp socket isn't an inet socket.
As David Miller points out:
"If we wanted this to work, it'd have to look up the tunnel and then
use tunnel->sk, but I wonder how useful that would be"
Since this can never have worked so nobody could possibly have depended on that functionality, just remove the broken code and return -EINVAL.
--- net/l2tp/l2tp_ppp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/l2tp/l2tp_ppp.c +2 -2
@@ -1365,7 +1365,7 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,int err;if (level !=SOL_PPPOL2TP ) -return udp_prot.setsockopt (sk, level, optname, optval, optlen); +return -EINVAL ;if (optlen <sizeof (int ))return -EINVAL ;
@@ -1491,7 +1491,7 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,struct pppol2tp_session *ps;if (level !=SOL_PPPOL2TP ) -return udp_prot.getsockopt (sk, level, optname, optval, optlen); +return -EINVAL ;if (get_user (len, optlen))return -EFAULT ;
Signature · 1 line
2.0.4
PATCH 30/104 lib/btree.c: fix leak of whole btree nodes
In reply to Jiri SlabyFrom: Minfei Huang <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c75b53af2f0043aff500af0a6f878497bef41bca upstream.
I use btree from 3.14-rc2 in my own module. When the btree module is removed, a warning arises:
kmem_cache_destroy btree_node: Slab cache still has objects
CPU: 13 PID: 9150 Comm: rmmod Tainted: GF O 3.14.0-rc2 #1 Hardware name: Inspur NF5270M3/NF5270M3, BIOS CHEETAH_2.1.3 09/10/2013 Call Trace: dump_stack+0x49/0x5d kmem_cache_destroy+0xcf/0xe0 btree_module_exit+0x10/0x12 [btree] SyS_delete_module+0x198/0x1f0 system_call_fastpath+0x16/0x1b
The cause is that it doesn't release the last btree node, when height = 1 and fill = 1.
--- lib/btree.c | 1 + 1 file changed, 1 insertion(+)
lib/btree.c +1 -0
@@ -198,6 +198,7 @@ EXPORT_SYMBOL_GPL(btree_init);void btree_destroy (struct btree_head *head) { +mempool_free (head->node, head->mempool);mempool_destroy (head->mempool); head->mempool =NULL ; }
Signature · 1 line
2.0.4
PATCH 31/104 x86/espfix/xen: Fix allocation of pages for paravirt page tables
In reply to Jiri SlabyFrom: Boris Ostrovsky <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8762e5092828c4dc0f49da5a47a644c670df77f3 upstream.
init_espfix_ap() is currently off by one level when informing hypervisor that allocated pages will be used for ministacks' page tables.
The most immediate effect of this on a PV guest is that if 'stack_page = __get_free_page()' returns a non-zeroed-out page the hypervisor will refuse to use it for a page table (which it shouldn't be anyway). This will result in warnings by both Xen and Linux.
More importantly, a subsequent write to that page (again, by a PV guest) is likely to result in fatal page fault.
--- arch/x86/kernel/espfix_64.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
arch/x86/kernel/espfix_64.c +2 -3
@@ -175,7 +175,7 @@ void init_espfix_ap(void)if (!pud_present (pud)) { pmd_p = (pmd_t *)__get_free_page (PGALLOC_GFP ); pud =__pud (__pa (pmd_p) | (PGTABLE_PROT & ptemask)); -paravirt_alloc_pud (&init_mm,__pa (pmd_p) >>PAGE_SHIFT ); +paravirt_alloc_pmd (&init_mm,__pa (pmd_p) >>PAGE_SHIFT );for (n =0 ; n <ESPFIX_PUD_CLONES ; n++)set_pud (&pud_p[n], pud); }
@@ -185,7 +185,7 @@ void init_espfix_ap(void)if (!pmd_present (pmd)) { pte_p = (pte_t *)__get_free_page (PGALLOC_GFP ); pmd =__pmd (__pa (pte_p) | (PGTABLE_PROT & ptemask)); -paravirt_alloc_pmd (&init_mm,__pa (pte_p) >>PAGE_SHIFT ); +paravirt_alloc_pte (&init_mm,__pa (pte_p) >>PAGE_SHIFT );for (n =0 ; n <ESPFIX_PMD_CLONES ; n++)set_pmd (&pmd_p[n], pmd); }
@@ -193,7 +193,6 @@ void init_espfix_ap(void) pte_p =pte_offset_kernel (&pmd, addr); stack_page = (void *)__get_free_page (GFP_KERNEL ); pte =__pte (__pa (stack_page) | (__PAGE_KERNEL_RO & ptemask)); -paravirt_alloc_pte (&init_mm,__pa (stack_page) >>PAGE_SHIFT );for (n =0 ; n <ESPFIX_PTE_CLONES ; n++)set_pte (&pte_p[n*PTE_STRIDE ], pte);
Signature · 1 line
2.0.4
PATCH 32/104 bnx2x: fix crash during TSO tunneling
In reply to Jiri SlabyFrom: Dmitry Kravkov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit fe26566d8a05151ba1dce75081f6270f73ec4ae1 ]
When TSO packet is transmitted additional BD w/o mapping is used to describe the packed. The BD needs special handling in tx completion.
kernel: Call Trace:
kernel: <IRQ> [<ffffffff815e19ba>] dump_stack+0x19/0x1b
kernel: [<ffffffff8105dee1>] warn_slowpath_common+0x61/0x80
kernel: [<ffffffff8105df5c>] warn_slowpath_fmt+0x5c/0x80
kernel: [<ffffffff814a8c0d>] ? find_iova+0x4d/0x90
kernel: [<ffffffff814ab0e2>] intel_unmap_page.part.36+0x142/0x160
kernel: [<ffffffff814ad0e6>] intel_unmap_page+0x26/0x30
kernel: [<ffffffffa01f55d7>] bnx2x_free_tx_pkt+0x157/0x2b0 [bnx2x]
kernel: [<ffffffffa01f8dac>] bnx2x_tx_int+0xac/0x220 [bnx2x]
kernel: [<ffffffff8101a0d9>] ? read_tsc+0x9/0x20
kernel: [<ffffffffa01f8fdb>] bnx2x_poll+0xbb/0x3c0 [bnx2x]
kernel: [<ffffffff814d041a>] net_rx_action+0x15a/0x250
kernel: [<ffffffff81067047>] __do_softirq+0xf7/0x290
kernel: [<ffffffff815f3a5c>] call_softirq+0x1c/0x30
kernel: [<ffffffff81014d25>] do_softirq+0x55/0x90
kernel: [<ffffffff810673e5>] irq_exit+0x115/0x120
kernel: [<ffffffff815f4358>] do_IRQ+0x58/0xf0
kernel: [<ffffffff815e94ad>] common_interrupt+0x6d/0x6d
kernel: <EOI> [<ffffffff810bbff7>] ? clockevents_notify+0x127/0x140
kernel: [<ffffffff814834df>] ? cpuidle_enter_state+0x4f/0xc0
kernel: [<ffffffff81483615>] cpuidle_idle_call+0xc5/0x200
kernel: [<ffffffff8101bc7e>] arch_cpu_idle+0xe/0x30
kernel: [<ffffffff810b4725>] cpu_startup_entry+0xf5/0x290
kernel: [<ffffffff815cfee1>] start_secondary+0x265/0x27b
kernel: ---[ end trace 11aa7726f18d7e80 ]---
--- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 + drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 9 +++++++++ 2 files changed, 10 insertions(+)
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +1 -0
@@ -337,6 +337,7 @@ struct sw_tx_bd {u8 flags;/* Set on the first BD descriptor when there is a split BD */ #define BNX2X_TSO_SPLIT_BD (1<<0) +#define BNX2X_HAS_SECOND_PBD (1<<1) };struct sw_rx_page {
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +9 -0
@@ -186,6 +186,12 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, --nbd; bd_idx =TX_BD (NEXT_TX_IDX (bd_idx)); +if (tx_buf->flags &BNX2X_HAS_SECOND_PBD ) { +/* Skip second parse bd... */ + --nbd; + bd_idx =TX_BD (NEXT_TX_IDX (bd_idx)); + } +/* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */ if (tx_buf->flags &BNX2X_TSO_SPLIT_BD ) { tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
@@ -3822,6 +3828,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)/* set encapsulation flag in start BD */ SET_FLAG (tx_start_bd->general_data,ETH_TX_START_BD_TUNNEL_EXIST ,1 ); + + tx_buf->flags |=BNX2X_HAS_SECOND_PBD ; + nbd++; }else if (xmit_type &XMIT_CSUM ) {/* Set PBD in checksum offload case w/o encapsulation */
Signature · 1 line
2.0.4
PATCH 33/104 inetpeer: get rid of ip_id_count
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 73f156a6e8c1074ac6327e0abd1169e95eb66463 ]
Ideally, we would need to generate IP ID using a per destination IP generator.
linux kernels used inet_peer cache for this purpose, but this had a huge cost on servers disabling MTU discovery.
1) each inet_peer struct consumes 192 bytes
2) inetpeer cache uses a binary tree of inet_peer structs, with a nominal size of ~66000 elements under load.
3) lookups in this tree are hitting a lot of cache lines, as tree depth is about 20.
4) If server deals with many tcp flows, we have a high probability of not finding the inet_peer, allocating a fresh one, inserting it in the tree with same initial ip_id_count, (cf secure_ip_id())
5) We garbage collect inet_peer aggressively.
IP ID generation do not have to be 'perfect'
Goal is trying to avoid duplicates in a short period of time, so that reassembly units have a chance to complete reassembly of fragments belonging to one message before receiving other fragments with a recycled ID.
We simply use an array of generators, and a Jenkin hash using the dst IP as a key.
ipv6_select_ident() is put back into net/ipv6/ip6_output.c where it belongs (it is only used from this file)
secure_ip_id() and secure_ipv6_id() no longer are needed.
Rename ip_select_ident_more() to ip_select_ident_segs() to avoid unnecessary decrement/increment of the number of segments.
--- drivers/net/ppp/pptp.c | 2 +- include/net/inetpeer.h | 16 +++----------- include/net/ip.h | 40 ++++++++++++++++++++--------------- include/net/ipv6.h | 11 ++++++---- include/net/secure_seq.h | 2 -- net/core/secure_seq.c | 25 ---------------------- net/ipv4/igmp.c | 4 ++-- net/ipv4/inetpeer.c | 18 ---------------- net/ipv4/ip_output.c | 7 +++--- net/ipv4/ip_tunnel_core.c | 2 +- net/ipv4/ipmr.c | 2 +- net/ipv4/raw.c | 2 +- net/ipv4/route.c | 47 +++++++++++++++++------------------------ net/ipv4/xfrm4_mode_tunnel.c | 2 +- net/ipv6/ip6_output.c | 15 +++++++++++++ net/ipv6/output_core.c | 23 -------------------- net/netfilter/ipvs/ip_vs_xmit.c | 2 +- 17 files changed, 78 insertions(+), 142 deletions(-)
drivers/net/ppp/pptp.c +1 -1
@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)nf_reset (skb); skb->ip_summed =CHECKSUM_NONE ; -ip_select_ident (skb, &rt->dst,NULL ); +ip_select_ident (skb,NULL );ip_send_check (iph);ip_local_out (skb);
include/net/inetpeer.h +3 -13
@@ -41,14 +41,13 @@ struct inet_peer {struct rcu_head gc_rcu; };/* -* Once inet_peer is queued for deletion (refcnt == -1), following fields -* are not available: rid, ip_id_count +* Once inet_peer is queued for deletion (refcnt == -1), following field +* is not available: rid * We can share memory with rcu_head to help keep inet_peer small. */ union {struct {atomic_t rid;/* Frag reception counter */ -atomic_t ip_id_count;/* IP ID for the next packet */ };struct rcu_head rcu;struct inet_peer *gc_next;
@@ -166,7 +165,7 @@ extern void inetpeer_invalidate_tree(struct inet_peer_base *);extern void inetpeer_invalidate_family (int family);/* -* temporary check to make sure we dont access rid, ip_id_count, tcp_ts, +* temporary check to make sure we dont access rid, tcp_ts, * tcp_ts_stamp if no refcount is taken on inet_peer */ static inline void inet_peer_refcheck (const struct inet_peer *p)
@@ -174,13 +173,4 @@ static inline void inet_peer_refcheck(const struct inet_peer *p) WARN_ON_ONCE(atomic_read(&p->refcnt) <= 0); } - -/* can be called with or without local BH being disabled */ -static inline int inet_getid (struct inet_peer *p,int more) -{ - more++; -inet_peer_refcheck (p); -return atomic_add_return (more, &p->ip_id_count) - more; -} -#endif /* _NET_INETPEER_H */
include/net/ip.h +23 -17
@@ -262,9 +262,19 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) !(dst_metric_locked(dst, RTAX_MTU))); } -extern void __ip_select_ident (struct iphdr *iph,struct dst_entry *dst,int more); +#define IP_IDENTS_SZ 2048u +extern atomic_t *ip_idents; -static inline void ip_select_ident (struct sk_buff *skb,struct dst_entry *dst,struct sock *sk) +static inline u32 ip_idents_reserve (u32 hash,int segs) +{ +atomic_t *id_ptr = ip_idents + hash %IP_IDENTS_SZ ; + +return atomic_add_return (segs, id_ptr) - segs; +} + +void __ip_select_ident (struct iphdr *iph,int segs); + +static inline void ip_select_ident_segs (struct sk_buff *skb,struct sock *sk,int segs) {struct iphdr *iph =ip_hdr (skb);
@@ -274,24 +284,20 @@ static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, s* does not change, they drop every other packet in * a TCP stream using header compression. */ - iph->id = (sk &&inet_sk (sk)->inet_daddr) ? -htons (inet_sk (sk)->inet_id++) :0 ; - }else -__ip_select_ident (iph, dst,0 ); -} - -static inline void ip_select_ident_more (struct sk_buff *skb,struct dst_entry *dst,struct sock *sk,int more) -{ -struct iphdr *iph =ip_hdr (skb); - -if ((iph->frag_off &htons (IP_DF )) && !skb->local_df) {if (sk &&inet_sk (sk)->inet_daddr) { iph->id =htons (inet_sk (sk)->inet_id); -inet_sk (sk)->inet_id +=1 + more; - }else +inet_sk (sk)->inet_id += segs; + }else { iph->id =0 ; - }else -__ip_select_ident (iph, dst, more); + } + }else { +__ip_select_ident (iph, segs); + } +} + +static inline void ip_select_ident (struct sk_buff *skb,struct sock *sk) +{ +ip_select_ident_segs (skb, sk,1 ); }/*
include/net/ipv6.h +7 -4
@@ -537,14 +537,19 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a) }/* more secured version of ipv6_addr_hash() */ -static inline u32 ipv6_addr_jhash (const struct in6_addr *a) +static inline u32 __ipv6_addr_jhash (const struct in6_addr *a,const u32 initval) {u32 v = (__force u32 )a->s6_addr32[0 ] ^ (__force u32 )a->s6_addr32[1 ];return jhash_3words (v, (__force u32 )a->s6_addr32[2 ], (__force u32 )a->s6_addr32[3 ], - ipv6_hash_secret); + initval); +} + +static inline u32 ipv6_addr_jhash (const struct in6_addr *a) +{ +return __ipv6_addr_jhash (a, ipv6_hash_secret); }static inline bool ipv6_addr_loopback (const struct in6_addr *a)
@@ -656,8 +661,6 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addreturn __ipv6_addr_diff (a1, a2,sizeof (struct in6_addr )); } -extern void ipv6_select_ident (struct frag_hdr *fhdr,struct rt6_info *rt); -extern int ip6_dst_hoplimit (struct dst_entry *dst);/*
include/net/secure_seq.h +0 -2
@@ -3,8 +3,6 @@#include <linux/types.h> -extern __u32 secure_ip_id (__be32 daddr); -extern __u32 secure_ipv6_id (const __be32 daddr[4 ]);extern u32 secure_ipv4_port_ephemeral (__be32 saddr,__be32 daddr,__be16 dport);extern u32 secure_ipv6_port_ephemeral (const __be32 *saddr,const __be32 *daddr,__be16 dport);
net/core/secure_seq.c +0 -25
@@ -95,31 +95,6 @@ EXPORT_SYMBOL(secure_ipv6_port_ephemeral);#endif #ifdef CONFIG_INET -__u32 secure_ip_id (__be32 daddr) -{ -u32 hash[MD5_DIGEST_WORDS ]; - -net_secret_init (); - hash[0 ] = (__force __u32 ) daddr; - hash[1 ] = net_secret[13 ]; - hash[2 ] = net_secret[14 ]; - hash[3 ] = net_secret[15 ]; - -md5_transform (hash, net_secret); - -return hash[0 ]; -} - -__u32 secure_ipv6_id (const __be32 daddr[4 ]) -{ -__u32 hash[4 ]; - -net_secret_init (); -memcpy (hash, daddr,16 ); -md5_transform (hash, net_secret); - -return hash[0 ]; -}__u32 secure_tcp_sequence_number (__be32 saddr,__be32 daddr,__be16 sport,__be16 dport)
net/ipv4/igmp.c +2 -2
@@ -369,7 +369,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) pip->saddr = fl4.saddr; pip->protocol =IPPROTO_IGMP ; pip->tot_len =0 ;/* filled in later */ -ip_select_ident (skb, &rt->dst,NULL ); +ip_select_ident (skb,NULL ); ((u8 *)&pip[1 ])[0 ] =IPOPT_RA ; ((u8 *)&pip[1 ])[1 ] =4 ; ((u8 *)&pip[1 ])[2 ] =0 ;
@@ -714,7 +714,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, iph->daddr = dst; iph->saddr = fl4.saddr; iph->protocol =IPPROTO_IGMP ; -ip_select_ident (skb, &rt->dst,NULL ); +ip_select_ident (skb,NULL ); ((u8 *)&iph[1 ])[0 ] =IPOPT_RA ; ((u8 *)&iph[1 ])[1 ] =4 ; ((u8 *)&iph[1 ])[2 ] =0 ;
net/ipv4/inetpeer.c +0 -18
@@ -26,20 +26,7 @@* Theory of operations. * We keep one entry for each peer IP address. The nodes contains long-living * information about the peer which doesn't depend on routes. -* At this moment this information consists only of ID field for the next -* outgoing IP packet. This field is incremented with each packet as encoded -* in inet_getid() function (include/net/inetpeer.h). -* At the moment of writing this notes identifier of IP packets is generated -* to be unpredictable using this code only for packets subjected -* (actually or potentially) to defragmentation. I.e. DF packets less than -* PMTU in size when local fragmentation is disabled use a constant ID and do -* not use this code (see ip_select_ident() in include/net/ip.h). * -* Route cache entries hold references to our nodes. -* New cache entries get references via lookup by destination IP address in -* the avl tree. The reference is grabbed only when it's needed i.e. only -* when we try to output IP packet which needs an unpredictable ID (see -* __ip_select_ident() in net/ipv4/route.c). * Nodes are removed only when reference counter goes to 0. * When it's happened the node may be removed when a sufficient amount of * time has been passed since its last use. The less-recently-used entry can
@@ -62,7 +49,6 @@* refcnt: atomically against modifications on other CPU; * usually under some other lock to prevent node disappearing * daddr: unchangeable -* ip_id_count: atomic value (no lock needed) */ static struct kmem_cache *peer_cachep__read_mostly ;
@@ -504,10 +490,6 @@ relookup: p->daddr = *daddr;atomic_set (&p->refcnt,1 );atomic_set (&p->rid,0 ); -atomic_set (&p->ip_id_count, - (daddr->family ==AF_INET ) ? -secure_ip_id (daddr->addr.a4) : -secure_ipv6_id (daddr->addr.a6)); p->metrics[RTAX_LOCK -1 ] =INETPEER_METRICS_NEW ; p->rate_tokens =0 ;/* 60*HZ is arbitrary, but chosen enough high so that the first
net/ipv4/ip_output.c +3 -4
@@ -148,7 +148,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); iph->saddr = saddr; iph->protocol = sk->sk_protocol; -ip_select_ident (skb, &rt->dst, sk); +ip_select_ident (skb, sk);if (opt && opt->opt.optlen) { iph->ihl += opt->opt.optlen>>2 ;
@@ -386,8 +386,7 @@ packet_routed:ip_options_build (skb, &inet_opt->opt, inet->inet_daddr, rt,0 ); } -ip_select_ident_more (skb, &rt->dst, sk, - (skb_shinfo (skb)->gso_segs ?:1 ) -1 ); +ip_select_ident_segs (skb, sk,skb_shinfo (skb)->gso_segs ?:1 ); skb->priority = sk->sk_priority; skb->mark = sk->sk_mark;
@@ -1329,7 +1328,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk, iph->ttl = ttl; iph->protocol = sk->sk_protocol;ip_copy_addrs (iph, fl4); -ip_select_ident (skb, &rt->dst, sk); +ip_select_ident (skb, sk);if (opt) { iph->ihl += opt->optlen>>2 ;
net/ipv4/ip_tunnel_core.c +1 -1
@@ -74,7 +74,7 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, iph->daddr = dst; iph->saddr = src; iph->ttl = ttl; -__ip_select_ident (iph, &rt->dst, (skb_shinfo (skb)->gso_segs ?:1 ) -1 ); +__ip_select_ident (iph,skb_shinfo (skb)->gso_segs ?:1 ); err =ip_local_out (skb);if (unlikely (net_xmit_eval (err)))
net/ipv4/ipmr.c +1 -1
@@ -1661,7 +1661,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) iph->protocol =IPPROTO_IPIP ; iph->ihl =5 ; iph->tot_len =htons (skb->len); -ip_select_ident (skb,skb_dst (skb),NULL ); +ip_select_ident (skb,NULL );ip_send_check (iph);memset (&(IPCB (skb)->opt),0 ,sizeof (IPCB (skb)->opt));
net/ipv4/raw.c +1 -1
@@ -389,7 +389,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, iph->check =0 ; iph->tot_len =htons (length);if (!iph->id) -ip_select_ident (skb, &rt->dst,NULL ); +ip_select_ident (skb,NULL ); iph->check =ip_fast_csum ((unsigned char *)iph, iph->ihl); }
net/ipv4/route.c +19 -28
70 lines not on this page · raw message
net/ipv4/xfrm4_mode_tunnel.c +1 -1
@@ -117,12 +117,12 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->frag_off = (flags &XFRM_STATE_NOPMTUDISC ) ?0 : (XFRM_MODE_SKB_CB (skb)->frag_off &htons (IP_DF )); -ip_select_ident (skb, dst->child,NULL ); top_iph->ttl =ip4_dst_hoplimit (dst->child); top_iph->saddr = x->props.saddr.a4; top_iph->daddr = x->id.daddr.a4; +ip_select_ident (skb,NULL );return 0 ; }
net/ipv6/ip6_output.c +15 -0
@@ -516,6 +516,21 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)skb_copy_secmark (to, from); } +static void ipv6_select_ident (struct frag_hdr *fhdr,struct rt6_info *rt) +{ +static u32 ip6_idents_hashrnd__read_mostly ; +static bool hashrnd_initialized = false; +u32 hash, id; + +if (unlikely (!hashrnd_initialized)) { + hashrnd_initialized = true; +get_random_bytes (&ip6_idents_hashrnd,sizeof (ip6_idents_hashrnd)); + } + hash =__ipv6_addr_jhash (&rt->rt6i_dst.addr, ip6_idents_hashrnd); + id =ip_idents_reserve (hash,1 ); + fhdr->identification =htonl (id); +} +int ip6_fragment (struct sk_buff *skb,int (*output)(struct sk_buff *)) {struct sk_buff *frag;
net/ipv6/output_core.c +0 -23
@@ -7,29 +7,6 @@#include <net/ip6_fib.h> #include <net/addrconf.h> -void ipv6_select_ident (struct frag_hdr *fhdr,struct rt6_info *rt) -{ -static atomic_t ipv6_fragmentation_id; -int ident; - -#if IS_ENABLED (CONFIG_IPV6 ) -if (rt && !(rt->dst.flags &DST_NOPEER )) { -struct inet_peer *peer; -struct net *net; - - net =dev_net (rt->dst.dev); - peer =inet_getpeer_v6 (net->ipv6.peers, &rt->rt6i_dst.addr,1 ); -if (peer) { - fhdr->identification =htonl (inet_getid (peer,0 )); -inet_putpeer (peer); -return ; - } - } -#endif - ident =atomic_inc_return (&ipv6_fragmentation_id); - fhdr->identification =htonl (ident); -} -EXPORT_SYMBOL (ipv6_select_ident);int ip6_find_1stfragopt (struct sk_buff *skb,u8 **nexthdr) {
net/netfilter/ipvs/ip_vs_xmit.c +1 -1
@@ -883,7 +883,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, iph->daddr = cp->daddr.ip; iph->saddr = saddr; iph->ttl = old_iph->ttl; -ip_select_ident (skb, &rt->dst,NULL ); +ip_select_ident (skb,NULL );/* Another hack: avoid icmp_send in ip_fragment */ skb->local_df =1 ;
Signature · 1 line
2.0.4
PATCH 34/104 ip: make IP identifiers less predictable
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 04ca6973f7c1a0d8537f2d9906a0cf8e69886d75 ]
In "Counting Packets Sent Between Arbitrary Internet Hosts", Jeffrey and Jedidiah describe ways exploiting linux IP identifier generation to infer whether two machines are exchanging packets.
With commit 73f156a6e8c1 ("inetpeer: get rid of ip_id_count"), we changed IP id generation, but this does not really prevent this side-channel technique.
This patch adds a random amount of perturbation so that IP identifiers for a given destination [1] are no longer monotonically increasing after an idle period.
Note that prandom_u32_max(1) returns 0, so if generator is used at most once per jiffy, this patch inserts no hole in the ID suite and do not increase collision probability.
This is jiffies based, so in the worst case (HZ=1000), the id can rollover after ~65 seconds of idle time, which should be fine.
We also change the hash used in __ip_select_ident() to not only hash on daddr, but also saddr and protocol, so that ICMP probes can not be used to infer information for other protocols.
For IPv6, adds saddr into the hash as well, but not nexthdr.
If I ping the patched target, we can see ID are now hard to predict.
21:57:11.008086 IP (...)
A > target: ICMP echo request, seq 1, length 64
21:57:11.010752 IP (... id 2081 ...)
target > A: ICMP echo reply, seq 1, length 64
21:57:12.013133 IP (...)
A > target: ICMP echo request, seq 2, length 64
21:57:12.015737 IP (... id 3039 ...)
target > A: ICMP echo reply, seq 2, length 64
21:57:13.016580 IP (...)
A > target: ICMP echo request, seq 3, length 64
21:57:13.019251 IP (... id 3437 ...)
target > A: ICMP echo reply, seq 3, length 64
[1] TCP sessions uses a per flow ID generator not changed by this patch.
--- include/net/ip.h | 11 +---------- net/ipv4/route.c | 36 +++++++++++++++++++++++++++++++++--- net/ipv6/ip6_output.c | 2 ++ 3 files changed, 36 insertions(+), 13 deletions(-)
include/net/ip.h +1 -10
@@ -262,16 +262,7 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) !(dst_metric_locked(dst, RTAX_MTU))); } -#define IP_IDENTS_SZ 2048u -extern atomic_t *ip_idents; - -static inline u32 ip_idents_reserve (u32 hash,int segs) -{ -atomic_t *id_ptr = ip_idents + hash %IP_IDENTS_SZ ; - -return atomic_add_return (segs, id_ptr) - segs; -} - +u32 ip_idents_reserve (u32 hash,int segs);void __ip_select_ident (struct iphdr *iph,int segs);static inline void ip_select_ident_segs (struct sk_buff *skb,struct sock *sk,int segs)
net/ipv4/route.c +33 -3
@@ -466,8 +466,35 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,return neigh_create (&arp_tbl, pkey, dev); } -atomic_t *ip_idents__read_mostly ; -EXPORT_SYMBOL (ip_idents); +#define IP_IDENTS_SZ 2048u +struct ip_ident_bucket { +atomic_t id; +u32 stamp32; +}; + +static struct ip_ident_bucket *ip_idents__read_mostly ; + +/* In order to protect privacy, we add a perturbation to identifiers +* if one generator is seldom used. This makes hard for an attacker +* to infer how many packets were sent between two points in time. +*/ +u32 ip_idents_reserve (u32 hash,int segs) +{ +struct ip_ident_bucket *bucket = ip_idents + hash %IP_IDENTS_SZ ; +u32 old =ACCESS_ONCE (bucket->stamp32); +u32 now = (u32 )jiffies; +u32 delta =0 ; + +if (old != now &&cmpxchg (&bucket->stamp32, old, now) == old) { +u64 x =prandom_u32 (); + + x *= (now - old); + delta = (u32)(x >>32 ); + } + +return atomic_add_return (segs + delta, &bucket->id) - segs; +} +EXPORT_SYMBOL (ip_idents_reserve);void __ip_select_ident (struct iphdr *iph,int segs) {
@@ -480,7 +507,10 @@ void __ip_select_ident(struct iphdr *iph, int segs)get_random_bytes (&ip_idents_hashrnd,sizeof (ip_idents_hashrnd)); } - hash =jhash_1word ((__force u32 )iph->daddr, ip_idents_hashrnd); + hash =jhash_3words ((__force u32 )iph->daddr, + (__force u32 )iph->saddr, + iph->protocol, + ip_idents_hashrnd); id =ip_idents_reserve (hash, segs); iph->id =htons (id); }
net/ipv6/ip6_output.c +2 -0
@@ -527,6 +527,8 @@ static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)get_random_bytes (&ip6_idents_hashrnd,sizeof (ip6_idents_hashrnd)); } hash =__ipv6_addr_jhash (&rt->rt6i_dst.addr, ip6_idents_hashrnd); + hash =__ipv6_addr_jhash (&rt->rt6i_src.addr, hash); + id =ip_idents_reserve (hash,1 ); fhdr->identification =htonl (id); }
Signature · 1 line
2.0.4
PATCH 35/104 net: sendmsg: fix NULL pointer dereference
In reply to Jiri SlabyFrom: Andrey Ryabinin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 40eea803c6b2cfaab092f053248cbeab3f368412 ]
Sasha's report:
> While fuzzing with trinity inside a KVM tools guest running the latest -next > kernel with the KASAN patchset, I've stumbled on the following spew: > > [ 4448.949424] ================================================================== > [ 4448.951737] AddressSanitizer: user-memory-access on address 0 > [ 4448.952988] Read of size 2 by thread T19638: > [ 4448.954510] CPU: 28 PID: 19638 Comm: trinity-c76 Not tainted 3.16.0-rc4-next-20140711-sasha-00046-g07d3099-dirty #813 > [ 4448.956823] ffff88046d86ca40 0000000000000000 ffff880082f37e78 ffff880082f37a40 > [ 4448.958233] ffffffffb6e47068 ffff880082f37a68 ffff880082f37a58 ffffffffb242708d > [ 4448.959552] 0000000000000000 ffff880082f37a88 ffffffffb24255b1 0000000000000000 > [ 4448.961266] Call Trace: > [ 4448.963158] dump_stack (lib/dump_stack.c:52) > [ 4448.964244] kasan_report_user_access (mm/kasan/report.c:184) > [ 4448.965507] __asan_load2 (mm/kasan/kasan.c:352) > [ 4448.966482] ? netlink_sendmsg (net/netlink/af_netlink.c:2339) > [ 4448.967541] netlink_sendmsg (net/netlink/af_netlink.c:2339) > [ 4448.968537] ? get_parent_ip (kernel/sched/core.c:2555) > [ 4448.970103] sock_sendmsg (net/socket.c:654) > [ 4448.971584] ? might_fault (mm/memory.c:3741) > [ 4448.972526] ? might_fault (./arch/x86/include/asm/current.h:14 mm/memory.c:3740) > [ 4448.973596] ? verify_iovec (net/core/iovec.c:64) > [ 4448.974522] ___sys_sendmsg (net/socket.c:2096) > [ 4448.975797] ? put_lock_stats.isra.13 (./arch/x86/include/asm/preempt.h:98 kernel/locking/lockdep.c:254) > [ 4448.977030] ? lock_release_holdtime (kernel/locking/lockdep.c:273) > [ 4448.978197] ? lock_release_non_nested (kernel/locking/lockdep.c:3434 (discriminator 1)) > [ 4448.979346] ? check_chain_key (kernel/locking/lockdep.c:2188) > [ 4448.980535] __sys_sendmmsg (net/socket.c:2181) > [ 4448.981592] ? trace_hardirqs_on_caller (kernel/locking/lockdep.c:2600) > [ 4448.982773] ? trace_hardirqs_on (kernel/locking/lockdep.c:2607) > [ 4448.984458] ? syscall_trace_enter (arch/x86/kernel/ptrace.c:1500 (discriminator 2)) > [ 4448.985621] ? trace_hardirqs_on_caller (kernel/locking/lockdep.c:2600) > [ 4448.986754] SyS_sendmmsg (net/socket.c:2201) > [ 4448.987708] tracesys (arch/x86/kernel/entry_64.S:542) > [ 4448.988929] ==================================================================
This reports means that we've come to netlink_sendmsg() with msg->msg_name == NULL and msg->msg_namelen > 0.
After this report there was no usual "Unable to handle kernel NULL pointer dereference" and this gave me a clue that address 0 is mapped and contains valid socket address structure in it.
This bug was introduced in f3d3342602f8bcbf37d7c46641cb9bca7618eb1c (net: rework recvmsg handler msg_name and msg_namelen logic). Commit message states that:
"Set msg->msg_name = NULL if user specified a NULL in msg_name but had a
non-null msg_namelen in verify_iovec/verify_compat_iovec. This doesn't affect sendto as it would bail out earlier while trying to copy-in the address."
But in fact this affects sendto when address 0 is mapped and contains socket address structure in it. In such case copy-in address will succeed, verify_iovec() function will successfully exit with msg->msg_namelen > 0 and msg->msg_name == NULL.
This patch fixes it by setting msg_namelen to 0 if msg_name == NULL.
--- net/compat.c | 9 +++++---- net/core/iovec.c | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-)
net/compat.c +5 -4
@@ -85,7 +85,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, {int tot_len; -if (kern_msg->msg_namelen) { +if (kern_msg->msg_name && kern_msg->msg_namelen) {if (mode ==VERIFY_READ ) { int err = move_addr_to_kernel(kern_msg->msg_name, kern_msg->msg_namelen,
@@ -93,10 +93,11 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,if (err <0 )return err; } -if (kern_msg->msg_name) - kern_msg->msg_name = kern_address; - }else + kern_msg->msg_name = kern_address; + }else { kern_msg->msg_name =NULL ; + kern_msg->msg_namelen =0 ; + } tot_len = iov_from_user_compat_to_kern(kern_iov, (struct compat_iovec __user *)kern_msg->msg_iov,
net/core/iovec.c +3 -3
@@ -39,7 +39,7 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a {int size, ct, err; -if (m->msg_namelen) { +if (m->msg_name && m->msg_namelen) {if (mode ==VERIFY_READ ) {void __user *namep; namep = (void __user __force *) m->msg_name;
@@ -48,10 +48,10 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *aif (err <0 )return err; } -if (m->msg_name) - m->msg_name = address; + m->msg_name = address; }else { m->msg_name =NULL ; + m->msg_namelen =0 ; } size = m->msg_iovlen *sizeof (struct iovec );
Signature · 1 line
2.0.4
PATCH 36/104 tcp: Fix integer-overflows in TCP veno
In reply to Jiri SlabyFrom: Christoph Paasch <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 45a07695bc64b3ab5d6d2215f9677e5b8c05a7d0 ]
In veno we do a multiplication of the cwnd and the rtt. This may overflow and thus their result is stored in a u64. However, we first need to cast the cwnd so that actually 64-bit arithmetic is done.
A first attempt at fixing 76f1017757aa0 ([TCP]: TCP Veno congestion control) was made by 159131149c2 (tcp: Overflow bug in Vegas), but it failed to add the required cast in tcp_veno_cong_avoid().
--- net/ipv4/tcp_veno.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/tcp_veno.c +1 -1
@@ -144,7 +144,7 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) rtt = veno->minrtt; - target_cwnd = (tp->snd_cwnd * veno->basertt); + target_cwnd = (u64 )tp->snd_cwnd * veno->basertt; target_cwnd <<=V_PARAM_SHIFT ;do_div (target_cwnd, rtt);
Signature · 1 line
2.0.4
PATCH 37/104 tcp: Fix integer-overflow in TCP vegas
In reply to Jiri SlabyFrom: Christoph Paasch <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 1f74e613ded11517db90b2bd57e9464d9e0fb161 ]
In vegas we do a multiplication of the cwnd and the rtt. This may overflow and thus their result is stored in a u64. However, we first need to cast the cwnd so that actually 64-bit arithmetic is done.
Then, we need to do do_div to allow this to be used on 32-bit arches.
--- net/ipv4/tcp_vegas.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv4/tcp_vegas.c +2 -1
@@ -218,7 +218,8 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)* This is: * (actual rate in segments) * baseRTT */ - target_cwnd = tp->snd_cwnd * vegas->baseRTT / rtt; + target_cwnd = (u64 )tp->snd_cwnd * vegas->baseRTT; +do_div (target_cwnd, rtt);/* Calculate the difference between the window we had, * and the window we would like to have. This quantity
Signature · 1 line
2.0.4
PATCH 38/104 net: sctp: inherit auth_capable on INIT collisions
In reply to Jiri SlabyFrom: Daniel Borkmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 1be9a950c646c9092fb3618197f7b6bfb50e82aa ]
Jason reported an oops caused by SCTP on his ARM machine with SCTP authentication enabled:
Internal error: Oops: 17 [#1] ARM CPU: 0 PID: 104 Comm: sctp-test Not tainted 3.13.0-68744-g3632f30c9b20-dirty #1 task: c6eefa40 ti: c6f52000 task.ti: c6f52000 PC is at sctp_auth_calculate_hmac+0xc4/0x10c LR is at sg_init_table+0x20/0x38 pc : [<c024bb80>] lr : [<c00f32dc>] psr: 40000013
sp : c6f538e8 ip : 00000000 fp : c6f53924
r10: c6f50d80 r9 : 00000000 r8 : 00010000
r7 : 00000000 r6 : c7be4000 r5 : 00000000 r4 : c6f56254 r3 : c00c8170 r2 : 00000001 r1 : 00000008 r0 : c6f1e660
Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 0005397f Table: 06f28000 DAC: 00000015 Process sctp-test (pid: 104, stack limit = 0xc6f521c0)
Stack: (0xc6f538e8 to 0xc6f54000) [...] Backtrace: [<c024babc>] (sctp_auth_calculate_hmac+0x0/0x10c) from [<c0249af8>] (sctp_packet_transmit+0x33c/0x5c8) [<c02497bc>] (sctp_packet_transmit+0x0/0x5c8) from [<c023e96c>] (sctp_outq_flush+0x7fc/0x844) [<c023e170>] (sctp_outq_flush+0x0/0x844) from [<c023ef78>] (sctp_outq_uncork+0x24/0x28) [<c023ef54>] (sctp_outq_uncork+0x0/0x28) from [<c0234364>] (sctp_side_effects+0x1134/0x1220) [<c0233230>] (sctp_side_effects+0x0/0x1220) from [<c02330b0>] (sctp_do_sm+0xac/0xd4) [<c0233004>] (sctp_do_sm+0x0/0xd4) from [<c023675c>] (sctp_assoc_bh_rcv+0x118/0x160) [<c0236644>] (sctp_assoc_bh_rcv+0x0/0x160) from [<c023d5bc>] (sctp_inq_push+0x6c/0x74) [<c023d550>] (sctp_inq_push+0x0/0x74) from [<c024a6b0>] (sctp_rcv+0x7d8/0x888)
While we already had various kind of bugs in that area ec0223ec48a9 ("net: sctp: fix sctp_sf_do_5_1D_ce to verify if we/peer is AUTH capable") and b14878ccb7fa ("net: sctp: cache auth_enable per endpoint"), this one is a bit of a different kind.
Giving a bit more background on why SCTP authentication is needed can be found in RFC4895:
SCTP uses 32-bit verification tags to protect itself against blind attackers. These values are not changed during the lifetime of an SCTP association.
Looking at new SCTP extensions, there is the need to have a method of proving that an SCTP chunk(s) was really sent by the original peer that started the association and not by a malicious attacker.
To cause this bug, we're triggering an INIT collision between peers; normal SCTP handshake where both sides intent to authenticate packets contains RANDOM; CHUNKS; HMAC-ALGO parameters that are being negotiated among peers:
---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ----------> <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] --------- -------------------- COOKIE-ECHO --------------------> <-------------------- COOKIE-ACK ---------------------
RFC4895 says that each endpoint therefore knows its own random number and the peer's random number *after* the association has been established. The local and peer's random number along with the shared key are then part of the secret used for calculating the HMAC in the AUTH chunk.
Now, in our scenario, we have 2 threads with 1 non-blocking SEQ_PACKET socket each, setting up common shared SCTP_AUTH_KEY and SCTP_AUTH_ACTIVE_KEY properly, and each of them calling sctp_bindx(3), listen(2) and connect(2) against each other, thus the handshake looks similar to this, e.g.:
---------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ----------> <------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] --------- <--------- INIT[RANDOM; CHUNKS; HMAC-ALGO] ----------- -------- INIT-ACK[RANDOM; CHUNKS; HMAC-ALGO] -------->
...
Since such collisions can also happen with verification tags, the RFC4895 for AUTH rather vaguely says under section 6.1:
In case of INIT collision, the rules governing the handling of this Random Number follow the same pattern as those for the Verification Tag, as explained in Section 5.2.4 of RFC 2960 [5]. Therefore, each endpoint knows its own Random Number and the peer's Random Number after the association has been established.
In RFC2960, section 5.2.4, we're eventually hitting Action B:
B) In this case, both sides may be attempting to start an association at about the same time but the peer endpoint started its INIT after responding to the local endpoint's INIT. Thus it may have picked a new Verification Tag not being aware of the previous Tag it had sent this endpoint. The endpoint should stay in or enter the ESTABLISHED state but it MUST update its peer's Verification Tag from the State Cookie, stop any init or cookie timers that may running and send a COOKIE ACK.
In other words, the handling of the Random parameter is the same as behavior for the Verification Tag as described in Action B of section 5.2.4.
Looking at the code, we exactly hit the sctp_sf_do_dupcook_b() case which triggers an SCTP_CMD_UPDATE_ASSOC command to the side effect interpreter, and in fact it properly copies over peer_{random, hmacs, chunks} parameters from the newly created association to update the existing one.
Also, the old asoc_shared_key is being released and based on the new params, sctp_auth_asoc_init_active_key() updated. However, the issue observed in this case is that the previous asoc->peer.auth_capable was 0, and has *not* been updated, so that instead of creating a new secret, we're doing an early return from the function sctp_auth_asoc_init_active_key() leaving asoc->asoc_shared_key as NULL. However, we now have to authenticate chunks from the updated chunk list (e.g. COOKIE-ACK).
That in fact causes the server side when responding with ...
<------------------ AUTH; COOKIE-ACK -----------------
... to trigger a NULL pointer dereference, since in sctp_packet_transmit(), it discovers that an AUTH chunk is being queued for xmit, and thus it calls sctp_auth_calculate_hmac().
Since the asoc->active_key_id is still inherited from the endpoint, and the same as encoded into the chunk, it uses asoc->asoc_shared_key, which is still NULL, as an asoc_key and dereferences it in ...
crypto_hash_setkey(desc.tfm, &asoc_key->data[0], asoc_key->len)
... causing an oops. All this happens because sctp_make_cookie_ack() called with the *new* association has the peer.auth_capable=1 and therefore marks the chunk with auth=1 after checking sctp_auth_send_cid(), but it is *actually* sent later on over the then *updated* association's transport that didn't initialize its shared key due to peer.auth_capable=0. Since control chunks in that case are not sent by the temporary association which are scheduled for deletion, they are issued for xmit via SCTP_CMD_REPLY in the interpreter with the context of the *updated* association. peer.auth_capable was 0 in the updated association (which went from COOKIE_WAIT into ESTABLISHED state), since all previous processing that performed sctp_process_init() was being done on temporary associations, that we eventually throw away each time.
The correct fix is to update to the new peer.auth_capable value as well in the collision case via sctp_assoc_update(), so that in case the collision migrated from 0 -> 1, sctp_auth_asoc_init_active_key() can properly recalculate the secret. This therefore fixes the observed server panic.
--- net/sctp/associola.c | 1 + 1 file changed, 1 insertion(+)
net/sctp/associola.c +1 -0
@@ -1198,6 +1198,7 @@ void sctp_assoc_update(struct sctp_association *asoc, asoc->c = new->c; asoc->peer.rwnd = new->peer.rwnd; asoc->peer.sack_needed = new->peer.sack_needed; + asoc->peer.auth_capable = new->peer.auth_capable; asoc->peer.i = new->peer.i;sctp_tsnmap_init (&asoc->peer.tsn_map,SCTP_TSN_MAP_INITIAL , asoc->peer.i.initial_tsn,GFP_ATOMIC );
Signature · 1 line
2.0.4
PATCH 39/104 macvlan: Initialize vlan_features to turn on offload support.
In reply to Jiri SlabyFrom: Vlad Yasevich <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 081e83a78db9b0ae1f5eabc2dedecc865f509b98 ]
Macvlan devices do not initialize vlan_features. As a result, any vlan devices configured on top of macvlans perform very poorly. Initialize vlan_features based on the vlan features of the lower-level device.
--- drivers/net/macvlan.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/macvlan.c +1 -0
@@ -505,6 +505,7 @@ static int macvlan_init(struct net_device *dev) (lowerdev->state &MACVLAN_STATE_MASK ); dev->features = lowerdev->features &MACVLAN_FEATURES ; dev->features |=NETIF_F_LLTX ; + dev->vlan_features = lowerdev->vlan_features &MACVLAN_FEATURES ; dev->gso_max_size = lowerdev->gso_max_size; dev->iflink = lowerdev->ifindex; dev->hard_header_len = lowerdev->hard_header_len;
Signature · 1 line
2.0.4
PATCH 40/104 net: Correctly set segment mac_len in skb_segment().
In reply to Jiri SlabyFrom: Vlad Yasevich <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit fcdfe3a7fa4cb74391d42b6a26dc07c20dab1d82 ]
When performing segmentation, the mac_len value is copied right out of the original skb. However, this value is not always set correctly (like when the packet is VLAN-tagged) and we'll end up copying a bad value.
One way to demonstrate this is to configure a VM which tags packets internally and turn off VLAN acceleration on the forwarding bridge port. The packets show up corrupt like this:
16:18:24.985548 52:54:00:ab:be:25 > 52:54:00:26:ce:a3, ethertype 802.1Q (0x8100), length 1518: vlan 100, p 0, ethertype 0x05e0,
0x0000: 8cdb 1c7c 8cdb 0064 4006 b59d 0a00 6402 ...|[email protected]. 0x0010: 0a00 6401 9e0d b441 0a5e 64ec 0330 14fa ..d....A.^d..0.. 0x0020: 29e3 01c9 f871 0000 0101 080a 000a e833)....q.........3 0x0030: 000f 8c75 6e65 7470 6572 6600 6e65 7470 ...unetperf.netp 0x0040: 6572 6600 6e65 7470 6572 6600 6e65 7470 erf.netperf.netp 0x0050: 6572 6600 6e65 7470 6572 6600 6e65 7470 erf.netperf.netp 0x0060: 6572 6600 6e65 7470 6572 6600 6e65 7470 erf.netperf.netp ...
This also leads to awful throughput as GSO packets are dropped and cause retransmissions.
The solution is to set the mac_len using the values already available in then new skb. We've already adjusted all of the header offset, so we might as well correctly figure out the mac_len using skb_reset_mac_len(). After this change, packets are segmented correctly and performance is restored.
--- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/skbuff.c +1 -1
@@ -2831,7 +2831,6 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, tail = nskb;__copy_skb_header (nskb, head_skb); - nskb->mac_len = head_skb->mac_len;/* nskb and skb might have different headroom */ if (nskb->ip_summed ==CHECKSUM_PARTIAL )
@@ -2841,6 +2840,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,skb_set_network_header (nskb, head_skb->mac_len); nskb->transport_header = (nskb->network_header +skb_network_header_len (head_skb)); +skb_reset_mac_len (nskb); skb_copy_from_linear_data_offset(head_skb, -tnl_hlen, nskb->data - tnl_hlen,
Signature · 1 line
2.0.4
PATCH 41/104 iovec: make sure the caller actually wants anything in memcpy_fromiovecend
In reply to Jiri SlabyFrom: Sasha Levin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 06ebb06d49486676272a3c030bfeef4bd969a8e6 ]
Check for cases when the caller requests 0 bytes instead of running off and dereferencing potentially invalid iovecs.
--- net/core/iovec.c | 4 ++++ 1 file changed, 4 insertions(+)
net/core/iovec.c +4 -0
@@ -107,6 +107,10 @@ EXPORT_SYMBOL(memcpy_toiovecend);int memcpy_fromiovecend (unsigned char *kdata,const struct iovec *iov,int offset,int len) { +/* No data? Done! */ +if (len ==0 ) +return 0 ; +/* Skip over the finished iovecs */ while (offset >= iov->iov_len) { offset -= iov->iov_len;
Signature · 1 line
2.0.4
PATCH 42/104 sctp: fix possible seqlock seadlock in sctp_packet_transmit()
In reply to Jiri SlabyFrom: Eric Dumazet <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 757efd32d5ce31f67193cc0e6a56e4dffcc42fb1 ]
Dave reported following splat, caused by improper use of IP_INC_STATS_BH() in process context.
BUG: using __this_cpu_add() in preemptible [00000000] code: trinity-c117/14551 caller is __this_cpu_preempt_check+0x13/0x20 CPU: 3 PID: 14551 Comm: trinity-c117 Not tainted 3.16.0+ #33 ffffffff9ec898f0 0000000047ea7e23 ffff88022d32f7f0 ffffffff9e7ee207 0000000000000003 ffff88022d32f818 ffffffff9e397eaa ffff88023ee70b40 ffff88022d32f970 ffff8801c026d580 ffff88022d32f828 ffffffff9e397ee3 Call Trace: [<ffffffff9e7ee207>] dump_stack+0x4e/0x7a [<ffffffff9e397eaa>] check_preemption_disabled+0xfa/0x100 [<ffffffff9e397ee3>] __this_cpu_preempt_check+0x13/0x20 [<ffffffffc0839872>] sctp_packet_transmit+0x692/0x710 [sctp] [<ffffffffc082a7f2>] sctp_outq_flush+0x2a2/0xc30 [sctp] [<ffffffff9e0d985c>] ? mark_held_locks+0x7c/0xb0 [<ffffffff9e7f8c6d>] ? _raw_spin_unlock_irqrestore+0x5d/0x80 [<ffffffffc082b99a>] sctp_outq_uncork+0x1a/0x20 [sctp] [<ffffffffc081e112>] sctp_cmd_interpreter.isra.23+0x1142/0x13f0 [sctp] [<ffffffffc081c86b>] sctp_do_sm+0xdb/0x330 [sctp] [<ffffffff9e0b8f1b>] ? preempt_count_sub+0xab/0x100 [<ffffffffc083b350>] ? sctp_cname+0x70/0x70 [sctp] [<ffffffffc08389ca>] sctp_primitive_ASSOCIATE+0x3a/0x50 [sctp] [<ffffffffc083358f>] sctp_sendmsg+0x88f/0xe30 [sctp] [<ffffffff9e0d673a>] ? lock_release_holdtime.part.28+0x9a/0x160 [<ffffffff9e0d62ce>] ? put_lock_stats.isra.27+0xe/0x30 [<ffffffff9e73b624>] inet_sendmsg+0x104/0x220 [<ffffffff9e73b525>] ? inet_sendmsg+0x5/0x220 [<ffffffff9e68ac4e>] sock_sendmsg+0x9e/0xe0 [<ffffffff9e1c0c09>] ? might_fault+0xb9/0xc0 [<ffffffff9e1c0bae>] ? might_fault+0x5e/0xc0 [<ffffffff9e68b234>] SYSC_sendto+0x124/0x1c0 [<ffffffff9e0136b0>] ? syscall_trace_enter+0x250/0x330 [<ffffffff9e68c3ce>] SyS_sendto+0xe/0x10 [<ffffffff9e7f9be4>] tracesys+0xdd/0xe2
This is a followup of commits f1d8cba61c3c4b ("inet: fix possible seqlock deadlocks") and 7f88c6b23afbd315 ("ipv6: fix possible seqlock deadlock in ip6_finish_output2")
--- net/sctp/output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sctp/output.c +1 -1
@@ -606,7 +606,7 @@ out:return err; no_route:kfree_skb (nskb); -IP_INC_STATS_BH (sock_net (asoc->base.sk),IPSTATS_MIB_OUTNOROUTES ); +IP_INC_STATS (sock_net (asoc->base.sk),IPSTATS_MIB_OUTNOROUTES );/* FIXME: Returning the 'err' will effect all the associations * associated with a socket, although only one of the paths of the
Signature · 1 line
2.0.4
PATCH 43/104 sparc64: Fix argument sign extension for compat_sys_futex().
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit aa3449ee9c87d9b7660dd1493248abcc57769e31 ]
Only the second argument, 'op', is signed.
--- arch/sparc/kernel/sys32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sparc/kernel/sys32.S +1 -1
@@ -44,7 +44,7 @@ SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1) SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) SIGN1(sys32_select, compat_sys_select, %o0) -SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) +SIGN1(sys32_futex, compat_sys_futex, %o1) SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0)
Signature · 1 line
2.0.4
PATCH 44/104 sparc64: Make itc_sync_lock raw
In reply to Jiri SlabyFrom: Kirill Tkhai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 49b6c01f4c1de3b5e5427ac5aba80f9f6d27837a ]
One more place where we must not be able
to be preempted or to be interrupted in RT.
Always actually disable interrupts during synchronization cycle.
--- arch/sparc/kernel/smp_64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/sparc/kernel/smp_64.c +3 -3
@@ -150,7 +150,7 @@ void cpu_panic(void)#define NUM_ROUNDS 64/* magic value */ #define NUM_ITERS 5/* likewise */ -static DEFINE_SPINLOCK (itc_sync_lock); +static DEFINE_RAW_SPINLOCK (itc_sync_lock);static unsigned long go[SLAVE +1 ];#define DEBUG_TICK_SYNC 0
@@ -258,7 +258,7 @@ static void smp_synchronize_one_tick(int cpu) go[MASTER ] =0 ;membar_safe ("#StoreLoad" ); -spin_lock_irqsave (&itc_sync_lock, flags); +raw_spin_lock_irqsave (&itc_sync_lock, flags); {for (i =0 ; i <NUM_ROUNDS *NUM_ITERS ; i++) {while (!go[MASTER ])
@@ -269,7 +269,7 @@ static void smp_synchronize_one_tick(int cpu)membar_safe ("#StoreLoad" ); } } -spin_unlock_irqrestore (&itc_sync_lock, flags); +raw_spin_unlock_irqrestore (&itc_sync_lock, flags); }#if defined(CONFIG_SUN_LDOMS ) && defined(CONFIG_HOTPLUG_CPU )
Signature · 1 line
2.0.4
PATCH 45/104 sparc64: Fix executable bit testing in set_pmd_at() paths.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 5b1e94fa439a3227beefad58c28c17f68287a8e9 ]
This code was mistakenly using the exec bit from the PMD in all cases, even when the PMD isn't a huge PMD.
If it's not a huge PMD, test the exec bit in the individual ptes down in tlb_batch_pmd_scan().
--- arch/sparc/mm/tlb.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
arch/sparc/mm/tlb.c +10 -7
@@ -135,7 +135,7 @@ no_cache_flush:#ifdef CONFIG_TRANSPARENT_HUGEPAGE static void tlb_batch_pmd_scan (struct mm_struct *mm,unsigned long vaddr, -pmd_t pmd,bool exec) +pmd_t pmd) {unsigned long end;pte_t *pte;
@@ -143,8 +143,11 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, pte =pte_offset_map (&pmd, vaddr); end = vaddr +HPAGE_SIZE ;while (vaddr < end) { -if (pte_val (*pte) & _PAGE_VALID) +if (pte_val (*pte) & _PAGE_VALID) { +bool exec =pte_exec (*pte); +tlb_batch_add_one (mm, vaddr, exec); + } pte++; vaddr +=PAGE_SIZE ; }
@@ -178,13 +181,13 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, }if (!pmd_none (orig)) { -bool exec = ((pmd_val (orig) &PMD_HUGE_EXEC ) !=0 ); - addr &=HPAGE_MASK ; -if (pmd_val (orig) &PMD_ISHUGE ) +if (pmd_val (orig) &PMD_ISHUGE ) { +bool exec = ((pmd_val (orig) &PMD_HUGE_EXEC ) !=0 ); +tlb_batch_add_one (mm, addr, exec); -else -tlb_batch_pmd_scan (mm, addr, orig, exec); + }else +tlb_batch_pmd_scan (mm, addr, orig); } }
Signature · 1 line
2.0.4
PATCH 46/104 sparc64: Handle 32-bit tasks properly in compute_effective_address().
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit d037d16372bbe4d580342bebbb8826821ad9edf0 ]
If we have a 32-bit task we must chop off the top 32-bits of the 64-bit value just as the cpu would.
--- arch/sparc/kernel/unaligned_64.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
arch/sparc/kernel/unaligned_64.c +9 -3
@@ -163,17 +163,23 @@ static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)unsigned long compute_effective_address (struct pt_regs *regs,unsigned int insn,unsigned int rd) { +int from_kernel = (regs->tstate &TSTATE_PRIV ) !=0 ;unsigned int rs1 = (insn >>14 ) &0x1f ;unsigned int rs2 = insn &0x1f ; -int from_kernel = (regs->tstate &TSTATE_PRIV ) !=0 ; +unsigned long addr;if (insn &0x2000 ) {maybe_flush_windows (rs1,0 , rd, from_kernel); -return (fetch_reg (rs1, regs) +sign_extend_imm13 (insn)); + addr = (fetch_reg (rs1, regs) +sign_extend_imm13 (insn)); }else {maybe_flush_windows (rs1, rs2, rd, from_kernel); -return (fetch_reg (rs1, regs) +fetch_reg (rs2, regs)); + addr = (fetch_reg (rs1, regs) +fetch_reg (rs2, regs)); } + +if (!from_kernel &&test_thread_flag (TIF_32BIT )) + addr &=0xffffffff ; + +return addr; }/* This is just to make gcc think die_if_kernel does return... */
Signature · 1 line
2.0.4
PATCH 47/104 sparc64: Fix top-level fault handling bugs.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 70ffc6ebaead783ac8dafb1e87df0039bb043596 ]
Make get_user_insn() able to cope with huge PMDs.
Next, make do_fault_siginfo() more robust when get_user_insn() can't actually fetch the instruction. In particular, use the MMU announced fault address when that happens, instead of calling compute_effective_address() and computing garbage.
--- arch/sparc/mm/fault_64.c | 82 ++++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 30 deletions(-)
arch/sparc/mm/fault_64.c +52 -30
@@ -95,38 +95,51 @@ static unsigned int get_user_insn(unsigned long tpc)pte_t *ptep, pte;unsigned long pa;u32 insn =0 ; -unsigned long pstate; -if (pgd_none (*pgdp)) - goto outret; +if (pgd_none (*pgdp) ||unlikely (pgd_bad (*pgdp))) + goto out; pudp =pud_offset (pgdp, tpc); -if (pud_none (*pudp)) - goto outret; - pmdp =pmd_offset (pudp, tpc); -if (pmd_none (*pmdp)) - goto outret; +if (pud_none (*pudp) ||unlikely (pud_bad (*pudp))) + goto out;/* This disables preemption for us as well. */ - __asm__ __volatile__("rdpr %%pstate, %0" :"=r" (pstate)); - __asm__ __volatile__("wrpr %0, %1, %%pstate" - : :"r" (pstate),"i" (PSTATE_IE )); - ptep =pte_offset_map (pmdp, tpc); - pte = *ptep; -if (!pte_present (pte)) - goto out; +local_irq_disable (); - pa = (pte_pfn (pte) <<PAGE_SHIFT ); - pa += (tpc & ~PAGE_MASK ); + pmdp =pmd_offset (pudp, tpc); +if (pmd_none (*pmdp) ||unlikely (pmd_bad (*pmdp))) + goto out_irq_enable; + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +if (pmd_trans_huge (*pmdp)) { +if (pmd_trans_splitting (*pmdp)) + goto out_irq_enable; -/* Use phys bypass so we don't pollute dtlb/dcache. */ - __asm__ __volatile__("lduwa [%1] %2, %0" - :"=r" (insn) - :"r" (pa),"i" (ASI_PHYS_USE_EC )); + pa =pmd_pfn (*pmdp) <<PAGE_SHIFT ; + pa += tpc & ~HPAGE_MASK ; +/* Use phys bypass so we don't pollute dtlb/dcache. */ + __asm__ __volatile__("lduwa [%1] %2, %0" + :"=r" (insn) + :"r" (pa),"i" (ASI_PHYS_USE_EC )); + } else +#endif + { + ptep =pte_offset_map (pmdp, tpc); + pte = *ptep; +if (pte_present (pte)) { + pa = (pte_pfn (pte) <<PAGE_SHIFT ); + pa += (tpc & ~PAGE_MASK ); + +/* Use phys bypass so we don't pollute dtlb/dcache. */ + __asm__ __volatile__("lduwa [%1] %2, %0" + :"=r" (insn) + :"r" (pa),"i" (ASI_PHYS_USE_EC )); + } +pte_unmap (ptep); + } +out_irq_enable: +local_irq_enable (); out: -pte_unmap (ptep); - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : :"r" (pstate)); -outret:return insn; }
@@ -152,7 +165,8 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, }static void do_fault_siginfo (int code,int sig,struct pt_regs *regs, -unsigned int insn,int fault_code) +unsigned long fault_addr,unsigned int insn, +int fault_code) {unsigned long addr;siginfo_t info;
@@ -160,10 +174,18 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, info.si_code = code; info.si_signo = sig; info.si_errno =0 ; -if (fault_code &FAULT_CODE_ITLB ) +if (fault_code &FAULT_CODE_ITLB ) { addr = regs->tpc; -else - addr =compute_effective_address (regs, insn,0 ); + }else { +/* If we were able to probe the faulting instruction, use it +* to compute a precise fault address. Otherwise use the fault +* time provided address which may only have page granularity. +*/ +if (insn) + addr =compute_effective_address (regs, insn,0 ); +else + addr = fault_addr; + } info.si_addr = (void __user *) addr; info.si_trapno =0 ;
@@ -238,7 +260,7 @@ static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code,/* The si_code was set to make clear whether * this was a SEGV_MAPERR or SEGV_ACCERR fault. */ -do_fault_siginfo (si_code,SIGSEGV , regs, insn, fault_code); +do_fault_siginfo (si_code,SIGSEGV , regs, address, insn, fault_code);return ; }
@@ -521,7 +543,7 @@ do_sigbus:* Send a sigbus, regardless of whether we were in kernel * or user mode. */ -do_fault_siginfo (BUS_ADRERR ,SIGBUS , regs, insn, fault_code); +do_fault_siginfo (BUS_ADRERR ,SIGBUS , regs, address, insn, fault_code);/* Kernel mode? Handle exceptions or die */ if (regs->tstate &TSTATE_PRIV )
Signature · 1 line
2.0.4
PATCH 48/104 sparc64: Add basic validations to {pud,pmd}_bad().
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 26cf432551d749e7d581db33529507a711c6eaab ]
Instead of returning false we should at least check the most basic things, otherwise page table corruptions will be very difficult to debug.
PMD and PTE tables are of size PAGE_SIZE, so none of the sub-PAGE_SIZE bits should be set.
We also complement this with a check that the physical address the pud/pmd points to is valid memory.
PowerPC was used as a guide while implementating this.
--- arch/sparc/include/asm/pgtable_64.h | 46 +++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 15 deletions(-)
arch/sparc/include/asm/pgtable_64.h +31 -15
@@ -94,6 +94,23 @@#include <linux/sched.h> +extern unsigned long sparc64_valid_addr_bitmap[]; + +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +static inline bool __kern_addr_valid (unsigned long paddr) +{ +if ((paddr >>41UL ) !=0UL ) +return false; +return test_bit (paddr >>22 , sparc64_valid_addr_bitmap); +} + +static inline bool kern_addr_valid (unsigned long addr) +{ +unsigned long paddr =__pa (addr); + +return __kern_addr_valid (paddr); +} +/* Entries per page directory level. */ #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-4))#define PTRS_PER_PMD (1UL << PMD_BITS)
@@ -715,6 +732,20 @@ static inline int pmd_present(pmd_t pmd)#define pmd_none (pmd) (!pmd_val(pmd)) +/* pmd_bad() is only called on non-trans-huge PMDs. Our encoding is +* very simple, it's just the physical address. PTE tables are of +* size PAGE_SIZE so make sure the sub-PAGE_SIZE bits are clear and +* the top bits outside of the range of any physical address size we +* support are clear as well. We also validate the physical itself. +*/ +#define pmd_bad (pmd) ((pmd_val(pmd) & ~PAGE_MASK) || \ + !__kern_addr_valid(pmd_val(pmd))) + +#define pud_none (pud) (!pud_val(pud)) + +#define pud_bad (pud) ((pud_val(pud) & ~PAGE_MASK) || \ + !__kern_addr_valid(pud_val(pud))) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE extern void set_pmd_at (struct mm_struct *mm,unsigned long addr,pmd_t *pmdp,pmd_t pmd);
@@ -749,10 +780,7 @@ static inline unsigned long __pmd_page(pmd_t pmd)#define pud_page_vaddr (pud) \ ((unsigned long) __va((((unsigned long)pud_val(pud))<<PGD_PADDR_SHIFT)))#define pud_page (pud) virt_to_page((void *)pud_page_vaddr(pud)) -#define pmd_bad (pmd) (0)#define pmd_clear (pmdp) (pmd_val(*(pmdp)) = 0U) -#define pud_none (pud) (!pud_val(pud)) -#define pud_bad (pud) (0)#define pud_present (pud) (pud_val(pud) != 0U)#define pud_clear (pudp) (pud_val(*(pudp)) = 0U)
@@ -878,18 +906,6 @@ extern unsigned long pte_file(pte_t);extern pte_t pgoff_to_pte (unsigned long );#define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) -extern unsigned long sparc64_valid_addr_bitmap[]; - -/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ -static inline bool kern_addr_valid (unsigned long addr) -{ -unsigned long paddr =__pa (addr); - -if ((paddr >>41UL ) !=0UL ) -return false; -return test_bit (paddr >>22 , sparc64_valid_addr_bitmap); -} -extern int page_in_phys_avail (unsigned long paddr);/*
Signature · 1 line
2.0.4
PATCH 49/104 sparc64: Give more detailed information in {pgd,pmd}_ERROR() and kill pte_ERROR().
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit fe866433f843b080246ce729b5e6b27b5f5d9a58 ]
pte_ERROR() is not used anywhere, delete it.
For pgd_ERROR() and pmd_ERROR(), output something similar to x86, giving the address of the pgd/pmd as well as it's value.
Also provide the caller, since these macros are invoked from pgd_clear_bad() and pmd_clear_bad() which provides little context as to what high level operation was occuring when the BAD state was detected.
--- arch/sparc/include/asm/pgtable_64.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/sparc/include/asm/pgtable_64.h +6 -3
@@ -119,9 +119,12 @@ static inline bool kern_addr_valid(unsigned long addr)/* Kernel has a separate 44bit address space. */ #define FIRST_USER_ADDRESS 0 -#define pte_ERROR (e) __builtin_trap() -#define pmd_ERROR (e) __builtin_trap() -#define pgd_ERROR (e) __builtin_trap() +#define pmd_ERROR (e) \ + pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \ + __FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0)) +#define pgd_ERROR (e) \ + pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \ + __FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0))#endif /* !(__ASSEMBLY__) */
Signature · 1 line
2.0.4
PATCH 50/104 sparc64: Don't bark so loudly about 32-bit tasks generating 64-bit fault addresses.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit e5c460f46ae7ee94831cb55cb980f942aa9e5a85 ]
This was found using Dave Jone's trinity tool.
When a user process which is 32-bit performs a load or a store, the cpu chops off the top 32-bits of the effective address before translating it.
This is because we run 32-bit tasks with the PSTATE_AM (address masking) bit set.
We can't run the kernel with that bit set, so when the kernel accesses userspace no address masking occurs.
Since a 32-bit process will have no mappings in that region we will properly fault, so we don't try to handle this using access_ok(), which can safely just be a NOP on sparc64.
Real faults from 32-bit processes should never generate such addresses so a bug check was added long ago, and it barks in the logs if this happens.
But it also barks when a kernel user access causes this condition, and that _can_ happen. For example, if a pointer passed into a system call is "0xfffffffc" and the kernel access 4 bytes offset from that pointer.
Just handle such faults normally via the exception entries.
--- arch/sparc/mm/fault_64.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-)
arch/sparc/mm/fault_64.c +1 -15
@@ -280,18 +280,6 @@ static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs)show_regs (regs); } -static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs, -unsigned long addr) -{ -static int times; - -if (times++ <10 ) -printk (KERN_ERR "FAULT[%s:%d]: 32-bit process " -"reports 64-bit fault address [%lx]\n" , - current->comm, current->pid, addr); -show_regs (regs); -} - asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) {struct mm_struct *mm = current->mm;
@@ -320,10 +308,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) goto intr_or_no_mm; } } -if (unlikely ((address >>32 ) !=0 )) { -bogus_32bit_fault_address (regs, address); +if (unlikely ((address >>32 ) !=0 )) goto intr_or_no_mm; - } }if (regs->tstate &TSTATE_PRIV ) {
Signature · 1 line
2.0.4
PATCH 51/104 sparc64: Fix huge TSB mapping on pre-UltraSPARC-III cpus.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit b18eb2d779240631a098626cb6841ee2dd34fda0 ]
Access to the TSB hash tables during TLB misses requires that there be an atomic 128-bit quad load available so that we fetch a matching TAG and DATA field at the same time.
On cpus prior to UltraSPARC-III only virtual address based quad loads are available. UltraSPARC-III and later provide physical address based variants which are easier to use.
When we only have virtual address based quad loads available this means that we have to lock the TSB into the TLB at a fixed virtual address on each cpu when it runs that process. We can't just access the PAGE_OFFSET based aliased mapping of these TSBs because we cannot take a recursive TLB miss inside of the TLB miss handler without risking running out of hardware trap levels (some trap combinations can be deep, such as those generated by register window spill and fill traps).
Without huge pages it's working perfectly fine, but when the huge TSB got added another chunk of fixed virtual address space was not allocated for this second TSB mapping.
So we were mapping both the 8K and 4MB TSBs to the same exact virtual address, causing multiple TLB matches which gives undefined behavior.
--- arch/sparc/include/asm/pgtable_64.h | 6 ++++-- arch/sparc/mm/tsb.c | 14 +++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-)
arch/sparc/include/asm/pgtable_64.h +4 -2
@@ -24,7 +24,8 @@/* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB). * The page copy blockops can use 0x6000000 to 0x8000000. -* The TSB is mapped in the 0x8000000 to 0xa000000 range. +* The 8K TSB is mapped in the 0x8000000 to 0x8400000 range. +* The 4M TSB is mapped in the 0x8400000 to 0x8800000 range. * The PROM resides in an area spanning 0xf0000000 to 0x100000000. * The vmalloc area spans 0x100000000 to 0x200000000. * Since modules need to be in the lowest 32-bits of the address space,
@@ -33,7 +34,8 @@* 0x400000000. */ #define TLBTEMP_BASE _AC(0x0000000006000000,UL) -#define TSBMAP_BASE _AC(0x0000000008000000,UL) +#define TSBMAP_8K_BASE _AC(0x0000000008000000,UL) +#define TSBMAP_4M_BASE _AC(0x0000000008400000,UL)#define MODULES_VADDR _AC(0x0000000010000000,UL)#define MODULES_LEN _AC(0x00000000e0000000,UL)#define MODULES_END _AC(0x00000000f0000000,UL)
arch/sparc/mm/tsb.c +13 -1
@@ -133,7 +133,19 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsign mm->context.tsb_block[tsb_idx].tsb_nentries = tsb_bytes /sizeof (struct tsb ); - base =TSBMAP_BASE ; +switch (tsb_idx) { +case MM_TSB_BASE : + base =TSBMAP_8K_BASE ; +break ; +#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) +case MM_TSB_HUGE : + base =TSBMAP_4M_BASE ; +break ; +#endif +default : +BUG (); + } + tte =pgprot_val (PAGE_KERNEL_LOCKED ); tsb_paddr =__pa (mm->context.tsb_block[tsb_idx].tsb);BUG_ON (tsb_paddr & (tsb_bytes -1UL ));
Signature · 1 line
2.0.4
PATCH 52/104 sparc64: Add membar to Niagara2 memcpy code.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 5aa4ecfd0ddb1e6dcd1c886e6c49677550f581aa ]
This is the prevent previous stores from overlapping the block stores done by the memcpy loop.
Based upon a glibc patch by Jose E. Marchesi
--- arch/sparc/lib/NG2memcpy.S | 1 + 1 file changed, 1 insertion(+)
arch/sparc/lib/NG2memcpy.S +1 -0
@@ -236,6 +236,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ */ VISEntryHalf + membar #Sync alignaddr %o1, %g0, %g0 add %o1, (64 - 1), %o4
Signature · 1 line
2.0.4
PATCH 53/104 sparc64: Do not insert non-valid PTEs into the TSB hash table.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 18f38132528c3e603c66ea464727b29e9bbcb91b ]
The assumption was that update_mmu_cache() (and the equivalent for PMDs) would only be called when the PTE being installed will be accessible by the user.
This is not true for code paths originating from remove_migration_pte().
There are dire consequences for placing a non-valid PTE into the TSB. The TLB miss frramework assumes thatwhen a TSB entry matches we can just load it into the TLB and return from the TLB miss trap.
So if a non-valid PTE is in there, we will deadlock taking the TLB miss over and over, never satisfying the miss.
Just exit early from update_mmu_cache() and friends in this situation.
Based upon a report and patch from Christopher Alexander Tobias Schulze.
--- arch/sparc/mm/init_64.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/sparc/mm/init_64.c +4 -0
@@ -350,6 +350,10 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t * mm = vma->vm_mm; +/* Don't insert a non-valid PTE into the TSB, we'll deadlock. */ +if (!pte_accessible (mm, pte)) +return ; +spin_lock_irqsave (&mm->context.lock, flags);#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE )
Signature · 1 line
2.0.4
PATCH 54/104 sparc64: Guard against flushing openfirmware mappings.
In reply to Jiri SlabyFrom: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 4ca9a23765da3260058db3431faf5b4efd8cf926 ]
Based almost entirely upon a patch by Christopher Alexander Tobias Schulze.
In commit db64fe02258f1507e13fe5212a989922323685ce ("mm: rewrite vmap layer") lazy VMAP tlb flushing was added to the vmalloc layer. This causes problems on sparc64.
Sparc64 has two VMAP mapped regions and they are not contiguous with eachother. First we have the malloc mapping area, then another unrelated region, then the vmalloc region.
This "another unrelated region" is where the firmware is mapped.
If the lazy TLB flushing logic in the vmalloc code triggers after we've had both a module unload and a vfree or similar, it will pass an address range that goes from somewhere inside the malloc region to somewhere inside the vmalloc region, and thus covering the openfirmware area entirely.
The sparc64 kernel learns about openfirmware's dynamic mappings in this region early in the boot, and then services TLB misses in this area. But openfirmware has some locked TLB entries which are not mentioned in those dynamic mappings and we should thus not disturb them.
These huge lazy TLB flush ranges causes those openfirmware locked TLB entries to be removed, resulting in all kinds of problems including hard hangs and crashes during reboot/reset.
Besides causing problems like this, such huge TLB flush ranges are also incredibly inefficient. A plea has been made with the author of the VMAP lazy TLB flushing code, but for now we'll put a safety guard into our flush_tlb_kernel_range() implementation.
Since the implementation has become non-trivial, stop defining it as a macro and instead make it a function in a C source file.
--- arch/sparc/include/asm/tlbflush_64.h | 12 ++---------- arch/sparc/mm/init_64.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-)
arch/sparc/include/asm/tlbflush_64.h +2 -10
@@ -35,6 +35,8 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, { } +void flush_tlb_kernel_range (unsigned long start,unsigned long end); +#define __HAVE_ARCH_ENTER_LAZY_MMU_MODEextern void flush_tlb_pending (void );
@@ -49,11 +51,6 @@ extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);#ifndef CONFIG_SMP -#define flush_tlb_kernel_range (start,end) \ -do { flush_tsb_kernel_range(start,end); \ - __flush_tlb_kernel_range(start,end); \ -} while (0) -static inline void global_flush_tlb_page (struct mm_struct *mm,unsigned long vaddr) {__flush_tlb_page (CTX_HWBITS (mm->context), vaddr);
@@ -64,11 +61,6 @@ static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vadextern void smp_flush_tlb_kernel_range (unsigned long start,unsigned long end);extern void smp_flush_tlb_page (struct mm_struct *mm,unsigned long vaddr); -#define flush_tlb_kernel_range (start, end) \ -do { flush_tsb_kernel_range(start,end); \ - smp_flush_tlb_kernel_range(start, end); \ -} while (0) -#define global_flush_tlb_page (mm, vaddr) \ smp_flush_tlb_page(mm, vaddr)
arch/sparc/mm/init_64.c +23 -0
@@ -2750,3 +2750,26 @@ void hugetlb_setup(struct pt_regs *regs) } }#endif + +#ifdef CONFIG_SMP +#define do_flush_tlb_kernel_range smp_flush_tlb_kernel_range +#else +#define do_flush_tlb_kernel_range __flush_tlb_kernel_range +#endif + +void flush_tlb_kernel_range (unsigned long start,unsigned long end) +{ +if (start <HI_OBP_ADDRESS && end >LOW_OBP_ADDRESS ) { +if (start <LOW_OBP_ADDRESS ) { +flush_tsb_kernel_range (start,LOW_OBP_ADDRESS ); +do_flush_tlb_kernel_range (start,LOW_OBP_ADDRESS ); + } +if (end >HI_OBP_ADDRESS ) { +flush_tsb_kernel_range (end,HI_OBP_ADDRESS ); +do_flush_tlb_kernel_range (end,HI_OBP_ADDRESS ); + } + }else { +flush_tsb_kernel_range (start, end); +do_flush_tlb_kernel_range (start, end); + } +}
Signature · 1 line
2.0.4
PATCH 55/104 bbc-i2c: Fix BBC I2C envctrl on SunBlade 2000
In reply to Jiri SlabyFrom: Christopher Alexander Tobias Schulze <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 5cdceab3d5e02eb69ea0f5d8fa9181800baf6f77 ]
Fix regression in bbc i2c temperature and fan control on some Sun systems that causes the driver to refuse to load due to the bbc_i2c_bussel resource not being present on the (second) i2c bus where the temperature sensors and fan control are located. (The check for the number of resources was removed when the driver was ported to a pure OF driver in mid 2008.)
--- drivers/sbus/char/bbc_envctrl.c | 6 ++++++ drivers/sbus/char/bbc_i2c.c | 11 ++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-)
drivers/sbus/char/bbc_envctrl.c +6 -0
@@ -452,6 +452,9 @@ static void attach_one_temp(struct bbc_i2c_bus *bp, struct platform_device *op,if (!tp)return ; +INIT_LIST_HEAD (&tp->bp_list); +INIT_LIST_HEAD (&tp->glob_list); + tp->client =bbc_i2c_attach (bp, op);if (!tp->client) {kfree (tp);
@@ -497,6 +500,9 @@ static void attach_one_fan(struct bbc_i2c_bus *bp, struct platform_device *op,if (!fp)return ; +INIT_LIST_HEAD (&fp->bp_list); +INIT_LIST_HEAD (&fp->glob_list); + fp->client =bbc_i2c_attach (bp, op);if (!fp->client) {kfree (fp);
drivers/sbus/char/bbc_i2c.c +8 -3
@@ -301,13 +301,18 @@ static struct bbc_i2c_bus * attach_one_i2c(struct platform_device *op, int indexif (!bp)return NULL ; +INIT_LIST_HEAD (&bp->temps); +INIT_LIST_HEAD (&bp->fans); + bp->i2c_control_regs =of_ioremap (&op->resource[0 ],0 ,0x2 ,"bbc_i2c_regs" );if (!bp->i2c_control_regs) goto fail; - bp->i2c_bussel_reg =of_ioremap (&op->resource[1 ],0 ,0x1 ,"bbc_i2c_bussel" ); -if (!bp->i2c_bussel_reg) - goto fail; +if (op->num_resources ==2 ) { + bp->i2c_bussel_reg =of_ioremap (&op->resource[1 ],0 ,0x1 ,"bbc_i2c_bussel" ); +if (!bp->i2c_bussel_reg) + goto fail; + } bp->waiting =0 ;init_waitqueue_head (&bp->wq);
Signature · 1 line
2.0.4
PATCH 56/104 sunsab: Fix detection of BREAK on sunsab serial console
In reply to Jiri SlabyFrom: Christopher Alexander Tobias Schulze <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit fe418231b195c205701c0cc550a03f6c9758fd9e ]
Fix detection of BREAK on sunsab serial console: BREAK detection was only performed when there were also serial characters received simultaneously. To handle all BREAKs correctly, the check for BREAK and the corresponding call to uart_handle_break() must also be done if count == 0, therefore duplicate this code fragment and pull it out of the loop over the received characters.
Patch applies to 3.16-rc6.
--- drivers/tty/serial/sunsab.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/tty/serial/sunsab.c +9 -0
@@ -157,6 +157,15 @@ receive_chars(struct uart_sunsab_port *up, (up->port.line == up->port.cons->index)) saw_console_brk =1 ; +if (count ==0 ) { +if (unlikely (stat->sreg.isr1 &SAB82532_ISR1_BRK )) { + stat->sreg.isr0 &= ~(SAB82532_ISR0_PERR | +SAB82532_ISR0_FERR ); + up->port.icount.brk++; +uart_handle_break (&up->port); + } + } +for (i =0 ; i < count; i++) {unsigned char ch = buf[i], flag;
Signature · 1 line
2.0.4
PATCH 57/104 sparc64: ldc_connect() should not return EINVAL when handshake is in progress.
In reply to Jiri SlabyFrom: Sowmini Varadhan <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 4ec1b01029b4facb651b8ef70bc20a4be4cebc63 ]
The LDC handshake could have been asynchronously triggered after ldc_bind() enables the ldc_rx() receive interrupt-handler (and thus intercepts incoming control packets)
and before vio_port_up() calls ldc_connect(). If that is the case, ldc_connect() should return 0 and let the state-machine progress.
--- arch/sparc/kernel/ldc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sparc/kernel/ldc.c +1 -1
@@ -1336,7 +1336,7 @@ int ldc_connect(struct ldc_channel *lp)if (!(lp->flags &LDC_FLAG_ALLOCED_QUEUES ) || !(lp->flags &LDC_FLAG_REGISTERED_QUEUES ) || lp->hs_state !=LDC_HS_OPEN ) - err = -EINVAL ; + err = ((lp->hs_state >LDC_HS_OPEN ) ?0 : -EINVAL );else err =start_handshake (lp);
Signature · 1 line
2.0.4
PATCH 58/104 arch/sparc/math-emu/math_32.c: drop stray break operator
In reply to Jiri SlabyFrom: Andrey Utkin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
[ Upstream commit 093758e3daede29cb4ce6aedb111becf9d4bfc57 ]
This commit is a guesswork, but it seems to make sense to drop this break, as otherwise the following line is never executed and becomes dead code. And that following line actually saves the result of local calculation by the pointer given in function argument. So the proposed change makes sense if this code in the whole makes sense (but I am unable to analyze it in the whole).
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=81641
--- arch/sparc/math-emu/math_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sparc/math-emu/math_32.c +1 -1
@@ -499,7 +499,7 @@ static int do_one_mathemu(u32 insn, unsigned long *pfsr, unsigned long *fregs)case 0 : fsr = *pfsr;if (IR ==-1 )IR =2 ;/* fcc is always fcc0 */ - fsr &= ~0xc00 ; fsr |= (IR <<10 );break ; + fsr &= ~0xc00 ; fsr |= (IR <<10 ); *pfsr = fsr;break ;case 1 : rd->s =IR ;break ;
Signature · 1 line
2.0.4
PATCH 59/104 iwlwifi: mvm: Add a missed beacons threshold
In reply to Jiri SlabyFrom: Ilan Peer <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 12d423e816c69b0b4457bc047dda9a0a1c1a53c1 upstream.
Instead of always calling ieee80211_beacon_loss() on every missed beacons notification, call this function only if the number of consecutive missed beacons from last rx is higher than a predefined threshold.
--- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 25 ++++++++++++++++++++----- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 2 files changed, 21 insertions(+), 5 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +20 -5
@@ -1102,10 +1102,18 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,static void iwl_mvm_beacon_loss_iterator (void *_data,u8 *mac,struct ieee80211_vif *vif) { -u16 *id = _data; +struct iwl_missed_beacons_notif *missed_beacons = _data;struct iwl_mvm_vif *mvmvif =iwl_mvm_vif_from_mac80211 (vif); -if (mvmvif->id == *id) +if (mvmvif->id != (u16 )le32_to_cpu (missed_beacons->mac_id)) +return ; + +/* +* TODO: the threshold should be adjusted based on latency conditions, +* and/or in case of a CS flow on one of the other AP vifs. +*/ +if (le32_to_cpu (missed_beacons->consec_missed_beacons_since_last_rx) > +IWL_MVM_MISSED_BEACONS_THRESHOLD )ieee80211_beacon_loss (vif); }
@@ -1114,12 +1122,19 @@ int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, struct iwl_device_cmd *cmd) {struct iwl_rx_packet *pkt =rxb_addr (rxb); -struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data; -u16 id = (u16 )le32_to_cpu (missed_beacons->mac_id); +struct iwl_missed_beacons_notif *mb = (void *)pkt->data; + +IWL_DEBUG_INFO (mvm, +"missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n" , +le32_to_cpu (mb->mac_id), +le32_to_cpu (mb->consec_missed_beacons), +le32_to_cpu (mb->consec_missed_beacons_since_last_rx), +le32_to_cpu (mb->num_recvd_beacons), +le32_to_cpu (mb->num_expected_beacons));ieee80211_iterate_active_interfaces_atomic (mvm->hw,IEEE80211_IFACE_ITER_NORMAL , iwl_mvm_beacon_loss_iterator, - &id); + mb);return 0 ; }
drivers/net/wireless/iwlwifi/mvm/mvm.h +1 -0
@@ -82,6 +82,7 @@#define IWL_MVM_MAX_ADDRESSES 5/* RSSI offset for WkP */ #define IWL_RSSI_OFFSET 50 +#define IWL_MVM_MISSED_BEACONS_THRESHOLD 8enum iwl_mvm_tx_fifo {IWL_MVM_TX_FIFO_BK =0 ,
Signature · 1 line
2.0.4
PATCH 60/104 mac80211: reset probe_send_count also in HW_CONNECTION_MONITOR case
In reply to Jiri SlabyFrom: Eliad Peller <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 448cd2e248732326632957e52ea9c44729affcb2 upstream.
In case of beacon_loss with IEEE80211_HW_CONNECTION_MONITOR device, mac80211 probes the ap (and disconnects on timeout) but ignores the ack.
If we already got an ack, there's no reason to continue disconnecting. this can help devices that supports IEEE80211_HW_CONNECTION_MONITOR only partially (e.g. take care of keep alives, but does not probe the ap.
In case the device wants to disconnect without probing, it can just call ieee80211_connection_loss.
--- include/net/mac80211.h | 2 -- net/mac80211/mlme.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-)
include/net/mac80211.h +0 -2
@@ -1449,8 +1449,6 @@ struct ieee80211_tx_control {* @IEEE80211_HW_CONNECTION_MONITOR: * The hardware performs its own connection monitoring, including * periodic keep-alives to the AP and probing the AP on beacon loss. -* When this flag is set, signaling beacon-loss will cause an immediate -* change to disassociated state. * * @IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC: * This device needs to get data from beacon before association (i.e.
net/mac80211/mlme.c +2 -2
@@ -131,13 +131,13 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)if (unlikely (!sdata->u.mgd.associated))return ; + ifmgd->probe_send_count =0 ; +if (sdata->local->hw.flags &IEEE80211_HW_CONNECTION_MONITOR )return ;mod_timer (&sdata->u.mgd.conn_mon_timer,round_jiffies_up (jiffies +IEEE80211_CONNECTION_IDLE_TIME )); - - ifmgd->probe_send_count =0 ; }static int ecw2cw (int ecw)
Signature · 1 line
2.0.4
PATCH 61/104 hugetlb: fix copy_hugetlb_page_range() to handle migration/hwpoisoned entry
In reply to Jiri SlabyFrom: Naoya Horiguchi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4a705fef986231a3e7a6b1a6d3c37025f021f49f upstream.
There's a race between fork() and hugepage migration, as a result we try to "dereference" a swap entry as a normal pte, causing kernel panic. The cause of the problem is that copy_hugetlb_page_range() can't handle "swap entry" family (migration entry and hwpoisoned entry) so let's fix it.
--- mm/hugetlb.c | 71 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 28 deletions(-)
mm/hugetlb.c +43 -28
@@ -2381,6 +2381,31 @@ static void set_huge_ptep_writable(struct vm_area_struct *vma,update_mmu_cache (vma, address, ptep); } +static int is_hugetlb_entry_migration (pte_t pte) +{ +swp_entry_t swp; + +if (huge_pte_none (pte) ||pte_present (pte)) +return 0 ; + swp =pte_to_swp_entry (pte); +if (non_swap_entry (swp) &&is_migration_entry (swp)) +return 1 ; +else +return 0 ; +} + +static int is_hugetlb_entry_hwpoisoned (pte_t pte) +{ +swp_entry_t swp; + +if (huge_pte_none (pte) ||pte_present (pte)) +return 0 ; + swp =pte_to_swp_entry (pte); +if (non_swap_entry (swp) &&is_hwpoison_entry (swp)) +return 1 ; +else +return 0 ; +}int copy_hugetlb_page_range (struct mm_struct *dst,struct mm_struct *src,struct vm_area_struct *vma)
@@ -2408,10 +2433,26 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,spin_lock (&dst->page_table_lock);spin_lock_nested (&src->page_table_lock,SINGLE_DEPTH_NESTING ); -if (!huge_pte_none (huge_ptep_get (src_pte))) { + entry =huge_ptep_get (src_pte); +if (huge_pte_none (entry)) {/* skip none entry */ + ; + }else if (unlikely (is_hugetlb_entry_migration (entry) || +is_hugetlb_entry_hwpoisoned (entry))) { +swp_entry_t swp_entry =pte_to_swp_entry (entry); + +if (is_write_migration_entry (swp_entry) && cow) { +/* +* COW mappings require pages in both +* parent and child to be set to read. +*/ +make_migration_entry_read (&swp_entry); + entry =swp_entry_to_pte (swp_entry); +set_huge_pte_at (src, addr, src_pte, entry); + } +set_huge_pte_at (dst, addr, dst_pte, entry); + }else {if (cow)huge_ptep_set_wrprotect (src, addr, src_pte); - entry =huge_ptep_get (src_pte); ptepage =pte_page (entry);get_page (ptepage);page_dup_rmap (ptepage);
@@ -2426,32 +2467,6 @@ nomem:return -ENOMEM ; } -static int is_hugetlb_entry_migration (pte_t pte) -{ -swp_entry_t swp; - -if (huge_pte_none (pte) ||pte_present (pte)) -return 0 ; - swp =pte_to_swp_entry (pte); -if (non_swap_entry (swp) &&is_migration_entry (swp)) -return 1 ; -else -return 0 ; -} - -static int is_hugetlb_entry_hwpoisoned (pte_t pte) -{ -swp_entry_t swp; - -if (huge_pte_none (pte) ||pte_present (pte)) -return 0 ; - swp =pte_to_swp_entry (pte); -if (non_swap_entry (swp) &&is_hwpoison_entry (swp)) -return 1 ; -else -return 0 ; -} -void __unmap_hugepage_range (struct mmu_gather *tlb,struct vm_area_struct *vma,unsigned long start,unsigned long end,struct page *ref_page)
Signature · 1 line
2.0.4
PATCH 62/104 mm: hugetlb: fix copy_hugetlb_page_range()
In reply to Jiri SlabyFrom: Naoya Horiguchi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0253d634e0803a8376a0d88efee0bf523d8673f9 upstream.
Commit 4a705fef9862 ("hugetlb: fix copy_hugetlb_page_range() to handle migration/hwpoisoned entry") changed the order of huge_ptep_set_wrprotect() and huge_ptep_get(), which leads to breakage in some workloads like hugepage-backed heap allocation via libhugetlbfs. This patch fixes it.
The test program for the problem is shown below:
$ cat heap.c #include <unistd.h> #include <stdlib.h> #include <string.h>
#define HPS 0x200000
int main() {
int i;
char *p = malloc(HPS);
memset(p, '1', HPS);
for (i = 0; i < 5; i++) {
if (!fork()) {
memset(p, '2', HPS);
p = malloc(HPS);
memset(p, '3', HPS);
free(p);
return 0;
}
}
sleep(1);
free(p);
return 0;
}
$ export HUGETLB_MORECORE=yes ; export HUGETLB_NO_PREFAULT= ; hugectl --heap ./heapFixes 4a705fef9862 ("hugetlb: fix copy_hugetlb_page_range() to handle migration/hwpoisoned entry"), so is applicable to -stable kernels which include it.
--- mm/hugetlb.c | 1 + 1 file changed, 1 insertion(+)
mm/hugetlb.c +1 -0
@@ -2453,6 +2453,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, }else {if (cow)huge_ptep_set_wrprotect (src, addr, src_pte); + entry =huge_ptep_get (src_pte); ptepage =pte_page (entry);get_page (ptepage);page_dup_rmap (ptepage);
Signature · 1 line
2.0.4
PATCH 63/104 mnt: Only change user settable mount flags in remount
In reply to Jiri SlabyFrom: "Eric W. Biederman" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a6138db815df5ee542d848318e5dae681590fccd upstream.
Kenton Varda <[email protected]> discovered that by remounting a read-only bind mount read-only in a user namespace the MNT_LOCK_READONLY bit would be cleared, allowing an unprivileged user to the remount a read-only mount read-write.
Correct this by replacing the mask of mount flags to preserve with a mask of mount flags that may be changed, and preserve
all others. This ensures that any future bugs with this mask and
remount will fail in an easy to detect way where new mount flags simply won't change.
--- fs/namespace.c | 2 +- include/linux/mount.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
fs/namespace.c +1 -1
@@ -1847,7 +1847,7 @@ static int do_remount(struct path *path, int flags, int mnt_flags, err =do_remount_sb (sb, flags, data,0 );if (!err) {br_write_lock (&vfsmount_lock); - mnt_flags |= mnt->mnt.mnt_flags &MNT_PROPAGATION_MASK ; + mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK ; mnt->mnt.mnt_flags = mnt_flags;br_write_unlock (&vfsmount_lock); }
include/linux/mount.h +3 -1
@@ -42,7 +42,9 @@ struct mnt_namespace;* flag, consider how it interacts with shared mounts. */ #define MNT_SHARED_MASK (MNT_UNBINDABLE) -#define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE) +#define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \ + | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \ + | MNT_READONLY)#define MNT_INTERNAL 0x4000
Signature · 1 line
2.0.4
PATCH 64/104 mnt: Move the test for MNT_LOCK_READONLY from change_mount_flags into do_remount
In reply to Jiri SlabyFrom: "Eric W. Biederman" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 07b645589dcda8b7a5249e096fece2a67556f0f4 upstream.
There are no races as locked mount flags are guaranteed to never change.
Moving the test into do_remount makes it more visible, and ensures all filesystem remounts pass the MNT_LOCK_READONLY permission check. This second case is not an issue today as filesystem remounts are guarded by capable(CAP_DAC_ADMIN) and thus will always fail in less privileged mount namespaces, but it could become an issue in the future.
--- fs/namespace.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
fs/namespace.c +10 -3
@@ -1806,9 +1806,6 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)if (readonly_request ==__mnt_is_readonly (mnt))return 0 ; -if (mnt->mnt_flags &MNT_LOCK_READONLY ) -return -EPERM ; -if (readonly_request) error =mnt_make_readonly (real_mount (mnt));else
@@ -1834,6 +1831,16 @@ static int do_remount(struct path *path, int flags, int mnt_flags,if (path->dentry != path->mnt->mnt_root)return -EINVAL ; +/* Don't allow changing of locked mnt flags. +* +* No locks need to be held here while testing the various +* MNT_LOCK flags because those flags can never be cleared +* once they are set. +*/ +if ((mnt->mnt.mnt_flags &MNT_LOCK_READONLY ) && + !(mnt_flags &MNT_READONLY )) { +return -EPERM ; + } err =security_sb_remount (sb, data);if (err)return err;
Signature · 1 line
2.0.4
PATCH 65/104 mnt: Correct permission checks in do_remount
In reply to Jiri SlabyFrom: "Eric W. Biederman" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9566d6742852c527bf5af38af5cbb878dad75705 upstream.
While invesgiating the issue where in "mount --bind -oremount,ro ..." would result in later "mount --bind -oremount,rw" succeeding even if the mount started off locked I realized that there are several additional mount flags that should be locked and are not.
In particular MNT_NOSUID, MNT_NODEV, MNT_NOEXEC, and the atime flags in addition to MNT_READONLY should all be locked. These flags are all per superblock, can all be changed with MS_BIND, and should not be changable if set by a more privileged user.
The following additions to the current logic are added in this patch.
- nosuid may not be clearable by a less privileged user.
- nodev may not be clearable by a less privielged user.
- noexec may not be clearable by a less privileged user.
- atime flags may not be changeable by a less privileged user.
The logic with atime is that always setting atime on access is a global policy and backup software and auditing software could break if atime bits are not updated (when they are configured to be updated), and serious performance degradation could result (DOS attack) if atime updates happen when they have been explicitly disabled. Therefore an unprivileged user should not be able to mess with the atime bits set by a more privileged user.
The additional restrictions are implemented with the addition of MNT_LOCK_NOSUID, MNT_LOCK_NODEV, MNT_LOCK_NOEXEC, and MNT_LOCK_ATIME mnt flags.
Taken together these changes and the fixes for MNT_LOCK_READONLY should make it safe for an unprivileged user to create a user namespace and to call "mount --bind -o remount,... ..." without the danger of mount flags being changed maliciously.
--- fs/namespace.c | 36 +++++++++++++++++++++++++++++++++--- include/linux/mount.h | 5 +++++ 2 files changed, 38 insertions(+), 3 deletions(-)
fs/namespace.c +33 -3
@@ -827,8 +827,21 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD ;/* Don't allow unprivileged users to change mount flags */ -if ((flag &CL_UNPRIVILEGED ) && (mnt->mnt.mnt_flags &MNT_READONLY )) - mnt->mnt.mnt_flags |=MNT_LOCK_READONLY ; +if (flag &CL_UNPRIVILEGED ) { + mnt->mnt.mnt_flags |=MNT_LOCK_ATIME ; + +if (mnt->mnt.mnt_flags &MNT_READONLY ) + mnt->mnt.mnt_flags |=MNT_LOCK_READONLY ; + +if (mnt->mnt.mnt_flags &MNT_NODEV ) + mnt->mnt.mnt_flags |=MNT_LOCK_NODEV ; + +if (mnt->mnt.mnt_flags &MNT_NOSUID ) + mnt->mnt.mnt_flags |=MNT_LOCK_NOSUID ; + +if (mnt->mnt.mnt_flags &MNT_NOEXEC ) + mnt->mnt.mnt_flags |=MNT_LOCK_NOEXEC ; + }/* Don't allow unprivileged users to reveal what is under a mount */ if ((flag &CL_UNPRIVILEGED ) &&list_empty (&old->mnt_expire))
@@ -1841,6 +1854,23 @@ static int do_remount(struct path *path, int flags, int mnt_flags, !(mnt_flags & MNT_READONLY)) {return -EPERM ; } +if ((mnt->mnt.mnt_flags &MNT_LOCK_NODEV ) && + !(mnt_flags &MNT_NODEV )) { +return -EPERM ; + } +if ((mnt->mnt.mnt_flags &MNT_LOCK_NOSUID ) && + !(mnt_flags &MNT_NOSUID )) { +return -EPERM ; + } +if ((mnt->mnt.mnt_flags &MNT_LOCK_NOEXEC ) && + !(mnt_flags &MNT_NOEXEC )) { +return -EPERM ; + } +if ((mnt->mnt.mnt_flags &MNT_LOCK_ATIME ) && + ((mnt->mnt.mnt_flags &MNT_ATIME_MASK ) != (mnt_flags &MNT_ATIME_MASK ))) { +return -EPERM ; + } + err =security_sb_remount (sb, data);if (err)return err;
@@ -2043,7 +2073,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,*/ if (!(type->fs_flags &FS_USERNS_DEV_MOUNT )) { flags |=MS_NODEV ; - mnt_flags |=MNT_NODEV ; + mnt_flags |=MNT_NODEV |MNT_LOCK_NODEV ; } }
include/linux/mount.h +5 -0
@@ -45,10 +45,15 @@ struct mnt_namespace;#define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \ | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \ | MNT_READONLY) +#define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME )#define MNT_INTERNAL 0x4000 +#define MNT_LOCK_ATIME 0x040000 +#define MNT_LOCK_NOEXEC 0x080000 +#define MNT_LOCK_NOSUID 0x100000 +#define MNT_LOCK_NODEV 0x200000#define MNT_LOCK_READONLY 0x400000#define MNT_LOCKED 0x800000
Signature · 1 line
2.0.4
PATCH 66/104 ext4: Fix block zeroing when punching holes in indirect block files
In reply to Jiri SlabyFrom: Jan Kara <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 77ea2a4ba657a1ad4fb7c64bc5cdce84b8a132b6 upstream.
free_holes_block() passed local variable as a block pointer to ext4_clear_blocks(). Thus ext4_clear_blocks() zeroed out this local variable instead of proper place in inode / indirect block. We later zero out proper place in inode / indirect block but don't dirty the inode / buffer again which can lead to subtle issues (some changes e.g. to inode can be lost).
--- fs/ext4/indirect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/indirect.c +2 -2
@@ -1345,8 +1345,8 @@ static int free_hole_blocks(handle_t *handle, struct inode *inode,if (level ==0 || (bh &&all_zeroes ((__le32 *)bh->b_data, (__le32 *)bh->b_data + addr_per_block))) { -ext4_free_data (handle, inode, parent_bh, &blk, &blk+1 ); - *i_data =0 ; +ext4_free_data (handle, inode, parent_bh, + i_data, i_data +1 ); }brelse (bh); bh =NULL ;
Signature · 1 line
2.0.4
PATCH 67/104 offb: Little endian fixes
In reply to Jiri SlabyFrom: Cedric Le Goater <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 212c0cbd5be721a39ef3e2f723e0c78008f9e955 upstream.
The "screen" properties : depth, width, height, linebytes need to be converted to the host endian order when read from the device tree.
The offb_init_palette_hacks() routine also made assumption on the host endian order.
--- drivers/video/offb.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
drivers/video/offb.c +11 -7
@@ -301,7 +301,7 @@ static struct fb_ops offb_ops = {static void __iomem *offb_map_reg (struct device_node *np,int index,unsigned long offset,unsigned long size) { -const u32 *addrp; +const __be32 *addrp;u64 asize, taddr;unsigned int flags;
@@ -369,7 +369,11 @@ static void offb_init_palette_hacks(struct fb_info *info, struct device_node *dp }of_node_put (pciparent); }else if (dp &&of_device_is_compatible (dp,"qemu,std-vga" )) { -const u32 io_of_addr[3 ] = {0x01000000 ,0x0 ,0x0 }; +#ifdef __BIG_ENDIAN +const __be32 io_of_addr[3 ] = {0x01000000 ,0x0 ,0x0 }; +#else +const __be32 io_of_addr[3 ] = {0x00000001 ,0x0 ,0x0 }; +#endif u64 io_addr =of_translate_address (dp, io_of_addr);if (io_addr !=OF_BAD_ADDR ) { par->cmap_adr =ioremap (io_addr +0x3c8 ,2 );
@@ -536,7 +540,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)unsigned int flags, rsize, addr_prop =0 ;unsigned long max_size =0 ;u64 rstart, address =OF_BAD_ADDR ; -const u32 *pp, *addrp, *up; +const __be32 *pp, *addrp, *up;u64 asize;int foreign_endian =0 ;
@@ -552,25 +556,25 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)if (pp ==NULL ) pp =of_get_property (dp,"depth" , &len);if (pp && len ==sizeof (u32)) - depth = *pp; + depth =be32_to_cpup (pp); pp =of_get_property (dp,"linux,bootx-width" , &len);if (pp ==NULL ) pp =of_get_property (dp,"width" , &len);if (pp && len ==sizeof (u32)) - width = *pp; + width =be32_to_cpup (pp); pp =of_get_property (dp,"linux,bootx-height" , &len);if (pp ==NULL ) pp =of_get_property (dp,"height" , &len);if (pp && len ==sizeof (u32)) - height = *pp; + height =be32_to_cpup (pp); pp =of_get_property (dp,"linux,bootx-linebytes" , &len);if (pp ==NULL ) pp =of_get_property (dp,"linebytes" , &len);if (pp && len ==sizeof (u32) && (*pp !=0xffffffffu )) - pitch = *pp; + pitch =be32_to_cpup (pp);else pitch = width * ((depth +7 ) /8 );
Signature · 1 line
2.0.4
PATCH 68/104 fbcon: Clean up fbcon data in fb_info on FB_EVENT_FB_UNBIND with 0 fbs
In reply to Jiri SlabyFrom: Keith Packard <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5f4dc28bd9c8a990ed6253303b7a821a7abfe9fa upstream.
When FB_EVENT_FB_UNBIND is sent, fbcon has two paths, one path taken when there is another frame buffer to switch any affected vcs to and another path when there isn't.
In the case where there is another frame buffer to use, fbcon_fb_unbind calls set_con2fb_map to remap all of the affected vcs to the replacement frame buffer. set_con2fb_map will eventually call con2fb_release_oldinfo when the last vcs gets unmapped from the old frame buffer.
con2fb_release_oldinfo frees the fbcon data that is hooked off of the fb_info structure, including the cursor timer.
In the case where there isn't another frame buffer to use, fbcon_fb_unbind simply calls fbcon_unbind, which doesn't clear the con2fb_map or free the fbcon data hooked from the fb_info structure. In particular, it doesn't stop the cursor blink timer. When the fb_info structure is then freed, we end up with a timer queue pointing into freed memory and "bad things" start happening.
This patch first changes con2fb_release_oldinfo so that it can take a NULL pointer for the new frame buffer, but still does all of the deallocation and cursor timer cleanup.
Finally, the patch tries to replicate some of what set_con2fb_map does by clearing the con2fb_map for the affected vcs and calling the modified con2fb_release_info function to clean up the fb_info structure.
--- drivers/video/console/fbcon.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)
drivers/video/console/fbcon.c +25 -2
@@ -759,7 +759,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,newinfo in an undefined state. Thus, a call to fb_set_par() may be needed for the newinfo. */ -if (newinfo->fbops->fb_set_par) { +if (newinfo && newinfo->fbops->fb_set_par) { ret = newinfo->fbops->fb_set_par (newinfo);if (ret)
@@ -3028,8 +3028,31 @@ static int fbcon_fb_unbind(int idx)if (con2fb_map[i] == idx)set_con2fb_map (i, new_idx,0 ); } - }else + }else { +struct fb_info *info = registered_fb[idx]; + +/* This is sort of like set_con2fb_map, except it maps +* the consoles to no device and then releases the +* oldinfo to free memory and cancel the cursor blink +* timer. I can imagine this just becoming part of +* set_con2fb_map where new_idx is -1 +*/ +for (i = first_fb_vc; i <= last_fb_vc; i++) { +if (con2fb_map[i] == idx) { + con2fb_map[i] =-1 ; +if (!search_fb_in_map (idx)) { + ret =con2fb_release_oldinfo (vc_cons[i].d, + info,NULL , i, + idx,0 ); +if (ret) { + con2fb_map[i] = idx; +return ret; + } + } + } + } ret =fbcon_unbind (); + }return ret; }
Signature · 1 line
2.0.4
PATCH 69/104 DMA-API: provide a helper to set both DMA and coherent DMA masks
In reply to Jiri SlabyFrom: Russell King <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4aa806b771d16b810771d86ce23c4c3160888db3 upstream.
Provide a helper to set both the DMA and coherent DMA masks to the same value - this avoids duplicated code in a number of drivers, sometimes with buggy error handling, and also allows us identify which drivers do things differently.
--- Documentation/DMA-API-HOWTO.txt | 37 ++++++++++++++++++++++--------------- Documentation/DMA-API.txt | 8 ++++++++ include/linux/dma-mapping.h | 14 ++++++++++++++ 3 files changed, 44 insertions(+), 15 deletions(-)
Documentation/DMA-API-HOWTO.txt +22 -15
@@ -101,14 +101,23 @@ style to do this even if your device holds the default setting, because this shows that you did think about these issues wrt. your device. -The query is performed via a call to dma_set_mask(): +The query is performed via a call to dma_set_mask_and_coherent(): - int dma_set_mask(struct device *dev, u64 mask); + int dma_set_mask_and_coherent(struct device *dev, u64 mask); -The query for consistent allocations is performed via a call to -dma_set_coherent_mask(): +which will query the mask for both streaming and coherent APIs together. +If you have some special requirements, then the following two separate +queries can be used instead: - int dma_set_coherent_mask(struct device *dev, u64 mask); + The query for streaming mappings is performed via a call to + dma_set_mask(): + + int dma_set_mask(struct device *dev, u64 mask); + + The query for consistent allocations is performed via a call + to dma_set_coherent_mask(): + + int dma_set_coherent_mask(struct device *dev, u64 mask); Here, dev is a pointer to the device struct of your device, and mask is a bit mask describing which bits of an address your device
@@ -137,7 +146,7 @@ exactly why. The standard 32-bit addressing device would do something like this: - if (dma_set_mask(dev, DMA_BIT_MASK(32))) { + if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) { printk(KERN_WARNING "mydev: No suitable DMA available.\n"); goto ignore_this_device;
@@ -171,22 +180,20 @@ the case would look like this: int using_dac, consistent_using_dac; - if (!dma_set_mask(dev, DMA_BIT_MASK(64))) { + if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { using_dac = 1; consistent_using_dac = 1; - dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); - } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) { + } else if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) { using_dac = 0; consistent_using_dac = 0; - dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); } else { printk(KERN_WARNING "mydev: No suitable DMA available.\n"); goto ignore_this_device; } -dma_set_coherent_mask() will always be able to set the same or a -smaller mask as dma_set_mask(). However for the rare case that a +The coherent coherent mask will always be able to set the same or a +smaller mask as the streaming mask. However for the rare case that a device driver only uses consistent allocations, one would have to check the return value from dma_set_coherent_mask().
@@ -199,9 +206,9 @@ address you might do something like: goto ignore_this_device; } -When dma_set_mask() is successful, and returns zero, the kernel saves -away this mask you have provided. The kernel will use this -information later when you make DMA mappings. +When dma_set_mask() or dma_set_mask_and_coherent() is successful, and +returns zero, the kernel saves away this mask you have provided. The +kernel will use this information later when you make DMA mappings. There is a case which we are aware of at this time, which is worth mentioning in this documentation. If your device supports multiple
Documentation/DMA-API.txt +8 -0
@@ -142,6 +142,14 @@ internal API for use by the platform than an external API for use by driver writers. int +dma_set_mask_and_coherent(struct device *dev, u64 mask) + +Checks to see if the mask is possible and updates the device +streaming and coherent DMA mask parameters if it is. + +Returns: 0 if successful and a negative error if not. + +int dma_set_mask(struct device *dev, u64 mask) Checks to see if the mask is possible and updates the device
include/linux/dma-mapping.h +14 -0
@@ -97,6 +97,20 @@ static inline int dma_set_coherent_mask(struct device *dev, u64 mask) }#endif +/* +* Set both the DMA mask and the coherent DMA mask to the same thing. +* Note that we don't check the return value from dma_set_coherent_mask() +* as the DMA API guarantees that the coherent DMA mask can be set to +* the same or smaller than the streaming DMA mask. +*/ +static inline int dma_set_mask_and_coherent (struct device *dev,u64 mask) +{ +int rc =dma_set_mask (dev, mask); +if (rc ==0 ) +dma_set_coherent_mask (dev, mask); +return rc; +} +extern u64 dma_get_required_mask (struct device *dev);static inline unsigned int dma_get_max_seg_size (struct device *dev)
Signature · 1 line
2.0.4
PATCH 70/104 DMA-API: net: intel/e1000e: fix 32-bit DMA mask handling
In reply to Jiri SlabyFrom: Russell King <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 718a39eb587e038f7ded076afcfd8d709879139f upstream.
The fallback to 32-bit DMA mask is rather odd:
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
if (!err) {
err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (!err)
pci_using_dac = 1;
} else {
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
err = dma_set_coherent_mask(&pdev->dev,
DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev,
"No usable DMA configuration, aborting\n");
goto err_dma;
}
}
}This means we only set the coherent DMA mask in the fallback path if the DMA mask set failed, which is silly. This fixes it to set the coherent DMA mask only if dma_set_mask() succeeded, and to error out if either fails.
--- drivers/net/ethernet/intel/e1000e/netdev.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-)
drivers/net/ethernet/intel/e1000e/netdev.c +6 -12
@@ -6563,21 +6563,15 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)return err; pci_using_dac =0 ; - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (64 )); + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (64 ));if (!err) { - err =dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (64 )); -if (!err) - pci_using_dac =1 ; + pci_using_dac =1 ; }else { - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (32 )); + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (32 ));if (err) { - err =dma_set_coherent_mask (&pdev->dev, -DMA_BIT_MASK (32 )); -if (err) { -dev_err (&pdev->dev, -"No usable DMA configuration, aborting\n" ); - goto err_dma; - } +dev_err (&pdev->dev, +"No usable DMA configuration, aborting\n" ); + goto err_dma; } }
Signature · 1 line
2.0.4
PATCH 71/104 e1000e: Fix a compile flag mis-match for suspend/resume
In reply to Jiri SlabyFrom: David Ertman <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7509963c703b71eebccc421585e7f48ebbbd3f38 upstream.
This patch addresses a mis-match between the declaration and usage of the e1000_suspend and e1000_resume functions. Previously, these functions were declared in a CONFIG_PM_SLEEP wrapper, and then utilized within a CONFIG_PM wrapper. Both the declaration and usage will now be contained within CONFIG_PM wrappers.
--- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/e1000e/netdev.c +2 -2
@@ -6186,7 +6186,7 @@ static int __e1000_resume(struct pci_dev *pdev)return 0 ; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int e1000_suspend (struct device *dev) {struct pci_dev *pdev =to_pci_dev (dev);
@@ -6205,7 +6205,7 @@ static int e1000_resume(struct device *dev) return __e1000_resume(pdev); } -#endif /* CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM */ #ifdef CONFIG_PM_RUNTIME static int e1000_runtime_suspend (struct device *dev)
Signature · 1 line
2.0.4
PATCH 72/104 e1000e: Fix compilation warning when !CONFIG_PM_SLEEP
In reply to Jiri SlabyFrom: Mika Westerberg <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 38a529b5d42e4cfc5ac94844e61335a00eb2d320 upstream.
Commit 7509963c703b (e1000e: Fix a compile flag mis-match for suspend/resume) moved suspend and resume hooks to be available when CONFIG_PM is set. However, it can be set even if CONFIG_PM_SLEEP is not set causing following warnings to be emitted:
drivers/net/ethernet/intel/e1000e/netdev.c:6178:12: warning:
‘e1000_suspend’ defined but not used [-Wunused-function]
drivers/net/ethernet/intel/e1000e/netdev.c:6185:12: warning:
‘e1000_resume’ defined but not used [-Wunused-function]
To fix this make the hooks to be available only when CONFIG_PM_SLEEP is set and remove CONFIG_PM wrapping from driver ops because this is already handled by SET_SYSTEM_SLEEP_PM_OPS() and SET_RUNTIME_PM_OPS().
--- drivers/net/ethernet/intel/e1000e/netdev.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/e1000e/netdev.c +2 -6
@@ -6186,7 +6186,7 @@ static int __e1000_resume(struct pci_dev *pdev)return 0 ; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int e1000_suspend (struct device *dev) {struct pci_dev *pdev =to_pci_dev (dev);
@@ -6205,7 +6205,7 @@ static int e1000_resume(struct device *dev) return __e1000_resume(pdev); } -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ #ifdef CONFIG_PM_RUNTIME static int e1000_runtime_suspend (struct device *dev)
@@ -7027,13 +7027,11 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = { };MODULE_DEVICE_TABLE (pci, e1000_pci_tbl); -#ifdef CONFIG_PM static const struct dev_pm_ops e1000_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume)SET_RUNTIME_PM_OPS (e1000_runtime_suspend, e1000_runtime_resume, e1000_idle) }; -#endif /* PCI Device API Driver */ static struct pci_driver e1000_driver = {
@@ -7041,11 +7039,9 @@ static struct pci_driver e1000_driver = { .id_table = e1000_pci_tbl, .probe = e1000_probe, .remove = e1000_remove, -#ifdef CONFIG_PM .driver = { .pm = &e1000_pm_ops, }, -#endif .shutdown = e1000_shutdown, .err_handler = &e1000_err_handler };
Signature · 1 line
2.0.4
PATCH 73/104 e1000: fix wrong queue idx calculation
In reply to Jiri SlabyFrom: Hong Zhiguo <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 49a45a0686cc2b43bcb3834a68416a201475dc77 upstream.
tx_ring and adapter->tx_ring are already of type "struct e1000_tx_ring *"
--- drivers/net/ethernet/intel/e1000/e1000_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/intel/e1000/e1000_main.c +1 -2
@@ -3917,8 +3917,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter," next_to_watch <%x>\n" " jiffies <%lx>\n" " next_to_watch.status <%x>\n" , - (unsigned long )((tx_ring - adapter->tx_ring) / -sizeof (struct e1000_tx_ring )), + (unsigned long )(tx_ring - adapter->tx_ring),readl (hw->hw_addr + tx_ring->tdh),readl (hw->hw_addr + tx_ring->tdt), tx_ring->next_to_use,
Signature · 1 line
2.0.4
PATCH 74/104 e1000: prevent oops when adapter is being closed and reset simultaneously
In reply to Jiri SlabyFrom: yzhu1 <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6a7d64e3e09e11181a07a2e8cd6af5d6355133be upstream.
This change is based on a similar change made to e1000e support in commit bb9e44d0d0f4 ("e1000e: prevent oops when adapter is being closed and reset simultaneously"). The same issue has also been observed on the older e1000 cards.
Here, we have increased the RESET_COUNT value to 50 because there are too many accesses to e1000 nic on stress tests to e1000 nic, it is not enough to set RESET_COUT 25. Experimentation has shown that it is enough to set RESET_COUNT 50.
--- drivers/net/ethernet/intel/e1000/e1000.h | 5 +++++ drivers/net/ethernet/intel/e1000/e1000_main.c | 9 +++++++++ 2 files changed, 14 insertions(+)
drivers/net/ethernet/intel/e1000/e1000.h +5 -0
@@ -83,6 +83,11 @@ struct e1000_adapter;#define E1000_MAX_INTR 10 +/* +* Count for polling __E1000_RESET condition every 10-20msec. +*/ +#define E1000_CHECK_RESET_COUNT 50 +/* TX/RX descriptor defines */ #define E1000_DEFAULT_TXD 256#define E1000_MAX_TXD 256
drivers/net/ethernet/intel/e1000/e1000_main.c +9 -0
@@ -1445,6 +1445,10 @@ static int e1000_close(struct net_device *netdev) {struct e1000_adapter *adapter =netdev_priv (netdev);struct e1000_hw *hw = &adapter->hw; +int count =E1000_CHECK_RESET_COUNT ; + +while (test_bit (__E1000_RESETTING, &adapter->flags) && count--) +usleep_range (10000 ,20000 );WARN_ON (test_bit (__E1000_RESETTING, &adapter->flags));e1000_down (adapter);
@@ -4968,6 +4972,11 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)netif_device_detach (netdev);if (netif_running (netdev)) { +int count =E1000_CHECK_RESET_COUNT ; + +while (test_bit (__E1000_RESETTING, &adapter->flags) && count--) +usleep_range (10000 ,20000 ); +WARN_ON (test_bit (__E1000_RESETTING, &adapter->flags));e1000_down (adapter); }
Signature · 1 line
2.0.4
PATCH 75/104 e1000: fix possible reset_task running after adapter down
In reply to Jiri SlabyFrom: Vladimir Davydov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 74a1b1ea8a30b035aaad833bbd6b9263e72acfac upstream.
On e1000_down(), we should ensure every asynchronous work is canceled before proceeding. Since the watchdog_task can schedule other works apart from itself, it should be stopped first, but currently it is stopped after the reset_task. This can result in the following race leading to the reset_task running after the module unload:
e1000_down_and_stop(): e1000_watchdog():
---------------------- -----------------
cancel_work_sync(reset_task)
schedule_work(reset_task)cancel_delayed_work_sync(watchdog_task)
The patch moves cancel_delayed_work_sync(watchdog_task) at the beginning of e1000_down_and_stop() thus ensuring the race is impossible.
--- drivers/net/ethernet/intel/e1000/e1000_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/net/ethernet/intel/e1000/e1000_main.c +11 -4
@@ -494,13 +494,20 @@ static void e1000_down_and_stop(struct e1000_adapter *adapter) {set_bit (__E1000_DOWN, &adapter->flags); -/* Only kill reset task if adapter is not resetting */ -if (!test_bit (__E1000_RESETTING, &adapter->flags)) -cancel_work_sync (&adapter->reset_task); -cancel_delayed_work_sync (&adapter->watchdog_task); + +/* +* Since the watchdog task can reschedule other tasks, we should cancel +* it first, otherwise we can run into the situation when a work is +* still running after the adapter has been turned down. +*/ +cancel_delayed_work_sync (&adapter->phy_info_task);cancel_delayed_work_sync (&adapter->fifo_stall_task); + +/* Only kill reset task if adapter is not resetting */ +if (!test_bit (__E1000_RESETTING, &adapter->flags)) +cancel_work_sync (&adapter->reset_task); }void e1000_down (struct e1000_adapter *adapter)
Signature · 1 line
2.0.4
PATCH 76/104 DMA-API: net: intel/ixgbe: fix 32-bit DMA mask handling
In reply to Jiri SlabyFrom: Russell King <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f5f2eda8049644a27af5fdf59c3766589358e435 upstream.
The fallback to 32-bit DMA mask is rather odd:
if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
!dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
err = dma_set_coherent_mask(&pdev->dev,
DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev,
"No usable DMA configuration, aborting\n");
goto err_dma;
}
}
pci_using_dac = 0;
}This means we only set the coherent DMA mask in the fallback path if the DMA mask set failed, which is silly. This fixes it to set the coherent DMA mask only if dma_set_mask() succeeded, and to error out if either fails.
--- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +5 -10
@@ -7490,19 +7490,14 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (err)return err; -if (!dma_set_mask (&pdev->dev,DMA_BIT_MASK (64 )) && - !dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (64 ))) { +if (!dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (64 ))) { pci_using_dac =1 ; }else { - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (32 )); + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (32 ));if (err) { - err =dma_set_coherent_mask (&pdev->dev, -DMA_BIT_MASK (32 )); -if (err) { -dev_err (&pdev->dev, -"No usable DMA configuration, aborting\n" ); - goto err_dma; - } +dev_err (&pdev->dev, +"No usable DMA configuration, aborting\n" ); + goto err_dma; } pci_using_dac =0 ; }
Signature · 1 line
2.0.4
PATCH 77/104 ixgbe: fix rx-usecs range checks for BQL
In reply to Jiri SlabyFrom: Emil Tantilov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2e0103810c6fed6a736c4a3af87b0f5c6bd8cd5b upstream.
This patch resolves an issue where the logic used to detect changes in rx-usecs was incorrect and was masked by the call to ixgbe_update_rsc().
Setting rx-usecs between 0,2-9 and 1,10 and up requires a reset to allow ixgbe_configure_tx_ring() to set the correct value for TXDCTL.WTHRESH in order to avoid Tx hangs with BQL enabled.
--- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +3 -3
@@ -2212,13 +2212,13 @@ static int ixgbe_set_coalesce(struct net_device *netdev,#if IS_ENABLED (CONFIG_BQL )/* detect ITR changes that require update of TXDCTL.WTHRESH */ -if ((adapter->tx_itr_setting >1 ) && +if ((adapter->tx_itr_setting !=1 ) && (adapter->tx_itr_setting <IXGBE_100K_ITR )) {if ((tx_itr_prev ==1 ) || - (tx_itr_prev >IXGBE_100K_ITR )) + (tx_itr_prev >=IXGBE_100K_ITR )) need_reset = true; }else { -if ((tx_itr_prev >1 ) && +if ((tx_itr_prev !=1 ) && (tx_itr_prev <IXGBE_100K_ITR )) need_reset = true; }
Signature · 1 line
2.0.4
PATCH 78/104 ixgbe: fix qv_lock_napi call in ixgbe_napi_disable_all
In reply to Jiri SlabyFrom: Jacob Keller <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 27d9ce4fd0e2e75c2907f6d3dc0487012a3e4298 upstream.
ixgbe_napi_disable_all calls napi_disable on each queue, however the busy polling code introduced a local_bh_disable()d context around the napi_disable. The original author did not realize that napi_disable might sleep, which would cause a sleep while atomic BUG. In addition, on a single processor system, the ixgbe_qv_lock_napi loop shouldn't have to mdelay. This patch adds an ixgbe_qv_disable along with a new IXGBE_QV_STATE_DISABLED bit, which it uses to indicate to the poll and napi routines that the q_vector has been disabled. Now the ixgbe_napi_disable_all function will wait until all pending work has been finished and prevent any future work from being started.
--- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 48 ++++++++++++++++++++------- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 6 ++-- 2 files changed, 38 insertions(+), 16 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe.h +36 -12
@@ -369,11 +369,13 @@ struct ixgbe_q_vector {#ifdef CONFIG_NET_RX_BUSY_POLL unsigned int state;#define IXGBE_QV_STATE_IDLE 0 -#define IXGBE_QV_STATE_NAPI 1/* NAPI owns this QV */ -#define IXGBE_QV_STATE_POLL 2/* poll owns this QV */ -#define IXGBE_QV_LOCKED (IXGBE_QV_STATE_NAPI | IXGBE_QV_STATE_POLL) -#define IXGBE_QV_STATE_NAPI_YIELD 4/* NAPI yielded this QV */ -#define IXGBE_QV_STATE_POLL_YIELD 8/* poll yielded this QV */ +#define IXGBE_QV_STATE_NAPI 1/* NAPI owns this QV */ +#define IXGBE_QV_STATE_POLL 2/* poll owns this QV */ +#define IXGBE_QV_STATE_DISABLED 4/* QV is disabled */ +#define IXGBE_QV_OWNED (IXGBE_QV_STATE_NAPI | IXGBE_QV_STATE_POLL) +#define IXGBE_QV_LOCKED (IXGBE_QV_OWNED | IXGBE_QV_STATE_DISABLED) +#define IXGBE_QV_STATE_NAPI_YIELD 8/* NAPI yielded this QV */ +#define IXGBE_QV_STATE_POLL_YIELD 16/* poll yielded this QV */ #define IXGBE_QV_YIELD (IXGBE_QV_STATE_NAPI_YIELD | IXGBE_QV_STATE_POLL_YIELD)#define IXGBE_QV_USER_PEND (IXGBE_QV_STATE_POLL | IXGBE_QV_STATE_POLL_YIELD)spinlock_t lock;
@@ -394,7 +396,7 @@ static inline void ixgbe_qv_init_lock(struct ixgbe_q_vector *q_vector)static inline bool ixgbe_qv_lock_napi (struct ixgbe_q_vector *q_vector) {int rc = true; -spin_lock (&q_vector->lock); +spin_lock_bh (&q_vector->lock);if (q_vector->state &IXGBE_QV_LOCKED ) {WARN_ON (q_vector->state &IXGBE_QV_STATE_NAPI ); q_vector->state |=IXGBE_QV_STATE_NAPI_YIELD ;
@@ -405,7 +407,7 @@ static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector) }else /* we don't care if someone yielded */ q_vector->state =IXGBE_QV_STATE_NAPI ; -spin_unlock (&q_vector->lock); +spin_unlock_bh (&q_vector->lock);return rc; }
@@ -413,14 +415,15 @@ static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector)static inline bool ixgbe_qv_unlock_napi (struct ixgbe_q_vector *q_vector) {int rc = false; -spin_lock (&q_vector->lock); +spin_lock_bh (&q_vector->lock);WARN_ON (q_vector->state & (IXGBE_QV_STATE_POLL |IXGBE_QV_STATE_NAPI_YIELD ));if (q_vector->state &IXGBE_QV_STATE_POLL_YIELD ) rc = true; - q_vector->state =IXGBE_QV_STATE_IDLE ; -spin_unlock (&q_vector->lock); +/* will reset state to idle, unless QV is disabled */ + q_vector->state &=IXGBE_QV_STATE_DISABLED ; +spin_unlock_bh (&q_vector->lock);return rc; }
@@ -451,7 +454,8 @@ static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector)if (q_vector->state &IXGBE_QV_STATE_POLL_YIELD ) rc = true; - q_vector->state =IXGBE_QV_STATE_IDLE ; +/* will reset state to idle, unless QV is disabled */ + q_vector->state &=IXGBE_QV_STATE_DISABLED ;spin_unlock_bh (&q_vector->lock);return rc; }
@@ -459,9 +463,23 @@ static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector)/* true if a socket is polling, even if it did not get the lock */ static inline bool ixgbe_qv_ll_polling (struct ixgbe_q_vector *q_vector) { -WARN_ON (!(q_vector->state &IXGBE_QV_LOCKED )); +WARN_ON (!(q_vector->state &IXGBE_QV_OWNED ));return q_vector->state &IXGBE_QV_USER_PEND ; } + +/* false if QV is currently owned */ +static inline bool ixgbe_qv_disable (struct ixgbe_q_vector *q_vector) +{ +int rc = true; +spin_lock_bh (&q_vector->lock); +if (q_vector->state &IXGBE_QV_OWNED ) + rc = false; + q_vector->state |=IXGBE_QV_STATE_DISABLED ; +spin_unlock_bh (&q_vector->lock); + +return rc; +} +#else /* CONFIG_NET_RX_BUSY_POLL */ static inline void ixgbe_qv_init_lock (struct ixgbe_q_vector *q_vector) {
@@ -491,6 +509,12 @@ static inline bool ixgbe_qv_ll_polling(struct ixgbe_q_vector *q_vector) {return false; } + +static inline bool ixgbe_qv_disable (struct ixgbe_q_vector *q_vector) +{ +return true; +} +#endif /* CONFIG_NET_RX_BUSY_POLL */ #ifdef CONFIG_IXGBE_HWMON
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +2 -4
@@ -3893,15 +3893,13 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter) {int q_idx; -local_bh_disable ();/* for ixgbe_qv_lock_napi() */ for (q_idx =0 ; q_idx < adapter->num_q_vectors; q_idx++) {napi_disable (&adapter->q_vector[q_idx]->napi); -while (!ixgbe_qv_lock_napi (adapter->q_vector[q_idx])) { +while (!ixgbe_qv_disable (adapter->q_vector[q_idx])) {pr_info ("QV %d locked\n" , q_idx); -mdelay (1 ); +usleep_range (1000 ,20000 ); } } -local_bh_enable (); }#ifdef CONFIG_IXGBE_DCB
Signature · 1 line
2.0.4
Re: [PATCH 3.12 078/104] ixgbe: fix qv_lock_napi call in ixgbe_napi_disable_all
Quoted 3 lines · Jiri Slaby
From: Jacob Keller <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
No objection, I am however unable to test this myself at the moment.
I would suggest that someone takes a look at other drivers that support busypoll, to make sure that they don't have a similar issue.
-Eliezer
Re: [PATCH 3.12 078/104] ixgbe: fix qv_lock_napi call in ixgbe_napi_disable_all
Quoted 11 lines · Eliezer Tamir
Quoted 3 lines · Jiri Slaby
From: Jacob Keller <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
No objection, I am however unable to test this myself at the moment.
I would suggest that someone takes a look at other drivers that support busypoll, to make sure that they don't have a similar issue.
-Eliezer
This was tested and resolved an issue found in the net-next kernel at the time this was made, so I'd say it's had a fair amount of testing :)
Thanks,
Jake
PATCH 79/104 ixgbe: fix inconsistent clearing of the multicast table
In reply to Jiri SlabyFrom: Emil Tantilov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit cf78959c0d7afbde31498afc4212294c28e2c278 upstream.
This patch resolves an issue where the MTA table can be cleared when the interface is reset while in promisc mode. As result IPv6 traffic between VFs will be interrupted.
This patch makes the update of the MTA table unconditional to avoid the inconsistent clearing on reset.
--- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +7 -8
@@ -3825,14 +3825,6 @@ void ixgbe_set_rx_mode(struct net_device *netdev)if (netdev->flags &IFF_ALLMULTI ) { fctrl |=IXGBE_FCTRL_MPE ; vmolr |=IXGBE_VMOLR_MPE ; - }else { -/* -* Write addresses to the MTA, if the attempt fails -* then we should just turn on promiscuous mode so -* that we can at least receive multicast traffic -*/ - hw->mac.ops.update_mc_addr_list (hw, netdev); - vmolr |=IXGBE_VMOLR_ROMPE ; }ixgbe_vlan_filter_enable (adapter); hw->addr_ctrl.user_set_promisc = false;
@@ -3849,6 +3841,13 @@ void ixgbe_set_rx_mode(struct net_device *netdev) vmolr |=IXGBE_VMOLR_ROPE ; } +/* Write addresses to the MTA, if the attempt fails +* then we should just turn on promiscuous mode so +* that we can at least receive multicast traffic +*/ + hw->mac.ops.update_mc_addr_list (hw, netdev); + vmolr |=IXGBE_VMOLR_ROMPE ; +if (adapter->num_vfs)ixgbe_restore_vf_multicasts (adapter);
Signature · 1 line
2.0.4
PATCH 80/104 DMA-API: net: intel/ixgbevf: fix 32-bit DMA mask handling
In reply to Jiri SlabyFrom: Russell King <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 53567aa4e00399aa59339bba81b285a5b95f425c upstream.
The fallback to 32-bit DMA mask is rather odd:
if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
!dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
pci_using_dac = 1;
} else {
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
err = dma_set_coherent_mask(&pdev->dev,
DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "No usable DMA "
"configuration, aborting\n");
goto err_dma;
}
}
pci_using_dac = 0;
}This means we only set the coherent DMA mask in the fallback path if the DMA mask set failed, which is silly. This fixes it to set the coherent DMA mask only if dma_set_mask() succeeded, and to error out if either fails.
--- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +5 -10
@@ -3326,19 +3326,14 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (err)return err; -if (!dma_set_mask (&pdev->dev,DMA_BIT_MASK (64 )) && - !dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (64 ))) { +if (!dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (64 ))) { pci_using_dac =1 ; }else { - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (32 )); + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (32 ));if (err) { - err =dma_set_coherent_mask (&pdev->dev, -DMA_BIT_MASK (32 )); -if (err) { -dev_err (&pdev->dev,"No usable DMA " -"configuration, aborting\n" ); - goto err_dma; - } +dev_err (&pdev->dev,"No usable DMA " +"configuration, aborting\n" ); + goto err_dma; } pci_using_dac =0 ; }
Signature · 1 line
2.0.4
PATCH 81/104 ixgbevf: cleanup redundant mailbox read failure check
In reply to Jiri SlabyFrom: Don Skidmore <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c7bb417dbb8888cfd20824d54f9af9c92b9ff43d upstream.
Since we are already checking for read failure in check_link we don't need to do it here. Instead just make sure the watchdog task gets scheduled, if we are up, and it can be done there. This will better follow igbvf method of handling a mailbox event and message timeout.
--- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 29 ++--------------------- 1 file changed, 2 insertions(+), 27 deletions(-)
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +2 -27
@@ -756,37 +756,12 @@ static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector)static irqreturn_t ixgbevf_msix_other (int irq,void *data) {struct ixgbevf_adapter *adapter = data; -struct pci_dev *pdev = adapter->pdev;struct ixgbe_hw *hw = &adapter->hw; -u32 msg; -bool got_ack = false; hw->mac.get_link_status =1 ; -if (!hw->mbx.ops.check_for_ack (hw)) - got_ack = true; - -if (!hw->mbx.ops.check_for_msg (hw)) { - hw->mbx.ops.read (hw, &msg,1 ); -if ((msg &IXGBE_MBVFICR_VFREQ_MASK ) ==IXGBE_PF_CONTROL_MSG ) { -mod_timer (&adapter->watchdog_timer, -round_jiffies (jiffies +1 )); - adapter->link_up = false; - } - -if (msg &IXGBE_VT_MSGTYPE_NACK ) -dev_info (&pdev->dev, -"Last Request of type %2.2x to PF Nacked\n" , - msg &0xFF ); - hw->mbx.v2p_mailbox |=IXGBE_VFMAILBOX_PFSTS ; - } - -/* checking for the ack clears the PFACK bit. Place -* it back in the v2p_mailbox cache so that anyone -* polling for an ack will not miss it -*/ -if (got_ack) - hw->mbx.v2p_mailbox |=IXGBE_VFMAILBOX_PFACK ; +if (!test_bit (__IXGBEVF_DOWN, &adapter->state)) +mod_timer (&adapter->watchdog_timer, jiffies);IXGBE_WRITE_REG (hw,IXGBE_VTEIMS , adapter->eims_other);
Signature · 1 line
2.0.4
PATCH 82/104 DMA-API: net: intel/igb: fix 32-bit DMA mask handling
In reply to Jiri SlabyFrom: Russell King <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dc4ff9bb7534ebd153f8441ec0e9190964ad8944 upstream.
The fallback to 32-bit DMA mask is rather odd:
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
if (!err) {
err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (!err)
pci_using_dac = 1;
} else {
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
err = dma_set_coherent_mask(&pdev->dev,
DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev,
"No usable DMA configuration, aborting\n");
goto err_dma;
}
}
}This means we only set the coherent DMA mask in the fallback path if the DMA mask set failed, which is silly. This fixes it to set the coherent DMA mask only if dma_set_mask() succeeded, and to error out if either fails.
--- drivers/net/ethernet/intel/igb/igb_main.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-)
drivers/net/ethernet/intel/igb/igb_main.c +6 -12
@@ -2034,21 +2034,15 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)return err; pci_using_dac =0 ; - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (64 )); + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (64 ));if (!err) { - err =dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (64 )); -if (!err) - pci_using_dac =1 ; + pci_using_dac =1 ; }else { - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (32 )); + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (32 ));if (err) { - err =dma_set_coherent_mask (&pdev->dev, -DMA_BIT_MASK (32 )); -if (err) { -dev_err (&pdev->dev, -"No usable DMA configuration, aborting\n" ); - goto err_dma; - } +dev_err (&pdev->dev, +"No usable DMA configuration, aborting\n" ); + goto err_dma; } }
Signature · 1 line
2.0.4
PATCH 83/104 igb: Add ethtool offline tests for i354
In reply to Jiri SlabyFrom: "Fujinaka, Todd" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a4e979a27db3eb77e286dbe484e96c0c9c986e83 upstream.
Add the ethtool offline tests for i354 devices.
--- drivers/net/ethernet/intel/igb/igb_ethtool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igb/igb_ethtool.c +4 -2
@@ -1659,7 +1659,8 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)if ((hw->device_id ==E1000_DEV_ID_DH89XXCC_SGMII ) || (hw->device_id ==E1000_DEV_ID_DH89XXCC_SERDES ) || (hw->device_id ==E1000_DEV_ID_DH89XXCC_BACKPLANE ) || - (hw->device_id ==E1000_DEV_ID_DH89XXCC_SFP )) { + (hw->device_id ==E1000_DEV_ID_DH89XXCC_SFP ) || + (hw->device_id ==E1000_DEV_ID_I354_SGMII )) {/* Enable DH89xxCC MPHY for near end loopback */ reg =rd32 (E1000_MPHY_ADDR_CTL );
@@ -1725,7 +1726,8 @@ static void igb_loopback_cleanup(struct igb_adapter *adapter)if ((hw->device_id ==E1000_DEV_ID_DH89XXCC_SGMII ) || (hw->device_id ==E1000_DEV_ID_DH89XXCC_SERDES ) || (hw->device_id ==E1000_DEV_ID_DH89XXCC_BACKPLANE ) || - (hw->device_id ==E1000_DEV_ID_DH89XXCC_SFP )) { + (hw->device_id ==E1000_DEV_ID_DH89XXCC_SFP ) || + (hw->device_id ==E1000_DEV_ID_I354_SGMII )) {u32 reg;/* Disable near end loopback on DH89xxCC */
Signature · 1 line
2.0.4
PATCH 84/104 igb: Fix master/slave mode for all m88 i354 PHY's
In reply to Jiri SlabyFrom: Carolyn Wyborny <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d1c17d806b6a52ff020322bec457717a91ea50a9 upstream.
This patch calls code to set the master/slave mode for all m88 gen 2 PHY's. This patch also removes the call to this function for I210 devices only from the function that is not called by I210 devices.
--- drivers/net/ethernet/intel/igb/e1000_phy.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/net/ethernet/intel/igb/e1000_phy.c +3 -5
@@ -708,11 +708,6 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)hw_dbg ("Error committing the PHY changes\n" ); goto out; } -if (phy->type == e1000_phy_i210) { - ret_val =igb_set_master_slave_mode (hw); -if (ret_val) -return ret_val; - } out:return ret_val;
@@ -806,6 +801,9 @@ s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)hw_dbg ("Error committing the PHY changes\n" );return ret_val; } + ret_val =igb_set_master_slave_mode (hw); +if (ret_val) +return ret_val;return 0 ; }
Signature · 1 line
2.0.4
PATCH 85/104 igb: fix driver reload with VF assigned to guest
In reply to Jiri SlabyFrom: Stefan Assmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 781798a11e2820ee35fa9142869bb8cec117dedc upstream.
commit fa44f2f185f7f9da19d331929bb1b56c1ccd1d93 broke reloading of igb, when VFs are assigned to a guest, in several ways.
1. on module load adapter->vf_data does not get properly allocated, resulting in a null pointer exception when accessing adapter->vf_data in igb_reset() on module reload.
modprobe -r igb ; modprobe igb max_vfs=7
[ 215.215837] igb 0000:01:00.1: removed PHC on eth1 [ 216.932072] igb 0000:01:00.1: IOV Disabled [ 216.937038] igb 0000:01:00.0: removed PHC on eth0 [ 217.127032] igb 0000:01:00.0: Cannot deallocate SR-IOV virtual functions while they are assigned - VFs will not be deallocated [ 217.146178] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.0.5-k [ 217.154050] igb: Copyright (c) 2007-2013 Intel Corporation. [ 217.160688] igb 0000:01:00.0: Enabling SR-IOV VFs using the module parameter is deprecated - please use the pci sysfs interface. [ 217.173703] igb 0000:01:00.0: irq 103 for MSI/MSI-X [ 217.179227] igb 0000:01:00.0: irq 104 for MSI/MSI-X [ 217.184735] igb 0000:01:00.0: irq 105 for MSI/MSI-X [ 217.220082] BUG: unable to handle kernel NULL pointer dereference at 0000000000000048 [ 217.228846] IP: [<ffffffffa007c5e5>] igb_reset+0xc5/0x4b0 [igb] [ 217.235472] PGD 3607ec067 PUD 36170b067 PMD 0 [ 217.240461] Oops: 0002 [#1] SMP [ 217.244085] Modules linked in: igb(+) igbvf mptsas mptscsih mptbase scsi_transport_sas [last unloaded: igb] [ 217.255040] CPU: 4 PID: 4833 Comm: modprobe Not tainted 3.11.0+ #46 [...] [ 217.390007] [<ffffffffa007fab2>] igb_probe+0x892/0xfd0 [igb] [ 217.396422] [<ffffffff81470b3e>] local_pci_probe+0x1e/0x40 [ 217.402641] [<ffffffff81472029>] pci_device_probe+0xf9/0x110
[...]
2. A follow up issue, pci_enable_sriov() should only be called if no VFs were still allocated on module unload. Otherwise pci_enable_sriov() gets called multiple times in a row rendering the NIC unusable until reset.
3. simply calling igb_enable_sriov() in igb_probe_vfs() is not enough as the interrupts need to be re-setup. Switching that to igb_pci_enable_sriov().
--- drivers/net/ethernet/intel/igb/igb_main.c | 37 +++++++++++++------------------ 1 file changed, 16 insertions(+), 21 deletions(-)
drivers/net/ethernet/intel/igb/igb_main.c +16 -21
@@ -182,6 +182,7 @@ static void igb_check_vf_rate_limit(struct igb_adapter *);#ifdef CONFIG_PCI_IOV static int igb_vf_configure (struct igb_adapter *adapter,int vf); +static int igb_pci_enable_sriov (struct pci_dev *dev,int num_vfs);#endif #ifdef CONFIG_PM
@@ -2423,7 +2424,7 @@ err_dma: }#ifdef CONFIG_PCI_IOV -static int igb_disable_sriov (struct pci_dev *pdev) +static int igb_disable_sriov (struct pci_dev *pdev) {struct net_device *netdev =pci_get_drvdata (pdev);struct igb_adapter *adapter =netdev_priv (netdev);
@@ -2464,27 +2465,19 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs)int err =0 ;int i; -if (!adapter->msix_entries) { +if (!adapter->msix_entries || num_vfs >7 ) { err = -EPERM ; goto out; } -if (!num_vfs) goto out; -else if (old_vfs && old_vfs == num_vfs) - goto out; -else if (old_vfs && old_vfs != num_vfs) - err =igb_disable_sriov (pdev); - -if (err) - goto out; -if (num_vfs >7 ) { - err = -EPERM ; - goto out; - } - - adapter->vfs_allocated_count = num_vfs; +if (old_vfs) { +dev_info (&pdev->dev,"%d pre-allocated VFs found - override max_vfs setting of %d\n" , + old_vfs, max_vfs); + adapter->vfs_allocated_count = old_vfs; + }else + adapter->vfs_allocated_count = num_vfs; adapter->vf_data =kcalloc (adapter->vfs_allocated_count,sizeof (struct vf_data_storage ),GFP_KERNEL );
@@ -2498,10 +2491,12 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs) goto out; } - err =pci_enable_sriov (pdev, adapter->vfs_allocated_count); -if (err) - goto err_out; - +/* only call pci_enable_sriov() if no VFs are allocated already */ +if (!old_vfs) { + err =pci_enable_sriov (pdev, adapter->vfs_allocated_count); +if (err) + goto err_out; + }dev_info (&pdev->dev,"%d VFs allocated\n" , adapter->vfs_allocated_count);for (i =0 ; i < adapter->vfs_allocated_count; i++)
@@ -2617,7 +2612,7 @@ static void igb_probe_vfs(struct igb_adapter *adapter)return ;pci_sriov_set_totalvfs (pdev,7 ); -igb_enable_sriov (pdev, max_vfs); +igb_pci_enable_sriov (pdev, max_vfs);#endif /* CONFIG_PCI_IOV */ }
Signature · 1 line
2.0.4
PATCH 86/104 igb: Don't let ethtool try to write to iNVM in i210/i211
In reply to Jiri SlabyFrom: "Fujinaka, Todd" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a71fc313c4f569be5788caff07ef1fe346842c5b upstream.
Don't let ethtool try to write to iNVM in i210/i211.
This fixes an issue seen by Marek Vasut.
--- drivers/net/ethernet/intel/igb/igb_ethtool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/igb/igb_ethtool.c +3 -1
@@ -771,8 +771,10 @@ static int igb_set_eeprom(struct net_device *netdev,if (eeprom->len ==0 )return -EOPNOTSUPP ; -if (hw->mac.type == e1000_i211) +if ((hw->mac.type >= e1000_i210) && + !igb_get_flash_presence_i210 (hw)) {return -EOPNOTSUPP ; + }if (eeprom->magic != (hw->vendor_id | (hw->device_id <<16 )))return -EFAULT ;
Signature · 1 line
2.0.4
PATCH 87/104 igb: Fixed Wake On LAN support
In reply to Jiri SlabyFrom: Akeem G Abodunrin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 42ce4126d8bc2e128e1f207cf79bb0623fac498f upstream.
This patch fixes Wake on LAN being reported as supported on some Ethernet ports, in contrary to Hardware capability.
--- drivers/net/ethernet/intel/igb/igb_ethtool.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/igb/igb_ethtool.c +4 -3
@@ -2059,14 +2059,15 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) {struct igb_adapter *adapter =netdev_priv (netdev); - wol->supported =WAKE_UCAST |WAKE_MCAST | -WAKE_BCAST |WAKE_MAGIC | -WAKE_PHY ; wol->wolopts =0 ;if (!(adapter->flags &IGB_FLAG_WOL_SUPPORTED ))return ; + wol->supported =WAKE_UCAST |WAKE_MCAST | +WAKE_BCAST |WAKE_MAGIC | +WAKE_PHY ; +/* apply any specific unsupported masks here */ switch (adapter->hw.device_id) {default :
Signature · 1 line
2.0.4
PATCH 88/104 DMA-API: net: intel/igbvf: fix 32-bit DMA mask handling
In reply to Jiri SlabyFrom: Russell King <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c21b8ebc2f1613fd0a9d5aa0d0d1083aee8ca306 upstream.
The fallback to 32-bit DMA mask is rather odd:
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
if (!err) {
err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
if (!err)
pci_using_dac = 1;
} else {
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
err = dma_set_coherent_mask(&pdev->dev,
DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "No usable DMA "
"configuration, aborting\n");
goto err_dma;
}
}
}This means we only set the coherent DMA mask in the fallback path if the DMA mask set failed, which is silly. This fixes it to set the coherent DMA mask only if dma_set_mask() succeeded, and to error out if either fails.
--- drivers/net/ethernet/intel/igbvf/netdev.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-)
drivers/net/ethernet/intel/igbvf/netdev.c +6 -12
@@ -2638,21 +2638,15 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)return err; pci_using_dac =0 ; - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (64 )); + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (64 ));if (!err) { - err =dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (64 )); -if (!err) - pci_using_dac =1 ; + pci_using_dac =1 ; }else { - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (32 )); + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (32 ));if (err) { - err =dma_set_coherent_mask (&pdev->dev, -DMA_BIT_MASK (32 )); -if (err) { -dev_err (&pdev->dev,"No usable DMA " -"configuration, aborting\n" ); - goto err_dma; - } +dev_err (&pdev->dev,"No usable DMA " +"configuration, aborting\n" ); + goto err_dma; } }
Signature · 1 line
2.0.4
PATCH 89/104 igbvf: integer wrapping bug setting the mtu
In reply to Jiri SlabyFrom: Dan Carpenter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3de9e65f011b95235a789b12abc4730570cdb737 upstream.
If new_mtu is very large then "new_mtu + ETH_HLEN + ETH_FCS_LEN" can wrap and the check on the next line can underflow. This is one of those bugs which can be triggered by the user if you have namespaces configured.
Also since this is something the user can trigger then we don't want to have dev_err() message.
This is a static checker fix and I'm not sure what the impact is.
--- drivers/net/ethernet/intel/igbvf/netdev.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/igbvf/netdev.c +2 -3
@@ -2343,10 +2343,9 @@ static int igbvf_change_mtu(struct net_device *netdev, int new_mtu)struct igbvf_adapter *adapter =netdev_priv (netdev);int max_frame = new_mtu +ETH_HLEN +ETH_FCS_LEN ; -if ((new_mtu <68 ) || (max_frame >MAX_JUMBO_FRAME_SIZE )) { -dev_err (&adapter->pdev->dev,"Invalid MTU setting\n" ); +if (new_mtu <68 || new_mtu >INT_MAX -ETH_HLEN -ETH_FCS_LEN || + max_frame >MAX_JUMBO_FRAME_SIZE )return -EINVAL ; - }#define MAX_STD_JUMBO_FRAME_SIZE 9234if (max_frame >MAX_STD_JUMBO_FRAME_SIZE ) {
Signature · 1 line
2.0.4
PATCH 90/104 igbvf: add missing iounmap() on error in igbvf_probe()
In reply to Jiri SlabyFrom: Wei Yongjun <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit de524681f88ff4ed293aa239f83c8cb04d59b47d upstream.
Add the missing iounmap() before return from igbvf_probe() in the error handling case.
--- drivers/net/ethernet/intel/igbvf/netdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/igbvf/netdev.c +2 -1
@@ -2692,7 +2692,7 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (ei->get_variants) { err = ei->get_variants (adapter);if (err) - goto err_ioremap; + goto err_get_variants; }/* setup adapter struct */
@@ -2789,6 +2789,7 @@ err_hw_init:kfree (adapter->rx_ring); err_sw_init:igbvf_reset_interrupt_capability (adapter); +err_get_variants:iounmap (adapter->hw.hw_addr); err_ioremap:free_netdev (netdev);
Signature · 1 line
2.0.4
PATCH 91/104 DMA-API: net: brocade/bna/bnad.c: fix 32-bit DMA mask handling
In reply to Jiri SlabyFrom: Russell King <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3e5480791e3b0e239d2cd4e5ecd43a7d2585484b upstream.
The fallback to 32-bit DMA mask is rather odd:
if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
!dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
*using_dac = true;
} else {
err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
err = dma_set_coherent_mask(&pdev->dev,
DMA_BIT_MASK(32));
if (err)
goto release_regions;
}This means we only try and set the coherent DMA mask if we failed to set a 32-bit DMA mask, and only if both fail do we fail the driver. Adjust this so that if either setting fails, we fail the driver - and thereby end up properly setting both the DMA mask and the coherent DMA mask in the fallback case.
--- drivers/net/ethernet/brocade/bna/bnad.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
drivers/net/ethernet/brocade/bna/bnad.c +4 -9
@@ -3300,17 +3300,12 @@ bnad_pci_init(struct bnad *bnad, err =pci_request_regions (pdev,BNAD_NAME );if (err) goto disable_device; -if (!dma_set_mask (&pdev->dev,DMA_BIT_MASK (64 )) && - !dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (64 ))) { +if (!dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (64 ))) { *using_dac = true; }else { - err =dma_set_mask (&pdev->dev,DMA_BIT_MASK (32 )); -if (err) { - err =dma_set_coherent_mask (&pdev->dev, -DMA_BIT_MASK (32 )); -if (err) - goto release_regions; - } + err =dma_set_mask_and_coherent (&pdev->dev,DMA_BIT_MASK (32 )); +if (err) + goto release_regions; *using_dac = false; }pci_set_master (pdev);
Signature · 1 line
2.0.4
PATCH 92/104 netxen: Correct off-by-one errors in bounds checks
In reply to Jiri SlabyFrom: David Gibson <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4710b2ba873692194c636811ceda398f95e02db2 upstream.
netxen_process_lro() contains two bounds checks. One for the ring number against the number of rings, and one for the Rx buffer ID against the array of receive buffers.
Both of these have off-by-one errors, using > instead of >=. The correct versions are used in netxen_process_rcv(), they're just wrong in netxen_process_lro().
--- drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +2 -2
@@ -1604,13 +1604,13 @@ netxen_process_lro(struct netxen_adapter *adapter,u32 seq_number;u8 vhdr_len =0 ; -if (unlikely (ring > adapter->max_rds_rings)) +if (unlikely (ring >= adapter->max_rds_rings))return NULL ; rds_ring = &recv_ctx->rds_rings[ring]; index =netxen_get_lro_sts_refhandle (sts_data0); -if (unlikely (index > rds_ring->num_desc)) +if (unlikely (index >= rds_ring->num_desc))return NULL ; buffer = &rds_ring->rx_buf_arr[index];
Signature · 1 line
2.0.4
PATCH 93/104 RDMA/cxgb3: Fix information leak in send_abort()
In reply to Jiri SlabyFrom: Dan Carpenter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e4514cbd972786af67dd6c442c072685387e22a2 upstream.
The cpl_abort_req struct has several reserved members which need to be cleared to avoid disclosing kernel information. I have added a memset() so now it matches the cxgb4 version of this function.
--- drivers/infiniband/hw/cxgb3/iwch_cm.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/hw/cxgb3/iwch_cm.c +1 -0
@@ -418,6 +418,7 @@ static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp) skb->priority =CPL_PRIORITY_DATA ;set_arp_failure_handler (skb, abort_arp_failure); req = (struct cpl_abort_req *)skb_put (skb,sizeof (*req)); +memset (req,0 ,sizeof (*req)); req->wr.wr_hi =htonl (V_WR_OP (FW_WROPCODE_OFLD_HOST_ABORT_CON_REQ )); req->wr.wr_lo =htonl (V_WR_TID (ep->hwtid));OPCODE_TID (req) =htonl (MK_OPCODE_TID (CPL_ABORT_REQ , ep->hwtid));
Signature · 1 line
2.0.4
PATCH 94/104 bnx2x: Test nvram when interface is down
In reply to Jiri SlabyFrom: Yuval Mintz <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit bd8e012b5d369933f50842294372ed580f5d9605 upstream.
Since commit 3fb43eb ("bnx2x: Change to D3hot only on removal") nvram is accessible whenever the driver is loaded - Thus it is possible to test it during self-test even if the interface is down
--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +10 -9
@@ -2864,9 +2864,16 @@ static void bnx2x_self_test(struct net_device *dev,memset (buf,0 ,sizeof (u64) *BNX2X_NUM_TESTS (bp)); +if (bnx2x_test_nvram (bp) !=0 ) { +if (!IS_MF (bp)) + buf[4 ] =1 ; +else + buf[0 ] =1 ; + etest->flags |=ETH_TEST_FL_FAILED ; + } +if (!netif_running (dev)) { -DP (BNX2X_MSG_ETHTOOL , -"Can't perform self-test when interface is down\n" ); +DP (BNX2X_MSG_ETHTOOL ,"Interface is down\n" );return ; }
@@ -2928,13 +2935,7 @@ static void bnx2x_self_test(struct net_device *dev,/* wait until link state is restored */ bnx2x_wait_for_link (bp, link_up, is_serdes); } -if (bnx2x_test_nvram (bp) !=0 ) { -if (!IS_MF (bp)) - buf[4 ] =1 ; -else - buf[0 ] =1 ; - etest->flags |=ETH_TEST_FL_FAILED ; - } +if (bnx2x_test_intr (bp) !=0 ) {if (!IS_MF (bp)) buf[5 ] =1 ;
Signature · 1 line
2.0.4
PATCH 95/104 bnx2fc: fix memory leak in bnx2fc_allocate_hash_table()
In reply to Jiri SlabyFrom: Maurizio Lombardi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit fdbcbcab0eae6773430546697ace0b3fe48e7fbc upstream.
In case of error, the bnx2fc_allocate_hash_table() didn't free all the memory it allocated.
--- drivers/scsi/bnx2fc/bnx2fc_hwi.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
drivers/scsi/bnx2fc/bnx2fc_hwi.c +19 -12
@@ -2023,7 +2023,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba) dma_segment_array =kzalloc (dma_segment_array_size,GFP_KERNEL );if (!dma_segment_array) { printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n"); -return -ENOMEM ; + goto cleanup_ht; }for (i =0 ; i < segment_count; ++i) {
@@ -2034,15 +2034,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba) GFP_KERNEL);if (!hba->hash_tbl_segments[i]) { printk(KERN_ERR PFX "hash segment alloc failed\n"); -while (--i >=0 ) { -dma_free_coherent (&hba->pcidev->dev, -BNX2FC_HASH_TBL_CHUNK_SIZE , - hba->hash_tbl_segments[i], - dma_segment_array[i]); - hba->hash_tbl_segments[i] =NULL ; - } -kfree (dma_segment_array); -return -ENOMEM ; + goto cleanup_dma; }memset (hba->hash_tbl_segments[i],0 ,BNX2FC_HASH_TBL_CHUNK_SIZE );
@@ -2054,8 +2046,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba) GFP_KERNEL);if (!hba->hash_tbl_pbl) { printk(KERN_ERR PFX "hash table pbl alloc failed\n"); -kfree (dma_segment_array); -return -ENOMEM ; + goto cleanup_dma; }memset (hba->hash_tbl_pbl,0 ,PAGE_SIZE );
@@ -2080,6 +2071,22 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba) }kfree (dma_segment_array);return 0 ; + +cleanup_dma: +for (i =0 ; i < segment_count; ++i) { +if (hba->hash_tbl_segments[i]) +dma_free_coherent (&hba->pcidev->dev, +BNX2FC_HASH_TBL_CHUNK_SIZE , + hba->hash_tbl_segments[i], + dma_segment_array[i]); + } + +kfree (dma_segment_array); + +cleanup_ht: +kfree (hba->hash_tbl_segments); + hba->hash_tbl_segments =NULL ; +return -ENOMEM ; }/**
Signature · 1 line
2.0.4
PATCH 96/104 tg3: Add support for new 577xx device ids
In reply to Jiri SlabyFrom: Nithin Sujir <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 68273712a19e9107a498a371532b3b3eb6dbb14c upstream.
This patch adds support for 57764, 57765, 57787, 57782 and 57786 devices.
--- drivers/net/ethernet/broadcom/tg3.c | 15 +++++++++++++-- drivers/net/ethernet/broadcom/tg3.h | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +13 -2
@@ -337,6 +337,11 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5762)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5725)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5727)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57764)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57767)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57787)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57782)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57786)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -15760,9 +15765,12 @@ static void tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg) tp->pdev->device ==TG3PCI_DEVICE_TIGON3_5718 || tp->pdev->device ==TG3PCI_DEVICE_TIGON3_5719 || tp->pdev->device ==TG3PCI_DEVICE_TIGON3_5720 || + tp->pdev->device ==TG3PCI_DEVICE_TIGON3_57767 || + tp->pdev->device ==TG3PCI_DEVICE_TIGON3_57764 || tp->pdev->device ==TG3PCI_DEVICE_TIGON3_5762 || tp->pdev->device ==TG3PCI_DEVICE_TIGON3_5725 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) + tp->pdev->device ==TG3PCI_DEVICE_TIGON3_5727 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) reg = TG3PCI_GEN2_PRODID_ASICREV; else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
@@ -17413,9 +17421,12 @@ static int tg3_init_one(struct pci_dev *pdev, tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57767 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57764 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5762 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727) { + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5727 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57787) {tg3_flag_set (tp,ENABLE_APE ); tp->aperegs =pci_ioremap_bar (pdev,BAR_2 );if (!tp->aperegs) {
drivers/net/ethernet/broadcom/tg3.h +3 -0
@@ -68,6 +68,9 @@#define TG3PCI_DEVICE_TIGON3_5762 0x1687#define TG3PCI_DEVICE_TIGON3_5725 0x1643#define TG3PCI_DEVICE_TIGON3_5727 0x16f3 +#define TG3PCI_DEVICE_TIGON3_57764 0x1642 +#define TG3PCI_DEVICE_TIGON3_57767 0x1683 +#define TG3PCI_DEVICE_TIGON3_57787 0x1641/* 0x04 --> 0x2c unused */ #define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM#define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644
Signature · 1 line
2.0.4
PATCH 97/104 tipc: don't use memcpy to copy from user space
In reply to Jiri SlabyFrom: Ying Xue <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5c0a0fc81f4dc786b42c4fc9c7c72ba635406ab5 upstream.
tipc_msg_build() calls skb_copy_to_linear_data_offset() to copy data from user space to kernel space. However, the latter function does in its turn call memcpy() to perform the actual copying. This poses an obvious security and robustness risk, since memcpy() never makes any validity check on the pointer it is copying from.
To correct this, we the replace the offending function call with a call to memcpy_fromiovecend(), which uses copy_from_user() to perform the copying.
--- net/tipc/msg.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
net/tipc/msg.c +9 -13
@@ -76,10 +76,11 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, unsigned int total_len, int max_size, struct sk_buff **buf) { - int dsz, sz, hsz, pos, res, cnt; + int dsz, sz, hsz; +unsigned char *to; dsz = total_len; - pos = hsz =msg_hdr_sz (hdr); + hsz =msg_hdr_sz (hdr); sz = hsz + dsz;msg_set_size (hdr, sz);if (unlikely (sz > max_size)) {
@@ -91,16 +92,11 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,if (!(*buf))return -ENOMEM ;skb_copy_to_linear_data (*buf, hdr, hsz); -for (res =1 , cnt =0 ; res && (cnt < num_sect); cnt++) { -skb_copy_to_linear_data_offset (*buf, pos, - msg_sect[cnt].iov_base, - msg_sect[cnt].iov_len); - pos += msg_sect[cnt].iov_len; + to = (*buf)->data + hsz; +if (total_len &&memcpy_fromiovecend (to, msg_sect,0 , dsz)) { +kfree_skb (*buf); + *buf =NULL ; +return -EFAULT ; } -if (likely (res)) -return dsz; - -kfree_skb (*buf); - *buf =NULL ; -return -EFAULT ; +return dsz; }
Signature · 1 line
2.0.4
PATCH 98/104 PCI: rphahp: Fix endianess issues
In reply to Jiri SlabyFrom: Laurent Dufour <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 761ce53330a4f02c58768631027d1c1dd0d538f7 upstream.
Numerical values stored in the device tree are encoded in Big Endian and should be byte swapped when running in Little Endian.
The RPA hotplug module should convert those values as well.
Note that in rpaphp_get_drc_props(), the comparison between indexes[i+1] and *index is done using the BE values (whatever is the current endianess). This doesn't matter since we are checking for equality here. This way only the returned value is byte swapped.
RPA also made RTAS calls which implies BE values to be used. According to the patch done in RTAS (http://patchwork.ozlabs.org/patch/336865), no additional conversion is required in RPA.
--- drivers/pci/hotplug/rpaphp_core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/pci/hotplug/rpaphp_core.c +9 -6
@@ -223,16 +223,16 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, type_tmp = (char *) &types[1 ];/* Iterate through parent properties, looking for my-drc-index */ -for (i =0 ; i < indexes[0 ]; i++) { +for (i =0 ; i <be32_to_cpu (indexes[0 ]); i++) {if ((unsigned int ) indexes[i +1 ] == *my_index) {if (drc_name) *drc_name = name_tmp;if (drc_type) *drc_type = type_tmp;if (drc_index) - *drc_index = *my_index; + *drc_index =be32_to_cpu (*my_index);if (drc_power_domain) - *drc_power_domain = domains[i+1 ]; + *drc_power_domain =be32_to_cpu (domains[i+1 ]);return 0 ; } name_tmp += (strlen (name_tmp) +1 );
@@ -321,16 +321,19 @@ int rpaphp_add_slot(struct device_node *dn)/* register PCI devices */ name = (char *) &names[1 ]; type = (char *) &types[1 ]; -for (i =0 ; i < indexes[0 ]; i++) { +for (i =0 ; i <be32_to_cpu (indexes[0 ]); i++) { +int index; - slot =alloc_slot_struct (dn, indexes[i +1 ], name, power_domains[i +1 ]); + index =be32_to_cpu (indexes[i +1 ]); + slot =alloc_slot_struct (dn, index, name, +be32_to_cpu (power_domains[i +1 ]));if (!slot)return -ENOMEM ; slot->type =simple_strtoul (type,NULL ,10 );dbg ("Found drc-index:0x%x drc-name:%s drc-type:%s\n" , - indexes[i +1 ], name, type); + index, name, type); retval =rpaphp_enable_slot (slot);if (!retval)
Signature · 1 line
2.0.4
PATCH 99/104 Input: i8042 - add Acer Aspire 5710 to nomux blacklist
In reply to Jiri SlabyFrom: Jiri Kosina <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8c947e20cb1f442c704852b2ca24b81981b09493 upstream.
Acer Aspire needs to be added to nomux blacklist, otherwise the touchpad misbehaves rather randomly.
--- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-x86ia64io.h +7 -0
@@ -402,6 +402,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { }, }, { +/* Acer Aspire 5710 */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Acer" ), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"), + }, + }, + {/* Gericom Bellagio */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
Signature · 1 line
2.0.4
PATCH 100/104 HID: logitech-dj: Fix USB 3.0 issue
In reply to Jiri SlabyFrom: Benjamin Tisssoires <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 42c22dbf81ebd1146960875ddfe71630cb2b3ae6 upstream.
This fix (not very clean though) should fix the long time USB3 issue that was spotted last year. The rational has been given by Hans de Goede:
----
I think the most likely cause for this is a firmware bug in the unifying receiver, likely a race condition.
The most prominent difference between having a USB-2 device plugged into an EHCI (so USB-2 only) port versus an XHCI port will be inter packet timing. Specifically if you send packets (ie hid reports) one at a time, then with the EHCI controller their will be a significant pause between them, where with XHCI they will be very close together in time.
The reason for this is the difference in EHCI / XHCI controller OS <-> driver interfaces.
For non periodic endpoints (control, bulk) the EHCI uses a circular linked-list of commands in dma-memory, which it follows to execute commands, if the list is empty, it will go into an idle state and re-check periodically.
The XHCI uses a ring of commands per endpoint, and if the OS places anything new on the ring it will do an ioport write, waking up the XHCI making it send the new packet immediately.
For periodic transfers (isoc, interrupt) the delay between packets when sending one at a time (rather then queuing them up) will be even larger, because they need to be inserted into the EHCI schedule 2 ms in the future so the OS driver can be sure that the EHCI driver does not try to start executing the time slot in question before the insertion has completed.
So a possible fix may be to insert a delay between packets being send to the receiver.
----
I tested this on a buggy Haswell USB 3.0 motherboard, and I always get the notification after adding the msleep.
--- drivers/hid/hid-logitech-dj.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/hid/hid-logitech-dj.c +8 -0
@@ -516,6 +516,14 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS ] = (u8 )timeout; retval =logi_dj_recv_send_report (djrcv_dev, dj_report);kfree (dj_report); + +/* +* Ugly sleep to work around a USB 3.0 bug when the receiver is still +* processing the "switch-to-dj" command while we send an other command. +* 50 msec should gives enough time to the receiver to be ready. +*/ +msleep (50 ); +return retval; }
Signature · 1 line
2.0.4
PATCH 101/104 ALSA: hda - load EQ params into IDT codec on HP bNB13 systems
In reply to Jiri SlabyFrom: Vitaliy Kulikov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d009f3deb788f7d06fe04c52eaf812b657a0ca68 upstream.
Adds linear EQ filtering for integrated speaker protection
--- sound/pci/hda/patch_sigmatel.c | 532 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 531 insertions(+), 1 deletion(-)
sound/pci/hda/patch_sigmatel.c +531 -1
@@ -102,6 +102,7 @@ enum {STAC_92HD83XXX_HEADSET_JACK ,STAC_92HD83XXX_HP ,STAC_HP_ENVY_BASS , +STAC_HP_BNB13_EQ , STAC_92HD83XXX_MODELS };
@@ -2136,6 +2137,434 @@ static void stac92hd83xxx_fixup_headset_jack(struct hda_codec *codec, spec->headset_jack =1 ; } +static const struct hda_verb hp_bnb13_eq_verbs[] = { +/* 44.1KHz base */ + {0x22 ,0x7A6 ,0x3E }, + {0x22 ,0x7A7 ,0x68 }, + {0x22 ,0x7A8 ,0x17 }, + {0x22 ,0x7A9 ,0x3E }, + {0x22 ,0x7AA ,0x68 }, + {0x22 ,0x7AB ,0x17 }, + {0x22 ,0x7AC ,0x00 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x83 }, + {0x22 ,0x7A7 ,0x2F }, + {0x22 ,0x7A8 ,0xD1 }, + {0x22 ,0x7A9 ,0x83 }, + {0x22 ,0x7AA ,0x2F }, + {0x22 ,0x7AB ,0xD1 }, + {0x22 ,0x7AC ,0x01 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3E }, + {0x22 ,0x7A7 ,0x68 }, + {0x22 ,0x7A8 ,0x17 }, + {0x22 ,0x7A9 ,0x3E }, + {0x22 ,0x7AA ,0x68 }, + {0x22 ,0x7AB ,0x17 }, + {0x22 ,0x7AC ,0x02 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x7C }, + {0x22 ,0x7A7 ,0xC6 }, + {0x22 ,0x7A8 ,0x0C }, + {0x22 ,0x7A9 ,0x7C }, + {0x22 ,0x7AA ,0xC6 }, + {0x22 ,0x7AB ,0x0C }, + {0x22 ,0x7AC ,0x03 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xC3 }, + {0x22 ,0x7A7 ,0x25 }, + {0x22 ,0x7A8 ,0xAF }, + {0x22 ,0x7A9 ,0xC3 }, + {0x22 ,0x7AA ,0x25 }, + {0x22 ,0x7AB ,0xAF }, + {0x22 ,0x7AC ,0x04 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3E }, + {0x22 ,0x7A7 ,0x85 }, + {0x22 ,0x7A8 ,0x73 }, + {0x22 ,0x7A9 ,0x3E }, + {0x22 ,0x7AA ,0x85 }, + {0x22 ,0x7AB ,0x73 }, + {0x22 ,0x7AC ,0x05 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x85 }, + {0x22 ,0x7A7 ,0x39 }, + {0x22 ,0x7A8 ,0xC7 }, + {0x22 ,0x7A9 ,0x85 }, + {0x22 ,0x7AA ,0x39 }, + {0x22 ,0x7AB ,0xC7 }, + {0x22 ,0x7AC ,0x06 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3C }, + {0x22 ,0x7A7 ,0x90 }, + {0x22 ,0x7A8 ,0xB0 }, + {0x22 ,0x7A9 ,0x3C }, + {0x22 ,0x7AA ,0x90 }, + {0x22 ,0x7AB ,0xB0 }, + {0x22 ,0x7AC ,0x07 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x7A }, + {0x22 ,0x7A7 ,0xC6 }, + {0x22 ,0x7A8 ,0x39 }, + {0x22 ,0x7A9 ,0x7A }, + {0x22 ,0x7AA ,0xC6 }, + {0x22 ,0x7AB ,0x39 }, + {0x22 ,0x7AC ,0x08 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xC4 }, + {0x22 ,0x7A7 ,0xE9 }, + {0x22 ,0x7A8 ,0xDC }, + {0x22 ,0x7A9 ,0xC4 }, + {0x22 ,0x7AA ,0xE9 }, + {0x22 ,0x7AB ,0xDC }, + {0x22 ,0x7AC ,0x09 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3D }, + {0x22 ,0x7A7 ,0xE1 }, + {0x22 ,0x7A8 ,0x0D }, + {0x22 ,0x7A9 ,0x3D }, + {0x22 ,0x7AA ,0xE1 }, + {0x22 ,0x7AB ,0x0D }, + {0x22 ,0x7AC ,0x0A }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x89 }, + {0x22 ,0x7A7 ,0xB6 }, + {0x22 ,0x7A8 ,0xEB }, + {0x22 ,0x7A9 ,0x89 }, + {0x22 ,0x7AA ,0xB6 }, + {0x22 ,0x7AB ,0xEB }, + {0x22 ,0x7AC ,0x0B }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x39 }, + {0x22 ,0x7A7 ,0x9D }, + {0x22 ,0x7A8 ,0xFE }, + {0x22 ,0x7A9 ,0x39 }, + {0x22 ,0x7AA ,0x9D }, + {0x22 ,0x7AB ,0xFE }, + {0x22 ,0x7AC ,0x0C }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x76 }, + {0x22 ,0x7A7 ,0x49 }, + {0x22 ,0x7A8 ,0x15 }, + {0x22 ,0x7A9 ,0x76 }, + {0x22 ,0x7AA ,0x49 }, + {0x22 ,0x7AB ,0x15 }, + {0x22 ,0x7AC ,0x0D }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xC8 }, + {0x22 ,0x7A7 ,0x80 }, + {0x22 ,0x7A8 ,0xF5 }, + {0x22 ,0x7A9 ,0xC8 }, + {0x22 ,0x7AA ,0x80 }, + {0x22 ,0x7AB ,0xF5 }, + {0x22 ,0x7AC ,0x0E }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x40 }, + {0x22 ,0x7A7 ,0x00 }, + {0x22 ,0x7A8 ,0x00 }, + {0x22 ,0x7A9 ,0x40 }, + {0x22 ,0x7AA ,0x00 }, + {0x22 ,0x7AB ,0x00 }, + {0x22 ,0x7AC ,0x0F }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x90 }, + {0x22 ,0x7A7 ,0x68 }, + {0x22 ,0x7A8 ,0xF1 }, + {0x22 ,0x7A9 ,0x90 }, + {0x22 ,0x7AA ,0x68 }, + {0x22 ,0x7AB ,0xF1 }, + {0x22 ,0x7AC ,0x10 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x34 }, + {0x22 ,0x7A7 ,0x47 }, + {0x22 ,0x7A8 ,0x6C }, + {0x22 ,0x7A9 ,0x34 }, + {0x22 ,0x7AA ,0x47 }, + {0x22 ,0x7AB ,0x6C }, + {0x22 ,0x7AC ,0x11 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x6F }, + {0x22 ,0x7A7 ,0x97 }, + {0x22 ,0x7A8 ,0x0F }, + {0x22 ,0x7A9 ,0x6F }, + {0x22 ,0x7AA ,0x97 }, + {0x22 ,0x7AB ,0x0F }, + {0x22 ,0x7AC ,0x12 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xCB }, + {0x22 ,0x7A7 ,0xB8 }, + {0x22 ,0x7A8 ,0x94 }, + {0x22 ,0x7A9 ,0xCB }, + {0x22 ,0x7AA ,0xB8 }, + {0x22 ,0x7AB ,0x94 }, + {0x22 ,0x7AC ,0x13 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x40 }, + {0x22 ,0x7A7 ,0x00 }, + {0x22 ,0x7A8 ,0x00 }, + {0x22 ,0x7A9 ,0x40 }, + {0x22 ,0x7AA ,0x00 }, + {0x22 ,0x7AB ,0x00 }, + {0x22 ,0x7AC ,0x14 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x95 }, + {0x22 ,0x7A7 ,0x76 }, + {0x22 ,0x7A8 ,0x5B }, + {0x22 ,0x7A9 ,0x95 }, + {0x22 ,0x7AA ,0x76 }, + {0x22 ,0x7AB ,0x5B }, + {0x22 ,0x7AC ,0x15 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x31 }, + {0x22 ,0x7A7 ,0xAC }, + {0x22 ,0x7A8 ,0x31 }, + {0x22 ,0x7A9 ,0x31 }, + {0x22 ,0x7AA ,0xAC }, + {0x22 ,0x7AB ,0x31 }, + {0x22 ,0x7AC ,0x16 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x6A }, + {0x22 ,0x7A7 ,0x89 }, + {0x22 ,0x7A8 ,0xA5 }, + {0x22 ,0x7A9 ,0x6A }, + {0x22 ,0x7AA ,0x89 }, + {0x22 ,0x7AB ,0xA5 }, + {0x22 ,0x7AC ,0x17 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xCE }, + {0x22 ,0x7A7 ,0x53 }, + {0x22 ,0x7A8 ,0xCF }, + {0x22 ,0x7A9 ,0xCE }, + {0x22 ,0x7AA ,0x53 }, + {0x22 ,0x7AB ,0xCF }, + {0x22 ,0x7AC ,0x18 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x40 }, + {0x22 ,0x7A7 ,0x00 }, + {0x22 ,0x7A8 ,0x00 }, + {0x22 ,0x7A9 ,0x40 }, + {0x22 ,0x7AA ,0x00 }, + {0x22 ,0x7AB ,0x00 }, + {0x22 ,0x7AC ,0x19 }, + {0x22 ,0x7AD ,0x80 }, +/* 48KHz base */ + {0x22 ,0x7A6 ,0x3E }, + {0x22 ,0x7A7 ,0x88 }, + {0x22 ,0x7A8 ,0xDC }, + {0x22 ,0x7A9 ,0x3E }, + {0x22 ,0x7AA ,0x88 }, + {0x22 ,0x7AB ,0xDC }, + {0x22 ,0x7AC ,0x1A }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x82 }, + {0x22 ,0x7A7 ,0xEE }, + {0x22 ,0x7A8 ,0x46 }, + {0x22 ,0x7A9 ,0x82 }, + {0x22 ,0x7AA ,0xEE }, + {0x22 ,0x7AB ,0x46 }, + {0x22 ,0x7AC ,0x1B }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3E }, + {0x22 ,0x7A7 ,0x88 }, + {0x22 ,0x7A8 ,0xDC }, + {0x22 ,0x7A9 ,0x3E }, + {0x22 ,0x7AA ,0x88 }, + {0x22 ,0x7AB ,0xDC }, + {0x22 ,0x7AC ,0x1C }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x7D }, + {0x22 ,0x7A7 ,0x09 }, + {0x22 ,0x7A8 ,0x28 }, + {0x22 ,0x7A9 ,0x7D }, + {0x22 ,0x7AA ,0x09 }, + {0x22 ,0x7AB ,0x28 }, + {0x22 ,0x7AC ,0x1D }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xC2 }, + {0x22 ,0x7A7 ,0xE5 }, + {0x22 ,0x7A8 ,0xB4 }, + {0x22 ,0x7A9 ,0xC2 }, + {0x22 ,0x7AA ,0xE5 }, + {0x22 ,0x7AB ,0xB4 }, + {0x22 ,0x7AC ,0x1E }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3E }, + {0x22 ,0x7A7 ,0xA3 }, + {0x22 ,0x7A8 ,0x1F }, + {0x22 ,0x7A9 ,0x3E }, + {0x22 ,0x7AA ,0xA3 }, + {0x22 ,0x7AB ,0x1F }, + {0x22 ,0x7AC ,0x1F }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x84 }, + {0x22 ,0x7A7 ,0xCA }, + {0x22 ,0x7A8 ,0xF1 }, + {0x22 ,0x7A9 ,0x84 }, + {0x22 ,0x7AA ,0xCA }, + {0x22 ,0x7AB ,0xF1 }, + {0x22 ,0x7AC ,0x20 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3C }, + {0x22 ,0x7A7 ,0xD5 }, + {0x22 ,0x7A8 ,0x9C }, + {0x22 ,0x7A9 ,0x3C }, + {0x22 ,0x7AA ,0xD5 }, + {0x22 ,0x7AB ,0x9C }, + {0x22 ,0x7AC ,0x21 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x7B }, + {0x22 ,0x7A7 ,0x35 }, + {0x22 ,0x7A8 ,0x0F }, + {0x22 ,0x7A9 ,0x7B }, + {0x22 ,0x7AA ,0x35 }, + {0x22 ,0x7AB ,0x0F }, + {0x22 ,0x7AC ,0x22 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xC4 }, + {0x22 ,0x7A7 ,0x87 }, + {0x22 ,0x7A8 ,0x45 }, + {0x22 ,0x7A9 ,0xC4 }, + {0x22 ,0x7AA ,0x87 }, + {0x22 ,0x7AB ,0x45 }, + {0x22 ,0x7AC ,0x23 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3E }, + {0x22 ,0x7A7 ,0x0A }, + {0x22 ,0x7A8 ,0x78 }, + {0x22 ,0x7A9 ,0x3E }, + {0x22 ,0x7AA ,0x0A }, + {0x22 ,0x7AB ,0x78 }, + {0x22 ,0x7AC ,0x24 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x88 }, + {0x22 ,0x7A7 ,0xE2 }, + {0x22 ,0x7A8 ,0x05 }, + {0x22 ,0x7A9 ,0x88 }, + {0x22 ,0x7AA ,0xE2 }, + {0x22 ,0x7AB ,0x05 }, + {0x22 ,0x7AC ,0x25 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x3A }, + {0x22 ,0x7A7 ,0x1A }, + {0x22 ,0x7A8 ,0xA3 }, + {0x22 ,0x7A9 ,0x3A }, + {0x22 ,0x7AA ,0x1A }, + {0x22 ,0x7AB ,0xA3 }, + {0x22 ,0x7AC ,0x26 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x77 }, + {0x22 ,0x7A7 ,0x1D }, + {0x22 ,0x7A8 ,0xFB }, + {0x22 ,0x7A9 ,0x77 }, + {0x22 ,0x7AA ,0x1D }, + {0x22 ,0x7AB ,0xFB }, + {0x22 ,0x7AC ,0x27 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xC7 }, + {0x22 ,0x7A7 ,0xDA }, + {0x22 ,0x7A8 ,0xE5 }, + {0x22 ,0x7A9 ,0xC7 }, + {0x22 ,0x7AA ,0xDA }, + {0x22 ,0x7AB ,0xE5 }, + {0x22 ,0x7AC ,0x28 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x40 }, + {0x22 ,0x7A7 ,0x00 }, + {0x22 ,0x7A8 ,0x00 }, + {0x22 ,0x7A9 ,0x40 }, + {0x22 ,0x7AA ,0x00 }, + {0x22 ,0x7AB ,0x00 }, + {0x22 ,0x7AC ,0x29 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x8E }, + {0x22 ,0x7A7 ,0xD7 }, + {0x22 ,0x7A8 ,0x22 }, + {0x22 ,0x7A9 ,0x8E }, + {0x22 ,0x7AA ,0xD7 }, + {0x22 ,0x7AB ,0x22 }, + {0x22 ,0x7AC ,0x2A }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x35 }, + {0x22 ,0x7A7 ,0x26 }, + {0x22 ,0x7A8 ,0xC6 }, + {0x22 ,0x7A9 ,0x35 }, + {0x22 ,0x7AA ,0x26 }, + {0x22 ,0x7AB ,0xC6 }, + {0x22 ,0x7AC ,0x2B }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x71 }, + {0x22 ,0x7A7 ,0x28 }, + {0x22 ,0x7A8 ,0xDE }, + {0x22 ,0x7A9 ,0x71 }, + {0x22 ,0x7AA ,0x28 }, + {0x22 ,0x7AB ,0xDE }, + {0x22 ,0x7AC ,0x2C }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xCA }, + {0x22 ,0x7A7 ,0xD9 }, + {0x22 ,0x7A8 ,0x3A }, + {0x22 ,0x7A9 ,0xCA }, + {0x22 ,0x7AA ,0xD9 }, + {0x22 ,0x7AB ,0x3A }, + {0x22 ,0x7AC ,0x2D }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x40 }, + {0x22 ,0x7A7 ,0x00 }, + {0x22 ,0x7A8 ,0x00 }, + {0x22 ,0x7A9 ,0x40 }, + {0x22 ,0x7AA ,0x00 }, + {0x22 ,0x7AB ,0x00 }, + {0x22 ,0x7AC ,0x2E }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x93 }, + {0x22 ,0x7A7 ,0x5E }, + {0x22 ,0x7A8 ,0xD8 }, + {0x22 ,0x7A9 ,0x93 }, + {0x22 ,0x7AA ,0x5E }, + {0x22 ,0x7AB ,0xD8 }, + {0x22 ,0x7AC ,0x2F }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x32 }, + {0x22 ,0x7A7 ,0xB7 }, + {0x22 ,0x7A8 ,0xB1 }, + {0x22 ,0x7A9 ,0x32 }, + {0x22 ,0x7AA ,0xB7 }, + {0x22 ,0x7AB ,0xB1 }, + {0x22 ,0x7AC ,0x30 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x6C }, + {0x22 ,0x7A7 ,0xA1 }, + {0x22 ,0x7A8 ,0x28 }, + {0x22 ,0x7A9 ,0x6C }, + {0x22 ,0x7AA ,0xA1 }, + {0x22 ,0x7AB ,0x28 }, + {0x22 ,0x7AC ,0x31 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0xCD }, + {0x22 ,0x7A7 ,0x48 }, + {0x22 ,0x7A8 ,0x4F }, + {0x22 ,0x7A9 ,0xCD }, + {0x22 ,0x7AA ,0x48 }, + {0x22 ,0x7AB ,0x4F }, + {0x22 ,0x7AC ,0x32 }, + {0x22 ,0x7AD ,0x80 }, + {0x22 ,0x7A6 ,0x40 }, + {0x22 ,0x7A7 ,0x00 }, + {0x22 ,0x7A8 ,0x00 }, + {0x22 ,0x7A9 ,0x40 }, + {0x22 ,0x7AA ,0x00 }, + {0x22 ,0x7AB ,0x00 }, + {0x22 ,0x7AC ,0x33 }, + {0x22 ,0x7AD ,0x80 }, +/* common */ + {0x22 ,0x782 ,0xC1 }, + {0x22 ,0x771 ,0x2C }, + {0x22 ,0x772 ,0x2C }, + {0x22 ,0x788 ,0x04 }, + {0x01 ,0x7B0 ,0x08 }, + {} +}; +static const struct hda_fixup stac92hd83xxx_fixups[] = { [STAC_92HD83XXX_REF ] = { .type =HDA_FIXUP_PINS ,
@@ -2210,6 +2639,12 @@ static const struct hda_fixup stac92hd83xxx_fixups[] = { {} }, }, + [STAC_HP_BNB13_EQ ] = { + .type =HDA_FIXUP_VERBS , + .v.verbs = hp_bnb13_eq_verbs, + .chained = true, + .chain_id =STAC_92HD83XXX_HP_MIC_LED , + }, };static const struct hda_model_fixup stac92hd83xxx_models[] = {
@@ -2225,6 +2660,7 @@ static const struct hda_model_fixup stac92hd83xxx_models[] = { { .id = STAC_92HD83XXX_HP_MIC_LED, .name = "hp-mic-led" }, { .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" }, { .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" }, + { .id = STAC_HP_BNB13_EQ, .name = "hp-bnb13-eq" }, {} };
@@ -2273,7 +2709,101 @@ static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1899 ,"HP Folio 13" ,STAC_HP_LED_GPIO10 ),SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x18df , -"HP Folio" ,STAC_92HD83XXX_HP_MIC_LED ), +"HP Folio" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x18F8 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1909 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x190A , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1940 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1941 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1942 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1943 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1944 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1945 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1946 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1948 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1949 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x194A , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x194B , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x194C , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x194E , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x194F , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1950 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1951 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x195A , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x195B , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x195C , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x1991 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2103 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2104 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2105 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2106 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2107 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2108 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2109 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x210A , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x210B , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x211C , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x211D , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x211E , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x211F , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2120 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2121 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2122 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2123 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x213E , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x213F , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x2140 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x21B2 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x21B3 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x21B5 , +"HP bNB13" ,STAC_HP_BNB13_EQ ), +SND_PCI_QUIRK (PCI_VENDOR_ID_HP ,0x21B6 , +"HP bNB13" ,STAC_HP_BNB13_EQ ),SND_PCI_QUIRK_MASK (PCI_VENDOR_ID_HP ,0xff00 ,0x1900 ,"HP" ,STAC_92HD83XXX_HP_MIC_LED ), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2000,
Signature · 1 line
2.0.4
PATCH 102/104 drivers/rtc/rtc-efi.c: avoid subtracting day twice when computing year days
In reply to Jiri SlabyFrom: "Lee, Chun-Yi" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 809d9627087e1db63b8672c1f264af73b13116fb upstream.
Compared source code of rtc-lib.c::rtc_year_days() with efirtc.c::rtc_year_days(), found the code in rtc-efi decreases value of day twice when it computing year days. rtc-lib.c::rtc_year_days() has already decrease days and return the year days from 0 to 365.
--- drivers/rtc/rtc-efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-efi.c +1 -1
@@ -35,7 +35,7 @@ static inline int compute_yday(efi_time_t *eft) {/* efi_time_t.month is in the [1-12] so, we need -1 */ -return rtc_year_days (eft->day -1 , eft->month -1 , eft->year); +return rtc_year_days (eft->day, eft->month -1 , eft->year); }/* * returns day of the week [0-6] 0=Sunday
Signature · 1 line
2.0.4
PATCH 103/104 drivers/rtc/rtc-efi.c: check for invalid data coming back from UEFI
In reply to Jiri SlabyFrom: Jan Beulich <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6e85bab6bc1019f9b87c53b32da3ad7791e7ddf9 upstream.
In particular seeing zero in eft->month is problematic, as it results in -1 (converted to unsigned int, i.e. yielding 0xffffffff) getting passed to rtc_year_days(), where the value gets used as an array index (normally resulting in a crash). This was observed with the driver enabled on x86 on some Fujitsu system (with possibly not up to date firmware, but anyway).
Perhaps efi_read_alarm() should not fail if neither enabled nor pending are set, but the returned time is invalid?
--- drivers/rtc/rtc-efi.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-)
drivers/rtc/rtc-efi.c +27 -5
@@ -17,6 +17,7 @@#include <linux/kernel.h> #include <linux/module.h> +#include <linux/stringify.h> #include <linux/time.h> #include <linux/platform_device.h> #include <linux/rtc.h>
@@ -48,8 +49,8 @@ compute_wday(efi_time_t *eft)int y;int ndays =0 ; -if (eft->year <1998 ) { -pr_err ("EFI year < 1998, invalid date\n" ); +if (eft->year <EFI_RTC_EPOCH ) { + pr_err("EFI year < " __stringify(EFI_RTC_EPOCH) ", invalid date\n");return -1 ; }
@@ -78,19 +79,36 @@ convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft) eft->timezone =EFI_UNSPECIFIED_TIMEZONE ; } -static void +static bool convert_from_efi_time (efi_time_t *eft,struct rtc_time *wtime) {memset (wtime,0 ,sizeof (*wtime)); + +if (eft->second >=60 ) +return false; wtime->tm_sec = eft->second; + +if (eft->minute >=60 ) +return false; wtime->tm_min = eft->minute; + +if (eft->hour >=24 ) +return false; wtime->tm_hour = eft->hour; + +if (!eft->day || eft->day >31 ) +return false; wtime->tm_mday = eft->day; + +if (!eft->month || eft->month >12 ) +return false; wtime->tm_mon = eft->month -1 ; wtime->tm_year = eft->year -1900 ;/* day of the week [0-6], Sunday=0 */ wtime->tm_wday =compute_wday (eft); +if (wtime->tm_wday <0 ) +return false;/* day in the year [1-365]*/ wtime->tm_yday =compute_yday (eft);
@@ -106,6 +124,8 @@ convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)default : wtime->tm_isdst =-1 ; } + +return true; }static int efi_read_alarm (struct device *dev,struct rtc_wkalrm *wkalrm)
@@ -122,7 +142,8 @@ static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)if (status !=EFI_SUCCESS )return -EINVAL ; -convert_from_efi_time (&eft, &wkalrm->time); +if (!convert_from_efi_time (&eft, &wkalrm->time)) +return -EIO ;return rtc_valid_tm (&wkalrm->time); }
@@ -163,7 +184,8 @@ static int efi_read_time(struct device *dev, struct rtc_time *tm)return -EINVAL ; } -convert_from_efi_time (&eft, tm); +if (!convert_from_efi_time (&eft, tm)) +return -EIO ;return rtc_valid_tm (tm); }
Signature · 1 line
2.0.4
PATCH 104/104 drivers/rtc/interface.c: fix infinite loop in initializing the alarm
In reply to Jiri SlabyFrom: Ales Novak <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ee1d90146815fdc8d653c558b327fff2acba041d upstream.
In __rtc_read_alarm(), if the alarm time retrieved by rtc_read_alarm_internal() from the device contains invalid values (e.g. month=2,mday=31) and the year not set (=-1), the initialization will loop infinitely because the year-fixing loop expects the time being invalid due to leap year.
Fix reduces the loop to the leap years and adds final validity check.
--- drivers/rtc/interface.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/rtc/interface.c +12 -2
@@ -290,7 +290,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)dev_dbg (&rtc->dev,"alarm rollover: %s\n" ,"year" );do { alarm->time.tm_year++; - }while (rtc_valid_tm (&alarm->time) !=0 ); + }while (!is_leap_year (alarm->time.tm_year +1900 ) + &&rtc_valid_tm (&alarm->time) !=0 );break ;default :
@@ -298,7 +299,16 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) } done: -return 0 ; + err =rtc_valid_tm (&alarm->time); + +if (err) { +dev_warn (&rtc->dev,"invalid alarm value: %d-%d-%d %d:%d:%d\n" , + alarm->time.tm_year +1900 , alarm->time.tm_mon +1 , + alarm->time.tm_mday, alarm->time.tm_hour, alarm->time.tm_min, + alarm->time.tm_sec); + } + +return err; }int rtc_read_alarm (struct rtc_device *rtc,struct rtc_wkalrm *alarm)
Signature · 1 line
2.0.4
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.27 release. There are 104 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Aug 22 13:43:20 CEST 2014. Anything received after that time might be too late.
Build results look good:
total: 135 pass: 135 fail: 0
qemu tests passed except for sparc64 which hangs during boot, both for SMP and non-SMP builds. I'll try to bisect as soon as I have a somewhat stable internet connection.
Guenter
Quoted 9 lines · Guenter Roeck
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.27 release. There are 104 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Aug 22 13:43:20 CEST 2014. Anything received after that time might be too late.
Quoted 7 lines
Build results look good:
total: 135 pass: 135 fail: 0qemu tests passed except for sparc64 which hangs during boot, both for SMP and non-SMP builds. I'll try to bisect as soon as I have a somewhat stable internet connection.
Bisect result:
# bad: [c07d9e5da83f1470ccc58d37fe222dab36dbca67] drivers/rtc/interface.c: fix infinite loop in initializing the alarm # good: [d83a3234d2e1e2a55e7f2430fc9ca29a9bd315e7] Linux 3.12.26
git bisect start 'HEAD' 'v3.12.26'
# bad: [0d543dade2be5f0ddb268c6d6ea0e86938e3bf42] sparc64: Add membar to Niagara2 memcpy code.
git bisect bad 0d543dade2be5f0ddb268c6d6ea0e86938e3bf42
# good: [6e1af05639abfc6f1841e6bf8b5c8492971ed1f2] staging: vt6655: Fix Warning on boot handle_irq_event_percpu. git bisect good 6e1af05639abfc6f1841e6bf8b5c8492971ed1f2
# good: [6a25e8f778995cabb0cfe2acb3247e3b42dec35f] macvlan: Initialize vlan_features to turn on offload support. git bisect good 6a25e8f778995cabb0cfe2acb3247e3b42dec35f
# good: [bf42f839476f1f447ca696fbbab7e741861d9d7d] sparc64: Fix executable bit testing in set_pmd_at() paths. git bisect good bf42f839476f1f447ca696fbbab7e741861d9d7d
# bad: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad(). git bisect bad 6acda98c75b536deaba1bf21f93411fcc484fbb5
# good: [a91ce41d405b3cc59d6666ec91a5a3235f9cbcf6] sparc64: Fix top-level fault handling bugs.
git bisect good a91ce41d405b3cc59d6666ec91a5a3235f9cbcf6
# first bad commit: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad().Reverting the offending patch ('Add basic validations ...') fixes the problem.
There is a twist: The final kernel hangs during boot. Some of the interim builds crash. I did not try to track down where it stops crashing and starts hanging.
Adding Dave for additional input. I suspect there may be some missing patch, but no idea where to even start looking.
Guenter
Quoted 34 lines · Guenter Roeck
Quoted 9 lines · Guenter Roeck
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.27 release. There are 104 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Aug 22 13:43:20 CEST 2014. Anything received after that time might be too late.
Quoted 7 lines
Build results look good:
total: 135 pass: 135 fail: 0qemu tests passed except for sparc64 which hangs during boot, both for SMP and non-SMP builds. I'll try to bisect as soon as I have a somewhat stable internet connection.
Bisect result:
# bad: [
c07d9e5da83f1470ccc58d37fe222dab36dbca67]drivers/rtc/interface.c: fix infinite loop in initializing the alarm # good: [d83a3234d2e1e2a55e7f2430fc9ca29a9bd315e7] Linux 3.12.26
git bisect start 'HEAD' 'v3.12.26'
# bad: [0d543dade2be5f0ddb268c6d6ea0e86938e3bf42] sparc64: Add membar to Niagara2 memcpy code.
git bisect bad0d543dade2be5f0ddb268c6d6ea0e86938e3bf42
# good: [6e1af05639abfc6f1841e6bf8b5c8492971ed1f2] staging: vt6655: Fix Warning on boothandle_irq_event_percpu. git bisect good6e1af05639abfc6f1841e6bf8b5c8492971ed1f2
# good: [6a25e8f778995cabb0cfe2acb3247e3b42dec35f] macvlan: Initializevlan_featuresto turn on offload support. git bisect good6a25e8f778995cabb0cfe2acb3247e3b42dec35f
# good: [bf42f839476f1f447ca696fbbab7e741861d9d7d] sparc64: Fix executable bit testing inset_pmd_at()paths. git bisect goodbf42f839476f1f447ca696fbbab7e741861d9d7d
# bad: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad(). git bisect bad6acda98c75b536deaba1bf21f93411fcc484fbb5
# good: [a91ce41d405b3cc59d6666ec91a5a3235f9cbcf6] sparc64: Fix top-level fault handling bugs.
git bisect gooda91ce41d405b3cc59d6666ec91a5a3235f9cbcf6
Quoted 3 lines
# first bad commit: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad().Reverting the offending patch ('Add basic validations ...') fixes the problem.
Hi,
thanks for the work!
Just note on patches, in 3.12, there are all 3.10 patches plus these three:
+sparc64-add-basic-validations-to-pud-pmd-_bad.patch +sparc64-fix-executable-bit-testing-in-set_pmd_at-paths.patch +sparc64-give-more-detailed-information-in-pgd-pmd-_error-and-kill-pte_error.patch
where the third adds only printouts.
These 3.14 patches are not applied to 3.12:
+sparc64-don-t-use-_page_present-in-pte_modify-mask.patch +sparc64-fix-bugs-in-get_user_pages_fast-wrt.-thp.patch +sparc64-fix-huge-pmd-invalidation.patch +sparc64-fix-hex-values-in-comment-above-pte_modify.patch +sparc64-fix-range-check-in-kern_addr_valid.patch +sparc64-use-ilog2_4mb-instead-of-constant-22.patch
The last three are just cosmetical in 3.12. And I do not immediately see in the rest, how they could improve the state. So I am going to remove the add-basic-validations patch from 3.12.
thanks,
Signature · 2 lines
js suse labs
Quoted 45 lines · Jiri Slaby
Quoted 34 lines · Guenter Roeck
Quoted 9 lines · Guenter Roeck
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.27 release. There are 104 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Aug 22 13:43:20 CEST 2014. Anything received after that time might be too late.
Quoted 7 lines
Build results look good:
total: 135 pass: 135 fail: 0qemu tests passed except for sparc64 which hangs during boot, both for SMP and non-SMP builds. I'll try to bisect as soon as I have a somewhat stable internet connection.
Bisect result:
# bad: [
c07d9e5da83f1470ccc58d37fe222dab36dbca67]drivers/rtc/interface.c: fix infinite loop in initializing the alarm # good: [d83a3234d2e1e2a55e7f2430fc9ca29a9bd315e7] Linux 3.12.26
git bisect start 'HEAD' 'v3.12.26'
# bad: [0d543dade2be5f0ddb268c6d6ea0e86938e3bf42] sparc64: Add membar to Niagara2 memcpy code.
git bisect bad0d543dade2be5f0ddb268c6d6ea0e86938e3bf42
# good: [6e1af05639abfc6f1841e6bf8b5c8492971ed1f2] staging: vt6655: Fix Warning on boothandle_irq_event_percpu. git bisect good6e1af05639abfc6f1841e6bf8b5c8492971ed1f2
# good: [6a25e8f778995cabb0cfe2acb3247e3b42dec35f] macvlan: Initializevlan_featuresto turn on offload support. git bisect good6a25e8f778995cabb0cfe2acb3247e3b42dec35f
# good: [bf42f839476f1f447ca696fbbab7e741861d9d7d] sparc64: Fix executable bit testing inset_pmd_at()paths. git bisect goodbf42f839476f1f447ca696fbbab7e741861d9d7d
# bad: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad(). git bisect bad6acda98c75b536deaba1bf21f93411fcc484fbb5
# good: [a91ce41d405b3cc59d6666ec91a5a3235f9cbcf6] sparc64: Fix top-level fault handling bugs.
git bisect gooda91ce41d405b3cc59d6666ec91a5a3235f9cbcf6Quoted 3 lines
# first bad commit: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad().Reverting the offending patch ('Add basic validations ...') fixes the problem.
Hi,
thanks for the work!
Just note on patches, in 3.12, there are all 3.10 patches plus these three:
Review
Quoted 3 lines
(quoted diff) +3
-0+sparc64-add-basic-validations-to-pud-pmd-_bad.patch +sparc64-fix-executable-bit-testing-in-set_pmd_at-paths.patch +sparc64-give-more-detailed-information-in-pgd-pmd-_error-and-kill-pte_error.patch
The above is the patch causing the hangup. It may be caused by its use of __builtin_return_address; I recall I had trouble with that function before.
Review
Quoted 10 lines
where the third adds only printouts.
These 3.14 patches are not applied to 3.12:
(quoted diff) +6
-0+sparc64-don-t-use-_page_present-in-pte_modify-mask.patch +sparc64-fix-bugs-in-get_user_pages_fast-wrt.-thp.patch +sparc64-fix-huge-pmd-invalidation.patch +sparc64-fix-hex-values-in-comment-above-pte_modify.patch +sparc64-fix-range-check-in-kern_addr_valid.patch +sparc64-use-ilog2_4mb-instead-of-constant-22.patch
I'll check if any of those fixes the hangup/crash and let you know.
Guenter
Quoted 52 lines · Jiri Slaby
Quoted 34 lines · Guenter Roeck
Quoted 9 lines · Guenter Roeck
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.27 release. There are 104 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Aug 22 13:43:20 CEST 2014. Anything received after that time might be too late.
Quoted 7 lines
Build results look good:
total: 135 pass: 135 fail: 0qemu tests passed except for sparc64 which hangs during boot, both for SMP and non-SMP builds. I'll try to bisect as soon as I have a somewhat stable internet connection.
Bisect result:
# bad: [
c07d9e5da83f1470ccc58d37fe222dab36dbca67]drivers/rtc/interface.c: fix infinite loop in initializing the alarm # good: [d83a3234d2e1e2a55e7f2430fc9ca29a9bd315e7] Linux 3.12.26
git bisect start 'HEAD' 'v3.12.26'
# bad: [0d543dade2be5f0ddb268c6d6ea0e86938e3bf42] sparc64: Add membar to Niagara2 memcpy code.
git bisect bad0d543dade2be5f0ddb268c6d6ea0e86938e3bf42
# good: [6e1af05639abfc6f1841e6bf8b5c8492971ed1f2] staging: vt6655: Fix Warning on boothandle_irq_event_percpu. git bisect good6e1af05639abfc6f1841e6bf8b5c8492971ed1f2
# good: [6a25e8f778995cabb0cfe2acb3247e3b42dec35f] macvlan: Initializevlan_featuresto turn on offload support. git bisect good6a25e8f778995cabb0cfe2acb3247e3b42dec35f
# good: [bf42f839476f1f447ca696fbbab7e741861d9d7d] sparc64: Fix executable bit testing inset_pmd_at()paths. git bisect goodbf42f839476f1f447ca696fbbab7e741861d9d7d
# bad: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad(). git bisect bad6acda98c75b536deaba1bf21f93411fcc484fbb5
# good: [a91ce41d405b3cc59d6666ec91a5a3235f9cbcf6] sparc64: Fix top-level fault handling bugs.
git bisect gooda91ce41d405b3cc59d6666ec91a5a3235f9cbcf6Quoted 3 lines
# first bad commit: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad().Reverting the offending patch ('Add basic validations ...') fixes the problem.
Hi,
thanks for the work!
Just note on patches, in 3.12, there are all 3.10 patches plus these three:
(quoted diff) +3
-0+sparc64-add-basic-validations-to-pud-pmd-_bad.patch +sparc64-fix-executable-bit-testing-in-set_pmd_at-paths.patch +sparc64-give-more-detailed-information-in-pgd-pmd-_error-and-kill-pte_error.patchwhere the third adds only printouts.
These 3.14 patches are not applied to 3.12:
Review
Quoted 6 lines
(quoted diff) +6
-0+sparc64-don-t-use-_page_present-in-pte_modify-mask.patch +sparc64-fix-bugs-in-get_user_pages_fast-wrt.-thp.patch +sparc64-fix-huge-pmd-invalidation.patch +sparc64-fix-hex-values-in-comment-above-pte_modify.patch +sparc64-fix-range-check-in-kern_addr_valid.patch +sparc64-use-ilog2_4mb-instead-of-constant-22.patch
I tried to apply a couple of those, but they don't apply cleanly.
Quoted 4 lines
The last three are just cosmetical in 3.12. And I do not immediately see in the rest, how they could improve the state. So I am going to remove the add-basic-validations patch from 3.12.
... so that seems to be the best available solution, at least for now.
Guenter
Quoted 58 lines · Jiri Slaby
Quoted 34 lines · Guenter Roeck
Quoted 9 lines · Guenter Roeck
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.27 release. There are 104 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Aug 22 13:43:20 CEST 2014. Anything received after that time might be too late.
Quoted 7 lines
Build results look good:
total: 135 pass: 135 fail: 0qemu tests passed except for sparc64 which hangs during boot, both for SMP and non-SMP builds. I'll try to bisect as soon as I have a somewhat stable internet connection.
Bisect result:
# bad: [
c07d9e5da83f1470ccc58d37fe222dab36dbca67]drivers/rtc/interface.c: fix infinite loop in initializing the alarm # good: [d83a3234d2e1e2a55e7f2430fc9ca29a9bd315e7] Linux 3.12.26
git bisect start 'HEAD' 'v3.12.26'
# bad: [0d543dade2be5f0ddb268c6d6ea0e86938e3bf42] sparc64: Add membar to Niagara2 memcpy code.
git bisect bad0d543dade2be5f0ddb268c6d6ea0e86938e3bf42
# good: [6e1af05639abfc6f1841e6bf8b5c8492971ed1f2] staging: vt6655: Fix Warning on boothandle_irq_event_percpu. git bisect good6e1af05639abfc6f1841e6bf8b5c8492971ed1f2
# good: [6a25e8f778995cabb0cfe2acb3247e3b42dec35f] macvlan: Initializevlan_featuresto turn on offload support. git bisect good6a25e8f778995cabb0cfe2acb3247e3b42dec35f
# good: [bf42f839476f1f447ca696fbbab7e741861d9d7d] sparc64: Fix executable bit testing inset_pmd_at()paths. git bisect goodbf42f839476f1f447ca696fbbab7e741861d9d7d
# bad: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad(). git bisect bad6acda98c75b536deaba1bf21f93411fcc484fbb5
# good: [a91ce41d405b3cc59d6666ec91a5a3235f9cbcf6] sparc64: Fix top-level fault handling bugs.
git bisect gooda91ce41d405b3cc59d6666ec91a5a3235f9cbcf6Quoted 3 lines
# first bad commit: [6acda98c75b536deaba1bf21f93411fcc484fbb5] sparc64: Add basic validations to {pud,pmd}_bad().Reverting the offending patch ('Add basic validations ...') fixes the problem.
Hi,
thanks for the work!
Just note on patches, in 3.12, there are all 3.10 patches plus these three:
(quoted diff) +3
-0+sparc64-add-basic-validations-to-pud-pmd-_bad.patch +sparc64-fix-executable-bit-testing-in-set_pmd_at-paths.patch +sparc64-give-more-detailed-information-in-pgd-pmd-_error-and-kill-pte_error.patchwhere the third adds only printouts.
These 3.14 patches are not applied to 3.12:
(quoted diff) +6
-0+sparc64-don-t-use-_page_present-in-pte_modify-mask.patch +sparc64-fix-bugs-in-get_user_pages_fast-wrt.-thp.patch +sparc64-fix-huge-pmd-invalidation.patch +sparc64-fix-hex-values-in-comment-above-pte_modify.patch +sparc64-fix-range-check-in-kern_addr_valid.patch +sparc64-use-ilog2_4mb-instead-of-constant-22.patch
Quoted 4 lines
The last three are just cosmetical in 3.12. And I do not immediately see in the rest, how they could improve the state. So I am going to remove the add-basic-validations patch from 3.12.
Build and tests now look good.
Guenter
From: Guenter Roeck <[email protected]>
Date: Sat, 23 Aug 2014 08:14:54 -0700
Quoted 8 lines · Jiri Slaby
Quoted 5 lines
The last three are just cosmetical in 3.12. And I do not immediately see
in the rest, how they could improve the state. So I am going to remove the add-basic-validations patch from 3.12.Build and tests now look good.
I am hugely disappointed in this.
This is why I really do all the backports for each -stable release myself and I therefore really wish there was more thought put into when these changes are placed into other trees.
Almost all of those sparc64 memory management fixes should not go into anything before v3.13, because all of these fixes are in the context of the page tables encoding PMDs using the PTE layout.
If you're just forcing changes you see go into other -stable submissions into your tree until they compile, and just hoping that a tester will catch any problems, you are absolutely doing it wrong and taking a large amount of value out of the -stable releases.
Thanks.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 10 lines · David Miller
From: Guenter Roeck <[email protected]> Date: Sat, 23 Aug 2014 08:14:54 -0700
Quoted 7 lines · Jiri Slaby
Quoted 5 lines
The last three are just cosmetical in 3.12. And I do not immediately see in the rest, how they could improve the state. So I am going to remove the add-basic-validations patch from 3.12.
Quoted 3 lines
Quoted 1 line
Build and tests now look good.
I am hugely disappointed in this.
Yes, me too.
Quoted 3 lines
This is why I really do all the backports for each -stable release myself and I therefore really wish there was more thought put into when these changes are placed into other trees.
If everybody were using the standard stable rules and did not introduce a very special patches handling, we would have known what stable trees should contain which patches. Not only that everybody is confused about the special handling, but fixes for holes happened to be missed in the special process several times as of now.
Furthermore, with the special handling and given subtree maintainers provide backports only to selected stable trees, we have no way to find out what should (not) be applied. Interpolation is only what remains for us poor. (Leaving apart the great testing by the guys.)
Quoted 3 lines
Almost all of those sparc64 memory management fixes should not go into anything before v3.13, because all of these fixes are in the context of the page tables encoding PMDs using the PTE layout.
Again, until subtree maintainers distribute their private local knowledge somehow, we cannot know.
Quoted 4 lines
If you're just forcing changes you see go into other -stable submissions into your tree until they compile, and just hoping that a tester will catch any problems, you are absolutely doing it wrong and taking a large amount of value out of the -stable releases.
Actually, like it or not, this is exactly how all stable trees work for specific scenarios/hardware. And then, we have the -rc's. If patch authors do not bother to reply to the "patch added" mails despite they know it is inappropriate, stable maintainers are short of possibilities. Unless they are lucky, i.e. maintain a selected stable tree, where a subtree maintainer provides them with a set of patches for that tree.
thank you,
- --
js
suse labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQIcBAEBAgAGBQJT/HA/AAoJEL0lsQQGtHBJAqwP/1iqbPpBmDVA82gijLprtJPt O57ELwN9rOYsyfr702eXBm7UVW42T0AroxjAqoNx3MpoXfhXav49KaakAucMp7Sr fF4AHUz1ztT//xjhplJqZ/ht3WxwkNfDzliQ31vjFLnMpRyeLHrJeQu4FEk+G5wM 2NLue5JdG2rHYxYxT5Rzwxg/n0eIXwSHCgt2DydmqhAiIkkigVkD+ajRMzpnmH2y QErE3TN5PfKvs0tOjttZGuzCNKPdBfXacZyGe5HuXlg9LQ3TR+mqqWMIX3RUy6np i/TCI0aC+MQCsS59YVQaea6GZBC9uFprS+G1lYRlf520Anslrdqw4XNt4m3Y9GdL ptdUDTtp2b1bJQIC7PL+T9Nt8Wro1p3q0to1gEW4e8YJLYor0z5E9bDqPBXX/e+x fZ9IQsbUa+OjUkjqF+Cp4FWiI5hPzbJBbITiiAhYMjwr5zyaO7dt1higccvaXaIj 9P3zzqpFgsVQcD6IUC9krW3wJ6Pgba+a9oj+AXwxffAvhHxaR2KSRCzfIMa7rcwk Q+wPG31V781h1NHf0q0Wc/3AVacs9WrmGh+MWciUCJUvSQQ+4mTQIoehAGIzF86s bljMaVQ1tf4aJpojQ1jltTBbckY2rhuDgs5u5fQDKQn+FKL/IMQ2NIr9xYYy54C0 MnOIE7FqoMFVJaMAWSC7
=ueH5
-----END PGP SIGNATURE-----
Quoted 8 lines · Jiri Slaby
This is the start of the stable review cycle for the 3.12.27 release. There are 104 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Aug 22 13:43:20 CEST 2014. Anything received after that time might be too late.
Quoted 7 lines
The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.27-rc1.xzand the diffstat can be found below.
thanks,
js
Compiled and booted on my test system. No dmesg regressions. I pulled the patch this morning, hoping add-basic-validations patch has been removed.
-- Shuah
Signature · 4 lines
Shuah Khan Sr. Linux Kernel Developer Samsung Research America (Silicon Valley) [email protected] | (970) 217-8978