From d5df82c992b296747704e620717d3c60e7d28e88 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 10 Apr 2017 17:24:22 +0200 Subject: [PATCH] 3.18 work mbox... --- queue-3.18/work_mbox | 20266 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 20266 insertions(+) create mode 100644 queue-3.18/work_mbox diff --git a/queue-3.18/work_mbox b/queue-3.18/work_mbox new file mode 100644 index 00000000000..30d532a713a --- /dev/null +++ b/queue-3.18/work_mbox @@ -0,0 +1,20266 @@ +From 59c4d7838e3e526f3e253c536727e3539321fbd6 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Thu, 26 Nov 2015 19:28:26 +0100 +Subject: [PATCH 001/251] TTY: n_hdlc, fix lockdep false positive +Status: RO +Content-Length: 3446 +Lines: 97 + +commit e9b736d88af1a143530565929390cadf036dc799 upstream. + +The class of 4 n_hdls buf locks is the same because a single function +n_hdlc_buf_list_init is used to init all the locks. But since +flush_tx_queue takes n_hdlc->tx_buf_list.spinlock and then calls +n_hdlc_buf_put which takes n_hdlc->tx_free_buf_list.spinlock, lockdep +emits a warning: +============================================= +[ INFO: possible recursive locking detected ] +4.3.0-25.g91e30a7-default #1 Not tainted +--------------------------------------------- +a.out/1248 is trying to acquire lock: + (&(&list->spinlock)->rlock){......}, at: [] n_hdlc_buf_put+0x20/0x60 [n_hdlc] + +but task is already holding lock: + (&(&list->spinlock)->rlock){......}, at: [] n_hdlc_tty_ioctl+0x127/0x1d0 [n_hdlc] + +other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(&(&list->spinlock)->rlock); + lock(&(&list->spinlock)->rlock); + + *** DEADLOCK *** + + May be due to missing lock nesting notation + +2 locks held by a.out/1248: + #0: (&tty->ldisc_sem){++++++}, at: [] tty_ldisc_ref_wait+0x20/0x50 + #1: (&(&list->spinlock)->rlock){......}, at: [] n_hdlc_tty_ioctl+0x127/0x1d0 [n_hdlc] +... +Call Trace: +... + [] _raw_spin_lock_irqsave+0x50/0x70 + [] n_hdlc_buf_put+0x20/0x60 [n_hdlc] + [] n_hdlc_tty_ioctl+0x144/0x1d0 [n_hdlc] + [] tty_ioctl+0x3f1/0xe40 +... + +Fix it by initializing the spin_locks separately. This removes also +reduntand memset of a freshly kzallocated space. + +Signed-off-by: Jiri Slaby +Reported-by: Dmitry Vyukov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_hdlc.c | 19 ++++--------------- + 1 file changed, 4 insertions(+), 15 deletions(-) + +diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c +index 644ddb841d9f..a7fa016f31eb 100644 +--- a/drivers/tty/n_hdlc.c ++++ b/drivers/tty/n_hdlc.c +@@ -159,7 +159,6 @@ struct n_hdlc { + /* + * HDLC buffer list manipulation functions + */ +-static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list); + static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, + struct n_hdlc_buf *buf); + static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list); +@@ -853,10 +852,10 @@ static struct n_hdlc *n_hdlc_alloc(void) + if (!n_hdlc) + return NULL; + +- n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list); +- n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list); +- n_hdlc_buf_list_init(&n_hdlc->rx_buf_list); +- n_hdlc_buf_list_init(&n_hdlc->tx_buf_list); ++ spin_lock_init(&n_hdlc->rx_free_buf_list.spinlock); ++ spin_lock_init(&n_hdlc->tx_free_buf_list.spinlock); ++ spin_lock_init(&n_hdlc->rx_buf_list.spinlock); ++ spin_lock_init(&n_hdlc->tx_buf_list.spinlock); + + /* allocate free rx buffer list */ + for(i=0;ispinlock); +-} /* end of n_hdlc_buf_list_init() */ +- +-/** + * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list + * @list - pointer to buffer list + * @buf - pointer to buffer +-- +2.12.2 + +From 999853d941b99ca2ac4a331552c388e2603a9b1d Mon Sep 17 00:00:00 2001 +From: Alexander Popov +Date: Tue, 28 Feb 2017 19:54:40 +0300 +Subject: [PATCH 002/251] tty: n_hdlc: get rid of racy n_hdlc.tbuf +Content-Length: 9967 +Lines: 308 + +commit 82f2341c94d270421f383641b7cd670e474db56b upstream. + +Currently N_HDLC line discipline uses a self-made singly linked list for +data buffers and has n_hdlc.tbuf pointer for buffer retransmitting after +an error. + +The commit be10eb7589337e5defbe214dae038a53dd21add8 +("tty: n_hdlc add buffer flushing") introduced racy access to n_hdlc.tbuf. +After tx error concurrent flush_tx_queue() and n_hdlc_send_frames() can put +one data buffer to tx_free_buf_list twice. That causes double free in +n_hdlc_release(). + +Let's use standard kernel linked list and get rid of n_hdlc.tbuf: +in case of tx error put current data buffer after the head of tx_buf_list. + +Signed-off-by: Alexander Popov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/n_hdlc.c | 132 +++++++++++++++++++++++++++------------------------ + 1 file changed, 69 insertions(+), 63 deletions(-) + +diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c +index a7fa016f31eb..6d1e2f746ab4 100644 +--- a/drivers/tty/n_hdlc.c ++++ b/drivers/tty/n_hdlc.c +@@ -114,7 +114,7 @@ + #define DEFAULT_TX_BUF_COUNT 3 + + struct n_hdlc_buf { +- struct n_hdlc_buf *link; ++ struct list_head list_item; + int count; + char buf[1]; + }; +@@ -122,8 +122,7 @@ struct n_hdlc_buf { + #define N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe) + + struct n_hdlc_buf_list { +- struct n_hdlc_buf *head; +- struct n_hdlc_buf *tail; ++ struct list_head list; + int count; + spinlock_t spinlock; + }; +@@ -136,7 +135,6 @@ struct n_hdlc_buf_list { + * @backup_tty - TTY to use if tty gets closed + * @tbusy - reentrancy flag for tx wakeup code + * @woke_up - FIXME: describe this field +- * @tbuf - currently transmitting tx buffer + * @tx_buf_list - list of pending transmit frame buffers + * @rx_buf_list - list of received frame buffers + * @tx_free_buf_list - list unused transmit frame buffers +@@ -149,7 +147,6 @@ struct n_hdlc { + struct tty_struct *backup_tty; + int tbusy; + int woke_up; +- struct n_hdlc_buf *tbuf; + struct n_hdlc_buf_list tx_buf_list; + struct n_hdlc_buf_list rx_buf_list; + struct n_hdlc_buf_list tx_free_buf_list; +@@ -159,6 +156,8 @@ struct n_hdlc { + /* + * HDLC buffer list manipulation functions + */ ++static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list, ++ struct n_hdlc_buf *buf); + static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, + struct n_hdlc_buf *buf); + static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list); +@@ -208,16 +207,9 @@ static void flush_tx_queue(struct tty_struct *tty) + { + struct n_hdlc *n_hdlc = tty2n_hdlc(tty); + struct n_hdlc_buf *buf; +- unsigned long flags; + + while ((buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list))) + n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf); +- spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); +- if (n_hdlc->tbuf) { +- n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf); +- n_hdlc->tbuf = NULL; +- } +- spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); + } + + static struct tty_ldisc_ops n_hdlc_ldisc = { +@@ -283,7 +275,6 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc) + } else + break; + } +- kfree(n_hdlc->tbuf); + kfree(n_hdlc); + + } /* end of n_hdlc_release() */ +@@ -402,13 +393,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) + n_hdlc->woke_up = 0; + spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); + +- /* get current transmit buffer or get new transmit */ +- /* buffer from list of pending transmit buffers */ +- +- tbuf = n_hdlc->tbuf; +- if (!tbuf) +- tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list); +- ++ tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list); + while (tbuf) { + if (debuglevel >= DEBUG_LEVEL_INFO) + printk("%s(%d)sending frame %p, count=%d\n", +@@ -420,7 +405,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) + + /* rollback was possible and has been done */ + if (actual == -ERESTARTSYS) { +- n_hdlc->tbuf = tbuf; ++ n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf); + break; + } + /* if transmit error, throw frame away by */ +@@ -435,10 +420,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) + + /* free current transmit buffer */ + n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf); +- +- /* this tx buffer is done */ +- n_hdlc->tbuf = NULL; +- ++ + /* wait up sleeping writers */ + wake_up_interruptible(&tty->write_wait); + +@@ -448,10 +430,12 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) + if (debuglevel >= DEBUG_LEVEL_INFO) + printk("%s(%d)frame %p pending\n", + __FILE__,__LINE__,tbuf); +- +- /* buffer not accepted by driver */ +- /* set this buffer as pending buffer */ +- n_hdlc->tbuf = tbuf; ++ ++ /* ++ * the buffer was not accepted by driver, ++ * return it back into tx queue ++ */ ++ n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf); + break; + } + } +@@ -749,7 +733,8 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, + int error = 0; + int count; + unsigned long flags; +- ++ struct n_hdlc_buf *buf = NULL; ++ + if (debuglevel >= DEBUG_LEVEL_INFO) + printk("%s(%d)n_hdlc_tty_ioctl() called %d\n", + __FILE__,__LINE__,cmd); +@@ -763,8 +748,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, + /* report count of read data available */ + /* in next available frame (if any) */ + spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags); +- if (n_hdlc->rx_buf_list.head) +- count = n_hdlc->rx_buf_list.head->count; ++ buf = list_first_entry_or_null(&n_hdlc->rx_buf_list.list, ++ struct n_hdlc_buf, list_item); ++ if (buf) ++ count = buf->count; + else + count = 0; + spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags); +@@ -776,8 +763,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, + count = tty_chars_in_buffer(tty); + /* add size of next output frame in queue */ + spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags); +- if (n_hdlc->tx_buf_list.head) +- count += n_hdlc->tx_buf_list.head->count; ++ buf = list_first_entry_or_null(&n_hdlc->tx_buf_list.list, ++ struct n_hdlc_buf, list_item); ++ if (buf) ++ count += buf->count; + spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags); + error = put_user(count, (int __user *)arg); + break; +@@ -825,14 +814,14 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp, + poll_wait(filp, &tty->write_wait, wait); + + /* set bits for operations that won't block */ +- if (n_hdlc->rx_buf_list.head) ++ if (!list_empty(&n_hdlc->rx_buf_list.list)) + mask |= POLLIN | POLLRDNORM; /* readable */ + if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) + mask |= POLLHUP; + if (tty_hung_up_p(filp)) + mask |= POLLHUP; + if (!tty_is_writelocked(tty) && +- n_hdlc->tx_free_buf_list.head) ++ !list_empty(&n_hdlc->tx_free_buf_list.list)) + mask |= POLLOUT | POLLWRNORM; /* writable */ + } + return mask; +@@ -856,7 +845,12 @@ static struct n_hdlc *n_hdlc_alloc(void) + spin_lock_init(&n_hdlc->tx_free_buf_list.spinlock); + spin_lock_init(&n_hdlc->rx_buf_list.spinlock); + spin_lock_init(&n_hdlc->tx_buf_list.spinlock); +- ++ ++ INIT_LIST_HEAD(&n_hdlc->rx_free_buf_list.list); ++ INIT_LIST_HEAD(&n_hdlc->tx_free_buf_list.list); ++ INIT_LIST_HEAD(&n_hdlc->rx_buf_list.list); ++ INIT_LIST_HEAD(&n_hdlc->tx_buf_list.list); ++ + /* allocate free rx buffer list */ + for(i=0;ispinlock, flags); ++ ++ list_add(&buf->list_item, &buf_list->list); ++ buf_list->count++; ++ ++ spin_unlock_irqrestore(&buf_list->spinlock, flags); ++} ++ ++/** + * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list +- * @list - pointer to buffer list ++ * @buf_list - pointer to buffer list + * @buf - pointer to buffer + */ +-static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, ++static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list, + struct n_hdlc_buf *buf) + { + unsigned long flags; +- spin_lock_irqsave(&list->spinlock,flags); +- +- buf->link=NULL; +- if (list->tail) +- list->tail->link = buf; +- else +- list->head = buf; +- list->tail = buf; +- (list->count)++; +- +- spin_unlock_irqrestore(&list->spinlock,flags); +- ++ ++ spin_lock_irqsave(&buf_list->spinlock, flags); ++ ++ list_add_tail(&buf->list_item, &buf_list->list); ++ buf_list->count++; ++ ++ spin_unlock_irqrestore(&buf_list->spinlock, flags); + } /* end of n_hdlc_buf_put() */ + + /** + * n_hdlc_buf_get - remove and return an HDLC buffer from list +- * @list - pointer to HDLC buffer list ++ * @buf_list - pointer to HDLC buffer list + * + * Remove and return an HDLC buffer from the head of the specified HDLC buffer + * list. + * Returns a pointer to HDLC buffer if available, otherwise %NULL. + */ +-static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list) ++static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *buf_list) + { + unsigned long flags; + struct n_hdlc_buf *buf; +- spin_lock_irqsave(&list->spinlock,flags); +- +- buf = list->head; ++ ++ spin_lock_irqsave(&buf_list->spinlock, flags); ++ ++ buf = list_first_entry_or_null(&buf_list->list, ++ struct n_hdlc_buf, list_item); + if (buf) { +- list->head = buf->link; +- (list->count)--; ++ list_del(&buf->list_item); ++ buf_list->count--; + } +- if (!list->head) +- list->tail = NULL; +- +- spin_unlock_irqrestore(&list->spinlock,flags); ++ ++ spin_unlock_irqrestore(&buf_list->spinlock, flags); + return buf; +- + } /* end of n_hdlc_buf_get() */ + + static char hdlc_banner[] __initdata = +-- +2.12.2 + +From 4b34572e98f1b0d0df4ea084347b89b5a20fbede Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Fri, 3 Feb 2017 20:25:00 +0000 +Subject: [PATCH 003/251] serial: 8250_pci: Add MKS Tenta SCOM-0800 and + SCOM-0801 cards +Content-Length: 1922 +Lines: 56 + +commit 1c9c858e2ff8ae8024a3d75d2ed080063af43754 upstream. + +The MKS Instruments SCOM-0800 and SCOM-0801 cards (originally by Tenta +Technologies) are 3U CompactPCI serial cards with 4 and 8 serial ports, +respectively. The first 4 ports are implemented by an OX16PCI954 chip, +and the second 4 ports are implemented by an OX16C954 chip on a local +bus, bridged by the second PCI function of the OX16PCI954. The ports +are jumper-selectable as RS-232 and RS-422/485, and the UARTs use a +non-standard oscillator frequency of 20 MHz (base_baud = 1250000). + +Signed-off-by: Ian Abbott +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250_pci.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 029de3f99752..5b24ffd93649 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -2880,6 +2880,8 @@ enum pci_board_num_t { + pbn_b0_4_1152000_200, + pbn_b0_8_1152000_200, + ++ pbn_b0_4_1250000, ++ + pbn_b0_2_1843200, + pbn_b0_4_1843200, + +@@ -3113,6 +3115,13 @@ static struct pciserial_board pci_boards[] = { + .uart_offset = 0x200, + }, + ++ [pbn_b0_4_1250000] = { ++ .flags = FL_BASE0, ++ .num_ports = 4, ++ .base_baud = 1250000, ++ .uart_offset = 8, ++ }, ++ + [pbn_b0_2_1843200] = { + .flags = FL_BASE0, + .num_ports = 2, +@@ -5778,6 +5787,10 @@ static struct pci_device_id serial_pci_tbl[] = { + { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 }, + { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 }, + ++ /* MKS Tenta SCOM-080x serial cards */ ++ { PCI_DEVICE(0x1601, 0x0800), .driver_data = pbn_b0_4_1250000 }, ++ { PCI_DEVICE(0x1601, 0xa801), .driver_data = pbn_b0_4_1250000 }, ++ + /* + * These entries match devices with class COMMUNICATION_SERIAL, + * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL +-- +2.12.2 + +From 0a3df0418d90d7be1abf8e41191c3caa26f2ad4e Mon Sep 17 00:00:00 2001 +From: Janosch Frank +Date: Thu, 2 Feb 2017 16:39:31 +0100 +Subject: [PATCH 004/251] KVM: s390: Disable dirty log retrieval for UCONTROL + guests +Content-Length: 1240 +Lines: 38 + +commit e1e8a9624f7ba8ead4f056ff558ed070e86fa747 upstream. + +User controlled KVM guests do not support the dirty log, as they have +no single gmap that we can check for changes. + +As they have no single gmap, kvm->arch.gmap is NULL and all further +referencing to it for dirty checking will result in a NULL +dereference. + +Let's return -EINVAL if a caller tries to sync dirty logs for a +UCONTROL guest. + +Fixes: 15f36eb ("KVM: s390: Add proper dirty bitmap support to S390 kvm.") +Signed-off-by: Janosch Frank +Reported-by: Martin Schwidefsky +Reviewed-by: Cornelia Huck +Signed-off-by: Christian Borntraeger +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/kvm/kvm-s390.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index 575dc123bda2..23e3f5d77a24 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -295,6 +295,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, + struct kvm_memory_slot *memslot; + int is_dirty = 0; + ++ if (kvm_is_ucontrol(kvm)) ++ return -EINVAL; ++ + mutex_lock(&kvm->slots_lock); + + r = -EINVAL; +-- +2.12.2 + +From cae929bd8d807457997bec4e9fbc61885cc582f7 Mon Sep 17 00:00:00 2001 +From: Chao Peng +Date: Tue, 21 Feb 2017 03:50:01 -0500 +Subject: [PATCH 005/251] KVM: VMX: use correct vmcs_read/write for guest + segment selector/base +Content-Length: 1437 +Lines: 38 + +commit 96794e4ed4d758272c486e1529e431efb7045265 upstream. + +Guest segment selector is 16 bit field and guest segment base is natural +width field. Fix two incorrect invocations accordingly. + +Without this patch, build fails when aggressive inlining is used with ICC. + +Signed-off-by: Chao Peng +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/vmx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 64f60a48def1..3a7ae80dc49d 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -3499,7 +3499,7 @@ static void fix_rmode_seg(int seg, struct kvm_segment *save) + } + + vmcs_write16(sf->selector, var.selector); +- vmcs_write32(sf->base, var.base); ++ vmcs_writel(sf->base, var.base); + vmcs_write32(sf->limit, var.limit); + vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(&var)); + } +@@ -7905,7 +7905,7 @@ static void kvm_flush_pml_buffers(struct kvm *kvm) + static void vmx_dump_sel(char *name, uint32_t sel) + { + pr_err("%s sel=0x%04x, attr=0x%05x, limit=0x%08x, base=0x%016lx\n", +- name, vmcs_read32(sel), ++ name, vmcs_read16(sel), + vmcs_read32(sel + GUEST_ES_AR_BYTES - GUEST_ES_SELECTOR), + vmcs_read32(sel + GUEST_ES_LIMIT - GUEST_ES_SELECTOR), + vmcs_readl(sel + GUEST_ES_BASE - GUEST_ES_SELECTOR)); +-- +2.12.2 + +From 00cfdbf5ab6e3285bb4589e6e5d241c8db8cd3ed Mon Sep 17 00:00:00 2001 +From: Dmitry Tunin +Date: Thu, 5 Jan 2017 13:19:53 +0300 +Subject: [PATCH 006/251] Bluetooth: Add another AR3012 04ca:3018 device +Content-Length: 2385 +Lines: 51 + +commit 441ad62d6c3f131f1dbd7dcdd9cbe3f74dbd8501 upstream. + +T: Bus=01 Lev=01 Prnt=01 Port=07 Cnt=04 Dev#= 5 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=04ca ProdID=3018 Rev=00.01 +C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + +Signed-off-by: Dmitry Tunin +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/ath3k.c | 2 ++ + drivers/bluetooth/btusb.c | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c +index 0beaa52df66b..5df8e1234505 100644 +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -94,6 +94,7 @@ static const struct usb_device_id ath3k_table[] = { + { USB_DEVICE(0x04CA, 0x300f) }, + { USB_DEVICE(0x04CA, 0x3010) }, + { USB_DEVICE(0x04CA, 0x3014) }, ++ { USB_DEVICE(0x04CA, 0x3018) }, + { USB_DEVICE(0x0930, 0x0219) }, + { USB_DEVICE(0x0930, 0x021c) }, + { USB_DEVICE(0x0930, 0x0220) }, +@@ -160,6 +161,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { + { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index c306b483de60..cd6b141b9825 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -208,6 +208,7 @@ static const struct usb_device_id blacklist_table[] = { + { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, +-- +2.12.2 + +From ec50c80c780152d2058c23d9e246fc81f73742da Mon Sep 17 00:00:00 2001 +From: Julian Wiedmann +Date: Mon, 21 Nov 2016 13:37:48 +0100 +Subject: [PATCH 007/251] s390/qdio: clear DSCI prior to scanning multiple + input queues +Content-Length: 2241 +Lines: 56 + +commit 1e4a382fdc0ba8d1a85b758c0811de3a3631085e upstream. + +For devices with multiple input queues, tiqdio_call_inq_handlers() +iterates over all input queues and clears the device's DSCI +during each iteration. If the DSCI is re-armed during one +of the later iterations, we therefore do not scan the previous +queues again. +The re-arming also raises a new adapter interrupt. But its +handler does not trigger a rescan for the device, as the DSCI +has already been erroneously cleared. +This can result in queue stalls on devices with multiple +input queues. + +Fix it by clearing the DSCI just once, prior to scanning the queues. + +As the code is moved in front of the loop, we also need to access +the DSCI directly (ie irq->dsci) instead of going via each queue's +parent pointer to the same irq. This is not a functional change, +and a follow-up patch will clean up the other users. + +In practice, this bug only affects CQ-enabled HiperSockets devices, +ie. devices with sysfs-attribute "hsuid" set. Setting a hsuid is +needed for AF_IUCV socket applications that use HiperSockets +communication. + +Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks") +Reviewed-by: Ursula Braun +Signed-off-by: Julian Wiedmann +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + drivers/s390/cio/qdio_thinint.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c +index 5d06253c2a7a..30e9fbbff051 100644 +--- a/drivers/s390/cio/qdio_thinint.c ++++ b/drivers/s390/cio/qdio_thinint.c +@@ -147,11 +147,11 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq) + struct qdio_q *q; + int i; + +- for_each_input_queue(irq, q, i) { +- if (!references_shared_dsci(irq) && +- has_multiple_inq_on_dsci(irq)) +- xchg(q->irq_ptr->dsci, 0); ++ if (!references_shared_dsci(irq) && ++ has_multiple_inq_on_dsci(irq)) ++ xchg(irq->dsci, 0); + ++ for_each_input_queue(irq, q, i) { + if (q->u.in.queue_start_poll) { + /* skip if polling is enabled or already in work */ + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, +-- +2.12.2 + +From 792bd1fb5b0338232e47412bce2a9b6f0f1fbdaf Mon Sep 17 00:00:00 2001 +From: Gerald Schaefer +Date: Mon, 30 Jan 2017 15:52:14 +0100 +Subject: [PATCH 008/251] s390/dcssblk: fix device size calculation in + dcssblk_direct_access() +Content-Length: 1263 +Lines: 32 + +commit a63f53e34db8b49675448d03ae324f6c5bc04fe6 upstream. + +Since commit dd22f551 "block: Change direct_access calling convention", +the device size calculation in dcssblk_direct_access() is off-by-one. +This results in bdev_direct_access() always returning -ENXIO because the +returned value is not page aligned. + +Fix this by adding 1 to the dev_sz calculation. + +Fixes: dd22f551 ("block: Change direct_access calling convention") +Signed-off-by: Gerald Schaefer +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + drivers/s390/block/dcssblk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c +index 94a8f4ab57bc..ae1dc37e4068 100644 +--- a/drivers/s390/block/dcssblk.c ++++ b/drivers/s390/block/dcssblk.c +@@ -892,7 +892,7 @@ dcssblk_direct_access (struct block_device *bdev, sector_t secnum, + dev_info = bdev->bd_disk->private_data; + if (!dev_info) + return -ENODEV; +- dev_sz = dev_info->end - dev_info->start; ++ dev_sz = dev_info->end - dev_info->start + 1; + offset = secnum * 512; + addr = (void *) (dev_info->start + offset); + *pfn = virt_to_phys(addr) >> PAGE_SHIFT; +-- +2.12.2 + +From 9cf431dbd8f78d4e78d4aa3ef4fb453cd71e2978 Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Fri, 24 Feb 2017 07:43:51 +0100 +Subject: [PATCH 009/251] s390: TASK_SIZE for kernel threads +Content-Length: 1158 +Lines: 30 + +commit fb94a687d96c570d46332a4a890f1dcb7310e643 upstream. + +Return a sensible value if TASK_SIZE if called from a kernel thread. + +This gets us around an issue with copy_mount_options that does a magic +size calculation "TASK_SIZE - (unsigned long)data" while in a kernel +thread and data pointing to kernel space. + +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/include/asm/processor.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h +index c1ea67db8404..c61ed7890cef 100644 +--- a/arch/s390/include/asm/processor.h ++++ b/arch/s390/include/asm/processor.h +@@ -74,7 +74,8 @@ extern void execve_tail(void); + * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. + */ + +-#define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit) ++#define TASK_SIZE_OF(tsk) ((tsk)->mm ? \ ++ (tsk)->mm->context.asce_limit : TASK_MAX_SIZE) + #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ + (1UL << 30) : (1UL << 41)) + #define TASK_SIZE TASK_SIZE_OF(current) +-- +2.12.2 + +From 296f7bd7f1dbd2379489ea779779ef437d9e6c6f Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Sat, 4 Feb 2017 11:40:36 +0100 +Subject: [PATCH 010/251] s390: make setup_randomness work +Content-Length: 1465 +Lines: 40 + +commit da8fd820f389a0e29080b14c61bf5cf1d8ef5ca1 upstream. + +Commit bcfcbb6bae64 ("s390: add system information as device +randomness") intended to add some virtual machine specific information +to the randomness pool. + +Unfortunately it uses the page allocator before it is ready to use. In +result the page allocator always returns NULL and the setup_randomness +function never adds anything to the randomness pool. + +To fix this use memblock_alloc and memblock_free instead. + +Fixes: bcfcbb6bae64 ("s390: add system information as device randomness") +Signed-off-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/kernel/setup.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c +index 1f581eb61bc2..1cf4aae76780 100644 +--- a/arch/s390/kernel/setup.c ++++ b/arch/s390/kernel/setup.c +@@ -805,10 +805,10 @@ static void __init setup_randomness(void) + { + struct sysinfo_3_2_2 *vmms; + +- vmms = (struct sysinfo_3_2_2 *) alloc_page(GFP_KERNEL); +- if (vmms && stsi(vmms, 3, 2, 2) == 0 && vmms->count) ++ vmms = (struct sysinfo_3_2_2 *) memblock_alloc(PAGE_SIZE, PAGE_SIZE); ++ if (stsi(vmms, 3, 2, 2) == 0 && vmms->count) + add_device_randomness(&vmms, vmms->count); +- free_page((unsigned long) vmms); ++ memblock_free((unsigned long) vmms, PAGE_SIZE); + } + + /* +-- +2.12.2 + +From 376a12eb7f608fad96b13fab3f151eb4c9b40c7c Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Sun, 5 Feb 2017 23:03:18 +0100 +Subject: [PATCH 011/251] s390: use correct input data address for + setup_randomness +Content-Length: 1414 +Lines: 37 + +commit 4920e3cf77347d7d7373552d4839e8d832321313 upstream. + +The current implementation of setup_randomness uses the stack address +and therefore the pointer to the SYSIB 3.2.2 block as input data +address. Furthermore the length of the input data is the number of +virtual-machine description blocks which is typically one. + +This means that typically a single zero byte is fed to +add_device_randomness. + +Fix both of these and use the address of the first virtual machine +description block as input data address and also use the correct +length. + +Fixes: bcfcbb6bae64 ("s390: add system information as device randomness") +Signed-off-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/kernel/setup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c +index 1cf4aae76780..d097d71685df 100644 +--- a/arch/s390/kernel/setup.c ++++ b/arch/s390/kernel/setup.c +@@ -807,7 +807,7 @@ static void __init setup_randomness(void) + + vmms = (struct sysinfo_3_2_2 *) memblock_alloc(PAGE_SIZE, PAGE_SIZE); + if (stsi(vmms, 3, 2, 2) == 0 && vmms->count) +- add_device_randomness(&vmms, vmms->count); ++ add_device_randomness(&vmms->vm, sizeof(vmms->vm[0]) * vmms->count); + memblock_free((unsigned long) vmms, PAGE_SIZE); + } + +-- +2.12.2 + +From b57ffb2a8466a7628b316c8e3a5ce34b8ee4e519 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Tue, 21 Feb 2017 11:28:01 +0100 +Subject: [PATCH 012/251] net: mvpp2: fix DMA address calculation in + mvpp2_txq_inc_put() +Content-Length: 1642 +Lines: 38 + +commit 239a3b663647869330955ec59caac0100ef9b60a upstream. + +When TX descriptors are filled in, the buffer DMA address is split +between the tx_desc->buf_phys_addr field (high-order bits) and +tx_desc->packet_offset field (5 low-order bits). + +However, when we re-calculate the DMA address from the TX descriptor in +mvpp2_txq_inc_put(), we do not take tx_desc->packet_offset into +account. This means that when the DMA address is not aligned on a 32 +bytes boundary, we end up calling dma_unmap_single() with a DMA address +that was not the one returned by dma_map_single(). + +This inconsistency is detected by the kernel when DMA_API_DEBUG is +enabled. We fix this problem by properly calculating the DMA address in +mvpp2_txq_inc_put(). + +Signed-off-by: Thomas Petazzoni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/mvpp2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c +index 25aba9886990..0e67145bc418 100644 +--- a/drivers/net/ethernet/marvell/mvpp2.c ++++ b/drivers/net/ethernet/marvell/mvpp2.c +@@ -993,7 +993,7 @@ static void mvpp2_txq_inc_put(struct mvpp2_txq_pcpu *txq_pcpu, + txq_pcpu->buffs + txq_pcpu->txq_put_index; + tx_buf->skb = skb; + tx_buf->size = tx_desc->data_size; +- tx_buf->phys = tx_desc->buf_phys_addr; ++ tx_buf->phys = tx_desc->buf_phys_addr + tx_desc->packet_offset; + txq_pcpu->txq_put_index++; + if (txq_pcpu->txq_put_index == txq_pcpu->size) + txq_pcpu->txq_put_index = 0; +-- +2.12.2 + +From 839d42687dfce0ed0ea2c6bd8d707cc0e276fbe7 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 20 Jan 2017 18:28:35 +1300 +Subject: [PATCH 013/251] mnt: Tuck mounts under others instead of creating + shadow/side mounts. +Content-Length: 13585 +Lines: 423 + +commit 1064f874abc0d05eeed8993815f584d847b72486 upstream. + +Ever since mount propagation was introduced in cases where a mount in +propagated to parent mount mountpoint pair that is already in use the +code has placed the new mount behind the old mount in the mount hash +table. + +This implementation detail is problematic as it allows creating +arbitrary length mount hash chains. + +Furthermore it invalidates the constraint maintained elsewhere in the +mount code that a parent mount and a mountpoint pair will have exactly +one mount upon them. Making it hard to deal with and to talk about +this special case in the mount code. + +Modify mount propagation to notice when there is already a mount at +the parent mount and mountpoint where a new mount is propagating to +and place that preexisting mount on top of the new mount. + +Modify unmount propagation to notice when a mount that is being +unmounted has another mount on top of it (and no other children), and +to replace the unmounted mount with the mount on top of it. + +Move the MNT_UMUONT test from __lookup_mnt_last into +__propagate_umount as that is the only call of __lookup_mnt_last where +MNT_UMOUNT may be set on any mount visible in the mount hash table. + +These modifications allow: + - __lookup_mnt_last to be removed. + - attach_shadows to be renamed __attach_mnt and its shadow + handling to be removed. + - commit_tree to be simplified + - copy_tree to be simplified + +The result is an easier to understand tree of mounts that does not +allow creation of arbitrary length hash chains in the mount hash table. + +The result is also a very slight userspace visible difference in semantics. +The following two cases now behave identically, where before order +mattered: + +case 1: (explicit user action) + B is a slave of A + mount something on A/a , it will propagate to B/a + and than mount something on B/a + +case 2: (tucked mount) + B is a slave of A + mount something on B/a + and than mount something on A/a + +Histroically umount A/a would fail in case 1 and succeed in case 2. +Now umount A/a succeeds in both configurations. + +This very small change in semantics appears if anything to be a bug +fix to me and my survey of userspace leads me to believe that no programs +will notice or care of this subtle semantic change. + +v2: Updated to mnt_change_mountpoint to not call dput or mntput +and instead to decrement the counts directly. It is guaranteed +that there will be other references when mnt_change_mountpoint is +called so this is safe. + +v3: Moved put_mountpoint under mount_lock in attach_recursive_mnt + As the locking in fs/namespace.c changed between v2 and v3. + +v4: Reworked the logic in propagate_mount_busy and __propagate_umount + that detects when a mount completely covers another mount. + +v5: Removed unnecessary tests whose result is alwasy true in + find_topper and attach_recursive_mnt. + +v6: Document the user space visible semantic difference. + +Fixes: b90fa9ae8f51 ("[PATCH] shared mount handling: bind and rbind") +Tested-by: Andrei Vagin +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman +--- + fs/mount.h | 1 - + fs/namespace.c | 109 +++++++++++++++++++++++++++++++-------------------------- + fs/pnode.c | 61 +++++++++++++++++++++++++------- + fs/pnode.h | 2 ++ + 4 files changed, 110 insertions(+), 63 deletions(-) + +diff --git a/fs/mount.h b/fs/mount.h +index 14db05d424f7..3dc7dea5a357 100644 +--- a/fs/mount.h ++++ b/fs/mount.h +@@ -86,7 +86,6 @@ static inline int is_mounted(struct vfsmount *mnt) + } + + extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *); +-extern struct mount *__lookup_mnt_last(struct vfsmount *, struct dentry *); + + extern int __legitimize_mnt(struct vfsmount *, unsigned); + extern bool legitimize_mnt(struct vfsmount *, unsigned); +diff --git a/fs/namespace.c b/fs/namespace.c +index da98a1bbd8b5..7df3d406d3e0 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -638,28 +638,6 @@ struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry) + } + + /* +- * find the last mount at @dentry on vfsmount @mnt. +- * mount_lock must be held. +- */ +-struct mount *__lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry) +-{ +- struct mount *p, *res = NULL; +- p = __lookup_mnt(mnt, dentry); +- if (!p) +- goto out; +- if (!(p->mnt.mnt_flags & MNT_UMOUNT)) +- res = p; +- hlist_for_each_entry_continue(p, mnt_hash) { +- if (&p->mnt_parent->mnt != mnt || p->mnt_mountpoint != dentry) +- break; +- if (!(p->mnt.mnt_flags & MNT_UMOUNT)) +- res = p; +- } +-out: +- return res; +-} +- +-/* + * lookup_mnt - Return the first child mount mounted at path + * + * "First" means first mounted chronologically. If you create the +@@ -879,6 +857,13 @@ void mnt_set_mountpoint(struct mount *mnt, + hlist_add_head(&child_mnt->mnt_mp_list, &mp->m_list); + } + ++static void __attach_mnt(struct mount *mnt, struct mount *parent) ++{ ++ hlist_add_head_rcu(&mnt->mnt_hash, ++ m_hash(&parent->mnt, mnt->mnt_mountpoint)); ++ list_add_tail(&mnt->mnt_child, &parent->mnt_mounts); ++} ++ + /* + * vfsmount lock must be held for write + */ +@@ -887,28 +872,45 @@ static void attach_mnt(struct mount *mnt, + struct mountpoint *mp) + { + mnt_set_mountpoint(parent, mp, mnt); +- hlist_add_head_rcu(&mnt->mnt_hash, m_hash(&parent->mnt, mp->m_dentry)); +- list_add_tail(&mnt->mnt_child, &parent->mnt_mounts); ++ __attach_mnt(mnt, parent); + } + +-static void attach_shadowed(struct mount *mnt, +- struct mount *parent, +- struct mount *shadows) ++void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp, struct mount *mnt) + { +- if (shadows) { +- hlist_add_behind_rcu(&mnt->mnt_hash, &shadows->mnt_hash); +- list_add(&mnt->mnt_child, &shadows->mnt_child); +- } else { +- hlist_add_head_rcu(&mnt->mnt_hash, +- m_hash(&parent->mnt, mnt->mnt_mountpoint)); +- list_add_tail(&mnt->mnt_child, &parent->mnt_mounts); +- } ++ struct mountpoint *old_mp = mnt->mnt_mp; ++ struct dentry *old_mountpoint = mnt->mnt_mountpoint; ++ struct mount *old_parent = mnt->mnt_parent; ++ ++ list_del_init(&mnt->mnt_child); ++ hlist_del_init(&mnt->mnt_mp_list); ++ hlist_del_init_rcu(&mnt->mnt_hash); ++ ++ attach_mnt(mnt, parent, mp); ++ ++ put_mountpoint(old_mp); ++ ++ /* ++ * Safely avoid even the suggestion this code might sleep or ++ * lock the mount hash by taking advantage of the knowledge that ++ * mnt_change_mountpoint will not release the final reference ++ * to a mountpoint. ++ * ++ * During mounting, the mount passed in as the parent mount will ++ * continue to use the old mountpoint and during unmounting, the ++ * old mountpoint will continue to exist until namespace_unlock, ++ * which happens well after mnt_change_mountpoint. ++ */ ++ spin_lock(&old_mountpoint->d_lock); ++ old_mountpoint->d_lockref.count--; ++ spin_unlock(&old_mountpoint->d_lock); ++ ++ mnt_add_count(old_parent, -1); + } + + /* + * vfsmount lock must be held for write + */ +-static void commit_tree(struct mount *mnt, struct mount *shadows) ++static void commit_tree(struct mount *mnt) + { + struct mount *parent = mnt->mnt_parent; + struct mount *m; +@@ -923,7 +925,7 @@ static void commit_tree(struct mount *mnt, struct mount *shadows) + + list_splice(&head, n->list.prev); + +- attach_shadowed(mnt, parent, shadows); ++ __attach_mnt(mnt, parent); + touch_mnt_namespace(n); + } + +@@ -1718,7 +1720,6 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, + continue; + + for (s = r; s; s = next_mnt(s, r)) { +- struct mount *t = NULL; + if (!(flag & CL_COPY_UNBINDABLE) && + IS_MNT_UNBINDABLE(s)) { + s = skip_mnt_tree(s); +@@ -1740,14 +1741,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, + goto out; + lock_mount_hash(); + list_add_tail(&q->mnt_list, &res->mnt_list); +- mnt_set_mountpoint(parent, p->mnt_mp, q); +- if (!list_empty(&parent->mnt_mounts)) { +- t = list_last_entry(&parent->mnt_mounts, +- struct mount, mnt_child); +- if (t->mnt_mp != p->mnt_mp) +- t = NULL; +- } +- attach_shadowed(q, parent, t); ++ attach_mnt(q, parent, p->mnt_mp); + unlock_mount_hash(); + } + } +@@ -1925,10 +1919,18 @@ static int attach_recursive_mnt(struct mount *source_mnt, + struct path *parent_path) + { + HLIST_HEAD(tree_list); ++ struct mountpoint *smp; + struct mount *child, *p; + struct hlist_node *n; + int err; + ++ /* Preallocate a mountpoint in case the new mounts need ++ * to be tucked under other mounts. ++ */ ++ smp = get_mountpoint(source_mnt->mnt.mnt_root); ++ if (IS_ERR(smp)) ++ return PTR_ERR(smp); ++ + if (IS_MNT_SHARED(dest_mnt)) { + err = invent_group_ids(source_mnt, true); + if (err) +@@ -1948,16 +1950,19 @@ static int attach_recursive_mnt(struct mount *source_mnt, + touch_mnt_namespace(source_mnt->mnt_ns); + } else { + mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt); +- commit_tree(source_mnt, NULL); ++ commit_tree(source_mnt); + } + + hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) { + struct mount *q; + hlist_del_init(&child->mnt_hash); +- q = __lookup_mnt_last(&child->mnt_parent->mnt, +- child->mnt_mountpoint); +- commit_tree(child, q); ++ q = __lookup_mnt(&child->mnt_parent->mnt, ++ child->mnt_mountpoint); ++ if (q) ++ mnt_change_mountpoint(child, smp, q); ++ commit_tree(child); + } ++ put_mountpoint(smp); + unlock_mount_hash(); + + return 0; +@@ -1970,6 +1975,10 @@ static int attach_recursive_mnt(struct mount *source_mnt, + unlock_mount_hash(); + cleanup_group_ids(source_mnt, NULL); + out: ++ read_seqlock_excl(&mount_lock); ++ put_mountpoint(smp); ++ read_sequnlock_excl(&mount_lock); ++ + return err; + } + +diff --git a/fs/pnode.c b/fs/pnode.c +index 99899705b105..b9f2af59b9a6 100644 +--- a/fs/pnode.c ++++ b/fs/pnode.c +@@ -324,6 +324,21 @@ out: + return ret; + } + ++static struct mount *find_topper(struct mount *mnt) ++{ ++ /* If there is exactly one mount covering mnt completely return it. */ ++ struct mount *child; ++ ++ if (!list_is_singular(&mnt->mnt_mounts)) ++ return NULL; ++ ++ child = list_first_entry(&mnt->mnt_mounts, struct mount, mnt_child); ++ if (child->mnt_mountpoint != mnt->mnt.mnt_root) ++ return NULL; ++ ++ return child; ++} ++ + /* + * return true if the refcount is greater than count + */ +@@ -344,9 +359,8 @@ static inline int do_refcount_check(struct mount *mnt, int count) + */ + int propagate_mount_busy(struct mount *mnt, int refcnt) + { +- struct mount *m, *child; ++ struct mount *m, *child, *topper; + struct mount *parent = mnt->mnt_parent; +- int ret = 0; + + if (mnt == parent) + return do_refcount_check(mnt, refcnt); +@@ -361,12 +375,24 @@ int propagate_mount_busy(struct mount *mnt, int refcnt) + + for (m = propagation_next(parent, parent); m; + m = propagation_next(m, parent)) { +- child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint); +- if (child && list_empty(&child->mnt_mounts) && +- (ret = do_refcount_check(child, 1))) +- break; ++ int count = 1; ++ child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint); ++ if (!child) ++ continue; ++ ++ /* Is there exactly one mount on the child that covers ++ * it completely whose reference should be ignored? ++ */ ++ topper = find_topper(child); ++ if (topper) ++ count += 1; ++ else if (!list_empty(&child->mnt_mounts)) ++ continue; ++ ++ if (do_refcount_check(child, count)) ++ return 1; + } +- return ret; ++ return 0; + } + + /* +@@ -383,7 +409,7 @@ void propagate_mount_unlock(struct mount *mnt) + + for (m = propagation_next(parent, parent); m; + m = propagation_next(m, parent)) { +- child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint); ++ child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint); + if (child) + child->mnt.mnt_flags &= ~MNT_LOCKED; + } +@@ -401,9 +427,11 @@ static void mark_umount_candidates(struct mount *mnt) + + for (m = propagation_next(parent, parent); m; + m = propagation_next(m, parent)) { +- struct mount *child = __lookup_mnt_last(&m->mnt, ++ struct mount *child = __lookup_mnt(&m->mnt, + mnt->mnt_mountpoint); +- if (child && (!IS_MNT_LOCKED(child) || IS_MNT_MARKED(m))) { ++ if (!child || (child->mnt.mnt_flags & MNT_UMOUNT)) ++ continue; ++ if (!IS_MNT_LOCKED(child) || IS_MNT_MARKED(m)) { + SET_MNT_MARK(child); + } + } +@@ -422,8 +450,8 @@ static void __propagate_umount(struct mount *mnt) + + for (m = propagation_next(parent, parent); m; + m = propagation_next(m, parent)) { +- +- struct mount *child = __lookup_mnt_last(&m->mnt, ++ struct mount *topper; ++ struct mount *child = __lookup_mnt(&m->mnt, + mnt->mnt_mountpoint); + /* + * umount the child only if the child has no children +@@ -432,6 +460,15 @@ static void __propagate_umount(struct mount *mnt) + if (!child || !IS_MNT_MARKED(child)) + continue; + CLEAR_MNT_MARK(child); ++ ++ /* If there is exactly one mount covering all of child ++ * replace child with that mount. ++ */ ++ topper = find_topper(child); ++ if (topper) ++ mnt_change_mountpoint(child->mnt_parent, child->mnt_mp, ++ topper); ++ + if (list_empty(&child->mnt_mounts)) { + list_del_init(&child->mnt_child); + child->mnt.mnt_flags |= MNT_UMOUNT; +diff --git a/fs/pnode.h b/fs/pnode.h +index 0fcdbe7ca648..623f01772bec 100644 +--- a/fs/pnode.h ++++ b/fs/pnode.h +@@ -49,6 +49,8 @@ int get_dominating_id(struct mount *mnt, const struct path *root); + unsigned int mnt_get_count(struct mount *mnt); + void mnt_set_mountpoint(struct mount *, struct mountpoint *, + struct mount *); ++void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp, ++ struct mount *mnt); + struct mount *copy_tree(struct mount *, struct dentry *, int); + bool is_path_reachable(struct mount *, struct dentry *, + const struct path *root); +-- +2.12.2 + +From 10beca53745eff651209fbd6d8ddbbc0f46c30a4 Mon Sep 17 00:00:00 2001 +From: Feras Daoud +Date: Wed, 28 Dec 2016 14:47:23 +0200 +Subject: [PATCH 014/251] IB/ipoib: Fix deadlock between rmmod and set_mode +Content-Length: 4326 +Lines: 110 + +commit 0a0007f28304cb9fc87809c86abb80ec71317f20 upstream. + +When calling set_mode from sys/fs, the call flow locks the sys/fs lock +first and then tries to lock rtnl_lock (when calling ipoib_set_mod). +On the other hand, the rmmod call flow takes the rtnl_lock first +(when calling unregister_netdev) and then tries to take the sys/fs +lock. Deadlock a->b, b->a. + +The problem starts when ipoib_set_mod frees it's rtnl_lck and tries +to get it after that. + + set_mod: + [] ? check_preempt_curr+0x6d/0x90 + [] __mutex_lock_slowpath+0x13e/0x180 + [] ? __rtnl_unlock+0x15/0x20 + [] mutex_lock+0x2b/0x50 + [] rtnl_lock+0x15/0x20 + [] ipoib_set_mode+0x97/0x160 [ib_ipoib] + [] set_mode+0x3b/0x80 [ib_ipoib] + [] dev_attr_store+0x20/0x30 + [] sysfs_write_file+0xe5/0x170 + [] vfs_write+0xb8/0x1a0 + [] sys_write+0x51/0x90 + [] system_call_fastpath+0x16/0x1b + + rmmod: + [] ? put_dec+0x10c/0x110 + [] ? number+0x2ee/0x320 + [] schedule_timeout+0x215/0x2e0 + [] ? vsnprintf+0x484/0x5f0 + [] ? string+0x40/0x100 + [] wait_for_common+0x123/0x180 + [] ? default_wake_function+0x0/0x20 + [] ? ifind_fast+0x5e/0xb0 + [] wait_for_completion+0x1d/0x20 + [] sysfs_addrm_finish+0x228/0x270 + [] sysfs_remove_dir+0xa3/0xf0 + [] kobject_del+0x16/0x40 + [] device_del+0x184/0x1e0 + [] netdev_unregister_kobject+0xab/0xc0 + [] rollback_registered+0xae/0x130 + [] unregister_netdevice+0x22/0x70 + [] unregister_netdev+0x1e/0x30 + [] ipoib_remove_one+0xe0/0x120 [ib_ipoib] + [] ib_unregister_device+0x4f/0x100 [ib_core] + [] mlx4_ib_remove+0x41/0x180 [mlx4_ib] + [] mlx4_remove_device+0x71/0x90 [mlx4_core] + +Fixes: 862096a8bbf8 ("IB/ipoib: Add more rtnl_link_ops callbacks") +Cc: Or Gerlitz +Signed-off-by: Feras Daoud +Signed-off-by: Erez Shitrit +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/ulp/ipoib/ipoib_cm.c | 12 +++++++----- + drivers/infiniband/ulp/ipoib/ipoib_main.c | 6 ++---- + 2 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +index 3ba7de5f9379..2018d24344de 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +@@ -1488,12 +1488,14 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr, + + ret = ipoib_set_mode(dev, buf); + +- rtnl_unlock(); +- +- if (!ret) +- return count; ++ /* The assumption is that the function ipoib_set_mode returned ++ * with the rtnl held by it, if not the value -EBUSY returned, ++ * then no need to rtnl_unlock ++ */ ++ if (ret != -EBUSY) ++ rtnl_unlock(); + +- return ret; ++ return (!ret || ret == -EBUSY) ? count : ret; + } + + static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode); +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c +index 8a4d10452d61..b34f9ffe559a 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c +@@ -464,8 +464,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf) + priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM; + + ipoib_flush_paths(dev); +- rtnl_lock(); +- return 0; ++ return (!rtnl_trylock()) ? -EBUSY : 0; + } + + if (!strcmp(buf, "datagram\n")) { +@@ -474,8 +473,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf) + dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu)); + rtnl_unlock(); + ipoib_flush_paths(dev); +- rtnl_lock(); +- return 0; ++ return (!rtnl_trylock()) ? -EBUSY : 0; + } + + return -EINVAL; +-- +2.12.2 + +From bb4a21dcb6fb57892eea7c941fdfd57e55ba5dbe Mon Sep 17 00:00:00 2001 +From: Erez Shitrit +Date: Wed, 1 Feb 2017 19:10:05 +0200 +Subject: [PATCH 015/251] IB/IPoIB: Add destination address when re-queue + packet +Content-Length: 4692 +Lines: 125 + +commit 2b0841766a898aba84630fb723989a77a9d3b4e6 upstream. + +When sending packet to destination that was not resolved yet +via path query, the driver keeps the skb and tries to re-send it +again when the path is resolved. + +But when re-sending via dev_queue_xmit the kernel doesn't call +to dev_hard_header, so IPoIB needs to keep 20 bytes in the skb +and to put the destination address inside them. + +In that way the dev_start_xmit will have the correct destination, +and the driver won't take the destination from the skb->data, while +nothing exists there, which causes to packet be be dropped. + +The test flow is: +1. Run the SM on remote node, +2. Restart the driver. +4. Ping some destination, +3. Observe that first ICMP request will be dropped. + +Fixes: fc791b633515 ("IB/ipoib: move back IB LL address into the hard header") +Signed-off-by: Erez Shitrit +Signed-off-by: Noa Osherovich +Signed-off-by: Leon Romanovsky +Tested-by: Yuval Shaia +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/ulp/ipoib/ipoib_main.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c +index b34f9ffe559a..8efcff1beb8f 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c +@@ -626,6 +626,14 @@ void ipoib_mark_paths_invalid(struct net_device *dev) + spin_unlock_irq(&priv->lock); + } + ++static void push_pseudo_header(struct sk_buff *skb, const char *daddr) ++{ ++ struct ipoib_pseudo_header *phdr; ++ ++ phdr = (struct ipoib_pseudo_header *)skb_push(skb, sizeof(*phdr)); ++ memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); ++} ++ + void ipoib_flush_paths(struct net_device *dev) + { + struct ipoib_dev_priv *priv = netdev_priv(dev); +@@ -850,8 +858,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, + } + if (skb_queue_len(&neigh->queue) < + IPOIB_MAX_PATH_REC_QUEUE) { +- /* put pseudoheader back on for next time */ +- skb_push(skb, IPOIB_PSEUDO_LEN); ++ push_pseudo_header(skb, neigh->daddr); + __skb_queue_tail(&neigh->queue, skb); + } else { + ipoib_warn(priv, "queue length limit %d. Packet drop.\n", +@@ -869,10 +876,12 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, + + if (!path->query && path_rec_start(dev, path)) + goto err_path; +- if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) ++ if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { ++ push_pseudo_header(skb, neigh->daddr); + __skb_queue_tail(&neigh->queue, skb); +- else ++ } else { + goto err_drop; ++ } + } + + spin_unlock_irqrestore(&priv->lock, flags); +@@ -908,8 +917,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, + } + if (path) { + if (skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { +- /* put pseudoheader back on for next time */ +- skb_push(skb, IPOIB_PSEUDO_LEN); ++ push_pseudo_header(skb, phdr->hwaddr); + __skb_queue_tail(&path->queue, skb); + } else { + ++dev->stats.tx_dropped; +@@ -941,8 +949,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, + return; + } else if ((path->query || !path_rec_start(dev, path)) && + skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { +- /* put pseudoheader back on for next time */ +- skb_push(skb, IPOIB_PSEUDO_LEN); ++ push_pseudo_header(skb, phdr->hwaddr); + __skb_queue_tail(&path->queue, skb); + } else { + ++dev->stats.tx_dropped; +@@ -1023,8 +1030,7 @@ send_using_neigh: + } + + if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { +- /* put pseudoheader back on for next time */ +- skb_push(skb, sizeof(*phdr)); ++ push_pseudo_header(skb, phdr->hwaddr); + spin_lock_irqsave(&priv->lock, flags); + __skb_queue_tail(&neigh->queue, skb); + spin_unlock_irqrestore(&priv->lock, flags); +@@ -1056,7 +1062,6 @@ static int ipoib_hard_header(struct sk_buff *skb, + unsigned short type, + const void *daddr, const void *saddr, unsigned len) + { +- struct ipoib_pseudo_header *phdr; + struct ipoib_header *header; + + header = (struct ipoib_header *) skb_push(skb, sizeof *header); +@@ -1069,8 +1074,7 @@ static int ipoib_hard_header(struct sk_buff *skb, + * destination address into skb hard header so we can figure out where + * to send the packet later. + */ +- phdr = (struct ipoib_pseudo_header *) skb_push(skb, sizeof(*phdr)); +- memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); ++ push_pseudo_header(skb, daddr); + + return IPOIB_HARD_LEN; + } +-- +2.12.2 + +From 944690cdb5f48d03842365b7359fe090d6c2b1fa Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Tue, 14 Feb 2017 10:56:30 -0800 +Subject: [PATCH 016/251] IB/srp: Avoid that duplicate responses trigger a + kernel bug +Content-Length: 1979 +Lines: 54 + +commit 6cb72bc1b40bb2c1750ee7a5ebade93bed49a5fb upstream. + +After srp_process_rsp() returns there is a short time during which +the scsi_host_find_tag() call will return a pointer to the SCSI +command that is being completed. If during that time a duplicate +response is received, avoid that the following call stack appears: + +BUG: unable to handle kernel NULL pointer dereference at (null) +IP: srp_recv_done+0x450/0x6b0 [ib_srp] +Oops: 0000 [#1] SMP +CPU: 10 PID: 0 Comm: swapper/10 Not tainted 4.10.0-rc7-dbg+ #1 +Call Trace: + + __ib_process_cq+0x4b/0xd0 [ib_core] + ib_poll_handler+0x1d/0x70 [ib_core] + irq_poll_softirq+0xba/0x120 + __do_softirq+0xba/0x4c0 + irq_exit+0xbe/0xd0 + smp_apic_timer_interrupt+0x38/0x50 + apic_timer_interrupt+0x90/0xa0 + +RIP: srp_recv_done+0x450/0x6b0 [ib_srp] RSP: ffff88046f483e20 + +Signed-off-by: Bart Van Assche +Cc: Israel Rukshin +Cc: Max Gurtovoy +Cc: Laurence Oberman +Cc: Steve Feeley +Reviewed-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/ulp/srp/ib_srp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 5f0f4fc58f43..57a8a200e741 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -1795,9 +1795,11 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp) + complete(&ch->tsk_mgmt_done); + } else { + scmnd = scsi_host_find_tag(target->scsi_host, rsp->tag); +- if (scmnd) { ++ if (scmnd && scmnd->host_scribble) { + req = (void *)scmnd->host_scribble; + scmnd = srp_claim_req(ch, req, NULL, scmnd); ++ } else { ++ scmnd = NULL; + } + if (!scmnd) { + shost_printk(KERN_ERR, target->scsi_host, +-- +2.12.2 + +From 696255449b89af5487bce53b1a65eddedc72aeff Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Tue, 14 Feb 2017 10:56:31 -0800 +Subject: [PATCH 017/251] IB/srp: Fix race conditions related to task + management +Content-Length: 5896 +Lines: 169 + +commit 0a6fdbdeb1c25e31763c1fb333fa2723a7d2aba6 upstream. + +Avoid that srp_process_rsp() overwrites the status information +in ch if the SRP target response timed out and processing of +another task management function has already started. Avoid that +issuing multiple task management functions concurrently triggers +list corruption. This patch prevents that the following stack +trace appears in the system log: + +WARNING: CPU: 8 PID: 9269 at lib/list_debug.c:52 __list_del_entry_valid+0xbc/0xc0 +list_del corruption. prev->next should be ffffc90004bb7b00, but was ffff8804052ecc68 +CPU: 8 PID: 9269 Comm: sg_reset Tainted: G W 4.10.0-rc7-dbg+ #3 +Call Trace: + dump_stack+0x68/0x93 + __warn+0xc6/0xe0 + warn_slowpath_fmt+0x4a/0x50 + __list_del_entry_valid+0xbc/0xc0 + wait_for_completion_timeout+0x12e/0x170 + srp_send_tsk_mgmt+0x1ef/0x2d0 [ib_srp] + srp_reset_device+0x5b/0x110 [ib_srp] + scsi_ioctl_reset+0x1c7/0x290 + scsi_ioctl+0x12a/0x420 + sd_ioctl+0x9d/0x100 + blkdev_ioctl+0x51e/0x9f0 + block_ioctl+0x38/0x40 + do_vfs_ioctl+0x8f/0x700 + SyS_ioctl+0x3c/0x70 + entry_SYSCALL_64_fastpath+0x18/0xad + +Signed-off-by: Bart Van Assche +Cc: Israel Rukshin +Cc: Max Gurtovoy +Cc: Laurence Oberman +Cc: Steve Feeley +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/ulp/srp/ib_srp.c | 45 ++++++++++++++++++++++++------------- + drivers/infiniband/ulp/srp/ib_srp.h | 1 + + 2 files changed, 30 insertions(+), 16 deletions(-) + +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 57a8a200e741..e397f1b0af09 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -1787,12 +1787,17 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp) + if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) { + spin_lock_irqsave(&ch->lock, flags); + ch->req_lim += be32_to_cpu(rsp->req_lim_delta); ++ if (rsp->tag == ch->tsk_mgmt_tag) { ++ ch->tsk_mgmt_status = -1; ++ if (be32_to_cpu(rsp->resp_data_len) >= 4) ++ ch->tsk_mgmt_status = rsp->data[3]; ++ complete(&ch->tsk_mgmt_done); ++ } else { ++ shost_printk(KERN_ERR, target->scsi_host, ++ "Received tsk mgmt response too late for tag %#llx\n", ++ rsp->tag); ++ } + spin_unlock_irqrestore(&ch->lock, flags); +- +- ch->tsk_mgmt_status = -1; +- if (be32_to_cpu(rsp->resp_data_len) >= 4) +- ch->tsk_mgmt_status = rsp->data[3]; +- complete(&ch->tsk_mgmt_done); + } else { + scmnd = scsi_host_find_tag(target->scsi_host, rsp->tag); + if (scmnd && scmnd->host_scribble) { +@@ -2471,19 +2476,18 @@ srp_change_queue_depth(struct scsi_device *sdev, int qdepth) + } + + static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun, +- u8 func) ++ u8 func, u8 *status) + { + struct srp_target_port *target = ch->target; + struct srp_rport *rport = target->rport; + struct ib_device *dev = target->srp_host->srp_dev->dev; + struct srp_iu *iu; + struct srp_tsk_mgmt *tsk_mgmt; ++ int res; + + if (!ch->connected || target->qp_in_error) + return -1; + +- init_completion(&ch->tsk_mgmt_done); +- + /* + * Lock the rport mutex to avoid that srp_create_ch_ib() is + * invoked while a task management function is being sent. +@@ -2506,10 +2510,16 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun, + + tsk_mgmt->opcode = SRP_TSK_MGMT; + int_to_scsilun(lun, &tsk_mgmt->lun); +- tsk_mgmt->tag = req_tag | SRP_TAG_TSK_MGMT; + tsk_mgmt->tsk_mgmt_func = func; + tsk_mgmt->task_tag = req_tag; + ++ spin_lock_irq(&ch->lock); ++ ch->tsk_mgmt_tag = (ch->tsk_mgmt_tag + 1) | SRP_TAG_TSK_MGMT; ++ tsk_mgmt->tag = ch->tsk_mgmt_tag; ++ spin_unlock_irq(&ch->lock); ++ ++ init_completion(&ch->tsk_mgmt_done); ++ + ib_dma_sync_single_for_device(dev, iu->dma, sizeof *tsk_mgmt, + DMA_TO_DEVICE); + if (srp_post_send(ch, iu, sizeof(*tsk_mgmt))) { +@@ -2518,13 +2528,15 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun, + + return -1; + } ++ res = wait_for_completion_timeout(&ch->tsk_mgmt_done, ++ msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS)); ++ if (res > 0 && status) ++ *status = ch->tsk_mgmt_status; + mutex_unlock(&rport->mutex); + +- if (!wait_for_completion_timeout(&ch->tsk_mgmt_done, +- msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS))) +- return -1; ++ WARN_ON_ONCE(res < 0); + +- return 0; ++ return res > 0 ? 0 : -1; + } + + static int srp_abort(struct scsi_cmnd *scmnd) +@@ -2550,7 +2562,7 @@ static int srp_abort(struct scsi_cmnd *scmnd) + shost_printk(KERN_ERR, target->scsi_host, + "Sending SRP abort for tag %#x\n", tag); + if (srp_send_tsk_mgmt(ch, tag, scmnd->device->lun, +- SRP_TSK_ABORT_TASK) == 0) ++ SRP_TSK_ABORT_TASK, NULL) == 0) + ret = SUCCESS; + else if (target->rport->state == SRP_RPORT_LOST) + ret = FAST_IO_FAIL; +@@ -2568,14 +2580,15 @@ static int srp_reset_device(struct scsi_cmnd *scmnd) + struct srp_target_port *target = host_to_target(scmnd->device->host); + struct srp_rdma_ch *ch; + int i; ++ u8 status; + + shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n"); + + ch = &target->ch[0]; + if (srp_send_tsk_mgmt(ch, SRP_TAG_NO_REQ, scmnd->device->lun, +- SRP_TSK_LUN_RESET)) ++ SRP_TSK_LUN_RESET, &status)) + return FAILED; +- if (ch->tsk_mgmt_status) ++ if (status) + return FAILED; + + for (i = 0; i < target->ch_count; i++) { +diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h +index f6af531f9f32..109eea94d0f9 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.h ++++ b/drivers/infiniband/ulp/srp/ib_srp.h +@@ -168,6 +168,7 @@ struct srp_rdma_ch { + int max_ti_iu_len; + int comp_vector; + ++ u64 tsk_mgmt_tag; + struct completion tsk_mgmt_done; + u8 tsk_mgmt_status; + bool connected; +-- +2.12.2 + +From 485171b1ee8c7cc74cff9881b92b178b1c709663 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Tue, 7 Feb 2017 12:05:25 -0500 +Subject: [PATCH 018/251] ktest: Fix child exit code processing +Content-Length: 849 +Lines: 27 + +commit 32677207dcc5e594254b7fb4fb2352b1755b1d5b upstream. + +The child_exit errno needs to be shifted by 8 bits to compare against the +return values for the bisect variables. + +Fixes: c5dacb88f0a64 ("ktest: Allow overriding bisect test results") +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/ktest/ktest.pl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl +index d08e214ec6e7..223d88e25e05 100755 +--- a/tools/testing/ktest/ktest.pl ++++ b/tools/testing/ktest/ktest.pl +@@ -2629,7 +2629,7 @@ sub do_run_test { + } + + waitpid $child_pid, 0; +- $child_exit = $?; ++ $child_exit = $? >> 8; + + my $end_time = time; + $test_time = $end_time - $start_time; +-- +2.12.2 + +From 05a9143edb47e7799f191f1015f56eb2dacfee0d Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Tue, 14 Feb 2017 10:09:40 -0500 +Subject: [PATCH 019/251] ceph: remove req from unsafe list when unregistering + it +Content-Length: 1752 +Lines: 46 + +commit df963ea8a082d31521a120e8e31a29ad8a1dc215 upstream. + +There's no reason a request should ever be on a s_unsafe list but not +in the request tree. + +Link: http://tracker.ceph.com/issues/18474 +Signed-off-by: Jeff Layton +Reviewed-by: Yan, Zheng +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ceph/mds_client.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c +index 239bc9cba28c..f54f77037d22 100644 +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -644,6 +644,9 @@ static void __unregister_request(struct ceph_mds_client *mdsc, + { + dout("__unregister_request %p tid %lld\n", req, req->r_tid); + ++ /* Never leave an unregistered request on an unsafe list! */ ++ list_del_init(&req->r_unsafe_item); ++ + if (req->r_tid == mdsc->oldest_tid) { + struct rb_node *p = rb_next(&req->r_node); + mdsc->oldest_tid = 0; +@@ -1051,7 +1054,6 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc, + while (!list_empty(&session->s_unsafe)) { + req = list_first_entry(&session->s_unsafe, + struct ceph_mds_request, r_unsafe_item); +- list_del_init(&req->r_unsafe_item); + pr_warn_ratelimited(" dropping unsafe request %llu\n", + req->r_tid); + __unregister_request(mdsc, req); +@@ -2477,7 +2479,6 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) + * useful we could do with a revised return value. + */ + dout("got safe reply %llu, mds%d\n", tid, mds); +- list_del_init(&req->r_unsafe_item); + + /* last unsafe request during umount? */ + if (mdsc->stopping && !__get_oldest_req(mdsc)) +-- +2.12.2 + +From ca739e3fd7dc803d526ea5bb9b80c0d07fbca55f Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 22 Feb 2017 22:06:32 -0800 +Subject: [PATCH 020/251] target: Fix NULL dereference during LUN lookup + + active I/O shutdown +Content-Length: 6768 +Lines: 191 + +commit bd4e2d2907fa23a11d46217064ecf80470ddae10 upstream. + +When transport_clear_lun_ref() is shutting down a se_lun via +configfs with new I/O in-flight, it's possible to trigger a +NULL pointer dereference in transport_lookup_cmd_lun() due +to the fact percpu_ref_get() doesn't do any __PERCPU_REF_DEAD +checking before incrementing lun->lun_ref.count after +lun->lun_ref has switched to atomic_t mode. + +This results in a NULL pointer dereference as LUN shutdown +code in core_tpg_remove_lun() continues running after the +existing ->release() -> core_tpg_lun_ref_release() callback +completes, and clears the RCU protected se_lun->lun_se_dev +pointer. + +During the OOPs, the state of lun->lun_ref in the process +which triggered the NULL pointer dereference looks like +the following on v4.1.y stable code: + +struct se_lun { + lun_link_magic = 4294932337, + lun_status = TRANSPORT_LUN_STATUS_FREE, + + ..... + + lun_se_dev = 0x0, + lun_sep = 0x0, + + ..... + + lun_ref = { + count = { + counter = 1 + }, + percpu_count_ptr = 3, + release = 0xffffffffa02fa1e0 , + confirm_switch = 0x0, + force_atomic = false, + rcu = { + next = 0xffff88154fa1a5d0, + func = 0xffffffff8137c4c0 + } + } +} + +To address this bug, use percpu_ref_tryget_live() to ensure +once __PERCPU_REF_DEAD is visable on all CPUs and ->lun_ref +has switched to atomic_t, all new I/Os will fail to obtain +a new lun->lun_ref reference. + +Also use an explicit percpu_ref_kill_and_confirm() callback +to block on ->lun_ref_comp to allow the first stage and +associated RCU grace period to complete, and then block on +->lun_ref_shutdown waiting for the final percpu_ref_put() +to drop the last reference via transport_lun_remove_cmd() +before continuing with core_tpg_remove_lun() shutdown. + +Reported-by: Rob Millner +Tested-by: Rob Millner +Cc: Rob Millner +Tested-by: Vaibhav Tandon +Cc: Vaibhav Tandon +Tested-by: Bryant G. Ly +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman +--- + drivers/target/target_core_device.c | 10 ++++++++-- + drivers/target/target_core_tpg.c | 3 ++- + drivers/target/target_core_transport.c | 31 ++++++++++++++++++++++++++++++- + include/target/target_core_base.h | 1 + + 4 files changed, 41 insertions(+), 4 deletions(-) + +diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c +index 356c80fbb304..bb6a6c35324a 100644 +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -77,12 +77,16 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) + &deve->read_bytes); + + se_lun = rcu_dereference(deve->se_lun); ++ ++ if (!percpu_ref_tryget_live(&se_lun->lun_ref)) { ++ se_lun = NULL; ++ goto out_unlock; ++ } ++ + se_cmd->se_lun = rcu_dereference(deve->se_lun); + se_cmd->pr_res_key = deve->pr_res_key; + se_cmd->orig_fe_lun = unpacked_lun; + se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; +- +- percpu_ref_get(&se_lun->lun_ref); + se_cmd->lun_ref_active = true; + + if ((se_cmd->data_direction == DMA_TO_DEVICE) && +@@ -96,6 +100,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) + goto ref_dev; + } + } ++out_unlock: + rcu_read_unlock(); + + if (!se_lun) { +@@ -826,6 +831,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) + xcopy_lun = &dev->xcopy_lun; + rcu_assign_pointer(xcopy_lun->lun_se_dev, dev); + init_completion(&xcopy_lun->lun_ref_comp); ++ init_completion(&xcopy_lun->lun_shutdown_comp); + INIT_LIST_HEAD(&xcopy_lun->lun_deve_list); + INIT_LIST_HEAD(&xcopy_lun->lun_dev_link); + mutex_init(&xcopy_lun->lun_tg_pt_md_mutex); +diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c +index 028854cda97b..2794c6ec5c3c 100644 +--- a/drivers/target/target_core_tpg.c ++++ b/drivers/target/target_core_tpg.c +@@ -539,7 +539,7 @@ static void core_tpg_lun_ref_release(struct percpu_ref *ref) + { + struct se_lun *lun = container_of(ref, struct se_lun, lun_ref); + +- complete(&lun->lun_ref_comp); ++ complete(&lun->lun_shutdown_comp); + } + + int core_tpg_register( +@@ -666,6 +666,7 @@ struct se_lun *core_tpg_alloc_lun( + lun->lun_link_magic = SE_LUN_LINK_MAGIC; + atomic_set(&lun->lun_acl_count, 0); + init_completion(&lun->lun_ref_comp); ++ init_completion(&lun->lun_shutdown_comp); + INIT_LIST_HEAD(&lun->lun_deve_list); + INIT_LIST_HEAD(&lun->lun_dev_link); + atomic_set(&lun->lun_tg_pt_secondary_offline, 0); +diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c +index befe22744802..df2059984e14 100644 +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -2680,10 +2680,39 @@ void target_wait_for_sess_cmds(struct se_session *se_sess) + } + EXPORT_SYMBOL(target_wait_for_sess_cmds); + ++static void target_lun_confirm(struct percpu_ref *ref) ++{ ++ struct se_lun *lun = container_of(ref, struct se_lun, lun_ref); ++ ++ complete(&lun->lun_ref_comp); ++} ++ + void transport_clear_lun_ref(struct se_lun *lun) + { +- percpu_ref_kill(&lun->lun_ref); ++ /* ++ * Mark the percpu-ref as DEAD, switch to atomic_t mode, drop ++ * the initial reference and schedule confirm kill to be ++ * executed after one full RCU grace period has completed. ++ */ ++ percpu_ref_kill_and_confirm(&lun->lun_ref, target_lun_confirm); ++ /* ++ * The first completion waits for percpu_ref_switch_to_atomic_rcu() ++ * to call target_lun_confirm after lun->lun_ref has been marked ++ * as __PERCPU_REF_DEAD on all CPUs, and switches to atomic_t ++ * mode so that percpu_ref_tryget_live() lookup of lun->lun_ref ++ * fails for all new incoming I/O. ++ */ + wait_for_completion(&lun->lun_ref_comp); ++ /* ++ * The second completion waits for percpu_ref_put_many() to ++ * invoke ->release() after lun->lun_ref has switched to ++ * atomic_t mode, and lun->lun_ref.count has reached zero. ++ * ++ * At this point all target-core lun->lun_ref references have ++ * been dropped via transport_lun_remove_cmd(), and it's safe ++ * to proceed with the remaining LUN shutdown. ++ */ ++ wait_for_completion(&lun->lun_shutdown_comp); + } + + static bool +diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h +index 800fe16cc36f..ed66414b91f0 100644 +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -740,6 +740,7 @@ struct se_lun { + struct config_group lun_group; + struct se_port_stat_grps port_stat_grps; + struct completion lun_ref_comp; ++ struct completion lun_shutdown_comp; + struct percpu_ref lun_ref; + struct list_head lun_dev_link; + struct hlist_node link; +-- +2.12.2 + +From e1c924e85a937de5e1d0dd6c47f094b089952e0c Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sat, 11 Feb 2017 10:37:38 -0500 +Subject: [PATCH 021/251] nlm: Ensure callback code also checks that the files + match +Content-Length: 1237 +Lines: 31 + +commit 251af29c320d86071664f02c76f0d063a19fefdf upstream. + +It is not sufficient to just check that the lock pids match when +granting a callback, we also need to ensure that we're granting +the callback on the right file. + +Reported-by: Pankaj Singh +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/lockd/lockd.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h +index c15373894a42..b37dee3acaba 100644 +--- a/include/linux/lockd/lockd.h ++++ b/include/linux/lockd/lockd.h +@@ -355,7 +355,8 @@ static inline int nlm_privileged_requester(const struct svc_rqst *rqstp) + static inline int nlm_compare_locks(const struct file_lock *fl1, + const struct file_lock *fl2) + { +- return fl1->fl_pid == fl2->fl_pid ++ return file_inode(fl1->fl_file) == file_inode(fl2->fl_file) ++ && fl1->fl_pid == fl2->fl_pid + && fl1->fl_owner == fl2->fl_owner + && fl1->fl_start == fl2->fl_start + && fl1->fl_end == fl2->fl_end +-- +2.12.2 + +From 6ef213d6219456ea5e4df7d201b4a3384e06783b Mon Sep 17 00:00:00 2001 +From: Clemens Gruber +Date: Tue, 13 Dec 2016 16:52:50 +0100 +Subject: [PATCH 022/251] pwm: pca9685: Fix period change with same duty cycle +Content-Length: 1777 +Lines: 51 + +commit 8d254a340efb12b40c4c1ff25a48a4f48f7bbd6b upstream. + +When first implementing support for changing the output frequency, an +optimization was added to continue the PWM after changing the prescaler +without having to reprogram the ON and OFF registers for the duty cycle, +in case the duty cycle stayed the same. This was flawed, because we +compared the absolute value of the duty cycle in nanoseconds instead of +the ratio to the period. + +Fix the problem by removing the shortcut. + +Fixes: 01ec8472009c9 ("pwm-pca9685: Support changing the output frequency") +Signed-off-by: Clemens Gruber +Reviewed-by: Mika Westerberg +Signed-off-by: Thierry Reding +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pwm/pwm-pca9685.c | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c +index 117fccf7934a..01a6a83f625d 100644 +--- a/drivers/pwm/pwm-pca9685.c ++++ b/drivers/pwm/pwm-pca9685.c +@@ -65,7 +65,6 @@ + #define PCA9685_MAXCHAN 0x10 + + #define LED_FULL (1 << 4) +-#define MODE1_RESTART (1 << 7) + #define MODE1_SLEEP (1 << 4) + #define MODE2_INVRT (1 << 4) + #define MODE2_OUTDRV (1 << 2) +@@ -117,16 +116,6 @@ static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + udelay(500); + + pca->period_ns = period_ns; +- +- /* +- * If the duty cycle did not change, restart PWM with +- * the same duty cycle to period ratio and return. +- */ +- if (duty_ns == pca->duty_ns) { +- regmap_update_bits(pca->regmap, PCA9685_MODE1, +- MODE1_RESTART, 0x1); +- return 0; +- } + } else { + dev_err(chip->dev, + "prescaler not set: period out of bounds!\n"); +-- +2.12.2 + +From 21096328c97e707f2190b26a06d8b805551a543d Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 3 Jan 2017 09:37:34 -0800 +Subject: [PATCH 023/251] xtensa: move parse_tag_fdt out of #ifdef + CONFIG_BLK_DEV_INITRD +Content-Length: 1156 +Lines: 37 + +commit 4ab18701c66552944188dbcd0ce0012729baab84 upstream. + +FDT tag parsing is not related to whether BLK_DEV_INITRD is configured +or not, move it out of the corresponding #ifdef/#endif block. +This fixes passing external FDT to the kernel configured w/o +BLK_DEV_INITRD support. + +Signed-off-by: Max Filippov +Signed-off-by: Greg Kroah-Hartman +--- + arch/xtensa/kernel/setup.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c +index 9735691f37f1..49ccbd9022f6 100644 +--- a/arch/xtensa/kernel/setup.c ++++ b/arch/xtensa/kernel/setup.c +@@ -133,6 +133,8 @@ static int __init parse_tag_initrd(const bp_tag_t* tag) + + __tagtable(BP_TAG_INITRD, parse_tag_initrd); + ++#endif /* CONFIG_BLK_DEV_INITRD */ ++ + #ifdef CONFIG_OF + + static int __init parse_tag_fdt(const bp_tag_t *tag) +@@ -145,8 +147,6 @@ __tagtable(BP_TAG_FDT, parse_tag_fdt); + + #endif /* CONFIG_OF */ + +-#endif /* CONFIG_BLK_DEV_INITRD */ +- + static int __init parse_tag_cmdline(const bp_tag_t* tag) + { + strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE); +-- +2.12.2 + +From 8650af261d6c119062da542c70881653db0a0b20 Mon Sep 17 00:00:00 2001 +From: Matt Chen +Date: Sun, 22 Jan 2017 02:16:58 +0800 +Subject: [PATCH 024/251] mac80211: flush delayed work when entering suspend +Content-Length: 1043 +Lines: 34 + +commit a9e9200d8661c1a0be8c39f93deb383dc940de35 upstream. + +The issue was found when entering suspend and resume. +It triggers a warning in: +mac80211/key.c: ieee80211_enable_keys() +... +WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || + sdata->crypto_tx_tailroom_pending_dec); +... + +It points out sdata->crypto_tx_tailroom_pending_dec isn't cleaned up successfully +in a delayed_work during suspend. Add a flush_delayed_work to fix it. + +Signed-off-by: Matt Chen +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/pm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c +index 00a43a70e1fc..0402fa45b343 100644 +--- a/net/mac80211/pm.c ++++ b/net/mac80211/pm.c +@@ -168,6 +168,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) + break; + } + ++ flush_delayed_work(&sdata->dec_tailroom_needed_wk); + drv_remove_interface(local, sdata); + } + +-- +2.12.2 + +From 0d80ac62b609bce00b78a656b7cdde2d8f587345 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 10 Feb 2017 00:00:52 -0500 +Subject: [PATCH 025/251] drm/amdgpu: add more cases to DCE11 possible crtc + mask setup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1129 +Lines: 38 + +commit 4ce3bd45b351633f2a0512c587f7fcba2ce044e8 upstream. + +Add cases for asics with 3 and 5 crtcs. Fixes an artificial +limitation on asics with 3 or 5 crtcs. + +Fixes: +https://bugs.freedesktop.org/show_bug.cgi?id=99744 + +Reviewed-by: Michel Dänzer +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +index c161eeda417b..267749a94c5a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +@@ -3704,9 +3704,15 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev, + default: + encoder->possible_crtcs = 0x3; + break; ++ case 3: ++ encoder->possible_crtcs = 0x7; ++ break; + case 4: + encoder->possible_crtcs = 0xf; + break; ++ case 5: ++ encoder->possible_crtcs = 0x1f; ++ break; + case 6: + encoder->possible_crtcs = 0x3f; + break; +-- +2.12.2 + +From 8b787652386e26c7974092f11bd477126b0d53ce Mon Sep 17 00:00:00 2001 +From: "Y.C. Chen" +Date: Wed, 22 Feb 2017 15:10:50 +1100 +Subject: [PATCH 026/251] drm/ast: Fix test for VGA enabled +Content-Length: 1240 +Lines: 38 + +commit 905f21a49d388de3e99438235f3301cabf0c0ef4 upstream. + +The test to see if VGA was already enabled is doing an unnecessary +second test from a register that may or may not have been initialized +to a valid value. Remove it. + +Signed-off-by: Y.C. Chen +Signed-off-by: Benjamin Herrenschmidt +Acked-by: Joel Stanley +Tested-by: Y.C. Chen +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/ast/ast_post.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c +index 810c51d92b99..4e8aaab5dd52 100644 +--- a/drivers/gpu/drm/ast/ast_post.c ++++ b/drivers/gpu/drm/ast/ast_post.c +@@ -58,13 +58,9 @@ bool ast_is_vga_enabled(struct drm_device *dev) + /* TODO 1180 */ + } else { + ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); +- if (ch) { +- ast_open_key(ast); +- ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff); +- return ch & 0x04; +- } ++ return !!(ch & 0x01); + } +- return 0; ++ return false; + } + + static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff }; +-- +2.12.2 + +From 93eab4f5259485e9cad0339a298b6da1dd2e6e40 Mon Sep 17 00:00:00 2001 +From: "Y.C. Chen" +Date: Wed, 22 Feb 2017 15:14:19 +1100 +Subject: [PATCH 027/251] drm/ast: Call open_key before enable_mmio in POST + code +Content-Length: 1014 +Lines: 30 + +commit 9bb92f51558f2ef5f56c257bdcea0588f31d857e upstream. + +open_key enables access the registers used by enable_mmio + +Signed-off-by: Y.C. Chen +Signed-off-by: Benjamin Herrenschmidt +Acked-by: Joel Stanley +Tested-by: Y.C. Chen +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/ast/ast_post.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c +index 4e8aaab5dd52..50836e549867 100644 +--- a/drivers/gpu/drm/ast/ast_post.c ++++ b/drivers/gpu/drm/ast/ast_post.c +@@ -371,8 +371,8 @@ void ast_post_gpu(struct drm_device *dev) + pci_write_config_dword(ast->dev->pdev, 0x04, reg); + + ast_enable_vga(dev); +- ast_enable_mmio(dev); + ast_open_key(ast); ++ ast_enable_mmio(dev); + ast_set_def_ext_reg(dev); + + if (ast->chip == AST2300 || ast->chip == AST2400) +-- +2.12.2 + +From b9cfd5517b309513e50d80b89eaae98a82a2c3b1 Mon Sep 17 00:00:00 2001 +From: "Y.C. Chen" +Date: Thu, 23 Feb 2017 15:52:33 +0800 +Subject: [PATCH 028/251] drm/ast: Fix AST2400 POST failure without BMC FW or + VBIOS +Content-Length: 2034 +Lines: 70 + +commit 3856081eede297b617560b85e948cfb00bb395ec upstream. + +The current POST code for the AST2300/2400 family doesn't work properly +if the chip hasn't been initialized previously by either the BMC own FW +or the VBIOS. This fixes it. + +Signed-off-by: Y.C. Chen +Signed-off-by: Benjamin Herrenschmidt +Tested-by: Y.C. Chen +Acked-by: Joel Stanley +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/ast/ast_post.c | 38 +++++++++++++++++++++++++++++++++++--- + 1 file changed, 35 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c +index 50836e549867..30672a3df8a9 100644 +--- a/drivers/gpu/drm/ast/ast_post.c ++++ b/drivers/gpu/drm/ast/ast_post.c +@@ -1626,12 +1626,44 @@ static void ast_init_dram_2300(struct drm_device *dev) + temp |= 0x73; + ast_write32(ast, 0x12008, temp); + ++ param.dram_freq = 396; + param.dram_type = AST_DDR3; ++ temp = ast_mindwm(ast, 0x1e6e2070); + if (temp & 0x01000000) + param.dram_type = AST_DDR2; +- param.dram_chipid = ast->dram_type; +- param.dram_freq = ast->mclk; +- param.vram_size = ast->vram_size; ++ switch (temp & 0x18000000) { ++ case 0: ++ param.dram_chipid = AST_DRAM_512Mx16; ++ break; ++ default: ++ case 0x08000000: ++ param.dram_chipid = AST_DRAM_1Gx16; ++ break; ++ case 0x10000000: ++ param.dram_chipid = AST_DRAM_2Gx16; ++ break; ++ case 0x18000000: ++ param.dram_chipid = AST_DRAM_4Gx16; ++ break; ++ } ++ switch (temp & 0x0c) { ++ default: ++ case 0x00: ++ param.vram_size = AST_VIDMEM_SIZE_8M; ++ break; ++ ++ case 0x04: ++ param.vram_size = AST_VIDMEM_SIZE_16M; ++ break; ++ ++ case 0x08: ++ param.vram_size = AST_VIDMEM_SIZE_32M; ++ break; ++ ++ case 0x0c: ++ param.vram_size = AST_VIDMEM_SIZE_64M; ++ break; ++ } + + if (param.dram_type == AST_DDR3) { + get_ddr3_info(ast, ¶m); +-- +2.12.2 + +From 36fd36b900b9382af54a1e49a81cd99663b83eda Mon Sep 17 00:00:00 2001 +From: Tomeu Vizoso +Date: Mon, 20 Feb 2017 16:25:45 +0100 +Subject: [PATCH 029/251] drm/edid: Add EDID_QUIRK_FORCE_8BPC quirk for Rotel + RSX-1058 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1596 +Lines: 44 + +commit 36fc579761b50784b63dafd0f2e796b659e0f5ee upstream. + +Rotel RSX-1058 is a receiver with 4 HDMI inputs and a HDMI output, all +1.1. + +When a sink that supports deep color is connected to the output, the +receiver will send EDIDs that advertise this capability, even if it +isn't possible with HDMI versions earlier than 1.3. + +Currently the kernel is assuming that deep color is possible and the +sink displays an error. + +This quirk will make sure that deep color isn't used with this +particular receiver. + +Fixes: 7a0baa623446 ("Revert "drm/i915: Disable 12bpc hdmi for now"") +Signed-off-by: Tomeu Vizoso +Link: http://patchwork.freedesktop.org/patch/msgid/20170220152545.13153-1-tomeu.vizoso@collabora.com +Cc: Matt Horan +Tested-by: Matt Horan +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99869 +Reviewed-by: Ville Syrjälä +Signed-off-by: Ville Syrjälä +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_edid.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 8c9ac021608f..cc1e16fd7e76 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -144,6 +144,9 @@ static struct edid_quirk { + + /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */ + { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC }, ++ ++ /* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/ ++ { "ETR", 13896, EDID_QUIRK_FORCE_8BPC }, + }; + + /* +-- +2.12.2 + +From 59fc34fc69066bfabf8bed21f4ce5bf312e68bb3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +Date: Wed, 25 Jan 2017 17:21:31 +0900 +Subject: [PATCH 030/251] drm/ttm: Make sure BOs being swapped out are + cacheable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1580 +Lines: 44 + +commit 239ac65fa5ffab71adf66e642750f940e7241d99 upstream. + +The current caching state may not be tt_cached, even though the +placement contains TTM_PL_FLAG_CACHED, because placement can contain +multiple caching flags. Trying to swap out such a BO would trip up the + + BUG_ON(ttm->caching_state != tt_cached); + +in ttm_tt_swapout. + +Signed-off-by: Michel Dänzer +Reviewed-by: Thomas Hellstrom +Reviewed-by: Christian König . +Reviewed-by: Sinclair Yeh +Signed-off-by: Christian König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/ttm/ttm_bo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c +index 4ae8b56b1847..037c38bb5333 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -1621,7 +1621,6 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) + struct ttm_buffer_object *bo; + int ret = -EBUSY; + int put_count; +- uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM); + + spin_lock(&glob->lru_lock); + list_for_each_entry(bo, &glob->swap_lru, swap) { +@@ -1657,7 +1656,8 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) + if (unlikely(ret != 0)) + goto out; + +- if ((bo->mem.placement & swap_placement) != swap_placement) { ++ if (bo->mem.mem_type != TTM_PL_SYSTEM || ++ bo->ttm->caching_state != tt_cached) { + struct ttm_mem_reg evict_mem; + + evict_mem = bo->mem; +-- +2.12.2 + +From bb5b96344ed378a1d5b8cf3bd149bb86919f3b9f Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 8 Feb 2017 02:46:01 +0300 +Subject: [PATCH 031/251] drm/atomic: fix an error code in mode_fixup() +Content-Length: 1297 +Lines: 34 + +commit f9ad86e42d0303eeb8e0d41bb208153022ebd9d2 upstream. + +Having "ret" be a bool type works for everything except +ret = funcs->atomic_check(). The other functions all return zero on +error but ->atomic_check() returns negative error codes. We want to +propagate the error code but instead we return 1. + +I found this bug with static analysis and I don't know if it affects +run time. + +Fixes: 4cd4df8080a3 ("drm/atomic: Add ->atomic_check() to encoder helpers") +Signed-off-by: Dan Carpenter +Signed-off-by: Daniel Vetter +Link: http://patchwork.freedesktop.org/patch/msgid/20170207234601.GA23981@mwanda +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_atomic_helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index 1ac29d703c12..ea443fafb934 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -265,7 +265,7 @@ mode_fixup(struct drm_atomic_state *state) + struct drm_connector *connector; + struct drm_connector_state *conn_state; + int i; +- bool ret; ++ int ret; + + for_each_crtc_in_state(state, crtc, crtc_state, i) { + if (!crtc_state->mode_changed && +-- +2.12.2 + +From 77fec8bc7a0fbee3bf5893d8c1ce755c029f2b40 Mon Sep 17 00:00:00 2001 +From: Alexander Aring +Date: Thu, 1 Sep 2016 11:24:57 +0200 +Subject: [PATCH 032/251] fakelb: fix schedule while atomic +Content-Length: 2082 +Lines: 68 + +commit bdca1fd9a6df745857e23c6056494b7fe062b4e6 upstream. + +This patch changes the spinlock to mutex for the available fakelb phy +list. When holding the spinlock the ieee802154_unregister_hw is called +which holding the rtnl_mutex, in that case we get a "BUG: sleeping function +called from invalid context" error. We simple change the spinlock to +mutex which allows to hold the rtnl lock there. + +Signed-off-by: Alexander Aring +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ieee802154/fakelb.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c +index 860d4aed8274..43617ded3773 100644 +--- a/drivers/net/ieee802154/fakelb.c ++++ b/drivers/net/ieee802154/fakelb.c +@@ -30,7 +30,7 @@ + static int numlbs = 2; + + static LIST_HEAD(fakelb_phys); +-static DEFINE_SPINLOCK(fakelb_phys_lock); ++static DEFINE_MUTEX(fakelb_phys_lock); + + static LIST_HEAD(fakelb_ifup_phys); + static DEFINE_RWLOCK(fakelb_ifup_phys_lock); +@@ -180,9 +180,9 @@ static int fakelb_add_one(struct device *dev) + if (err) + goto err_reg; + +- spin_lock(&fakelb_phys_lock); ++ mutex_lock(&fakelb_phys_lock); + list_add_tail(&phy->list, &fakelb_phys); +- spin_unlock(&fakelb_phys_lock); ++ mutex_unlock(&fakelb_phys_lock); + + return 0; + +@@ -214,10 +214,10 @@ static int fakelb_probe(struct platform_device *pdev) + return 0; + + err_slave: +- spin_lock(&fakelb_phys_lock); ++ mutex_lock(&fakelb_phys_lock); + list_for_each_entry_safe(phy, tmp, &fakelb_phys, list) + fakelb_del(phy); +- spin_unlock(&fakelb_phys_lock); ++ mutex_unlock(&fakelb_phys_lock); + return err; + } + +@@ -225,10 +225,10 @@ static int fakelb_remove(struct platform_device *pdev) + { + struct fakelb_phy *phy, *tmp; + +- spin_lock(&fakelb_phys_lock); ++ mutex_lock(&fakelb_phys_lock); + list_for_each_entry_safe(phy, tmp, &fakelb_phys, list) + fakelb_del(phy); +- spin_unlock(&fakelb_phys_lock); ++ mutex_unlock(&fakelb_phys_lock); + return 0; + } + +-- +2.12.2 + +From 7952b6490bbce45e078c8c0e669df7a0a8f8948a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 2 Dec 2016 15:29:04 +0100 +Subject: [PATCH 033/251] drm/i915/dsi: Do not clear DPOUNIT_CLOCK_GATE_DISABLE + from vlv_init_display_clock_gating +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 2606 +Lines: 62 + +commit bb98e72adaf9d19719aba35f802d4836f5d5176c upstream. + +On my Cherrytrail CUBE iwork8 Air tablet PIPE-A would get stuck on loading +i915 at boot 1 out of every 3 boots, resulting in a non functional LCD. +Once the i915 driver has successfully loaded, the panel can be disabled / +enabled without hitting this issue. + +The getting stuck is caused by vlv_init_display_clock_gating() clearing +the DPOUNIT_CLOCK_GATE_DISABLE bit in DSPCLK_GATE_D when called from +chv_pipe_power_well_ops.enable() on driver load, while a pipe is enabled +driving the DSI LCD by the BIOS. + +Clearing this bit while DSI is in use is a known issue and +intel_dsi_pre_enable() / intel_dsi_post_disable() already set / clear it +as appropriate. + +This commit modifies vlv_init_display_clock_gating() to leave the +DPOUNIT_CLOCK_GATE_DISABLE bit alone fixing the pipe getting stuck. + +Changes in v2: +-Replace PIPE-A with "a pipe" or "the pipe" in the commit msg and +comment + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97330 +Signed-off-by: Hans de Goede +Reviewed-by: Ville Syrjälä +Link: http://patchwork.freedesktop.org/patch/msgid/20161202142904.25613-1-hdegoede@redhat.com +Signed-off-by: Ville Syrjälä +(cherry picked from commit 721d484563e1a51ada760089c490cbc47e909756) +Signed-off-by: Jani Nikula +Signed-off-by: River Zhou +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/intel_pm.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 3f802163f7d4..e7c18519274a 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -6803,7 +6803,18 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) + + static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv) + { +- I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); ++ u32 val; ++ ++ /* ++ * On driver load, a pipe may be active and driving a DSI display. ++ * Preserve DPOUNIT_CLOCK_GATE_DISABLE to avoid the pipe getting stuck ++ * (and never recovering) in this case. intel_dsi_post_disable() will ++ * clear it when we turn off the display. ++ */ ++ val = I915_READ(DSPCLK_GATE_D); ++ val &= DPOUNIT_CLOCK_GATE_DISABLE; ++ val |= VRHUNIT_CLOCK_GATE_DISABLE; ++ I915_WRITE(DSPCLK_GATE_D, val); + + /* + * Disable trickle feed and enable pnd deadline calculation +-- +2.12.2 + +From 13ef90e1bb7963ec2fb9d3680fe418a4b7dedfa3 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 16 Jan 2017 12:06:09 +0100 +Subject: [PATCH 034/251] libceph: use BUG() instead of BUG_ON(1) +Content-Length: 1071 +Lines: 34 + +commit d24cdcd3e40a6825135498e11c20c7976b9bf545 upstream. + +I ran into this compile warning, which is the result of BUG_ON(1) +not always leading to the compiler treating the code path as +unreachable: + + include/linux/ceph/osdmap.h: In function 'ceph_can_shift_osds': + include/linux/ceph/osdmap.h:62:1: error: control reaches end of non-void function [-Werror=return-type] + +Using BUG() here avoids the warning. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Ilya Dryomov +Cc: Heinrich Schuchardt +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/ceph/osdmap.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h +index e55c08bc3a96..0abc56140c83 100644 +--- a/include/linux/ceph/osdmap.h ++++ b/include/linux/ceph/osdmap.h +@@ -49,7 +49,7 @@ static inline bool ceph_can_shift_osds(struct ceph_pg_pool_info *pool) + case CEPH_POOL_TYPE_EC: + return false; + default: +- BUG_ON(1); ++ BUG(); + } + } + +-- +2.12.2 + +From 8353f338def1df3b58150cf1d6f42d1a51902b55 Mon Sep 17 00:00:00 2001 +From: OGAWA Hirofumi +Date: Thu, 9 Mar 2017 16:17:37 -0800 +Subject: [PATCH 035/251] fat: fix using uninitialized fields of + fat_inode/fsinfo_inode +Content-Length: 1922 +Lines: 59 + +commit c0d0e351285161a515396b7b1ee53ec9ffd97e3c upstream. + +Recently fallocate patch was merged and it uses +MSDOS_I(inode)->mmu_private at fat_evict_inode(). However, +fat_inode/fsinfo_inode that was introduced in past didn't initialize +MSDOS_I(inode) properly. + +With those combinations, it became the cause of accessing random entry +in FAT area. + +Link: http://lkml.kernel.org/r/87pohrj4i8.fsf@mail.parknet.co.jp +Signed-off-by: OGAWA Hirofumi +Reported-by: Moreno Bartalucci +Tested-by: Moreno Bartalucci +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + fs/fat/inode.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/fs/fat/inode.c b/fs/fat/inode.c +index 509411dd3698..cf644d52c0cf 100644 +--- a/fs/fat/inode.c ++++ b/fs/fat/inode.c +@@ -1269,6 +1269,16 @@ out: + return 0; + } + ++static void fat_dummy_inode_init(struct inode *inode) ++{ ++ /* Initialize this dummy inode to work as no-op. */ ++ MSDOS_I(inode)->mmu_private = 0; ++ MSDOS_I(inode)->i_start = 0; ++ MSDOS_I(inode)->i_logstart = 0; ++ MSDOS_I(inode)->i_attrs = 0; ++ MSDOS_I(inode)->i_pos = 0; ++} ++ + static int fat_read_root(struct inode *inode) + { + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); +@@ -1713,12 +1723,13 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, + fat_inode = new_inode(sb); + if (!fat_inode) + goto out_fail; +- MSDOS_I(fat_inode)->i_pos = 0; ++ fat_dummy_inode_init(fat_inode); + sbi->fat_inode = fat_inode; + + fsinfo_inode = new_inode(sb); + if (!fsinfo_inode) + goto out_fail; ++ fat_dummy_inode_init(fsinfo_inode); + fsinfo_inode->i_ino = MSDOS_FSINFO_INO; + sbi->fsinfo_inode = fsinfo_inode; + insert_inode_hash(fsinfo_inode); +-- +2.12.2 + +From 4cdfa660c82b57828ffcca94950eccc9458e18e4 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Wed, 8 Feb 2017 18:30:56 -0700 +Subject: [PATCH 036/251] drivers: hv: Turn off write permission on the + hypercall page +Content-Length: 977 +Lines: 29 + +commit 372b1e91343e657a7cc5e2e2bcecd5140ac28119 upstream. + +The hypercall page only needs to be executable but currently it is setup to +be writable as well. Fix the issue. + +Signed-off-by: K. Y. Srinivasan +Acked-by: Kees Cook +Reported-by: Stephen Hemminger +Tested-by: Stephen Hemminger +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hv/hv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c +index 89fd0113aa5c..57c191798699 100644 +--- a/drivers/hv/hv.c ++++ b/drivers/hv/hv.c +@@ -219,7 +219,7 @@ int hv_init(void) + /* See if the hypercall page is already set */ + rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); + +- virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); ++ virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX); + + if (!virtaddr) + goto cleanup; +-- +2.12.2 + +From 804a935963a91acd1764ba914f825dd2a29c5871 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 15 Mar 2017 09:57:56 +0800 +Subject: [PATCH 037/251] Linux 4.4.54 +Content-Length: 301 +Lines: 18 + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 10aec937e9e4..7f54ac081cf3 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 53 ++SUBLEVEL = 54 + EXTRAVERSION = + NAME = Blurry Fish Butt + +-- +2.12.2 + +From 4d95645f3dd5b1e8453d65220f604c39e822d990 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 31 Jan 2017 17:17:27 +0100 +Subject: [PATCH 038/251] USB: serial: digi_acceleport: fix OOB data sanity + check +Content-Length: 1827 +Lines: 49 + +commit 2d380889215fe20b8523345649dee0579821800c upstream. + +Make sure to check for short transfers to avoid underflow in a loop +condition when parsing the receive buffer. + +Also fix an off-by-one error in the incomplete sanity check which could +lead to invalid data being parsed. + +Fixes: 8c209e6782ca ("USB: make actual_length in struct urb field u32") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/digi_acceleport.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c +index 3df7b7ec178e..19c3bef426c3 100644 +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -1483,16 +1483,20 @@ static int digi_read_oob_callback(struct urb *urb) + struct usb_serial *serial = port->serial; + struct tty_struct *tty; + struct digi_port *priv = usb_get_serial_port_data(port); ++ unsigned char *buf = urb->transfer_buffer; + int opcode, line, status, val; + int i; + unsigned int rts; + ++ if (urb->actual_length < 4) ++ return -1; ++ + /* handle each oob command */ +- for (i = 0; i < urb->actual_length - 3;) { +- opcode = ((unsigned char *)urb->transfer_buffer)[i++]; +- line = ((unsigned char *)urb->transfer_buffer)[i++]; +- status = ((unsigned char *)urb->transfer_buffer)[i++]; +- val = ((unsigned char *)urb->transfer_buffer)[i++]; ++ for (i = 0; i < urb->actual_length - 4; i += 4) { ++ opcode = buf[i]; ++ line = buf[i + 1]; ++ status = buf[i + 2]; ++ val = buf[i + 3]; + + dev_dbg(&port->dev, "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d\n", + opcode, line, status, val); +-- +2.12.2 + +From a8cb5c02a20f04d947e386bdd958e1e80e920baa Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 24 Feb 2017 19:11:28 +0100 +Subject: [PATCH 039/251] USB: serial: digi_acceleport: fix OOB-event + processing +Content-Length: 1276 +Lines: 34 + +commit 2e46565cf622dd0534a9d8bffe152a577b48d7aa upstream. + +A recent change claimed to fix an off-by-one error in the OOB-port +completion handler, but instead introduced such an error. This could +specifically led to modem-status changes going unnoticed, effectively +breaking TIOCMGET. + +Note that the offending commit fixes a loop-condition underflow and is +marked for stable, but should not be backported without this fix. + +Reported-by: Ben Hutchings +Fixes: 2d380889215f ("USB: serial: digi_acceleport: fix OOB data sanity +check") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/digi_acceleport.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c +index 19c3bef426c3..e0b1fe2f60e1 100644 +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -1492,7 +1492,7 @@ static int digi_read_oob_callback(struct urb *urb) + return -1; + + /* handle each oob command */ +- for (i = 0; i < urb->actual_length - 4; i += 4) { ++ for (i = 0; i < urb->actual_length - 3; i += 4) { + opcode = buf[i]; + line = buf[i + 1]; + status = buf[i + 2]; +-- +2.12.2 + +From e041ad0664407c60a9d29217819f991933e10edd Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 3 Feb 2017 23:33:23 +0100 +Subject: [PATCH 040/251] crypto: improve gcc optimization flags for serpent + and wp512 +Content-Length: 6651 +Lines: 154 + +commit 7d6e9105026788c497f0ab32fa16c82f4ab5ff61 upstream. + +An ancient gcc bug (first reported in 2003) has apparently resurfaced +on MIPS, where kernelci.org reports an overly large stack frame in the +whirlpool hash algorithm: + +crypto/wp512.c:987:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=] + +With some testing in different configurations, I'm seeing large +variations in stack frames size up to 1500 bytes for what should have +around 300 bytes at most. I also checked the reference implementation, +which is essentially the same code but also comes with some test and +benchmarking infrastructure. + +It seems that recent compiler versions on at least arm, arm64 and powerpc +have a partial fix for this problem, but enabling "-fsched-pressure", but +even with that fix they suffer from the issue to a certain degree. Some +testing on arm64 shows that the time needed to hash a given amount of +data is roughly proportional to the stack frame size here, which makes +sense given that the wp512 implementation is doing lots of loads for +table lookups, and the problem with the overly large stack is a result +of doing a lot more loads and stores for spilled registers (as seen from +inspecting the object code). + +Disabling -fschedule-insns consistently fixes the problem for wp512, +in my collection of cross-compilers, the results are consistently better +or identical when comparing the stack sizes in this function, though +some architectures (notable x86) have schedule-insns disabled by +default. + +The four columns are: +default: -O2 +press: -O2 -fsched-pressure +nopress: -O2 -fschedule-insns -fno-sched-pressure +nosched: -O2 -no-schedule-insns (disables sched-pressure) + + default press nopress nosched +alpha-linux-gcc-4.9.3 1136 848 1136 176 +am33_2.0-linux-gcc-4.9.3 2100 2076 2100 2104 +arm-linux-gnueabi-gcc-4.9.3 848 848 1048 352 +cris-linux-gcc-4.9.3 272 272 272 272 +frv-linux-gcc-4.9.3 1128 1000 1128 280 +hppa64-linux-gcc-4.9.3 1128 336 1128 184 +hppa-linux-gcc-4.9.3 644 308 644 276 +i386-linux-gcc-4.9.3 352 352 352 352 +m32r-linux-gcc-4.9.3 720 656 720 268 +microblaze-linux-gcc-4.9.3 1108 604 1108 256 +mips64-linux-gcc-4.9.3 1328 592 1328 208 +mips-linux-gcc-4.9.3 1096 624 1096 240 +powerpc64-linux-gcc-4.9.3 1088 432 1088 160 +powerpc-linux-gcc-4.9.3 1080 584 1080 224 +s390-linux-gcc-4.9.3 456 456 624 360 +sh3-linux-gcc-4.9.3 292 292 292 292 +sparc64-linux-gcc-4.9.3 992 240 992 208 +sparc-linux-gcc-4.9.3 680 592 680 312 +x86_64-linux-gcc-4.9.3 224 240 272 224 +xtensa-linux-gcc-4.9.3 1152 704 1152 304 + +aarch64-linux-gcc-7.0.0 224 224 1104 208 +arm-linux-gnueabi-gcc-7.0.1 824 824 1048 352 +mips-linux-gcc-7.0.0 1120 648 1120 272 +x86_64-linux-gcc-7.0.1 240 240 304 240 + +arm-linux-gnueabi-gcc-4.4.7 840 392 +arm-linux-gnueabi-gcc-4.5.4 784 728 784 320 +arm-linux-gnueabi-gcc-4.6.4 736 728 736 304 +arm-linux-gnueabi-gcc-4.7.4 944 784 944 352 +arm-linux-gnueabi-gcc-4.8.5 464 464 760 352 +arm-linux-gnueabi-gcc-4.9.3 848 848 1048 352 +arm-linux-gnueabi-gcc-5.3.1 824 824 1064 336 +arm-linux-gnueabi-gcc-6.1.1 808 808 1056 344 +arm-linux-gnueabi-gcc-7.0.1 824 824 1048 352 + +Trying the same test for serpent-generic, the picture is a bit different, +and while -fno-schedule-insns is generally better here than the default, +-fsched-pressure wins overall, so I picked that instead. + + default press nopress nosched +alpha-linux-gcc-4.9.3 1392 864 1392 960 +am33_2.0-linux-gcc-4.9.3 536 524 536 528 +arm-linux-gnueabi-gcc-4.9.3 552 552 776 536 +cris-linux-gcc-4.9.3 528 528 528 528 +frv-linux-gcc-4.9.3 536 400 536 504 +hppa64-linux-gcc-4.9.3 524 208 524 480 +hppa-linux-gcc-4.9.3 768 472 768 508 +i386-linux-gcc-4.9.3 564 564 564 564 +m32r-linux-gcc-4.9.3 712 576 712 532 +microblaze-linux-gcc-4.9.3 724 392 724 512 +mips64-linux-gcc-4.9.3 720 384 720 496 +mips-linux-gcc-4.9.3 728 384 728 496 +powerpc64-linux-gcc-4.9.3 704 304 704 480 +powerpc-linux-gcc-4.9.3 704 296 704 480 +s390-linux-gcc-4.9.3 560 560 592 536 +sh3-linux-gcc-4.9.3 540 540 540 540 +sparc64-linux-gcc-4.9.3 544 352 544 496 +sparc-linux-gcc-4.9.3 544 344 544 496 +x86_64-linux-gcc-4.9.3 528 536 576 528 +xtensa-linux-gcc-4.9.3 752 544 752 544 + +aarch64-linux-gcc-7.0.0 432 432 656 480 +arm-linux-gnueabi-gcc-7.0.1 616 616 808 536 +mips-linux-gcc-7.0.0 720 464 720 488 +x86_64-linux-gcc-7.0.1 536 528 600 536 + +arm-linux-gnueabi-gcc-4.4.7 592 440 +arm-linux-gnueabi-gcc-4.5.4 776 448 776 544 +arm-linux-gnueabi-gcc-4.6.4 776 448 776 544 +arm-linux-gnueabi-gcc-4.7.4 768 448 768 544 +arm-linux-gnueabi-gcc-4.8.5 488 488 776 544 +arm-linux-gnueabi-gcc-4.9.3 552 552 776 536 +arm-linux-gnueabi-gcc-5.3.1 552 552 776 536 +arm-linux-gnueabi-gcc-6.1.1 560 560 776 536 +arm-linux-gnueabi-gcc-7.0.1 616 616 808 536 + +I did not do any runtime tests with serpent, so it is possible that stack +frame size does not directly correlate with runtime performance here and +it actually makes things worse, but it's more likely to help here, and +the reduced stack frame size is probably enough reason to apply the patch, +especially given that the crypto code is often used in deep call chains. + +Link: https://kernelci.org/build/id/58797d7559b5149efdf6c3a9/logs/ +Link: http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html +Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11488 +Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149 +Cc: Ralf Baechle +Signed-off-by: Arnd Bergmann +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + crypto/Makefile | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/crypto/Makefile b/crypto/Makefile +index 82fbff180ad3..03e66097eb0c 100644 +--- a/crypto/Makefile ++++ b/crypto/Makefile +@@ -62,6 +62,7 @@ obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o + obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o + obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o + obj-$(CONFIG_CRYPTO_WP512) += wp512.o ++CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149 + obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o + obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o + obj-$(CONFIG_CRYPTO_ECB) += ecb.o +@@ -85,6 +86,7 @@ obj-$(CONFIG_CRYPTO_BLOWFISH_COMMON) += blowfish_common.o + obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o + obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o + obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o ++CFLAGS_serpent_generic.o := $(call cc-option,-fsched-pressure) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149 + obj-$(CONFIG_CRYPTO_AES) += aes_generic.o + obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o + obj-$(CONFIG_CRYPTO_CAST_COMMON) += cast_common.o +-- +2.12.2 + +From adc48c710b7e3d0d169e013ca089f46347aaf064 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 11 Jan 2017 15:29:48 +0100 +Subject: [PATCH 041/251] MIPS: Update defconfigs for NF_CT_PROTO_DCCP/UDPLITE + change +Content-Length: 5304 +Lines: 136 + +commit 9ddc16ad8e0bc7742fc96d5aaabc5b8698512cd1 upstream. + +In linux-4.10-rc, NF_CT_PROTO_UDPLITE and NF_CT_PROTO_DCCP are bool +symbols instead of tristate, and kernelci.org reports a bunch of +warnings for this, like: + +arch/mips/configs/malta_kvm_guest_defconfig:63:warning: symbol value 'm' invalid for NF_CT_PROTO_UDPLITE +arch/mips/configs/malta_defconfig:62:warning: symbol value 'm' invalid for NF_CT_PROTO_DCCP +arch/mips/configs/malta_defconfig:63:warning: symbol value 'm' invalid for NF_CT_PROTO_UDPLITE +arch/mips/configs/ip22_defconfig:70:warning: symbol value 'm' invalid for NF_CT_PROTO_DCCP +arch/mips/configs/ip22_defconfig:71:warning: symbol value 'm' invalid for NF_CT_PROTO_UDPLITE + +This changes all the MIPS defconfigs with these symbols to have them +built-in. + +Fixes: 9b91c96c5d1f ("netfilter: conntrack: built-in support for UDPlite") +Fixes: c51d39010a1b ("netfilter: conntrack: built-in support for DCCP") +Signed-off-by: Arnd Bergmann +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/14999/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/configs/ip22_defconfig | 4 ++-- + arch/mips/configs/malta_defconfig | 4 ++-- + arch/mips/configs/malta_kvm_defconfig | 4 ++-- + arch/mips/configs/malta_kvm_guest_defconfig | 4 ++-- + arch/mips/configs/maltaup_xpa_defconfig | 4 ++-- + arch/mips/configs/nlm_xlp_defconfig | 2 +- + arch/mips/configs/nlm_xlr_defconfig | 2 +- + 7 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig +index 57ed466e00db..2f140d75d01c 100644 +--- a/arch/mips/configs/ip22_defconfig ++++ b/arch/mips/configs/ip22_defconfig +@@ -68,8 +68,8 @@ CONFIG_NETFILTER_NETLINK_QUEUE=m + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_DCCP=m +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_DCCP=y ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig +index 5afb4840aec7..739ccd0dca64 100644 +--- a/arch/mips/configs/malta_defconfig ++++ b/arch/mips/configs/malta_defconfig +@@ -59,8 +59,8 @@ CONFIG_NETFILTER=y + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_DCCP=m +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_DCCP=y ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig +index 98f13879bb8f..47f4ecf125ba 100644 +--- a/arch/mips/configs/malta_kvm_defconfig ++++ b/arch/mips/configs/malta_kvm_defconfig +@@ -60,8 +60,8 @@ CONFIG_NETFILTER=y + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_DCCP=m +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_DCCP=y ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig +index 3b5d5913f548..e79d325aa085 100644 +--- a/arch/mips/configs/malta_kvm_guest_defconfig ++++ b/arch/mips/configs/malta_kvm_guest_defconfig +@@ -59,8 +59,8 @@ CONFIG_NETFILTER=y + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_DCCP=m +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_DCCP=y ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig +index 732215732751..ae87ad86243b 100644 +--- a/arch/mips/configs/maltaup_xpa_defconfig ++++ b/arch/mips/configs/maltaup_xpa_defconfig +@@ -61,8 +61,8 @@ CONFIG_NETFILTER=y + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_DCCP=m +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_DCCP=y ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig +index b3d1d37f85ea..47492fee2952 100644 +--- a/arch/mips/configs/nlm_xlp_defconfig ++++ b/arch/mips/configs/nlm_xlp_defconfig +@@ -111,7 +111,7 @@ CONFIG_NETFILTER=y + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig +index 3d8016d6cf3e..472a818f1eb8 100644 +--- a/arch/mips/configs/nlm_xlr_defconfig ++++ b/arch/mips/configs/nlm_xlr_defconfig +@@ -91,7 +91,7 @@ CONFIG_NETFILTER=y + CONFIG_NF_CONNTRACK=m + CONFIG_NF_CONNTRACK_SECMARK=y + CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CT_PROTO_UDPLITE=y + CONFIG_NF_CONNTRACK_AMANDA=m + CONFIG_NF_CONNTRACK_FTP=m + CONFIG_NF_CONNTRACK_H323=m +-- +2.12.2 + +From 8ed0fdcc0c1157f49795913ab9fd3de768fad8f6 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 3 Feb 2017 17:43:50 +0100 +Subject: [PATCH 042/251] MIPS: ip27: Disable qlge driver in defconfig +Content-Length: 1534 +Lines: 41 + +commit b617649468390713db1515ea79fc772d2eb897a8 upstream. + +One of the last remaining failures in kernelci.org is for a gcc bug: + +drivers/net/ethernet/qlogic/qlge/qlge_main.c:4819:1: error: insn does not satisfy its constraints: +drivers/net/ethernet/qlogic/qlge/qlge_main.c:4819:1: internal compiler error: in extract_constrain_insn, at recog.c:2190 + +This is apparently broken in gcc-6 but fixed in gcc-7, and I cannot +reproduce the problem here. However, it is clear that ip27_defconfig +does not actually need this driver as the platform has only PCI-X but +not PCIe, and the qlge adapter in turn is PCIe-only. + +The driver was originally enabled in 2010 along with lots of other +drivers. + +Fixes: 59d302b342e5 ("MIPS: IP27: Make defconfig useful again.") +Signed-off-by: Arnd Bergmann +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15197/ +Signed-off-by: James Hogan +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/configs/ip27_defconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig +index 48e16d98b2cc..6ecc67f3736b 100644 +--- a/arch/mips/configs/ip27_defconfig ++++ b/arch/mips/configs/ip27_defconfig +@@ -206,7 +206,6 @@ CONFIG_MLX4_EN=m + # CONFIG_MLX4_DEBUG is not set + CONFIG_TEHUTI=m + CONFIG_BNX2X=m +-CONFIG_QLGE=m + CONFIG_SFC=m + CONFIG_BE2NET=m + CONFIG_LIBERTAS_THINFIRM=m +-- +2.12.2 + +From 7a6a965f350ec47171184898368a17b8228cdaf9 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 11 Jan 2017 15:29:50 +0100 +Subject: [PATCH 043/251] MIPS: Update ip27_defconfig for SCSI_DH change +Content-Length: 1140 +Lines: 35 + +commit ea58fca1842a5dc410cae4167b01643db971a4e2 upstream. + +Since linux-4.3, SCSI_DH is a bool symbol, causing a warning in +kernelci.org: + +arch/mips/configs/ip27_defconfig:136:warning: symbol value 'm' invalid for SCSI_DH + +This updates the defconfig to have the feature built-in. + +Fixes: 086b91d052eb ("scsi_dh: integrate into the core SCSI code") +Signed-off-by: Arnd Bergmann +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15001/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/configs/ip27_defconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig +index 6ecc67f3736b..b15508447366 100644 +--- a/arch/mips/configs/ip27_defconfig ++++ b/arch/mips/configs/ip27_defconfig +@@ -134,7 +134,7 @@ CONFIG_LIBFC=m + CONFIG_SCSI_QLOGIC_1280=y + CONFIG_SCSI_PMCRAID=m + CONFIG_SCSI_BFA_FC=m +-CONFIG_SCSI_DH=m ++CONFIG_SCSI_DH=y + CONFIG_SCSI_DH_RDAC=m + CONFIG_SCSI_DH_HP_SW=m + CONFIG_SCSI_DH_EMC=m +-- +2.12.2 + +From c018595d83a39dc4156f46ac21955778835e7781 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 17 Jan 2017 16:18:46 +0100 +Subject: [PATCH 044/251] MIPS: ip22: Fix ip28 build for modern gcc +Content-Length: 1395 +Lines: 37 + +commit 23ca9b522383d3b9b7991d8586db30118992af4a upstream. + +kernelci reports a failure of the ip28_defconfig build after upgrading its +gcc version: + +arch/mips/sgi-ip22/Platform:29: *** gcc doesn't support needed option -mr10k-cache-barrier=store. Stop. + +The problem apparently is that the -mr10k-cache-barrier=store option is now +rejected for CPUs other than r10k. Explicitly including the CPU in the +check fixes this and is safe because both options were introduced in +gcc-4.4. + +Signed-off-by: Arnd Bergmann +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15049/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/sgi-ip22/Platform | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/mips/sgi-ip22/Platform b/arch/mips/sgi-ip22/Platform +index b7a4b7e04c38..e8f6b3a42a48 100644 +--- a/arch/mips/sgi-ip22/Platform ++++ b/arch/mips/sgi-ip22/Platform +@@ -25,7 +25,7 @@ endif + # Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys + # + ifdef CONFIG_SGI_IP28 +- ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n) ++ ifeq ($(call cc-option-yn,-march=r10000 -mr10k-cache-barrier=store), n) + $(error gcc doesn't support needed option -mr10k-cache-barrier=store) + endif + endif +-- +2.12.2 + +From d2a8d746ae9530aeea0a3b4b129c970ffc90d926 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 11 Jan 2017 15:29:49 +0100 +Subject: [PATCH 045/251] MIPS: Update lemote2f_defconfig for CPU_FREQ_STAT + change +Content-Length: 1241 +Lines: 35 + +commit b3f6046186ef45acfeebc5a59c9fb45cefc685e7 upstream. + +Since linux-4.8, CPU_FREQ_STAT is a bool symbol, causing a warning in +kernelci.org: + +arch/mips/configs/lemote2f_defconfig:42:warning: symbol value 'm' invalid for CPU_FREQ_STAT + +This updates the defconfig to have the feature built-in. + +Fixes: 1aefc75b2449 ("cpufreq: stats: Make the stats code non-modular") +Signed-off-by: Arnd Bergmann +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15000/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/configs/lemote2f_defconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig +index 004cf52d1b7d..c24b87819ccb 100644 +--- a/arch/mips/configs/lemote2f_defconfig ++++ b/arch/mips/configs/lemote2f_defconfig +@@ -39,7 +39,7 @@ CONFIG_HIBERNATION=y + CONFIG_PM_STD_PARTITION="/dev/hda3" + CONFIG_CPU_FREQ=y + CONFIG_CPU_FREQ_DEBUG=y +-CONFIG_CPU_FREQ_STAT=m ++CONFIG_CPU_FREQ_STAT=y + CONFIG_CPU_FREQ_STAT_DETAILS=y + CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y + CONFIG_CPU_FREQ_GOV_POWERSAVE=m +-- +2.12.2 + +From 3dc8f1e3a8f2cd8481578689f49c586184f25eed Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 3 Feb 2017 10:49:17 +0100 +Subject: [PATCH 046/251] mtd: pmcmsp: use kstrndup instead of kmalloc+strncpy +Content-Length: 1377 +Lines: 40 + +commit 906b268477bc03daaa04f739844c120fe4dbc991 upstream. + +kernelci.org reports a warning for this driver, as it copies a local +variable into a 'const char *' string: + + drivers/mtd/maps/pmcmsp-flash.c:149:30: warning: passing argument 1 of 'strncpy' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] + +Using kstrndup() simplifies the code and avoids the warning. + +Signed-off-by: Arnd Bergmann +Acked-by: Marek Vasut +Signed-off-by: Brian Norris +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/maps/pmcmsp-flash.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c +index f9fa3fad728e..2051f28ddac6 100644 +--- a/drivers/mtd/maps/pmcmsp-flash.c ++++ b/drivers/mtd/maps/pmcmsp-flash.c +@@ -139,15 +139,13 @@ static int __init init_msp_flash(void) + } + + msp_maps[i].bankwidth = 1; +- msp_maps[i].name = kmalloc(7, GFP_KERNEL); ++ msp_maps[i].name = kstrndup(flash_name, 7, GFP_KERNEL); + if (!msp_maps[i].name) { + iounmap(msp_maps[i].virt); + kfree(msp_parts[i]); + goto cleanup_loop; + } + +- msp_maps[i].name = strncpy(msp_maps[i].name, flash_name, 7); +- + for (j = 0; j < pcnt; j++) { + part_name[5] = '0' + i; + part_name[7] = '0' + j; +-- +2.12.2 + +From 4b91e7a2a9a78b161caebfa5fcf6372a40161699 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 20 Dec 2016 19:12:46 +0100 +Subject: [PATCH 047/251] MIPS: ralink: Cosmetic change to prom_init(). +Content-Length: 1412 +Lines: 49 + +commit 9c48568b3692f1a56cbf1935e4eea835e6b185b1 upstream. + +Over the years the code has been changed various times leading to +argc/argv being defined in a different function to where we actually +use the variables. Clean this up by moving them to prom_init_cmdline(). + +Signed-off-by: John Crispin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14902/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/ralink/prom.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c +index 39a9142f71be..7ecb4af79b7b 100644 +--- a/arch/mips/ralink/prom.c ++++ b/arch/mips/ralink/prom.c +@@ -30,8 +30,10 @@ const char *get_system_type(void) + return soc_info.sys_type; + } + +-static __init void prom_init_cmdline(int argc, char **argv) ++static __init void prom_init_cmdline(void) + { ++ int argc; ++ char **argv; + int i; + + pr_debug("prom: fw_arg0=%08x fw_arg1=%08x fw_arg2=%08x fw_arg3=%08x\n", +@@ -60,14 +62,11 @@ static __init void prom_init_cmdline(int argc, char **argv) + + void __init prom_init(void) + { +- int argc; +- char **argv; +- + prom_soc_init(&soc_info); + + pr_info("SoC Type: %s\n", get_system_type()); + +- prom_init_cmdline(argc, argv); ++ prom_init_cmdline(); + } + + void __init prom_free_prom_memory(void) +-- +2.12.2 + +From 32883383f5e0c95436c2affaad675245727c0493 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 17 Jan 2017 16:18:43 +0100 +Subject: [PATCH 048/251] MIPS: ralink: Remove unused rt*_wdt_reset functions +Content-Length: 2704 +Lines: 91 + +commit 886f9c69fc68f56ddea34d3de51ac1fc2ac8dfbc upstream. + +All pointers to these functions were removed, so now they produce +warnings: + +arch/mips/ralink/rt305x.c:92:13: error: 'rt305x_wdt_reset' defined but not used [-Werror=unused-function] + +This removes the functions. If we need them again, the patch can be +reverted later. + +Fixes: f576fb6a0700 ("MIPS: ralink: cleanup the soc specific pinmux data") +Signed-off-by: Arnd Bergmann +Cc: John Crispin +Cc: Colin Ian King +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/15044/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/ralink/rt288x.c | 10 ---------- + arch/mips/ralink/rt305x.c | 11 ----------- + arch/mips/ralink/rt3883.c | 10 ---------- + 3 files changed, 31 deletions(-) + +diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c +index 844f5cd55c8f..15506a1ff22a 100644 +--- a/arch/mips/ralink/rt288x.c ++++ b/arch/mips/ralink/rt288x.c +@@ -40,16 +40,6 @@ static struct rt2880_pmx_group rt2880_pinmux_data_act[] = { + { 0 } + }; + +-static void rt288x_wdt_reset(void) +-{ +- u32 t; +- +- /* enable WDT reset output on pin SRAM_CS_N */ +- t = rt_sysc_r32(SYSC_REG_CLKCFG); +- t |= CLKCFG_SRAM_CS_N_WDT; +- rt_sysc_w32(t, SYSC_REG_CLKCFG); +-} +- + void __init ralink_clk_init(void) + { + unsigned long cpu_rate, wmac_rate = 40000000; +diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c +index 9e4572592065..15b32cd01906 100644 +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -89,17 +89,6 @@ static struct rt2880_pmx_group rt5350_pinmux_data[] = { + { 0 } + }; + +-static void rt305x_wdt_reset(void) +-{ +- u32 t; +- +- /* enable WDT reset output on pin SRAM_CS_N */ +- t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); +- t |= RT305X_SYSCFG_SRAM_CS0_MODE_WDT << +- RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT; +- rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); +-} +- + static unsigned long rt5350_get_mem_size(void) + { + void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); +diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c +index 582995aaaf4e..f42834c7f007 100644 +--- a/arch/mips/ralink/rt3883.c ++++ b/arch/mips/ralink/rt3883.c +@@ -63,16 +63,6 @@ static struct rt2880_pmx_group rt3883_pinmux_data[] = { + { 0 } + }; + +-static void rt3883_wdt_reset(void) +-{ +- u32 t; +- +- /* enable WDT reset output on GPIO 2 */ +- t = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1); +- t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT; +- rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); +-} +- + void __init ralink_clk_init(void) + { + unsigned long cpu_rate, sys_rate; +-- +2.12.2 + +From 5e45d834f762312e3031a8b6bba3bc2b1f9481ec Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 16 Jan 2017 14:20:54 +0100 +Subject: [PATCH 049/251] cpmac: remove hopeless #warning +Content-Length: 1108 +Lines: 32 + +commit d43e6fb4ac4abfe4ef7c102833ed02330ad701e0 upstream. + +The #warning was present 10 years ago when the driver first got merged. +As the platform is rather obsolete by now, it seems very unlikely that +the warning will cause anyone to fix the code properly. + +kernelci.org reports the warning for every build in the meantime, so +I think it's better to just turn it into a code comment to reduce +noise. + +Signed-off-by: Arnd Bergmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/ti/cpmac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c +index d52ea3008946..7e8bce46e6b4 100644 +--- a/drivers/net/ethernet/ti/cpmac.c ++++ b/drivers/net/ethernet/ti/cpmac.c +@@ -1237,7 +1237,7 @@ int cpmac_init(void) + goto fail_alloc; + } + +-#warning FIXME: unhardcode gpio&reset bits ++ /* FIXME: unhardcode gpio&reset bits */ + ar7_gpio_disable(26); + ar7_gpio_disable(27); + ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); +-- +2.12.2 + +From 5fad17434465a9e9ddddfb38a162e9e2e53e33a1 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 25 Aug 2016 15:17:08 -0700 +Subject: [PATCH 050/251] mm: memcontrol: avoid unused function warning +Content-Length: 2551 +Lines: 79 + +commit 358c07fcc3b60ab08d77f1684de8bd81bcf49a1a upstream. + +A bugfix in v4.8-rc2 introduced a harmless warning when +CONFIG_MEMCG_SWAP is disabled but CONFIG_MEMCG is enabled: + + mm/memcontrol.c:4085:27: error: 'mem_cgroup_id_get_online' defined but not used [-Werror=unused-function] + static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) + +This moves the function inside of the #ifdef block that hides the +calling function, to avoid the warning. + +Fixes: 1f47b61fb407 ("mm: memcontrol: fix swap counter leak on swapout from offline cgroup") +Link: http://lkml.kernel.org/r/20160824113733.2776701-1-arnd@arndb.de +Signed-off-by: Arnd Bergmann +Acked-by: Michal Hocko +Acked-by: Vladimir Davydov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + mm/memcontrol.c | 36 ++++++++++++++++++------------------ + 1 file changed, 18 insertions(+), 18 deletions(-) + +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index 43eefe9d834c..e25b93a4267d 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4150,24 +4150,6 @@ static void mem_cgroup_id_get_many(struct mem_cgroup *memcg, unsigned int n) + atomic_add(n, &memcg->id.ref); + } + +-static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) +-{ +- while (!atomic_inc_not_zero(&memcg->id.ref)) { +- /* +- * The root cgroup cannot be destroyed, so it's refcount must +- * always be >= 1. +- */ +- if (WARN_ON_ONCE(memcg == root_mem_cgroup)) { +- VM_BUG_ON(1); +- break; +- } +- memcg = parent_mem_cgroup(memcg); +- if (!memcg) +- memcg = root_mem_cgroup; +- } +- return memcg; +-} +- + static void mem_cgroup_id_put_many(struct mem_cgroup *memcg, unsigned int n) + { + if (atomic_sub_and_test(n, &memcg->id.ref)) { +@@ -5751,6 +5733,24 @@ static int __init mem_cgroup_init(void) + subsys_initcall(mem_cgroup_init); + + #ifdef CONFIG_MEMCG_SWAP ++static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) ++{ ++ while (!atomic_inc_not_zero(&memcg->id.ref)) { ++ /* ++ * The root cgroup cannot be destroyed, so it's refcount must ++ * always be >= 1. ++ */ ++ if (WARN_ON_ONCE(memcg == root_mem_cgroup)) { ++ VM_BUG_ON(1); ++ break; ++ } ++ memcg = parent_mem_cgroup(memcg); ++ if (!memcg) ++ memcg = root_mem_cgroup; ++ } ++ return memcg; ++} ++ + /** + * mem_cgroup_swapout - transfer a memsw charge to swap + * @page: page whose memsw charge to transfer +-- +2.12.2 + +From 2e4aff2405af6a4573299dee361a44903c9bb717 Mon Sep 17 00:00:00 2001 +From: Ralf Baechle +Date: Tue, 20 Sep 2016 14:33:01 +0200 +Subject: [PATCH 051/251] MIPS: DEC: Avoid la pseudo-instruction in delay slots +Content-Length: 2448 +Lines: 81 + +commit 3021773c7c3e75e20b693931a19362681e744ea9 upstream. + +When expanding the la or dla pseudo-instruction in a delay slot the GNU +assembler will complain should the pseudo-instruction expand to multiple +actual instructions, since only the first of them will be in the delay +slot leading to the pseudo-instruction being only partially executed if +the branch is taken. Use of PTR_LA in the dec int-handler.S leads to +such warnings: + + arch/mips/dec/int-handler.S: Assembler messages: + arch/mips/dec/int-handler.S:149: Warning: macro instruction expanded into multiple instructions in a branch delay slot + arch/mips/dec/int-handler.S:198: Warning: macro instruction expanded into multiple instructions in a branch delay slot + +Avoid this by open coding the PTR_LA macros. + +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/dec/int-handler.S | 40 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 38 insertions(+), 2 deletions(-) + +diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S +index 8c6f508e59de..554d1da97743 100644 +--- a/arch/mips/dec/int-handler.S ++++ b/arch/mips/dec/int-handler.S +@@ -146,7 +146,25 @@ + /* + * Find irq with highest priority + */ +- PTR_LA t1,cpu_mask_nr_tbl ++ # open coded PTR_LA t1, cpu_mask_nr_tbl ++#if (_MIPS_SZPTR == 32) ++ # open coded la t1, cpu_mask_nr_tbl ++ lui t1, %hi(cpu_mask_nr_tbl) ++ addiu t1, %lo(cpu_mask_nr_tbl) ++ ++#endif ++#if (_MIPS_SZPTR == 64) ++ # open coded dla t1, cpu_mask_nr_tbl ++ .set push ++ .set noat ++ lui t1, %highest(cpu_mask_nr_tbl) ++ lui AT, %hi(cpu_mask_nr_tbl) ++ daddiu t1, t1, %higher(cpu_mask_nr_tbl) ++ daddiu AT, AT, %lo(cpu_mask_nr_tbl) ++ dsll t1, 32 ++ daddu t1, t1, AT ++ .set pop ++#endif + 1: lw t2,(t1) + nop + and t2,t0 +@@ -195,7 +213,25 @@ + /* + * Find irq with highest priority + */ +- PTR_LA t1,asic_mask_nr_tbl ++ # open coded PTR_LA t1,asic_mask_nr_tbl ++#if (_MIPS_SZPTR == 32) ++ # open coded la t1, asic_mask_nr_tbl ++ lui t1, %hi(asic_mask_nr_tbl) ++ addiu t1, %lo(asic_mask_nr_tbl) ++ ++#endif ++#if (_MIPS_SZPTR == 64) ++ # open coded dla t1, asic_mask_nr_tbl ++ .set push ++ .set noat ++ lui t1, %highest(asic_mask_nr_tbl) ++ lui AT, %hi(asic_mask_nr_tbl) ++ daddiu t1, t1, %higher(asic_mask_nr_tbl) ++ daddiu AT, AT, %lo(asic_mask_nr_tbl) ++ dsll t1, 32 ++ daddu t1, t1, AT ++ .set pop ++#endif + 2: lw t2,(t1) + nop + and t2,t0 +-- +2.12.2 + +From 127651058594cafc624cf63bd266a42a62dfefcf Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Thu, 28 Apr 2016 17:06:16 +0100 +Subject: [PATCH 052/251] MIPS: Netlogic: Fix CP0_EBASE redefinition warnings +Content-Length: 3506 +Lines: 106 + +commit 32eb6e8bee147b45e5e59230630d59541ccbb6e5 upstream. + +A couple of netlogic assembly files define CP0_EBASE to $15, the same as +CP0_PRID in mipsregs.h, and use it for accessing both CP0_PRId and +CP0_EBase registers. However commit 609cf6f2291a ("MIPS: CPS: Early +debug using an ns16550-compatible UART") added a different definition of +CP0_EBASE to mipsregs.h, which included a register select of 1. This +causes harmless build warnings like the following: + + arch/mips/netlogic/common/reset.S:53:0: warning: "CP0_EBASE" redefined + #define CP0_EBASE $15 + ^ + In file included from arch/mips/netlogic/common/reset.S:41:0: + ./arch/mips/include/asm/mipsregs.h:63:0: note: this is the location of the previous definition + #define CP0_EBASE $15, 1 + ^ + +Update the code to use the definitions from mipsregs.h for accessing +both registers. + +Fixes: 609cf6f2291a ("MIPS: CPS: Early debug using an ns16550-compatible UART") +Signed-off-by: James Hogan +Acked-by: Jayachandran C +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/13183/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/netlogic/common/reset.S | 11 +++++------ + arch/mips/netlogic/common/smpboot.S | 4 +--- + 2 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/arch/mips/netlogic/common/reset.S b/arch/mips/netlogic/common/reset.S +index edbab9b8691f..c474981a6c0d 100644 +--- a/arch/mips/netlogic/common/reset.S ++++ b/arch/mips/netlogic/common/reset.S +@@ -50,7 +50,6 @@ + #include + #include + +-#define CP0_EBASE $15 + #define SYS_CPU_COHERENT_BASE CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \ + XLP_IO_SYS_OFFSET(0) + XLP_IO_PCI_HDRSZ + \ + SYS_CPU_NONCOHERENT_MODE * 4 +@@ -92,7 +91,7 @@ + * registers. On XLPII CPUs, usual cache instructions work. + */ + .macro xlp_flush_l1_dcache +- mfc0 t0, CP0_EBASE, 0 ++ mfc0 t0, CP0_PRID + andi t0, t0, PRID_IMP_MASK + slt t1, t0, 0x1200 + beqz t1, 15f +@@ -171,7 +170,7 @@ FEXPORT(nlm_reset_entry) + nop + + 1: /* Entry point on core wakeup */ +- mfc0 t0, CP0_EBASE, 0 /* processor ID */ ++ mfc0 t0, CP0_PRID /* processor ID */ + andi t0, PRID_IMP_MASK + li t1, 0x1500 /* XLP 9xx */ + beq t0, t1, 2f /* does not need to set coherent */ +@@ -182,8 +181,8 @@ FEXPORT(nlm_reset_entry) + nop + + /* set bit in SYS coherent register for the core */ +- mfc0 t0, CP0_EBASE, 1 +- mfc0 t1, CP0_EBASE, 1 ++ mfc0 t0, CP0_EBASE ++ mfc0 t1, CP0_EBASE + srl t1, 5 + andi t1, 0x3 /* t1 <- node */ + li t2, 0x40000 +@@ -232,7 +231,7 @@ EXPORT(nlm_boot_siblings) + + * NOTE: All GPR contents are lost after the mtcr above! + */ +- mfc0 v0, CP0_EBASE, 1 ++ mfc0 v0, CP0_EBASE + andi v0, 0x3ff /* v0 <- node/core */ + + /* +diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S +index 805355b0bd05..f0cc4c9de2bb 100644 +--- a/arch/mips/netlogic/common/smpboot.S ++++ b/arch/mips/netlogic/common/smpboot.S +@@ -48,8 +48,6 @@ + #include + #include + +-#define CP0_EBASE $15 +- + .set noreorder + .set noat + .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */ +@@ -86,7 +84,7 @@ NESTED(nlm_boot_secondary_cpus, 16, sp) + PTR_L gp, 0(t1) + + /* a0 has the processor id */ +- mfc0 a0, CP0_EBASE, 1 ++ mfc0 a0, CP0_EBASE + andi a0, 0x3ff /* a0 <- node/core */ + PTR_LA t0, nlm_early_init_secondary + jalr t0 +-- +2.12.2 + +From 074893495b72c043a108797ffd6297db3e4af1dc Mon Sep 17 00:00:00 2001 +From: Rik van Riel +Date: Wed, 28 Sep 2016 22:55:54 -0400 +Subject: [PATCH 053/251] tracing: Add #undef to fix compile error +Content-Length: 1319 +Lines: 35 + +commit bf7165cfa23695c51998231c4efa080fe1d3548d upstream. + +There are several trace include files that define TRACE_INCLUDE_FILE. + +Include several of them in the same .c file (as I currently have in +some code I am working on), and the compile will blow up with a +"warning: "TRACE_INCLUDE_FILE" redefined #define TRACE_INCLUDE_FILE syscalls" + +Every other include file in include/trace/events/ avoids that issue +by having a #undef TRACE_INCLUDE_FILE before the #define; syscalls.h +should have one, too. + +Link: http://lkml.kernel.org/r/20160928225554.13bd7ac6@annuminas.surriel.com + +Fixes: b8007ef74222 ("tracing: Separate raw syscall from syscall tracer") +Signed-off-by: Rik van Riel +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman +--- + include/trace/events/syscalls.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/trace/events/syscalls.h b/include/trace/events/syscalls.h +index 14e49c798135..b35533b94277 100644 +--- a/include/trace/events/syscalls.h ++++ b/include/trace/events/syscalls.h +@@ -1,5 +1,6 @@ + #undef TRACE_SYSTEM + #define TRACE_SYSTEM raw_syscalls ++#undef TRACE_INCLUDE_FILE + #define TRACE_INCLUDE_FILE syscalls + + #if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ) +-- +2.12.2 + +From 2ca39d1300152e70977797c3e39c105adfcc0e0b Mon Sep 17 00:00:00 2001 +From: Ravi Bangoria +Date: Tue, 14 Feb 2017 14:46:42 +0530 +Subject: [PATCH 054/251] powerpc: Emulation support for load/store + instructions on LE +Content-Length: 3197 +Lines: 106 + +commit e148bd17f48bd17fca2f4f089ec879fa6e47e34c upstream. + +emulate_step() uses a number of underlying kernel functions that were +initially not enabled for LE. This has been rectified since. So, fix +emulate_step() for LE for the corresponding instructions. + +Reported-by: Anton Blanchard +Signed-off-by: Ravi Bangoria +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/lib/sstep.c | 20 -------------------- + 1 file changed, 20 deletions(-) + +diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c +index dc885b30f7a6..4014881e9843 100644 +--- a/arch/powerpc/lib/sstep.c ++++ b/arch/powerpc/lib/sstep.c +@@ -1806,8 +1806,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) + goto instr_done; + + case LARX: +- if (regs->msr & MSR_LE) +- return 0; + if (op.ea & (size - 1)) + break; /* can't handle misaligned */ + err = -EFAULT; +@@ -1829,8 +1827,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) + goto ldst_done; + + case STCX: +- if (regs->msr & MSR_LE) +- return 0; + if (op.ea & (size - 1)) + break; /* can't handle misaligned */ + err = -EFAULT; +@@ -1854,8 +1850,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) + goto ldst_done; + + case LOAD: +- if (regs->msr & MSR_LE) +- return 0; + err = read_mem(®s->gpr[op.reg], op.ea, size, regs); + if (!err) { + if (op.type & SIGNEXT) +@@ -1867,8 +1861,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) + + #ifdef CONFIG_PPC_FPU + case LOAD_FP: +- if (regs->msr & MSR_LE) +- return 0; + if (size == 4) + err = do_fp_load(op.reg, do_lfs, op.ea, size, regs); + else +@@ -1877,15 +1869,11 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) + #endif + #ifdef CONFIG_ALTIVEC + case LOAD_VMX: +- if (regs->msr & MSR_LE) +- return 0; + err = do_vec_load(op.reg, do_lvx, op.ea & ~0xfUL, regs); + goto ldst_done; + #endif + #ifdef CONFIG_VSX + case LOAD_VSX: +- if (regs->msr & MSR_LE) +- return 0; + err = do_vsx_load(op.reg, do_lxvd2x, op.ea, regs); + goto ldst_done; + #endif +@@ -1908,8 +1896,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) + goto instr_done; + + case STORE: +- if (regs->msr & MSR_LE) +- return 0; + if ((op.type & UPDATE) && size == sizeof(long) && + op.reg == 1 && op.update_reg == 1 && + !(regs->msr & MSR_PR) && +@@ -1922,8 +1908,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) + + #ifdef CONFIG_PPC_FPU + case STORE_FP: +- if (regs->msr & MSR_LE) +- return 0; + if (size == 4) + err = do_fp_store(op.reg, do_stfs, op.ea, size, regs); + else +@@ -1932,15 +1916,11 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) + #endif + #ifdef CONFIG_ALTIVEC + case STORE_VMX: +- if (regs->msr & MSR_LE) +- return 0; + err = do_vec_store(op.reg, do_stvx, op.ea & ~0xfUL, regs); + goto ldst_done; + #endif + #ifdef CONFIG_VSX + case STORE_VSX: +- if (regs->msr & MSR_LE) +- return 0; + err = do_vsx_store(op.reg, do_stxvd2x, op.ea, regs); + goto ldst_done; + #endif +-- +2.12.2 + +From f47b97f2cdaa42b211299bac93d0a2ba0f617b9e Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Tue, 28 Feb 2017 14:25:45 +0800 +Subject: [PATCH 055/251] usb: gadget: dummy_hcd: clear usb_gadget region + before registration +Content-Length: 4651 +Lines: 77 + +commit 5bbc852676ae08e818241cf66a3ffe4be44225c4 upstream. + +When the user does device unbind and rebind test, the kernel will +show below dump due to usb_gadget memory region is dirty after unbind. +Clear usb_gadget region for every new probe. + +root@imx6qdlsolo:/sys/bus/platform/drivers/dummy_udc# echo dummy_udc.0 > bind +[ 102.523312] kobject (eddd78b0): tried to init an initialized object, something is seriously wrong. +[ 102.532447] CPU: 0 PID: 734 Comm: sh Not tainted 4.10.0-rc7-00872-g1b2b8e9 #1298 +[ 102.539866] Hardware name: Freescale i.MX6 SoloX (Device Tree) +[ 102.545717] Backtrace: +[ 102.548225] [] (dump_backtrace) from [] (show_stack+0x18/0x1c) +[ 102.555822] r7:ede34000 r6:60010013 r5:00000000 r4:c0f29418 +[ 102.561512] [] (show_stack) from [] (dump_stack+0xb4/0xe8) +[ 102.568764] [] (dump_stack) from [] (kobject_init+0x80/0x9c) +[ 102.576187] r10:0000001f r9:eddd7000 r8:eeaf8c10 r7:eddd78a8 r6:c177891c r5:c0f3b060 +[ 102.584036] r4:eddd78b0 r3:00000000 +[ 102.587641] [] (kobject_init) from [] (device_initialize+0x28/0xf8) +[ 102.595665] r5:eebc4800 r4:eddd78a8 +[ 102.599268] [] (device_initialize) from [] (device_register+0x14/0x20) +[ 102.607556] r7:eddd78a8 r6:00000000 r5:eebc4800 r4:eddd78a8 +[ 102.613256] [] (device_register) from [] (usb_add_gadget_udc_release+0x8c/0x1ec) +[ 102.622410] r5:eebc4800 r4:eddd7860 +[ 102.626015] [] (usb_add_gadget_udc_release) from [] (usb_add_gadget_udc+0x14/0x18) +[ 102.635351] r10:0000001f r9:eddd7000 r8:eddd788c r7:bf003770 r6:eddd77f8 r5:eddd7818 +[ 102.643198] r4:eddd785c r3:eddd7b24 +[ 102.646834] [] (usb_add_gadget_udc) from [] (dummy_udc_probe+0x170/0x1c4 [dummy_hcd]) +[ 102.656458] [] (dummy_udc_probe [dummy_hcd]) from [] (platform_drv_probe+0x54/0xb8) +[ 102.665881] r10:00000008 r9:c1778960 r8:bf004128 r7:fffffdfb r6:bf004128 r5:eeaf8c10 +[ 102.673727] r4:eeaf8c10 +[ 102.676293] [] (platform_drv_probe) from [] (driver_probe_device+0x264/0x474) +[ 102.685186] r7:00000000 r6:00000000 r5:c1778960 r4:eeaf8c10 +[ 102.690876] [] (driver_probe_device) from [] (bind_store+0xb8/0x14c) +[ 102.698994] r10:eeb3bb4c r9:ede34000 r8:0000000c r7:eeaf8c44 r6:bf004128 r5:c0f3b668 +[ 102.706840] r4:eeaf8c10 +[ 102.709402] [] (bind_store) from [] (drv_attr_store+0x28/0x34) +[ 102.716998] r9:ede34000 r8:00000000 r7:ee3863c0 r6:ee3863c0 r5:c0538c80 r4:c053970c +[ 102.724776] [] (drv_attr_store) from [] (sysfs_kf_write+0x50/0x54) +[ 102.732711] r5:c0538c80 r4:0000000c +[ 102.736313] [] (sysfs_kf_write) from [] (kernfs_fop_write+0x100/0x214) +[ 102.744599] r7:ee3863c0 r6:eeb3bb40 r5:00000000 r4:00000000 +[ 102.750287] [] (kernfs_fop_write) from [] (__vfs_write+0x34/0x120) +[ 102.758231] r10:00000000 r9:ede34000 r8:c0108bc4 r7:0000000c r6:ede35f80 r5:c029bd84 +[ 102.766077] r4:ee223780 +[ 102.768638] [] (__vfs_write) from [] (vfs_write+0xa8/0x170) +[ 102.775974] r9:ede34000 r8:c0108bc4 r7:ede35f80 r6:01861cb0 r5:ee223780 r4:0000000c +[ 102.783743] [] (vfs_write) from [] (SyS_write+0x4c/0xa8) +[ 102.790818] r9:ede34000 r8:c0108bc4 r7:0000000c r6:01861cb0 r5:ee223780 r4:ee223780 +[ 102.798595] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x1c) +[ 102.806188] r7:00000004 r6:b6e83d58 r5:01861cb0 r4:0000000c + +Fixes: 90fccb529d24 ("usb: gadget: Gadget directory cleanup - group UDC drivers") +Acked-by: Alan Stern +Signed-off-by: Peter Chen +Tested-by: Xiaolong Ye +Reported-by: Fengguang Wu +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c +index 22d067cd5aa3..6610f7a023d3 100644 +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -1033,6 +1033,8 @@ static int dummy_udc_probe(struct platform_device *pdev) + int rc; + + dum = *((void **)dev_get_platdata(&pdev->dev)); ++ /* Clear usb_gadget region for new registration to udc-core */ ++ memzero_explicit(&dum->gadget, sizeof(struct usb_gadget)); + dum->gadget.name = gadget_name; + dum->gadget.ops = &dummy_ops; + dum->gadget.max_speed = USB_SPEED_SUPER; +-- +2.12.2 + +From 10af2485650387d928ad00ec7843d66b5b2a705f Mon Sep 17 00:00:00 2001 +From: Felipe Balbi +Date: Tue, 31 Jan 2017 13:24:54 +0200 +Subject: [PATCH 056/251] usb: dwc3: gadget: make Set Endpoint Configuration + macros safe +Content-Length: 2326 +Lines: 57 + +commit 7369090a9fb57c3fc705ce355d2e4523a5a24716 upstream. + +Some gadget drivers are bad, bad boys. We notice +that ADB was passing bad Burst Size which caused top +bits of param0 to be overwritten which confused DWC3 +when running this command. + +In order to avoid future issues, we're going to make +sure values passed by macros are always safe for the +controller. Note that ADB still needs a fix to *not* +pass bad values. + +Reported-by: Mohamed Abbas +Sugested-by: Adam Andruszak +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.h | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h +index 18ae3eaa8b6f..ccd9694f8e36 100644 +--- a/drivers/usb/dwc3/gadget.h ++++ b/drivers/usb/dwc3/gadget.h +@@ -28,23 +28,23 @@ struct dwc3; + #define gadget_to_dwc(g) (container_of(g, struct dwc3, gadget)) + + /* DEPCFG parameter 1 */ +-#define DWC3_DEPCFG_INT_NUM(n) ((n) << 0) ++#define DWC3_DEPCFG_INT_NUM(n) (((n) & 0x1f) << 0) + #define DWC3_DEPCFG_XFER_COMPLETE_EN (1 << 8) + #define DWC3_DEPCFG_XFER_IN_PROGRESS_EN (1 << 9) + #define DWC3_DEPCFG_XFER_NOT_READY_EN (1 << 10) + #define DWC3_DEPCFG_FIFO_ERROR_EN (1 << 11) + #define DWC3_DEPCFG_STREAM_EVENT_EN (1 << 13) +-#define DWC3_DEPCFG_BINTERVAL_M1(n) ((n) << 16) ++#define DWC3_DEPCFG_BINTERVAL_M1(n) (((n) & 0xff) << 16) + #define DWC3_DEPCFG_STREAM_CAPABLE (1 << 24) +-#define DWC3_DEPCFG_EP_NUMBER(n) ((n) << 25) ++#define DWC3_DEPCFG_EP_NUMBER(n) (((n) & 0x1f) << 25) + #define DWC3_DEPCFG_BULK_BASED (1 << 30) + #define DWC3_DEPCFG_FIFO_BASED (1 << 31) + + /* DEPCFG parameter 0 */ +-#define DWC3_DEPCFG_EP_TYPE(n) ((n) << 1) +-#define DWC3_DEPCFG_MAX_PACKET_SIZE(n) ((n) << 3) +-#define DWC3_DEPCFG_FIFO_NUMBER(n) ((n) << 17) +-#define DWC3_DEPCFG_BURST_SIZE(n) ((n) << 22) ++#define DWC3_DEPCFG_EP_TYPE(n) (((n) & 0x3) << 1) ++#define DWC3_DEPCFG_MAX_PACKET_SIZE(n) (((n) & 0x7ff) << 3) ++#define DWC3_DEPCFG_FIFO_NUMBER(n) (((n) & 0x1f) << 17) ++#define DWC3_DEPCFG_BURST_SIZE(n) (((n) & 0xf) << 22) + #define DWC3_DEPCFG_DATA_SEQ_NUM(n) ((n) << 26) + /* This applies for core versions earlier than 1.94a */ + #define DWC3_DEPCFG_IGN_SEQ_NUM (1 << 31) +-- +2.12.2 + +From 4a1a3bb70fb4255a9f6052eb86db1ff2140255a6 Mon Sep 17 00:00:00 2001 +From: Felipe Balbi +Date: Tue, 31 Jan 2017 14:54:45 +0200 +Subject: [PATCH 057/251] usb: gadget: function: f_fs: pass companion + descriptor along +Content-Length: 1743 +Lines: 53 + +commit 2bfa0719ac2a9b2f3c91345873d3cdebd0296ba9 upstream. + +If we're dealing with SuperSpeed endpoints, we need +to make sure to pass along the companion descriptor +and initialize fields needed by the Gadget +API. Eventually, f_fs.c should be converted to use +config_ep_by_speed() like all other functions, +though. + +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_fs.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index cfda1a1c0ab6..9ad5145d3103 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -1643,11 +1643,14 @@ static int ffs_func_eps_enable(struct ffs_function *func) + spin_lock_irqsave(&func->ffs->eps_lock, flags); + do { + struct usb_endpoint_descriptor *ds; ++ struct usb_ss_ep_comp_descriptor *comp_desc = NULL; ++ int needs_comp_desc = false; + int desc_idx; + +- if (ffs->gadget->speed == USB_SPEED_SUPER) ++ if (ffs->gadget->speed == USB_SPEED_SUPER) { + desc_idx = 2; +- else if (ffs->gadget->speed == USB_SPEED_HIGH) ++ needs_comp_desc = true; ++ } else if (ffs->gadget->speed == USB_SPEED_HIGH) + desc_idx = 1; + else + desc_idx = 0; +@@ -1664,6 +1667,14 @@ static int ffs_func_eps_enable(struct ffs_function *func) + + ep->ep->driver_data = ep; + ep->ep->desc = ds; ++ ++ comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds + ++ USB_DT_ENDPOINT_SIZE); ++ ep->ep->maxburst = comp_desc->bMaxBurst + 1; ++ ++ if (needs_comp_desc) ++ ep->ep->comp_desc = comp_desc; ++ + ret = usb_ep_enable(ep->ep); + if (likely(!ret)) { + epfile->ep = ep; +-- +2.12.2 + +From 40c5634ffe3dd484d633dafc1d32e0c87d67d23a Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Thu, 9 Mar 2017 15:39:36 +0200 +Subject: [PATCH 058/251] usb: host: xhci-dbg: HCIVERSION should be a binary + number +Content-Length: 1211 +Lines: 30 + +commit f95e60a7dbecd2de816bb3ad517b3d4fbc20b507 upstream. + +According to xHCI spec, HCIVERSION containing a BCD encoding +of the xHCI specification revision number, 0100h corresponds +to xHCI version 1.0. Change "100" as "0x100". + +Cc: Lu Baolu +Fixes: 04abb6de2825 ("xhci: Read and parse new xhci 1.1 capability register") +Signed-off-by: Peter Chen +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c +index 74c42f722678..3425154baf8b 100644 +--- a/drivers/usb/host/xhci-dbg.c ++++ b/drivers/usb/host/xhci-dbg.c +@@ -111,7 +111,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci) + xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK); + + /* xhci 1.1 controllers have the HCCPARAMS2 register */ +- if (hci_version > 100) { ++ if (hci_version > 0x100) { + temp = readl(&xhci->cap_regs->hcc_params2); + xhci_dbg(xhci, "HCC PARAMS2 0x%x:\n", (unsigned int) temp); + xhci_dbg(xhci, " HC %s Force save context capability", +-- +2.12.2 + +From cf09c7d60ccc8189cd8e313ae83b8d377fa67359 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Thu, 9 Mar 2017 15:39:37 +0200 +Subject: [PATCH 059/251] usb: host: xhci-plat: Fix timeout on removal of hot + pluggable xhci controllers +Content-Length: 1413 +Lines: 38 + +commit dcc7620cad5ad1326a78f4031a7bf4f0e5b42984 upstream. + +Upstream commit 98d74f9ceaef ("xhci: fix 10 second timeout on removal of +PCI hotpluggable xhci controllers") fixes a problem with hot pluggable PCI +xhci controllers which can result in excessive timeouts, to the point where +the system reports a deadlock. + +The same problem is seen with hot pluggable xhci controllers using the +xhci-plat driver, such as the driver used for Type-C ports on rk3399. +Similar to hot-pluggable PCI controllers, the driver for this chip +removes the xhci controller from the system when the Type-C cable is +disconnected. + +The solution for PCI devices works just as well for non-PCI devices +and avoids the problem. + +Signed-off-by: Guenter Roeck +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-plat.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index 19cb32a65161..268829db9e88 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -213,6 +213,8 @@ static int xhci_plat_remove(struct platform_device *dev) + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct clk *clk = xhci->clk; + ++ xhci->xhc_state |= XHCI_STATE_REMOVING; ++ + usb_remove_hcd(xhci->shared_hcd); + usb_phy_shutdown(hcd->usb_phy); + +-- +2.12.2 + +From 3cdc94638746eab168accf0f808a83e59fe1ca67 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 6 Mar 2017 17:36:41 +0100 +Subject: [PATCH 060/251] USB: serial: safe_serial: fix information leak in + completion handler +Content-Length: 1033 +Lines: 33 + +commit 8c76d7cd520ebffc1ea9ea0850d87a224a50c7f2 upstream. + +Add missing sanity check to the bulk-in completion handler to avoid an +integer underflow that could be triggered by a malicious device. + +This avoids leaking up to 56 bytes from after the URB transfer buffer to +user space. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/safe_serial.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c +index b2dff0f14743..236ea43f7815 100644 +--- a/drivers/usb/serial/safe_serial.c ++++ b/drivers/usb/serial/safe_serial.c +@@ -205,6 +205,11 @@ static void safe_process_read_urb(struct urb *urb) + if (!safe) + goto out; + ++ if (length < 2) { ++ dev_err(&port->dev, "malformed packet\n"); ++ return; ++ } ++ + fcs = fcs_compute10(data, length, CRC10_INITFCS); + if (fcs) { + dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); +-- +2.12.2 + +From 54f11a9662b632defe4d75c7574fddbc5c503c9c Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 6 Mar 2017 17:36:38 +0100 +Subject: [PATCH 061/251] USB: serial: omninet: fix reference leaks at open +Content-Length: 1124 +Lines: 33 + +commit 30572418b445d85fcfe6c8fe84c947d2606767d8 upstream. + +This driver needlessly took another reference to the tty on open, a +reference which was then never released on close. This lead to not just +a leak of the tty, but also a driver reference leak that prevented the +driver from being unloaded after a port had once been opened. + +Fixes: 4a90f09b20f4 ("tty: usb-serial krefs") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/omninet.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c +index a180b17d2432..76564b3bebb9 100644 +--- a/drivers/usb/serial/omninet.c ++++ b/drivers/usb/serial/omninet.c +@@ -142,12 +142,6 @@ static int omninet_port_remove(struct usb_serial_port *port) + + static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port) + { +- struct usb_serial *serial = port->serial; +- struct usb_serial_port *wport; +- +- wport = serial->port[1]; +- tty_port_tty_set(&wport->port, tty); +- + return usb_serial_generic_open(tty, port); + } + +-- +2.12.2 + +From 179295c38d23874357ca75af104fd6f1fe769cfd Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 7 Mar 2017 16:11:03 +0100 +Subject: [PATCH 062/251] USB: iowarrior: fix NULL-deref at probe +Content-Length: 1947 +Lines: 51 + +commit b7321e81fc369abe353cf094d4f0dc2fe11ab95f upstream. + +Make sure to check for the required interrupt-in endpoint to avoid +dereferencing a NULL-pointer should a malicious device lack such an +endpoint. + +Note that a fairly recent change purported to fix this issue, but added +an insufficient test on the number of endpoints only, a test which can +now be removed. + +Fixes: 4ec0ef3a8212 ("USB: iowarrior: fix oops with malicious USB descriptors") +Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/iowarrior.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c +index 1950e87b4219..e4d17878743e 100644 +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -787,12 +787,6 @@ static int iowarrior_probe(struct usb_interface *interface, + iface_desc = interface->cur_altsetting; + dev->product_id = le16_to_cpu(udev->descriptor.idProduct); + +- if (iface_desc->desc.bNumEndpoints < 1) { +- dev_err(&interface->dev, "Invalid number of endpoints\n"); +- retval = -EINVAL; +- goto error; +- } +- + /* set up the endpoint information */ + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; +@@ -803,6 +797,13 @@ static int iowarrior_probe(struct usb_interface *interface, + /* this one will match for the IOWarrior56 only */ + dev->int_out_endpoint = endpoint; + } ++ ++ if (!dev->int_in_endpoint) { ++ dev_err(&interface->dev, "no interrupt-in endpoint found\n"); ++ retval = -ENODEV; ++ goto error; ++ } ++ + /* we have to check the report_size often, so remember it in the endianness suitable for our machine */ + dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint); + if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) && +-- +2.12.2 + +From 6498086195b9d6939293d35e93b804228158eb7f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 7 Mar 2017 16:11:04 +0100 +Subject: [PATCH 063/251] USB: iowarrior: fix NULL-deref in write +Content-Length: 1244 +Lines: 34 + +commit de46e56653de7b3b54baa625bd582635008b8d05 upstream. + +Make sure to verify that we have the required interrupt-out endpoint for +IOWarrior56 devices to avoid dereferencing a NULL-pointer in write +should a malicious device lack such an endpoint. + +Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/iowarrior.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c +index e4d17878743e..775690bed4c0 100644 +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -804,6 +804,14 @@ static int iowarrior_probe(struct usb_interface *interface, + goto error; + } + ++ if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56) { ++ if (!dev->int_out_endpoint) { ++ dev_err(&interface->dev, "no interrupt-out endpoint found\n"); ++ retval = -ENODEV; ++ goto error; ++ } ++ } ++ + /* we have to check the report_size often, so remember it in the endianness suitable for our machine */ + dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint); + if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) && +-- +2.12.2 + +From e71c7bad68449a59e4e411257420916397cdff85 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 6 Mar 2017 17:36:37 +0100 +Subject: [PATCH 064/251] USB: serial: io_ti: fix NULL-deref in interrupt + callback +Content-Length: 1115 +Lines: 32 + +commit 0b1d250afb8eb9d65afb568bac9b9f9253a82b49 upstream. + +Fix a NULL-pointer dereference in the interrupt callback should a +malicious device send data containing a bad port number by adding the +missing sanity check. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/io_ti.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c +index c02808a30436..67d68b502a51 100644 +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -1674,6 +1674,12 @@ static void edge_interrupt_callback(struct urb *urb) + function = TIUMP_GET_FUNC_FROM_CODE(data[0]); + dev_dbg(dev, "%s - port_number %d, function %d, info 0x%x\n", __func__, + port_number, function, data[1]); ++ ++ if (port_number >= edge_serial->serial->num_ports) { ++ dev_err(dev, "bad port number %d\n", port_number); ++ goto exit; ++ } ++ + port = edge_serial->serial->port[port_number]; + edge_port = usb_get_serial_port_data(port); + if (!edge_port) { +-- +2.12.2 + +From 72bb2b96b8568a74f28e2a2c39e005583595b2c2 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 6 Mar 2017 17:36:40 +0100 +Subject: [PATCH 065/251] USB: serial: io_ti: fix information leak in + completion handler +Content-Length: 1156 +Lines: 31 + +commit 654b404f2a222f918af9b0cd18ad469d0c941a8e upstream. + +Add missing sanity check to the bulk-in completion handler to avoid an +integer underflow that can be triggered by a malicious device. + +This avoids leaking 128 kB of memory content from after the URB transfer +buffer to user space. + +Fixes: 8c209e6782ca ("USB: make actual_length in struct urb field u32") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/io_ti.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c +index 67d68b502a51..f1a8fdcd8674 100644 +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -1761,7 +1761,7 @@ static void edge_bulk_in_callback(struct urb *urb) + + port_number = edge_port->port->port_number; + +- if (edge_port->lsr_event) { ++ if (urb->actual_length > 0 && edge_port->lsr_event) { + edge_port->lsr_event = 0; + dev_dbg(dev, "%s ===== Port %u LSR Status = %02x, Data = %02x ======\n", + __func__, port_number, edge_port->lsr_mask, *data); +-- +2.12.2 + +From 72ca0ab30680571295c97b6a0d87b56d1212c417 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Sat, 25 Feb 2017 18:36:44 +0200 +Subject: [PATCH 066/251] serial: samsung: Continue to work if DMA request + fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1564 +Lines: 42 + +commit f98c7bce570bdbe344b74ff5daa7dfeef3f22929 upstream. + +If DMA is not available (even when configured in DeviceTree), the driver +will fail the startup procedure thus making serial console not +available. + +For example this causes boot failure on QEMU ARMv7 (Exynos4210, SMDKC210): + [    1.302575] OF: amba_device_add() failed (-19) for /amba/pdma@12680000 + ... + [   11.435732] samsung-uart 13800000.serial: DMA request failed + [   72.963893] samsung-uart 13800000.serial: DMA request failed + [   73.143361] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000 + +DMA is not necessary for serial to work, so continue with UART startup +after emitting a warning. + +Fixes: 62c37eedb74c ("serial: samsung: add dma reqest/release functions") +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/samsung.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c +index 237ef5573c18..6deb06147202 100644 +--- a/drivers/tty/serial/samsung.c ++++ b/drivers/tty/serial/samsung.c +@@ -1030,8 +1030,10 @@ static int s3c64xx_serial_startup(struct uart_port *port) + if (ourport->dma) { + ret = s3c24xx_serial_request_dma(ourport); + if (ret < 0) { +- dev_warn(port->dev, "DMA request failed\n"); +- return ret; ++ dev_warn(port->dev, ++ "DMA request failed, DMA will not be used\n"); ++ devm_kfree(port->dev, ourport->dma); ++ ourport->dma = NULL; + } + } + +-- +2.12.2 + +From 61fbad6a28fd3c80567cc615e2de6bd6476ab60c Mon Sep 17 00:00:00 2001 +From: Luis de Bethencourt +Date: Mon, 30 Nov 2015 14:32:17 +0000 +Subject: [PATCH 067/251] mvsas: fix misleading indentation +Content-Length: 1232 +Lines: 34 + +commit 7789cd39274c51bf475411fe22a8ee7255082809 upstream. + +Fix a smatch warning: +drivers/scsi/mvsas/mv_sas.c:740 mvs_task_prep() warn: curly braces intended? + +The code is correct, the indention is misleading. When the device is not +ready we want to return SAS_PHY_DOWN. But current indentation makes it +look like we only do so in the else branch of if (mvi_dev). + +Signed-off-by: Luis de Bethencourt +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/mvsas/mv_sas.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c +index 9c780740fb82..e712fe745955 100644 +--- a/drivers/scsi/mvsas/mv_sas.c ++++ b/drivers/scsi/mvsas/mv_sas.c +@@ -737,8 +737,8 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf + mv_dprintk("device %016llx not ready.\n", + SAS_ADDR(dev->sas_addr)); + +- rc = SAS_PHY_DOWN; +- return rc; ++ rc = SAS_PHY_DOWN; ++ return rc; + } + tei.port = dev->port->lldd_port; + if (tei.port && !tei.port->port_attached && !tmf) { +-- +2.12.2 + +From b0e85701a7766341618d5e924f29f359431f9c91 Mon Sep 17 00:00:00 2001 +From: Janosch Frank +Date: Thu, 2 Mar 2017 15:23:42 +0100 +Subject: [PATCH 068/251] KVM: s390: Fix guest migration for huge guests + resulting in panic +Content-Length: 1904 +Lines: 58 + +commit 2e4d88009f57057df7672fa69a32b5224af54d37 upstream. + +While we can technically not run huge page guests right now, we can +setup a guest with huge pages. Trying to migrate it will trigger a +VM_BUG_ON and, if the kernel is not configured to panic on a BUG, it +will happily try to work on non-existing page table entries. + +With this patch, we always return "dirty" if we encounter a large page +when migrating. This at least fixes the immediate problem until we +have proper handling for both kind of pages. + +Fixes: 15f36eb ("KVM: s390: Add proper dirty bitmap support to S390 kvm.") +Cc: # 3.16+ + +Signed-off-by: Janosch Frank +Acked-by: Christian Borntraeger +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/mm/pgtable.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c +index 8345ae1f117d..05ae254f84cf 100644 +--- a/arch/s390/mm/pgtable.c ++++ b/arch/s390/mm/pgtable.c +@@ -1237,11 +1237,28 @@ EXPORT_SYMBOL_GPL(s390_reset_cmma); + */ + bool gmap_test_and_clear_dirty(unsigned long address, struct gmap *gmap) + { ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; + pte_t *pte; + spinlock_t *ptl; + bool dirty = false; + +- pte = get_locked_pte(gmap->mm, address, &ptl); ++ pgd = pgd_offset(gmap->mm, address); ++ pud = pud_alloc(gmap->mm, pgd, address); ++ if (!pud) ++ return false; ++ pmd = pmd_alloc(gmap->mm, pud, address); ++ if (!pmd) ++ return false; ++ /* We can't run guests backed by huge pages, but userspace can ++ * still set them up and then try to migrate them without any ++ * migration support. ++ */ ++ if (pmd_large(*pmd)) ++ return true; ++ ++ pte = pte_alloc_map_lock(gmap->mm, pmd, address, &ptl); + if (unlikely(!pte)) + return false; + +-- +2.12.2 + +From a084aeef5633db4f649b699785f79676cb71ba6c Mon Sep 17 00:00:00 2001 +From: Michael Holzheu +Date: Tue, 7 Feb 2017 18:09:14 +0100 +Subject: [PATCH 069/251] s390/kdump: Use "LINUX" ELF note name instead of + "CORE" +Content-Length: 3784 +Lines: 108 + +commit a4a81d8eebdc1d209d034f62a082a5131e4242b5 upstream. + +In binutils/libbfd (bfd/elf.c) it is enforced that all s390 specific ELF +notes like e.g. NT_S390_PREFIX or NT_S390_CTRS have "LINUX" specified +as note name. Otherwise the notes are ignored. + +For /proc/vmcore we currently use "CORE" for these notes. + +Up to now this has not been a real problem because the dump analysis tool +"crash" does not check the note name. But it will break all programs that +use libbfd for processing ELF notes. + +So fix this and use "LINUX" for all s390 specific notes to comply with +libbfd. + +Reported-by: Philipp Rudo +Reviewed-by: Philipp Rudo +Signed-off-by: Michael Holzheu +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/kernel/crash_dump.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c +index 171e09bb8ea2..f7c3a61040bd 100644 +--- a/arch/s390/kernel/crash_dump.c ++++ b/arch/s390/kernel/crash_dump.c +@@ -23,6 +23,8 @@ + #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y))) + #define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) (y)))) + ++#define LINUX_NOTE_NAME "LINUX" ++ + static struct memblock_region oldmem_region; + + static struct memblock_type oldmem_type = { +@@ -312,7 +314,7 @@ static void *nt_fpregset(void *ptr, struct save_area *sa) + static void *nt_s390_timer(void *ptr, struct save_area *sa) + { + return nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer), +- KEXEC_CORE_NOTE_NAME); ++ LINUX_NOTE_NAME); + } + + /* +@@ -321,7 +323,7 @@ static void *nt_s390_timer(void *ptr, struct save_area *sa) + static void *nt_s390_tod_cmp(void *ptr, struct save_area *sa) + { + return nt_init(ptr, NT_S390_TODCMP, &sa->clk_cmp, +- sizeof(sa->clk_cmp), KEXEC_CORE_NOTE_NAME); ++ sizeof(sa->clk_cmp), LINUX_NOTE_NAME); + } + + /* +@@ -330,7 +332,7 @@ static void *nt_s390_tod_cmp(void *ptr, struct save_area *sa) + static void *nt_s390_tod_preg(void *ptr, struct save_area *sa) + { + return nt_init(ptr, NT_S390_TODPREG, &sa->tod_reg, +- sizeof(sa->tod_reg), KEXEC_CORE_NOTE_NAME); ++ sizeof(sa->tod_reg), LINUX_NOTE_NAME); + } + + /* +@@ -339,7 +341,7 @@ static void *nt_s390_tod_preg(void *ptr, struct save_area *sa) + static void *nt_s390_ctrs(void *ptr, struct save_area *sa) + { + return nt_init(ptr, NT_S390_CTRS, &sa->ctrl_regs, +- sizeof(sa->ctrl_regs), KEXEC_CORE_NOTE_NAME); ++ sizeof(sa->ctrl_regs), LINUX_NOTE_NAME); + } + + /* +@@ -348,7 +350,7 @@ static void *nt_s390_ctrs(void *ptr, struct save_area *sa) + static void *nt_s390_prefix(void *ptr, struct save_area *sa) + { + return nt_init(ptr, NT_S390_PREFIX, &sa->pref_reg, +- sizeof(sa->pref_reg), KEXEC_CORE_NOTE_NAME); ++ sizeof(sa->pref_reg), LINUX_NOTE_NAME); + } + + /* +@@ -357,7 +359,7 @@ static void *nt_s390_prefix(void *ptr, struct save_area *sa) + static void *nt_s390_vx_high(void *ptr, __vector128 *vx_regs) + { + return nt_init(ptr, NT_S390_VXRS_HIGH, &vx_regs[16], +- 16 * sizeof(__vector128), KEXEC_CORE_NOTE_NAME); ++ 16 * sizeof(__vector128), LINUX_NOTE_NAME); + } + + /* +@@ -370,12 +372,12 @@ static void *nt_s390_vx_low(void *ptr, __vector128 *vx_regs) + int i; + + note = (Elf64_Nhdr *)ptr; +- note->n_namesz = strlen(KEXEC_CORE_NOTE_NAME) + 1; ++ note->n_namesz = strlen(LINUX_NOTE_NAME) + 1; + note->n_descsz = 16 * 8; + note->n_type = NT_S390_VXRS_LOW; + len = sizeof(Elf64_Nhdr); + +- memcpy(ptr + len, KEXEC_CORE_NOTE_NAME, note->n_namesz); ++ memcpy(ptr + len, LINUX_NOTE_NAME, note->n_namesz); + len = roundup(len + note->n_namesz, 4); + + ptr += len; +-- +2.12.2 + +From 66dd58f56eabe2795ed8f83a8480f0e8aace908f Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Tue, 28 Feb 2017 18:32:48 -0800 +Subject: [PATCH 070/251] nfit, libnvdimm: fix interleave set cookie + calculation +Content-Length: 6812 +Lines: 182 + +commit 86ef58a4e35e8fa66afb5898cf6dec6a3bb29f67 upstream. + +The interleave-set cookie is a sum that sanity checks the composition of +an interleave set has not changed from when the namespace was initially +created. The checksum is calculated by sorting the DIMMs by their +location in the interleave-set. The comparison for the sort must be +64-bit wide, not byte-by-byte as performed by memcmp() in the broken +case. + +Fix the implementation to accept correct cookie values in addition to +the Linux "memcmp" order cookies, but only allow correct cookies to be +generated going forward. It does mean that namespaces created by +third-party-tooling, or created by newer kernels with this fix, will not +validate on older kernels. However, there are a couple mitigating +conditions: + + 1/ platforms with namespace-label capable NVDIMMs are not widely + available. + + 2/ interleave-sets with a single-dimm are by definition not affected + (nothing to sort). This covers the QEMU-KVM NVDIMM emulation case. + +The cookie stored in the namespace label will be fixed by any write the +namespace label, the most straightforward way to achieve this is to +write to the "alt_name" attribute of a namespace in sysfs. + +Fixes: eaf961536e16 ("libnvdimm, nfit: add interleave-set state-tracking infrastructure") +Reported-by: Nicholas Moulin +Tested-by: Nicholas Moulin +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/nfit.c | 16 +++++++++++++++- + drivers/nvdimm/namespace_devs.c | 28 +++++++++++++++++++++------- + drivers/nvdimm/nd.h | 1 + + drivers/nvdimm/region_devs.c | 9 +++++++++ + include/linux/libnvdimm.h | 2 ++ + 5 files changed, 48 insertions(+), 8 deletions(-) + +diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c +index c097f477c74c..14c2a07c9f3f 100644 +--- a/drivers/acpi/nfit.c ++++ b/drivers/acpi/nfit.c +@@ -965,7 +965,7 @@ static size_t sizeof_nfit_set_info(int num_mappings) + + num_mappings * sizeof(struct nfit_set_info_map); + } + +-static int cmp_map(const void *m0, const void *m1) ++static int cmp_map_compat(const void *m0, const void *m1) + { + const struct nfit_set_info_map *map0 = m0; + const struct nfit_set_info_map *map1 = m1; +@@ -974,6 +974,14 @@ static int cmp_map(const void *m0, const void *m1) + sizeof(u64)); + } + ++static int cmp_map(const void *m0, const void *m1) ++{ ++ const struct nfit_set_info_map *map0 = m0; ++ const struct nfit_set_info_map *map1 = m1; ++ ++ return map0->region_offset - map1->region_offset; ++} ++ + /* Retrieve the nth entry referencing this spa */ + static struct acpi_nfit_memory_map *memdev_from_spa( + struct acpi_nfit_desc *acpi_desc, u16 range_index, int n) +@@ -1029,6 +1037,12 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc, + sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map), + cmp_map, NULL); + nd_set->cookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0); ++ ++ /* support namespaces created with the wrong sort order */ ++ sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map), ++ cmp_map_compat, NULL); ++ nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0); ++ + ndr_desc->nd_set = nd_set; + devm_kfree(dev, info); + +diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c +index 62120c38d56b..aae7379af4e4 100644 +--- a/drivers/nvdimm/namespace_devs.c ++++ b/drivers/nvdimm/namespace_devs.c +@@ -1534,6 +1534,7 @@ static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id) + static int find_pmem_label_set(struct nd_region *nd_region, + struct nd_namespace_pmem *nspm) + { ++ u64 altcookie = nd_region_interleave_set_altcookie(nd_region); + u64 cookie = nd_region_interleave_set_cookie(nd_region); + struct nd_namespace_label *nd_label; + u8 select_id[NSLABEL_UUID_LEN]; +@@ -1542,8 +1543,10 @@ static int find_pmem_label_set(struct nd_region *nd_region, + int rc = -ENODEV, l; + u16 i; + +- if (cookie == 0) ++ if (cookie == 0) { ++ dev_dbg(&nd_region->dev, "invalid interleave-set-cookie\n"); + return -ENXIO; ++ } + + /* + * Find a complete set of labels by uuid. By definition we can start +@@ -1552,13 +1555,24 @@ static int find_pmem_label_set(struct nd_region *nd_region, + for_each_label(l, nd_label, nd_region->mapping[0].labels) { + u64 isetcookie = __le64_to_cpu(nd_label->isetcookie); + +- if (isetcookie != cookie) +- continue; ++ if (isetcookie != cookie) { ++ dev_dbg(&nd_region->dev, "invalid cookie in label: %pUb\n", ++ nd_label->uuid); ++ if (isetcookie != altcookie) ++ continue; ++ ++ dev_dbg(&nd_region->dev, "valid altcookie in label: %pUb\n", ++ nd_label->uuid); ++ } ++ ++ for (i = 0; nd_region->ndr_mappings; i++) { ++ if (has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i)) ++ continue; ++ if (has_uuid_at_pos(nd_region, nd_label->uuid, altcookie, i)) ++ continue; ++ break; ++ } + +- for (i = 0; nd_region->ndr_mappings; i++) +- if (!has_uuid_at_pos(nd_region, nd_label->uuid, +- cookie, i)) +- break; + if (i < nd_region->ndr_mappings) { + /* + * Give up if we don't find an instance of a +diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h +index 417e521d299c..fc870e55bb66 100644 +--- a/drivers/nvdimm/nd.h ++++ b/drivers/nvdimm/nd.h +@@ -245,6 +245,7 @@ struct nd_region *to_nd_region(struct device *dev); + int nd_region_to_nstype(struct nd_region *nd_region); + int nd_region_register_namespaces(struct nd_region *nd_region, int *err); + u64 nd_region_interleave_set_cookie(struct nd_region *nd_region); ++u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region); + void nvdimm_bus_lock(struct device *dev); + void nvdimm_bus_unlock(struct device *dev); + bool is_nvdimm_bus_locked(struct device *dev); +diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c +index 9521696c9385..dc2e919daa39 100644 +--- a/drivers/nvdimm/region_devs.c ++++ b/drivers/nvdimm/region_devs.c +@@ -379,6 +379,15 @@ u64 nd_region_interleave_set_cookie(struct nd_region *nd_region) + return 0; + } + ++u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region) ++{ ++ struct nd_interleave_set *nd_set = nd_region->nd_set; ++ ++ if (nd_set) ++ return nd_set->altcookie; ++ return 0; ++} ++ + /* + * Upon successful probe/remove, take/release a reference on the + * associated interleave set (if present), and plant new btt + namespace +diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h +index 3f021dc5da8c..30201b9be7bc 100644 +--- a/include/linux/libnvdimm.h ++++ b/include/linux/libnvdimm.h +@@ -83,6 +83,8 @@ struct nd_cmd_desc { + + struct nd_interleave_set { + u64 cookie; ++ /* compatibility with initial buggy Linux implementation */ ++ u64 altcookie; + }; + + struct nd_region_desc { +-- +2.12.2 + +From cd8ad4d9eb6d9ee04e77b42c6a7a15eabada85ac Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 15 Feb 2017 11:26:10 -0500 +Subject: [PATCH 071/251] dm: flush queued bios when process blocks to avoid + deadlock +Content-Length: 3875 +Lines: 118 + +commit d67a5f4b5947aba4bfe9a80a2b86079c215ca755 upstream. + +Commit df2cb6daa4 ("block: Avoid deadlocks with bio allocation by +stacking drivers") created a workqueue for every bio set and code +in bio_alloc_bioset() that tries to resolve some low-memory deadlocks +by redirecting bios queued on current->bio_list to the workqueue if the +system is low on memory. However other deadlocks (see below **) may +happen, without any low memory condition, because generic_make_request +is queuing bios to current->bio_list (rather than submitting them). + +** the related dm-snapshot deadlock is detailed here: +https://www.redhat.com/archives/dm-devel/2016-July/msg00065.html + +Fix this deadlock by redirecting any bios on current->bio_list to the +bio_set's rescue workqueue on every schedule() call. Consequently, +when the process blocks on a mutex, the bios queued on +current->bio_list are dispatched to independent workqueus and they can +complete without waiting for the mutex to be available. + +The structure blk_plug contains an entry cb_list and this list can contain +arbitrary callback functions that are called when the process blocks. +To implement this fix DM (ab)uses the onstack plug's cb_list interface +to get its flush_current_bio_list() called at schedule() time. + +This fixes the snapshot deadlock - if the map method blocks, +flush_current_bio_list() will be called and it redirects bios waiting +on current->bio_list to appropriate workqueues. + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1267650 +Depends-on: df2cb6daa4 ("block: Avoid deadlocks with bio allocation by stacking drivers") +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 3384a3eef917..397f0454100b 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1467,11 +1467,62 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors) + } + EXPORT_SYMBOL_GPL(dm_accept_partial_bio); + ++/* ++ * Flush current->bio_list when the target map method blocks. ++ * This fixes deadlocks in snapshot and possibly in other targets. ++ */ ++struct dm_offload { ++ struct blk_plug plug; ++ struct blk_plug_cb cb; ++}; ++ ++static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule) ++{ ++ struct dm_offload *o = container_of(cb, struct dm_offload, cb); ++ struct bio_list list; ++ struct bio *bio; ++ ++ INIT_LIST_HEAD(&o->cb.list); ++ ++ if (unlikely(!current->bio_list)) ++ return; ++ ++ list = *current->bio_list; ++ bio_list_init(current->bio_list); ++ ++ while ((bio = bio_list_pop(&list))) { ++ struct bio_set *bs = bio->bi_pool; ++ if (unlikely(!bs) || bs == fs_bio_set) { ++ bio_list_add(current->bio_list, bio); ++ continue; ++ } ++ ++ spin_lock(&bs->rescue_lock); ++ bio_list_add(&bs->rescue_list, bio); ++ queue_work(bs->rescue_workqueue, &bs->rescue_work); ++ spin_unlock(&bs->rescue_lock); ++ } ++} ++ ++static void dm_offload_start(struct dm_offload *o) ++{ ++ blk_start_plug(&o->plug); ++ o->cb.callback = flush_current_bio_list; ++ list_add(&o->cb.list, ¤t->plug->cb_list); ++} ++ ++static void dm_offload_end(struct dm_offload *o) ++{ ++ list_del(&o->cb.list); ++ blk_finish_plug(&o->plug); ++} ++ + static void __map_bio(struct dm_target_io *tio) + { + int r; + sector_t sector; + struct mapped_device *md; ++ struct dm_offload o; + struct bio *clone = &tio->clone; + struct dm_target *ti = tio->ti; + +@@ -1484,7 +1535,11 @@ static void __map_bio(struct dm_target_io *tio) + */ + atomic_inc(&tio->io->io_count); + sector = clone->bi_iter.bi_sector; ++ ++ dm_offload_start(&o); + r = ti->type->map(ti, clone); ++ dm_offload_end(&o); ++ + if (r == DM_MAPIO_REMAPPED) { + /* the bio has been remapped so dispatch it */ + +-- +2.12.2 + +From 1c5265be54d32ee21128137ccdb6ecbab0458f07 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Tue, 14 Feb 2017 11:31:15 -0500 +Subject: [PATCH 072/251] ext4: don't BUG when truncating encrypted inodes on + the orphan list +Content-Length: 4100 +Lines: 96 + +commit 0d06863f903ac5f4f6efb0273079d27de3e53a28 upstream. + +Fix a BUG when the kernel tries to mount a file system constructed as +follows: + +echo foo > foo.txt +mke2fs -Fq -t ext4 -O encrypt foo.img 100 +debugfs -w foo.img << EOF +write foo.txt a +set_inode_field a i_flags 0x80800 +set_super_value s_last_orphan 12 +quit +EOF + +root@kvm-xfstests:~# mount -o loop foo.img /mnt +[ 160.238770] ------------[ cut here ]------------ +[ 160.240106] kernel BUG at /usr/projects/linux/ext4/fs/ext4/inode.c:3874! +[ 160.240106] invalid opcode: 0000 [#1] SMP +[ 160.240106] Modules linked in: +[ 160.240106] CPU: 0 PID: 2547 Comm: mount Tainted: G W 4.10.0-rc3-00034-gcdd33b941b67 #227 +[ 160.240106] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1 04/01/2014 +[ 160.240106] task: f4518000 task.stack: f47b6000 +[ 160.240106] EIP: ext4_block_zero_page_range+0x1a7/0x2b4 +[ 160.240106] EFLAGS: 00010246 CPU: 0 +[ 160.240106] EAX: 00000001 EBX: f7be4b50 ECX: f47b7dc0 EDX: 00000007 +[ 160.240106] ESI: f43b05a8 EDI: f43babec EBP: f47b7dd0 ESP: f47b7dac +[ 160.240106] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 +[ 160.240106] CR0: 80050033 CR2: bfd85b08 CR3: 34a00680 CR4: 000006f0 +[ 160.240106] Call Trace: +[ 160.240106] ext4_truncate+0x1e9/0x3e5 +[ 160.240106] ext4_fill_super+0x286f/0x2b1e +[ 160.240106] ? set_blocksize+0x2e/0x7e +[ 160.240106] mount_bdev+0x114/0x15f +[ 160.240106] ext4_mount+0x15/0x17 +[ 160.240106] ? ext4_calculate_overhead+0x39d/0x39d +[ 160.240106] mount_fs+0x58/0x115 +[ 160.240106] vfs_kern_mount+0x4b/0xae +[ 160.240106] do_mount+0x671/0x8c3 +[ 160.240106] ? _copy_from_user+0x70/0x83 +[ 160.240106] ? strndup_user+0x31/0x46 +[ 160.240106] SyS_mount+0x57/0x7b +[ 160.240106] do_int80_syscall_32+0x4f/0x61 +[ 160.240106] entry_INT80_32+0x2f/0x2f +[ 160.240106] EIP: 0xb76b919e +[ 160.240106] EFLAGS: 00000246 CPU: 0 +[ 160.240106] EAX: ffffffda EBX: 08053838 ECX: 08052188 EDX: 080537e8 +[ 160.240106] ESI: c0ed0000 EDI: 00000000 EBP: 080537e8 ESP: bfa13660 +[ 160.240106] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b +[ 160.240106] Code: 59 8b 00 a8 01 0f 84 09 01 00 00 8b 07 66 25 00 f0 66 3d 00 80 75 61 89 f8 e8 3e e2 ff ff 84 c0 74 56 83 bf 48 02 00 00 00 75 02 <0f> 0b 81 7d e8 00 10 00 00 74 02 0f 0b 8b 43 04 8b 53 08 31 c9 +[ 160.240106] EIP: ext4_block_zero_page_range+0x1a7/0x2b4 SS:ESP: 0068:f47b7dac +[ 160.317241] ---[ end trace d6a773a375c810a5 ]--- + +The problem is that when the kernel tries to truncate an inode in +ext4_truncate(), it tries to clear any on-disk data beyond i_size. +Without the encryption key, it can't do that, and so it triggers a +BUG. + +E2fsck does *not* provide this service, and in practice most file +systems have their orphan list processed by e2fsck, so to avoid +crashing, this patch skips this step if we don't have access to the +encryption key (which is the case when processing the orphan list; in +all other cases, we will have the encryption key, or the kernel +wouldn't have allowed the file to be opened). + +An open question is whether the fact that e2fsck isn't clearing the +bytes beyond i_size causing problems --- and if we've lived with it +not doing it for so long, can we drop this from the kernel replay of +the orphan list in all cases (not just when we don't have the key for +encrypted inodes). + +Addresses-Google-Bug: #35209576 + +Signed-off-by: Theodore Ts'o +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/inode.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index e0f862146793..7dcc97eadb12 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3573,6 +3573,10 @@ static int ext4_block_truncate_page(handle_t *handle, + unsigned blocksize; + struct inode *inode = mapping->host; + ++ /* If we are processing an encrypted inode during orphan list handling */ ++ if (ext4_encrypted_inode(inode) && !ext4_has_encryption_key(inode)) ++ return 0; ++ + blocksize = inode->i_sb->s_blocksize; + length = blocksize - (offset & (blocksize - 1)); + +-- +2.12.2 + +From 28ec98bc2e4a175b60f45d505e715a33b93dd077 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Sat, 18 Mar 2017 19:10:23 +0800 +Subject: [PATCH 073/251] Linux 4.4.55 +Content-Length: 301 +Lines: 18 + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 7f54ac081cf3..d9cc21df444d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 54 ++SUBLEVEL = 55 + EXTRAVERSION = + NAME = Blurry Fish Butt + +-- +2.12.2 + +From 0c0be310ba29e4a053e8aac934aebe590c5da909 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Thu, 18 Feb 2016 15:03:24 +0100 +Subject: [PATCH 074/251] netlink: remove mmapped netlink support +Content-Length: 42335 +Lines: 1432 + +commit d1b4c689d4130bcfd3532680b64db562300716b6 upstream. + +mmapped netlink has a number of unresolved issues: + +- TX zerocopy support had to be disabled more than a year ago via + commit 4682a0358639b29cf ("netlink: Always copy on mmap TX.") + because the content of the mmapped area can change after netlink + attribute validation but before message processing. + +- RX support was implemented mainly to speed up nfqueue dumping packet + payload to userspace. However, since commit ae08ce0021087a5d812d2 + ("netfilter: nfnetlink_queue: zero copy support") we avoid one copy + with the socket-based interface too (via the skb_zerocopy helper). + +The other problem is that skbs attached to mmaped netlink socket +behave different from normal skbs: + +- they don't have a shinfo area, so all functions that use skb_shinfo() +(e.g. skb_clone) cannot be used. + +- reserving headroom prevents userspace from seeing the content as +it expects message to start at skb->head. +See for instance +commit aa3a022094fa ("netlink: not trim skb for mmaped socket when dump"). + +- skbs handed e.g. to netlink_ack must have non-NULL skb->sk, else we +crash because it needs the sk to check if a tx ring is attached. + +Also not obvious, leads to non-intuitive bug fixes such as 7c7bdf359 +("netfilter: nfnetlink: use original skbuff when acking batches"). + +mmaped netlink also didn't play nicely with the skb_zerocopy helper +used by nfqueue and openvswitch. Daniel Borkmann fixed this via +commit 6bb0fef489f6 ("netlink, mmap: fix edge-case leakages in nf queue +zero-copy")' but at the cost of also needing to provide remaining +length to the allocation function. + +nfqueue also has problems when used with mmaped rx netlink: +- mmaped netlink doesn't allow use of nfqueue batch verdict messages. + Problem is that in the mmap case, the allocation time also determines + the ordering in which the frame will be seen by userspace (A + allocating before B means that A is located in earlier ring slot, + but this also means that B might get a lower sequence number then A + since seqno is decided later. To fix this we would need to extend the + spinlocked region to also cover the allocation and message setup which + isn't desirable. +- nfqueue can now be configured to queue large (GSO) skbs to userspace. + Queing GSO packets is faster than having to force a software segmentation + in the kernel, so this is a desirable option. However, with a mmap based + ring one has to use 64kb per ring slot element, else mmap has to fall back + to the socket path (NL_MMAP_STATUS_COPY) for all large packets. + +To use the mmap interface, userspace not only has to probe for mmap netlink +support, it also has to implement a recv/socket receive path in order to +handle messages that exceed the size of an rx ring element. + +Cc: Daniel Borkmann +Cc: Ken-ichirou MATSUZAWA +Cc: Pablo Neira Ayuso +Cc: Patrick McHardy +Cc: Thomas Graf +Signed-off-by: Florian Westphal +Signed-off-by: David S. Miller +Cc: Shi Yuejie +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/networking/netlink_mmap.txt | 332 ------------- + include/uapi/linux/netlink.h | 4 + + include/uapi/linux/netlink_diag.h | 2 + + net/netlink/Kconfig | 9 - + net/netlink/af_netlink.c | 751 +----------------------------- + net/netlink/af_netlink.h | 15 - + net/netlink/diag.c | 39 -- + 7 files changed, 14 insertions(+), 1138 deletions(-) + delete mode 100644 Documentation/networking/netlink_mmap.txt + +diff --git a/Documentation/networking/netlink_mmap.txt b/Documentation/networking/netlink_mmap.txt +deleted file mode 100644 +index 54f10478e8e3..000000000000 +--- a/Documentation/networking/netlink_mmap.txt ++++ /dev/null +@@ -1,332 +0,0 @@ +-This file documents how to use memory mapped I/O with netlink. +- +-Author: Patrick McHardy +- +-Overview +--------- +- +-Memory mapped netlink I/O can be used to increase throughput and decrease +-overhead of unicast receive and transmit operations. Some netlink subsystems +-require high throughput, these are mainly the netfilter subsystems +-nfnetlink_queue and nfnetlink_log, but it can also help speed up large +-dump operations of f.i. the routing database. +- +-Memory mapped netlink I/O used two circular ring buffers for RX and TX which +-are mapped into the processes address space. +- +-The RX ring is used by the kernel to directly construct netlink messages into +-user-space memory without copying them as done with regular socket I/O, +-additionally as long as the ring contains messages no recvmsg() or poll() +-syscalls have to be issued by user-space to get more message. +- +-The TX ring is used to process messages directly from user-space memory, the +-kernel processes all messages contained in the ring using a single sendmsg() +-call. +- +-Usage overview +--------------- +- +-In order to use memory mapped netlink I/O, user-space needs three main changes: +- +-- ring setup +-- conversion of the RX path to get messages from the ring instead of recvmsg() +-- conversion of the TX path to construct messages into the ring +- +-Ring setup is done using setsockopt() to provide the ring parameters to the +-kernel, then a call to mmap() to map the ring into the processes address space: +- +-- setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, ¶ms, sizeof(params)); +-- setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, ¶ms, sizeof(params)); +-- ring = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) +- +-Usage of either ring is optional, but even if only the RX ring is used the +-mapping still needs to be writable in order to update the frame status after +-processing. +- +-Conversion of the reception path involves calling poll() on the file +-descriptor, once the socket is readable the frames from the ring are +-processed in order until no more messages are available, as indicated by +-a status word in the frame header. +- +-On kernel side, in order to make use of memory mapped I/O on receive, the +-originating netlink subsystem needs to support memory mapped I/O, otherwise +-it will use an allocated socket buffer as usual and the contents will be +- copied to the ring on transmission, nullifying most of the performance gains. +-Dumps of kernel databases automatically support memory mapped I/O. +- +-Conversion of the transmit path involves changing message construction to +-use memory from the TX ring instead of (usually) a buffer declared on the +-stack and setting up the frame header appropriately. Optionally poll() can +-be used to wait for free frames in the TX ring. +- +-Structured and definitions for using memory mapped I/O are contained in +-. +- +-RX and TX rings +----------------- +- +-Each ring contains a number of continuous memory blocks, containing frames of +-fixed size dependent on the parameters used for ring setup. +- +-Ring: [ block 0 ] +- [ frame 0 ] +- [ frame 1 ] +- [ block 1 ] +- [ frame 2 ] +- [ frame 3 ] +- ... +- [ block n ] +- [ frame 2 * n ] +- [ frame 2 * n + 1 ] +- +-The blocks are only visible to the kernel, from the point of view of user-space +-the ring just contains the frames in a continuous memory zone. +- +-The ring parameters used for setting up the ring are defined as follows: +- +-struct nl_mmap_req { +- unsigned int nm_block_size; +- unsigned int nm_block_nr; +- unsigned int nm_frame_size; +- unsigned int nm_frame_nr; +-}; +- +-Frames are grouped into blocks, where each block is a continuous region of memory +-and holds nm_block_size / nm_frame_size frames. The total number of frames in +-the ring is nm_frame_nr. The following invariants hold: +- +-- frames_per_block = nm_block_size / nm_frame_size +- +-- nm_frame_nr = frames_per_block * nm_block_nr +- +-Some parameters are constrained, specifically: +- +-- nm_block_size must be a multiple of the architectures memory page size. +- The getpagesize() function can be used to get the page size. +- +-- nm_frame_size must be equal or larger to NL_MMAP_HDRLEN, IOW a frame must be +- able to hold at least the frame header +- +-- nm_frame_size must be smaller or equal to nm_block_size +- +-- nm_frame_size must be a multiple of NL_MMAP_MSG_ALIGNMENT +- +-- nm_frame_nr must equal the actual number of frames as specified above. +- +-When the kernel can't allocate physically continuous memory for a ring block, +-it will fall back to use physically discontinuous memory. This might affect +-performance negatively, in order to avoid this the nm_frame_size parameter +-should be chosen to be as small as possible for the required frame size and +-the number of blocks should be increased instead. +- +-Ring frames +------------- +- +-Each frames contain a frame header, consisting of a synchronization word and some +-meta-data, and the message itself. +- +-Frame: [ header message ] +- +-The frame header is defined as follows: +- +-struct nl_mmap_hdr { +- unsigned int nm_status; +- unsigned int nm_len; +- __u32 nm_group; +- /* credentials */ +- __u32 nm_pid; +- __u32 nm_uid; +- __u32 nm_gid; +-}; +- +-- nm_status is used for synchronizing processing between the kernel and user- +- space and specifies ownership of the frame as well as the operation to perform +- +-- nm_len contains the length of the message contained in the data area +- +-- nm_group specified the destination multicast group of message +- +-- nm_pid, nm_uid and nm_gid contain the netlink pid, UID and GID of the sending +- process. These values correspond to the data available using SOCK_PASSCRED in +- the SCM_CREDENTIALS cmsg. +- +-The possible values in the status word are: +- +-- NL_MMAP_STATUS_UNUSED: +- RX ring: frame belongs to the kernel and contains no message +- for user-space. Approriate action is to invoke poll() +- to wait for new messages. +- +- TX ring: frame belongs to user-space and can be used for +- message construction. +- +-- NL_MMAP_STATUS_RESERVED: +- RX ring only: frame is currently used by the kernel for message +- construction and contains no valid message yet. +- Appropriate action is to invoke poll() to wait for +- new messages. +- +-- NL_MMAP_STATUS_VALID: +- RX ring: frame contains a valid message. Approriate action is +- to process the message and release the frame back to +- the kernel by setting the status to +- NL_MMAP_STATUS_UNUSED or queue the frame by setting the +- status to NL_MMAP_STATUS_SKIP. +- +- TX ring: the frame contains a valid message from user-space to +- be processed by the kernel. After completing processing +- the kernel will release the frame back to user-space by +- setting the status to NL_MMAP_STATUS_UNUSED. +- +-- NL_MMAP_STATUS_COPY: +- RX ring only: a message is ready to be processed but could not be +- stored in the ring, either because it exceeded the +- frame size or because the originating subsystem does +- not support memory mapped I/O. Appropriate action is +- to invoke recvmsg() to receive the message and release +- the frame back to the kernel by setting the status to +- NL_MMAP_STATUS_UNUSED. +- +-- NL_MMAP_STATUS_SKIP: +- RX ring only: user-space queued the message for later processing, but +- processed some messages following it in the ring. The +- kernel should skip this frame when looking for unused +- frames. +- +-The data area of a frame begins at a offset of NL_MMAP_HDRLEN relative to the +-frame header. +- +-TX limitations +--------------- +- +-As of Jan 2015 the message is always copied from the ring frame to an +-allocated buffer due to unresolved security concerns. +-See commit 4682a0358639b29cf ("netlink: Always copy on mmap TX."). +- +-Example +-------- +- +-Ring setup: +- +- unsigned int block_size = 16 * getpagesize(); +- struct nl_mmap_req req = { +- .nm_block_size = block_size, +- .nm_block_nr = 64, +- .nm_frame_size = 16384, +- .nm_frame_nr = 64 * block_size / 16384, +- }; +- unsigned int ring_size; +- void *rx_ring, *tx_ring; +- +- /* Configure ring parameters */ +- if (setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req)) < 0) +- exit(1); +- if (setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req)) < 0) +- exit(1) +- +- /* Calculate size of each individual ring */ +- ring_size = req.nm_block_nr * req.nm_block_size; +- +- /* Map RX/TX rings. The TX ring is located after the RX ring */ +- rx_ring = mmap(NULL, 2 * ring_size, PROT_READ | PROT_WRITE, +- MAP_SHARED, fd, 0); +- if ((long)rx_ring == -1L) +- exit(1); +- tx_ring = rx_ring + ring_size: +- +-Message reception: +- +-This example assumes some ring parameters of the ring setup are available. +- +- unsigned int frame_offset = 0; +- struct nl_mmap_hdr *hdr; +- struct nlmsghdr *nlh; +- unsigned char buf[16384]; +- ssize_t len; +- +- while (1) { +- struct pollfd pfds[1]; +- +- pfds[0].fd = fd; +- pfds[0].events = POLLIN | POLLERR; +- pfds[0].revents = 0; +- +- if (poll(pfds, 1, -1) < 0 && errno != -EINTR) +- exit(1); +- +- /* Check for errors. Error handling omitted */ +- if (pfds[0].revents & POLLERR) +- +- +- /* If no new messages, poll again */ +- if (!(pfds[0].revents & POLLIN)) +- continue; +- +- /* Process all frames */ +- while (1) { +- /* Get next frame header */ +- hdr = rx_ring + frame_offset; +- +- if (hdr->nm_status == NL_MMAP_STATUS_VALID) { +- /* Regular memory mapped frame */ +- nlh = (void *)hdr + NL_MMAP_HDRLEN; +- len = hdr->nm_len; +- +- /* Release empty message immediately. May happen +- * on error during message construction. +- */ +- if (len == 0) +- goto release; +- } else if (hdr->nm_status == NL_MMAP_STATUS_COPY) { +- /* Frame queued to socket receive queue */ +- len = recv(fd, buf, sizeof(buf), MSG_DONTWAIT); +- if (len <= 0) +- break; +- nlh = buf; +- } else +- /* No more messages to process, continue polling */ +- break; +- +- process_msg(nlh); +-release: +- /* Release frame back to the kernel */ +- hdr->nm_status = NL_MMAP_STATUS_UNUSED; +- +- /* Advance frame offset to next frame */ +- frame_offset = (frame_offset + frame_size) % ring_size; +- } +- } +- +-Message transmission: +- +-This example assumes some ring parameters of the ring setup are available. +-A single message is constructed and transmitted, to send multiple messages +-at once they would be constructed in consecutive frames before a final call +-to sendto(). +- +- unsigned int frame_offset = 0; +- struct nl_mmap_hdr *hdr; +- struct nlmsghdr *nlh; +- struct sockaddr_nl addr = { +- .nl_family = AF_NETLINK, +- }; +- +- hdr = tx_ring + frame_offset; +- if (hdr->nm_status != NL_MMAP_STATUS_UNUSED) +- /* No frame available. Use poll() to avoid. */ +- exit(1); +- +- nlh = (void *)hdr + NL_MMAP_HDRLEN; +- +- /* Build message */ +- build_message(nlh); +- +- /* Fill frame header: length and status need to be set */ +- hdr->nm_len = nlh->nlmsg_len; +- hdr->nm_status = NL_MMAP_STATUS_VALID; +- +- if (sendto(fd, NULL, 0, 0, &addr, sizeof(addr)) < 0) +- exit(1); +- +- /* Advance frame offset to next frame */ +- frame_offset = (frame_offset + frame_size) % ring_size; +diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h +index f095155d8749..0dba4e4ed2be 100644 +--- a/include/uapi/linux/netlink.h ++++ b/include/uapi/linux/netlink.h +@@ -107,8 +107,10 @@ struct nlmsgerr { + #define NETLINK_PKTINFO 3 + #define NETLINK_BROADCAST_ERROR 4 + #define NETLINK_NO_ENOBUFS 5 ++#ifndef __KERNEL__ + #define NETLINK_RX_RING 6 + #define NETLINK_TX_RING 7 ++#endif + #define NETLINK_LISTEN_ALL_NSID 8 + #define NETLINK_LIST_MEMBERSHIPS 9 + #define NETLINK_CAP_ACK 10 +@@ -134,6 +136,7 @@ struct nl_mmap_hdr { + __u32 nm_gid; + }; + ++#ifndef __KERNEL__ + enum nl_mmap_status { + NL_MMAP_STATUS_UNUSED, + NL_MMAP_STATUS_RESERVED, +@@ -145,6 +148,7 @@ enum nl_mmap_status { + #define NL_MMAP_MSG_ALIGNMENT NLMSG_ALIGNTO + #define NL_MMAP_MSG_ALIGN(sz) __ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT) + #define NL_MMAP_HDRLEN NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr)) ++#endif + + #define NET_MAJOR 36 /* Major 36 is reserved for networking */ + +diff --git a/include/uapi/linux/netlink_diag.h b/include/uapi/linux/netlink_diag.h +index f2159d30d1f5..d79399394b46 100644 +--- a/include/uapi/linux/netlink_diag.h ++++ b/include/uapi/linux/netlink_diag.h +@@ -48,6 +48,8 @@ enum { + + #define NDIAG_SHOW_MEMINFO 0x00000001 /* show memory info of a socket */ + #define NDIAG_SHOW_GROUPS 0x00000002 /* show groups of a netlink socket */ ++#ifndef __KERNEL__ + #define NDIAG_SHOW_RING_CFG 0x00000004 /* show ring configuration */ ++#endif + + #endif +diff --git a/net/netlink/Kconfig b/net/netlink/Kconfig +index 2c5e95e9bfbd..5d6e8c05b3d4 100644 +--- a/net/netlink/Kconfig ++++ b/net/netlink/Kconfig +@@ -2,15 +2,6 @@ + # Netlink Sockets + # + +-config NETLINK_MMAP +- bool "NETLINK: mmaped IO" +- ---help--- +- This option enables support for memory mapped netlink IO. This +- reduces overhead by avoiding copying data between kernel- and +- userspace. +- +- If unsure, say N. +- + config NETLINK_DIAG + tristate "NETLINK: socket monitoring interface" + default n +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 360700a2f46c..8e33019d8e7b 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -225,7 +225,7 @@ static int __netlink_deliver_tap_skb(struct sk_buff *skb, + + dev_hold(dev); + +- if (netlink_skb_is_mmaped(skb) || is_vmalloc_addr(skb->head)) ++ if (is_vmalloc_addr(skb->head)) + nskb = netlink_to_full_skb(skb, GFP_ATOMIC); + else + nskb = skb_clone(skb, GFP_ATOMIC); +@@ -300,610 +300,8 @@ static void netlink_rcv_wake(struct sock *sk) + wake_up_interruptible(&nlk->wait); + } + +-#ifdef CONFIG_NETLINK_MMAP +-static bool netlink_rx_is_mmaped(struct sock *sk) +-{ +- return nlk_sk(sk)->rx_ring.pg_vec != NULL; +-} +- +-static bool netlink_tx_is_mmaped(struct sock *sk) +-{ +- return nlk_sk(sk)->tx_ring.pg_vec != NULL; +-} +- +-static __pure struct page *pgvec_to_page(const void *addr) +-{ +- if (is_vmalloc_addr(addr)) +- return vmalloc_to_page(addr); +- else +- return virt_to_page(addr); +-} +- +-static void free_pg_vec(void **pg_vec, unsigned int order, unsigned int len) +-{ +- unsigned int i; +- +- for (i = 0; i < len; i++) { +- if (pg_vec[i] != NULL) { +- if (is_vmalloc_addr(pg_vec[i])) +- vfree(pg_vec[i]); +- else +- free_pages((unsigned long)pg_vec[i], order); +- } +- } +- kfree(pg_vec); +-} +- +-static void *alloc_one_pg_vec_page(unsigned long order) +-{ +- void *buffer; +- gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | __GFP_ZERO | +- __GFP_NOWARN | __GFP_NORETRY; +- +- buffer = (void *)__get_free_pages(gfp_flags, order); +- if (buffer != NULL) +- return buffer; +- +- buffer = vzalloc((1 << order) * PAGE_SIZE); +- if (buffer != NULL) +- return buffer; +- +- gfp_flags &= ~__GFP_NORETRY; +- return (void *)__get_free_pages(gfp_flags, order); +-} +- +-static void **alloc_pg_vec(struct netlink_sock *nlk, +- struct nl_mmap_req *req, unsigned int order) +-{ +- unsigned int block_nr = req->nm_block_nr; +- unsigned int i; +- void **pg_vec; +- +- pg_vec = kcalloc(block_nr, sizeof(void *), GFP_KERNEL); +- if (pg_vec == NULL) +- return NULL; +- +- for (i = 0; i < block_nr; i++) { +- pg_vec[i] = alloc_one_pg_vec_page(order); +- if (pg_vec[i] == NULL) +- goto err1; +- } +- +- return pg_vec; +-err1: +- free_pg_vec(pg_vec, order, block_nr); +- return NULL; +-} +- +- +-static void +-__netlink_set_ring(struct sock *sk, struct nl_mmap_req *req, bool tx_ring, void **pg_vec, +- unsigned int order) +-{ +- struct netlink_sock *nlk = nlk_sk(sk); +- struct sk_buff_head *queue; +- struct netlink_ring *ring; +- +- queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue; +- ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring; +- +- spin_lock_bh(&queue->lock); +- +- ring->frame_max = req->nm_frame_nr - 1; +- ring->head = 0; +- ring->frame_size = req->nm_frame_size; +- ring->pg_vec_pages = req->nm_block_size / PAGE_SIZE; +- +- swap(ring->pg_vec_len, req->nm_block_nr); +- swap(ring->pg_vec_order, order); +- swap(ring->pg_vec, pg_vec); +- +- __skb_queue_purge(queue); +- spin_unlock_bh(&queue->lock); +- +- WARN_ON(atomic_read(&nlk->mapped)); +- +- if (pg_vec) +- free_pg_vec(pg_vec, order, req->nm_block_nr); +-} +- +-static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req, +- bool tx_ring) +-{ +- struct netlink_sock *nlk = nlk_sk(sk); +- struct netlink_ring *ring; +- void **pg_vec = NULL; +- unsigned int order = 0; +- +- ring = tx_ring ? &nlk->tx_ring : &nlk->rx_ring; +- +- if (atomic_read(&nlk->mapped)) +- return -EBUSY; +- if (atomic_read(&ring->pending)) +- return -EBUSY; +- +- if (req->nm_block_nr) { +- if (ring->pg_vec != NULL) +- return -EBUSY; +- +- if ((int)req->nm_block_size <= 0) +- return -EINVAL; +- if (!PAGE_ALIGNED(req->nm_block_size)) +- return -EINVAL; +- if (req->nm_frame_size < NL_MMAP_HDRLEN) +- return -EINVAL; +- if (!IS_ALIGNED(req->nm_frame_size, NL_MMAP_MSG_ALIGNMENT)) +- return -EINVAL; +- +- ring->frames_per_block = req->nm_block_size / +- req->nm_frame_size; +- if (ring->frames_per_block == 0) +- return -EINVAL; +- if (ring->frames_per_block * req->nm_block_nr != +- req->nm_frame_nr) +- return -EINVAL; +- +- order = get_order(req->nm_block_size); +- pg_vec = alloc_pg_vec(nlk, req, order); +- if (pg_vec == NULL) +- return -ENOMEM; +- } else { +- if (req->nm_frame_nr) +- return -EINVAL; +- } +- +- mutex_lock(&nlk->pg_vec_lock); +- if (atomic_read(&nlk->mapped) == 0) { +- __netlink_set_ring(sk, req, tx_ring, pg_vec, order); +- mutex_unlock(&nlk->pg_vec_lock); +- return 0; +- } +- +- mutex_unlock(&nlk->pg_vec_lock); +- +- if (pg_vec) +- free_pg_vec(pg_vec, order, req->nm_block_nr); +- +- return -EBUSY; +-} +- +-static void netlink_mm_open(struct vm_area_struct *vma) +-{ +- struct file *file = vma->vm_file; +- struct socket *sock = file->private_data; +- struct sock *sk = sock->sk; +- +- if (sk) +- atomic_inc(&nlk_sk(sk)->mapped); +-} +- +-static void netlink_mm_close(struct vm_area_struct *vma) +-{ +- struct file *file = vma->vm_file; +- struct socket *sock = file->private_data; +- struct sock *sk = sock->sk; +- +- if (sk) +- atomic_dec(&nlk_sk(sk)->mapped); +-} +- +-static const struct vm_operations_struct netlink_mmap_ops = { +- .open = netlink_mm_open, +- .close = netlink_mm_close, +-}; +- +-static int netlink_mmap(struct file *file, struct socket *sock, +- struct vm_area_struct *vma) +-{ +- struct sock *sk = sock->sk; +- struct netlink_sock *nlk = nlk_sk(sk); +- struct netlink_ring *ring; +- unsigned long start, size, expected; +- unsigned int i; +- int err = -EINVAL; +- +- if (vma->vm_pgoff) +- return -EINVAL; +- +- mutex_lock(&nlk->pg_vec_lock); +- +- expected = 0; +- for (ring = &nlk->rx_ring; ring <= &nlk->tx_ring; ring++) { +- if (ring->pg_vec == NULL) +- continue; +- expected += ring->pg_vec_len * ring->pg_vec_pages * PAGE_SIZE; +- } +- +- if (expected == 0) +- goto out; +- +- size = vma->vm_end - vma->vm_start; +- if (size != expected) +- goto out; +- +- start = vma->vm_start; +- for (ring = &nlk->rx_ring; ring <= &nlk->tx_ring; ring++) { +- if (ring->pg_vec == NULL) +- continue; +- +- for (i = 0; i < ring->pg_vec_len; i++) { +- struct page *page; +- void *kaddr = ring->pg_vec[i]; +- unsigned int pg_num; +- +- for (pg_num = 0; pg_num < ring->pg_vec_pages; pg_num++) { +- page = pgvec_to_page(kaddr); +- err = vm_insert_page(vma, start, page); +- if (err < 0) +- goto out; +- start += PAGE_SIZE; +- kaddr += PAGE_SIZE; +- } +- } +- } +- +- atomic_inc(&nlk->mapped); +- vma->vm_ops = &netlink_mmap_ops; +- err = 0; +-out: +- mutex_unlock(&nlk->pg_vec_lock); +- return err; +-} +- +-static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr, unsigned int nm_len) +-{ +-#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE == 1 +- struct page *p_start, *p_end; +- +- /* First page is flushed through netlink_{get,set}_status */ +- p_start = pgvec_to_page(hdr + PAGE_SIZE); +- p_end = pgvec_to_page((void *)hdr + NL_MMAP_HDRLEN + nm_len - 1); +- while (p_start <= p_end) { +- flush_dcache_page(p_start); +- p_start++; +- } +-#endif +-} +- +-static enum nl_mmap_status netlink_get_status(const struct nl_mmap_hdr *hdr) +-{ +- smp_rmb(); +- flush_dcache_page(pgvec_to_page(hdr)); +- return hdr->nm_status; +-} +- +-static void netlink_set_status(struct nl_mmap_hdr *hdr, +- enum nl_mmap_status status) +-{ +- smp_mb(); +- hdr->nm_status = status; +- flush_dcache_page(pgvec_to_page(hdr)); +-} +- +-static struct nl_mmap_hdr * +-__netlink_lookup_frame(const struct netlink_ring *ring, unsigned int pos) +-{ +- unsigned int pg_vec_pos, frame_off; +- +- pg_vec_pos = pos / ring->frames_per_block; +- frame_off = pos % ring->frames_per_block; +- +- return ring->pg_vec[pg_vec_pos] + (frame_off * ring->frame_size); +-} +- +-static struct nl_mmap_hdr * +-netlink_lookup_frame(const struct netlink_ring *ring, unsigned int pos, +- enum nl_mmap_status status) +-{ +- struct nl_mmap_hdr *hdr; +- +- hdr = __netlink_lookup_frame(ring, pos); +- if (netlink_get_status(hdr) != status) +- return NULL; +- +- return hdr; +-} +- +-static struct nl_mmap_hdr * +-netlink_current_frame(const struct netlink_ring *ring, +- enum nl_mmap_status status) +-{ +- return netlink_lookup_frame(ring, ring->head, status); +-} +- +-static void netlink_increment_head(struct netlink_ring *ring) +-{ +- ring->head = ring->head != ring->frame_max ? ring->head + 1 : 0; +-} +- +-static void netlink_forward_ring(struct netlink_ring *ring) +-{ +- unsigned int head = ring->head; +- const struct nl_mmap_hdr *hdr; +- +- do { +- hdr = __netlink_lookup_frame(ring, ring->head); +- if (hdr->nm_status == NL_MMAP_STATUS_UNUSED) +- break; +- if (hdr->nm_status != NL_MMAP_STATUS_SKIP) +- break; +- netlink_increment_head(ring); +- } while (ring->head != head); +-} +- +-static bool netlink_has_valid_frame(struct netlink_ring *ring) +-{ +- unsigned int head = ring->head, pos = head; +- const struct nl_mmap_hdr *hdr; +- +- do { +- hdr = __netlink_lookup_frame(ring, pos); +- if (hdr->nm_status == NL_MMAP_STATUS_VALID) +- return true; +- pos = pos != 0 ? pos - 1 : ring->frame_max; +- } while (pos != head); +- +- return false; +-} +- +-static bool netlink_dump_space(struct netlink_sock *nlk) +-{ +- struct netlink_ring *ring = &nlk->rx_ring; +- struct nl_mmap_hdr *hdr; +- unsigned int n; +- +- hdr = netlink_current_frame(ring, NL_MMAP_STATUS_UNUSED); +- if (hdr == NULL) +- return false; +- +- n = ring->head + ring->frame_max / 2; +- if (n > ring->frame_max) +- n -= ring->frame_max; +- +- hdr = __netlink_lookup_frame(ring, n); +- +- return hdr->nm_status == NL_MMAP_STATUS_UNUSED; +-} +- +-static unsigned int netlink_poll(struct file *file, struct socket *sock, +- poll_table *wait) +-{ +- struct sock *sk = sock->sk; +- struct netlink_sock *nlk = nlk_sk(sk); +- unsigned int mask; +- int err; +- +- if (nlk->rx_ring.pg_vec != NULL) { +- /* Memory mapped sockets don't call recvmsg(), so flow control +- * for dumps is performed here. A dump is allowed to continue +- * if at least half the ring is unused. +- */ +- while (nlk->cb_running && netlink_dump_space(nlk)) { +- err = netlink_dump(sk); +- if (err < 0) { +- sk->sk_err = -err; +- sk->sk_error_report(sk); +- break; +- } +- } +- netlink_rcv_wake(sk); +- } +- +- mask = datagram_poll(file, sock, wait); +- +- /* We could already have received frames in the normal receive +- * queue, that will show up as NL_MMAP_STATUS_COPY in the ring, +- * so if mask contains pollin/etc already, there's no point +- * walking the ring. +- */ +- if ((mask & (POLLIN | POLLRDNORM)) != (POLLIN | POLLRDNORM)) { +- spin_lock_bh(&sk->sk_receive_queue.lock); +- if (nlk->rx_ring.pg_vec) { +- if (netlink_has_valid_frame(&nlk->rx_ring)) +- mask |= POLLIN | POLLRDNORM; +- } +- spin_unlock_bh(&sk->sk_receive_queue.lock); +- } +- +- spin_lock_bh(&sk->sk_write_queue.lock); +- if (nlk->tx_ring.pg_vec) { +- if (netlink_current_frame(&nlk->tx_ring, NL_MMAP_STATUS_UNUSED)) +- mask |= POLLOUT | POLLWRNORM; +- } +- spin_unlock_bh(&sk->sk_write_queue.lock); +- +- return mask; +-} +- +-static struct nl_mmap_hdr *netlink_mmap_hdr(struct sk_buff *skb) +-{ +- return (struct nl_mmap_hdr *)(skb->head - NL_MMAP_HDRLEN); +-} +- +-static void netlink_ring_setup_skb(struct sk_buff *skb, struct sock *sk, +- struct netlink_ring *ring, +- struct nl_mmap_hdr *hdr) +-{ +- unsigned int size; +- void *data; +- +- size = ring->frame_size - NL_MMAP_HDRLEN; +- data = (void *)hdr + NL_MMAP_HDRLEN; +- +- skb->head = data; +- skb->data = data; +- skb_reset_tail_pointer(skb); +- skb->end = skb->tail + size; +- skb->len = 0; +- +- skb->destructor = netlink_skb_destructor; +- NETLINK_CB(skb).flags |= NETLINK_SKB_MMAPED; +- NETLINK_CB(skb).sk = sk; +-} +- +-static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg, +- u32 dst_portid, u32 dst_group, +- struct scm_cookie *scm) +-{ +- struct netlink_sock *nlk = nlk_sk(sk); +- struct netlink_ring *ring; +- struct nl_mmap_hdr *hdr; +- struct sk_buff *skb; +- unsigned int maxlen; +- int err = 0, len = 0; +- +- mutex_lock(&nlk->pg_vec_lock); +- +- ring = &nlk->tx_ring; +- maxlen = ring->frame_size - NL_MMAP_HDRLEN; +- +- do { +- unsigned int nm_len; +- +- hdr = netlink_current_frame(ring, NL_MMAP_STATUS_VALID); +- if (hdr == NULL) { +- if (!(msg->msg_flags & MSG_DONTWAIT) && +- atomic_read(&nlk->tx_ring.pending)) +- schedule(); +- continue; +- } +- +- nm_len = ACCESS_ONCE(hdr->nm_len); +- if (nm_len > maxlen) { +- err = -EINVAL; +- goto out; +- } +- +- netlink_frame_flush_dcache(hdr, nm_len); +- +- skb = alloc_skb(nm_len, GFP_KERNEL); +- if (skb == NULL) { +- err = -ENOBUFS; +- goto out; +- } +- __skb_put(skb, nm_len); +- memcpy(skb->data, (void *)hdr + NL_MMAP_HDRLEN, nm_len); +- netlink_set_status(hdr, NL_MMAP_STATUS_UNUSED); +- +- netlink_increment_head(ring); +- +- NETLINK_CB(skb).portid = nlk->portid; +- NETLINK_CB(skb).dst_group = dst_group; +- NETLINK_CB(skb).creds = scm->creds; +- +- err = security_netlink_send(sk, skb); +- if (err) { +- kfree_skb(skb); +- goto out; +- } +- +- if (unlikely(dst_group)) { +- atomic_inc(&skb->users); +- netlink_broadcast(sk, skb, dst_portid, dst_group, +- GFP_KERNEL); +- } +- err = netlink_unicast(sk, skb, dst_portid, +- msg->msg_flags & MSG_DONTWAIT); +- if (err < 0) +- goto out; +- len += err; +- +- } while (hdr != NULL || +- (!(msg->msg_flags & MSG_DONTWAIT) && +- atomic_read(&nlk->tx_ring.pending))); +- +- if (len > 0) +- err = len; +-out: +- mutex_unlock(&nlk->pg_vec_lock); +- return err; +-} +- +-static void netlink_queue_mmaped_skb(struct sock *sk, struct sk_buff *skb) +-{ +- struct nl_mmap_hdr *hdr; +- +- hdr = netlink_mmap_hdr(skb); +- hdr->nm_len = skb->len; +- hdr->nm_group = NETLINK_CB(skb).dst_group; +- hdr->nm_pid = NETLINK_CB(skb).creds.pid; +- hdr->nm_uid = from_kuid(sk_user_ns(sk), NETLINK_CB(skb).creds.uid); +- hdr->nm_gid = from_kgid(sk_user_ns(sk), NETLINK_CB(skb).creds.gid); +- netlink_frame_flush_dcache(hdr, hdr->nm_len); +- netlink_set_status(hdr, NL_MMAP_STATUS_VALID); +- +- NETLINK_CB(skb).flags |= NETLINK_SKB_DELIVERED; +- kfree_skb(skb); +-} +- +-static void netlink_ring_set_copied(struct sock *sk, struct sk_buff *skb) +-{ +- struct netlink_sock *nlk = nlk_sk(sk); +- struct netlink_ring *ring = &nlk->rx_ring; +- struct nl_mmap_hdr *hdr; +- +- spin_lock_bh(&sk->sk_receive_queue.lock); +- hdr = netlink_current_frame(ring, NL_MMAP_STATUS_UNUSED); +- if (hdr == NULL) { +- spin_unlock_bh(&sk->sk_receive_queue.lock); +- kfree_skb(skb); +- netlink_overrun(sk); +- return; +- } +- netlink_increment_head(ring); +- __skb_queue_tail(&sk->sk_receive_queue, skb); +- spin_unlock_bh(&sk->sk_receive_queue.lock); +- +- hdr->nm_len = skb->len; +- hdr->nm_group = NETLINK_CB(skb).dst_group; +- hdr->nm_pid = NETLINK_CB(skb).creds.pid; +- hdr->nm_uid = from_kuid(sk_user_ns(sk), NETLINK_CB(skb).creds.uid); +- hdr->nm_gid = from_kgid(sk_user_ns(sk), NETLINK_CB(skb).creds.gid); +- netlink_set_status(hdr, NL_MMAP_STATUS_COPY); +-} +- +-#else /* CONFIG_NETLINK_MMAP */ +-#define netlink_rx_is_mmaped(sk) false +-#define netlink_tx_is_mmaped(sk) false +-#define netlink_mmap sock_no_mmap +-#define netlink_poll datagram_poll +-#define netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, scm) 0 +-#endif /* CONFIG_NETLINK_MMAP */ +- + static void netlink_skb_destructor(struct sk_buff *skb) + { +-#ifdef CONFIG_NETLINK_MMAP +- struct nl_mmap_hdr *hdr; +- struct netlink_ring *ring; +- struct sock *sk; +- +- /* If a packet from the kernel to userspace was freed because of an +- * error without being delivered to userspace, the kernel must reset +- * the status. In the direction userspace to kernel, the status is +- * always reset here after the packet was processed and freed. +- */ +- if (netlink_skb_is_mmaped(skb)) { +- hdr = netlink_mmap_hdr(skb); +- sk = NETLINK_CB(skb).sk; +- +- if (NETLINK_CB(skb).flags & NETLINK_SKB_TX) { +- netlink_set_status(hdr, NL_MMAP_STATUS_UNUSED); +- ring = &nlk_sk(sk)->tx_ring; +- } else { +- if (!(NETLINK_CB(skb).flags & NETLINK_SKB_DELIVERED)) { +- hdr->nm_len = 0; +- netlink_set_status(hdr, NL_MMAP_STATUS_VALID); +- } +- ring = &nlk_sk(sk)->rx_ring; +- } +- +- WARN_ON(atomic_read(&ring->pending) == 0); +- atomic_dec(&ring->pending); +- sock_put(sk); +- +- skb->head = NULL; +- } +-#endif + if (is_vmalloc_addr(skb->head)) { + if (!skb->cloned || + !atomic_dec_return(&(skb_shinfo(skb)->dataref))) +@@ -936,18 +334,6 @@ static void netlink_sock_destruct(struct sock *sk) + } + + skb_queue_purge(&sk->sk_receive_queue); +-#ifdef CONFIG_NETLINK_MMAP +- if (1) { +- struct nl_mmap_req req; +- +- memset(&req, 0, sizeof(req)); +- if (nlk->rx_ring.pg_vec) +- __netlink_set_ring(sk, &req, false, NULL, 0); +- memset(&req, 0, sizeof(req)); +- if (nlk->tx_ring.pg_vec) +- __netlink_set_ring(sk, &req, true, NULL, 0); +- } +-#endif /* CONFIG_NETLINK_MMAP */ + + if (!sock_flag(sk, SOCK_DEAD)) { + printk(KERN_ERR "Freeing alive netlink socket %p\n", sk); +@@ -1201,9 +587,6 @@ static int __netlink_create(struct net *net, struct socket *sock, + mutex_init(nlk->cb_mutex); + } + init_waitqueue_head(&nlk->wait); +-#ifdef CONFIG_NETLINK_MMAP +- mutex_init(&nlk->pg_vec_lock); +-#endif + + sk->sk_destruct = netlink_sock_destruct; + sk->sk_protocol = protocol; +@@ -1745,8 +1128,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, + nlk = nlk_sk(sk); + + if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || +- test_bit(NETLINK_S_CONGESTED, &nlk->state)) && +- !netlink_skb_is_mmaped(skb)) { ++ test_bit(NETLINK_S_CONGESTED, &nlk->state))) { + DECLARE_WAITQUEUE(wait, current); + if (!*timeo) { + if (!ssk || netlink_is_kernel(ssk)) +@@ -1784,14 +1166,7 @@ static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb) + + netlink_deliver_tap(skb); + +-#ifdef CONFIG_NETLINK_MMAP +- if (netlink_skb_is_mmaped(skb)) +- netlink_queue_mmaped_skb(sk, skb); +- else if (netlink_rx_is_mmaped(sk)) +- netlink_ring_set_copied(sk, skb); +- else +-#endif /* CONFIG_NETLINK_MMAP */ +- skb_queue_tail(&sk->sk_receive_queue, skb); ++ skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk); + return len; + } +@@ -1815,9 +1190,6 @@ static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation) + int delta; + + WARN_ON(skb->sk != NULL); +- if (netlink_skb_is_mmaped(skb)) +- return skb; +- + delta = skb->end - skb->tail; + if (is_vmalloc_addr(skb->head) || delta * 2 < skb->truesize) + return skb; +@@ -1897,71 +1269,6 @@ struct sk_buff *__netlink_alloc_skb(struct sock *ssk, unsigned int size, + unsigned int ldiff, u32 dst_portid, + gfp_t gfp_mask) + { +-#ifdef CONFIG_NETLINK_MMAP +- unsigned int maxlen, linear_size; +- struct sock *sk = NULL; +- struct sk_buff *skb; +- struct netlink_ring *ring; +- struct nl_mmap_hdr *hdr; +- +- sk = netlink_getsockbyportid(ssk, dst_portid); +- if (IS_ERR(sk)) +- goto out; +- +- ring = &nlk_sk(sk)->rx_ring; +- /* fast-path without atomic ops for common case: non-mmaped receiver */ +- if (ring->pg_vec == NULL) +- goto out_put; +- +- /* We need to account the full linear size needed as a ring +- * slot cannot have non-linear parts. +- */ +- linear_size = size + ldiff; +- if (ring->frame_size - NL_MMAP_HDRLEN < linear_size) +- goto out_put; +- +- skb = alloc_skb_head(gfp_mask); +- if (skb == NULL) +- goto err1; +- +- spin_lock_bh(&sk->sk_receive_queue.lock); +- /* check again under lock */ +- if (ring->pg_vec == NULL) +- goto out_free; +- +- /* check again under lock */ +- maxlen = ring->frame_size - NL_MMAP_HDRLEN; +- if (maxlen < linear_size) +- goto out_free; +- +- netlink_forward_ring(ring); +- hdr = netlink_current_frame(ring, NL_MMAP_STATUS_UNUSED); +- if (hdr == NULL) +- goto err2; +- +- netlink_ring_setup_skb(skb, sk, ring, hdr); +- netlink_set_status(hdr, NL_MMAP_STATUS_RESERVED); +- atomic_inc(&ring->pending); +- netlink_increment_head(ring); +- +- spin_unlock_bh(&sk->sk_receive_queue.lock); +- return skb; +- +-err2: +- kfree_skb(skb); +- spin_unlock_bh(&sk->sk_receive_queue.lock); +- netlink_overrun(sk); +-err1: +- sock_put(sk); +- return NULL; +- +-out_free: +- kfree_skb(skb); +- spin_unlock_bh(&sk->sk_receive_queue.lock); +-out_put: +- sock_put(sk); +-out: +-#endif + return alloc_skb(size, gfp_mask); + } + EXPORT_SYMBOL_GPL(__netlink_alloc_skb); +@@ -2242,8 +1549,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, + if (level != SOL_NETLINK) + return -ENOPROTOOPT; + +- if (optname != NETLINK_RX_RING && optname != NETLINK_TX_RING && +- optlen >= sizeof(int) && ++ if (optlen >= sizeof(int) && + get_user(val, (unsigned int __user *)optval)) + return -EFAULT; + +@@ -2296,25 +1602,6 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, + } + err = 0; + break; +-#ifdef CONFIG_NETLINK_MMAP +- case NETLINK_RX_RING: +- case NETLINK_TX_RING: { +- struct nl_mmap_req req; +- +- /* Rings might consume more memory than queue limits, require +- * CAP_NET_ADMIN. +- */ +- if (!capable(CAP_NET_ADMIN)) +- return -EPERM; +- if (optlen < sizeof(req)) +- return -EINVAL; +- if (copy_from_user(&req, optval, sizeof(req))) +- return -EFAULT; +- err = netlink_set_ring(sk, &req, +- optname == NETLINK_TX_RING); +- break; +- } +-#endif /* CONFIG_NETLINK_MMAP */ + case NETLINK_LISTEN_ALL_NSID: + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_BROADCAST)) + return -EPERM; +@@ -2484,18 +1771,6 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + smp_rmb(); + } + +- /* It's a really convoluted way for userland to ask for mmaped +- * sendmsg(), but that's what we've got... +- */ +- if (netlink_tx_is_mmaped(sk) && +- iter_is_iovec(&msg->msg_iter) && +- msg->msg_iter.nr_segs == 1 && +- msg->msg_iter.iov->iov_base == NULL) { +- err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, +- &scm); +- goto out; +- } +- + err = -EMSGSIZE; + if (len > sk->sk_sndbuf - 32) + goto out; +@@ -2812,8 +2087,7 @@ static int netlink_dump(struct sock *sk) + goto errout_skb; + } + +- if (!netlink_rx_is_mmaped(sk) && +- atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) ++ if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) + goto errout_skb; + + /* NLMSG_GOODSIZE is small to avoid high order allocations being +@@ -2902,16 +2176,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, + struct netlink_sock *nlk; + int ret; + +- /* Memory mapped dump requests need to be copied to avoid looping +- * on the pending state in netlink_mmap_sendmsg() while the CB hold +- * a reference to the skb. +- */ +- if (netlink_skb_is_mmaped(skb)) { +- skb = skb_copy(skb, GFP_KERNEL); +- if (skb == NULL) +- return -ENOBUFS; +- } else +- atomic_inc(&skb->users); ++ atomic_inc(&skb->users); + + sk = netlink_lookup(sock_net(ssk), ssk->sk_protocol, NETLINK_CB(skb).portid); + if (sk == NULL) { +@@ -3255,7 +2520,7 @@ static const struct proto_ops netlink_ops = { + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .getname = netlink_getname, +- .poll = netlink_poll, ++ .poll = datagram_poll, + .ioctl = sock_no_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, +@@ -3263,7 +2528,7 @@ static const struct proto_ops netlink_ops = { + .getsockopt = netlink_getsockopt, + .sendmsg = netlink_sendmsg, + .recvmsg = netlink_recvmsg, +- .mmap = netlink_mmap, ++ .mmap = sock_no_mmap, + .sendpage = sock_no_sendpage, + }; + +diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h +index df32cb92d9fc..ea4600aea6b0 100644 +--- a/net/netlink/af_netlink.h ++++ b/net/netlink/af_netlink.h +@@ -45,12 +45,6 @@ struct netlink_sock { + int (*netlink_bind)(struct net *net, int group); + void (*netlink_unbind)(struct net *net, int group); + struct module *module; +-#ifdef CONFIG_NETLINK_MMAP +- struct mutex pg_vec_lock; +- struct netlink_ring rx_ring; +- struct netlink_ring tx_ring; +- atomic_t mapped; +-#endif /* CONFIG_NETLINK_MMAP */ + + struct rhash_head node; + struct rcu_head rcu; +@@ -62,15 +56,6 @@ static inline struct netlink_sock *nlk_sk(struct sock *sk) + return container_of(sk, struct netlink_sock, sk); + } + +-static inline bool netlink_skb_is_mmaped(const struct sk_buff *skb) +-{ +-#ifdef CONFIG_NETLINK_MMAP +- return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED; +-#else +- return false; +-#endif /* CONFIG_NETLINK_MMAP */ +-} +- + struct netlink_table { + struct rhashtable hash; + struct hlist_head mc_list; +diff --git a/net/netlink/diag.c b/net/netlink/diag.c +index 3ee63a3cff30..8dd836a8dd60 100644 +--- a/net/netlink/diag.c ++++ b/net/netlink/diag.c +@@ -8,41 +8,6 @@ + + #include "af_netlink.h" + +-#ifdef CONFIG_NETLINK_MMAP +-static int sk_diag_put_ring(struct netlink_ring *ring, int nl_type, +- struct sk_buff *nlskb) +-{ +- struct netlink_diag_ring ndr; +- +- ndr.ndr_block_size = ring->pg_vec_pages << PAGE_SHIFT; +- ndr.ndr_block_nr = ring->pg_vec_len; +- ndr.ndr_frame_size = ring->frame_size; +- ndr.ndr_frame_nr = ring->frame_max + 1; +- +- return nla_put(nlskb, nl_type, sizeof(ndr), &ndr); +-} +- +-static int sk_diag_put_rings_cfg(struct sock *sk, struct sk_buff *nlskb) +-{ +- struct netlink_sock *nlk = nlk_sk(sk); +- int ret; +- +- mutex_lock(&nlk->pg_vec_lock); +- ret = sk_diag_put_ring(&nlk->rx_ring, NETLINK_DIAG_RX_RING, nlskb); +- if (!ret) +- ret = sk_diag_put_ring(&nlk->tx_ring, NETLINK_DIAG_TX_RING, +- nlskb); +- mutex_unlock(&nlk->pg_vec_lock); +- +- return ret; +-} +-#else +-static int sk_diag_put_rings_cfg(struct sock *sk, struct sk_buff *nlskb) +-{ +- return 0; +-} +-#endif +- + static int sk_diag_dump_groups(struct sock *sk, struct sk_buff *nlskb) + { + struct netlink_sock *nlk = nlk_sk(sk); +@@ -87,10 +52,6 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, + sock_diag_put_meminfo(sk, skb, NETLINK_DIAG_MEMINFO)) + goto out_nlmsg_trim; + +- if ((req->ndiag_show & NDIAG_SHOW_RING_CFG) && +- sk_diag_put_rings_cfg(sk, skb)) +- goto out_nlmsg_trim; +- + nlmsg_end(skb, nlh); + return 0; + +-- +2.12.2 + +From 51a219a1371ed26ce45acc8209d6064257d00f70 Mon Sep 17 00:00:00 2001 +From: Matthias Schiffer +Date: Thu, 23 Feb 2017 17:19:41 +0100 +Subject: [PATCH 075/251] vxlan: correctly validate VXLAN ID against + VXLAN_N_VID +Content-Length: 915 +Lines: 29 + +[ Upstream commit 4e37d6911f36545b286d15073f6f2222f840e81c ] + +The incorrect check caused an off-by-one error: the maximum VID 0xffffff +was unusable. + +Fixes: d342894c5d2f ("vxlan: virtual extensible lan") +Signed-off-by: Matthias Schiffer +Acked-by: Jiri Benc +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index 6fa8e165878e..590750ab6564 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -2600,7 +2600,7 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) + + if (data[IFLA_VXLAN_ID]) { + __u32 id = nla_get_u32(data[IFLA_VXLAN_ID]); +- if (id >= VXLAN_VID_MASK) ++ if (id >= VXLAN_N_VID) + return -ERANGE; + } + +-- +2.12.2 + +From f1b3aae1f1bfdbec1956670aa3aa28d25f88d4b3 Mon Sep 17 00:00:00 2001 +From: David Forster +Date: Fri, 24 Feb 2017 14:20:32 +0000 +Subject: [PATCH 076/251] vti6: return GRE_KEY for vti6 +Content-Length: 884 +Lines: 29 + +[ Upstream commit 7dcdf941cdc96692ab99fd790c8cc68945514851 ] + +Align vti6 with vti by returning GRE_KEY flag. This enables iproute2 +to display tunnel keys on "ip -6 tunnel show" + +Signed-off-by: David Forster +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_vti.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c +index 0a8610b33d79..bdcc4d9cedd3 100644 +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -680,6 +680,10 @@ vti6_parm_to_user(struct ip6_tnl_parm2 *u, const struct __ip6_tnl_parm *p) + u->link = p->link; + u->i_key = p->i_key; + u->o_key = p->o_key; ++ if (u->i_key) ++ u->i_flags |= GRE_KEY; ++ if (u->o_key) ++ u->o_flags |= GRE_KEY; + u->proto = p->proto; + + memcpy(u->name, p->name, sizeof(u->name)); +-- +2.12.2 + +From 354f79125f12bcd7352704e770c0b10c4a4b424e Mon Sep 17 00:00:00 2001 +From: Julian Anastasov +Date: Sun, 26 Feb 2017 17:14:35 +0200 +Subject: [PATCH 077/251] ipv4: mask tos for input route +Content-Length: 916 +Lines: 31 + +[ Upstream commit 6e28099d38c0e50d62c1afc054e37e573adf3d21 ] + +Restore the lost masking of TOS in input route code to +allow ip rules to match it properly. + +Problem [1] noticed by Shmulik Ladkani + +[1] http://marc.info/?t=137331755300040&r=1&w=2 + +Fixes: 89aef8921bfb ("ipv4: Delete routing cache.") +Signed-off-by: Julian Anastasov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/route.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index ef2f527a119b..da4d68d78590 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1958,6 +1958,7 @@ int ip_route_input_noref(struct sk_buff *skb, __be32 daddr, __be32 saddr, + { + int res; + ++ tos &= IPTOS_RT_MASK; + rcu_read_lock(); + + /* Multicast recognition logic is moved from route cache to here. +-- +2.12.2 + +From 2cd0afc64e333f2ef62444300418883cff0e79da Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Paul=20H=C3=BCber?= +Date: Sun, 26 Feb 2017 17:58:19 +0100 +Subject: [PATCH 078/251] l2tp: avoid use-after-free caused by + l2tp_ip_backlog_recv +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 923 +Lines: 28 + +[ Upstream commit 51fb60eb162ab84c5edf2ae9c63cf0b878e5547e ] + +l2tp_ip_backlog_recv may not return -1 if the packet gets dropped. +The return value is passed up to ip_local_deliver_finish, which treats +negative values as an IP protocol number for resubmission. + +Signed-off-by: Paul Hüber +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c +index 445b7cd0826a..48ab93842322 100644 +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -383,7 +383,7 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb) + drop: + IP_INC_STATS(sock_net(sk), IPSTATS_MIB_INDISCARDS); + kfree_skb(skb); +- return -1; ++ return 0; + } + + /* Userspace will call sendmsg() on the tunnel socket to send L2TP +-- +2.12.2 + +From f331d6445a3e4013428b06169acf3ae33614e69b Mon Sep 17 00:00:00 2001 +From: Alexander Potapenko +Date: Wed, 1 Mar 2017 12:57:20 +0100 +Subject: [PATCH 079/251] net: don't call strlen() on the user buffer in + packet_bind_spkt() +Content-Length: 3957 +Lines: 104 + +[ Upstream commit 540e2894f7905538740aaf122bd8e0548e1c34a4 ] + +KMSAN (KernelMemorySanitizer, a new error detection tool) reports use of +uninitialized memory in packet_bind_spkt(): +Acked-by: Eric Dumazet + +================================================================== +BUG: KMSAN: use of unitialized memory +CPU: 0 PID: 1074 Comm: packet Not tainted 4.8.0-rc6+ #1891 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs +01/01/2011 + 0000000000000000 ffff88006b6dfc08 ffffffff82559ae8 ffff88006b6dfb48 + ffffffff818a7c91 ffffffff85b9c870 0000000000000092 ffffffff85b9c550 + 0000000000000000 0000000000000092 00000000ec400911 0000000000000002 +Call Trace: + [< inline >] __dump_stack lib/dump_stack.c:15 + [] dump_stack+0x238/0x290 lib/dump_stack.c:51 + [] kmsan_report+0x276/0x2e0 mm/kmsan/kmsan.c:1003 + [] __msan_warning+0x5b/0xb0 +mm/kmsan/kmsan_instr.c:424 + [< inline >] strlen lib/string.c:484 + [] strlcpy+0x9d/0x200 lib/string.c:144 + [] packet_bind_spkt+0x144/0x230 +net/packet/af_packet.c:3132 + [] SYSC_bind+0x40d/0x5f0 net/socket.c:1370 + [] SyS_bind+0x82/0xa0 net/socket.c:1356 + [] entry_SYSCALL_64_fastpath+0x13/0x8f +arch/x86/entry/entry_64.o:? +chained origin: 00000000eba00911 + [] save_stack_trace+0x27/0x50 +arch/x86/kernel/stacktrace.c:67 + [< inline >] kmsan_save_stack_with_flags mm/kmsan/kmsan.c:322 + [< inline >] kmsan_save_stack mm/kmsan/kmsan.c:334 + [] kmsan_internal_chain_origin+0x118/0x1e0 +mm/kmsan/kmsan.c:527 + [] __msan_set_alloca_origin4+0xc3/0x130 +mm/kmsan/kmsan_instr.c:380 + [] SYSC_bind+0x129/0x5f0 net/socket.c:1356 + [] SyS_bind+0x82/0xa0 net/socket.c:1356 + [] entry_SYSCALL_64_fastpath+0x13/0x8f +arch/x86/entry/entry_64.o:? +origin description: ----address@SYSC_bind (origin=00000000eb400911) +================================================================== +(the line numbers are relative to 4.8-rc6, but the bug persists +upstream) + +, when I run the following program as root: + +===================================== + #include + #include + #include + #include + + int main() { + struct sockaddr addr; + memset(&addr, 0xff, sizeof(addr)); + addr.sa_family = AF_PACKET; + int fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL)); + bind(fd, &addr, sizeof(addr)); + return 0; + } +===================================== + +This happens because addr.sa_data copied from the userspace is not +zero-terminated, and copying it with strlcpy() in packet_bind_spkt() +results in calling strlen() on the kernel copy of that non-terminated +buffer. + +Signed-off-by: Alexander Potapenko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index d805cd577a60..3975ac809934 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3021,7 +3021,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, + int addr_len) + { + struct sock *sk = sock->sk; +- char name[15]; ++ char name[sizeof(uaddr->sa_data) + 1]; + + /* + * Check legality +@@ -3029,7 +3029,11 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, + + if (addr_len != sizeof(struct sockaddr)) + return -EINVAL; +- strlcpy(name, uaddr->sa_data, sizeof(name)); ++ /* uaddr->sa_data comes from the userspace, it's not guaranteed to be ++ * zero-terminated. ++ */ ++ memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data)); ++ name[sizeof(uaddr->sa_data)] = 0; + + return packet_do_bind(sk, name, 0, pkt_sk(sk)->num); + } +-- +2.12.2 + +From a70c328597045be2962098916c88ddd172caa054 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 1 Mar 2017 14:28:39 -0800 +Subject: [PATCH 080/251] net: net_enable_timestamp() can be called from irq + contexts +Content-Length: 2734 +Lines: 92 + +[ Upstream commit 13baa00ad01bb3a9f893e3a08cbc2d072fc0c15d ] + +It is now very clear that silly TCP listeners might play with +enabling/disabling timestamping while new children are added +to their accept queue. + +Meaning net_enable_timestamp() can be called from BH context +while current state of the static key is not enabled. + +Lets play safe and allow all contexts. + +The work queue is scheduled only under the problematic cases, +which are the static key enable/disable transition, to not slow down +critical paths. + +This extends and improves what we did in commit 5fa8bbda38c6 ("net: use +a work queue to defer net_disable_timestamp() work") + +Fixes: b90e5794c5bd ("net: dont call jump_label_dec from irq context") +Signed-off-by: Eric Dumazet +Reported-by: Dmitry Vyukov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 35 +++++++++++++++++++++++++++++++---- + 1 file changed, 31 insertions(+), 4 deletions(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 08215a85c742..48399d8ce614 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1677,27 +1677,54 @@ EXPORT_SYMBOL_GPL(net_dec_ingress_queue); + static struct static_key netstamp_needed __read_mostly; + #ifdef HAVE_JUMP_LABEL + static atomic_t netstamp_needed_deferred; ++static atomic_t netstamp_wanted; + static void netstamp_clear(struct work_struct *work) + { + int deferred = atomic_xchg(&netstamp_needed_deferred, 0); ++ int wanted; + +- while (deferred--) +- static_key_slow_dec(&netstamp_needed); ++ wanted = atomic_add_return(deferred, &netstamp_wanted); ++ if (wanted > 0) ++ static_key_enable(&netstamp_needed); ++ else ++ static_key_disable(&netstamp_needed); + } + static DECLARE_WORK(netstamp_work, netstamp_clear); + #endif + + void net_enable_timestamp(void) + { ++#ifdef HAVE_JUMP_LABEL ++ int wanted; ++ ++ while (1) { ++ wanted = atomic_read(&netstamp_wanted); ++ if (wanted <= 0) ++ break; ++ if (atomic_cmpxchg(&netstamp_wanted, wanted, wanted + 1) == wanted) ++ return; ++ } ++ atomic_inc(&netstamp_needed_deferred); ++ schedule_work(&netstamp_work); ++#else + static_key_slow_inc(&netstamp_needed); ++#endif + } + EXPORT_SYMBOL(net_enable_timestamp); + + void net_disable_timestamp(void) + { + #ifdef HAVE_JUMP_LABEL +- /* net_disable_timestamp() can be called from non process context */ +- atomic_inc(&netstamp_needed_deferred); ++ int wanted; ++ ++ while (1) { ++ wanted = atomic_read(&netstamp_wanted); ++ if (wanted <= 1) ++ break; ++ if (atomic_cmpxchg(&netstamp_wanted, wanted, wanted - 1) == wanted) ++ return; ++ } ++ atomic_dec(&netstamp_needed_deferred); + schedule_work(&netstamp_work); + #else + static_key_slow_dec(&netstamp_needed); +-- +2.12.2 + +From 9216632bf4a0bafdc998d1c68b37b70446775900 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Wed, 1 Mar 2017 16:35:07 -0300 +Subject: [PATCH 081/251] dccp: Unlock sock before calling sk_free() +Content-Length: 3158 +Lines: 77 + +[ Upstream commit d5afb6f9b6bb2c57bd0c05e76e12489dc0d037d9 ] + +The code where sk_clone() came from created a new socket and locked it, +but then, on the error path didn't unlock it. + +This problem stayed there for a long while, till b0691c8ee7c2 ("net: +Unlock sock before calling sk_free()") fixed it, but unfortunately the +callers of sk_clone() (now sk_clone_locked()) were not audited and the +one in dccp_create_openreq_child() remained. + +Now in the age of the syskaller fuzzer, this was finally uncovered, as +reported by Dmitry: + + ---- 8< ---- + +I've got the following report while running syzkaller fuzzer on +86292b33d4b7 ("Merge branch 'akpm' (patches from Andrew)") + + [ BUG: held lock freed! ] + 4.10.0+ #234 Not tainted + ------------------------- + syz-executor6/6898 is freeing memory + ffff88006286cac0-ffff88006286d3b7, with a lock still held there! + (slock-AF_INET6){+.-...}, at: [] spin_lock + include/linux/spinlock.h:299 [inline] + (slock-AF_INET6){+.-...}, at: [] + sk_clone_lock+0x3d9/0x12c0 net/core/sock.c:1504 + 5 locks held by syz-executor6/6898: + #0: (sk_lock-AF_INET6){+.+.+.}, at: [] lock_sock + include/net/sock.h:1460 [inline] + #0: (sk_lock-AF_INET6){+.+.+.}, at: [] + inet_stream_connect+0x44/0xa0 net/ipv4/af_inet.c:681 + #1: (rcu_read_lock){......}, at: [] + inet6_csk_xmit+0x12a/0x5d0 net/ipv6/inet6_connection_sock.c:126 + #2: (rcu_read_lock){......}, at: [] __skb_unlink + include/linux/skbuff.h:1767 [inline] + #2: (rcu_read_lock){......}, at: [] __skb_dequeue + include/linux/skbuff.h:1783 [inline] + #2: (rcu_read_lock){......}, at: [] + process_backlog+0x264/0x730 net/core/dev.c:4835 + #3: (rcu_read_lock){......}, at: [] + ip6_input_finish+0x0/0x1700 net/ipv6/ip6_input.c:59 + #4: (slock-AF_INET6){+.-...}, at: [] spin_lock + include/linux/spinlock.h:299 [inline] + #4: (slock-AF_INET6){+.-...}, at: [] + sk_clone_lock+0x3d9/0x12c0 net/core/sock.c:1504 + +Fix it just like was done by b0691c8ee7c2 ("net: Unlock sock before calling +sk_free()"). + +Reported-by: Dmitry Vyukov +Cc: Cong Wang +Cc: Eric Dumazet +Cc: Gerrit Renker +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/20170301153510.GE15145@kernel.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dccp/minisocks.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c +index 1994f8af646b..e314caa39176 100644 +--- a/net/dccp/minisocks.c ++++ b/net/dccp/minisocks.c +@@ -122,6 +122,7 @@ struct sock *dccp_create_openreq_child(const struct sock *sk, + /* It is still raw copy of parent, so invalidate + * destructor and make plain sk_free() */ + newsk->sk_destruct = NULL; ++ bh_unlock_sock(newsk); + sk_free(newsk); + return NULL; + } +-- +2.12.2 + +From 2681a7853ad73bfebc3a683765a496bb283c6648 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 3 Mar 2017 14:08:21 -0800 +Subject: [PATCH 082/251] tcp: fix various issues for sockets morphing to + listen state +Content-Length: 2289 +Lines: 72 + +[ Upstream commit 02b2faaf0af1d85585f6d6980e286d53612acfc2 ] + +Dmitry Vyukov reported a divide by 0 triggered by syzkaller, exploiting +tcp_disconnect() path that was never really considered and/or used +before syzkaller ;) + +I was not able to reproduce the bug, but it seems issues here are the +three possible actions that assumed they would never trigger on a +listener. + +1) tcp_write_timer_handler +2) tcp_delack_timer_handler +3) MTU reduction + +Only IPv6 MTU reduction was properly testing TCP_CLOSE and TCP_LISTEN + states from tcp_v6_mtu_reduced() + +Signed-off-by: Eric Dumazet +Reported-by: Dmitry Vyukov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_ipv4.c | 7 +++++-- + net/ipv4/tcp_timer.c | 6 ++++-- + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index b58a38eea059..f66d4b5d47f9 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -271,10 +271,13 @@ EXPORT_SYMBOL(tcp_v4_connect); + */ + void tcp_v4_mtu_reduced(struct sock *sk) + { +- struct dst_entry *dst; + struct inet_sock *inet = inet_sk(sk); +- u32 mtu = tcp_sk(sk)->mtu_info; ++ struct dst_entry *dst; ++ u32 mtu; + ++ if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) ++ return; ++ mtu = tcp_sk(sk)->mtu_info; + dst = inet_csk_update_pmtu(sk, mtu); + if (!dst) + return; +diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c +index 193ba1fa8a9a..ebb34d0c5e80 100644 +--- a/net/ipv4/tcp_timer.c ++++ b/net/ipv4/tcp_timer.c +@@ -223,7 +223,8 @@ void tcp_delack_timer_handler(struct sock *sk) + + sk_mem_reclaim_partial(sk); + +- if (sk->sk_state == TCP_CLOSE || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) ++ if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || ++ !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) + goto out; + + if (time_after(icsk->icsk_ack.timeout, jiffies)) { +@@ -504,7 +505,8 @@ void tcp_write_timer_handler(struct sock *sk) + struct inet_connection_sock *icsk = inet_csk(sk); + int event; + +- if (sk->sk_state == TCP_CLOSE || !icsk->icsk_pending) ++ if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || ++ !icsk->icsk_pending) + goto out; + + if (time_after(icsk->icsk_timeout, jiffies)) { +-- +2.12.2 + +From 9e7683301beef0cef8254eecb661e7eac3146717 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 3 Mar 2017 21:01:02 -0800 +Subject: [PATCH 083/251] net: fix socket refcounting in + skb_complete_wifi_ack() +Content-Length: 1864 +Lines: 58 + +[ Upstream commit dd4f10722aeb10f4f582948839f066bebe44e5fb ] + +TX skbs do not necessarily hold a reference on skb->sk->sk_refcnt +By the time TX completion happens, sk_refcnt might be already 0. + +sock_hold()/sock_put() would then corrupt critical state, like +sk_wmem_alloc. + +Fixes: bf7fa551e0ce ("mac80211: Resolve sk_refcnt/sk_wmem_alloc issue in wifi ack path") +Signed-off-by: Eric Dumazet +Cc: Alexander Duyck +Cc: Johannes Berg +Cc: Soheil Hassas Yeganeh +Cc: Willem de Bruijn +Acked-by: Soheil Hassas Yeganeh +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 4968b5ddea69..370f4f86e2b5 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3735,7 +3735,7 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) + { + struct sock *sk = skb->sk; + struct sock_exterr_skb *serr; +- int err; ++ int err = 1; + + skb->wifi_acked_valid = 1; + skb->wifi_acked = acked; +@@ -3745,14 +3745,15 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) + serr->ee.ee_errno = ENOMSG; + serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; + +- /* take a reference to prevent skb_orphan() from freeing the socket */ +- sock_hold(sk); +- +- err = sock_queue_err_skb(sk, skb); ++ /* Take a reference to prevent skb_orphan() from freeing the socket, ++ * but only if the socket refcount is not zero. ++ */ ++ if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { ++ err = sock_queue_err_skb(sk, skb); ++ sock_put(sk); ++ } + if (err) + kfree_skb(skb); +- +- sock_put(sk); + } + EXPORT_SYMBOL_GPL(skb_complete_wifi_ack); + +-- +2.12.2 + +From ec4d8692b76e08a40221eb7c74775a390114f098 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 3 Mar 2017 21:01:03 -0800 +Subject: [PATCH 084/251] net: fix socket refcounting in + skb_complete_tx_timestamp() +Content-Length: 1731 +Lines: 49 + +[ Upstream commit 9ac25fc063751379cb77434fef9f3b088cd3e2f7 ] + +TX skbs do not necessarily hold a reference on skb->sk->sk_refcnt +By the time TX completion happens, sk_refcnt might be already 0. + +sock_hold()/sock_put() would then corrupt critical state, like +sk_wmem_alloc and lead to leaks or use after free. + +Fixes: 62bccb8cdb69 ("net-timestamp: Make the clone operation stand-alone from phy timestamping") +Signed-off-by: Eric Dumazet +Cc: Alexander Duyck +Cc: Johannes Berg +Cc: Soheil Hassas Yeganeh +Cc: Willem de Bruijn +Acked-by: Soheil Hassas Yeganeh +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 370f4f86e2b5..73dfd7729bc9 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3678,13 +3678,14 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, + if (!skb_may_tx_timestamp(sk, false)) + return; + +- /* take a reference to prevent skb_orphan() from freeing the socket */ +- sock_hold(sk); +- +- *skb_hwtstamps(skb) = *hwtstamps; +- __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND); +- +- sock_put(sk); ++ /* Take a reference to prevent skb_orphan() from freeing the socket, ++ * but only if the socket refcount is not zero. ++ */ ++ if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { ++ *skb_hwtstamps(skb) = *hwtstamps; ++ __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND); ++ sock_put(sk); ++ } + } + EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); + +-- +2.12.2 + +From d0ebde92fbeb98eedbfce15cef3c86b652846d25 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 5 Mar 2017 10:52:16 -0800 +Subject: [PATCH 085/251] dccp: fix use-after-free in dccp_feat_activate_values +Content-Length: 9868 +Lines: 235 + +[ Upstream commit 62f8f4d9066c1c6f2474845d1ca7e2891f2ae3fd ] + +Dmitry reported crashes in DCCP stack [1] + +Problem here is that when I got rid of listener spinlock, I missed the +fact that DCCP stores a complex state in struct dccp_request_sock, +while TCP does not. + +Since multiple cpus could access it at the same time, we need to add +protection. + +[1] +BUG: KASAN: use-after-free in dccp_feat_activate_values+0x967/0xab0 +net/dccp/feat.c:1541 at addr ffff88003713be68 +Read of size 8 by task syz-executor2/8457 +CPU: 2 PID: 8457 Comm: syz-executor2 Not tainted 4.10.0-rc7+ #127 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +Call Trace: + + __dump_stack lib/dump_stack.c:15 [inline] + dump_stack+0x292/0x398 lib/dump_stack.c:51 + kasan_object_err+0x1c/0x70 mm/kasan/report.c:162 + print_address_description mm/kasan/report.c:200 [inline] + kasan_report_error mm/kasan/report.c:289 [inline] + kasan_report.part.1+0x20e/0x4e0 mm/kasan/report.c:311 + kasan_report mm/kasan/report.c:332 [inline] + __asan_report_load8_noabort+0x29/0x30 mm/kasan/report.c:332 + dccp_feat_activate_values+0x967/0xab0 net/dccp/feat.c:1541 + dccp_create_openreq_child+0x464/0x610 net/dccp/minisocks.c:121 + dccp_v6_request_recv_sock+0x1f6/0x1960 net/dccp/ipv6.c:457 + dccp_check_req+0x335/0x5a0 net/dccp/minisocks.c:186 + dccp_v6_rcv+0x69e/0x1d00 net/dccp/ipv6.c:711 + ip6_input_finish+0x46d/0x17a0 net/ipv6/ip6_input.c:279 + NF_HOOK include/linux/netfilter.h:257 [inline] + ip6_input+0xdb/0x590 net/ipv6/ip6_input.c:322 + dst_input include/net/dst.h:507 [inline] + ip6_rcv_finish+0x289/0x890 net/ipv6/ip6_input.c:69 + NF_HOOK include/linux/netfilter.h:257 [inline] + ipv6_rcv+0x12ec/0x23d0 net/ipv6/ip6_input.c:203 + __netif_receive_skb_core+0x1ae5/0x3400 net/core/dev.c:4190 + __netif_receive_skb+0x2a/0x170 net/core/dev.c:4228 + process_backlog+0xe5/0x6c0 net/core/dev.c:4839 + napi_poll net/core/dev.c:5202 [inline] + net_rx_action+0xe70/0x1900 net/core/dev.c:5267 + __do_softirq+0x2fb/0xb7d kernel/softirq.c:284 + do_softirq_own_stack+0x1c/0x30 arch/x86/entry/entry_64.S:902 + + do_softirq.part.17+0x1e8/0x230 kernel/softirq.c:328 + do_softirq kernel/softirq.c:176 [inline] + __local_bh_enable_ip+0x1f2/0x200 kernel/softirq.c:181 + local_bh_enable include/linux/bottom_half.h:31 [inline] + rcu_read_unlock_bh include/linux/rcupdate.h:971 [inline] + ip6_finish_output2+0xbb0/0x23d0 net/ipv6/ip6_output.c:123 + ip6_finish_output+0x302/0x960 net/ipv6/ip6_output.c:148 + NF_HOOK_COND include/linux/netfilter.h:246 [inline] + ip6_output+0x1cb/0x8d0 net/ipv6/ip6_output.c:162 + ip6_xmit+0xcdf/0x20d0 include/net/dst.h:501 + inet6_csk_xmit+0x320/0x5f0 net/ipv6/inet6_connection_sock.c:179 + dccp_transmit_skb+0xb09/0x1120 net/dccp/output.c:141 + dccp_xmit_packet+0x215/0x760 net/dccp/output.c:280 + dccp_write_xmit+0x168/0x1d0 net/dccp/output.c:362 + dccp_sendmsg+0x79c/0xb10 net/dccp/proto.c:796 + inet_sendmsg+0x164/0x5b0 net/ipv4/af_inet.c:744 + sock_sendmsg_nosec net/socket.c:635 [inline] + sock_sendmsg+0xca/0x110 net/socket.c:645 + SYSC_sendto+0x660/0x810 net/socket.c:1687 + SyS_sendto+0x40/0x50 net/socket.c:1655 + entry_SYSCALL_64_fastpath+0x1f/0xc2 +RIP: 0033:0x4458b9 +RSP: 002b:00007f8ceb77bb58 EFLAGS: 00000282 ORIG_RAX: 000000000000002c +RAX: ffffffffffffffda RBX: 0000000000000017 RCX: 00000000004458b9 +RDX: 0000000000000023 RSI: 0000000020e60000 RDI: 0000000000000017 +RBP: 00000000006e1b90 R08: 00000000200f9fe1 R09: 0000000000000020 +R10: 0000000000008010 R11: 0000000000000282 R12: 00000000007080a8 +R13: 0000000000000000 R14: 00007f8ceb77c9c0 R15: 00007f8ceb77c700 +Object at ffff88003713be50, in cache kmalloc-64 size: 64 +Allocated: +PID = 8446 + save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57 + save_stack+0x43/0xd0 mm/kasan/kasan.c:502 + set_track mm/kasan/kasan.c:514 [inline] + kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:605 + kmem_cache_alloc_trace+0x82/0x270 mm/slub.c:2738 + kmalloc include/linux/slab.h:490 [inline] + dccp_feat_entry_new+0x214/0x410 net/dccp/feat.c:467 + dccp_feat_push_change+0x38/0x220 net/dccp/feat.c:487 + __feat_register_sp+0x223/0x2f0 net/dccp/feat.c:741 + dccp_feat_propagate_ccid+0x22b/0x2b0 net/dccp/feat.c:949 + dccp_feat_server_ccid_dependencies+0x1b3/0x250 net/dccp/feat.c:1012 + dccp_make_response+0x1f1/0xc90 net/dccp/output.c:423 + dccp_v6_send_response+0x4ec/0xc20 net/dccp/ipv6.c:217 + dccp_v6_conn_request+0xaba/0x11b0 net/dccp/ipv6.c:377 + dccp_rcv_state_process+0x51e/0x1650 net/dccp/input.c:606 + dccp_v6_do_rcv+0x213/0x350 net/dccp/ipv6.c:632 + sk_backlog_rcv include/net/sock.h:893 [inline] + __sk_receive_skb+0x36f/0xcc0 net/core/sock.c:479 + dccp_v6_rcv+0xba5/0x1d00 net/dccp/ipv6.c:742 + ip6_input_finish+0x46d/0x17a0 net/ipv6/ip6_input.c:279 + NF_HOOK include/linux/netfilter.h:257 [inline] + ip6_input+0xdb/0x590 net/ipv6/ip6_input.c:322 + dst_input include/net/dst.h:507 [inline] + ip6_rcv_finish+0x289/0x890 net/ipv6/ip6_input.c:69 + NF_HOOK include/linux/netfilter.h:257 [inline] + ipv6_rcv+0x12ec/0x23d0 net/ipv6/ip6_input.c:203 + __netif_receive_skb_core+0x1ae5/0x3400 net/core/dev.c:4190 + __netif_receive_skb+0x2a/0x170 net/core/dev.c:4228 + process_backlog+0xe5/0x6c0 net/core/dev.c:4839 + napi_poll net/core/dev.c:5202 [inline] + net_rx_action+0xe70/0x1900 net/core/dev.c:5267 + __do_softirq+0x2fb/0xb7d kernel/softirq.c:284 +Freed: +PID = 15 + save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57 + save_stack+0x43/0xd0 mm/kasan/kasan.c:502 + set_track mm/kasan/kasan.c:514 [inline] + kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:578 + slab_free_hook mm/slub.c:1355 [inline] + slab_free_freelist_hook mm/slub.c:1377 [inline] + slab_free mm/slub.c:2954 [inline] + kfree+0xe8/0x2b0 mm/slub.c:3874 + dccp_feat_entry_destructor.part.4+0x48/0x60 net/dccp/feat.c:418 + dccp_feat_entry_destructor net/dccp/feat.c:416 [inline] + dccp_feat_list_pop net/dccp/feat.c:541 [inline] + dccp_feat_activate_values+0x57f/0xab0 net/dccp/feat.c:1543 + dccp_create_openreq_child+0x464/0x610 net/dccp/minisocks.c:121 + dccp_v6_request_recv_sock+0x1f6/0x1960 net/dccp/ipv6.c:457 + dccp_check_req+0x335/0x5a0 net/dccp/minisocks.c:186 + dccp_v6_rcv+0x69e/0x1d00 net/dccp/ipv6.c:711 + ip6_input_finish+0x46d/0x17a0 net/ipv6/ip6_input.c:279 + NF_HOOK include/linux/netfilter.h:257 [inline] + ip6_input+0xdb/0x590 net/ipv6/ip6_input.c:322 + dst_input include/net/dst.h:507 [inline] + ip6_rcv_finish+0x289/0x890 net/ipv6/ip6_input.c:69 + NF_HOOK include/linux/netfilter.h:257 [inline] + ipv6_rcv+0x12ec/0x23d0 net/ipv6/ip6_input.c:203 + __netif_receive_skb_core+0x1ae5/0x3400 net/core/dev.c:4190 + __netif_receive_skb+0x2a/0x170 net/core/dev.c:4228 + process_backlog+0xe5/0x6c0 net/core/dev.c:4839 + napi_poll net/core/dev.c:5202 [inline] + net_rx_action+0xe70/0x1900 net/core/dev.c:5267 + __do_softirq+0x2fb/0xb7d kernel/softirq.c:284 +Memory state around the buggy address: + ffff88003713bd00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ffff88003713bd80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +>ffff88003713be00: fc fc fc fc fc fc fc fc fc fc fb fb fb fb fb fb + ^ + +Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table") +Signed-off-by: Eric Dumazet +Reported-by: Dmitry Vyukov +Tested-by: Dmitry Vyukov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/dccp.h | 1 + + net/dccp/minisocks.c | 24 ++++++++++++++++-------- + 2 files changed, 17 insertions(+), 8 deletions(-) + +diff --git a/include/linux/dccp.h b/include/linux/dccp.h +index 61d042bbbf60..68449293c4b6 100644 +--- a/include/linux/dccp.h ++++ b/include/linux/dccp.h +@@ -163,6 +163,7 @@ struct dccp_request_sock { + __u64 dreq_isr; + __u64 dreq_gsr; + __be32 dreq_service; ++ spinlock_t dreq_lock; + struct list_head dreq_featneg; + __u32 dreq_timestamp_echo; + __u32 dreq_timestamp_time; +diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c +index e314caa39176..68eed344b471 100644 +--- a/net/dccp/minisocks.c ++++ b/net/dccp/minisocks.c +@@ -146,6 +146,13 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, + struct dccp_request_sock *dreq = dccp_rsk(req); + bool own_req; + ++ /* TCP/DCCP listeners became lockless. ++ * DCCP stores complex state in its request_sock, so we need ++ * a protection for them, now this code runs without being protected ++ * by the parent (listener) lock. ++ */ ++ spin_lock_bh(&dreq->dreq_lock); ++ + /* Check for retransmitted REQUEST */ + if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) { + +@@ -160,7 +167,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, + inet_rtx_syn_ack(sk, req); + } + /* Network Duplicate, discard packet */ +- return NULL; ++ goto out; + } + + DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; +@@ -186,20 +193,20 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, + + child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, + req, &own_req); +- if (!child) +- goto listen_overflow; +- +- return inet_csk_complete_hashdance(sk, child, req, own_req); ++ if (child) { ++ child = inet_csk_complete_hashdance(sk, child, req, own_req); ++ goto out; ++ } + +-listen_overflow: +- dccp_pr_debug("listen_overflow!\n"); + DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY; + drop: + if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET) + req->rsk_ops->send_reset(sk, skb); + + inet_csk_reqsk_queue_drop(sk, req); +- return NULL; ++out: ++ spin_unlock_bh(&dreq->dreq_lock); ++ return child; + } + + EXPORT_SYMBOL_GPL(dccp_check_req); +@@ -250,6 +257,7 @@ int dccp_reqsk_init(struct request_sock *req, + { + struct dccp_request_sock *dreq = dccp_rsk(req); + ++ spin_lock_init(&dreq->dreq_lock); + inet_rsk(req)->ir_rmt_port = dccp_hdr(skb)->dccph_sport; + inet_rsk(req)->ir_num = ntohs(dccp_hdr(skb)->dccph_dport); + inet_rsk(req)->acked = 0; +-- +2.12.2 + +From e671f1cc588f380b17e1c0ce38c7c712d13dfe93 Mon Sep 17 00:00:00 2001 +From: David Ahern +Date: Mon, 6 Mar 2017 08:53:04 -0800 +Subject: [PATCH 086/251] vrf: Fix use-after-free in vrf_xmit +Content-Length: 1945 +Lines: 52 + +[ Upstream commit f7887d40e541f74402df0684a1463c0a0bb68c68 ] + +KASAN detected a use-after-free: + +[ 269.467067] BUG: KASAN: use-after-free in vrf_xmit+0x7f1/0x827 [vrf] at addr ffff8800350a21c0 +[ 269.467067] Read of size 4 by task ssh/1879 +[ 269.467067] CPU: 1 PID: 1879 Comm: ssh Not tainted 4.10.0+ #249 +[ 269.467067] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014 +[ 269.467067] Call Trace: +[ 269.467067] dump_stack+0x81/0xb6 +[ 269.467067] kasan_object_err+0x21/0x78 +[ 269.467067] kasan_report+0x2f7/0x450 +[ 269.467067] ? vrf_xmit+0x7f1/0x827 [vrf] +[ 269.467067] ? ip_output+0xa4/0xdb +[ 269.467067] __asan_load4+0x6b/0x6d +[ 269.467067] vrf_xmit+0x7f1/0x827 [vrf] +... + +Which corresponds to the skb access after xmit handling. Fix by saving +skb->len and using the saved value to update stats. + +Fixes: 193125dbd8eb2 ("net: Introduce VRF device driver") +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vrf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c +index d6b619667f1a..349aecbc210a 100644 +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -345,6 +345,7 @@ static netdev_tx_t is_ip_tx_frame(struct sk_buff *skb, struct net_device *dev) + + static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) + { ++ int len = skb->len; + netdev_tx_t ret = is_ip_tx_frame(skb, dev); + + if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { +@@ -352,7 +353,7 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) + + u64_stats_update_begin(&dstats->syncp); + dstats->tx_pkts++; +- dstats->tx_bytes += skb->len; ++ dstats->tx_bytes += len; + u64_stats_update_end(&dstats->syncp); + } else { + this_cpu_inc(dev->dstats->tx_drps); +-- +2.12.2 + +From 6c72458ab428ce659261fa060295e580503a5b12 Mon Sep 17 00:00:00 2001 +From: "Dmitry V. Levin" +Date: Tue, 7 Mar 2017 23:50:50 +0300 +Subject: [PATCH 087/251] uapi: fix linux/packet_diag.h userspace compilation + error +Content-Length: 1344 +Lines: 40 + +[ Upstream commit 745cb7f8a5de0805cade3de3991b7a95317c7c73 ] + +Replace MAX_ADDR_LEN with its numeric value to fix the following +linux/packet_diag.h userspace compilation error: + +/usr/include/linux/packet_diag.h:67:17: error: 'MAX_ADDR_LEN' undeclared here (not in a function) + __u8 pdmc_addr[MAX_ADDR_LEN]; + +This is not the first case in the UAPI where the numeric value +of MAX_ADDR_LEN is used instead of symbolic one, uapi/linux/if_link.h +already does the same: + +$ grep MAX_ADDR_LEN include/uapi/linux/if_link.h + __u8 mac[32]; /* MAX_ADDR_LEN */ + +There are no UAPI headers besides these two that use MAX_ADDR_LEN. + +Signed-off-by: Dmitry V. Levin +Acked-by: Pavel Emelyanov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/packet_diag.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/uapi/linux/packet_diag.h b/include/uapi/linux/packet_diag.h +index d08c63f3dd6f..0c5d5dd61b6a 100644 +--- a/include/uapi/linux/packet_diag.h ++++ b/include/uapi/linux/packet_diag.h +@@ -64,7 +64,7 @@ struct packet_diag_mclist { + __u32 pdmc_count; + __u16 pdmc_type; + __u16 pdmc_alen; +- __u8 pdmc_addr[MAX_ADDR_LEN]; ++ __u8 pdmc_addr[32]; /* MAX_ADDR_LEN */ + }; + + struct packet_diag_ring { +-- +2.12.2 + +From 710fbeb3f5c5441fbe002b2c1566ceaad0725c01 Mon Sep 17 00:00:00 2001 +From: Etienne Noss +Date: Fri, 10 Mar 2017 16:55:32 +0100 +Subject: [PATCH 088/251] act_connmark: avoid crashing on malformed nlattrs + with null parms +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 2433 +Lines: 53 + +[ Upstream commit 52491c7607c5527138095edf44c53169dc1ddb82 ] + +tcf_connmark_init does not check in its configuration if TCA_CONNMARK_PARMS +is set, resulting in a null pointer dereference when trying to access it. + +[501099.043007] BUG: unable to handle kernel NULL pointer dereference at 0000000000000004 +[501099.043039] IP: [] tcf_connmark_init+0x8b/0x180 [act_connmark] +... +[501099.044334] Call Trace: +[501099.044345] [] ? tcf_action_init_1+0x198/0x1b0 +[501099.044363] [] ? tcf_action_init+0xb0/0x120 +[501099.044380] [] ? tcf_exts_validate+0xc4/0x110 +[501099.044398] [] ? u32_set_parms+0xa7/0x270 [cls_u32] +[501099.044417] [] ? u32_change+0x680/0x87b [cls_u32] +[501099.044436] [] ? tc_ctl_tfilter+0x4dd/0x8a0 +[501099.044454] [] ? security_capable+0x41/0x60 +[501099.044471] [] ? rtnetlink_rcv_msg+0xe1/0x220 +[501099.044490] [] ? rtnl_newlink+0x870/0x870 +[501099.044507] [] ? netlink_rcv_skb+0xa1/0xc0 +[501099.044524] [] ? rtnetlink_rcv+0x24/0x30 +[501099.044541] [] ? netlink_unicast+0x184/0x230 +[501099.044558] [] ? netlink_sendmsg+0x2f8/0x3b0 +[501099.044576] [] ? sock_sendmsg+0x30/0x40 +[501099.044592] [] ? SYSC_sendto+0xd3/0x150 +[501099.044608] [] ? __do_page_fault+0x2d1/0x510 +[501099.044626] [] ? system_call_fast_compare_end+0xc/0x9b + +Fixes: 22a5dc0e5e3e ("net: sched: Introduce connmark action") +Signed-off-by: Étienne Noss +Signed-off-by: Victorien Molle +Acked-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/act_connmark.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c +index bb41699c6c49..7ecb14f3db54 100644 +--- a/net/sched/act_connmark.c ++++ b/net/sched/act_connmark.c +@@ -109,6 +109,9 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, + if (ret < 0) + return ret; + ++ if (!tb[TCA_CONNMARK_PARMS]) ++ return -EINVAL; ++ + parm = nla_data(tb[TCA_CONNMARK_PARMS]); + + if (!tcf_hash_check(parm->index, a, bind)) { +-- +2.12.2 + +From b57955ea30e13aa37e5955bf20617f839f32c560 Mon Sep 17 00:00:00 2001 +From: David Ahern +Date: Fri, 10 Mar 2017 09:46:15 -0800 +Subject: [PATCH 089/251] mpls: Send route delete notifications when router + module is unloaded +Content-Length: 1050 +Lines: 29 + +[ Upstream commit e37791ec1ad785b59022ae211f63a16189bacebf ] + +When the mpls_router module is unloaded, mpls routes are deleted but +notifications are not sent to userspace leaving userspace caches +out of sync. Add the call to mpls_notify_route in mpls_net_exit as +routes are freed. + +Fixes: 0189197f44160 ("mpls: Basic routing support") +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/mpls/af_mpls.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c +index 881bc2072809..52cfc4478511 100644 +--- a/net/mpls/af_mpls.c ++++ b/net/mpls/af_mpls.c +@@ -1567,6 +1567,7 @@ static void mpls_net_exit(struct net *net) + for (index = 0; index < platform_labels; index++) { + struct mpls_route *rt = rtnl_dereference(platform_label[index]); + RCU_INIT_POINTER(platform_label[index], NULL); ++ mpls_notify_route(net, index, rt, NULL, NULL); + mpls_rt_free(rt); + } + rtnl_unlock(); +-- +2.12.2 + +From 5f8bc3856e285cc12597879039c17f7397f4b37d Mon Sep 17 00:00:00 2001 +From: Sabrina Dubroca +Date: Mon, 13 Mar 2017 13:28:09 +0100 +Subject: [PATCH 090/251] ipv6: make ECMP route replacement less greedy +Content-Length: 2282 +Lines: 67 + +[ Upstream commit 67e194007be08d071294456274dd53e0a04fdf90 ] + +Commit 27596472473a ("ipv6: fix ECMP route replacement") introduced a +loop that removes all siblings of an ECMP route that is being +replaced. However, this loop doesn't stop when it has replaced +siblings, and keeps removing other routes with a higher metric. +We also end up triggering the WARN_ON after the loop, because after +this nsiblings < 0. + +Instead, stop the loop when we have taken care of all routes with the +same metric as the route being replaced. + + Reproducer: + =========== + #!/bin/sh + + ip netns add ns1 + ip netns add ns2 + ip -net ns1 link set lo up + + for x in 0 1 2 ; do + ip link add veth$x netns ns2 type veth peer name eth$x netns ns1 + ip -net ns1 link set eth$x up + ip -net ns2 link set veth$x up + done + + ip -net ns1 -6 r a 2000::/64 nexthop via fe80::0 dev eth0 \ + nexthop via fe80::1 dev eth1 nexthop via fe80::2 dev eth2 + ip -net ns1 -6 r a 2000::/64 via fe80::42 dev eth0 metric 256 + ip -net ns1 -6 r a 2000::/64 via fe80::43 dev eth0 metric 2048 + + echo "before replace, 3 routes" + ip -net ns1 -6 r | grep -v '^fe80\|^ff00' + echo + + ip -net ns1 -6 r c 2000::/64 nexthop via fe80::4 dev eth0 \ + nexthop via fe80::5 dev eth1 nexthop via fe80::6 dev eth2 + + echo "after replace, only 2 routes, metric 2048 is gone" + ip -net ns1 -6 r | grep -v '^fe80\|^ff00' + +Fixes: 27596472473a ("ipv6: fix ECMP route replacement") +Signed-off-by: Sabrina Dubroca +Acked-by: Nicolas Dichtel +Reviewed-by: Xin Long +Reviewed-by: Michal Kubecek +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_fib.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 34cf46d74554..85bf86458706 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -903,6 +903,8 @@ add: + ins = &rt->dst.rt6_next; + iter = *ins; + while (iter) { ++ if (iter->rt6i_metric > rt->rt6i_metric) ++ break; + if (rt6_qualify_for_ecmp(iter)) { + *ins = iter->dst.rt6_next; + fib6_purge_rt(iter, fn, info->nl_net); +-- +2.12.2 + +From aed728c38c483650885dfd975dd9f4903e5505bf Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 13 Mar 2017 16:24:28 +0100 +Subject: [PATCH 091/251] ipv6: avoid write to a possibly cloned skb +Content-Length: 1969 +Lines: 61 + +[ Upstream commit 79e49503efe53a8c51d8b695bedc8a346c5e4a87 ] + +ip6_fragment, in case skb has a fraglist, checks if the +skb is cloned. If it is, it will move to the 'slow path' and allocates +new skbs for each fragment. + +However, right before entering the slowpath loop, it updates the +nexthdr value of the last ipv6 extension header to NEXTHDR_FRAGMENT, +to account for the fragment header that will be inserted in the new +ipv6-fragment skbs. + +In case original skb is cloned this munges nexthdr value of another +skb. Avoid this by doing the nexthdr update for each of the new fragment +skbs separately. + +This was observed with tcpdump on a bridge device where netfilter ipv6 +reassembly is active: tcpdump shows malformed fragment headers as +the l4 header (icmpv6, tcp, etc). is decoded as a fragment header. + +Cc: Hannes Frederic Sowa +Reported-by: Andreas Karis +Signed-off-by: Florian Westphal +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 58900c21e4e4..8004532fa882 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -742,13 +742,14 @@ slow_path: + * Fragment the datagram. + */ + +- *prevhdr = NEXTHDR_FRAGMENT; + troom = rt->dst.dev->needed_tailroom; + + /* + * Keep copying data until we run out. + */ + while (left > 0) { ++ u8 *fragnexthdr_offset; ++ + len = left; + /* IF: it doesn't fit, use 'mtu' - the data space left */ + if (len > mtu) +@@ -793,6 +794,10 @@ slow_path: + */ + skb_copy_from_linear_data(skb, skb_network_header(frag), hlen); + ++ fragnexthdr_offset = skb_network_header(frag); ++ fragnexthdr_offset += prevhdr - skb_network_header(skb); ++ *fragnexthdr_offset = NEXTHDR_FRAGMENT; ++ + /* + * Build fragment header. + */ +-- +2.12.2 + +From 56f9b9502f2d15b9c7b83f9cfb32798e2e364f61 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 13 Mar 2017 17:38:17 +0100 +Subject: [PATCH 092/251] bridge: drop netfilter fake rtable unconditionally +Content-Length: 2943 +Lines: 81 + +[ Upstream commit a13b2082ece95247779b9995c4e91b4246bed023 ] + +Andreas reports kernel oops during rmmod of the br_netfilter module. +Hannes debugged the oops down to a NULL rt6info->rt6i_indev. + +Problem is that br_netfilter has the nasty concept of adding a fake +rtable to skb->dst; this happens in a br_netfilter prerouting hook. + +A second hook (in bridge LOCAL_IN) is supposed to remove these again +before the skb is handed up the stack. + +However, on module unload hooks get unregistered which means an +skb could traverse the prerouting hook that attaches the fake_rtable, +while the 'fake rtable remove' hook gets removed from the hooklist +immediately after. + +Fixes: 34666d467cbf1e2e3c7 ("netfilter: bridge: move br_netfilter out of the core") +Reported-by: Andreas Karis +Debugged-by: Hannes Frederic Sowa +Signed-off-by: Florian Westphal +Acked-by: Pablo Neira Ayuso +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_input.c | 1 + + net/bridge/br_netfilter_hooks.c | 21 --------------------- + 2 files changed, 1 insertion(+), 21 deletions(-) + +diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c +index f7fba74108a9..e24754a0e052 100644 +--- a/net/bridge/br_input.c ++++ b/net/bridge/br_input.c +@@ -29,6 +29,7 @@ EXPORT_SYMBOL(br_should_route_hook); + static int + br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) + { ++ br_drop_fake_rtable(skb); + return netif_receive_skb(skb); + } + +diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c +index 7ddbe7ec81d6..97fc19f001bf 100644 +--- a/net/bridge/br_netfilter_hooks.c ++++ b/net/bridge/br_netfilter_hooks.c +@@ -516,21 +516,6 @@ static unsigned int br_nf_pre_routing(void *priv, + } + + +-/* PF_BRIDGE/LOCAL_IN ************************************************/ +-/* The packet is locally destined, which requires a real +- * dst_entry, so detach the fake one. On the way up, the +- * packet would pass through PRE_ROUTING again (which already +- * took place when the packet entered the bridge), but we +- * register an IPv4 PRE_ROUTING 'sabotage' hook that will +- * prevent this from happening. */ +-static unsigned int br_nf_local_in(void *priv, +- struct sk_buff *skb, +- const struct nf_hook_state *state) +-{ +- br_drop_fake_rtable(skb); +- return NF_ACCEPT; +-} +- + /* PF_BRIDGE/FORWARD *************************************************/ + static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb) + { +@@ -901,12 +886,6 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = { + .priority = NF_BR_PRI_BRNF, + }, + { +- .hook = br_nf_local_in, +- .pf = NFPROTO_BRIDGE, +- .hooknum = NF_BR_LOCAL_IN, +- .priority = NF_BR_PRI_BRNF, +- }, +- { + .hook = br_nf_forward_ip, + .pf = NFPROTO_BRIDGE, + .hooknum = NF_BR_FORWARD, +-- +2.12.2 + +From 4ab956b561334866dfe1b17d9c7567313e07cfa2 Mon Sep 17 00:00:00 2001 +From: Jon Maxwell +Date: Fri, 10 Mar 2017 16:40:33 +1100 +Subject: [PATCH 093/251] dccp/tcp: fix routing redirect race +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 5663 +Lines: 162 + +[ Upstream commit 45caeaa5ac0b4b11784ac6f932c0ad4c6b67cda0 ] + +As Eric Dumazet pointed out this also needs to be fixed in IPv6. +v2: Contains the IPv6 tcp/Ipv6 dccp patches as well. + +We have seen a few incidents lately where a dst_enty has been freed +with a dangling TCP socket reference (sk->sk_dst_cache) pointing to that +dst_entry. If the conditions/timings are right a crash then ensues when the +freed dst_entry is referenced later on. A Common crashing back trace is: + + #8 [] page_fault at ffffffff8163e648 + [exception RIP: __tcp_ack_snd_check+74] +. +. + #9 [] tcp_rcv_established at ffffffff81580b64 +#10 [] tcp_v4_do_rcv at ffffffff8158b54a +#11 [] tcp_v4_rcv at ffffffff8158cd02 +#12 [] ip_local_deliver_finish at ffffffff815668f4 +#13 [] ip_local_deliver at ffffffff81566bd9 +#14 [] ip_rcv_finish at ffffffff8156656d +#15 [] ip_rcv at ffffffff81566f06 +#16 [] __netif_receive_skb_core at ffffffff8152b3a2 +#17 [] __netif_receive_skb at ffffffff8152b608 +#18 [] netif_receive_skb at ffffffff8152b690 +#19 [] vmxnet3_rq_rx_complete at ffffffffa015eeaf [vmxnet3] +#20 [] vmxnet3_poll_rx_only at ffffffffa015f32a [vmxnet3] +#21 [] net_rx_action at ffffffff8152bac2 +#22 [] __do_softirq at ffffffff81084b4f +#23 [] call_softirq at ffffffff8164845c +#24 [] do_softirq at ffffffff81016fc5 +#25 [] irq_exit at ffffffff81084ee5 +#26 [] do_IRQ at ffffffff81648ff8 + +Of course it may happen with other NIC drivers as well. + +It's found the freed dst_entry here: + + 224 static bool tcp_in_quickack_mode(struct sock *sk)↩ + 225 {↩ + 226 ▹ const struct inet_connection_sock *icsk = inet_csk(sk);↩ + 227 ▹ const struct dst_entry *dst = __sk_dst_get(sk);↩ + 228 ↩ + 229 ▹ return (dst && dst_metric(dst, RTAX_QUICKACK)) ||↩ + 230 ▹ ▹ (icsk->icsk_ack.quick && !icsk->icsk_ack.pingpong);↩ + 231 }↩ + +But there are other backtraces attributed to the same freed dst_entry in +netfilter code as well. + +All the vmcores showed 2 significant clues: + +- Remote hosts behind the default gateway had always been redirected to a +different gateway. A rtable/dst_entry will be added for that host. Making +more dst_entrys with lower reference counts. Making this more probable. + +- All vmcores showed a postitive LockDroppedIcmps value, e.g: + +LockDroppedIcmps 267 + +A closer look at the tcp_v4_err() handler revealed that do_redirect() will run +regardless of whether user space has the socket locked. This can result in a +race condition where the same dst_entry cached in sk->sk_dst_entry can be +decremented twice for the same socket via: + +do_redirect()->__sk_dst_check()-> dst_release(). + +Which leads to the dst_entry being prematurely freed with another socket +pointing to it via sk->sk_dst_cache and a subsequent crash. + +To fix this skip do_redirect() if usespace has the socket locked. Instead let +the redirect take place later when user space does not have the socket +locked. + +The dccp/IPv6 code is very similar in this respect, so fixing it there too. + +As Eric Garver pointed out the following commit now invalidates routes. Which +can set the dst->obsolete flag so that ipv4_dst_check() returns null and +triggers the dst_release(). + +Fixes: ceb3320610d6 ("ipv4: Kill routes during PMTU/redirect updates.") +Cc: Eric Garver +Cc: Hannes Sowa +Signed-off-by: Jon Maxwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dccp/ipv4.c | 3 ++- + net/dccp/ipv6.c | 8 +++++--- + net/ipv4/tcp_ipv4.c | 3 ++- + net/ipv6/tcp_ipv6.c | 8 +++++--- + 4 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index 0759f5b9180e..6467bf392e1b 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -289,7 +289,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) + + switch (type) { + case ICMP_REDIRECT: +- dccp_do_redirect(skb, sk); ++ if (!sock_owned_by_user(sk)) ++ dccp_do_redirect(skb, sk); + goto out; + case ICMP_SOURCE_QUENCH: + /* Just silently ignore these. */ +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index 27c4e81efa24..8113ad58fcb4 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -122,10 +122,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + np = inet6_sk(sk); + + if (type == NDISC_REDIRECT) { +- struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); ++ if (!sock_owned_by_user(sk)) { ++ struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); + +- if (dst) +- dst->ops->redirect(dst, sk, skb); ++ if (dst) ++ dst->ops->redirect(dst, sk, skb); ++ } + goto out; + } + +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index f66d4b5d47f9..198fc2314c82 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -423,7 +423,8 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) + + switch (type) { + case ICMP_REDIRECT: +- do_redirect(icmp_skb, sk); ++ if (!sock_owned_by_user(sk)) ++ do_redirect(icmp_skb, sk); + goto out; + case ICMP_SOURCE_QUENCH: + /* Just silently ignore these. */ +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 76a8c8057a23..1a63c4deef26 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -376,10 +376,12 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + np = inet6_sk(sk); + + if (type == NDISC_REDIRECT) { +- struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); ++ if (!sock_owned_by_user(sk)) { ++ struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); + +- if (dst) +- dst->ops->redirect(dst, sk, skb); ++ if (dst) ++ dst->ops->redirect(dst, sk, skb); ++ } + goto out; + } + +-- +2.12.2 + +From 676fe978525d3d3f583e1f6463f3b25623e81afd Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Mon, 13 Mar 2017 00:01:30 +0100 +Subject: [PATCH 094/251] dccp: fix memory leak during tear-down of + unsuccessful connection request +Content-Length: 1037 +Lines: 29 + +[ Upstream commit 72ef9c4125c7b257e3a714d62d778ab46583d6a3 ] + +This patch fixes a memory leak, which happens if the connection request +is not fulfilled between parsing the DCCP options and handling the SYN +(because e.g. the backlog is full), because we forgot to free the +list of ack vectors. + +Reported-by: Jianwen Ji +Signed-off-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dccp/ccids/ccid2.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c +index f053198e730c..5e3a7302f774 100644 +--- a/net/dccp/ccids/ccid2.c ++++ b/net/dccp/ccids/ccid2.c +@@ -749,6 +749,7 @@ static void ccid2_hc_tx_exit(struct sock *sk) + for (i = 0; i < hc->tx_seqbufc; i++) + kfree(hc->tx_seqbuf[i]); + hc->tx_seqbufc = 0; ++ dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); + } + + static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) +-- +2.12.2 + +From c10ffe988f15a0306d5d8cb1c6b475c9fe2fc2c9 Mon Sep 17 00:00:00 2001 +From: Roman Mashak +Date: Fri, 24 Feb 2017 11:00:32 -0500 +Subject: [PATCH 095/251] net sched actions: decrement module reference count + after table flush. +Content-Length: 2407 +Lines: 90 + +[ Upstream commit edb9d1bff4bbe19b8ae0e71b1f38732591a9eeb2 ] + +When tc actions are loaded as a module and no actions have been installed, +flushing them would result in actions removed from the memory, but modules +reference count not being decremented, so that the modules would not be +unloaded. + +Following is example with GACT action: + +% sudo modprobe act_gact +% lsmod +Module Size Used by +act_gact 16384 0 +% +% sudo tc actions ls action gact +% +% sudo tc actions flush action gact +% lsmod +Module Size Used by +act_gact 16384 1 +% sudo tc actions flush action gact +% lsmod +Module Size Used by +act_gact 16384 2 +% sudo rmmod act_gact +rmmod: ERROR: Module act_gact is in use +.... + +After the fix: +% lsmod +Module Size Used by +act_gact 16384 0 +% +% sudo tc actions add action pass index 1 +% sudo tc actions add action pass index 2 +% sudo tc actions add action pass index 3 +% lsmod +Module Size Used by +act_gact 16384 3 +% +% sudo tc actions flush action gact +% lsmod +Module Size Used by +act_gact 16384 0 +% +% sudo tc actions flush action gact +% lsmod +Module Size Used by +act_gact 16384 0 +% sudo rmmod act_gact +% lsmod +Module Size Used by +% + +Fixes: f97017cdefef ("net-sched: Fix actions flushing") +Signed-off-by: Roman Mashak +Signed-off-by: Jamal Hadi Salim +Acked-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/act_api.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/net/sched/act_api.c b/net/sched/act_api.c +index 06e7c4a37245..694a06f1e0d5 100644 +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -820,10 +820,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, + goto out_module_put; + + err = a.ops->walk(skb, &dcb, RTM_DELACTION, &a); +- if (err < 0) ++ if (err <= 0) + goto out_module_put; +- if (err == 0) +- goto noflush_out; + + nla_nest_end(skb, nest); + +@@ -840,7 +838,6 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, + out_module_put: + module_put(a.ops->owner); + err_out: +-noflush_out: + kfree_skb(skb); + return err; + } +-- +2.12.2 + +From fd74e8d258da9f9678da6bf88a0b02b2c1b71d0c Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 19 Dec 2016 14:20:13 -0800 +Subject: [PATCH 096/251] fscrypt: fix renaming and linking special files +Content-Length: 2187 +Lines: 59 + +commit 42d97eb0ade31e1bc537d086842f5d6e766d9d51 upstream. + +Attempting to link a device node, named pipe, or socket file into an +encrypted directory through rename(2) or link(2) always failed with +EPERM. This happened because fscrypt_has_permitted_context() saw that +the file was unencrypted and forbid creating the link. This behavior +was unexpected because such files are never encrypted; only regular +files, directories, and symlinks can be encrypted. + +To fix this, make fscrypt_has_permitted_context() always return true on +special files. + +This will be covered by a test in my encryption xfstests patchset. + +Fixes: 9bd8212f981e ("ext4 crypto: add encryption policy and password salt support") +Signed-off-by: Eric Biggers +Reviewed-by: Richard Weinberger +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/crypto_policy.c | 6 ++++++ + fs/f2fs/crypto_policy.c | 5 +++++ + 2 files changed, 11 insertions(+) + +diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c +index 8a9feb341f31..dd561f916f0b 100644 +--- a/fs/ext4/crypto_policy.c ++++ b/fs/ext4/crypto_policy.c +@@ -156,6 +156,12 @@ int ext4_is_child_context_consistent_with_parent(struct inode *parent, + WARN_ON(1); /* Should never happen */ + return 0; + } ++ ++ /* No restrictions on file types which are never encrypted */ ++ if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) && ++ !S_ISLNK(child->i_mode)) ++ return 1; ++ + /* no restrictions if the parent directory is not encrypted */ + if (!ext4_encrypted_inode(parent)) + return 1; +diff --git a/fs/f2fs/crypto_policy.c b/fs/f2fs/crypto_policy.c +index e504f548b64e..5bbd1989d5e6 100644 +--- a/fs/f2fs/crypto_policy.c ++++ b/fs/f2fs/crypto_policy.c +@@ -149,6 +149,11 @@ int f2fs_is_child_context_consistent_with_parent(struct inode *parent, + BUG_ON(1); + } + ++ /* No restrictions on file types which are never encrypted */ ++ if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) && ++ !S_ISLNK(child->i_mode)) ++ return 1; ++ + /* no restrictions if the parent directory is not encrypted */ + if (!f2fs_encrypted_inode(parent)) + return 1; +-- +2.12.2 + +From 3a19419c50c6ee386ca6d22a23acc2df51583d3d Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Sat, 15 Oct 2016 09:48:50 -0400 +Subject: [PATCH 097/251] fscrypto: lock inode while setting encryption policy +Content-Length: 1807 +Lines: 62 + +commit 8906a8223ad4909b391c5628f7991ebceda30e52 upstream. + +i_rwsem needs to be acquired while setting an encryption policy so that +concurrent calls to FS_IOC_SET_ENCRYPTION_POLICY are correctly +serialized (especially the ->get_context() + ->set_context() pair), and +so that new files cannot be created in the directory during or after the +->empty_dir() check. + +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Reviewed-by: Richard Weinberger +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ioctl.c | 4 ++++ + fs/f2fs/file.c | 9 ++++++++- + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c +index 1fb12f9c97a6..789e2d6724a9 100644 +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -633,8 +633,12 @@ resizefs_out: + if (err) + goto encryption_policy_out; + ++ mutex_lock(&inode->i_mutex); ++ + err = ext4_process_policy(&policy, inode); + ++ mutex_unlock(&inode->i_mutex); ++ + mnt_drop_write_file(filp); + encryption_policy_out: + return err; +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index a197215ad52b..4b449d263333 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1535,12 +1535,19 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg) + #ifdef CONFIG_F2FS_FS_ENCRYPTION + struct f2fs_encryption_policy policy; + struct inode *inode = file_inode(filp); ++ int err; + + if (copy_from_user(&policy, (struct f2fs_encryption_policy __user *)arg, + sizeof(policy))) + return -EFAULT; + +- return f2fs_process_policy(&policy, inode); ++ mutex_lock(&inode->i_mutex); ++ ++ err = f2fs_process_policy(&policy, inode); ++ ++ mutex_unlock(&inode->i_mutex); ++ ++ return err; + #else + return -EOPNOTSUPP; + #endif +-- +2.12.2 + +From 8e0ec20539f8c626463ae43fcaeb218e3b2b5dc4 Mon Sep 17 00:00:00 2001 +From: Andrey Ryabinin +Date: Mon, 13 Mar 2017 19:33:37 +0300 +Subject: [PATCH 098/251] x86/kasan: Fix boot with KASAN=y and + PROFILE_ANNOTATED_BRANCHES=y +Content-Length: 1839 +Lines: 50 + +commit be3606ff739d1c1be36389f8737c577ad87e1f57 upstream. + +The kernel doesn't boot with both PROFILE_ANNOTATED_BRANCHES=y and KASAN=y +options selected. With branch profiling enabled we end up calling +ftrace_likely_update() before kasan_early_init(). ftrace_likely_update() is +built with KASAN instrumentation, so calling it before kasan has been +initialized leads to crash. + +Use DISABLE_BRANCH_PROFILING define to make sure that we don't call +ftrace_likely_update() from early code before kasan_early_init(). + +Fixes: ef7f0d6a6ca8 ("x86_64: add KASan support") +Reported-by: Fengguang Wu +Signed-off-by: Andrey Ryabinin +Cc: kasan-dev@googlegroups.com +Cc: Alexander Potapenko +Cc: Andrew Morton +Cc: lkp@01.org +Cc: Dmitry Vyukov +Link: http://lkml.kernel.org/r/20170313163337.1704-1-aryabinin@virtuozzo.com +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/head64.c | 1 + + arch/x86/mm/kasan_init_64.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c +index f129a9af6357..b6b0077da1af 100644 +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -4,6 +4,7 @@ + * Copyright (C) 2000 Andrea Arcangeli SuSE + */ + ++#define DISABLE_BRANCH_PROFILING + #include + #include + #include +diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c +index d470cf219a2d..4e5ac46adc9d 100644 +--- a/arch/x86/mm/kasan_init_64.c ++++ b/arch/x86/mm/kasan_init_64.c +@@ -1,3 +1,4 @@ ++#define DISABLE_BRANCH_PROFILING + #define pr_fmt(fmt) "kasan: " fmt + #include + #include +-- +2.12.2 + +From 62f57041fbdf15db6336542384a4b36f1f387299 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Thu, 16 Mar 2017 12:59:39 -0700 +Subject: [PATCH 099/251] x86/perf: Fix CR4.PCE propagation to use active_mm + instead of mm +Content-Length: 1726 +Lines: 44 + +commit 5dc855d44c2ad960a86f593c60461f1ae1566b6d upstream. + +If one thread mmaps a perf event while another thread in the same mm +is in some context where active_mm != mm (which can happen in the +scheduler, for example), refresh_pce() would write the wrong value +to CR4.PCE. This broke some PAPI tests. + +Reported-and-tested-by: Vince Weaver +Signed-off-by: Andy Lutomirski +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Borislav Petkov +Cc: H. Peter Anvin +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: stable@vger.kernel.org +Fixes: 7911d3f7af14 ("perf/x86: Only allow rdpmc if a perf_event is mapped") +Link: http://lkml.kernel.org/r/0c5b38a76ea50e405f9abe07a13dfaef87c173a1.1489694270.git.luto@kernel.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/perf_event.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c +index 1a8256dd6729..5b2f2306fbcc 100644 +--- a/arch/x86/kernel/cpu/perf_event.c ++++ b/arch/x86/kernel/cpu/perf_event.c +@@ -1996,8 +1996,8 @@ static int x86_pmu_event_init(struct perf_event *event) + + static void refresh_pce(void *ignored) + { +- if (current->mm) +- load_mm_cr4(current->mm); ++ if (current->active_mm) ++ load_mm_cr4(current->active_mm); + } + + static void x86_pmu_event_mapped(struct perf_event *event) +-- +2.12.2 + +From 44854c191e2cb62d369eb9927e6b6683c11d6b04 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Sat, 4 Mar 2017 10:27:18 +0100 +Subject: [PATCH 100/251] futex: Fix potential use-after-free in + FUTEX_REQUEUE_PI +Content-Length: 2788 +Lines: 81 + +commit c236c8e95a3d395b0494e7108f0d41cf36ec107c upstream. + +While working on the futex code, I stumbled over this potential +use-after-free scenario. Dmitry triggered it later with syzkaller. + +pi_mutex is a pointer into pi_state, which we drop the reference on in +unqueue_me_pi(). So any access to that pointer after that is bad. + +Since other sites already do rt_mutex_unlock() with hb->lock held, see +for example futex_lock_pi(), simply move the unlock before +unqueue_me_pi(). + +Reported-by: Dmitry Vyukov +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Darren Hart +Cc: juri.lelli@arm.com +Cc: bigeasy@linutronix.de +Cc: xlpang@redhat.com +Cc: rostedt@goodmis.org +Cc: mathieu.desnoyers@efficios.com +Cc: jdesfossez@efficios.com +Cc: dvhart@infradead.org +Cc: bristot@redhat.com +Link: http://lkml.kernel.org/r/20170304093558.801744246@infradead.org +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/kernel/futex.c b/kernel/futex.c +index 9d251dc3ec40..45170163a0b3 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2690,7 +2690,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + { + struct hrtimer_sleeper timeout, *to = NULL; + struct rt_mutex_waiter rt_waiter; +- struct rt_mutex *pi_mutex = NULL; + struct futex_hash_bucket *hb; + union futex_key key2 = FUTEX_KEY_INIT; + struct futex_q q = futex_q_init; +@@ -2782,6 +2781,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + spin_unlock(q.lock_ptr); + } + } else { ++ struct rt_mutex *pi_mutex; ++ + /* + * We have been woken up by futex_unlock_pi(), a timeout, or a + * signal. futex_unlock_pi() will not destroy the lock_ptr nor +@@ -2805,18 +2806,19 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + if (res) + ret = (res < 0) ? res : 0; + ++ /* ++ * If fixup_pi_state_owner() faulted and was unable to handle ++ * the fault, unlock the rt_mutex and return the fault to ++ * userspace. ++ */ ++ if (ret && rt_mutex_owner(pi_mutex) == current) ++ rt_mutex_unlock(pi_mutex); ++ + /* Unqueue and drop the lock. */ + unqueue_me_pi(&q); + } + +- /* +- * If fixup_pi_state_owner() faulted and was unable to handle the +- * fault, unlock the rt_mutex and return the fault to userspace. +- */ +- if (ret == -EFAULT) { +- if (pi_mutex && rt_mutex_owner(pi_mutex) == current) +- rt_mutex_unlock(pi_mutex); +- } else if (ret == -EINTR) { ++ if (ret == -EINTR) { + /* + * We've already been requeued, but cannot restart by calling + * futex_lock_pi() directly. We could restart this syscall, but +-- +2.12.2 + +From 99d403faba47e5adeb11dbf1094972fc78c29a75 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Sat, 4 Mar 2017 10:27:19 +0100 +Subject: [PATCH 101/251] futex: Add missing error handling to FUTEX_REQUEUE_PI +Content-Length: 1361 +Lines: 38 + +commit 9bbb25afeb182502ca4f2c4f3f88af0681b34cae upstream. + +Thomas spotted that fixup_pi_state_owner() can return errors and we +fail to unlock the rt_mutex in that case. + +Reported-by: Thomas Gleixner +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Darren Hart +Cc: juri.lelli@arm.com +Cc: bigeasy@linutronix.de +Cc: xlpang@redhat.com +Cc: rostedt@goodmis.org +Cc: mathieu.desnoyers@efficios.com +Cc: jdesfossez@efficios.com +Cc: dvhart@infradead.org +Cc: bristot@redhat.com +Link: http://lkml.kernel.org/r/20170304093558.867401760@infradead.org +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kernel/futex.c b/kernel/futex.c +index 45170163a0b3..3057dabf726f 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2773,6 +2773,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + if (q.pi_state && (q.pi_state->owner != current)) { + spin_lock(q.lock_ptr); + ret = fixup_pi_state_owner(uaddr2, &q, current); ++ if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) ++ rt_mutex_unlock(&q.pi_state->pi_mutex); + /* + * Drop the reference to the pi state which + * the requeue_pi() code acquired for us. +-- +2.12.2 + +From 0136bca4e0f65075b0b4716a270f8b04c6c46abc Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 22 Mar 2017 12:17:51 +0100 +Subject: [PATCH 102/251] Linux 4.4.56 +Content-Length: 301 +Lines: 18 + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index d9cc21df444d..cf9303a5d621 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 55 ++SUBLEVEL = 56 + EXTRAVERSION = + NAME = Blurry Fish Butt + +-- +2.12.2 + +From ac1a97d8a562161e42edd23e5d0f1740a3d93c85 Mon Sep 17 00:00:00 2001 +From: Chris Bainbridge +Date: Mon, 25 Apr 2016 13:48:38 +0100 +Subject: [PATCH 103/251] usb: core: hub: hub_port_init lock controller instead + of bus +Content-Length: 8176 +Lines: 219 + +commit feb26ac31a2a5cb88d86680d9a94916a6343e9e6 upstream. + +The XHCI controller presents two USB buses to the system - one for USB2 +and one for USB3. The hub init code (hub_port_init) is reentrant but +only locks one bus per thread, leading to a race condition failure when +two threads attempt to simultaneously initialise a USB2 and USB3 device: + +[ 8.034843] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command +[ 13.183701] usb 3-3: device descriptor read/all, error -110 + +On a test system this failure occurred on 6% of all boots. + +The call traces at the point of failure are: + +Call Trace: + [] schedule+0x37/0x90 + [] usb_kill_urb+0x8d/0xd0 + [] ? wake_up_atomic_t+0x30/0x30 + [] usb_start_wait_urb+0xbe/0x150 + [] usb_control_msg+0xbc/0xf0 + [] hub_port_init+0x51e/0xb70 + [] hub_event+0x817/0x1570 + [] process_one_work+0x1ff/0x620 + [] ? process_one_work+0x15f/0x620 + [] worker_thread+0x64/0x4b0 + [] ? rescuer_thread+0x390/0x390 + [] kthread+0x105/0x120 + [] ? kthread_create_on_node+0x200/0x200 + [] ret_from_fork+0x3f/0x70 + [] ? kthread_create_on_node+0x200/0x200 + +Call Trace: + [] xhci_setup_device+0x53d/0xa40 + [] xhci_address_device+0xe/0x10 + [] hub_port_init+0x1bf/0xb70 + [] ? trace_hardirqs_on+0xd/0x10 + [] hub_event+0x817/0x1570 + [] process_one_work+0x1ff/0x620 + [] ? process_one_work+0x15f/0x620 + [] worker_thread+0x64/0x4b0 + [] ? rescuer_thread+0x390/0x390 + [] kthread+0x105/0x120 + [] ? kthread_create_on_node+0x200/0x200 + [] ret_from_fork+0x3f/0x70 + [] ? kthread_create_on_node+0x200/0x200 + +Which results from the two call chains: + +hub_port_init + usb_get_device_descriptor + usb_get_descriptor + usb_control_msg + usb_internal_control_msg + usb_start_wait_urb + usb_submit_urb / wait_for_completion_timeout / usb_kill_urb + +hub_port_init + hub_set_address + xhci_address_device + xhci_setup_device + +Mathias Nyman explains the current behaviour violates the XHCI spec: + + hub_port_reset() will end up moving the corresponding xhci device slot + to default state. + + As hub_port_reset() is called several times in hub_port_init() it + sounds reasonable that we could end up with two threads having their + xhci device slots in default state at the same time, which according to + xhci 4.5.3 specs still is a big no no: + + "Note: Software shall not transition more than one Device Slot to the + Default State at a time" + + So both threads fail at their next task after this. + One fails to read the descriptor, and the other fails addressing the + device. + +Fix this in hub_port_init by locking the USB controller (instead of an +individual bus) to prevent simultaneous initialisation of both buses. + +Fixes: 638139eb95d2 ("usb: hub: allow to process more usb hub events in parallel") +Link: https://lkml.org/lkml/2016/2/8/312 +Link: https://lkml.org/lkml/2016/2/4/748 +Signed-off-by: Chris Bainbridge +Cc: stable +Acked-by: Mathias Nyman +Signed-off-by: Sumit Semwal + [sumits: minor merge conflict resolution for linux-4.4.y] +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hcd.c | 15 +++++++++++++-- + drivers/usb/core/hub.c | 8 ++++---- + include/linux/usb.h | 3 +-- + include/linux/usb/hcd.h | 1 + + 4 files changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index f44ce09367bc..9a5303c17de7 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -966,7 +966,7 @@ static void usb_bus_init (struct usb_bus *bus) + bus->bandwidth_allocated = 0; + bus->bandwidth_int_reqs = 0; + bus->bandwidth_isoc_reqs = 0; +- mutex_init(&bus->usb_address0_mutex); ++ mutex_init(&bus->devnum_next_mutex); + + INIT_LIST_HEAD (&bus->bus_list); + } +@@ -2497,6 +2497,14 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, + return NULL; + } + if (primary_hcd == NULL) { ++ hcd->address0_mutex = kmalloc(sizeof(*hcd->address0_mutex), ++ GFP_KERNEL); ++ if (!hcd->address0_mutex) { ++ kfree(hcd); ++ dev_dbg(dev, "hcd address0 mutex alloc failed\n"); ++ return NULL; ++ } ++ mutex_init(hcd->address0_mutex); + hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex), + GFP_KERNEL); + if (!hcd->bandwidth_mutex) { +@@ -2508,6 +2516,7 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, + dev_set_drvdata(dev, hcd); + } else { + mutex_lock(&usb_port_peer_mutex); ++ hcd->address0_mutex = primary_hcd->address0_mutex; + hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex; + hcd->primary_hcd = primary_hcd; + primary_hcd->primary_hcd = primary_hcd; +@@ -2574,8 +2583,10 @@ static void hcd_release(struct kref *kref) + struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref); + + mutex_lock(&usb_port_peer_mutex); +- if (usb_hcd_is_primary_hcd(hcd)) ++ if (usb_hcd_is_primary_hcd(hcd)) { ++ kfree(hcd->address0_mutex); + kfree(hcd->bandwidth_mutex); ++ } + if (hcd->shared_hcd) { + struct usb_hcd *peer = hcd->shared_hcd; + +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 780db8bb2262..f52d8abf6979 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1980,7 +1980,7 @@ static void choose_devnum(struct usb_device *udev) + struct usb_bus *bus = udev->bus; + + /* be safe when more hub events are proceed in parallel */ +- mutex_lock(&bus->usb_address0_mutex); ++ mutex_lock(&bus->devnum_next_mutex); + if (udev->wusb) { + devnum = udev->portnum + 1; + BUG_ON(test_bit(devnum, bus->devmap.devicemap)); +@@ -1998,7 +1998,7 @@ static void choose_devnum(struct usb_device *udev) + set_bit(devnum, bus->devmap.devicemap); + udev->devnum = devnum; + } +- mutex_unlock(&bus->usb_address0_mutex); ++ mutex_unlock(&bus->devnum_next_mutex); + } + + static void release_devnum(struct usb_device *udev) +@@ -4262,7 +4262,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, + if (oldspeed == USB_SPEED_LOW) + delay = HUB_LONG_RESET_TIME; + +- mutex_lock(&hdev->bus->usb_address0_mutex); ++ mutex_lock(hcd->address0_mutex); + + /* Reset the device; full speed may morph to high speed */ + /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ +@@ -4548,7 +4548,7 @@ fail: + hub_port_disable(hub, port1, 0); + update_devnum(udev, devnum); /* for disconnect processing */ + } +- mutex_unlock(&hdev->bus->usb_address0_mutex); ++ mutex_unlock(hcd->address0_mutex); + return retval; + } + +diff --git a/include/linux/usb.h b/include/linux/usb.h +index 12891ffd4bf0..8c75af6b7d5b 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -371,14 +371,13 @@ struct usb_bus { + + int devnum_next; /* Next open device number in + * round-robin allocation */ ++ struct mutex devnum_next_mutex; /* devnum_next mutex */ + + struct usb_devmap devmap; /* device address allocation map */ + struct usb_device *root_hub; /* Root hub */ + struct usb_bus *hs_companion; /* Companion EHCI bus, if any */ + struct list_head bus_list; /* list of busses */ + +- struct mutex usb_address0_mutex; /* unaddressed device mutex */ +- + int bandwidth_allocated; /* on this bus: how much of the time + * reserved for periodic (intr/iso) + * requests is used, on average? +diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h +index f89c24bd53a4..3993b21f3d11 100644 +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -180,6 +180,7 @@ struct usb_hcd { + * bandwidth_mutex should be dropped after a successful control message + * to the device, or resetting the bandwidth after a failed attempt. + */ ++ struct mutex *address0_mutex; + struct mutex *bandwidth_mutex; + struct usb_hcd *shared_hcd; + struct usb_hcd *primary_hcd; +-- +2.12.2 + +From 45d9558837d4d79e6d241f1c45cabea8d20dca22 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 27 Jun 2016 10:23:10 -0400 +Subject: [PATCH 104/251] USB: don't free bandwidth_mutex too early +Content-Length: 4635 +Lines: 119 + +commit ab2a4bf83902c170d29ba130a8abb5f9d90559e1 upstream. + +The USB core contains a bug that can show up when a USB-3 host +controller is removed. If the primary (USB-2) hcd structure is +released before the shared (USB-3) hcd, the core will try to do a +double-free of the common bandwidth_mutex. + +The problem was described in graphical form by Chung-Geol Kim, who +first reported it: + +================================================= + At *remove USB(3.0) Storage + sequence <1> --> <5> ((Problem Case)) +================================================= + VOLD +------------------------------------|------------ + (uevent) + ________|_________ + |<1> | + |dwc3_otg_sm_work | + |usb_put_hcd | + |peer_hcd(kref=2)| + |__________________| + ________|_________ + |<2> | + |New USB BUS #2 | + | | + |peer_hcd(kref=1) | + | | + --(Link)-bandXX_mutex| + | |__________________| + | + ___________________ | + |<3> | | + |dwc3_otg_sm_work | | + |usb_put_hcd | | + |primary_hcd(kref=1)| | + |___________________| | + _________|_________ | + |<4> | | + |New USB BUS #1 | | + |hcd_release | | + |primary_hcd(kref=0)| | + | | | + |bandXX_mutex(free) |<- + |___________________| + (( VOLD )) + ______|___________ + |<5> | + | SCSI | + |usb_put_hcd | + |peer_hcd(kref=0) | + |*hcd_release | + |bandXX_mutex(free*)|<- double free + |__________________| + +================================================= + +This happens because hcd_release() frees the bandwidth_mutex whenever +it sees a primary hcd being released (which is not a very good idea +in any case), but in the course of releasing the primary hcd, it +changes the pointers in the shared hcd in such a way that the shared +hcd will appear to be primary when it gets released. + +This patch fixes the problem by changing hcd_release() so that it +deallocates the bandwidth_mutex only when the _last_ hcd structure +referencing it is released. The patch also removes an unnecessary +test, so that when an hcd is released, both the shared_hcd and +primary_hcd pointers in the hcd's peer will be cleared. + +Signed-off-by: Alan Stern +Reported-by: Chung-Geol Kim +Tested-by: Chung-Geol Kim +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hcd.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index 9a5303c17de7..5724d7c41e29 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2573,26 +2573,23 @@ EXPORT_SYMBOL_GPL(usb_create_hcd); + * Don't deallocate the bandwidth_mutex until the last shared usb_hcd is + * deallocated. + * +- * Make sure to only deallocate the bandwidth_mutex when the primary HCD is +- * freed. When hcd_release() is called for either hcd in a peer set +- * invalidate the peer's ->shared_hcd and ->primary_hcd pointers to +- * block new peering attempts ++ * Make sure to deallocate the bandwidth_mutex only when the last HCD is ++ * freed. When hcd_release() is called for either hcd in a peer set, ++ * invalidate the peer's ->shared_hcd and ->primary_hcd pointers. + */ + static void hcd_release(struct kref *kref) + { + struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref); + + mutex_lock(&usb_port_peer_mutex); +- if (usb_hcd_is_primary_hcd(hcd)) { +- kfree(hcd->address0_mutex); +- kfree(hcd->bandwidth_mutex); +- } + if (hcd->shared_hcd) { + struct usb_hcd *peer = hcd->shared_hcd; + + peer->shared_hcd = NULL; +- if (peer->primary_hcd == hcd) +- peer->primary_hcd = NULL; ++ peer->primary_hcd = NULL; ++ } else { ++ kfree(hcd->address0_mutex); ++ kfree(hcd->bandwidth_mutex); + } + mutex_unlock(&usb_port_peer_mutex); + kfree(hcd); +-- +2.12.2 + +From c78c3376ec6707f4e2177906928b12cb6cd8c5a9 Mon Sep 17 00:00:00 2001 +From: "Wang, Rui Y" +Date: Sun, 29 Nov 2015 22:45:33 +0800 +Subject: [PATCH 105/251] crypto: ghash-clmulni - Fix load failure +Content-Length: 2363 +Lines: 69 + +commit 3a020a723c65eb8ffa7c237faca26521a024e582 upstream. + +ghash_clmulni_intel fails to load on Linux 4.3+ with the following message: +"modprobe: ERROR: could not insert 'ghash_clmulni_intel': Invalid argument" + +After 8996eafdc ("crypto: ahash - ensure statesize is non-zero") all ahash +drivers are required to implement import()/export(), and must have a non- +zero statesize. + +This patch has been tested with the algif_hash interface. The calculated +digest values, after several rounds of import()s and export()s, match those +calculated by tcrypt. + +Signed-off-by: Rui Wang +Signed-off-by: Herbert Xu +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/crypto/ghash-clmulni-intel_glue.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c +index 440df0c7a2ee..a69321a77783 100644 +--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c ++++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c +@@ -219,6 +219,29 @@ static int ghash_async_final(struct ahash_request *req) + } + } + ++static int ghash_async_import(struct ahash_request *req, const void *in) ++{ ++ struct ahash_request *cryptd_req = ahash_request_ctx(req); ++ struct shash_desc *desc = cryptd_shash_desc(cryptd_req); ++ struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); ++ ++ ghash_async_init(req); ++ memcpy(dctx, in, sizeof(*dctx)); ++ return 0; ++ ++} ++ ++static int ghash_async_export(struct ahash_request *req, void *out) ++{ ++ struct ahash_request *cryptd_req = ahash_request_ctx(req); ++ struct shash_desc *desc = cryptd_shash_desc(cryptd_req); ++ struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); ++ ++ memcpy(out, dctx, sizeof(*dctx)); ++ return 0; ++ ++} ++ + static int ghash_async_digest(struct ahash_request *req) + { + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); +@@ -288,8 +311,11 @@ static struct ahash_alg ghash_async_alg = { + .final = ghash_async_final, + .setkey = ghash_async_setkey, + .digest = ghash_async_digest, ++ .export = ghash_async_export, ++ .import = ghash_async_import, + .halg = { + .digestsize = GHASH_DIGEST_SIZE, ++ .statesize = sizeof(struct ghash_desc_ctx), + .base = { + .cra_name = "ghash", + .cra_driver_name = "ghash-clmulni", +-- +2.12.2 + +From 10659b8f5c600e642d0f1cadbbf83c739ac0c739 Mon Sep 17 00:00:00 2001 +From: "Wang, Rui Y" +Date: Sun, 29 Nov 2015 22:45:34 +0800 +Subject: [PATCH 106/251] crypto: cryptd - Assign statesize properly +Content-Length: 1078 +Lines: 30 + +commit 1a07834024dfca5c4bed5de8f8714306e0a11836 upstream. + +cryptd_create_hash() fails by returning -EINVAL. It is because after +8996eafdc ("crypto: ahash - ensure statesize is non-zero") all ahash +drivers must have a non-zero statesize. + +This patch fixes the problem by properly assigning the statesize. + +Signed-off-by: Rui Wang +Signed-off-by: Herbert Xu +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + crypto/cryptd.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/crypto/cryptd.c b/crypto/cryptd.c +index e7aa904cb20b..26a504db3f53 100644 +--- a/crypto/cryptd.c ++++ b/crypto/cryptd.c +@@ -642,6 +642,7 @@ static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, + inst->alg.halg.base.cra_flags = type; + + inst->alg.halg.digestsize = salg->digestsize; ++ inst->alg.halg.statesize = salg->statesize; + inst->alg.halg.base.cra_ctxsize = sizeof(struct cryptd_hash_ctx); + + inst->alg.halg.base.cra_init = cryptd_hash_init_tfm; +-- +2.12.2 + +From f8c07cbc2e72a7e26bff8c5823f6e045eeeb4e16 Mon Sep 17 00:00:00 2001 +From: "Wang, Rui Y" +Date: Wed, 27 Jan 2016 17:08:36 +0800 +Subject: [PATCH 107/251] crypto: mcryptd - Fix load failure +Content-Length: 994 +Lines: 28 + +commit ddef482420b1ba8ec45e6123a7e8d3f67b21e5e3 upstream. + +mcryptd_create_hash() fails by returning -EINVAL, causing any +driver using mcryptd to fail to load. It is because it needs +to set its statesize properly. + +Signed-off-by: Rui Wang +Signed-off-by: Herbert Xu +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + crypto/mcryptd.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c +index a0ceb41d5ccc..b4f3930266b1 100644 +--- a/crypto/mcryptd.c ++++ b/crypto/mcryptd.c +@@ -531,6 +531,7 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb, + inst->alg.halg.base.cra_flags = type; + + inst->alg.halg.digestsize = salg->digestsize; ++ inst->alg.halg.statesize = salg->statesize; + inst->alg.halg.base.cra_ctxsize = sizeof(struct mcryptd_hash_ctx); + + inst->alg.halg.base.cra_init = mcryptd_hash_init_tfm; +-- +2.12.2 + +From 12e1a3cd11ea373143e957cf9698a26a4e43f4a6 Mon Sep 17 00:00:00 2001 +From: "Manoj N. Kumar" +Date: Fri, 4 Mar 2016 15:55:20 -0600 +Subject: [PATCH 108/251] cxlflash: Increase cmd_per_lun for better throughput +Content-Length: 2593 +Lines: 71 + +commit 83430833b4d4a9c9b23964babbeb1f36450f8136 upstream. + +With the current value of cmd_per_lun at 16, the throughput +over a single adapter is limited to around 150kIOPS. + +Increase the value of cmd_per_lun to 256 to improve +throughput. With this change a single adapter is able to +attain close to the maximum throughput (380kIOPS). +Also change the number of RRQ entries that can be queued. + +Signed-off-by: Manoj N. Kumar +Acked-by: Matthew R. Ochs +Reviewed-by: Uma Krishnan +Signed-off-by: Martin K. Petersen +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/cxlflash/common.h | 8 +++++--- + drivers/scsi/cxlflash/main.c | 2 +- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h +index 5ada9268a450..a8ac4c0a1493 100644 +--- a/drivers/scsi/cxlflash/common.h ++++ b/drivers/scsi/cxlflash/common.h +@@ -34,7 +34,6 @@ extern const struct file_operations cxlflash_cxl_fops; + sectors + */ + +-#define NUM_RRQ_ENTRY 16 /* for master issued cmds */ + #define MAX_RHT_PER_CONTEXT (PAGE_SIZE / sizeof(struct sisl_rht_entry)) + + /* AFU command retry limit */ +@@ -48,9 +47,12 @@ extern const struct file_operations cxlflash_cxl_fops; + index derivation + */ + +-#define CXLFLASH_MAX_CMDS 16 ++#define CXLFLASH_MAX_CMDS 256 + #define CXLFLASH_MAX_CMDS_PER_LUN CXLFLASH_MAX_CMDS + ++/* RRQ for master issued cmds */ ++#define NUM_RRQ_ENTRY CXLFLASH_MAX_CMDS ++ + + static inline void check_sizes(void) + { +@@ -149,7 +151,7 @@ struct afu_cmd { + struct afu { + /* Stuff requiring alignment go first. */ + +- u64 rrq_entry[NUM_RRQ_ENTRY]; /* 128B RRQ */ ++ u64 rrq_entry[NUM_RRQ_ENTRY]; /* 2K RRQ */ + /* + * Command & data for AFU commands. + */ +diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c +index c86847c68448..2882bcac918a 100644 +--- a/drivers/scsi/cxlflash/main.c ++++ b/drivers/scsi/cxlflash/main.c +@@ -2305,7 +2305,7 @@ static struct scsi_host_template driver_template = { + .eh_device_reset_handler = cxlflash_eh_device_reset_handler, + .eh_host_reset_handler = cxlflash_eh_host_reset_handler, + .change_queue_depth = cxlflash_change_queue_depth, +- .cmd_per_lun = 16, ++ .cmd_per_lun = CXLFLASH_MAX_CMDS_PER_LUN, + .can_queue = CXLFLASH_MAX_CMDS, + .this_id = -1, + .sg_tablesize = SG_NONE, /* No scatter gather support */ +-- +2.12.2 + +From 962c66c74184b1c7927f5906c9848e605fe8b236 Mon Sep 17 00:00:00 2001 +From: Alex Hung +Date: Fri, 27 May 2016 15:47:06 +0800 +Subject: [PATCH 109/251] ACPI / video: skip evaluating _DOD when it does not + exist +Content-Length: 1067 +Lines: 30 + +commit e34fbbac669de0b7fb7803929d0477f35f6e2833 upstream. + +Some system supports hybrid graphics and its discrete VGA +does not have any connectors and therefore has no _DOD method. + +Signed-off-by: Alex Hung +Reviewed-by: Aaron Lu +Signed-off-by: Rafael J. Wysocki +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/acpi_video.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c +index 5fdac394207a..549cdbed7b0e 100644 +--- a/drivers/acpi/acpi_video.c ++++ b/drivers/acpi/acpi_video.c +@@ -1211,6 +1211,9 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) + union acpi_object *dod = NULL; + union acpi_object *obj; + ++ if (!video->cap._DOD) ++ return AE_NOT_EXIST; ++ + status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer); + if (!ACPI_SUCCESS(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); +-- +2.12.2 + +From 3787a071d145055a89442cf614ceec39c315bc9f Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Mon, 22 Aug 2016 14:42:52 +0300 +Subject: [PATCH 110/251] pinctrl: cherryview: Do not mask all interrupts in + probe +Content-Length: 2194 +Lines: 52 + +commit bcb48cca23ec9852739e4a464307fa29515bbe48 upstream. + +The Cherryview GPIO controller has 8 or 16 wires connected to the I/O-APIC +which can be used directly by the platform/BIOS or drivers. One such wire +is used as SCI (System Control Interrupt) which ACPI depends on to be able +to trigger GPEs (General Purpose Events). + +The pinctrl driver itself uses another IRQ resource which is wire OR of all +the 8 (or 16) wires and follows what BIOS has programmed to the IntSel +register of each pin. + +Currently the driver masks all interrupts at probe time and this prevents +these direct interrupts from working as expected. The reason for this is +that some early stage prototypes had some pins misconfigured causing lots +of spurious interrupts. + +We fix this by leaving the interrupt mask untouched. This allows SCI and +other direct interrupts work properly. What comes to the possible spurious +interrupts we switch the default handler to be handle_bad_irq() instead of +handle_simple_irq() (which was not correct anyway). + +Reported-by: Yu C Chen +Reported-by: Anisse Astier +Signed-off-by: Mika Westerberg +Signed-off-by: Linus Walleij +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/intel/pinctrl-cherryview.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c +index a009ae34c5ef..930f0f25c1ce 100644 +--- a/drivers/pinctrl/intel/pinctrl-cherryview.c ++++ b/drivers/pinctrl/intel/pinctrl-cherryview.c +@@ -1466,12 +1466,11 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) + offset += range->npins; + } + +- /* Mask and clear all interrupts */ +- chv_writel(0, pctrl->regs + CHV_INTMASK); ++ /* Clear all interrupts */ + chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); + + ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0, +- handle_simple_irq, IRQ_TYPE_NONE); ++ handle_bad_irq, IRQ_TYPE_NONE); + if (ret) { + dev_err(pctrl->dev, "failed to add IRQ chip\n"); + goto fail; +-- +2.12.2 + +From 0a2512768f1683514ef964e2e0767458baef14de Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Sat, 30 Apr 2016 19:21:35 -0700 +Subject: [PATCH 111/251] Drivers: hv: balloon: don't crash when memory is + added in non-sorted order +Content-Length: 1762 +Lines: 43 + +commit 77c0c9735bc0ba5898e637a3a20d6bcb50e3f67d upstream. + +When we iterate through all HA regions in handle_pg_range() we have an +assumption that all these regions are sorted in the list and the +'start_pfn >= has->end_pfn' check is enough to find the proper region. +Unfortunately it's not the case with WS2016 where host can hot-add regions +in a different order. We end up modifying the wrong HA region and crashing +later on pages online. Modify the check to make sure we found the region +we were searching for while iterating. Fix the same check in pfn_covered() +as well. + +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: K. Y. Srinivasan +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hv/hv_balloon.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c +index b853b4b083bd..43af91362be5 100644 +--- a/drivers/hv/hv_balloon.c ++++ b/drivers/hv/hv_balloon.c +@@ -714,7 +714,7 @@ static bool pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt) + * If the pfn range we are dealing with is not in the current + * "hot add block", move on. + */ +- if ((start_pfn >= has->end_pfn)) ++ if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn) + continue; + /* + * If the current hot add-request extends beyond +@@ -768,7 +768,7 @@ static unsigned long handle_pg_range(unsigned long pg_start, + * If the pfn range we are dealing with is not in the current + * "hot add block", move on. + */ +- if ((start_pfn >= has->end_pfn)) ++ if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn) + continue; + + old_covered_state = has->covered_end_pfn; +-- +2.12.2 + +From b1a0f744f8e63fbef10dc84029e9d213e03a3a18 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Fri, 3 Jun 2016 17:09:22 -0700 +Subject: [PATCH 112/251] Drivers: hv: avoid vfree() on crash +Content-Length: 3254 +Lines: 110 + +commit a9f61ca793becabdefab03b77568d6c6f8c1bc79 upstream. + +When we crash from NMI context (e.g. after NMI injection from host when +'sysctl -w kernel.unknown_nmi_panic=1' is set) we hit + + kernel BUG at mm/vmalloc.c:1530! + +as vfree() is denied. While the issue could be solved with in_nmi() check +instead I opted for skipping vfree on all sorts of crashes to reduce the +amount of work which can cause consequent crashes. We don't really need to +free anything on crash. + +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: K. Y. Srinivasan +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hv/hv.c | 8 +++++--- + drivers/hv/hyperv_vmbus.h | 2 +- + drivers/hv/vmbus_drv.c | 8 ++++---- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c +index 57c191798699..ddbf7e7e0d98 100644 +--- a/drivers/hv/hv.c ++++ b/drivers/hv/hv.c +@@ -274,7 +274,7 @@ cleanup: + * + * This routine is called normally during driver unloading or exiting. + */ +-void hv_cleanup(void) ++void hv_cleanup(bool crash) + { + union hv_x64_msr_hypercall_contents hypercall_msr; + +@@ -284,7 +284,8 @@ void hv_cleanup(void) + if (hv_context.hypercall_page) { + hypercall_msr.as_uint64 = 0; + wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); +- vfree(hv_context.hypercall_page); ++ if (!crash) ++ vfree(hv_context.hypercall_page); + hv_context.hypercall_page = NULL; + } + +@@ -304,7 +305,8 @@ void hv_cleanup(void) + + hypercall_msr.as_uint64 = 0; + wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64); +- vfree(hv_context.tsc_page); ++ if (!crash) ++ vfree(hv_context.tsc_page); + hv_context.tsc_page = NULL; + } + #endif +diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h +index 12156db2e88e..75e383e6d03d 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -581,7 +581,7 @@ struct hv_ring_buffer_debug_info { + + extern int hv_init(void); + +-extern void hv_cleanup(void); ++extern void hv_cleanup(bool crash); + + extern int hv_post_message(union hv_connection_id connection_id, + enum hv_message_type message_type, +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index 509ed9731630..802dcb409030 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -889,7 +889,7 @@ err_alloc: + bus_unregister(&hv_bus); + + err_cleanup: +- hv_cleanup(); ++ hv_cleanup(false); + + return ret; + } +@@ -1254,7 +1254,7 @@ static void hv_kexec_handler(void) + vmbus_initiate_unload(); + for_each_online_cpu(cpu) + smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); +- hv_cleanup(); ++ hv_cleanup(false); + }; + + static void hv_crash_handler(struct pt_regs *regs) +@@ -1266,7 +1266,7 @@ static void hv_crash_handler(struct pt_regs *regs) + * for kdump. + */ + hv_synic_cleanup(NULL); +- hv_cleanup(); ++ hv_cleanup(true); + }; + + static int __init hv_acpi_init(void) +@@ -1330,7 +1330,7 @@ static void __exit vmbus_exit(void) + &hyperv_panic_block); + } + bus_unregister(&hv_bus); +- hv_cleanup(); ++ hv_cleanup(false); + for_each_online_cpu(cpu) { + tasklet_kill(hv_context.event_dpc[cpu]); + smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); +-- +2.12.2 + +From e2d9577854f5a5469bcf7a3d1b17ca5e9b9ba673 Mon Sep 17 00:00:00 2001 +From: Ross Lagerwall +Date: Fri, 22 Apr 2016 13:05:31 +0100 +Subject: [PATCH 113/251] xen/qspinlock: Don't kick CPU if IRQ is not + initialized +Content-Length: 2791 +Lines: 76 + +commit 707e59ba494372a90d245f18b0c78982caa88e48 upstream. + +The following commit: + + 1fb3a8b2cfb2 ("xen/spinlock: Fix locking path engaging too soon under PVHVM.") + +... moved the initalization of the kicker interrupt until after +native_cpu_up() is called. + +However, when using qspinlocks, a CPU may try to kick another CPU that is +spinning (because it has not yet initialized its kicker interrupt), resulting +in the following crash during boot: + + kernel BUG at /build/linux-Ay7j_C/linux-4.4.0/drivers/xen/events/events_base.c:1210! + invalid opcode: 0000 [#1] SMP + ... + RIP: 0010:[] [] xen_send_IPI_one+0x59/0x60 + ... + Call Trace: + [] xen_qlock_kick+0xe/0x10 + [] __pv_queued_spin_unlock+0xb2/0xf0 + [] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x20 + [] ? check_tsc_warp+0x76/0x150 + [] check_tsc_sync_source+0x96/0x160 + [] native_cpu_up+0x3d8/0x9f0 + [] xen_hvm_cpu_up+0x35/0x80 + [] _cpu_up+0x13c/0x180 + [] cpu_up+0x7a/0xa0 + [] smp_init+0x7f/0x81 + [] kernel_init_freeable+0xef/0x212 + [] ? rest_init+0x80/0x80 + [] kernel_init+0xe/0xe0 + [] ret_from_fork+0x3f/0x70 + [] ? rest_init+0x80/0x80 + +To fix this, only send the kick if the target CPU's interrupt has been +initialized. This check isn't racy, because the target is waiting for +the spinlock, so it won't have initialized the interrupt in the +meantime. + +Signed-off-by: Ross Lagerwall +Reviewed-by: Boris Ostrovsky +Cc: David Vrabel +Cc: Juergen Gross +Cc: Konrad Rzeszutek Wilk +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: linux-kernel@vger.kernel.org +Cc: xen-devel@lists.xenproject.org +Signed-off-by: Ingo Molnar +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/xen/spinlock.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c +index 9e2ba5c6e1dd..f42e78de1e10 100644 +--- a/arch/x86/xen/spinlock.c ++++ b/arch/x86/xen/spinlock.c +@@ -27,6 +27,12 @@ static bool xen_pvspin = true; + + static void xen_qlock_kick(int cpu) + { ++ int irq = per_cpu(lock_kicker_irq, cpu); ++ ++ /* Don't kick if the target's kicker interrupt is not initialized. */ ++ if (irq == -1) ++ return; ++ + xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); + } + +-- +2.12.2 + +From 50730d7f361f9915ec7063a629500119b0e8c3b6 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Wed, 18 May 2016 21:01:20 +0200 +Subject: [PATCH 114/251] KVM: PPC: Book3S PR: Fix illegal opcode emulation +Content-Length: 2006 +Lines: 47 + +commit 708e75a3ee750dce1072134e630d66c4e6eaf63c upstream. + +If kvmppc_handle_exit_pr() calls kvmppc_emulate_instruction() to emulate +one instruction (in the BOOK3S_INTERRUPT_H_EMUL_ASSIST case), it calls +kvmppc_core_queue_program() afterwards if kvmppc_emulate_instruction() +returned EMULATE_FAIL, so the guest gets an program interrupt for the +illegal opcode. +However, the kvmppc_emulate_instruction() also tried to inject a +program exception for this already, so the program interrupt gets +injected twice and the return address in srr0 gets destroyed. +All other callers of kvmppc_emulate_instruction() are also injecting +a program interrupt, and since the callers have the right knowledge +about the srr1 flags that should be used, it is the function +kvmppc_emulate_instruction() that should _not_ inject program +interrupts, so remove the kvmppc_core_queue_program() here. + +This fixes the issue discovered by Laurent Vivier with kvm-unit-tests +where the logs are filled with these messages when the test tries +to execute an illegal instruction: + + Couldn't emulate instruction 0x00000000 (op 0 xop 0) + kvmppc_handle_exit_pr: emulation at 700 failed (00000000) + +Signed-off-by: Thomas Huth +Reviewed-by: Alexander Graf +Tested-by: Laurent Vivier +Signed-off-by: Paul Mackerras +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/kvm/emulate.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c +index 5cc2e7af3a7b..b379146de55b 100644 +--- a/arch/powerpc/kvm/emulate.c ++++ b/arch/powerpc/kvm/emulate.c +@@ -302,7 +302,6 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) + advance = 0; + printk(KERN_ERR "Couldn't emulate instruction 0x%08x " + "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst)); +- kvmppc_core_queue_program(vcpu, 0); + } + } + +-- +2.12.2 + +From 68ea3948ed3d48dd1e0897b121f37da6f14ffbcc Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Fri, 15 Apr 2016 09:41:35 +0200 +Subject: [PATCH 115/251] s390/pci: fix use after free in dma_init +Content-Length: 1833 +Lines: 64 + +commit dba599091c191d209b1499511a524ad9657c0e5a upstream. + +After a failure during registration of the dma_table (because of the +function being in error state) we free its memory but don't reset the +associated pointer to zero. + +When we then receive a notification from firmware (about the function +being in error state) we'll try to walk and free the dma_table again. + +Fix this by resetting the dma_table pointer. In addition to that make +sure that we free the iommu_bitmap when appropriate. + +Signed-off-by: Sebastian Ott +Reviewed-by: Gerald Schaefer +Signed-off-by: Martin Schwidefsky +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/pci/pci_dma.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c +index 3a40f718baef..4004e03267cd 100644 +--- a/arch/s390/pci/pci_dma.c ++++ b/arch/s390/pci/pci_dma.c +@@ -455,7 +455,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) + zdev->dma_table = dma_alloc_cpu_table(); + if (!zdev->dma_table) { + rc = -ENOMEM; +- goto out_clean; ++ goto out; + } + + /* +@@ -475,18 +475,22 @@ int zpci_dma_init_device(struct zpci_dev *zdev) + zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); + if (!zdev->iommu_bitmap) { + rc = -ENOMEM; +- goto out_reg; ++ goto free_dma_table; + } + + rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, + (u64) zdev->dma_table); + if (rc) +- goto out_reg; +- return 0; ++ goto free_bitmap; + +-out_reg: ++ return 0; ++free_bitmap: ++ vfree(zdev->iommu_bitmap); ++ zdev->iommu_bitmap = NULL; ++free_dma_table: + dma_free_cpu_table(zdev->dma_table); +-out_clean: ++ zdev->dma_table = NULL; ++out: + return rc; + } + +-- +2.12.2 + +From 13a26889cbc1eb8a7b9a7712c05538c55659fe40 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Thu, 14 Jan 2016 08:07:55 +1000 +Subject: [PATCH 116/251] drm/amdgpu: add missing irq.h include +Content-Length: 751 +Lines: 25 + +commit e9c5e7402dad6f4f04c2430db6f283512bcd4392 upstream. + +this fixes the build on arm. + +Signed-off-by: Dave Airlie +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +index 7c42ff670080..a0924330d125 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +@@ -25,6 +25,7 @@ + * Alex Deucher + * Jerome Glisse + */ ++#include + #include + #include + #include +-- +2.12.2 + +From cea050150323a2c09efc316f0272af053e0b87e2 Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Wed, 25 Nov 2015 14:05:30 -0700 +Subject: [PATCH 117/251] tpm_tis: Use devm_free_irq not free_irq +Content-Length: 1236 +Lines: 33 + +commit 727f28b8ca24a581c7bd868326b8cea1058c720a upstream. + +The interrupt is always allocated with devm_request_irq so it +must always be freed with devm_free_irq. + +Fixes: 448e9c55c12d ("tpm_tis: verify interrupt during init") +Signed-off-by: Jason Gunthorpe +Acked-by: Jarkko Sakkinen +Tested-by: Jarkko Sakkinen +Tested-by: Martin Wilck +Signed-off-by: Jarkko Sakkinen +Acked-by: Peter Huewe +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/tpm/tpm_tis.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c +index 65f7eecc45b0..f10a107614b4 100644 +--- a/drivers/char/tpm/tpm_tis.c ++++ b/drivers/char/tpm/tpm_tis.c +@@ -401,7 +401,7 @@ static void disable_interrupts(struct tpm_chip *chip) + iowrite32(intmask, + chip->vendor.iobase + + TPM_INT_ENABLE(chip->vendor.locality)); +- free_irq(chip->vendor.irq, chip); ++ devm_free_irq(chip->pdev, chip->vendor.irq, chip); + chip->vendor.irq = 0; + } + +-- +2.12.2 + +From 6cc5b73d79697e1a529249572ac022192f1ddffd Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Mon, 25 Jan 2016 16:00:41 +0100 +Subject: [PATCH 118/251] hv_netvsc: use skb_get_hash() instead of a homegrown + implementation +Content-Length: 2988 +Lines: 108 + +commit 757647e10e55c01fb7a9c4356529442e316a7c72 upstream. + +Recent changes to 'struct flow_keys' (e.g commit d34af823ff40 ("net: Add +VLAN ID to flow_keys")) introduced a performance regression in netvsc +driver. Is problem is, however, not the above mentioned commit but the +fact that netvsc_set_hash() function did some assumptions on the struct +flow_keys data layout and this is wrong. + +Get rid of netvsc_set_hash() by switching to skb_get_hash(). This change +will also imply switching to Jenkins hash from the currently used Toeplitz +but it seems there is no good excuse for Toeplitz to stay. + +Signed-off-by: Vitaly Kuznetsov +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hyperv/netvsc_drv.c | 67 ++--------------------------------------- + 1 file changed, 3 insertions(+), 64 deletions(-) + +diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c +index e8a09ff9e724..c8a7802d2953 100644 +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -197,65 +197,6 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size, + return ppi; + } + +-union sub_key { +- u64 k; +- struct { +- u8 pad[3]; +- u8 kb; +- u32 ka; +- }; +-}; +- +-/* Toeplitz hash function +- * data: network byte order +- * return: host byte order +- */ +-static u32 comp_hash(u8 *key, int klen, void *data, int dlen) +-{ +- union sub_key subk; +- int k_next = 4; +- u8 dt; +- int i, j; +- u32 ret = 0; +- +- subk.k = 0; +- subk.ka = ntohl(*(u32 *)key); +- +- for (i = 0; i < dlen; i++) { +- subk.kb = key[k_next]; +- k_next = (k_next + 1) % klen; +- dt = ((u8 *)data)[i]; +- for (j = 0; j < 8; j++) { +- if (dt & 0x80) +- ret ^= subk.ka; +- dt <<= 1; +- subk.k <<= 1; +- } +- } +- +- return ret; +-} +- +-static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb) +-{ +- struct flow_keys flow; +- int data_len; +- +- if (!skb_flow_dissect_flow_keys(skb, &flow, 0) || +- !(flow.basic.n_proto == htons(ETH_P_IP) || +- flow.basic.n_proto == htons(ETH_P_IPV6))) +- return false; +- +- if (flow.basic.ip_proto == IPPROTO_TCP) +- data_len = 12; +- else +- data_len = 8; +- +- *hash = comp_hash(netvsc_hash_key, HASH_KEYLEN, &flow, data_len); +- +- return true; +-} +- + static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) + { +@@ -268,11 +209,9 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb, + if (nvsc_dev == NULL || ndev->real_num_tx_queues <= 1) + return 0; + +- if (netvsc_set_hash(&hash, skb)) { +- q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] % +- ndev->real_num_tx_queues; +- skb_set_hash(skb, hash, PKT_HASH_TYPE_L3); +- } ++ hash = skb_get_hash(skb); ++ q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] % ++ ndev->real_num_tx_queues; + + return q_idx; + } +-- +2.12.2 + +From 6052eb871217c0679ac63779fc5e43eb49c83b0c Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Mon, 23 May 2016 16:24:05 -0700 +Subject: [PATCH 119/251] kernek/fork.c: allocate idle task for a CPU always on + its local node +Content-Length: 3134 +Lines: 88 + +commit 725fc629ff2545b061407305ae51016c9f928fce upstream. + +Linux preallocates the task structs of the idle tasks for all possible +CPUs. This currently means they all end up on node 0. This also +implies that the cache line of MWAIT, which is around the flags field in +the task struct, are all located in node 0. + +We see a noticeable performance improvement on Knights Landing CPUs when +the cache lines used for MWAIT are located in the local nodes of the +CPUs using them. I would expect this to give a (likely slight) +improvement on other systems too. + +The patch implements placing the idle task in the node of its CPUs, by +passing the right target node to copy_process() + +[akpm@linux-foundation.org: use NUMA_NO_NODE, not a bare -1] +Link: http://lkml.kernel.org/r/1463492694-15833-1-git-send-email-andi@firstfloor.org +Signed-off-by: Andi Kleen +Cc: Thomas Gleixner +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + kernel/fork.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/kernel/fork.c b/kernel/fork.c +index 2e55b53399de..278a2ddad351 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -331,13 +331,14 @@ void set_task_stack_end_magic(struct task_struct *tsk) + *stackend = STACK_END_MAGIC; /* for overflow detection */ + } + +-static struct task_struct *dup_task_struct(struct task_struct *orig) ++static struct task_struct *dup_task_struct(struct task_struct *orig, int node) + { + struct task_struct *tsk; + struct thread_info *ti; +- int node = tsk_fork_get_node(orig); + int err; + ++ if (node == NUMA_NO_NODE) ++ node = tsk_fork_get_node(orig); + tsk = alloc_task_struct_node(node); + if (!tsk) + return NULL; +@@ -1270,7 +1271,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, + int __user *child_tidptr, + struct pid *pid, + int trace, +- unsigned long tls) ++ unsigned long tls, ++ int node) + { + int retval; + struct task_struct *p; +@@ -1323,7 +1325,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, + goto fork_out; + + retval = -ENOMEM; +- p = dup_task_struct(current); ++ p = dup_task_struct(current, node); + if (!p) + goto fork_out; + +@@ -1699,7 +1701,8 @@ static inline void init_idle_pids(struct pid_link *links) + struct task_struct *fork_idle(int cpu) + { + struct task_struct *task; +- task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0); ++ task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0, ++ cpu_to_node(cpu)); + if (!IS_ERR(task)) { + init_idle_pids(task->pids); + init_idle(task, cpu); +@@ -1744,7 +1747,7 @@ long _do_fork(unsigned long clone_flags, + } + + p = copy_process(clone_flags, stack_start, stack_size, +- child_tidptr, NULL, trace, tls); ++ child_tidptr, NULL, trace, tls, NUMA_NO_NODE); + /* + * Do this prior waking up the new thread - the thread pointer + * might get invalid after that point, if the thread exits quickly. +-- +2.12.2 + +From 4cb0c0b73d1c79a8ce260836b3f27650aa1c57f1 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Thu, 2 Mar 2017 12:17:22 -0800 +Subject: [PATCH 120/251] give up on gcc ilog2() constant optimizations +Content-Length: 4200 +Lines: 125 + +commit 474c90156c8dcc2fa815e6716cc9394d7930cb9c upstream. + +gcc-7 has an "optimization" pass that completely screws up, and +generates the code expansion for the (impossible) case of calling +ilog2() with a zero constant, even when the code gcc compiles does not +actually have a zero constant. + +And we try to generate a compile-time error for anybody doing ilog2() on +a constant where that doesn't make sense (be it zero or negative). So +now gcc7 will fail the build due to our sanity checking, because it +created that constant-zero case that didn't actually exist in the source +code. + +There's a whole long discussion on the kernel mailing about how to work +around this gcc bug. The gcc people themselevs have discussed their +"feature" in + + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72785 + +but it's all water under the bridge, because while it looked at one +point like it would be solved by the time gcc7 was released, that was +not to be. + +So now we have to deal with this compiler braindamage. + +And the only simple approach seems to be to just delete the code that +tries to warn about bad uses of ilog2(). + +So now "ilog2()" will just return 0 not just for the value 1, but for +any non-positive value too. + +It's not like I can recall anybody having ever actually tried to use +this function on any invalid value, but maybe the sanity check just +meant that such code never made it out in public. + +Reported-by: Laura Abbott +Cc: John Stultz , +Cc: Thomas Gleixner +Cc: Ard Biesheuvel +Signed-off-by: Linus Torvalds +Cc: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/log2.h | 13 ++----------- + tools/include/linux/log2.h | 13 ++----------- + 2 files changed, 4 insertions(+), 22 deletions(-) + +diff --git a/include/linux/log2.h b/include/linux/log2.h +index fd7ff3d91e6a..f38fae23bdac 100644 +--- a/include/linux/log2.h ++++ b/include/linux/log2.h +@@ -16,12 +16,6 @@ + #include + + /* +- * deal with unrepresentable constant logarithms +- */ +-extern __attribute__((const, noreturn)) +-int ____ilog2_NaN(void); +- +-/* + * non-constant log of base 2 calculators + * - the arch may override these in asm/bitops.h if they can be implemented + * more efficiently than using fls() and fls64() +@@ -85,7 +79,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) + #define ilog2(n) \ + ( \ + __builtin_constant_p(n) ? ( \ +- (n) < 1 ? ____ilog2_NaN() : \ ++ (n) < 2 ? 0 : \ + (n) & (1ULL << 63) ? 63 : \ + (n) & (1ULL << 62) ? 62 : \ + (n) & (1ULL << 61) ? 61 : \ +@@ -148,10 +142,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) + (n) & (1ULL << 4) ? 4 : \ + (n) & (1ULL << 3) ? 3 : \ + (n) & (1ULL << 2) ? 2 : \ +- (n) & (1ULL << 1) ? 1 : \ +- (n) & (1ULL << 0) ? 0 : \ +- ____ilog2_NaN() \ +- ) : \ ++ 1 ) : \ + (sizeof(n) <= 4) ? \ + __ilog2_u32(n) : \ + __ilog2_u64(n) \ +diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h +index 41446668ccce..d5677d39c1e4 100644 +--- a/tools/include/linux/log2.h ++++ b/tools/include/linux/log2.h +@@ -13,12 +13,6 @@ + #define _TOOLS_LINUX_LOG2_H + + /* +- * deal with unrepresentable constant logarithms +- */ +-extern __attribute__((const, noreturn)) +-int ____ilog2_NaN(void); +- +-/* + * non-constant log of base 2 calculators + * - the arch may override these in asm/bitops.h if they can be implemented + * more efficiently than using fls() and fls64() +@@ -78,7 +72,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) + #define ilog2(n) \ + ( \ + __builtin_constant_p(n) ? ( \ +- (n) < 1 ? ____ilog2_NaN() : \ ++ (n) < 2 ? 0 : \ + (n) & (1ULL << 63) ? 63 : \ + (n) & (1ULL << 62) ? 62 : \ + (n) & (1ULL << 61) ? 61 : \ +@@ -141,10 +135,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) + (n) & (1ULL << 4) ? 4 : \ + (n) & (1ULL << 3) ? 3 : \ + (n) & (1ULL << 2) ? 2 : \ +- (n) & (1ULL << 1) ? 1 : \ +- (n) & (1ULL << 0) ? 0 : \ +- ____ilog2_NaN() \ +- ) : \ ++ 1 ) : \ + (sizeof(n) <= 4) ? \ + __ilog2_u32(n) : \ + __ilog2_u64(n) \ +-- +2.12.2 + +From f02729f2ab87c84bbc959e7631487a4b84dbdf63 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Thu, 16 Mar 2017 13:47:49 +0100 +Subject: [PATCH 121/251] perf/core: Fix event inheritance on fork() +Content-Length: 2243 +Lines: 62 + +commit e7cc4865f0f31698ef2f7aac01a50e78968985b7 upstream. + +While hunting for clues to a use-after-free, Oleg spotted that +perf_event_init_context() can loose an error value with the result +that fork() can succeed even though we did not fully inherit the perf +event context. + +Spotted-by: Oleg Nesterov +Signed-off-by: Peter Zijlstra (Intel) +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Arnaldo Carvalho de Melo +Cc: Dmitry Vyukov +Cc: Frederic Weisbecker +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Mathieu Desnoyers +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: Vince Weaver +Cc: oleg@redhat.com +Fixes: 889ff0150661 ("perf/core: Split context's event group list into pinned and non-pinned lists") +Link: http://lkml.kernel.org/r/20170316125823.190342547@infradead.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman +--- + kernel/events/core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 9bbe9ac23cf2..e4b5494f05f8 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -9230,7 +9230,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) + ret = inherit_task_group(event, parent, parent_ctx, + child, ctxn, &inherited_all); + if (ret) +- break; ++ goto out_unlock; + } + + /* +@@ -9246,7 +9246,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) + ret = inherit_task_group(event, parent, parent_ctx, + child, ctxn, &inherited_all); + if (ret) +- break; ++ goto out_unlock; + } + + raw_spin_lock_irqsave(&parent_ctx->lock, flags); +@@ -9274,6 +9274,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) + } + + raw_spin_unlock_irqrestore(&parent_ctx->lock, flags); ++out_unlock: + mutex_unlock(&parent_ctx->mutex); + + perf_unpin_context(parent_ctx); +-- +2.12.2 + +From 09875d1393d4589bcdfeeba8747a12dd69810cc9 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Wed, 15 Mar 2017 00:12:16 +0100 +Subject: [PATCH 122/251] cpufreq: Fix and clean up show_cpuinfo_cur_freq() +Content-Length: 992 +Lines: 33 + +commit 9b4f603e7a9f4282aec451063ffbbb8bb410dcd9 upstream. + +There is a missing newline in show_cpuinfo_cur_freq(), so add it, +but while at it clean that function up somewhat too. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/cpufreq.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 8412ce5f93a7..86fa9fdc8323 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -626,9 +626,11 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, + char *buf) + { + unsigned int cur_freq = __cpufreq_get(policy); +- if (!cur_freq) +- return sprintf(buf, ""); +- return sprintf(buf, "%u\n", cur_freq); ++ ++ if (cur_freq) ++ return sprintf(buf, "%u\n", cur_freq); ++ ++ return sprintf(buf, "\n"); + } + + /** +-- +2.12.2 + +From b24473976b985fd1c1d57a9ea934f9792bf654cc Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Tue, 7 Mar 2017 16:14:49 +1100 +Subject: [PATCH 123/251] powerpc/boot: Fix zImage TOC alignment +Content-Length: 925 +Lines: 29 + +commit 97ee351b50a49717543533cfb85b4bf9d88c9680 upstream. + +Recent toolchains force the TOC to be 256 byte aligned. We need to +enforce this alignment in the zImage linker script, otherwise pointers +to our TOC variables (__toc_start) could be incorrect. If the actual +start of the TOC and __toc_start don't have the same value we crash +early in the zImage wrapper. + +Suggested-by: Alan Modra +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/boot/zImage.lds.S | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S +index 861e72109df2..f080abfc2f83 100644 +--- a/arch/powerpc/boot/zImage.lds.S ++++ b/arch/powerpc/boot/zImage.lds.S +@@ -68,6 +68,7 @@ SECTIONS + } + + #ifdef CONFIG_PPC64_BOOT_WRAPPER ++ . = ALIGN(256); + .got : + { + __toc_start = .; +-- +2.12.2 + +From 582f548924cdda2dadf842020075f6b2525421d2 Mon Sep 17 00:00:00 2001 +From: Shaohua Li +Date: Tue, 28 Feb 2017 13:00:20 -0800 +Subject: [PATCH 124/251] md/raid1/10: fix potential deadlock +Content-Length: 3293 +Lines: 86 + +commit 61eb2b43b99ebdc9bc6bc83d9792257b243e7cb3 upstream. + +Neil Brown pointed out a potential deadlock in raid 10 code with +bio_split/chain. The raid1 code could have the same issue, but recent +barrier rework makes it less likely to happen. The deadlock happens in +below sequence: + +1. generic_make_request(bio), this will set current->bio_list +2. raid10_make_request will split bio to bio1 and bio2 +3. __make_request(bio1), wait_barrer, add underlayer disk bio to +current->bio_list +4. __make_request(bio2), wait_barrer + +If raise_barrier happens between 3 & 4, since wait_barrier runs at 3, +raise_barrier waits for IO completion from 3. And since raise_barrier +sets barrier, 4 waits for raise_barrier. But IO from 3 can't be +dispatched because raid10_make_request() doesn't finished yet. + +The solution is to adjust the IO ordering. Quotes from Neil: +" +It is much safer to: + + if (need to split) { + split = bio_split(bio, ...) + bio_chain(...) + make_request_fn(split); + generic_make_request(bio); + } else + make_request_fn(mddev, bio); + +This way we first process the initial section of the bio (in 'split') +which will queue some requests to the underlying devices. These +requests will be queued in generic_make_request. +Then we queue the remainder of the bio, which will be added to the end +of the generic_make_request queue. +Then we return. +generic_make_request() will pop the lower-level device requests off the +queue and handle them first. Then it will process the remainder +of the original bio once the first section has been fully processed. +" + +Note, this only happens in read path. In write path, the bio is flushed to +underlaying disks either by blk flush (from schedule) or offladed to raid1/10d. +It's queued in current->bio_list. + +Cc: Coly Li +Suggested-by: NeilBrown +Reviewed-by: Jack Wang +Signed-off-by: Shaohua Li +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/raid10.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index ebb0dd612ebd..122af340a531 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -1477,7 +1477,25 @@ static void make_request(struct mddev *mddev, struct bio *bio) + split = bio; + } + ++ /* ++ * If a bio is splitted, the first part of bio will pass ++ * barrier but the bio is queued in current->bio_list (see ++ * generic_make_request). If there is a raise_barrier() called ++ * here, the second part of bio can't pass barrier. But since ++ * the first part bio isn't dispatched to underlaying disks ++ * yet, the barrier is never released, hence raise_barrier will ++ * alays wait. We have a deadlock. ++ * Note, this only happens in read path. For write path, the ++ * first part of bio is dispatched in a schedule() call ++ * (because of blk plug) or offloaded to raid10d. ++ * Quitting from the function immediately can change the bio ++ * order queued in bio_list and avoid the deadlock. ++ */ + __make_request(mddev, split); ++ if (split != bio && bio_data_dir(bio) == READ) { ++ generic_make_request(bio); ++ break; ++ } + } while (split != bio); + + /* In case raid10d snuck in to freeze_array */ +-- +2.12.2 + +From 0a621633cdfa780c50907506457798c907cb8110 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Thu, 3 Nov 2016 23:06:53 -0700 +Subject: [PATCH 125/251] target/pscsi: Fix TYPE_TAPE + TYPE_MEDIMUM_CHANGER + export +Content-Length: 4575 +Lines: 144 + +commit a04e54f2c35823ca32d56afcd5cea5b783e2f51a upstream. + +The following fixes a divide by zero OOPs with TYPE_TAPE +due to pscsi_tape_read_blocksize() failing causing a zero +sd->sector_size being propigated up via dev_attrib.hw_block_size. + +It also fixes another long-standing bug where TYPE_TAPE and +TYPE_MEDIMUM_CHANGER where using pscsi_create_type_other(), +which does not call scsi_device_get() to take the device +reference. Instead, rename pscsi_create_type_rom() to +pscsi_create_type_nondisk() and use it for all cases. + +Finally, also drop a dump_stack() in pscsi_get_blocks() for +non TYPE_DISK, which in modern target-core can get invoked +via target_sense_desc_format() during CHECK_CONDITION. + +Reported-by: Malcolm Haak +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman +--- + drivers/target/target_core_pscsi.c | 47 ++++++++++---------------------------- + 1 file changed, 12 insertions(+), 35 deletions(-) + +diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c +index de18790eb21c..d72a4058fd08 100644 +--- a/drivers/target/target_core_pscsi.c ++++ b/drivers/target/target_core_pscsi.c +@@ -154,7 +154,7 @@ static void pscsi_tape_read_blocksize(struct se_device *dev, + + buf = kzalloc(12, GFP_KERNEL); + if (!buf) +- return; ++ goto out_free; + + memset(cdb, 0, MAX_COMMAND_SIZE); + cdb[0] = MODE_SENSE; +@@ -169,9 +169,10 @@ static void pscsi_tape_read_blocksize(struct se_device *dev, + * If MODE_SENSE still returns zero, set the default value to 1024. + */ + sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]); ++out_free: + if (!sdev->sector_size) + sdev->sector_size = 1024; +-out_free: ++ + kfree(buf); + } + +@@ -314,9 +315,10 @@ static int pscsi_add_device_to_list(struct se_device *dev, + sd->lun, sd->queue_depth); + } + +- dev->dev_attrib.hw_block_size = sd->sector_size; ++ dev->dev_attrib.hw_block_size = ++ min_not_zero((int)sd->sector_size, 512); + dev->dev_attrib.hw_max_sectors = +- min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q)); ++ min_not_zero(sd->host->max_sectors, queue_max_hw_sectors(q)); + dev->dev_attrib.hw_queue_depth = sd->queue_depth; + + /* +@@ -339,8 +341,10 @@ static int pscsi_add_device_to_list(struct se_device *dev, + /* + * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE. + */ +- if (sd->type == TYPE_TAPE) ++ if (sd->type == TYPE_TAPE) { + pscsi_tape_read_blocksize(dev, sd); ++ dev->dev_attrib.hw_block_size = sd->sector_size; ++ } + return 0; + } + +@@ -406,7 +410,7 @@ static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd) + /* + * Called with struct Scsi_Host->host_lock called. + */ +-static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) ++static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device *sd) + __releases(sh->host_lock) + { + struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; +@@ -433,28 +437,6 @@ static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) + return 0; + } + +-/* +- * Called with struct Scsi_Host->host_lock called. +- */ +-static int pscsi_create_type_other(struct se_device *dev, +- struct scsi_device *sd) +- __releases(sh->host_lock) +-{ +- struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; +- struct Scsi_Host *sh = sd->host; +- int ret; +- +- spin_unlock_irq(sh->host_lock); +- ret = pscsi_add_device_to_list(dev, sd); +- if (ret) +- return ret; +- +- pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%llu\n", +- phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, +- sd->channel, sd->id, sd->lun); +- return 0; +-} +- + static int pscsi_configure_device(struct se_device *dev) + { + struct se_hba *hba = dev->se_hba; +@@ -542,11 +524,8 @@ static int pscsi_configure_device(struct se_device *dev) + case TYPE_DISK: + ret = pscsi_create_type_disk(dev, sd); + break; +- case TYPE_ROM: +- ret = pscsi_create_type_rom(dev, sd); +- break; + default: +- ret = pscsi_create_type_other(dev, sd); ++ ret = pscsi_create_type_nondisk(dev, sd); + break; + } + +@@ -611,8 +590,7 @@ static void pscsi_free_device(struct se_device *dev) + else if (pdv->pdv_lld_host) + scsi_host_put(pdv->pdv_lld_host); + +- if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM)) +- scsi_device_put(sd); ++ scsi_device_put(sd); + + pdv->pdv_sd = NULL; + } +@@ -1088,7 +1066,6 @@ static sector_t pscsi_get_blocks(struct se_device *dev) + if (pdv->pdv_bd && pdv->pdv_bd->bd_part) + return pdv->pdv_bd->bd_part->nr_sects; + +- dump_stack(); + return 0; + } + +-- +2.12.2 + +From 82bd06aba880215dadd3e33dc3d583d32df9dbbb Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Mon, 13 Feb 2017 08:49:20 +1100 +Subject: [PATCH 126/251] scsi: lpfc: Add shutdown method for kexec +Content-Length: 1074 +Lines: 28 + +commit 85e8a23936ab3442de0c42da97d53b29f004ece1 upstream. + +We see lpfc devices regularly fail during kexec. Fix this by adding a +shutdown method which mirrors the remove method. + +Signed-off-by: Anton Blanchard +Reviewed-by: Mauricio Faria de Oliveira +Tested-by: Mauricio Faria de Oliveira +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/lpfc/lpfc_init.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c +index c14ab6c3ae40..60c21093f865 100644 +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -11387,6 +11387,7 @@ static struct pci_driver lpfc_driver = { + .id_table = lpfc_id_table, + .probe = lpfc_pci_probe_one, + .remove = lpfc_pci_remove_one, ++ .shutdown = lpfc_pci_remove_one, + .suspend = lpfc_pci_suspend_one, + .resume = lpfc_pci_resume_one, + .err_handler = &lpfc_err_handler, +-- +2.12.2 + +From 246760c61d9c4c0114ba5bd324df4ae17468e238 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Mon, 27 Feb 2017 16:58:36 -0800 +Subject: [PATCH 127/251] scsi: libiscsi: add lock around task lists to fix + list corruption regression +Content-Length: 6411 +Lines: 179 + +commit 6f8830f5bbab16e54f261de187f3df4644a5b977 upstream. + +There's a rather long standing regression from the commit "libiscsi: +Reduce locking contention in fast path" + +Depending on iSCSI target behavior, it's possible to hit the case in +iscsi_complete_task where the task is still on a pending list +(!list_empty(&task->running)). When that happens the task is removed +from the list while holding the session back_lock, but other task list +modification occur under the frwd_lock. That leads to linked list +corruption and eventually a panicked system. + +Rather than back out the session lock split entirely, in order to try +and keep some of the performance gains this patch adds another lock to +maintain the task lists integrity. + +Major enterprise supported kernels have been backing out the lock split +for while now, thanks to the efforts at IBM where a lab setup has the +most reliable reproducer I've seen on this issue. This patch has been +tested there successfully. + +Signed-off-by: Chris Leech +Fixes: 659743b02c41 ("[SCSI] libiscsi: Reduce locking contention in fast path") +Reported-by: Prashantha Subbarao +Reviewed-by: Guilherme G. Piccoli +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/libiscsi.c | 26 +++++++++++++++++++++++++- + include/scsi/libiscsi.h | 1 + + 2 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c +index 6bffd91b973a..c1ccf1ee99ea 100644 +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -560,8 +560,12 @@ static void iscsi_complete_task(struct iscsi_task *task, int state) + WARN_ON_ONCE(task->state == ISCSI_TASK_FREE); + task->state = state; + +- if (!list_empty(&task->running)) ++ spin_lock_bh(&conn->taskqueuelock); ++ if (!list_empty(&task->running)) { ++ pr_debug_once("%s while task on list", __func__); + list_del_init(&task->running); ++ } ++ spin_unlock_bh(&conn->taskqueuelock); + + if (conn->task == task) + conn->task = NULL; +@@ -783,7 +787,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, + if (session->tt->xmit_task(task)) + goto free_task; + } else { ++ spin_lock_bh(&conn->taskqueuelock); + list_add_tail(&task->running, &conn->mgmtqueue); ++ spin_unlock_bh(&conn->taskqueuelock); + iscsi_conn_queue_work(conn); + } + +@@ -1474,8 +1480,10 @@ void iscsi_requeue_task(struct iscsi_task *task) + * this may be on the requeue list already if the xmit_task callout + * is handling the r2ts while we are adding new ones + */ ++ spin_lock_bh(&conn->taskqueuelock); + if (list_empty(&task->running)) + list_add_tail(&task->running, &conn->requeue); ++ spin_unlock_bh(&conn->taskqueuelock); + iscsi_conn_queue_work(conn); + } + EXPORT_SYMBOL_GPL(iscsi_requeue_task); +@@ -1512,22 +1520,26 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) + * only have one nop-out as a ping from us and targets should not + * overflow us with nop-ins + */ ++ spin_lock_bh(&conn->taskqueuelock); + check_mgmt: + while (!list_empty(&conn->mgmtqueue)) { + conn->task = list_entry(conn->mgmtqueue.next, + struct iscsi_task, running); + list_del_init(&conn->task->running); ++ spin_unlock_bh(&conn->taskqueuelock); + if (iscsi_prep_mgmt_task(conn, conn->task)) { + /* regular RX path uses back_lock */ + spin_lock_bh(&conn->session->back_lock); + __iscsi_put_task(conn->task); + spin_unlock_bh(&conn->session->back_lock); + conn->task = NULL; ++ spin_lock_bh(&conn->taskqueuelock); + continue; + } + rc = iscsi_xmit_task(conn); + if (rc) + goto done; ++ spin_lock_bh(&conn->taskqueuelock); + } + + /* process pending command queue */ +@@ -1535,19 +1547,24 @@ check_mgmt: + conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task, + running); + list_del_init(&conn->task->running); ++ spin_unlock_bh(&conn->taskqueuelock); + if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { + fail_scsi_task(conn->task, DID_IMM_RETRY); ++ spin_lock_bh(&conn->taskqueuelock); + continue; + } + rc = iscsi_prep_scsi_cmd_pdu(conn->task); + if (rc) { + if (rc == -ENOMEM || rc == -EACCES) { ++ spin_lock_bh(&conn->taskqueuelock); + list_add_tail(&conn->task->running, + &conn->cmdqueue); + conn->task = NULL; ++ spin_unlock_bh(&conn->taskqueuelock); + goto done; + } else + fail_scsi_task(conn->task, DID_ABORT); ++ spin_lock_bh(&conn->taskqueuelock); + continue; + } + rc = iscsi_xmit_task(conn); +@@ -1558,6 +1575,7 @@ check_mgmt: + * we need to check the mgmt queue for nops that need to + * be sent to aviod starvation + */ ++ spin_lock_bh(&conn->taskqueuelock); + if (!list_empty(&conn->mgmtqueue)) + goto check_mgmt; + } +@@ -1577,12 +1595,15 @@ check_mgmt: + conn->task = task; + list_del_init(&conn->task->running); + conn->task->state = ISCSI_TASK_RUNNING; ++ spin_unlock_bh(&conn->taskqueuelock); + rc = iscsi_xmit_task(conn); + if (rc) + goto done; ++ spin_lock_bh(&conn->taskqueuelock); + if (!list_empty(&conn->mgmtqueue)) + goto check_mgmt; + } ++ spin_unlock_bh(&conn->taskqueuelock); + spin_unlock_bh(&conn->session->frwd_lock); + return -ENODATA; + +@@ -1738,7 +1759,9 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) + goto prepd_reject; + } + } else { ++ spin_lock_bh(&conn->taskqueuelock); + list_add_tail(&task->running, &conn->cmdqueue); ++ spin_unlock_bh(&conn->taskqueuelock); + iscsi_conn_queue_work(conn); + } + +@@ -2900,6 +2923,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, + INIT_LIST_HEAD(&conn->mgmtqueue); + INIT_LIST_HEAD(&conn->cmdqueue); + INIT_LIST_HEAD(&conn->requeue); ++ spin_lock_init(&conn->taskqueuelock); + INIT_WORK(&conn->xmitwork, iscsi_xmitworker); + + /* allocate login_task used for the login/text sequences */ +diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h +index 4d1c46aac331..c7b1dc713cdd 100644 +--- a/include/scsi/libiscsi.h ++++ b/include/scsi/libiscsi.h +@@ -196,6 +196,7 @@ struct iscsi_conn { + struct iscsi_task *task; /* xmit task in progress */ + + /* xmit */ ++ spinlock_t taskqueuelock; /* protects the next three lists */ + struct list_head mgmtqueue; /* mgmt (control) xmit queue */ + struct list_head cmdqueue; /* data-path cmd queue */ + struct list_head requeue; /* tasks needing another run */ +-- +2.12.2 + +From d267ecbdfdb4199c0e3a967ecc17a6b80d95209a Mon Sep 17 00:00:00 2001 +From: Max Lohrmann +Date: Tue, 7 Mar 2017 22:09:56 -0800 +Subject: [PATCH 128/251] target: Fix VERIFY_16 handling in sbc_parse_cdb +Content-Length: 1397 +Lines: 42 + +commit 13603685c1f12c67a7a2427f00b63f39a2b6f7c9 upstream. + +As reported by Max, the Windows 2008 R2 chkdsk utility expects +VERIFY_16 to be supported, and does not handle the returned +CHECK_CONDITION properly, resulting in an infinite loop. + +The kernel will log huge amounts of this error: + +kernel: TARGET_CORE[iSCSI]: Unsupported SCSI Opcode 0x8f, sending +CHECK_CONDITION. + +Signed-off-by: Max Lohrmann +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman +--- + drivers/target/target_core_sbc.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c +index 2e27b1034ede..90c5dffc9fa4 100644 +--- a/drivers/target/target_core_sbc.c ++++ b/drivers/target/target_core_sbc.c +@@ -1096,9 +1096,15 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) + return ret; + break; + case VERIFY: ++ case VERIFY_16: + size = 0; +- sectors = transport_get_sectors_10(cdb); +- cmd->t_task_lba = transport_lba_32(cdb); ++ if (cdb[0] == VERIFY) { ++ sectors = transport_get_sectors_10(cdb); ++ cmd->t_task_lba = transport_lba_32(cdb); ++ } else { ++ sectors = transport_get_sectors_16(cdb); ++ cmd->t_task_lba = transport_lba_64(cdb); ++ } + cmd->execute_cmd = sbc_emulate_noop; + goto check_lba; + case REZERO_UNIT: +-- +2.12.2 + +From 4f47ca4882564c4b76cc9c426583a49d23893dda Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:39:01 +0100 +Subject: [PATCH 129/251] isdn/gigaset: fix NULL-deref at probe +Content-Length: 1072 +Lines: 30 + +commit 68c32f9c2a36d410aa242e661506e5b2c2764179 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Fixes: cf7776dc05b8 ("[PATCH] isdn4linux: Siemens Gigaset drivers - direct USB connection") +Cc: Hansjoerg Lipp +Signed-off-by: Johan Hovold +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/isdn/gigaset/bas-gigaset.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c +index aecec6d32463..7f1c625b08ec 100644 +--- a/drivers/isdn/gigaset/bas-gigaset.c ++++ b/drivers/isdn/gigaset/bas-gigaset.c +@@ -2317,6 +2317,9 @@ static int gigaset_probe(struct usb_interface *interface, + return -ENODEV; + } + ++ if (hostif->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + dev_info(&udev->dev, + "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n", + __func__, le16_to_cpu(udev->descriptor.idVendor), +-- +2.12.2 + +From e08f608ab4288f4192a504e6c94dd7c9c931dad8 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 6 Mar 2017 12:58:42 -0500 +Subject: [PATCH 130/251] gfs2: Avoid alignment hole in struct lm_lockname +Content-Length: 1009 +Lines: 30 + +commit 28ea06c46fbcab63fd9a55531387b7928a18a590 upstream. + +Commit 88ffbf3e03 switches to using rhashtables for glocks, hashing over +the entire struct lm_lockname instead of its individual fields. On some +architectures, struct lm_lockname contains a hole of uninitialized +memory due to alignment rules, which now leads to incorrect hash values. +Get rid of that hole. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Bob Peterson +Signed-off-by: Greg Kroah-Hartman +--- + fs/gfs2/incore.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h +index de7b4f97ac75..be519416c112 100644 +--- a/fs/gfs2/incore.h ++++ b/fs/gfs2/incore.h +@@ -207,7 +207,7 @@ struct lm_lockname { + struct gfs2_sbd *ln_sbd; + u64 ln_number; + unsigned int ln_type; +-}; ++} __packed __aligned(sizeof(int)); + + #define lm_name_equal(name1, name2) \ + (((name1)->ln_number == (name2)->ln_number) && \ +-- +2.12.2 + +From d88b83e66bbf588a5d85168d9839501cd47fe561 Mon Sep 17 00:00:00 2001 +From: Tahsin Erdogan +Date: Sat, 25 Feb 2017 13:00:19 -0800 +Subject: [PATCH 131/251] percpu: acquire pcpu_lock when updating + pcpu_nr_empty_pop_pages +Content-Length: 1047 +Lines: 33 + +commit 320661b08dd6f1746d5c7ab4eb435ec64b97cd45 upstream. + +Update to pcpu_nr_empty_pop_pages in pcpu_alloc() is currently done +without holding pcpu_lock. This can lead to bad updates to the variable. +Add missing lock calls. + +Fixes: b539b87fed37 ("percpu: implmeent pcpu_nr_empty_pop_pages and chunk->nr_populated") +Signed-off-by: Tahsin Erdogan +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + mm/percpu.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/mm/percpu.c b/mm/percpu.c +index 1f376bce413c..ef6353f0adbd 100644 +--- a/mm/percpu.c ++++ b/mm/percpu.c +@@ -1012,8 +1012,11 @@ area_found: + mutex_unlock(&pcpu_alloc_mutex); + } + +- if (chunk != pcpu_reserved_chunk) ++ if (chunk != pcpu_reserved_chunk) { ++ spin_lock_irqsave(&pcpu_lock, flags); + pcpu_nr_empty_pop_pages -= occ_pages; ++ spin_unlock_irqrestore(&pcpu_lock, flags); ++ } + + if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_LOW) + pcpu_schedule_balance_work(); +-- +2.12.2 + +From 5fa513cb07213608907d4daa123b81e5a32d13e0 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 15 Feb 2017 01:26:39 -0500 +Subject: [PATCH 132/251] ext4: fix fencepost in s_first_meta_bg validation +Content-Length: 1128 +Lines: 31 + +commit 2ba3e6e8afc9b6188b471f27cf2b5e3cf34e7af2 upstream. + +It is OK for s_first_meta_bg to be equal to the number of block group +descriptor blocks. (It rarely happens, but it shouldn't cause any +problems.) + +https://bugzilla.kernel.org/show_bug.cgi?id=194567 + +Fixes: 3a4b77cd47bb837b8557595ec7425f281f2ca1fe +Signed-off-by: Theodore Ts'o +Cc: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 6fe8e30eeb99..68345a9e59b8 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3666,7 +3666,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) + db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / + EXT4_DESC_PER_BLOCK(sb); + if (ext4_has_feature_meta_bg(sb)) { +- if (le32_to_cpu(es->s_first_meta_bg) >= db_count) { ++ if (le32_to_cpu(es->s_first_meta_bg) > db_count) { + ext4_msg(sb, KERN_WARNING, + "first meta block group too large: %u " + "(group descriptor block count %u)", +-- +2.12.2 + +From a5c3f390eb7799c3d1d92121382372b1fd365fa3 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Sun, 26 Mar 2017 12:13:55 +0200 +Subject: [PATCH 133/251] Linux 4.4.57 +Content-Length: 301 +Lines: 18 + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index cf9303a5d621..841675e63a38 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 56 ++SUBLEVEL = 57 + EXTRAVERSION = + NAME = Blurry Fish Butt + +-- +2.12.2 + +From b362d6735156add0e43b1221b17277d5fb45622d Mon Sep 17 00:00:00 2001 +From: Or Gerlitz +Date: Wed, 15 Mar 2017 18:10:47 +0200 +Subject: [PATCH 134/251] net/openvswitch: Set the ipv6 source tunnel key + address attribute correctly +Content-Length: 1163 +Lines: 32 + +[ Upstream commit 3d20f1f7bd575d147ffa75621fa560eea0aec690 ] + +When dealing with ipv6 source tunnel key address attribute +(OVS_TUNNEL_KEY_ATTR_IPV6_SRC) we are wrongly setting the tunnel +dst ip, fix that. + +Fixes: 6b26ba3a7d95 ('openvswitch: netlink attributes for IPv6 tunneling') +Signed-off-by: Or Gerlitz +Reported-by: Paul Blakey +Acked-by: Jiri Benc +Acked-by: Joe Stringer +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/openvswitch/flow_netlink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c +index d1bd4a45ca2d..d26b28def310 100644 +--- a/net/openvswitch/flow_netlink.c ++++ b/net/openvswitch/flow_netlink.c +@@ -588,7 +588,7 @@ static int ip_tun_from_nlattr(const struct nlattr *attr, + ipv4 = true; + break; + case OVS_TUNNEL_KEY_ATTR_IPV6_SRC: +- SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst, ++ SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.src, + nla_get_in6_addr(a), is_mask); + ipv6 = true; + break; +-- +2.12.2 + +From 12f0bffc489dff7088c73f600b6be5769bc73cbd Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Wed, 15 Mar 2017 12:57:21 -0700 +Subject: [PATCH 135/251] net: bcmgenet: Do not suspend PHY if Wake-on-LAN is + enabled +Content-Length: 1278 +Lines: 39 + +[ Upstream commit 5371bbf4b295eea334ed453efa286afa2c3ccff3 ] + +Suspending the PHY would be putting it in a low power state where it +may no longer allow us to do Wake-on-LAN. + +Fixes: cc013fb48898 ("net: bcmgenet: correctly suspend and resume PHY device") +Signed-off-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index 91627561c58d..f971d92f7b41 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -3495,7 +3495,8 @@ static int bcmgenet_suspend(struct device *d) + + bcmgenet_netif_stop(dev); + +- phy_suspend(priv->phydev); ++ if (!device_may_wakeup(d)) ++ phy_suspend(priv->phydev); + + netif_device_detach(dev); + +@@ -3592,7 +3593,8 @@ static int bcmgenet_resume(struct device *d) + + netif_device_attach(dev); + +- phy_resume(priv->phydev); ++ if (!device_may_wakeup(d)) ++ phy_resume(priv->phydev); + + if (priv->eee.eee_enabled) + bcmgenet_eee_enable_set(dev, true); +-- +2.12.2 + +From f3126725228c0fdbe17c18bcc5ace1b86465cce9 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 15 Mar 2017 13:21:28 -0700 +Subject: [PATCH 136/251] net: properly release sk_frag.page +Content-Length: 1357 +Lines: 48 + +[ Upstream commit 22a0e18eac7a9e986fec76c60fa4a2926d1291e2 ] + +I mistakenly added the code to release sk->sk_frag in +sk_common_release() instead of sk_destruct() + +TCP sockets using sk->sk_allocation == GFP_ATOMIC do no call +sk_common_release() at close time, thus leaking one (order-3) page. + +iSCSI is using such sockets. + +Fixes: 5640f7685831 ("net: use a per task frag allocator") +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/sock.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/core/sock.c b/net/core/sock.c +index f4c0917e66b5..9f4c4473156a 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1459,6 +1459,11 @@ void sk_destruct(struct sock *sk) + pr_debug("%s: optmem leakage (%d bytes) detected\n", + __func__, atomic_read(&sk->sk_omem_alloc)); + ++ if (sk->sk_frag.page) { ++ put_page(sk->sk_frag.page); ++ sk->sk_frag.page = NULL; ++ } ++ + if (sk->sk_peer_cred) + put_cred(sk->sk_peer_cred); + put_pid(sk->sk_peer_pid); +@@ -2691,11 +2696,6 @@ void sk_common_release(struct sock *sk) + + sk_refcnt_debug_release(sk); + +- if (sk->sk_frag.page) { +- put_page(sk->sk_frag.page); +- sk->sk_frag.page = NULL; +- } +- + sock_put(sk); + } + EXPORT_SYMBOL(sk_common_release); +-- +2.12.2 + +From ae43f9360a21b35cf785ae9a0fdce524d7af0938 Mon Sep 17 00:00:00 2001 +From: "Lendacky, Thomas" +Date: Wed, 15 Mar 2017 15:11:23 -0500 +Subject: [PATCH 137/251] amd-xgbe: Fix jumbo MTU processing on newer hardware +Content-Length: 9733 +Lines: 284 + +[ Upstream commit 622c36f143fc9566ba49d7cec994c2da1182d9e2 ] + +Newer hardware does not provide a cumulative payload length when multiple +descriptors are needed to handle the data. Once the MTU increases beyond +the size that can be handled by a single descriptor, the SKB does not get +built properly by the driver. + +The driver will now calculate the size of the data buffers used by the +hardware. The first buffer of the first descriptor is for packet headers +or packet headers and data when the headers can't be split. Subsequent +descriptors in a multi-descriptor chain will not use the first buffer. The +second buffer is used by all the descriptors in the chain for payload data. +Based on whether the driver is processing the first, intermediate, or last +descriptor it can calculate the buffer usage and build the SKB properly. + +Tested and verified on both old and new hardware. + +Signed-off-by: Tom Lendacky +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/amd/xgbe/xgbe-common.h | 6 +- + drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 20 +++--- + drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 102 +++++++++++++++++----------- + 3 files changed, 78 insertions(+), 50 deletions(-) + +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h +index b6fa89102526..66ba1e0ff37e 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h +@@ -913,8 +913,8 @@ + #define RX_PACKET_ATTRIBUTES_CSUM_DONE_WIDTH 1 + #define RX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 1 + #define RX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1 +-#define RX_PACKET_ATTRIBUTES_INCOMPLETE_INDEX 2 +-#define RX_PACKET_ATTRIBUTES_INCOMPLETE_WIDTH 1 ++#define RX_PACKET_ATTRIBUTES_LAST_INDEX 2 ++#define RX_PACKET_ATTRIBUTES_LAST_WIDTH 1 + #define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_INDEX 3 + #define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_WIDTH 1 + #define RX_PACKET_ATTRIBUTES_CONTEXT_INDEX 4 +@@ -923,6 +923,8 @@ + #define RX_PACKET_ATTRIBUTES_RX_TSTAMP_WIDTH 1 + #define RX_PACKET_ATTRIBUTES_RSS_HASH_INDEX 6 + #define RX_PACKET_ATTRIBUTES_RSS_HASH_WIDTH 1 ++#define RX_PACKET_ATTRIBUTES_FIRST_INDEX 7 ++#define RX_PACKET_ATTRIBUTES_FIRST_WIDTH 1 + + #define RX_NORMAL_DESC0_OVT_INDEX 0 + #define RX_NORMAL_DESC0_OVT_WIDTH 16 +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +index f6a7161e3b85..5e6238e0b2bd 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +@@ -1658,10 +1658,15 @@ static int xgbe_dev_read(struct xgbe_channel *channel) + + /* Get the header length */ + if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, FD)) { ++ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, ++ FIRST, 1); + rdata->rx.hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2, + RX_NORMAL_DESC2, HL); + if (rdata->rx.hdr_len) + pdata->ext_stats.rx_split_header_packets++; ++ } else { ++ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, ++ FIRST, 0); + } + + /* Get the RSS hash */ +@@ -1684,19 +1689,16 @@ static int xgbe_dev_read(struct xgbe_channel *channel) + } + } + +- /* Get the packet length */ +- rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL); +- +- if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) { +- /* Not all the data has been transferred for this packet */ +- XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, +- INCOMPLETE, 1); ++ /* Not all the data has been transferred for this packet */ ++ if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) + return 0; +- } + + /* This is the last of the data for this packet */ + XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, +- INCOMPLETE, 0); ++ LAST, 1); ++ ++ /* Get the packet length */ ++ rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL); + + /* Set checksum done indicator as appropriate */ + if (netdev->features & NETIF_F_RXCSUM) +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +index 53ce1222b11d..865b7e0b133b 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +@@ -1760,13 +1760,12 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata, + { + struct sk_buff *skb; + u8 *packet; +- unsigned int copy_len; + + skb = napi_alloc_skb(napi, rdata->rx.hdr.dma_len); + if (!skb) + return NULL; + +- /* Start with the header buffer which may contain just the header ++ /* Pull in the header buffer which may contain just the header + * or the header plus data + */ + dma_sync_single_range_for_cpu(pdata->dev, rdata->rx.hdr.dma_base, +@@ -1775,30 +1774,49 @@ static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata, + + packet = page_address(rdata->rx.hdr.pa.pages) + + rdata->rx.hdr.pa.pages_offset; +- copy_len = (rdata->rx.hdr_len) ? rdata->rx.hdr_len : len; +- copy_len = min(rdata->rx.hdr.dma_len, copy_len); +- skb_copy_to_linear_data(skb, packet, copy_len); +- skb_put(skb, copy_len); +- +- len -= copy_len; +- if (len) { +- /* Add the remaining data as a frag */ +- dma_sync_single_range_for_cpu(pdata->dev, +- rdata->rx.buf.dma_base, +- rdata->rx.buf.dma_off, +- rdata->rx.buf.dma_len, +- DMA_FROM_DEVICE); +- +- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, +- rdata->rx.buf.pa.pages, +- rdata->rx.buf.pa.pages_offset, +- len, rdata->rx.buf.dma_len); +- rdata->rx.buf.pa.pages = NULL; +- } ++ skb_copy_to_linear_data(skb, packet, len); ++ skb_put(skb, len); + + return skb; + } + ++static unsigned int xgbe_rx_buf1_len(struct xgbe_ring_data *rdata, ++ struct xgbe_packet_data *packet) ++{ ++ /* Always zero if not the first descriptor */ ++ if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, FIRST)) ++ return 0; ++ ++ /* First descriptor with split header, return header length */ ++ if (rdata->rx.hdr_len) ++ return rdata->rx.hdr_len; ++ ++ /* First descriptor but not the last descriptor and no split header, ++ * so the full buffer was used ++ */ ++ if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, LAST)) ++ return rdata->rx.hdr.dma_len; ++ ++ /* First descriptor and last descriptor and no split header, so ++ * calculate how much of the buffer was used ++ */ ++ return min_t(unsigned int, rdata->rx.hdr.dma_len, rdata->rx.len); ++} ++ ++static unsigned int xgbe_rx_buf2_len(struct xgbe_ring_data *rdata, ++ struct xgbe_packet_data *packet, ++ unsigned int len) ++{ ++ /* Always the full buffer if not the last descriptor */ ++ if (!XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, LAST)) ++ return rdata->rx.buf.dma_len; ++ ++ /* Last descriptor so calculate how much of the buffer was used ++ * for the last bit of data ++ */ ++ return rdata->rx.len - len; ++} ++ + static int xgbe_tx_poll(struct xgbe_channel *channel) + { + struct xgbe_prv_data *pdata = channel->pdata; +@@ -1881,8 +1899,8 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) + struct napi_struct *napi; + struct sk_buff *skb; + struct skb_shared_hwtstamps *hwtstamps; +- unsigned int incomplete, error, context_next, context; +- unsigned int len, rdesc_len, max_len; ++ unsigned int last, error, context_next, context; ++ unsigned int len, buf1_len, buf2_len, max_len; + unsigned int received = 0; + int packet_count = 0; + +@@ -1892,7 +1910,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) + if (!ring) + return 0; + +- incomplete = 0; ++ last = 0; + context_next = 0; + + napi = (pdata->per_channel_irq) ? &channel->napi : &pdata->napi; +@@ -1926,9 +1944,8 @@ read_again: + received++; + ring->cur++; + +- incomplete = XGMAC_GET_BITS(packet->attributes, +- RX_PACKET_ATTRIBUTES, +- INCOMPLETE); ++ last = XGMAC_GET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, ++ LAST); + context_next = XGMAC_GET_BITS(packet->attributes, + RX_PACKET_ATTRIBUTES, + CONTEXT_NEXT); +@@ -1937,7 +1954,7 @@ read_again: + CONTEXT); + + /* Earlier error, just drain the remaining data */ +- if ((incomplete || context_next) && error) ++ if ((!last || context_next) && error) + goto read_again; + + if (error || packet->errors) { +@@ -1949,16 +1966,22 @@ read_again: + } + + if (!context) { +- /* Length is cumulative, get this descriptor's length */ +- rdesc_len = rdata->rx.len - len; +- len += rdesc_len; ++ /* Get the data length in the descriptor buffers */ ++ buf1_len = xgbe_rx_buf1_len(rdata, packet); ++ len += buf1_len; ++ buf2_len = xgbe_rx_buf2_len(rdata, packet, len); ++ len += buf2_len; + +- if (rdesc_len && !skb) { ++ if (!skb) { + skb = xgbe_create_skb(pdata, napi, rdata, +- rdesc_len); +- if (!skb) ++ buf1_len); ++ if (!skb) { + error = 1; +- } else if (rdesc_len) { ++ goto skip_data; ++ } ++ } ++ ++ if (buf2_len) { + dma_sync_single_range_for_cpu(pdata->dev, + rdata->rx.buf.dma_base, + rdata->rx.buf.dma_off, +@@ -1968,13 +1991,14 @@ read_again: + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, + rdata->rx.buf.pa.pages, + rdata->rx.buf.pa.pages_offset, +- rdesc_len, ++ buf2_len, + rdata->rx.buf.dma_len); + rdata->rx.buf.pa.pages = NULL; + } + } + +- if (incomplete || context_next) ++skip_data: ++ if (!last || context_next) + goto read_again; + + if (!skb) +@@ -2033,7 +2057,7 @@ next_packet: + } + + /* Check if we need to save state before leaving */ +- if (received && (incomplete || context_next)) { ++ if (received && (!last || context_next)) { + rdata = XGBE_GET_DESC_DATA(ring, ring->cur); + rdata->state_saved = 1; + rdata->state.skb = skb; +-- +2.12.2 + +From 610c6bcc5fcfb6d02d63cfded2375a829df7faba Mon Sep 17 00:00:00 2001 +From: Andrey Ulanov +Date: Tue, 14 Mar 2017 20:16:42 -0700 +Subject: [PATCH 138/251] net: unix: properly re-increment inflight counter of + GC discarded candidates +Content-Length: 4671 +Lines: 107 + +[ Upstream commit 7df9c24625b9981779afb8fcdbe2bb4765e61147 ] + +Dmitry has reported that a BUG_ON() condition in unix_notinflight() +may be triggered by a simple code that forwards unix socket in an +SCM_RIGHTS message. +That is caused by incorrect unix socket GC implementation in unix_gc(). + +The GC first collects list of candidates, then (a) decrements their +"children's" inflight counter, (b) checks which inflight counters are +now 0, and then (c) increments all inflight counters back. +(a) and (c) are done by calling scan_children() with inc_inflight or +dec_inflight as the second argument. + +Commit 6209344f5a37 ("net: unix: fix inflight counting bug in garbage +collector") changed scan_children() such that it no longer considers +sockets that do not have UNIX_GC_CANDIDATE flag. It also added a block +of code that that unsets this flag _before_ invoking +scan_children(, dec_iflight, ). This may lead to incorrect inflight +counters for some sockets. + +This change fixes this bug by changing order of operations: +UNIX_GC_CANDIDATE is now unset only after all inflight counters are +restored to the original state. + + kernel BUG at net/unix/garbage.c:149! + RIP: 0010:[] [] + unix_notinflight+0x3b4/0x490 net/unix/garbage.c:149 + Call Trace: + [] unix_detach_fds.isra.19+0xff/0x170 net/unix/af_unix.c:1487 + [] unix_destruct_scm+0xf9/0x210 net/unix/af_unix.c:1496 + [] skb_release_head_state+0x101/0x200 net/core/skbuff.c:655 + [] skb_release_all+0x1a/0x60 net/core/skbuff.c:668 + [] __kfree_skb+0x1a/0x30 net/core/skbuff.c:684 + [] kfree_skb+0x184/0x570 net/core/skbuff.c:705 + [] unix_release_sock+0x5b5/0xbd0 net/unix/af_unix.c:559 + [] unix_release+0x49/0x90 net/unix/af_unix.c:836 + [] sock_release+0x92/0x1f0 net/socket.c:570 + [] sock_close+0x1b/0x20 net/socket.c:1017 + [] __fput+0x34e/0x910 fs/file_table.c:208 + [] ____fput+0x1a/0x20 fs/file_table.c:244 + [] task_work_run+0x1a0/0x280 kernel/task_work.c:116 + [< inline >] exit_task_work include/linux/task_work.h:21 + [] do_exit+0x183a/0x2640 kernel/exit.c:828 + [] do_group_exit+0x14e/0x420 kernel/exit.c:931 + [] get_signal+0x663/0x1880 kernel/signal.c:2307 + [] do_signal+0xc5/0x2190 arch/x86/kernel/signal.c:807 + [] exit_to_usermode_loop+0x1ea/0x2d0 + arch/x86/entry/common.c:156 + [< inline >] prepare_exit_to_usermode arch/x86/entry/common.c:190 + [] syscall_return_slowpath+0x4d3/0x570 + arch/x86/entry/common.c:259 + [] entry_SYSCALL_64_fastpath+0xc4/0xc6 + +Link: https://lkml.org/lkml/2017/3/6/252 +Signed-off-by: Andrey Ulanov +Reported-by: Dmitry Vyukov +Fixes: 6209344 ("net: unix: fix inflight counting bug in garbage collector") +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/unix/garbage.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/net/unix/garbage.c b/net/unix/garbage.c +index 6a0d48525fcf..c36757e72844 100644 +--- a/net/unix/garbage.c ++++ b/net/unix/garbage.c +@@ -146,6 +146,7 @@ void unix_notinflight(struct user_struct *user, struct file *fp) + if (s) { + struct unix_sock *u = unix_sk(s); + ++ BUG_ON(!atomic_long_read(&u->inflight)); + BUG_ON(list_empty(&u->link)); + + if (atomic_long_dec_and_test(&u->inflight)) +@@ -341,6 +342,14 @@ void unix_gc(void) + } + list_del(&cursor); + ++ /* Now gc_candidates contains only garbage. Restore original ++ * inflight counters for these as well, and remove the skbuffs ++ * which are creating the cycle(s). ++ */ ++ skb_queue_head_init(&hitlist); ++ list_for_each_entry(u, &gc_candidates, link) ++ scan_children(&u->sk, inc_inflight, &hitlist); ++ + /* not_cycle_list contains those sockets which do not make up a + * cycle. Restore these to the inflight list. + */ +@@ -350,14 +359,6 @@ void unix_gc(void) + list_move_tail(&u->link, &gc_inflight_list); + } + +- /* Now gc_candidates contains only garbage. Restore original +- * inflight counters for these as well, and remove the skbuffs +- * which are creating the cycle(s). +- */ +- skb_queue_head_init(&hitlist); +- list_for_each_entry(u, &gc_candidates, link) +- scan_children(&u->sk, inc_inflight, &hitlist); +- + spin_unlock(&unix_gc_lock); + + /* Here we are. Hitlist is filled. Die. */ +-- +2.12.2 + +From 9d1894cba25c06b061565da6934ab43f446d3c69 Mon Sep 17 00:00:00 2001 +From: Maor Gottlieb +Date: Tue, 21 Mar 2017 15:59:17 +0200 +Subject: [PATCH 139/251] net/mlx5: Increase number of max QPs in default + profile +Content-Length: 1120 +Lines: 30 + +[ Upstream commit 5f40b4ed975c26016cf41953b7510fe90718e21c ] + +With ConnectX-4 sharing SRQs from the same space as QPs, we hit a +limit preventing some applications to allocate needed QPs amount. +Double the size to 256K. + +Fixes: e126ba97dba9e ('mlx5: Add driver for Mellanox Connect-IB adapters') +Signed-off-by: Maor Gottlieb +Signed-off-by: Saeed Mahameed +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c +index ba115ec7aa92..1e611980cf99 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -85,7 +85,7 @@ static struct mlx5_profile profile[] = { + [2] = { + .mask = MLX5_PROF_MASK_QP_SIZE | + MLX5_PROF_MASK_MR_CACHE, +- .log_max_qp = 17, ++ .log_max_qp = 18, + .mr_cache[0] = { + .size = 500, + .limit = 250 +-- +2.12.2 + +From fdcee7c1e2f8c6f46f26010b133ed963b620da2b Mon Sep 17 00:00:00 2001 +From: Gal Pressman +Date: Tue, 21 Mar 2017 15:59:19 +0200 +Subject: [PATCH 140/251] net/mlx5e: Count LRO packets correctly +Content-Length: 1894 +Lines: 50 + +[ Upstream commit 8ab7e2ae15d84ba758b2c8c6f4075722e9bd2a08 ] + +RX packets statistics ('rx_packets' counter) used to count LRO packets +as one, even though it contains multiple segments. +This patch will increment the counter by the number of segments, and +align the driver with the behavior of other drivers in the stack. + +Note that no information is lost in this patch due to 'rx_lro_packets' +counter existence. + +Before, ethtool showed: +$ ethtool -S ens6 | egrep "rx_packets|rx_lro_packets" + rx_packets: 435277 + rx_lro_packets: 35847 + rx_packets_phy: 1935066 + +Now, we will see the more logical statistics: +$ ethtool -S ens6 | egrep "rx_packets|rx_lro_packets" + rx_packets: 1935066 + rx_lro_packets: 35847 + rx_packets_phy: 1935066 + +Fixes: e586b3b0baee ("net/mlx5: Ethernet Datapath files") +Signed-off-by: Gal Pressman +Cc: kernel-team@fb.com +Signed-off-by: Saeed Mahameed +Acked-by: Alexei Starovoitov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index cf0098596e85..e9408f5e2a1d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -197,6 +197,10 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe, + if (lro_num_seg > 1) { + mlx5e_lro_update_hdr(skb, cqe); + skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_seg); ++ /* Subtract one since we already counted this as one ++ * "regular" packet in mlx5e_complete_rx_cqe() ++ */ ++ rq->stats.packets += lro_num_seg - 1; + rq->stats.lro_packets++; + rq->stats.lro_bytes += cqe_bcnt; + } +-- +2.12.2 + +From 85f00dac91a1047b57e600df9636c8408f70001f Mon Sep 17 00:00:00 2001 +From: Doug Berger +Date: Tue, 21 Mar 2017 14:01:06 -0700 +Subject: [PATCH 141/251] net: bcmgenet: remove bcmgenet_internal_phy_setup() +Content-Length: 3576 +Lines: 81 + +[ Upstream commit 31739eae738ccbe8b9d627c3f2251017ca03f4d2 ] + +Commit 6ac3ce8295e6 ("net: bcmgenet: Remove excessive PHY reset") +removed the bcmgenet_mii_reset() function from bcmgenet_power_up() and +bcmgenet_internal_phy_setup() functions. In so doing it broke the reset +of the internal PHY devices used by the GENETv1-GENETv3 which required +this reset before the UniMAC was enabled. It also broke the internal +GPHY devices used by the GENETv4 because the config_init that installed +the AFE workaround was no longer occurring after the reset of the GPHY +performed by bcmgenet_phy_power_set() in bcmgenet_internal_phy_setup(). +In addition the code in bcmgenet_internal_phy_setup() related to the +"enable APD" comment goes with the bcmgenet_mii_reset() so it should +have also been removed. + +Commit bd4060a6108b ("net: bcmgenet: Power on integrated GPHY in +bcmgenet_power_up()") moved the bcmgenet_phy_power_set() call to the +bcmgenet_power_up() function, but failed to remove it from the +bcmgenet_internal_phy_setup() function. Had it done so, the +bcmgenet_internal_phy_setup() function would have been empty and could +have been removed at that time. + +Commit 5dbebbb44a6a ("net: bcmgenet: Software reset EPHY after power on") +was submitted to correct the functional problems introduced by +commit 6ac3ce8295e6 ("net: bcmgenet: Remove excessive PHY reset"). It +was included in v4.4 and made available on 4.3-stable. Unfortunately, +it didn't fully revert the commit because this bcmgenet_mii_reset() +doesn't apply the soft reset to the internal GPHY used by GENETv4 like +the previous one did. This prevents the restoration of the AFE work- +arounds for internal GPHY devices after the bcmgenet_phy_power_set() in +bcmgenet_internal_phy_setup(). + +This commit takes the alternate approach of removing the unnecessary +bcmgenet_internal_phy_setup() function which shouldn't have been in v4.3 +so that when bcmgenet_mii_reset() was restored it should have only gone +into bcmgenet_power_up(). This will avoid the problems while also +removing the redundancy (and hopefully some of the confusion). + +Fixes: 6ac3ce8295e6 ("net: bcmgenet: Remove excessive PHY reset") +Signed-off-by: Doug Berger +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/genet/bcmmii.c | 15 --------------- + 1 file changed, 15 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c +index 8bdfe53754ba..e96d1f95bb47 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c +@@ -220,20 +220,6 @@ void bcmgenet_phy_power_set(struct net_device *dev, bool enable) + udelay(60); + } + +-static void bcmgenet_internal_phy_setup(struct net_device *dev) +-{ +- struct bcmgenet_priv *priv = netdev_priv(dev); +- u32 reg; +- +- /* Power up PHY */ +- bcmgenet_phy_power_set(dev, true); +- /* enable APD */ +- reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); +- reg |= EXT_PWR_DN_EN_LD; +- bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); +- bcmgenet_mii_reset(dev); +-} +- + static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv) + { + u32 reg; +@@ -281,7 +267,6 @@ int bcmgenet_mii_config(struct net_device *dev) + + if (priv->internal_phy) { + phy_name = "internal PHY"; +- bcmgenet_internal_phy_setup(dev); + } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { + phy_name = "MoCA"; + bcmgenet_moca_phy_setup(priv); +-- +2.12.2 + +From 38dece41e5be77478b333db580b5e171b136befa Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 21 Mar 2017 19:22:28 -0700 +Subject: [PATCH 142/251] ipv4: provide stronger user input validation in + nl_fib_input() +Content-Length: 1155 +Lines: 35 + +[ Upstream commit c64c0b3cac4c5b8cb093727d2c19743ea3965c0b ] + +Alexander reported a KMSAN splat caused by reads of uninitialized +field (tb_id_in) from user provided struct fib_result_nl + +It turns out nl_fib_input() sanity tests on user input is a bit +wrong : + +User can pretend nlh->nlmsg_len is big enough, but provide +at sendmsg() time a too small buffer. + +Reported-by: Alexander Potapenko +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/fib_frontend.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c +index 4e60dae86df5..1adba44f8fbc 100644 +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -1080,7 +1080,8 @@ static void nl_fib_input(struct sk_buff *skb) + + net = sock_net(skb->sk); + nlh = nlmsg_hdr(skb); +- if (skb->len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len || ++ if (skb->len < nlmsg_total_size(sizeof(*frn)) || ++ skb->len < nlh->nlmsg_len || + nlmsg_len(nlh) < sizeof(*frn)) + return; + +-- +2.12.2 + +From 95aa915c2f04c27bb3935c8b9446435f40f17f9d Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 22 Mar 2017 13:08:08 +0100 +Subject: [PATCH 143/251] socket, bpf: fix sk_filter use after free in + sk_clone_lock +Content-Length: 2672 +Lines: 61 + +[ Upstream commit a97e50cc4cb67e1e7bff56f6b41cda62ca832336 ] + +In sk_clone_lock(), we create a new socket and inherit most of the +parent's members via sock_copy() which memcpy()'s various sections. +Now, in case the parent socket had a BPF socket filter attached, +then newsk->sk_filter points to the same instance as the original +sk->sk_filter. + +sk_filter_charge() is then called on the newsk->sk_filter to take a +reference and should that fail due to hitting max optmem, we bail +out and release the newsk instance. + +The issue is that commit 278571baca2a ("net: filter: simplify socket +charging") wrongly combined the dismantle path with the failure path +of xfrm_sk_clone_policy(). This means, even when charging failed, we +call sk_free_unlock_clone() on the newsk, which then still points to +the same sk_filter as the original sk. + +Thus, sk_free_unlock_clone() calls into __sk_destruct() eventually +where it tests for present sk_filter and calls sk_filter_uncharge() +on it, which potentially lets sk_omem_alloc wrap around and releases +the eBPF prog and sk_filter structure from the (still intact) parent. + +Fix it by making sure that when sk_filter_charge() failed, we reset +newsk->sk_filter back to NULL before passing to sk_free_unlock_clone(), +so that we don't mess with the parents sk_filter. + +Only if xfrm_sk_clone_policy() fails, we did reach the point where +either the parent's filter was NULL and as a result newsk's as well +or where we previously had a successful sk_filter_charge(), thus for +that case, we do need sk_filter_uncharge() to release the prior taken +reference on sk_filter. + +Fixes: 278571baca2a ("net: filter: simplify socket charging") +Signed-off-by: Daniel Borkmann +Acked-by: Alexei Starovoitov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/sock.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/core/sock.c b/net/core/sock.c +index 9f4c4473156a..9c708a5fb751 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1557,6 +1557,12 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) + is_charged = sk_filter_charge(newsk, filter); + + if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) { ++ /* We need to make sure that we don't uncharge the new ++ * socket if we couldn't charge it in the first place ++ * as otherwise we uncharge the parent's filter. ++ */ ++ if (!is_charged) ++ RCU_INIT_POINTER(newsk->sk_filter, NULL); + /* It is still raw copy of parent, so invalidate + * destructor and make plain sk_free() */ + newsk->sk_destruct = NULL; +-- +2.12.2 + +From afaed241928f029e788bbbeed26b2b530ba7cd1a Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 22 Mar 2017 08:10:21 -0700 +Subject: [PATCH 144/251] tcp: initialize icsk_ack.lrcvtime at session start + time +Content-Length: 1952 +Lines: 53 + +[ Upstream commit 15bb7745e94a665caf42bfaabf0ce062845b533b ] + +icsk_ack.lrcvtime has a 0 value at socket creation time. + +tcpi_last_data_recv can have bogus value if no payload is ever received. + +This patch initializes icsk_ack.lrcvtime for active sessions +in tcp_finish_connect(), and for passive sessions in +tcp_create_openreq_child() + +Signed-off-by: Eric Dumazet +Acked-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 2 +- + net/ipv4/tcp_minisocks.c | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 7cc0f8aac28f..818630cec54f 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5435,6 +5435,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) + struct inet_connection_sock *icsk = inet_csk(sk); + + tcp_set_state(sk, TCP_ESTABLISHED); ++ icsk->icsk_ack.lrcvtime = tcp_time_stamp; + + if (skb) { + icsk->icsk_af_ops->sk_rx_dst_set(sk, skb); +@@ -5647,7 +5648,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, + * to stand against the temptation 8) --ANK + */ + inet_csk_schedule_ack(sk); +- icsk->icsk_ack.lrcvtime = tcp_time_stamp; + tcp_enter_quickack_mode(sk); + inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, + TCP_DELACK_MAX, TCP_RTO_MAX); +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index 9475a2748a9a..019db68bdb9f 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -472,6 +472,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, + newtp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT); + newtp->rtt_min[0].rtt = ~0U; + newicsk->icsk_rto = TCP_TIMEOUT_INIT; ++ newicsk->icsk_ack.lrcvtime = tcp_time_stamp; + + newtp->packets_out = 0; + newtp->retrans_out = 0; +-- +2.12.2 + +From 9ac7bd114e13628467c037066786775a357d91d6 Mon Sep 17 00:00:00 2001 +From: Matjaz Hegedic +Date: Fri, 10 Mar 2017 14:33:09 -0800 +Subject: [PATCH 145/251] Input: elan_i2c - add ASUS EeeBook X205TA special + touchpad fw +Content-Length: 1524 +Lines: 50 + +commit 92ef6f97a66e580189a41a132d0f8a9f78d6ddce upstream. + +EeeBook X205TA is yet another ASUS device with a special touchpad +firmware that needs to be accounted for during initialization, or +else the touchpad will go into an invalid state upon suspend/resume. +Adding the appropriate ic_type and product_id check fixes the problem. + +Signed-off-by: Matjaz Hegedic +Acked-by: KT Liao +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/mouse/elan_i2c_core.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index ed1935f300a7..da5458dfb1e3 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -218,17 +218,19 @@ static int elan_query_product(struct elan_tp_data *data) + + static int elan_check_ASUS_special_fw(struct elan_tp_data *data) + { +- if (data->ic_type != 0x0E) +- return false; +- +- switch (data->product_id) { +- case 0x05 ... 0x07: +- case 0x09: +- case 0x13: ++ if (data->ic_type == 0x0E) { ++ switch (data->product_id) { ++ case 0x05 ... 0x07: ++ case 0x09: ++ case 0x13: ++ return true; ++ } ++ } else if (data->ic_type == 0x08 && data->product_id == 0x26) { ++ /* ASUS EeeBook X205TA */ + return true; +- default: +- return false; + } ++ ++ return false; + } + + static int __elan_initialize(struct elan_tp_data *data) +-- +2.12.2 + +From 5f9243e4fca610599c30b552baacdcffc76ea7af Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Tue, 7 Mar 2017 09:31:29 -0800 +Subject: [PATCH 146/251] Input: i8042 - add noloop quirk for Dell Embedded Box + PC 3000 +Content-Length: 1172 +Lines: 36 + +commit 45838660e34d90db8d4f7cbc8fd66e8aff79f4fe upstream. + +The aux port does not get detected without noloop quirk, so external PS/2 +mouse cannot work as result. + +The PS/2 mouse can work with this quirk. + +BugLink: https://bugs.launchpad.net/bugs/1591053 +Signed-off-by: Kai-Heng Feng +Reviewed-by: Marcos Paulo de Souza +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index 0cdd95801a25..25eab453f2b2 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -120,6 +120,13 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { + }, + }, + { ++ /* Dell Embedded Box PC 3000 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"), ++ }, ++ }, ++ { + /* OQO Model 01 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "OQO"), +-- +2.12.2 + +From a07d3669654ad335c19df048199da0a063e0c387 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 16 Mar 2017 11:34:02 -0700 +Subject: [PATCH 147/251] Input: iforce - validate number of endpoints before + using them +Content-Length: 1031 +Lines: 29 + +commit 59cf8bed44a79ec42303151dd014fdb6434254bb upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer or accessing memory that lie beyond the end of the endpoint +array should a malicious device lack the expected endpoints. + +Signed-off-by: Johan Hovold +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/joystick/iforce/iforce-usb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c +index d96aa27dfcdc..db64adfbe1af 100644 +--- a/drivers/input/joystick/iforce/iforce-usb.c ++++ b/drivers/input/joystick/iforce/iforce-usb.c +@@ -141,6 +141,9 @@ static int iforce_usb_probe(struct usb_interface *intf, + + interface = intf->cur_altsetting; + ++ if (interface->desc.bNumEndpoints < 2) ++ return -ENODEV; ++ + epirq = &interface->endpoint[0].desc; + epout = &interface->endpoint[1].desc; + +-- +2.12.2 + +From 6bed7c1e2b78e58adab2e8448f3e6799857b5726 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 16 Mar 2017 11:36:13 -0700 +Subject: [PATCH 148/251] Input: ims-pcu - validate number of endpoints before + using them +Content-Length: 1032 +Lines: 30 + +commit 1916d319271664241b7aa0cd2b05e32bdb310ce9 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack control-interface endpoints. + +Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver") +Signed-off-by: Johan Hovold +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ims-pcu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c +index 9c0ea36913b4..f4e8fbec6a94 100644 +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -1667,6 +1667,10 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc + return -EINVAL; + + alt = pcu->ctrl_intf->cur_altsetting; ++ ++ if (alt->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + pcu->ep_ctrl = &alt->endpoint[0].desc; + pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl); + +-- +2.12.2 + +From 0812c6855c89d905e34e88166570cae4a401b23a Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 16 Mar 2017 11:39:29 -0700 +Subject: [PATCH 149/251] Input: hanwang - validate number of endpoints before + using them +Content-Length: 1020 +Lines: 29 + +commit ba340d7b83703768ce566f53f857543359aa1b98 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Fixes: bba5394ad3bd ("Input: add support for Hanwang tablets") +Signed-off-by: Johan Hovold +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/tablet/hanwang.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c +index cd852059b99e..df4bea96d7ed 100644 +--- a/drivers/input/tablet/hanwang.c ++++ b/drivers/input/tablet/hanwang.c +@@ -340,6 +340,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id + int error; + int i; + ++ if (intf->cur_altsetting->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!hanwang || !input_dev) { +-- +2.12.2 + +From e916f1d6188ef765303b4f74387d7e92d49a5be6 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 16 Mar 2017 11:37:01 -0700 +Subject: [PATCH 150/251] Input: yealink - validate number of endpoints before + using them +Content-Length: 1017 +Lines: 30 + +commit 5cc4a1a9f5c179795c8a1f2b0f4361829d6a070e upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Fixes: aca951a22a1d ("[PATCH] input-driver-yealink-P1K-usb-phone") +Signed-off-by: Johan Hovold +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/yealink.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c +index 79c964c075f1..6e7ff9561d92 100644 +--- a/drivers/input/misc/yealink.c ++++ b/drivers/input/misc/yealink.c +@@ -875,6 +875,10 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) + int ret, pipe, i; + + interface = intf->cur_altsetting; ++ ++ if (interface->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + endpoint = &interface->endpoint[0].desc; + if (!usb_endpoint_is_int_in(endpoint)) + return -ENODEV; +-- +2.12.2 + +From c05490638ddfffa35d2fb03c1852f9013757a9e1 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 16 Mar 2017 11:35:12 -0700 +Subject: [PATCH 151/251] Input: cm109 - validate number of endpoints before + using them +Content-Length: 976 +Lines: 30 + +commit ac2ee9ba953afe88f7a673e1c0c839227b1d7891 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Fixes: c04148f915e5 ("Input: add driver for USB VoIP phones with CM109...") +Signed-off-by: Johan Hovold +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/cm109.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c +index 9365535ba7f1..50a7faa504f7 100644 +--- a/drivers/input/misc/cm109.c ++++ b/drivers/input/misc/cm109.c +@@ -675,6 +675,10 @@ static int cm109_usb_probe(struct usb_interface *intf, + int error = -ENOMEM; + + interface = intf->cur_altsetting; ++ ++ if (interface->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + endpoint = &interface->endpoint[0].desc; + + if (!usb_endpoint_is_int_in(endpoint)) +-- +2.12.2 + +From b3c4c0c470b58dd4a5e40e11ccd9fea7fbbfa799 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 16 Mar 2017 11:41:55 -0700 +Subject: [PATCH 152/251] Input: kbtab - validate number of endpoints before + using them +Content-Length: 972 +Lines: 28 + +commit cb1b494663e037253337623bf1ef2df727883cb7 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Signed-off-by: Johan Hovold +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/tablet/kbtab.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c +index d2ac7c2b5b82..2812f9236b7d 100644 +--- a/drivers/input/tablet/kbtab.c ++++ b/drivers/input/tablet/kbtab.c +@@ -122,6 +122,9 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i + struct input_dev *input_dev; + int error = -ENOMEM; + ++ if (intf->cur_altsetting->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!kbtab || !input_dev) +-- +2.12.2 + +From 549993001e7de0553d85c9022dc41d5b3ff7d1ff Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 16 Mar 2017 11:43:09 -0700 +Subject: [PATCH 153/251] Input: sur40 - validate number of endpoints before + using them +Content-Length: 1132 +Lines: 30 + +commit 92461f5d723037530c1f36cce93640770037812c upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer or accessing memory that lie beyond the end of the endpoint +array should a malicious device lack the expected endpoints. + +Fixes: bdb5c57f209c ("Input: add sur40 driver for Samsung SUR40... ") +Signed-off-by: Johan Hovold +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/touchscreen/sur40.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c +index 45b466e3bbe8..0146e2c74649 100644 +--- a/drivers/input/touchscreen/sur40.c ++++ b/drivers/input/touchscreen/sur40.c +@@ -500,6 +500,9 @@ static int sur40_probe(struct usb_interface *interface, + if (iface_desc->desc.bInterfaceClass != 0xFF) + return -ENODEV; + ++ if (iface_desc->desc.bNumEndpoints < 5) ++ return -ENODEV; ++ + /* Use endpoint #4 (0x86). */ + endpoint = &iface_desc->endpoint[4].desc; + if (endpoint->bEndpointAddress != TOUCH_ENDPOINT) +-- +2.12.2 + +From b55ffcb1bc8a9c40db928f568ef61016ac681c29 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 21 Mar 2017 13:56:04 +0100 +Subject: [PATCH 154/251] ALSA: seq: Fix racy cell insertions during + snd_seq_pool_done() +Content-Length: 3599 +Lines: 105 + +commit c520ff3d03f0b5db7146d9beed6373ad5d2a5e0e upstream. + +When snd_seq_pool_done() is called, it marks the closing flag to +refuse the further cell insertions. But snd_seq_pool_done() itself +doesn't clear the cells but just waits until all cells are cleared by +the caller side. That is, it's racy, and this leads to the endless +stall as syzkaller spotted. + +This patch addresses the racy by splitting the setup of pool->closing +flag out of snd_seq_pool_done(), and calling it properly before +snd_seq_pool_done(). + +BugLink: http://lkml.kernel.org/r/CACT4Y+aqqy8bZA1fFieifNxR2fAfFQQABcBHj801+u5ePV0URw@mail.gmail.com +Reported-and-tested-by: Dmitry Vyukov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/core/seq/seq_clientmgr.c | 1 + + sound/core/seq/seq_fifo.c | 3 +++ + sound/core/seq/seq_memory.c | 17 +++++++++++++---- + sound/core/seq/seq_memory.h | 1 + + 4 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index 58e79e02f217..c67f9c212dd1 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1921,6 +1921,7 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client, + info.output_pool != client->pool->size)) { + if (snd_seq_write_pool_allocated(client)) { + /* remove all existing cells */ ++ snd_seq_pool_mark_closing(client->pool); + snd_seq_queue_client_leave_cells(client->number); + snd_seq_pool_done(client->pool); + } +diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c +index 86240d02b530..3f4efcb85df5 100644 +--- a/sound/core/seq/seq_fifo.c ++++ b/sound/core/seq/seq_fifo.c +@@ -70,6 +70,9 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo) + return; + *fifo = NULL; + ++ if (f->pool) ++ snd_seq_pool_mark_closing(f->pool); ++ + snd_seq_fifo_clear(f); + + /* wake up clients if any */ +diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c +index dfa5156f3585..5847c4475bf3 100644 +--- a/sound/core/seq/seq_memory.c ++++ b/sound/core/seq/seq_memory.c +@@ -414,6 +414,18 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) + return 0; + } + ++/* refuse the further insertion to the pool */ ++void snd_seq_pool_mark_closing(struct snd_seq_pool *pool) ++{ ++ unsigned long flags; ++ ++ if (snd_BUG_ON(!pool)) ++ return; ++ spin_lock_irqsave(&pool->lock, flags); ++ pool->closing = 1; ++ spin_unlock_irqrestore(&pool->lock, flags); ++} ++ + /* remove events */ + int snd_seq_pool_done(struct snd_seq_pool *pool) + { +@@ -424,10 +436,6 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) + return -EINVAL; + + /* wait for closing all threads */ +- spin_lock_irqsave(&pool->lock, flags); +- pool->closing = 1; +- spin_unlock_irqrestore(&pool->lock, flags); +- + if (waitqueue_active(&pool->output_sleep)) + wake_up(&pool->output_sleep); + +@@ -484,6 +492,7 @@ int snd_seq_pool_delete(struct snd_seq_pool **ppool) + *ppool = NULL; + if (pool == NULL) + return 0; ++ snd_seq_pool_mark_closing(pool); + snd_seq_pool_done(pool); + kfree(pool); + return 0; +diff --git a/sound/core/seq/seq_memory.h b/sound/core/seq/seq_memory.h +index 4a2ec779b8a7..32f959c17786 100644 +--- a/sound/core/seq/seq_memory.h ++++ b/sound/core/seq/seq_memory.h +@@ -84,6 +84,7 @@ static inline int snd_seq_total_cells(struct snd_seq_pool *pool) + int snd_seq_pool_init(struct snd_seq_pool *pool); + + /* done pool - free events */ ++void snd_seq_pool_mark_closing(struct snd_seq_pool *pool); + int snd_seq_pool_done(struct snd_seq_pool *pool); + + /* create pool */ +-- +2.12.2 + +From ed00b613bbcb7af32fbdd87e3c985c00e2c9c5a3 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 20 Mar 2017 10:08:19 +0100 +Subject: [PATCH 155/251] ALSA: ctxfi: Fix the incorrect check of + dma_set_mask() call +Content-Length: 1225 +Lines: 32 + +commit f363a06642f28caaa78cb6446bbad90c73fe183c upstream. + +In the commit [15c75b09f8d1: ALSA: ctxfi: Fallback DMA mask to 32bit], +I forgot to put "!" at dam_set_mask() call check in cthw20k1.c (while +cthw20k2.c is OK). This patch fixes that obvious bug. + +(As a side note: although the original commit was completely wrong, + it's still working for most of machines, as it sets to 32bit DMA mask + in the end. So the bug severity is low.) + +Fixes: 15c75b09f8d1 ("ALSA: ctxfi: Fallback DMA mask to 32bit") +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/ctxfi/cthw20k1.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c +index ab4cdab5cfa5..79edd88d5cd0 100644 +--- a/sound/pci/ctxfi/cthw20k1.c ++++ b/sound/pci/ctxfi/cthw20k1.c +@@ -1905,7 +1905,7 @@ static int hw_card_start(struct hw *hw) + return err; + + /* Set DMA transfer mask */ +- if (dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { ++ if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { + dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); + } else { + dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); +-- +2.12.2 + +From 1ea551eec703102af8db2c2dcc99fc660baa3602 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Thu, 23 Mar 2017 10:00:25 +0800 +Subject: [PATCH 156/251] ALSA: hda - Adding a group of pin definition to fix + headset problem +Content-Length: 1089 +Lines: 28 + +commit 3f307834e695f59dac4337a40316bdecfb9d0508 upstream. + +A new Dell laptop needs to apply ALC269_FIXUP_DELL1_MIC_NO_PRESENCE to +fix the headset problem, and the pin definiton of this machine is not +in the pin quirk table yet, now adding it to the table. + +Signed-off-by: Hui Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/hda/patch_realtek.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index cf0785ddbd14..1d4f34379f56 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6040,6 +6040,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { + ALC295_STANDARD_PINS, + {0x17, 0x21014040}, + {0x18, 0x21a19050}), ++ SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, ++ ALC295_STANDARD_PINS), + SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC298_STANDARD_PINS, + {0x17, 0x90170110}), +-- +2.12.2 + +From 8f0f081647cc1c7e7ce6bea99a3b2ebb3604b1f1 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Thu, 9 Mar 2017 11:32:28 -0600 +Subject: [PATCH 157/251] USB: serial: option: add Quectel UC15, UC20, EC21, + and EC25 modems +Content-Length: 2146 +Lines: 50 + +commit 6e9f44eaaef0df7b846e9316fa9ca72a02025d44 upstream. + +Add Quectel UC15, UC20, EC21, and EC25. The EC20 is handled by +qcserial due to a USB VID/PID conflict with an existing Acer +device. + +Signed-off-by: Dan Williams +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 42cc72e54c05..af67a0de6b5d 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -233,6 +233,14 @@ static void option_instat_callback(struct urb *urb); + #define BANDRICH_PRODUCT_1012 0x1012 + + #define QUALCOMM_VENDOR_ID 0x05C6 ++/* These Quectel products use Qualcomm's vendor ID */ ++#define QUECTEL_PRODUCT_UC20 0x9003 ++#define QUECTEL_PRODUCT_UC15 0x9090 ++ ++#define QUECTEL_VENDOR_ID 0x2c7c ++/* These Quectel products use Quectel's vendor ID */ ++#define QUECTEL_PRODUCT_EC21 0x0121 ++#define QUECTEL_PRODUCT_EC25 0x0125 + + #define CMOTECH_VENDOR_ID 0x16d8 + #define CMOTECH_PRODUCT_6001 0x6001 +@@ -1161,7 +1169,14 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ +- { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */ ++ /* Quectel products using Qualcomm vendor ID */ ++ { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, ++ { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ /* Quectel products using Quectel vendor ID */ ++ { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, +-- +2.12.2 + +From 9218793a39def5ee7555d990ef6034260024a379 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Fri, 17 Mar 2017 17:21:28 +0100 +Subject: [PATCH 158/251] USB: serial: qcserial: add Dell DW5811e +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1135 +Lines: 26 + +commit 436ecf5519d892397af133a79ccd38a17c25fa51 upstream. + +This is a Dell branded Sierra Wireless EM7455. + +Signed-off-by: Bjørn Mork +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/qcserial.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c +index 696458db7e3c..38b3f0d8cd58 100644 +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -169,6 +169,8 @@ static const struct usb_device_id id_table[] = { + {DEVICE_SWI(0x413c, 0x81a9)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ + {DEVICE_SWI(0x413c, 0x81b1)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */ + {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ ++ {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ ++ {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ + + /* Huawei devices */ + {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ +-- +2.12.2 + +From 19f0fe67b9d04580c377efc568cc8630a5af06b4 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Tue, 14 Mar 2017 12:09:56 +0100 +Subject: [PATCH 159/251] ACM gadget: fix endianness in notifications +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1317 +Lines: 36 + +commit cdd7928df0d2efaa3270d711963773a08a4cc8ab upstream. + +The gadget code exports the bitfield for serial status changes +over the wire in its internal endianness. The fix is to convert +to little endian before sending it over the wire. + +Signed-off-by: Oliver Neukum +Tested-by: 家瑋 +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_acm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c +index 2fa1e80a3ce7..67e474b13fca 100644 +--- a/drivers/usb/gadget/function/f_acm.c ++++ b/drivers/usb/gadget/function/f_acm.c +@@ -535,13 +535,15 @@ static int acm_notify_serial_state(struct f_acm *acm) + { + struct usb_composite_dev *cdev = acm->port.func.config->cdev; + int status; ++ __le16 serial_state; + + spin_lock(&acm->lock); + if (acm->notify_req) { + dev_dbg(&cdev->gadget->dev, "acm ttyGS%d serial state %04x\n", + acm->port_num, acm->serial_state); ++ serial_state = cpu_to_le16(acm->serial_state); + status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE, +- 0, &acm->serial_state, sizeof(acm->serial_state)); ++ 0, &serial_state, sizeof(acm->serial_state)); + } else { + acm->pending = true; + status = 0; +-- +2.12.2 + +From 8a8a8007871acae231ca5dba49f648d64326e919 Mon Sep 17 00:00:00 2001 +From: Roger Quadros +Date: Wed, 8 Mar 2017 16:05:43 +0200 +Subject: [PATCH 160/251] usb: gadget: f_uvc: Fix SuperSpeed companion + descriptor's wBytesPerInterval +Content-Length: 1446 +Lines: 35 + +commit 09424c50b7dff40cb30011c09114404a4656e023 upstream. + +The streaming_maxburst module parameter is 0 offset (0..15) +so we must add 1 while using it for wBytesPerInterval +calculation for the SuperSpeed companion descriptor. + +Without this host uvcvideo driver will always see the wrong +wBytesPerInterval for SuperSpeed uvc gadget and may not find +a suitable video interface endpoint. +e.g. for streaming_maxburst = 0 case it will always +fail as wBytePerInterval was evaluating to 0. + +Reviewed-by: Laurent Pinchart +Signed-off-by: Roger Quadros +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_uvc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c +index 29b41b5dee04..c7689d05356c 100644 +--- a/drivers/usb/gadget/function/f_uvc.c ++++ b/drivers/usb/gadget/function/f_uvc.c +@@ -625,7 +625,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) + uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; + uvc_ss_streaming_comp.wBytesPerInterval = + cpu_to_le16(max_packet_size * max_packet_mult * +- opts->streaming_maxburst); ++ (opts->streaming_maxburst + 1)); + + /* Allocate endpoints. */ + ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); +-- +2.12.2 + +From 2c929ea720f968da2f1ad90db995cc49a937955f Mon Sep 17 00:00:00 2001 +From: Samuel Thibault +Date: Mon, 13 Mar 2017 20:50:08 +0100 +Subject: [PATCH 161/251] usb-core: Add LINEAR_FRAME_INTR_BINTERVAL USB quirk +Content-Length: 3060 +Lines: 83 + +commit 3243367b209faed5c320a4e5f9a565ee2a2ba958 upstream. + +Some USB 2.0 devices erroneously report millisecond values in +bInterval. The generic config code manages to catch most of them, +but in some cases it's not completely enough. + +The case at stake here is a USB 2.0 braille device, which wants to +announce 10ms and thus sets bInterval to 10, but with the USB 2.0 +computation that yields to 64ms. It happens that one can type fast +enough to reach this interval and get the device buffers overflown, +leading to problematic latencies. The generic config code does not +catch this case because the 64ms is considered a sane enough value. + +This change thus adds a USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL quirk +to mark devices which actually report milliseconds in bInterval, +and marks Vario Ultra devices as needing it. + +Signed-off-by: Samuel Thibault +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/config.c | 10 ++++++++++ + drivers/usb/core/quirks.c | 8 ++++++++ + include/linux/usb/quirks.h | 6 ++++++ + 3 files changed, 24 insertions(+) + +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index ac30a051ad71..325cbc9c35d8 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -246,6 +246,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, + + /* + * Adjust bInterval for quirked devices. ++ */ ++ /* ++ * This quirk fixes bIntervals reported in ms. ++ */ ++ if (to_usb_device(ddev)->quirks & ++ USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) { ++ n = clamp(fls(d->bInterval) + 3, i, j); ++ i = j = n; ++ } ++ /* + * This quirk fixes bIntervals reported in + * linear microframes. + */ +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 24f9f98968a5..96b21b0dac1e 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -170,6 +170,14 @@ static const struct usb_device_id usb_quirk_list[] = { + /* M-Systems Flash Disk Pioneers */ + { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* Baum Vario Ultra */ ++ { USB_DEVICE(0x0904, 0x6101), .driver_info = ++ USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL }, ++ { USB_DEVICE(0x0904, 0x6102), .driver_info = ++ USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL }, ++ { USB_DEVICE(0x0904, 0x6103), .driver_info = ++ USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL }, ++ + /* Keytouch QWERTY Panel keyboard */ + { USB_DEVICE(0x0926, 0x3333), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, +diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h +index 1d0043dc34e4..de2a722fe3cf 100644 +--- a/include/linux/usb/quirks.h ++++ b/include/linux/usb/quirks.h +@@ -50,4 +50,10 @@ + /* device can't handle Link Power Management */ + #define USB_QUIRK_NO_LPM BIT(10) + ++/* ++ * Device reports its bInterval as linear frames instead of the ++ * USB 2.0 calculation. ++ */ ++#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL BIT(11) ++ + #endif /* __LINUX_USB_QUIRKS_H */ +-- +2.12.2 + +From 73490abe249c238e2141f62995e2cc2d4ae392db Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:47:50 +0100 +Subject: [PATCH 162/251] USB: uss720: fix NULL-deref at probe +Content-Length: 1198 +Lines: 37 + +commit f259ca3eed6e4b79ac3d5c5c9fb259fb46e86217 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer or accessing memory beyond the endpoint array should a +malicious device lack the expected endpoints. + +Note that the endpoint access that causes the NULL-deref is currently +only used for debugging purposes during probe so the oops only happens +when dynamic debugging is enabled. This means the driver could be +rewritten to continue to accept device with only two endpoints, should +such devices exist. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/uss720.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c +index bbd029c9c725..442b6631162e 100644 +--- a/drivers/usb/misc/uss720.c ++++ b/drivers/usb/misc/uss720.c +@@ -711,6 +711,11 @@ static int uss720_probe(struct usb_interface *intf, + + interface = intf->cur_altsetting; + ++ if (interface->desc.bNumEndpoints < 3) { ++ usb_put_dev(usbdev); ++ return -ENODEV; ++ } ++ + /* + * Allocate parport interface + */ +-- +2.12.2 + +From a7712869e2e7cb1a5add2a8613f04e6c3647ef38 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:47:49 +0100 +Subject: [PATCH 163/251] USB: lvtest: fix NULL-deref at probe +Content-Length: 995 +Lines: 32 + +commit 1dc56c52d2484be09c7398a5207d6b11a4256be9 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should the probed device lack endpoints. + +Note that this driver does not bind to any devices by default. + +Fixes: ce21bfe603b3 ("USB: Add LVS Test device driver") +Cc: Pratyush Anand +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/lvstest.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c +index 86b4e4b2ab9a..383fa007348f 100644 +--- a/drivers/usb/misc/lvstest.c ++++ b/drivers/usb/misc/lvstest.c +@@ -370,6 +370,10 @@ static int lvs_rh_probe(struct usb_interface *intf, + + hdev = interface_to_usbdev(intf); + desc = intf->cur_altsetting; ++ ++ if (desc->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + endpoint = &desc->endpoint[0].desc; + + /* valid only for SS root hub */ +-- +2.12.2 + +From d6389d6abb8aff1d67ea64ef5b295ab3f4967d2d Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:47:48 +0100 +Subject: [PATCH 164/251] USB: idmouse: fix NULL-deref at probe +Content-Length: 929 +Lines: 28 + +commit b0addd3fa6bcd119be9428996d5d4522479ab240 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/misc/idmouse.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c +index 4e38683c653c..6d4e75785710 100644 +--- a/drivers/usb/misc/idmouse.c ++++ b/drivers/usb/misc/idmouse.c +@@ -346,6 +346,9 @@ static int idmouse_probe(struct usb_interface *interface, + if (iface_desc->desc.bInterfaceClass != 0x0A) + return -ENODEV; + ++ if (iface_desc->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + /* allocate memory for our device state and initialize it */ + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) +-- +2.12.2 + +From a7cb1fafe429ebd9ecf7768edc577662cbb6011e Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:47:51 +0100 +Subject: [PATCH 165/251] USB: wusbcore: fix NULL-deref at probe +Content-Length: 1148 +Lines: 34 + +commit 03ace948a4eb89d1cf51c06afdfc41ebca5fdb27 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer or accessing memory beyond the endpoint array should a +malicious device lack the expected endpoints. + +This specifically fixes the NULL-pointer dereference when probing HWA HC +devices. + +Fixes: df3654236e31 ("wusb: add the Wire Adapter (WA) core") +Cc: Inaky Perez-Gonzalez +Cc: David Vrabel +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/wusbcore/wa-hc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/usb/wusbcore/wa-hc.c +index 252c7bd9218a..d01496fd27fe 100644 +--- a/drivers/usb/wusbcore/wa-hc.c ++++ b/drivers/usb/wusbcore/wa-hc.c +@@ -39,6 +39,9 @@ int wa_create(struct wahc *wa, struct usb_interface *iface, + int result; + struct device *dev = &iface->dev; + ++ if (iface->cur_altsetting->desc.bNumEndpoints < 3) ++ return -ENODEV; ++ + result = wa_rpipes_create(wa); + if (result < 0) + goto error_rpipes_create; +-- +2.12.2 + +From 47285be050ca3e9ca45f22966b0b655b5b83c250 Mon Sep 17 00:00:00 2001 +From: Bin Liu +Date: Fri, 10 Mar 2017 14:43:35 -0600 +Subject: [PATCH 166/251] usb: musb: cppi41: don't check early-TX-interrupt for + Isoch transfer +Content-Length: 1899 +Lines: 56 + +commit 0090114d336a9604aa2d90bc83f20f7cd121b76c upstream. + +The CPPI 4.1 driver polls register to workaround the premature TX +interrupt issue, but it causes audio playback underrun when triggered in +Isoch transfers. + +Isoch doesn't do back-to-back transfers, the TX should be done by the +time the next transfer is scheduled. So skip this polling workaround for +Isoch transfer. + +Fixes: a655f481d83d6 ("usb: musb: musb_cppi41: handle pre-mature TX complete interrupt") +Reported-by: Alexandre Bailon +Acked-by: Sebastian Andrzej Siewior +Tested-by: Alexandre Bailon +Signed-off-by: Bin Liu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/musb/musb_cppi41.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c +index e499b862a946..88f26ac2a185 100644 +--- a/drivers/usb/musb/musb_cppi41.c ++++ b/drivers/usb/musb/musb_cppi41.c +@@ -250,8 +250,27 @@ static void cppi41_dma_callback(void *private_data) + transferred < cppi41_channel->packet_sz) + cppi41_channel->prog_len = 0; + +- if (cppi41_channel->is_tx) +- empty = musb_is_tx_fifo_empty(hw_ep); ++ if (cppi41_channel->is_tx) { ++ u8 type; ++ ++ if (is_host_active(musb)) ++ type = hw_ep->out_qh->type; ++ else ++ type = hw_ep->ep_in.type; ++ ++ if (type == USB_ENDPOINT_XFER_ISOC) ++ /* ++ * Don't use the early-TX-interrupt workaround below ++ * for Isoch transfter. Since Isoch are periodic ++ * transfer, by the time the next transfer is ++ * scheduled, the current one should be done already. ++ * ++ * This avoids audio playback underrun issue. ++ */ ++ empty = true; ++ else ++ empty = musb_is_tx_fifo_empty(hw_ep); ++ } + + if (!cppi41_channel->is_tx || empty) { + cppi41_trans_done(cppi41_channel); +-- +2.12.2 + +From 14a2032287d43bbffadf22752e40830000aad503 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Wed, 8 Mar 2017 10:19:36 -0800 +Subject: [PATCH 167/251] usb: hub: Fix crash after failure to read BOS + descriptor +Content-Length: 2813 +Lines: 69 + +commit 7b2db29fbb4e766fcd02207eb2e2087170bd6ebc upstream. + +If usb_get_bos_descriptor() returns an error, usb->bos will be NULL. +Nevertheless, it is dereferenced unconditionally in +hub_set_initial_usb2_lpm_policy() if usb2_hw_lpm_capable is set. +This results in a crash. + +usb 5-1: unable to get BOS descriptor +... +Unable to handle kernel NULL pointer dereference at virtual address 00000008 +pgd = ffffffc00165f000 +[00000008] *pgd=000000000174f003, *pud=000000000174f003, + *pmd=0000000001750003, *pte=00e8000001751713 +Internal error: Oops: 96000005 [#1] PREEMPT SMP +Modules linked in: uinput uvcvideo videobuf2_vmalloc cmac [ ... ] +CPU: 5 PID: 3353 Comm: kworker/5:3 Tainted: G B 4.4.52 #480 +Hardware name: Google Kevin (DT) +Workqueue: events driver_set_config_work +task: ffffffc0c3690000 ti: ffffffc0ae9a8000 task.ti: ffffffc0ae9a8000 +PC is at hub_port_init+0xc3c/0xd10 +LR is at hub_port_init+0xc3c/0xd10 +... +Call trace: +[] hub_port_init+0xc3c/0xd10 +[] usb_reset_and_verify_device+0x15c/0x82c +[] usb_reset_device+0xe4/0x298 +[] rtl8152_probe+0x84/0x9b0 [r8152] +[] usb_probe_interface+0x244/0x2f8 +[] driver_probe_device+0x180/0x3b4 +[] __device_attach_driver+0xb4/0xe0 +[] bus_for_each_drv+0xb4/0xe4 +[] __device_attach+0xd0/0x158 +[] device_initial_probe+0x24/0x30 +[] bus_probe_device+0x50/0xe4 +[] device_add+0x414/0x738 +[] usb_set_configuration+0x89c/0x914 +[] driver_set_config_work+0xc0/0xf0 +[] process_one_work+0x390/0x6b8 +[] worker_thread+0x480/0x610 +[] kthread+0x164/0x178 +[] ret_from_fork+0x10/0x40 + +Since we don't know anything about LPM capabilities without BOS descriptor, +don't attempt to enable LPM if it is not available. + +Fixes: 890dae886721 ("xhci: Enable LPM support only for hardwired ...") +Cc: Mathias Nyman +Signed-off-by: Guenter Roeck +Acked-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index f52d8abf6979..9e62c93af96e 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4199,7 +4199,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) + struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); + int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN; + +- if (!udev->usb2_hw_lpm_capable) ++ if (!udev->usb2_hw_lpm_capable || !udev->bos) + return; + + if (hub) +-- +2.12.2 + +From 815321da2e267c5c44a2900b39ac92632a9d6e80 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:47:53 +0100 +Subject: [PATCH 168/251] uwb: i1480-dfu: fix NULL-deref at probe +Content-Length: 1114 +Lines: 33 + +commit 4ce362711d78a4999011add3115b8f4b0bc25e8c upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Note that the dereference happens in the cmd and wait_init_done +callbacks which are called during probe. + +Fixes: 1ba47da52712 ("uwb: add the i1480 DFU driver") +Cc: Inaky Perez-Gonzalez +Cc: David Vrabel +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/uwb/i1480/dfu/usb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c +index 2bfc846ac071..6345e85822a4 100644 +--- a/drivers/uwb/i1480/dfu/usb.c ++++ b/drivers/uwb/i1480/dfu/usb.c +@@ -362,6 +362,9 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id) + result); + } + ++ if (iface->cur_altsetting->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + result = -ENOMEM; + i1480_usb = kzalloc(sizeof(*i1480_usb), GFP_KERNEL); + if (i1480_usb == NULL) { +-- +2.12.2 + +From 2c251e568e1a5dfbdab7156eaa848cd45b3cb127 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:47:52 +0100 +Subject: [PATCH 169/251] uwb: hwa-rc: fix NULL-deref at probe +Content-Length: 1047 +Lines: 33 + +commit daf229b15907fbfdb6ee183aac8ca428cb57e361 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Note that the dereference happens in the start callback which is called +during probe. + +Fixes: de520b8bd552 ("uwb: add HWA radio controller driver") +Cc: Inaky Perez-Gonzalez +Cc: David Vrabel +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/uwb/hwa-rc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c +index 0257f35cfb9d..e75bbe5a10cd 100644 +--- a/drivers/uwb/hwa-rc.c ++++ b/drivers/uwb/hwa-rc.c +@@ -825,6 +825,9 @@ static int hwarc_probe(struct usb_interface *iface, + struct hwarc *hwarc; + struct device *dev = &iface->dev; + ++ if (iface->cur_altsetting->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + result = -ENOMEM; + uwb_rc = uwb_rc_alloc(); + if (uwb_rc == NULL) { +-- +2.12.2 + +From dcf879cb9ed37f4e4cb242aaa17316d6c37404dc Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:40:22 +0100 +Subject: [PATCH 170/251] mmc: ushc: fix NULL-deref at probe +Content-Length: 1009 +Lines: 30 + +commit 181302dc7239add8ab1449c23ecab193f52ee6ab upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Fixes: 53f3a9e26ed5 ("mmc: USB SD Host Controller (USHC) driver") +Cc: David Vrabel +Signed-off-by: Johan Hovold +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/ushc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c +index d2c386f09d69..1d843357422e 100644 +--- a/drivers/mmc/host/ushc.c ++++ b/drivers/mmc/host/ushc.c +@@ -426,6 +426,9 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id + struct ushc_data *ushc; + int ret; + ++ if (intf->cur_altsetting->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev); + if (mmc == NULL) + return -ENOMEM; +-- +2.12.2 + +From 8f189e1d0ecac38ac69b44b89f2561c3bcffacbd Mon Sep 17 00:00:00 2001 +From: Michael Engl +Date: Tue, 3 Oct 2017 13:57:00 +0100 +Subject: [PATCH 171/251] iio: adc: ti_am335x_adc: fix fifo overrun recovery +Content-Length: 2556 +Lines: 65 + +commit e83bb3e6f3efa21f4a9d883a25d0ecd9dfb431e1 upstream. + +The tiadc_irq_h(int irq, void *private) function is handling FIFO +overruns by clearing flags, disabling and enabling the ADC to +recover. + +If the ADC is running in continuous mode a FIFO overrun happens +regularly. If the disabling of the ADC happens concurrently with +a new conversion. It might happen that the enabling of the ADC +is ignored by the hardware. This stops the ADC permanently. No +more interrupts are triggered. + +According to the AM335x Reference Manual (SPRUH73H October 2011 - +Revised April 2013 - Chapter 12.4 and 12.5) it is necessary to +check the ADC FSM bits in REG_ADCFSM before enabling the ADC +again. Because the disabling of the ADC is done right after the +current conversion has been finished. + +To trigger this bug it is necessary to run the ADC in continuous +mode. The ADC values of all channels need to be read in an endless +loop. The bug appears within the first 6 hours (~5.4 million +handled FIFO overruns). The user space application will hang on +reading new values from the character device. + +Fixes: ca9a563805f7a ("iio: ti_am335x_adc: Add continuous sampling support") +Signed-off-by: Michael Engl +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ti_am335x_adc.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c +index 0470fc843d4e..9b6854607d73 100644 +--- a/drivers/iio/adc/ti_am335x_adc.c ++++ b/drivers/iio/adc/ti_am335x_adc.c +@@ -151,7 +151,9 @@ static irqreturn_t tiadc_irq_h(int irq, void *private) + { + struct iio_dev *indio_dev = private; + struct tiadc_device *adc_dev = iio_priv(indio_dev); +- unsigned int status, config; ++ unsigned int status, config, adc_fsm; ++ unsigned short count = 0; ++ + status = tiadc_readl(adc_dev, REG_IRQSTATUS); + + /* +@@ -165,6 +167,15 @@ static irqreturn_t tiadc_irq_h(int irq, void *private) + tiadc_writel(adc_dev, REG_CTRL, config); + tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN + | IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES); ++ ++ /* wait for idle state. ++ * ADC needs to finish the current conversion ++ * before disabling the module ++ */ ++ do { ++ adc_fsm = tiadc_readl(adc_dev, REG_ADCFSM); ++ } while (adc_fsm != 0x10 && count++ < 100); ++ + tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB)); + return IRQ_HANDLED; + } else if (status & IRQENB_FIFO1THRES) { +-- +2.12.2 + +From 7413d1f8991e7d5c240d89a3feb35e2a54d27baf Mon Sep 17 00:00:00 2001 +From: Song Hongyan +Date: Wed, 22 Feb 2017 17:17:38 +0800 +Subject: [PATCH 172/251] iio: hid-sensor-trigger: Change get poll value + function order to avoid sensor properties losing after resume from S3 +Content-Length: 2044 +Lines: 48 + +commit 3bec247474469f769af41e8c80d3a100dd97dd76 upstream. + +In function _hid_sensor_power_state(), when hid_sensor_read_poll_value() +is called, sensor's all properties will be updated by the value from +sensor hardware/firmware. +In some implementation, sensor hardware/firmware will do a power cycle +during S3. In this case, after resume, once hid_sensor_read_poll_value() +is called, sensor's all properties which are kept by driver during S3 +will be changed to default value. +But instead, if a set feature function is called first, sensor +hardware/firmware will be recovered to the last status. So change the +sensor_hub_set_feature() calling order to behind of set feature function +to avoid sensor properties lose. + +Signed-off-by: Song Hongyan +Acked-by: Srinivas Pandruvada +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +index 595511022795..0a86ef43e781 100644 +--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c ++++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +@@ -51,8 +51,6 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state) + st->report_state.report_id, + st->report_state.index, + HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM); +- +- poll_value = hid_sensor_read_poll_value(st); + } else { + int val; + +@@ -89,7 +87,9 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state) + sensor_hub_get_feature(st->hsdev, st->power_state.report_id, + st->power_state.index, + sizeof(state_val), &state_val); +- if (state && poll_value) ++ if (state) ++ poll_value = hid_sensor_read_poll_value(st); ++ if (poll_value > 0) + msleep_interruptible(poll_value * 2); + + return 0; +-- +2.12.2 + +From c7d1545c48ffbf19185753c1d786e5aab950d3e3 Mon Sep 17 00:00:00 2001 +From: Sudip Mukherjee +Date: Mon, 6 Mar 2017 23:23:42 +0000 +Subject: [PATCH 173/251] parport: fix attempt to write duplicate procfiles +Content-Length: 1584 +Lines: 41 + +commit 03270c6ac6207fc55bbf9d20d195029dca210c79 upstream. + +Usually every parallel port will have a single pardev registered with +it. But ppdev driver is an exception. This userspace parallel port +driver allows to create multiple parrallel port devices for a single +parallel port. And as a result we were having a nice warning like: +"sysctl table check failed: +/dev/parport/parport0/devices/ppdev0/timeslice Sysctl already exists" + +Use the same logic as used in parport_register_device() and register +the proc files only once for each parallel port. + +Fixes: 6fa45a226897 ("parport: add device-model to parport subsystem") +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1414656 +Bugzilla: https://bugs.archlinux.org/task/52322 +Tested-by: James Feeney +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + drivers/parport/share.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/parport/share.c b/drivers/parport/share.c +index 5ce5ef211bdb..754f21fd9768 100644 +--- a/drivers/parport/share.c ++++ b/drivers/parport/share.c +@@ -936,8 +936,10 @@ parport_register_dev_model(struct parport *port, const char *name, + * pardevice fields. -arca + */ + port->ops->init_state(par_dev, par_dev->state); +- port->proc_device = par_dev; +- parport_device_proc_register(par_dev); ++ if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) { ++ port->proc_device = par_dev; ++ parport_device_proc_register(par_dev); ++ } + + return par_dev; + +-- +2.12.2 + +From 27d9bf096406439ce406c82291cfe09c6653f94c Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 15 Mar 2017 14:52:02 -0400 +Subject: [PATCH 174/251] ext4: mark inode dirty after converting inline + directory +Content-Length: 1573 +Lines: 42 + +commit b9cf625d6ecde0d372e23ae022feead72b4228a6 upstream. + +If ext4_convert_inline_data() was called on a directory with inline +data, the filesystem was left in an inconsistent state (as considered by +e2fsck) because the file size was not increased to cover the new block. +This happened because the inode was not marked dirty after i_disksize +was updated. Fix this by marking the inode dirty at the end of +ext4_finish_convert_inline_dir(). + +This bug was probably not noticed before because most users mark the +inode dirty afterwards for other reasons. But if userspace executed +FS_IOC_SET_ENCRYPTION_POLICY with invalid parameters, as exercised by +'kvm-xfstests -c adv generic/396', then the inode was never marked dirty +after updating i_disksize. + +Fixes: 3c47d54170b6a678875566b1b8d6dcf57904e49b +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/inline.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index d4be4e23bc21..dad8e7bdf0a6 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -1158,10 +1158,9 @@ static int ext4_finish_convert_inline_dir(handle_t *handle, + set_buffer_uptodate(dir_block); + err = ext4_handle_dirty_dirent_node(handle, inode, dir_block); + if (err) +- goto out; ++ return err; + set_buffer_verified(dir_block); +-out: +- return err; ++ return ext4_mark_inode_dirty(handle, inode); + } + + static int ext4_convert_inline_data_nolock(handle_t *handle, +-- +2.12.2 + +From 52e40a2fcc3952f1edd2f810c36d05eece984cba Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Mon, 20 Mar 2017 19:50:29 +0200 +Subject: [PATCH 175/251] mmc: sdhci: Do not disable interrupts while waiting + for clock +Content-Length: 1383 +Lines: 40 + +commit e2ebfb2142acefecc2496e71360f50d25726040b upstream. + +Disabling interrupts for even a millisecond can cause problems for some +devices. That can happen when sdhci changes clock frequency because it +waits for the clock to become stable under a spin lock. + +The spin lock is not necessary here. Anything that is racing with changes +to the I/O state is already broken. The mmc core already provides +synchronization via "claiming" the host. + +Although the spin lock probably should be removed from the code paths that +lead to this point, such a patch would touch too much code to be suitable +for stable trees. Consequently, for this patch, just drop the spin lock +while waiting. + +Signed-off-by: Adrian Hunter +Signed-off-by: Ulf Hansson +Tested-by: Ludovic Desroches +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index bda164089904..62d37d2ac557 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -1274,7 +1274,9 @@ clock_set: + return; + } + timeout--; +- mdelay(1); ++ spin_unlock_irq(&host->lock); ++ usleep_range(900, 1100); ++ spin_lock_irq(&host->lock); + } + + clk |= SDHCI_CLOCK_CARD_EN; +-- +2.12.2 + +From c856b66c8aac95c74c0ddad4ce1d55a6741e23db Mon Sep 17 00:00:00 2001 +From: Ankur Arora +Date: Tue, 21 Mar 2017 15:43:38 -0700 +Subject: [PATCH 176/251] xen/acpi: upload PM state from init-domain to Xen +Content-Length: 3186 +Lines: 98 + +commit 1914f0cd203c941bba72f9452c8290324f1ef3dc upstream. + +This was broken in commit cd979883b9ed ("xen/acpi-processor: +fix enabling interrupts on syscore_resume"). do_suspend (from +xen/manage.c) and thus xen_resume_notifier never get called on +the initial-domain at resume (it is if running as guest.) + +The rationale for the breaking change was that upload_pm_data() +potentially does blocking work in syscore_resume(). This patch +addresses the original issue by scheduling upload_pm_data() to +execute in workqueue context. + +Cc: Stanislaw Gruszka +Based-on-patch-by: Konrad Wilk +Reviewed-by: Konrad Rzeszutek Wilk +Reviewed-by: Stanislaw Gruszka +Signed-off-by: Ankur Arora +Signed-off-by: Boris Ostrovsky +Signed-off-by: Greg Kroah-Hartman +--- + drivers/xen/xen-acpi-processor.c | 34 ++++++++++++++++++++++++++-------- + 1 file changed, 26 insertions(+), 8 deletions(-) + +diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c +index 611f9c11da85..2e319d0c395d 100644 +--- a/drivers/xen/xen-acpi-processor.c ++++ b/drivers/xen/xen-acpi-processor.c +@@ -27,10 +27,10 @@ + #include + #include + #include ++#include + #include + #include + #include +-#include + #include + #include + +@@ -466,15 +466,33 @@ static int xen_upload_processor_pm_data(void) + return rc; + } + +-static int xen_acpi_processor_resume(struct notifier_block *nb, +- unsigned long action, void *data) ++static void xen_acpi_processor_resume_worker(struct work_struct *dummy) + { ++ int rc; ++ + bitmap_zero(acpi_ids_done, nr_acpi_bits); +- return xen_upload_processor_pm_data(); ++ ++ rc = xen_upload_processor_pm_data(); ++ if (rc != 0) ++ pr_info("ACPI data upload failed, error = %d\n", rc); ++} ++ ++static void xen_acpi_processor_resume(void) ++{ ++ static DECLARE_WORK(wq, xen_acpi_processor_resume_worker); ++ ++ /* ++ * xen_upload_processor_pm_data() calls non-atomic code. ++ * However, the context for xen_acpi_processor_resume is syscore ++ * with only the boot CPU online and in an atomic context. ++ * ++ * So defer the upload for some point safer. ++ */ ++ schedule_work(&wq); + } + +-struct notifier_block xen_acpi_processor_resume_nb = { +- .notifier_call = xen_acpi_processor_resume, ++static struct syscore_ops xap_syscore_ops = { ++ .resume = xen_acpi_processor_resume, + }; + + static int __init xen_acpi_processor_init(void) +@@ -527,7 +545,7 @@ static int __init xen_acpi_processor_init(void) + if (rc) + goto err_unregister; + +- xen_resume_notifier_register(&xen_acpi_processor_resume_nb); ++ register_syscore_ops(&xap_syscore_ops); + + return 0; + err_unregister: +@@ -544,7 +562,7 @@ static void __exit xen_acpi_processor_exit(void) + { + int i; + +- xen_resume_notifier_unregister(&xen_acpi_processor_resume_nb); ++ unregister_syscore_ops(&xap_syscore_ops); + kfree(acpi_ids_done); + kfree(acpi_id_present); + kfree(acpi_id_cst_present); +-- +2.12.2 + +From 55b6c187cf9d12d8e667ccfa5386bd162fc7ae2b Mon Sep 17 00:00:00 2001 +From: Koos Vriezen +Date: Wed, 1 Mar 2017 21:02:50 +0100 +Subject: [PATCH 177/251] iommu/vt-d: Fix NULL pointer dereference in + device_to_iommu +Content-Length: 2697 +Lines: 73 + +commit 5003ae1e735e6bfe4679d9bed6846274f322e77e upstream. + +The function device_to_iommu() in the Intel VT-d driver +lacks a NULL-ptr check, resulting in this oops at boot on +some platforms: + + BUG: unable to handle kernel NULL pointer dereference at 00000000000007ab + IP: [] device_to_iommu+0x11a/0x1a0 + PGD 0 + + [...] + + Call Trace: + ? find_or_alloc_domain.constprop.29+0x1a/0x300 + ? dw_dma_probe+0x561/0x580 [dw_dmac_core] + ? __get_valid_domain_for_dev+0x39/0x120 + ? __intel_map_single+0x138/0x180 + ? intel_alloc_coherent+0xb6/0x120 + ? sst_hsw_dsp_init+0x173/0x420 [snd_soc_sst_haswell_pcm] + ? mutex_lock+0x9/0x30 + ? kernfs_add_one+0xdb/0x130 + ? devres_add+0x19/0x60 + ? hsw_pcm_dev_probe+0x46/0xd0 [snd_soc_sst_haswell_pcm] + ? platform_drv_probe+0x30/0x90 + ? driver_probe_device+0x1ed/0x2b0 + ? __driver_attach+0x8f/0xa0 + ? driver_probe_device+0x2b0/0x2b0 + ? bus_for_each_dev+0x55/0x90 + ? bus_add_driver+0x110/0x210 + ? 0xffffffffa11ea000 + ? driver_register+0x52/0xc0 + ? 0xffffffffa11ea000 + ? do_one_initcall+0x32/0x130 + ? free_vmap_area_noflush+0x37/0x70 + ? kmem_cache_alloc+0x88/0xd0 + ? do_init_module+0x51/0x1c4 + ? load_module+0x1ee9/0x2430 + ? show_taint+0x20/0x20 + ? kernel_read_file+0xfd/0x190 + ? SyS_finit_module+0xa3/0xb0 + ? do_syscall_64+0x4a/0xb0 + ? entry_SYSCALL64_slow_path+0x25/0x25 + Code: 78 ff ff ff 4d 85 c0 74 ee 49 8b 5a 10 0f b6 9b e0 00 00 00 41 38 98 e0 00 00 00 77 da 0f b6 eb 49 39 a8 88 00 00 00 72 ce eb 8f <41> f6 82 ab 07 00 00 04 0f 85 76 ff ff ff 0f b6 4d 08 88 0e 49 + RIP [] device_to_iommu+0x11a/0x1a0 + RSP + CR2: 00000000000007ab + ---[ end trace 16f974b6d58d0aad ]--- + +Add the missing pointer check. + +Fixes: 1c387188c60f53b338c20eee32db055dfe022a9b ("iommu/vt-d: Fix IOMMU lookup for SR-IOV Virtual Functions") +Signed-off-by: Koos Vriezen +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/intel-iommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index f0fc6f7b5d98..0628372f3591 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -908,7 +908,7 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf + * which we used for the IOMMU lookup. Strictly speaking + * we could do this for all PCI devices; we only need to + * get the BDF# from the scope table for ACPI matches. */ +- if (pdev->is_virtfn) ++ if (pdev && pdev->is_virtfn) + goto got_pdev; + + *bus = drhd->devices[i].bus; +-- +2.12.2 + +From 2705b183263bd6e2969a648d2c7353716ca1d7a8 Mon Sep 17 00:00:00 2001 +From: Nicolas Ferre +Date: Tue, 14 Mar 2017 09:38:04 +0100 +Subject: [PATCH 178/251] ARM: at91: pm: cpu_idle: switch DDR to power-down + mode +Content-Length: 2385 +Lines: 64 + +commit 60b89f1928af80b546b5c3fd8714a62f6f4b8844 upstream. + +On some DDR controllers, compatible with the sama5d3 one, +the sequence to enter/exit/re-enter the self-refresh mode adds +more constrains than what is currently written in the at91_idle +driver. An actual access to the DDR chip is needed between exit +and re-enter of this mode which is somehow difficult to implement. +This sequence can completely hang the SoC. It is particularly +experienced on parts which embed a L2 cache if the code run +between IDLE calls fits in it... + +Moreover, as the intention is to enter and exit pretty rapidly +from IDLE, the power-down mode is a good candidate. + +So now we use power-down instead of self-refresh. As we can +simplify the code for sama5d3 compatible DDR controllers, +we instantiate a new sama5d3_ddr_standby() function. + +Signed-off-by: Nicolas Ferre +Fixes: 017b5522d5e3 ("ARM: at91: Add new binding for sama5d3-ddramc") +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/mach-at91/pm.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 23726fb31741..d687f860a2da 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -286,6 +286,22 @@ static void at91_ddr_standby(void) + at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); + } + ++static void sama5d3_ddr_standby(void) ++{ ++ u32 lpr0; ++ u32 saved_lpr0; ++ ++ saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); ++ lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB; ++ lpr0 |= AT91_DDRSDRC_LPCB_POWER_DOWN; ++ ++ at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); ++ ++ cpu_do_idle(); ++ ++ at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); ++} ++ + /* We manage both DDRAM/SDRAM controllers, we need more than one value to + * remember. + */ +@@ -320,7 +336,7 @@ static const struct of_device_id const ramc_ids[] __initconst = { + { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, + { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, + { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, +- { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby }, ++ { .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby }, + { /*sentinel*/ } + }; + +-- +2.12.2 + +From e1af444e52ce1b08cd6534e61f8da7aa55b31880 Mon Sep 17 00:00:00 2001 +From: Nicolas Ferre +Date: Tue, 26 Jan 2016 17:30:18 +0100 +Subject: [PATCH 179/251] ARM: dts: at91: sama5d2: add dma properties to UART + nodes +Content-Length: 3124 +Lines: 89 + +commit b1708b72a0959a032cd2eebb77fa9086ea3e0c84 upstream. + +The dmas/dma-names properties are added to the UART nodes. Note that additional +properties are needed to enable them at the board level: check bindings for +details. + +Signed-off-by: Nicolas Ferre +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/boot/dts/sama5d2.dtsi | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi +index 4dfca8fc49b3..1bc61ece2589 100644 +--- a/arch/arm/boot/dts/sama5d2.dtsi ++++ b/arch/arm/boot/dts/sama5d2.dtsi +@@ -856,6 +856,13 @@ + compatible = "atmel,at91sam9260-usart"; + reg = <0xf801c000 0x100>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH 7>; ++ dmas = <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(35))>, ++ <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(36))>; ++ dma-names = "tx", "rx"; + clocks = <&uart0_clk>; + clock-names = "usart"; + status = "disabled"; +@@ -865,6 +872,13 @@ + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8020000 0x100>; + interrupts = <25 IRQ_TYPE_LEVEL_HIGH 7>; ++ dmas = <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(37))>, ++ <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(38))>; ++ dma-names = "tx", "rx"; + clocks = <&uart1_clk>; + clock-names = "usart"; + status = "disabled"; +@@ -874,6 +888,13 @@ + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8024000 0x100>; + interrupts = <26 IRQ_TYPE_LEVEL_HIGH 7>; ++ dmas = <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(39))>, ++ <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(40))>; ++ dma-names = "tx", "rx"; + clocks = <&uart2_clk>; + clock-names = "usart"; + status = "disabled"; +@@ -985,6 +1006,13 @@ + compatible = "atmel,at91sam9260-usart"; + reg = <0xfc008000 0x100>; + interrupts = <27 IRQ_TYPE_LEVEL_HIGH 7>; ++ dmas = <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(41))>, ++ <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(42))>; ++ dma-names = "tx", "rx"; + clocks = <&uart3_clk>; + clock-names = "usart"; + status = "disabled"; +@@ -993,6 +1021,13 @@ + uart4: serial@fc00c000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xfc00c000 0x100>; ++ dmas = <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(43))>, ++ <&dma0 ++ (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | ++ AT91_XDMAC_DT_PERID(44))>; ++ dma-names = "tx", "rx"; + interrupts = <28 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&uart4_clk>; + clock-names = "usart"; +-- +2.12.2 + +From 17503963206584333b674740ba75b5079ea7e196 Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Tue, 21 Mar 2017 11:36:06 +0530 +Subject: [PATCH 180/251] cpufreq: Restore policy min/max limits on CPU online +Content-Length: 1475 +Lines: 38 + +commit ff010472fb75670cb5c08671e820eeea3af59c87 upstream. + +On CPU online the cpufreq core restores the previous governor (or +the previous "policy" setting for ->setpolicy drivers), but it does +not restore the min/max limits at the same time, which is confusing, +inconsistent and real pain for users who set the limits and then +suspend/resume the system (using full suspend), in which case the +limits are reset on all CPUs except for the boot one. + +Fix this by making cpufreq_online() restore the limits when an inactive +policy is brought online. + +The commit log and patch are inspired from Rafael's earlier work. + +Reported-by: Rafael J. Wysocki +Signed-off-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/cpufreq.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 86fa9fdc8323..38b363f4316b 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1186,6 +1186,9 @@ static int cpufreq_online(unsigned int cpu) + for_each_cpu(j, policy->related_cpus) + per_cpu(cpufreq_cpu_data, j) = policy; + write_unlock_irqrestore(&cpufreq_driver_lock, flags); ++ } else { ++ policy->min = policy->user_policy.min; ++ policy->max = policy->user_policy.max; + } + + if (cpufreq_driver->get && !cpufreq_driver->setpolicy) { +-- +2.12.2 + +From 73dd1edf50a6bdf33046c2e4aa0b1ad4fef71a71 Mon Sep 17 00:00:00 2001 +From: Tomasz Majchrzak +Date: Thu, 28 Jul 2016 10:28:25 +0200 +Subject: [PATCH 181/251] raid10: increment write counter after bio is split +Content-Length: 1096 +Lines: 38 + +commit 9b622e2bbcf049c82e2550d35fb54ac205965f50 upstream. + +md pending write counter must be incremented after bio is split, +otherwise it gets decremented too many times in end bio callback and +becomes negative. + +Signed-off-by: Tomasz Majchrzak +Reviewed-by: Artur Paszkiewicz +Signed-off-by: Shaohua Li +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/raid10.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index 122af340a531..a92979e704e3 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -1072,6 +1072,8 @@ static void __make_request(struct mddev *mddev, struct bio *bio) + int max_sectors; + int sectors; + ++ md_write_start(mddev, bio); ++ + /* + * Register the new request and wait if the reconstruction + * thread has put up a bar for new requests. +@@ -1455,8 +1457,6 @@ static void make_request(struct mddev *mddev, struct bio *bio) + return; + } + +- md_write_start(mddev, bio); +- + do { + + /* +-- +2.12.2 + +From 48da8f817b9db7909e5758257bdc84a6c611d99a Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Wed, 1 Mar 2017 17:33:27 +0100 +Subject: [PATCH 182/251] libceph: don't set weight to IN when OSD is destroyed +Content-Length: 1361 +Lines: 34 + +commit b581a5854eee4b7851dedb0f8c2ceb54fb902c06 upstream. + +Since ceph.git commit 4e28f9e63644 ("osd/OSDMap: clear osd_info, +osd_xinfo on osd deletion"), weight is set to IN when OSD is deleted. +This changes the result of applying an incremental for clients, not +just OSDs. Because CRUSH computations are obviously affected, +pre-4e28f9e63644 servers disagree with post-4e28f9e63644 clients on +object placement, resulting in misdirected requests. + +Mirrors ceph.git commit a6009d1039a55e2c77f431662b3d6cc5a8e8e63f. + +Fixes: 930c53286977 ("libceph: apply new_state before new_up_client on incrementals") +Link: http://tracker.ceph.com/issues/19122 +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman +--- + net/ceph/osdmap.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c +index ddc3573894b0..bc95e48d5cfb 100644 +--- a/net/ceph/osdmap.c ++++ b/net/ceph/osdmap.c +@@ -1265,7 +1265,6 @@ static int decode_new_up_state_weight(void **p, void *end, + if ((map->osd_state[osd] & CEPH_OSD_EXISTS) && + (xorstate & CEPH_OSD_EXISTS)) { + pr_info("osd%d does not exist\n", osd); +- map->osd_weight[osd] = CEPH_OSD_IN; + ret = set_primary_affinity(map, osd, + CEPH_OSD_DEFAULT_PRIMARY_AFFINITY); + if (ret) +-- +2.12.2 + +From c4cf86f69597d4547a736e3edd5b88ae61b68fa2 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Mon, 5 Dec 2016 12:38:38 +1100 +Subject: [PATCH 183/251] xfs: don't allow di_size with high bit set +Content-Length: 1355 +Lines: 38 + +commit ef388e2054feedaeb05399ed654bdb06f385d294 upstream. + +The on-disk field di_size is used to set i_size, which is a signed +integer of loff_t. If the high bit of di_size is set, we'll end up with +a negative i_size, which will cause all sorts of problems. Since the +VFS won't let us create a file with such length, we should catch them +here in the verifier too. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Dave Chinner +Signed-off-by: Dave Chinner +Cc: Nikolay Borisov +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_inode_buf.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c +index 1aabfda669b0..7183b7ea065b 100644 +--- a/fs/xfs/libxfs/xfs_inode_buf.c ++++ b/fs/xfs/libxfs/xfs_inode_buf.c +@@ -299,6 +299,14 @@ xfs_dinode_verify( + if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC)) + return false; + ++ /* don't allow invalid i_size */ ++ if (be64_to_cpu(dip->di_size) & (1ULL << 63)) ++ return false; ++ ++ /* No zero-length symlinks. */ ++ if (S_ISLNK(be16_to_cpu(dip->di_mode)) && dip->di_size == 0) ++ return false; ++ + /* only version 3 or greater inodes are extensively verified here */ + if (dip->di_version < 3) + return true; +-- +2.12.2 + +From 7922c1becb36b61827a24ee32ffe7c39cf444efb Mon Sep 17 00:00:00 2001 +From: Eric Sandeen +Date: Tue, 8 Nov 2016 12:55:18 +1100 +Subject: [PATCH 184/251] xfs: fix up xfs_swap_extent_forks inline extent + handling +Content-Length: 3921 +Lines: 97 + +commit 4dfce57db6354603641132fac3c887614e3ebe81 upstream. + +There have been several reports over the years of NULL pointer +dereferences in xfs_trans_log_inode during xfs_fsr processes, +when the process is doing an fput and tearing down extents +on the temporary inode, something like: + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000018 +PID: 29439 TASK: ffff880550584fa0 CPU: 6 COMMAND: "xfs_fsr" + [exception RIP: xfs_trans_log_inode+0x10] + #9 [ffff8800a57bbbe0] xfs_bunmapi at ffffffffa037398e [xfs] +#10 [ffff8800a57bbce8] xfs_itruncate_extents at ffffffffa0391b29 [xfs] +#11 [ffff8800a57bbd88] xfs_inactive_truncate at ffffffffa0391d0c [xfs] +#12 [ffff8800a57bbdb8] xfs_inactive at ffffffffa0392508 [xfs] +#13 [ffff8800a57bbdd8] xfs_fs_evict_inode at ffffffffa035907e [xfs] +#14 [ffff8800a57bbe00] evict at ffffffff811e1b67 +#15 [ffff8800a57bbe28] iput at ffffffff811e23a5 +#16 [ffff8800a57bbe58] dentry_kill at ffffffff811dcfc8 +#17 [ffff8800a57bbe88] dput at ffffffff811dd06c +#18 [ffff8800a57bbea8] __fput at ffffffff811c823b +#19 [ffff8800a57bbef0] ____fput at ffffffff811c846e +#20 [ffff8800a57bbf00] task_work_run at ffffffff81093b27 +#21 [ffff8800a57bbf30] do_notify_resume at ffffffff81013b0c +#22 [ffff8800a57bbf50] int_signal at ffffffff8161405d + +As it turns out, this is because the i_itemp pointer, along +with the d_ops pointer, has been overwritten with zeros +when we tear down the extents during truncate. When the in-core +inode fork on the temporary inode used by xfs_fsr was originally +set up during the extent swap, we mistakenly looked at di_nextents +to determine whether all extents fit inline, but this misses extents +generated by speculative preallocation; we should be using if_bytes +instead. + +This mistake corrupts the in-memory inode, and code in +xfs_iext_remove_inline eventually gets bad inputs, causing +it to memmove and memset incorrect ranges; this became apparent +because the two values in ifp->if_u2.if_inline_ext[1] contained +what should have been in d_ops and i_itemp; they were memmoved due +to incorrect array indexing and then the original locations +were zeroed with memset, again due to an array overrun. + +Fix this by properly using i_df.if_bytes to determine the number +of extents, not di_nextents. + +Thanks to dchinner for looking at this with me and spotting the +root cause. + +[nborisov: backported to 4.4] + +Cc: stable@vger.kernel.org +Signed-off-by: Eric Sandeen +Reviewed-by: Brian Foster +Signed-off-by: Dave Chinner +Signed-off-by: Nikolay Borisov +Signed-off-by: Greg Kroah-Hartman +-- + fs/xfs/xfs_bmap_util.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) +--- + fs/xfs/xfs_bmap_util.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c +index dbae6490a79a..832764ee035a 100644 +--- a/fs/xfs/xfs_bmap_util.c ++++ b/fs/xfs/xfs_bmap_util.c +@@ -1713,6 +1713,7 @@ xfs_swap_extents( + xfs_trans_t *tp; + xfs_bstat_t *sbp = &sxp->sx_stat; + xfs_ifork_t *tempifp, *ifp, *tifp; ++ xfs_extnum_t nextents; + int src_log_flags, target_log_flags; + int error = 0; + int aforkblks = 0; +@@ -1899,7 +1900,8 @@ xfs_swap_extents( + * pointer. Otherwise it's already NULL or + * pointing to the extent. + */ +- if (ip->i_d.di_nextents <= XFS_INLINE_EXTS) { ++ nextents = ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t); ++ if (nextents <= XFS_INLINE_EXTS) { + ifp->if_u1.if_extents = + ifp->if_u2.if_inline_ext; + } +@@ -1918,7 +1920,8 @@ xfs_swap_extents( + * pointer. Otherwise it's already NULL or + * pointing to the extent. + */ +- if (tip->i_d.di_nextents <= XFS_INLINE_EXTS) { ++ nextents = tip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t); ++ if (nextents <= XFS_INLINE_EXTS) { + tifp->if_u1.if_extents = + tifp->if_u2.if_inline_ext; + } +-- +2.12.2 + +From 74c8dd066cc06da0a7ee1a4da0ba565e3536a53a Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 15 Mar 2017 14:26:04 +0100 +Subject: [PATCH 185/251] nl80211: fix dumpit error path RTNL deadlocks +Content-Length: 8374 +Lines: 326 + +commit ea90e0dc8cecba6359b481e24d9c37160f6f524f upstream. + +Sowmini pointed out Dmitry's RTNL deadlock report to me, and it turns out +to be perfectly accurate - there are various error paths that miss unlock +of the RTNL. + +To fix those, change the locking a bit to not be conditional in all those +nl80211_prepare_*_dump() functions, but make those require the RTNL to +start with, and fix the buggy error paths. This also let me use sparse +(by appropriately overriding the rtnl_lock/rtnl_unlock functions) to +validate the changes. + +Reported-by: Sowmini Varadhan +Reported-by: Dmitry Vyukov +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/wireless/nl80211.c | 121 ++++++++++++++++++++++--------------------------- + 1 file changed, 53 insertions(+), 68 deletions(-) + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 1f0de6d74daa..9d0953e5734f 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -492,21 +492,17 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb, + { + int err; + +- rtnl_lock(); +- + if (!cb->args[0]) { + err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, + nl80211_fam.attrbuf, nl80211_fam.maxattr, + nl80211_policy); + if (err) +- goto out_unlock; ++ return err; + + *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), + nl80211_fam.attrbuf); +- if (IS_ERR(*wdev)) { +- err = PTR_ERR(*wdev); +- goto out_unlock; +- } ++ if (IS_ERR(*wdev)) ++ return PTR_ERR(*wdev); + *rdev = wiphy_to_rdev((*wdev)->wiphy); + /* 0 is the first index - add 1 to parse only once */ + cb->args[0] = (*rdev)->wiphy_idx + 1; +@@ -516,10 +512,8 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb, + struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1); + struct wireless_dev *tmp; + +- if (!wiphy) { +- err = -ENODEV; +- goto out_unlock; +- } ++ if (!wiphy) ++ return -ENODEV; + *rdev = wiphy_to_rdev(wiphy); + *wdev = NULL; + +@@ -530,21 +524,11 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb, + } + } + +- if (!*wdev) { +- err = -ENODEV; +- goto out_unlock; +- } ++ if (!*wdev) ++ return -ENODEV; + } + + return 0; +- out_unlock: +- rtnl_unlock(); +- return err; +-} +- +-static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev) +-{ +- rtnl_unlock(); + } + + /* IE validation */ +@@ -3884,9 +3868,10 @@ static int nl80211_dump_station(struct sk_buff *skb, + int sta_idx = cb->args[2]; + int err; + ++ rtnl_lock(); + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); + if (err) +- return err; ++ goto out_err; + + if (!wdev->netdev) { + err = -EINVAL; +@@ -3922,7 +3907,7 @@ static int nl80211_dump_station(struct sk_buff *skb, + cb->args[2] = sta_idx; + err = skb->len; + out_err: +- nl80211_finish_wdev_dump(rdev); ++ rtnl_unlock(); + + return err; + } +@@ -4639,9 +4624,10 @@ static int nl80211_dump_mpath(struct sk_buff *skb, + int path_idx = cb->args[2]; + int err; + ++ rtnl_lock(); + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); + if (err) +- return err; ++ goto out_err; + + if (!rdev->ops->dump_mpath) { + err = -EOPNOTSUPP; +@@ -4675,7 +4661,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, + cb->args[2] = path_idx; + err = skb->len; + out_err: +- nl80211_finish_wdev_dump(rdev); ++ rtnl_unlock(); + return err; + } + +@@ -4835,9 +4821,10 @@ static int nl80211_dump_mpp(struct sk_buff *skb, + int path_idx = cb->args[2]; + int err; + ++ rtnl_lock(); + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); + if (err) +- return err; ++ goto out_err; + + if (!rdev->ops->dump_mpp) { + err = -EOPNOTSUPP; +@@ -4870,7 +4857,7 @@ static int nl80211_dump_mpp(struct sk_buff *skb, + cb->args[2] = path_idx; + err = skb->len; + out_err: +- nl80211_finish_wdev_dump(rdev); ++ rtnl_unlock(); + return err; + } + +@@ -6806,9 +6793,12 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb) + int start = cb->args[2], idx = 0; + int err; + ++ rtnl_lock(); + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); +- if (err) ++ if (err) { ++ rtnl_unlock(); + return err; ++ } + + wdev_lock(wdev); + spin_lock_bh(&rdev->bss_lock); +@@ -6831,7 +6821,7 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb) + wdev_unlock(wdev); + + cb->args[2] = idx; +- nl80211_finish_wdev_dump(rdev); ++ rtnl_unlock(); + + return skb->len; + } +@@ -6915,9 +6905,10 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) + int res; + bool radio_stats; + ++ rtnl_lock(); + res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); + if (res) +- return res; ++ goto out_err; + + /* prepare_wdev_dump parsed the attributes */ + radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS]; +@@ -6958,7 +6949,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) + cb->args[2] = survey_idx; + res = skb->len; + out_err: +- nl80211_finish_wdev_dump(rdev); ++ rtnl_unlock(); + return res; + } + +@@ -10158,17 +10149,13 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb, + void *data = NULL; + unsigned int data_len = 0; + +- rtnl_lock(); +- + if (cb->args[0]) { + /* subtract the 1 again here */ + struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1); + struct wireless_dev *tmp; + +- if (!wiphy) { +- err = -ENODEV; +- goto out_unlock; +- } ++ if (!wiphy) ++ return -ENODEV; + *rdev = wiphy_to_rdev(wiphy); + *wdev = NULL; + +@@ -10189,13 +10176,11 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb, + nl80211_fam.attrbuf, nl80211_fam.maxattr, + nl80211_policy); + if (err) +- goto out_unlock; ++ return err; + + if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] || +- !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) { +- err = -EINVAL; +- goto out_unlock; +- } ++ !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) ++ return -EINVAL; + + *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), + nl80211_fam.attrbuf); +@@ -10204,10 +10189,8 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb, + + *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), + nl80211_fam.attrbuf); +- if (IS_ERR(*rdev)) { +- err = PTR_ERR(*rdev); +- goto out_unlock; +- } ++ if (IS_ERR(*rdev)) ++ return PTR_ERR(*rdev); + + vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]); + subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]); +@@ -10220,19 +10203,15 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb, + if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd) + continue; + +- if (!vcmd->dumpit) { +- err = -EOPNOTSUPP; +- goto out_unlock; +- } ++ if (!vcmd->dumpit) ++ return -EOPNOTSUPP; + + vcmd_idx = i; + break; + } + +- if (vcmd_idx < 0) { +- err = -EOPNOTSUPP; +- goto out_unlock; +- } ++ if (vcmd_idx < 0) ++ return -EOPNOTSUPP; + + if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) { + data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]); +@@ -10249,9 +10228,6 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb, + + /* keep rtnl locked in successful case */ + return 0; +- out_unlock: +- rtnl_unlock(); +- return err; + } + + static int nl80211_vendor_cmd_dump(struct sk_buff *skb, +@@ -10266,9 +10242,10 @@ static int nl80211_vendor_cmd_dump(struct sk_buff *skb, + int err; + struct nlattr *vendor_data; + ++ rtnl_lock(); + err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev); + if (err) +- return err; ++ goto out; + + vcmd_idx = cb->args[2]; + data = (void *)cb->args[3]; +@@ -10277,18 +10254,26 @@ static int nl80211_vendor_cmd_dump(struct sk_buff *skb, + + if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV)) { +- if (!wdev) +- return -EINVAL; ++ if (!wdev) { ++ err = -EINVAL; ++ goto out; ++ } + if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV && +- !wdev->netdev) +- return -EINVAL; ++ !wdev->netdev) { ++ err = -EINVAL; ++ goto out; ++ } + + if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) { + if (wdev->netdev && +- !netif_running(wdev->netdev)) +- return -ENETDOWN; +- if (!wdev->netdev && !wdev->p2p_started) +- return -ENETDOWN; ++ !netif_running(wdev->netdev)) { ++ err = -ENETDOWN; ++ goto out; ++ } ++ if (!wdev->netdev && !wdev->p2p_started) { ++ err = -ENETDOWN; ++ goto out; ++ } + } + } + +-- +2.12.2 + +From f154de03f4167664808b002495a877dbe91dd798 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 14 Mar 2017 17:55:45 +0100 +Subject: [PATCH 186/251] USB: usbtmc: add missing endpoint sanity check +Content-Length: 2168 +Lines: 61 + +commit 687e0687f71ec00e0132a21fef802dee88c2f1ad upstream. + +USBTMC devices are required to have a bulk-in and a bulk-out endpoint, +but the driver failed to verify this, something which could lead to the +endpoint addresses being taken from uninitialised memory. + +Make sure to zero all private data as part of allocation, and add the +missing endpoint sanity check. + +Note that this also addresses a more recently introduced issue, where +the interrupt-in-presence flag would also be uninitialised whenever the +optional interrupt-in endpoint is not present. This in turn could lead +to an interrupt urb being allocated, initialised and submitted based on +uninitialised values. + +Fixes: dbf3e7f654c0 ("Implement an ioctl to support the USMTMC-USB488 READ_STATUS_BYTE operation.") +Fixes: 5b775f672cc9 ("USB: add USB test and measurement class driver") +Signed-off-by: Johan Hovold +[ johan: backport to v4.4 ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/usbtmc.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c +index deaddb950c20..24337ac3323f 100644 +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -1105,7 +1105,7 @@ static int usbtmc_probe(struct usb_interface *intf, + + dev_dbg(&intf->dev, "%s called\n", __func__); + +- data = kmalloc(sizeof(*data), GFP_KERNEL); ++ data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + +@@ -1163,6 +1163,12 @@ static int usbtmc_probe(struct usb_interface *intf, + } + } + ++ if (!data->bulk_out || !data->bulk_in) { ++ dev_err(&intf->dev, "bulk endpoints not found\n"); ++ retcode = -ENODEV; ++ goto err_put; ++ } ++ + retcode = get_capabilities(data); + if (retcode) + dev_err(&intf->dev, "can't read capabilities\n"); +@@ -1186,6 +1192,7 @@ static int usbtmc_probe(struct usb_interface *intf, + error_register: + sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); + sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); ++err_put: + kref_put(&data->kref, usbtmc_delete); + return retcode; + } +-- +2.12.2 + +From 6d43e485e0067b682466eb4e3aff8ff9a6822966 Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Wed, 25 Jan 2017 20:24:57 -0800 +Subject: [PATCH 187/251] xfs: clear _XBF_PAGES from buffers when readahead + page +Content-Length: 1594 +Lines: 42 + +commit 2aa6ba7b5ad3189cc27f14540aa2f57f0ed8df4b upstream. + +If we try to allocate memory pages to back an xfs_buf that we're trying +to read, it's possible that we'll be so short on memory that the page +allocation fails. For a blocking read we'll just wait, but for +readahead we simply dump all the pages we've collected so far. + +Unfortunately, after dumping the pages we neglect to clear the +_XBF_PAGES state, which means that the subsequent call to xfs_buf_free +thinks that b_pages still points to pages we own. It then double-frees +the b_pages pages. + +This results in screaming about negative page refcounts from the memory +manager, which xfs oughtn't be triggering. To reproduce this case, +mount a filesystem where the size of the inodes far outweighs the +availalble memory (a ~500M inode filesystem on a VM with 300MB memory +did the trick here) and run bulkstat in parallel with other memory +eating processes to put a huge load on the system. The "check summary" +phase of xfs_scrub also works for this purpose. + +Signed-off-by: Darrick J. Wong +Reviewed-by: Eric Sandeen +Cc: Ivan Kozik +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_buf.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c +index eb1b8c8acfcb..8146b0cf20ce 100644 +--- a/fs/xfs/xfs_buf.c ++++ b/fs/xfs/xfs_buf.c +@@ -375,6 +375,7 @@ retry: + out_free_pages: + for (i = 0; i < bp->b_page_count; i++) + __free_page(bp->b_pages[i]); ++ bp->b_flags &= ~_XBF_PAGES; + return error; + } + +-- +2.12.2 + +From ec52364445a497a0045c61145f0d795b606c23bb Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:01 +0530 +Subject: [PATCH 188/251] xen: do not re-use pirq number cached in pci device + msi msg data +Content-Length: 3533 +Lines: 83 + +From: Dan Streetman + +[ Upstream commit c74fd80f2f41d05f350bb478151021f88551afe8 ] + +Revert the main part of commit: +af42b8d12f8a ("xen: fix MSI setup and teardown for PV on HVM guests") + +That commit introduced reading the pci device's msi message data to see +if a pirq was previously configured for the device's msi/msix, and re-use +that pirq. At the time, that was the correct behavior. However, a +later change to Qemu caused it to call into the Xen hypervisor to unmap +all pirqs for a pci device, when the pci device disables its MSI/MSIX +vectors; specifically the Qemu commit: +c976437c7dba9c7444fb41df45468968aaa326ad +("qemu-xen: free all the pirqs for msi/msix when driver unload") + +Once Qemu added this pirq unmapping, it was no longer correct for the +kernel to re-use the pirq number cached in the pci device msi message +data. All Qemu releases since 2.1.0 contain the patch that unmaps the +pirqs when the pci device disables its MSI/MSIX vectors. + +This bug is causing failures to initialize multiple NVMe controllers +under Xen, because the NVMe driver sets up a single MSIX vector for +each controller (concurrently), and then after using that to talk to +the controller for some configuration data, it disables the single MSIX +vector and re-configures all the MSIX vectors it needs. So the MSIX +setup code tries to re-use the cached pirq from the first vector +for each controller, but the hypervisor has already given away that +pirq to another controller, and its initialization fails. + +This is discussed in more detail at: +https://lists.xen.org/archives/html/xen-devel/2017-01/msg00447.html + +Fixes: af42b8d12f8a ("xen: fix MSI setup and teardown for PV on HVM guests") +Signed-off-by: Dan Streetman +Reviewed-by: Stefano Stabellini +Acked-by: Konrad Rzeszutek Wilk +Signed-off-by: Boris Ostrovsky +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/pci/xen.c | 23 +++++++---------------- + 1 file changed, 7 insertions(+), 16 deletions(-) + +diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c +index c6d6efed392a..7575f0798194 100644 +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -231,23 +231,14 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) + return 1; + + for_each_pci_msi_entry(msidesc, dev) { +- __pci_read_msi_msg(msidesc, &msg); +- pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | +- ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); +- if (msg.data != XEN_PIRQ_MSI_DATA || +- xen_irq_from_pirq(pirq) < 0) { +- pirq = xen_allocate_pirq_msi(dev, msidesc); +- if (pirq < 0) { +- irq = -ENODEV; +- goto error; +- } +- xen_msi_compose_msg(dev, pirq, &msg); +- __pci_write_msi_msg(msidesc, &msg); +- dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); +- } else { +- dev_dbg(&dev->dev, +- "xen: msi already bound to pirq=%d\n", pirq); ++ pirq = xen_allocate_pirq_msi(dev, msidesc); ++ if (pirq < 0) { ++ irq = -ENODEV; ++ goto error; + } ++ xen_msi_compose_msg(dev, pirq, &msg); ++ __pci_write_msi_msg(msidesc, &msg); ++ dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, + (type == PCI_CAP_ID_MSI) ? nvec : 1, + (type == PCI_CAP_ID_MSIX) ? +-- +2.12.2 + +From 4db313df49466185211ea7d6d675f8c4f6724e23 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:02 +0530 +Subject: [PATCH 189/251] igb: Workaround for igb i210 firmware issue +Content-Length: 1454 +Lines: 38 + +From: Chris J Arges + +[ Upstream commit 4e684f59d760a2c7c716bb60190783546e2d08a1 ] + +Sometimes firmware may not properly initialize I347AT4_PAGE_SELECT causing +the probe of an igb i210 NIC to fail. This patch adds an addition zeroing +of this register during igb_get_phy_id to workaround this issue. + +Thanks for Jochen Henneberg for the idea and original patch. + +Signed-off-by: Chris J Arges +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/igb/e1000_phy.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c +index 23ec28f43f6d..13ad20b250bc 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_phy.c ++++ b/drivers/net/ethernet/intel/igb/e1000_phy.c +@@ -77,6 +77,10 @@ s32 igb_get_phy_id(struct e1000_hw *hw) + s32 ret_val = 0; + u16 phy_id; + ++ /* ensure PHY page selection to fix misconfigured i210 */ ++ if (hw->mac.type == e1000_i210) ++ phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0); ++ + ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); + if (ret_val) + goto out; +-- +2.12.2 + +From ca7e3bdc9c7e01d8040422d9eae0b9f07c81419e Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:03 +0530 +Subject: [PATCH 190/251] igb: add i211 to i210 PHY workaround +Content-Length: 1309 +Lines: 33 + +From: Todd Fujinaka + +[ Upstream commit 5bc8c230e2a993b49244f9457499f17283da9ec7 ] + +i210 and i211 share the same PHY but have different PCI IDs. Don't +forget i211 for any i210 workarounds. + +Signed-off-by: Todd Fujinaka +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/igb/e1000_phy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c +index 13ad20b250bc..afaa98d1d4e4 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_phy.c ++++ b/drivers/net/ethernet/intel/igb/e1000_phy.c +@@ -78,7 +78,7 @@ s32 igb_get_phy_id(struct e1000_hw *hw) + u16 phy_id; + + /* ensure PHY page selection to fix misconfigured i210 */ +- if (hw->mac.type == e1000_i210) ++ if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) + phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0); + + ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); +-- +2.12.2 + +From e4ce31c0265dc6086fb4f13d88deef50d20cdb24 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:04 +0530 +Subject: [PATCH 191/251] x86/hyperv: Handle unknown NMIs on one CPU when + unknown_nmi_panic +Content-Length: 4630 +Lines: 122 + +From: Vitaly Kuznetsov + +[ Upstream commit 59107e2f48831daedc46973ce4988605ab066de3 ] + +There is a feature in Hyper-V ('Debug-VM --InjectNonMaskableInterrupt') +which injects NMI to the guest. We may want to crash the guest and do kdump +on this NMI by enabling unknown_nmi_panic. To make kdump succeed we need to +allow the kdump kernel to re-establish VMBus connection so it will see +VMBus devices (storage, network,..). + +To properly unload VMBus making it possible to start over during kdump we +need to do the following: + + - Send an 'unload' message to the hypervisor. This can be done on any CPU + so we do this the crashing CPU. + + - Receive the 'unload finished' reply message. WS2012R2 delivers this + message to the CPU which was used to establish VMBus connection during + module load and this CPU may differ from the CPU sending 'unload'. + +Receiving a VMBus message means the following: + + - There is a per-CPU slot in memory for one message. This slot can in + theory be accessed by any CPU. + + - We get an interrupt on the CPU when a message was placed into the slot. + + - When we read the message we need to clear the slot and signal the fact + to the hypervisor. In case there are more messages to this CPU pending + the hypervisor will deliver the next message. The signaling is done by + writing to an MSR so this can only be done on the appropriate CPU. + +To avoid doing cross-CPU work on crash we have vmbus_wait_for_unload() +function which checks message slots for all CPUs in a loop waiting for the +'unload finished' messages. However, there is an issue which arises when +these conditions are met: + + - We're crashing on a CPU which is different from the one which was used + to initially contact the hypervisor. + + - The CPU which was used for the initial contact is blocked with interrupts + disabled and there is a message pending in the message slot. + +In this case we won't be able to read the 'unload finished' message on the +crashing CPU. This is reproducible when we receive unknown NMIs on all CPUs +simultaneously: the first CPU entering panic() will proceed to crash and +all other CPUs will stop themselves with interrupts disabled. + +The suggested solution is to handle unknown NMIs for Hyper-V guests on the +first CPU which gets them only. This will allow us to rely on VMBus +interrupt handler being able to receive the 'unload finish' message in +case it is delivered to a different CPU. + +The issue is not reproducible on WS2016 as Debug-VM delivers NMI to the +boot CPU only, WS2012R2 and earlier Hyper-V versions are affected. + +Signed-off-by: Vitaly Kuznetsov +Acked-by: K. Y. Srinivasan +Cc: devel@linuxdriverproject.org +Cc: Haiyang Zhang +Link: http://lkml.kernel.org/r/20161202100720.28121-1-vkuznets@redhat.com +Signed-off-by: Thomas Gleixner +Signed-off-by: Ingo Molnar +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/mshyperv.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c +index cfc4a966e2b9..83b5f7a323a9 100644 +--- a/arch/x86/kernel/cpu/mshyperv.c ++++ b/arch/x86/kernel/cpu/mshyperv.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + struct ms_hyperv_info ms_hyperv; + EXPORT_SYMBOL_GPL(ms_hyperv); +@@ -157,6 +158,26 @@ static unsigned char hv_get_nmi_reason(void) + return 0; + } + ++#ifdef CONFIG_X86_LOCAL_APIC ++/* ++ * Prior to WS2016 Debug-VM sends NMIs to all CPUs which makes ++ * it dificult to process CHANNELMSG_UNLOAD in case of crash. Handle ++ * unknown NMI on the first CPU which gets it. ++ */ ++static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs) ++{ ++ static atomic_t nmi_cpu = ATOMIC_INIT(-1); ++ ++ if (!unknown_nmi_panic) ++ return NMI_DONE; ++ ++ if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1) ++ return NMI_HANDLED; ++ ++ return NMI_DONE; ++} ++#endif ++ + static void __init ms_hyperv_init_platform(void) + { + /* +@@ -182,6 +203,9 @@ static void __init ms_hyperv_init_platform(void) + printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n", + lapic_timer_frequency); + } ++ ++ register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST, ++ "hv_nmi_unknown"); + #endif + + if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) +-- +2.12.2 + +From a87693ec42f24334ece33fac6ea639956f50bd90 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:05 +0530 +Subject: [PATCH 192/251] PCI: Separate VF BAR updates from standard BAR + updates +Content-Length: 4390 +Lines: 137 + +From: Bjorn Helgaas + +[ Upstream commit 6ffa2489c51da77564a0881a73765ea2169f955d ] + +Previously pci_update_resource() used the same code path for updating +standard BARs and VF BARs in SR-IOV capabilities. + +Split the VF BAR update into a new pci_iov_update_resource() internal +interface, which makes it simpler to compute the BAR address (we can get +rid of pci_resource_bar() and pci_iov_resource_bar()). + +This patch: + + - Renames pci_update_resource() to pci_std_update_resource(), + - Adds pci_iov_update_resource(), + - Makes pci_update_resource() a wrapper that calls the appropriate one, + +No functional change intended. + +Signed-off-by: Bjorn Helgaas +Reviewed-by: Gavin Shan +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/iov.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ + drivers/pci/pci.h | 1 + + drivers/pci/setup-res.c | 13 +++++++++++-- + 3 files changed, 62 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c +index 31f31d460fc9..a6b100168396 100644 +--- a/drivers/pci/iov.c ++++ b/drivers/pci/iov.c +@@ -572,6 +572,56 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno) + 4 * (resno - PCI_IOV_RESOURCES); + } + ++/** ++ * pci_iov_update_resource - update a VF BAR ++ * @dev: the PCI device ++ * @resno: the resource number ++ * ++ * Update a VF BAR in the SR-IOV capability of a PF. ++ */ ++void pci_iov_update_resource(struct pci_dev *dev, int resno) ++{ ++ struct pci_sriov *iov = dev->is_physfn ? dev->sriov : NULL; ++ struct resource *res = dev->resource + resno; ++ int vf_bar = resno - PCI_IOV_RESOURCES; ++ struct pci_bus_region region; ++ u32 new; ++ int reg; ++ ++ /* ++ * The generic pci_restore_bars() path calls this for all devices, ++ * including VFs and non-SR-IOV devices. If this is not a PF, we ++ * have nothing to do. ++ */ ++ if (!iov) ++ return; ++ ++ /* ++ * Ignore unimplemented BARs, unused resource slots for 64-bit ++ * BARs, and non-movable resources, e.g., those described via ++ * Enhanced Allocation. ++ */ ++ if (!res->flags) ++ return; ++ ++ if (res->flags & IORESOURCE_UNSET) ++ return; ++ ++ if (res->flags & IORESOURCE_PCI_FIXED) ++ return; ++ ++ pcibios_resource_to_bus(dev->bus, ®ion, res); ++ new = region.start; ++ new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; ++ ++ reg = iov->pos + PCI_SRIOV_BAR + 4 * vf_bar; ++ pci_write_config_dword(dev, reg, new); ++ if (res->flags & IORESOURCE_MEM_64) { ++ new = region.start >> 16 >> 16; ++ pci_write_config_dword(dev, reg + 4, new); ++ } ++} ++ + resource_size_t __weak pcibios_iov_resource_alignment(struct pci_dev *dev, + int resno) + { +diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h +index d390fc1475ec..eda77d1baec1 100644 +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -277,6 +277,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) + int pci_iov_init(struct pci_dev *dev); + void pci_iov_release(struct pci_dev *dev); + int pci_iov_resource_bar(struct pci_dev *dev, int resno); ++void pci_iov_update_resource(struct pci_dev *dev, int resno); + resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); + void pci_restore_iov_state(struct pci_dev *dev); + int pci_iov_bus_range(struct pci_bus *bus); +diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c +index 604011e047d6..ac58c566fb1a 100644 +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -25,8 +25,7 @@ + #include + #include "pci.h" + +- +-void pci_update_resource(struct pci_dev *dev, int resno) ++static void pci_std_update_resource(struct pci_dev *dev, int resno) + { + struct pci_bus_region region; + bool disable; +@@ -110,6 +109,16 @@ void pci_update_resource(struct pci_dev *dev, int resno) + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + ++void pci_update_resource(struct pci_dev *dev, int resno) ++{ ++ if (resno <= PCI_ROM_RESOURCE) ++ pci_std_update_resource(dev, resno); ++#ifdef CONFIG_PCI_IOV ++ else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END) ++ pci_iov_update_resource(dev, resno); ++#endif ++} ++ + int pci_claim_resource(struct pci_dev *dev, int resource) + { + struct resource *res = &dev->resource[resource]; +-- +2.12.2 + +From cef498a2c75adca3b4e3fc348e47498496eec809 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:06 +0530 +Subject: [PATCH 193/251] PCI: Remove pci_resource_bar() and + pci_iov_resource_bar() +Content-Length: 5197 +Lines: 160 + +From: Bjorn Helgaas + +[ Upstream commit 286c2378aaccc7343ebf17ec6cd86567659caf70 ] + +pci_std_update_resource() only deals with standard BARs, so we don't have +to worry about the complications of VF BARs in an SR-IOV capability. + +Compute the BAR address inline and remove pci_resource_bar(). That makes +pci_iov_resource_bar() unused, so remove that as well. + +Signed-off-by: Bjorn Helgaas +Reviewed-by: Gavin Shan +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/iov.c | 18 ------------------ + drivers/pci/pci.c | 30 ------------------------------ + drivers/pci/pci.h | 6 ------ + drivers/pci/setup-res.c | 13 +++++++------ + 4 files changed, 7 insertions(+), 60 deletions(-) + +diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c +index a6b100168396..2f8ea6f84c97 100644 +--- a/drivers/pci/iov.c ++++ b/drivers/pci/iov.c +@@ -555,24 +555,6 @@ void pci_iov_release(struct pci_dev *dev) + } + + /** +- * pci_iov_resource_bar - get position of the SR-IOV BAR +- * @dev: the PCI device +- * @resno: the resource number +- * +- * Returns position of the BAR encapsulated in the SR-IOV capability. +- */ +-int pci_iov_resource_bar(struct pci_dev *dev, int resno) +-{ +- if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END) +- return 0; +- +- BUG_ON(!dev->is_physfn); +- +- return dev->sriov->pos + PCI_SRIOV_BAR + +- 4 * (resno - PCI_IOV_RESOURCES); +-} +- +-/** + * pci_iov_update_resource - update a VF BAR + * @dev: the PCI device + * @resno: the resource number +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index e311a9bf2c90..a01e6d5fedec 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -4472,36 +4472,6 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags) + } + EXPORT_SYMBOL(pci_select_bars); + +-/** +- * pci_resource_bar - get position of the BAR associated with a resource +- * @dev: the PCI device +- * @resno: the resource number +- * @type: the BAR type to be filled in +- * +- * Returns BAR position in config space, or 0 if the BAR is invalid. +- */ +-int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) +-{ +- int reg; +- +- if (resno < PCI_ROM_RESOURCE) { +- *type = pci_bar_unknown; +- return PCI_BASE_ADDRESS_0 + 4 * resno; +- } else if (resno == PCI_ROM_RESOURCE) { +- *type = pci_bar_mem32; +- return dev->rom_base_reg; +- } else if (resno < PCI_BRIDGE_RESOURCES) { +- /* device specific resource */ +- *type = pci_bar_unknown; +- reg = pci_iov_resource_bar(dev, resno); +- if (reg) +- return reg; +- } +- +- dev_err(&dev->dev, "BAR %d: invalid resource\n", resno); +- return 0; +-} +- + /* Some architectures require additional programming to enable VGA */ + static arch_set_vga_state_t arch_set_vga_state; + +diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h +index eda77d1baec1..c43e448873ca 100644 +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -232,7 +232,6 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, + int pci_setup_device(struct pci_dev *dev); + int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, + struct resource *res, unsigned int reg); +-int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); + void pci_configure_ari(struct pci_dev *dev); + void __pci_bus_size_bridges(struct pci_bus *bus, + struct list_head *realloc_head); +@@ -276,7 +275,6 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) + #ifdef CONFIG_PCI_IOV + int pci_iov_init(struct pci_dev *dev); + void pci_iov_release(struct pci_dev *dev); +-int pci_iov_resource_bar(struct pci_dev *dev, int resno); + void pci_iov_update_resource(struct pci_dev *dev, int resno); + resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); + void pci_restore_iov_state(struct pci_dev *dev); +@@ -291,10 +289,6 @@ static inline void pci_iov_release(struct pci_dev *dev) + + { + } +-static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno) +-{ +- return 0; +-} + static inline void pci_restore_iov_state(struct pci_dev *dev) + { + } +diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c +index ac58c566fb1a..674e76c9334e 100644 +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -32,7 +32,6 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) + u16 cmd; + u32 new, check, mask; + int reg; +- enum pci_bar_type type; + struct resource *res = dev->resource + resno; + + if (dev->is_virtfn) { +@@ -66,14 +65,16 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) + else + mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; + +- reg = pci_resource_bar(dev, resno, &type); +- if (!reg) +- return; +- if (type != pci_bar_unknown) { ++ if (resno < PCI_ROM_RESOURCE) { ++ reg = PCI_BASE_ADDRESS_0 + 4 * resno; ++ } else if (resno == PCI_ROM_RESOURCE) { + if (!(res->flags & IORESOURCE_ROM_ENABLE)) + return; ++ ++ reg = dev->rom_base_reg; + new |= PCI_ROM_ADDRESS_ENABLE; +- } ++ } else ++ return; + + /* + * We can't update a 64-bit BAR atomically, so when possible, +-- +2.12.2 + +From 1278c9f87f1127b806a7733d3091df3ed2ab31c6 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:07 +0530 +Subject: [PATCH 194/251] PCI: Add comments about ROM BAR updating +Content-Length: 2629 +Lines: 68 + +From: Bjorn Helgaas + +[ Upstream commit 0b457dde3cf8b7c76a60f8e960f21bbd4abdc416 ] + +pci_update_resource() updates a hardware BAR so its address matches the +kernel's struct resource UNLESS it's a disabled ROM BAR. We only update +those when we enable the ROM. + +It's not obvious from the code why ROM BARs should be handled specially. +Apparently there are Matrox devices with defective ROM BARs that read as +zero when disabled. That means that if pci_enable_rom() reads the disabled +BAR, sets PCI_ROM_ADDRESS_ENABLE (without re-inserting the address), and +writes it back, it would enable the ROM at address zero. + +Add comments and references to explain why we can't make the code look more +rational. + +The code changes are from 755528c860b0 ("Ignore disabled ROM resources at +setup") and 8085ce084c0f ("[PATCH] Fix PCI ROM mapping"). + +Link: https://lkml.org/lkml/2005/8/30/138 +Signed-off-by: Bjorn Helgaas +Reviewed-by: Gavin Shan +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman + [sumits: minor fixup in rom.c for 4.4.y] +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/rom.c | 5 +++++ + drivers/pci/setup-res.c | 6 ++++++ + 2 files changed, 11 insertions(+) + +diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c +index eb0ad530dc43..3eea7fc5e1a2 100644 +--- a/drivers/pci/rom.c ++++ b/drivers/pci/rom.c +@@ -31,6 +31,11 @@ int pci_enable_rom(struct pci_dev *pdev) + if (!res->flags) + return -1; + ++ /* ++ * Ideally pci_update_resource() would update the ROM BAR address, ++ * and we would only set the enable bit here. But apparently some ++ * devices have buggy ROM BARs that read as zero when disabled. ++ */ + pcibios_resource_to_bus(pdev->bus, ®ion, res); + pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); + rom_addr &= ~PCI_ROM_ADDRESS_MASK; +diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c +index 674e76c9334e..d1ba5e0067c5 100644 +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -68,6 +68,12 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) + if (resno < PCI_ROM_RESOURCE) { + reg = PCI_BASE_ADDRESS_0 + 4 * resno; + } else if (resno == PCI_ROM_RESOURCE) { ++ ++ /* ++ * Apparently some Matrox devices have ROM BARs that read ++ * as zero when disabled, so don't update ROM BARs unless ++ * they're enabled. See https://lkml.org/lkml/2005/8/30/138. ++ */ + if (!(res->flags & IORESOURCE_ROM_ENABLE)) + return; + +-- +2.12.2 + +From 40a85d68185f9d9e7d370919f8a3532b0d259266 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:08 +0530 +Subject: [PATCH 195/251] PCI: Decouple IORESOURCE_ROM_ENABLE and + PCI_ROM_ADDRESS_ENABLE +Content-Length: 1362 +Lines: 35 + +From: Bjorn Helgaas + +[ Upstream commit 7a6d312b50e63f598f5b5914c4fd21878ac2b595 ] + +Remove the assumption that IORESOURCE_ROM_ENABLE == PCI_ROM_ADDRESS_ENABLE. +PCI_ROM_ADDRESS_ENABLE is the ROM enable bit defined by the PCI spec, so if +we're reading or writing a BAR register value, that's what we should use. +IORESOURCE_ROM_ENABLE is a corresponding bit in struct resource flags. + +Signed-off-by: Bjorn Helgaas +Reviewed-by: Gavin Shan +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/probe.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c +index 71d9a6d1bd56..b83df942794f 100644 +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -226,7 +226,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, + mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK; + } + } else { +- res->flags |= (l & IORESOURCE_ROM_ENABLE); ++ if (l & PCI_ROM_ADDRESS_ENABLE) ++ res->flags |= IORESOURCE_ROM_ENABLE; + l64 = l & PCI_ROM_ADDRESS_MASK; + sz64 = sz & PCI_ROM_ADDRESS_MASK; + mask64 = (u32)PCI_ROM_ADDRESS_MASK; +-- +2.12.2 + +From 131f7969048b8ede0be57f64930e9ef8fee0c53b Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:09 +0530 +Subject: [PATCH 196/251] PCI: Don't update VF BARs while VF memory space is + enabled +Content-Length: 1908 +Lines: 55 + +From: Bjorn Helgaas + +[ Upstream commit 546ba9f8f22f71b0202b6ba8967be5cc6dae4e21 ] + +If we update a VF BAR while it's enabled, there are two potential problems: + + 1) Any driver that's using the VF has a cached BAR value that is stale + after the update, and + + 2) We can't update 64-bit BARs atomically, so the intermediate state + (new lower dword with old upper dword) may conflict with another + device, and an access by a driver unrelated to the VF may cause a bus + error. + +Warn about attempts to update VF BARs while they are enabled. This is a +programming error, so use dev_WARN() to get a backtrace. + +Signed-off-by: Bjorn Helgaas +Reviewed-by: Gavin Shan +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/iov.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c +index 2f8ea6f84c97..47c46d07f110 100644 +--- a/drivers/pci/iov.c ++++ b/drivers/pci/iov.c +@@ -567,6 +567,7 @@ void pci_iov_update_resource(struct pci_dev *dev, int resno) + struct resource *res = dev->resource + resno; + int vf_bar = resno - PCI_IOV_RESOURCES; + struct pci_bus_region region; ++ u16 cmd; + u32 new; + int reg; + +@@ -578,6 +579,13 @@ void pci_iov_update_resource(struct pci_dev *dev, int resno) + if (!iov) + return; + ++ pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &cmd); ++ if ((cmd & PCI_SRIOV_CTRL_VFE) && (cmd & PCI_SRIOV_CTRL_MSE)) { ++ dev_WARN(&dev->dev, "can't update enabled VF BAR%d %pR\n", ++ vf_bar, res); ++ return; ++ } ++ + /* + * Ignore unimplemented BARs, unused resource slots for 64-bit + * BARs, and non-movable resources, e.g., those described via +-- +2.12.2 + +From d4f09ea7e35c02a765f58e900fbc159ff00c70e2 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:10 +0530 +Subject: [PATCH 197/251] PCI: Update BARs using property bits appropriate for + type +Content-Length: 1846 +Lines: 52 + +From: Bjorn Helgaas + +[ Upstream commit 45d004f4afefdd8d79916ee6d97a9ecd94bb1ffe ] + +The BAR property bits (0-3 for memory BARs, 0-1 for I/O BARs) are supposed +to be read-only, but we do save them in res->flags and include them when +updating the BAR. + +Mask the I/O property bits with ~PCI_BASE_ADDRESS_IO_MASK (0x3) instead of +PCI_REGION_FLAG_MASK (0xf) to make it obvious that we can't corrupt bits +2-3 of I/O addresses. + +Use PCI_ROM_ADDRESS_MASK for ROM BARs. This means we'll only check the top +21 bits (instead of the 28 bits we used to check) of a ROM BAR to see if +the update was successful. + +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/setup-res.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c +index d1ba5e0067c5..032a6b1ea512 100644 +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -58,12 +58,17 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) + return; + + pcibios_resource_to_bus(dev->bus, ®ion, res); ++ new = region.start; + +- new = region.start | (res->flags & PCI_REGION_FLAG_MASK); +- if (res->flags & IORESOURCE_IO) ++ if (res->flags & IORESOURCE_IO) { + mask = (u32)PCI_BASE_ADDRESS_IO_MASK; +- else ++ new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK; ++ } else if (resno == PCI_ROM_RESOURCE) { ++ mask = (u32)PCI_ROM_ADDRESS_MASK; ++ } else { + mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; ++ new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; ++ } + + if (resno < PCI_ROM_RESOURCE) { + reg = PCI_BASE_ADDRESS_0 + 4 * resno; +-- +2.12.2 + +From bcbdcf48469b062b6ee00b560b44de28f387d2e0 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:11 +0530 +Subject: [PATCH 198/251] PCI: Ignore BAR updates on virtual functions +Content-Length: 1848 +Lines: 56 + +From: Bjorn Helgaas + +[ Upstream commit 63880b230a4af502c56dde3d4588634c70c66006 ] + +VF BARs are read-only zero, so updating VF BARs will not have any effect. +See the SR-IOV spec r1.1, sec 3.4.1.11. + +We already ignore these updates because of 70675e0b6a1a ("PCI: Don't try to +restore VF BARs"); this merely restructures it slightly to make it easier +to split updates for standard and SR-IOV BARs. + +Signed-off-by: Bjorn Helgaas +Reviewed-by: Gavin Shan +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci.c | 4 ---- + drivers/pci/setup-res.c | 5 ++--- + 2 files changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index a01e6d5fedec..0e53488f8ec1 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -519,10 +519,6 @@ static void pci_restore_bars(struct pci_dev *dev) + { + int i; + +- /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */ +- if (dev->is_virtfn) +- return; +- + for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) + pci_update_resource(dev, i); + } +diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c +index 032a6b1ea512..25062966cbfa 100644 +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -34,10 +34,9 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) + int reg; + struct resource *res = dev->resource + resno; + +- if (dev->is_virtfn) { +- dev_warn(&dev->dev, "can't update VF BAR%d\n", resno); ++ /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */ ++ if (dev->is_virtfn) + return; +- } + + /* + * Ignore resources for unimplemented BARs and unused resource slots +-- +2.12.2 + +From 4110080574acd69677c869ba49207150c09c9c0f Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:12 +0530 +Subject: [PATCH 199/251] PCI: Do any VF BAR updates before enabling the BARs +Content-Length: 2118 +Lines: 63 + +From: Gavin Shan + +[ Upstream commit f40ec3c748c6912f6266c56a7f7992de61b255ed ] + +Previously we enabled VFs and enable their memory space before calling +pcibios_sriov_enable(). But pcibios_sriov_enable() may update the VF BARs: +for example, on PPC PowerNV we may change them to manage the association of +VFs to PEs. + +Because 64-bit BARs cannot be updated atomically, it's unsafe to update +them while they're enabled. The half-updated state may conflict with other +devices in the system. + +Call pcibios_sriov_enable() before enabling the VFs so any BAR updates +happen while the VF BARs are disabled. + +[bhelgaas: changelog] +Tested-by: Carol Soto +Signed-off-by: Gavin Shan +Signed-off-by: Bjorn Helgaas + +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/iov.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c +index 47c46d07f110..357527712539 100644 +--- a/drivers/pci/iov.c ++++ b/drivers/pci/iov.c +@@ -303,13 +303,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) + return rc; + } + +- pci_iov_set_numvfs(dev, nr_virtfn); +- iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; +- pci_cfg_access_lock(dev); +- pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); +- msleep(100); +- pci_cfg_access_unlock(dev); +- + iov->initial_VFs = initial; + if (nr_virtfn < initial) + initial = nr_virtfn; +@@ -320,6 +313,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) + goto err_pcibios; + } + ++ pci_iov_set_numvfs(dev, nr_virtfn); ++ iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; ++ pci_cfg_access_lock(dev); ++ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); ++ msleep(100); ++ pci_cfg_access_unlock(dev); ++ + for (i = 0; i < initial; i++) { + rc = virtfn_add(dev, i, 0); + if (rc) +-- +2.12.2 + +From 9fd9e1436380419a9a74f7ad90d85e09b1ed8058 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:13 +0530 +Subject: [PATCH 200/251] vfio/spapr: Postpone allocation of userspace version + of TCE table +Content-Length: 2738 +Lines: 78 + +From: Alexey Kardashevskiy + +[ Upstream commit 39701e56f5f16ea0cf8fc9e8472e645f8de91d23 ] + +The iommu_table struct manages a hardware TCE table and a vmalloc'd +table with corresponding userspace addresses. Both are allocated when +the default DMA window is created and this happens when the very first +group is attached to a container. + +As we are going to allow the userspace to configure container in one +memory context and pas container fd to another, we have to postpones +such allocations till a container fd is passed to the destination +user process so we would account locked memory limit against the actual +container user constrainsts. + +This postpones the it_userspace array allocation till it is used first +time for mapping. The unmapping patch already checks if the array is +allocated. + +Signed-off-by: Alexey Kardashevskiy +Reviewed-by: David Gibson +Acked-by: Alex Williamson +Signed-off-by: Michael Ellerman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vfio/vfio_iommu_spapr_tce.c | 20 +++++++------------- + 1 file changed, 7 insertions(+), 13 deletions(-) + +diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c +index 0582b72ef377..1a9f18b40be6 100644 +--- a/drivers/vfio/vfio_iommu_spapr_tce.c ++++ b/drivers/vfio/vfio_iommu_spapr_tce.c +@@ -511,6 +511,12 @@ static long tce_iommu_build_v2(struct tce_container *container, + unsigned long hpa; + enum dma_data_direction dirtmp; + ++ if (!tbl->it_userspace) { ++ ret = tce_iommu_userspace_view_alloc(tbl); ++ if (ret) ++ return ret; ++ } ++ + for (i = 0; i < pages; ++i) { + struct mm_iommu_table_group_mem_t *mem = NULL; + unsigned long *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl, +@@ -584,15 +590,6 @@ static long tce_iommu_create_table(struct tce_container *container, + WARN_ON(!ret && !(*ptbl)->it_ops->free); + WARN_ON(!ret && ((*ptbl)->it_allocated_size != table_size)); + +- if (!ret && container->v2) { +- ret = tce_iommu_userspace_view_alloc(*ptbl); +- if (ret) +- (*ptbl)->it_ops->free(*ptbl); +- } +- +- if (ret) +- decrement_locked_vm(table_size >> PAGE_SHIFT); +- + return ret; + } + +@@ -1064,10 +1061,7 @@ static int tce_iommu_take_ownership(struct tce_container *container, + if (!tbl || !tbl->it_map) + continue; + +- rc = tce_iommu_userspace_view_alloc(tbl); +- if (!rc) +- rc = iommu_take_ownership(tbl); +- ++ rc = iommu_take_ownership(tbl); + if (rc) { + for (j = 0; j < i; ++j) + iommu_release_ownership( +-- +2.12.2 + +From 7023f502c8355717ad4e400144b0833dee105602 Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:14 +0530 +Subject: [PATCH 201/251] block: allow WRITE_SAME commands with the SG_IO ioctl +Content-Length: 3332 +Lines: 80 + +From: Mauricio Faria de Oliveira + +[ Upstream commit 25cdb64510644f3e854d502d69c73f21c6df88a9 ] + +The WRITE_SAME commands are not present in the blk_default_cmd_filter +write_ok list, and thus are failed with -EPERM when the SG_IO ioctl() +is executed without CAP_SYS_RAWIO capability (e.g., unprivileged users). +[ sg_io() -> blk_fill_sghdr_rq() > blk_verify_command() -> -EPERM ] + +The problem can be reproduced with the sg_write_same command + + # sg_write_same --num 1 --xferlen 512 /dev/sda + # + + # capsh --drop=cap_sys_rawio -- -c \ + 'sg_write_same --num 1 --xferlen 512 /dev/sda' + Write same: pass through os error: Operation not permitted + # + +For comparison, the WRITE_VERIFY command does not observe this problem, +since it is in that list: + + # capsh --drop=cap_sys_rawio -- -c \ + 'sg_write_verify --num 1 --ilen 512 --lba 0 /dev/sda' + # + +So, this patch adds the WRITE_SAME commands to the list, in order +for the SG_IO ioctl to finish successfully: + + # capsh --drop=cap_sys_rawio -- -c \ + 'sg_write_same --num 1 --xferlen 512 /dev/sda' + # + +That case happens to be exercised by QEMU KVM guests with 'scsi-block' devices +(qemu "-device scsi-block" [1], libvirt "" [2]), +which employs the SG_IO ioctl() and runs as an unprivileged user (libvirt-qemu). + +In that scenario, when a filesystem (e.g., ext4) performs its zero-out calls, +which are translated to write-same calls in the guest kernel, and then into +SG_IO ioctls to the host kernel, SCSI I/O errors may be observed in the guest: + + [...] sd 0:0:0:0: [sda] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE + [...] sd 0:0:0:0: [sda] tag#0 Sense Key : Aborted Command [current] + [...] sd 0:0:0:0: [sda] tag#0 Add. Sense: I/O process terminated + [...] sd 0:0:0:0: [sda] tag#0 CDB: Write Same(10) 41 00 01 04 e0 78 00 00 08 00 + [...] blk_update_request: I/O error, dev sda, sector 17096824 + +Links: +[1] http://git.qemu.org/?p=qemu.git;a=commit;h=336a6915bc7089fb20fea4ba99972ad9a97c5f52 +[2] https://libvirt.org/formatdomain.html#elementsDisks (see 'disk' -> 'device') + +Signed-off-by: Mauricio Faria de Oliveira +Signed-off-by: Brahadambal Srinivasan +Reported-by: Manjunatha H R +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + block/scsi_ioctl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c +index 0774799942e0..c6fee7437be4 100644 +--- a/block/scsi_ioctl.c ++++ b/block/scsi_ioctl.c +@@ -182,6 +182,9 @@ static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) + __set_bit(WRITE_16, filter->write_ok); + __set_bit(WRITE_LONG, filter->write_ok); + __set_bit(WRITE_LONG_2, filter->write_ok); ++ __set_bit(WRITE_SAME, filter->write_ok); ++ __set_bit(WRITE_SAME_16, filter->write_ok); ++ __set_bit(WRITE_SAME_32, filter->write_ok); + __set_bit(ERASE, filter->write_ok); + __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok); + __set_bit(MODE_SELECT, filter->write_ok); +-- +2.12.2 + +From ce5494107946450f79ffce4538c243c37b08d85f Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:15 +0530 +Subject: [PATCH 202/251] s390/zcrypt: Introduce CEX6 toleration +Content-Length: 1646 +Lines: 43 + +From: Harald Freudenberger + +[ Upstream commit b3e8652bcbfa04807e44708d4d0c8cdad39c9215 ] + +Signed-off-by: Harald Freudenberger +Signed-off-by: Martin Schwidefsky +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/s390/crypto/ap_bus.c | 3 +++ + drivers/s390/crypto/ap_bus.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index 24ec282e15d8..7c3b8d3516e3 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -1651,6 +1651,9 @@ static void ap_scan_bus(struct work_struct *unused) + ap_dev->queue_depth = queue_depth; + ap_dev->raw_hwtype = device_type; + ap_dev->device_type = device_type; ++ /* CEX6 toleration: map to CEX5 */ ++ if (device_type == AP_DEVICE_TYPE_CEX6) ++ ap_dev->device_type = AP_DEVICE_TYPE_CEX5; + ap_dev->functions = device_functions; + spin_lock_init(&ap_dev->lock); + INIT_LIST_HEAD(&ap_dev->pendingq); +diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h +index 6adcbdf225d1..cc741e948170 100644 +--- a/drivers/s390/crypto/ap_bus.h ++++ b/drivers/s390/crypto/ap_bus.h +@@ -105,6 +105,7 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr) + #define AP_DEVICE_TYPE_CEX3C 9 + #define AP_DEVICE_TYPE_CEX4 10 + #define AP_DEVICE_TYPE_CEX5 11 ++#define AP_DEVICE_TYPE_CEX6 12 + + /* + * Known function facilities +-- +2.12.2 + +From 4e2c66bb6658f6f4583c8920adeecb7bcc90bd9f Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:16 +0530 +Subject: [PATCH 203/251] uvcvideo: uvc_scan_fallback() for webcams with broken + chain +Content-Length: 5053 +Lines: 172 + +From: Henrik Ingo + +[ Upstream commit e950267ab802c8558f1100eafd4087fd039ad634 ] + +Some devices have invalid baSourceID references, causing uvc_scan_chain() +to fail, but if we just take the entities we can find and put them +together in the most sensible chain we can think of, turns out they do +work anyway. Note: This heuristic assumes there is a single chain. + +At the time of writing, devices known to have such a broken chain are + - Acer Integrated Camera (5986:055a) + - Realtek rtl157a7 (0bda:57a7) + +Signed-off-by: Henrik Ingo +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/uvc/uvc_driver.c | 118 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 112 insertions(+), 6 deletions(-) + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 5cefca95734e..885f689ac870 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -1595,6 +1595,114 @@ static const char *uvc_print_chain(struct uvc_video_chain *chain) + return buffer; + } + ++static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev) ++{ ++ struct uvc_video_chain *chain; ++ ++ chain = kzalloc(sizeof(*chain), GFP_KERNEL); ++ if (chain == NULL) ++ return NULL; ++ ++ INIT_LIST_HEAD(&chain->entities); ++ mutex_init(&chain->ctrl_mutex); ++ chain->dev = dev; ++ v4l2_prio_init(&chain->prio); ++ ++ return chain; ++} ++ ++/* ++ * Fallback heuristic for devices that don't connect units and terminals in a ++ * valid chain. ++ * ++ * Some devices have invalid baSourceID references, causing uvc_scan_chain() ++ * to fail, but if we just take the entities we can find and put them together ++ * in the most sensible chain we can think of, turns out they do work anyway. ++ * Note: This heuristic assumes there is a single chain. ++ * ++ * At the time of writing, devices known to have such a broken chain are ++ * - Acer Integrated Camera (5986:055a) ++ * - Realtek rtl157a7 (0bda:57a7) ++ */ ++static int uvc_scan_fallback(struct uvc_device *dev) ++{ ++ struct uvc_video_chain *chain; ++ struct uvc_entity *iterm = NULL; ++ struct uvc_entity *oterm = NULL; ++ struct uvc_entity *entity; ++ struct uvc_entity *prev; ++ ++ /* ++ * Start by locating the input and output terminals. We only support ++ * devices with exactly one of each for now. ++ */ ++ list_for_each_entry(entity, &dev->entities, list) { ++ if (UVC_ENTITY_IS_ITERM(entity)) { ++ if (iterm) ++ return -EINVAL; ++ iterm = entity; ++ } ++ ++ if (UVC_ENTITY_IS_OTERM(entity)) { ++ if (oterm) ++ return -EINVAL; ++ oterm = entity; ++ } ++ } ++ ++ if (iterm == NULL || oterm == NULL) ++ return -EINVAL; ++ ++ /* Allocate the chain and fill it. */ ++ chain = uvc_alloc_chain(dev); ++ if (chain == NULL) ++ return -ENOMEM; ++ ++ if (uvc_scan_chain_entity(chain, oterm) < 0) ++ goto error; ++ ++ prev = oterm; ++ ++ /* ++ * Add all Processing and Extension Units with two pads. The order ++ * doesn't matter much, use reverse list traversal to connect units in ++ * UVC descriptor order as we build the chain from output to input. This ++ * leads to units appearing in the order meant by the manufacturer for ++ * the cameras known to require this heuristic. ++ */ ++ list_for_each_entry_reverse(entity, &dev->entities, list) { ++ if (entity->type != UVC_VC_PROCESSING_UNIT && ++ entity->type != UVC_VC_EXTENSION_UNIT) ++ continue; ++ ++ if (entity->num_pads != 2) ++ continue; ++ ++ if (uvc_scan_chain_entity(chain, entity) < 0) ++ goto error; ++ ++ prev->baSourceID[0] = entity->id; ++ prev = entity; ++ } ++ ++ if (uvc_scan_chain_entity(chain, iterm) < 0) ++ goto error; ++ ++ prev->baSourceID[0] = iterm->id; ++ ++ list_add_tail(&chain->list, &dev->chains); ++ ++ uvc_trace(UVC_TRACE_PROBE, ++ "Found a video chain by fallback heuristic (%s).\n", ++ uvc_print_chain(chain)); ++ ++ return 0; ++ ++error: ++ kfree(chain); ++ return -EINVAL; ++} ++ + /* + * Scan the device for video chains and register video devices. + * +@@ -1617,15 +1725,10 @@ static int uvc_scan_device(struct uvc_device *dev) + if (term->chain.next || term->chain.prev) + continue; + +- chain = kzalloc(sizeof(*chain), GFP_KERNEL); ++ chain = uvc_alloc_chain(dev); + if (chain == NULL) + return -ENOMEM; + +- INIT_LIST_HEAD(&chain->entities); +- mutex_init(&chain->ctrl_mutex); +- chain->dev = dev; +- v4l2_prio_init(&chain->prio); +- + term->flags |= UVC_ENTITY_FLAG_DEFAULT; + + if (uvc_scan_chain(chain, term) < 0) { +@@ -1639,6 +1742,9 @@ static int uvc_scan_device(struct uvc_device *dev) + list_add_tail(&chain->list, &dev->chains); + } + ++ if (list_empty(&dev->chains)) ++ uvc_scan_fallback(dev); ++ + if (list_empty(&dev->chains)) { + uvc_printk(KERN_INFO, "No valid video chain found.\n"); + return -1; +-- +2.12.2 + +From d3607fc2976e34f6b067508b608fefaa66fbecee Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:17 +0530 +Subject: [PATCH 204/251] ACPI / blacklist: add _REV quirks for Dell Precision + 5520 and 3520 +Content-Length: 1499 +Lines: 50 + +From: Alex Hung + +[ Upstream commit 9523b9bf6dceef6b0215e90b2348cd646597f796 ] + +Precision 5520 and 3520 either hang at login and during suspend or reboot. + +It turns out that that adding them to acpi_rev_dmi_table[] helps to work +around those issues. + +Signed-off-by: Alex Hung +[ rjw: Changelog ] +Signed-off-by: Rafael J. Wysocki + +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/blacklist.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c +index 96809cd99ace..b2e9395e095c 100644 +--- a/drivers/acpi/blacklist.c ++++ b/drivers/acpi/blacklist.c +@@ -346,6 +346,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { + DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"), + }, + }, ++ { ++ .callback = dmi_enable_rev_override, ++ .ident = "DELL Precision 5520", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5520"), ++ }, ++ }, ++ { ++ .callback = dmi_enable_rev_override, ++ .ident = "DELL Precision 3520", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520"), ++ }, ++ }, + #endif + {} + }; +-- +2.12.2 + +From b8687d83b34cf372b943c5639d8960703aeb2b8e Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:18 +0530 +Subject: [PATCH 205/251] ACPI / blacklist: Make Dell Latitude 3350 ethernet + work +Content-Length: 1438 +Lines: 46 + +From: Michael Pobega + +[ Upstream commit 708f5dcc21ae9b35f395865fc154b0105baf4de4 ] + +The Dell Latitude 3350's ethernet card attempts to use a reserved +IRQ (18), resulting in ACPI being unable to enable the ethernet. + +Adding it to acpi_rev_dmi_table[] helps to work around this problem. + +Signed-off-by: Michael Pobega +[ rjw: Changelog ] +Signed-off-by: Rafael J. Wysocki + +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/blacklist.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c +index b2e9395e095c..2f24b578bcaf 100644 +--- a/drivers/acpi/blacklist.c ++++ b/drivers/acpi/blacklist.c +@@ -362,6 +362,18 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { + DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520"), + }, + }, ++ /* ++ * Resolves a quirk with the Dell Latitude 3350 that ++ * causes the ethernet adapter to not function. ++ */ ++ { ++ .callback = dmi_enable_rev_override, ++ .ident = "DELL Latitude 3350", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350"), ++ }, ++ }, + #endif + {} + }; +-- +2.12.2 + +From ac601978a2aad7fbb617f0187268011b577a127f Mon Sep 17 00:00:00 2001 +From: Sumit Semwal +Date: Sat, 25 Mar 2017 21:48:19 +0530 +Subject: [PATCH 206/251] serial: 8250_pci: Detach low-level driver during PCI + error recovery +Content-Length: 3500 +Lines: 106 + +From: Gabriel Krisman Bertazi + +[ Upstream commit f209fa03fc9d131b3108c2e4936181eabab87416 ] + +During a PCI error recovery, like the ones provoked by EEH in the ppc64 +platform, all IO to the device must be blocked while the recovery is +completed. Current 8250_pci implementation only suspends the port +instead of detaching it, which doesn't prevent incoming accesses like +TIOCMGET and TIOCMSET calls from reaching the device. Those end up +racing with the EEH recovery, crashing it. Similar races were also +observed when opening the device and when shutting it down during +recovery. + +This patch implements a more robust IO blockage for the 8250_pci +recovery by unregistering the port at the beginning of the procedure and +re-adding it afterwards. Since the port is detached from the uart +layer, we can be sure that no request will make through to the device +during recovery. This is similar to the solution used by the JSM serial +driver. + +I thank Peter Hurley for valuable input on +this one over one year ago. + +Signed-off-by: Gabriel Krisman Bertazi +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250_pci.c | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 5b24ffd93649..83ff1724ec79 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -57,6 +57,7 @@ struct serial_private { + unsigned int nr; + void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES]; + struct pci_serial_quirk *quirk; ++ const struct pciserial_board *board; + int line[0]; + }; + +@@ -4058,6 +4059,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) + } + } + priv->nr = i; ++ priv->board = board; + return priv; + + err_deinit: +@@ -4068,7 +4070,7 @@ err_out: + } + EXPORT_SYMBOL_GPL(pciserial_init_ports); + +-void pciserial_remove_ports(struct serial_private *priv) ++void pciserial_detach_ports(struct serial_private *priv) + { + struct pci_serial_quirk *quirk; + int i; +@@ -4088,7 +4090,11 @@ void pciserial_remove_ports(struct serial_private *priv) + quirk = find_quirk(priv->dev); + if (quirk->exit) + quirk->exit(priv->dev); ++} + ++void pciserial_remove_ports(struct serial_private *priv) ++{ ++ pciserial_detach_ports(priv); + kfree(priv); + } + EXPORT_SYMBOL_GPL(pciserial_remove_ports); +@@ -5819,7 +5825,7 @@ static pci_ers_result_t serial8250_io_error_detected(struct pci_dev *dev, + return PCI_ERS_RESULT_DISCONNECT; + + if (priv) +- pciserial_suspend_ports(priv); ++ pciserial_detach_ports(priv); + + pci_disable_device(dev); + +@@ -5844,9 +5850,18 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) + static void serial8250_io_resume(struct pci_dev *dev) + { + struct serial_private *priv = pci_get_drvdata(dev); ++ const struct pciserial_board *board; + +- if (priv) +- pciserial_resume_ports(priv); ++ if (!priv) ++ return; ++ ++ board = priv->board; ++ kfree(priv); ++ priv = pciserial_init_ports(dev, board); ++ ++ if (!IS_ERR(priv)) { ++ pci_set_drvdata(dev, priv); ++ } + } + + static const struct pci_error_handlers serial8250_err_handler = { +-- +2.12.2 + +From 540d6d756ff82a23eb5bb73aa8149bab15eb407a Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 11 Jan 2017 17:09:50 +0100 +Subject: [PATCH 207/251] fbcon: Fix vc attr at deinit +Content-Length: 4857 +Lines: 144 + +commit 8aac7f34369726d1a158788ae8aff3002d5eb528 upstream. + +fbcon can deal with vc_hi_font_mask (the upper 256 chars) and adjust +the vc attrs dynamically when vc_hi_font_mask is changed at +fbcon_init(). When the vc_hi_font_mask is set, it remaps the attrs in +the existing console buffer with one bit shift up (for 9 bits), while +it remaps with one bit shift down (for 8 bits) when the value is +cleared. It works fine as long as the font gets updated after fbcon +was initialized. + +However, we hit a bizarre problem when the console is switched to +another fb driver (typically from vesafb or efifb to drmfb). At +switching to the new fb driver, we temporarily rebind the console to +the dummy console, then rebind to the new driver. During the +switching, we leave the modified attrs as is. Thus, the new fbcon +takes over the old buffer as if it were to contain 8 bits chars +(although the attrs are still shifted for 9 bits), and effectively +this results in the yellow color texts instead of the original white +color, as found in the bugzilla entry below. + +An easy fix for this is to re-adjust the attrs before leaving the +fbcon at con_deinit callback. Since the code to adjust the attrs is +already present in the current fbcon code, in this patch, we simply +factor out the relevant code, and call it from fbcon_deinit(). + +Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000619 +Signed-off-by: Takashi Iwai +Signed-off-by: Bartlomiej Zolnierkiewicz +Cc: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman +--- + drivers/video/console/fbcon.c | 67 ++++++++++++++++++++++++++----------------- + 1 file changed, 40 insertions(+), 27 deletions(-) + +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c +index 6e92917ba77a..4e3c78d88832 100644 +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -1168,6 +1168,8 @@ static void fbcon_free_font(struct display *p, bool freefont) + p->userfont = 0; + } + ++static void set_vc_hi_font(struct vc_data *vc, bool set); ++ + static void fbcon_deinit(struct vc_data *vc) + { + struct display *p = &fb_display[vc->vc_num]; +@@ -1203,6 +1205,9 @@ finished: + if (free_font) + vc->vc_font.data = NULL; + ++ if (vc->vc_hi_font_mask) ++ set_vc_hi_font(vc, false); ++ + if (!con_is_bound(&fb_con)) + fbcon_exit(); + +@@ -2439,32 +2444,10 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font) + return 0; + } + +-static int fbcon_do_set_font(struct vc_data *vc, int w, int h, +- const u8 * data, int userfont) ++/* set/clear vc_hi_font_mask and update vc attrs accordingly */ ++static void set_vc_hi_font(struct vc_data *vc, bool set) + { +- struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; +- struct fbcon_ops *ops = info->fbcon_par; +- struct display *p = &fb_display[vc->vc_num]; +- int resize; +- int cnt; +- char *old_data = NULL; +- +- if (CON_IS_VISIBLE(vc) && softback_lines) +- fbcon_set_origin(vc); +- +- resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); +- if (p->userfont) +- old_data = vc->vc_font.data; +- if (userfont) +- cnt = FNTCHARCNT(data); +- else +- cnt = 256; +- vc->vc_font.data = (void *)(p->fontdata = data); +- if ((p->userfont = userfont)) +- REFCOUNT(data)++; +- vc->vc_font.width = w; +- vc->vc_font.height = h; +- if (vc->vc_hi_font_mask && cnt == 256) { ++ if (!set) { + vc->vc_hi_font_mask = 0; + if (vc->vc_can_do_color) { + vc->vc_complement_mask >>= 1; +@@ -2487,7 +2470,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, + ((c & 0xfe00) >> 1) | (c & 0xff); + vc->vc_attr >>= 1; + } +- } else if (!vc->vc_hi_font_mask && cnt == 512) { ++ } else { + vc->vc_hi_font_mask = 0x100; + if (vc->vc_can_do_color) { + vc->vc_complement_mask <<= 1; +@@ -2519,8 +2502,38 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, + } else + vc->vc_video_erase_char = c & ~0x100; + } +- + } ++} ++ ++static int fbcon_do_set_font(struct vc_data *vc, int w, int h, ++ const u8 * data, int userfont) ++{ ++ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; ++ struct fbcon_ops *ops = info->fbcon_par; ++ struct display *p = &fb_display[vc->vc_num]; ++ int resize; ++ int cnt; ++ char *old_data = NULL; ++ ++ if (CON_IS_VISIBLE(vc) && softback_lines) ++ fbcon_set_origin(vc); ++ ++ resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); ++ if (p->userfont) ++ old_data = vc->vc_font.data; ++ if (userfont) ++ cnt = FNTCHARCNT(data); ++ else ++ cnt = 256; ++ vc->vc_font.data = (void *)(p->fontdata = data); ++ if ((p->userfont = userfont)) ++ REFCOUNT(data)++; ++ vc->vc_font.width = w; ++ vc->vc_font.height = h; ++ if (vc->vc_hi_font_mask && cnt == 256) ++ set_vc_hi_font(vc, false); ++ else if (!vc->vc_hi_font_mask && cnt == 512) ++ set_vc_hi_font(vc, true); + + if (resize) { + int cols, rows; +-- +2.12.2 + +From f8a62dbc790239d9cb8bb8757f43a9d2e09f747c Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Thu, 15 Dec 2016 14:31:01 +0100 +Subject: [PATCH 208/251] crypto: algif_hash - avoid zero-sized array +Content-Length: 2519 +Lines: 67 + +commit 6207119444595d287b1e9e83a2066c17209698f3 upstream. + +With this reproducer: + struct sockaddr_alg alg = { + .salg_family = 0x26, + .salg_type = "hash", + .salg_feat = 0xf, + .salg_mask = 0x5, + .salg_name = "digest_null", + }; + int sock, sock2; + + sock = socket(AF_ALG, SOCK_SEQPACKET, 0); + bind(sock, (struct sockaddr *)&alg, sizeof(alg)); + sock2 = accept(sock, NULL, NULL); + setsockopt(sock, SOL_ALG, ALG_SET_KEY, "\x9b\xca", 2); + accept(sock2, NULL, NULL); + +==== 8< ======== 8< ======== 8< ======== 8< ==== + +one can immediatelly see an UBSAN warning: +UBSAN: Undefined behaviour in crypto/algif_hash.c:187:7 +variable length array bound value 0 <= 0 +CPU: 0 PID: 15949 Comm: syz-executor Tainted: G E 4.4.30-0-default #1 +... +Call Trace: +... + [] ? __ubsan_handle_vla_bound_not_positive+0x13d/0x188 + [] ? __ubsan_handle_out_of_bounds+0x1bc/0x1bc + [] ? hash_accept+0x5bd/0x7d0 [algif_hash] + [] ? hash_accept_nokey+0x3f/0x51 [algif_hash] + [] ? hash_accept_parent_nokey+0x4a0/0x4a0 [algif_hash] + [] ? SyS_accept+0x2b/0x40 + +It is a correct warning, as hash state is propagated to accept as zero, +but creating a zero-length variable array is not allowed in C. + +Fix this as proposed by Herbert -- do "?: 1" on that site. No sizeof or +similar happens in the code there, so we just allocate one byte even +though we do not use the array. + +Signed-off-by: Jiri Slaby +Cc: Herbert Xu +Cc: "David S. Miller" (maintainer:CRYPTO API) +Reported-by: Sasha Levin +Signed-off-by: Herbert Xu +Cc: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman +--- + crypto/algif_hash.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c +index 68a5ceaa04c8..8d8b3eeba725 100644 +--- a/crypto/algif_hash.c ++++ b/crypto/algif_hash.c +@@ -184,7 +184,7 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags) + struct alg_sock *ask = alg_sk(sk); + struct hash_ctx *ctx = ask->private; + struct ahash_request *req = &ctx->req; +- char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req))]; ++ char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req)) ? : 1]; + struct sock *sk2; + struct alg_sock *ask2; + struct hash_ctx *ctx2; +-- +2.12.2 + +From 0a5766a6a73b1eb6a0dfa74adc40272e555ac2f0 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 30 Mar 2017 09:36:33 +0200 +Subject: [PATCH 209/251] Linux 4.4.58 +Content-Length: 301 +Lines: 18 + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 841675e63a38..3efe2ea99e2d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 57 ++SUBLEVEL = 58 + EXTRAVERSION = + NAME = Blurry Fish Butt + +-- +2.12.2 + +From a9a76a3e318ea559365210916378380109199121 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Wed, 8 Feb 2017 11:52:29 +0100 +Subject: [PATCH 210/251] xfrm: policy: init locks early +Content-Length: 2241 +Lines: 62 + +commit c282222a45cb9503cbfbebfdb60491f06ae84b49 upstream. + +Dmitry reports following splat: + INFO: trying to register non-static key. + the code is fine but needs lockdep annotation. + turning off the locking correctness validator. + CPU: 0 PID: 13059 Comm: syz-executor1 Not tainted 4.10.0-rc7-next-20170207 #1 +[..] + spin_lock_bh include/linux/spinlock.h:304 [inline] + xfrm_policy_flush+0x32/0x470 net/xfrm/xfrm_policy.c:963 + xfrm_policy_fini+0xbf/0x560 net/xfrm/xfrm_policy.c:3041 + xfrm_net_init+0x79f/0x9e0 net/xfrm/xfrm_policy.c:3091 + ops_init+0x10a/0x530 net/core/net_namespace.c:115 + setup_net+0x2ed/0x690 net/core/net_namespace.c:291 + copy_net_ns+0x26c/0x530 net/core/net_namespace.c:396 + create_new_namespaces+0x409/0x860 kernel/nsproxy.c:106 + unshare_nsproxy_namespaces+0xae/0x1e0 kernel/nsproxy.c:205 + SYSC_unshare kernel/fork.c:2281 [inline] + +Problem is that when we get error during xfrm_net_init we will call +xfrm_policy_fini which will acquire xfrm_policy_lock before it was +initialized. Just move it around so locks get set up first. + +Reported-by: Dmitry Vyukov +Fixes: 283bc9f35bbbcb0e9 ("xfrm: Namespacify xfrm state/policy locks") +Signed-off-by: Florian Westphal +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_policy.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index b5e665b3cfb0..36a50ef9295d 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -3030,6 +3030,11 @@ static int __net_init xfrm_net_init(struct net *net) + { + int rv; + ++ /* Initialize the per-net locks here */ ++ spin_lock_init(&net->xfrm.xfrm_state_lock); ++ rwlock_init(&net->xfrm.xfrm_policy_lock); ++ mutex_init(&net->xfrm.xfrm_cfg_mutex); ++ + rv = xfrm_statistics_init(net); + if (rv < 0) + goto out_statistics; +@@ -3046,11 +3051,6 @@ static int __net_init xfrm_net_init(struct net *net) + if (rv < 0) + goto out; + +- /* Initialize the per-net locks here */ +- spin_lock_init(&net->xfrm.xfrm_state_lock); +- rwlock_init(&net->xfrm.xfrm_policy_lock); +- mutex_init(&net->xfrm.xfrm_cfg_mutex); +- + return 0; + + out: +-- +2.12.2 + +From cce7e56dd73f75fef0a7f594fb129285a660fec0 Mon Sep 17 00:00:00 2001 +From: Andy Whitcroft +Date: Wed, 22 Mar 2017 07:29:31 +0000 +Subject: [PATCH 211/251] xfrm_user: validate XFRM_MSG_NEWAE + XFRMA_REPLAY_ESN_VAL replay_window +Content-Length: 1832 +Lines: 45 + +commit 677e806da4d916052585301785d847c3b3e6186a upstream. + +When a new xfrm state is created during an XFRM_MSG_NEWSA call we +validate the user supplied replay_esn to ensure that the size is valid +and to ensure that the replay_window size is within the allocated +buffer. However later it is possible to update this replay_esn via a +XFRM_MSG_NEWAE call. There we again validate the size of the supplied +buffer matches the existing state and if so inject the contents. We do +not at this point check that the replay_window is within the allocated +memory. This leads to out-of-bounds reads and writes triggered by +netlink packets. This leads to memory corruption and the potential for +priviledge escalation. + +We already attempt to validate the incoming replay information in +xfrm_new_ae() via xfrm_replay_verify_len(). This confirms that the user +is not trying to change the size of the replay state buffer which +includes the replay_esn. It however does not check the replay_window +remains within that buffer. Add validation of the contained +replay_window. + +CVE-2017-7184 +Signed-off-by: Andy Whitcroft +Acked-by: Steffen Klassert +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_user.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +index 805681a7d356..0e1f833bc77d 100644 +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -415,6 +415,9 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es + if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen) + return -EINVAL; + ++ if (up->replay_window > up->bmp_len * sizeof(__u32) * 8) ++ return -EINVAL; ++ + return 0; + } + +-- +2.12.2 + +From 22c9e7c092f63335ba7a7301e0e0b4c4ebed53a8 Mon Sep 17 00:00:00 2001 +From: Andy Whitcroft +Date: Thu, 23 Mar 2017 07:45:44 +0000 +Subject: [PATCH 212/251] xfrm_user: validate XFRM_MSG_NEWAE incoming ESN size + harder +Content-Length: 1382 +Lines: 35 + +commit f843ee6dd019bcece3e74e76ad9df0155655d0df upstream. + +Kees Cook has pointed out that xfrm_replay_state_esn_len() is subject to +wrapping issues. To ensure we are correctly ensuring that the two ESN +structures are the same size compare both the overall size as reported +by xfrm_replay_state_esn_len() and the internal length are the same. + +CVE-2017-7184 +Signed-off-by: Andy Whitcroft +Acked-by: Steffen Klassert +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_user.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +index 0e1f833bc77d..7a5a64e70b4d 100644 +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -412,7 +412,11 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es + up = nla_data(rp); + ulen = xfrm_replay_state_esn_len(up); + +- if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen) ++ /* Check the overall length and the internal bitmap length to avoid ++ * potential overflow. */ ++ if (nla_len(rp) < ulen || ++ xfrm_replay_state_esn_len(replay_esn) != ulen || ++ replay_esn->bmp_len != up->bmp_len) + return -EINVAL; + + if (up->replay_window > up->bmp_len * sizeof(__u32) * 8) +-- +2.12.2 + +From 927d04793f8a587532a5c26057bcdcb33bc8f5ba Mon Sep 17 00:00:00 2001 +From: Ladi Prosek +Date: Thu, 23 Mar 2017 08:04:18 +0100 +Subject: [PATCH 213/251] virtio_balloon: init 1st buffer in stats vq +Content-Length: 1861 +Lines: 47 + +commit fc8653228c8588a120f6b5dad6983b7b61ff669e upstream. + +When init_vqs runs, virtio_balloon.stats is either uninitialized or +contains stale values. The host updates its state with garbage data +because it has no way of knowing that this is just a marker buffer +used for signaling. + +This patch updates the stats before pushing the initial buffer. + +Alternative fixes: +* Push an empty buffer in init_vqs. Not easily done with the current + virtio implementation and violates the spec "Driver MUST supply the + same subset of statistics in all buffers submitted to the statsq". +* Push a buffer with invalid tags in init_vqs. Violates the same + spec clause, plus "invalid tag" is not really defined. + +Note: the spec says: + When using the legacy interface, the device SHOULD ignore all values in + the first buffer in the statsq supplied by the driver after device + initialization. Note: Historically, drivers supplied an uninitialized + buffer in the first buffer. + +Unfortunately QEMU does not seem to implement the recommendation +even for the legacy interface. + +Signed-off-by: Ladi Prosek +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/virtio/virtio_balloon.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c +index 56f7e2521202..01d15dca940e 100644 +--- a/drivers/virtio/virtio_balloon.c ++++ b/drivers/virtio/virtio_balloon.c +@@ -416,6 +416,8 @@ static int init_vqs(struct virtio_balloon *vb) + * Prime this virtqueue with one buffer so the hypervisor can + * use it to signal us later (it can't be broken yet!). + */ ++ update_balloon_stats(vb); ++ + sg_init_one(&sg, vb->stats, sizeof vb->stats); + if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL) + < 0) +-- +2.12.2 + +From 800791e7e0fd9835be2f55c55147c379888b7442 Mon Sep 17 00:00:00 2001 +From: Bjorn Andersson +Date: Tue, 14 Mar 2017 08:23:26 -0700 +Subject: [PATCH 214/251] pinctrl: qcom: Don't clear status bit on irq_unmask +Content-Length: 1223 +Lines: 33 + +commit a6566710adaa4a7dd5e0d99820ff9c9c30ee5951 upstream. + +Clearing the status bit on irq_unmask will discard any pending interrupt +that did arrive after the irq_ack, i.e. while the IRQ handler function +was executing. + +Fixes: f365be092572 ("pinctrl: Add Qualcomm TLMM driver") +Cc: Stephen Boyd +Reported-by: Timur Tabi +Signed-off-by: Bjorn Andersson +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/qcom/pinctrl-msm.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c +index 146264a41ec8..9736f9be5447 100644 +--- a/drivers/pinctrl/qcom/pinctrl-msm.c ++++ b/drivers/pinctrl/qcom/pinctrl-msm.c +@@ -597,10 +597,6 @@ static void msm_gpio_irq_unmask(struct irq_data *d) + + spin_lock_irqsave(&pctrl->lock, flags); + +- val = readl(pctrl->regs + g->intr_status_reg); +- val &= ~BIT(g->intr_status_bit); +- writel(val, pctrl->regs + g->intr_status_reg); +- + val = readl(pctrl->regs + g->intr_cfg_reg); + val |= BIT(g->intr_enable_bit); + writel(val, pctrl->regs + g->intr_cfg_reg); +-- +2.12.2 + +From 6e174bbd0631865acc193804fa4043852f3198c5 Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:53 +0100 +Subject: [PATCH 215/251] c6x/ptrace: Remove useless PTRACE_SETREGSET + implementation +Content-Length: 2142 +Lines: 78 + +commit fb411b837b587a32046dc4f369acb93a10b1def8 upstream. + +gpr_set won't work correctly and can never have been tested, and the +correct behaviour is not clear due to the endianness-dependent task +layout. + +So, just remove it. The core code will now return -EOPNOTSUPPORT when +trying to set NT_PRSTATUS on this architecture until/unless a correct +implementation is supplied. + +Signed-off-by: Dave Martin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/c6x/kernel/ptrace.c | 41 ----------------------------------------- + 1 file changed, 41 deletions(-) + +diff --git a/arch/c6x/kernel/ptrace.c b/arch/c6x/kernel/ptrace.c +index 3c494e84444d..a511ac16a8e3 100644 +--- a/arch/c6x/kernel/ptrace.c ++++ b/arch/c6x/kernel/ptrace.c +@@ -69,46 +69,6 @@ static int gpr_get(struct task_struct *target, + 0, sizeof(*regs)); + } + +-static int gpr_set(struct task_struct *target, +- const struct user_regset *regset, +- unsigned int pos, unsigned int count, +- const void *kbuf, const void __user *ubuf) +-{ +- int ret; +- struct pt_regs *regs = task_pt_regs(target); +- +- /* Don't copyin TSR or CSR */ +- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, +- ®s, +- 0, PT_TSR * sizeof(long)); +- if (ret) +- return ret; +- +- ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, +- PT_TSR * sizeof(long), +- (PT_TSR + 1) * sizeof(long)); +- if (ret) +- return ret; +- +- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, +- ®s, +- (PT_TSR + 1) * sizeof(long), +- PT_CSR * sizeof(long)); +- if (ret) +- return ret; +- +- ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, +- PT_CSR * sizeof(long), +- (PT_CSR + 1) * sizeof(long)); +- if (ret) +- return ret; +- +- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, +- ®s, +- (PT_CSR + 1) * sizeof(long), -1); +- return ret; +-} +- + enum c6x_regset { + REGSET_GPR, + }; +@@ -120,7 +80,6 @@ static const struct user_regset c6x_regsets[] = { + .size = sizeof(u32), + .align = sizeof(u32), + .get = gpr_get, +- .set = gpr_set + }, + }; + +-- +2.12.2 + +From e1dc8904b33b8c01f22d904fed4cb5f2060f5da3 Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:54 +0100 +Subject: [PATCH 216/251] h8300/ptrace: Fix incorrect register transfer count +Content-Length: 1903 +Lines: 51 + +commit 502585c7555083d4a949c08350306b9ec196779e upstream. + +regs_set() and regs_get() are vulnerable to an off-by-1 buffer overrun +if CONFIG_CPU_H8S is set, since this adds an extra entry to +register_offset[] but not to user_regs_struct. + +So, iterate over user_regs_struct based on its actual size, not based on +the length of register_offset[]. + +Signed-off-by: Dave Martin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/h8300/kernel/ptrace.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c +index 92075544a19a..0dc1c8f622bc 100644 +--- a/arch/h8300/kernel/ptrace.c ++++ b/arch/h8300/kernel/ptrace.c +@@ -95,7 +95,8 @@ static int regs_get(struct task_struct *target, + long *reg = (long *)®s; + + /* build user regs in buffer */ +- for (r = 0; r < ARRAY_SIZE(register_offset); r++) ++ BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0); ++ for (r = 0; r < sizeof(regs) / sizeof(long); r++) + *reg++ = h8300_get_reg(target, r); + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, +@@ -113,7 +114,8 @@ static int regs_set(struct task_struct *target, + long *reg; + + /* build user regs in buffer */ +- for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++) ++ BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0); ++ for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++) + *reg++ = h8300_get_reg(target, r); + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, +@@ -122,7 +124,7 @@ static int regs_set(struct task_struct *target, + return ret; + + /* write back to pt_regs */ +- for (reg = (long *)®s, r = 0; r < ARRAY_SIZE(register_offset); r++) ++ for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++) + h8300_put_reg(target, r, *reg++); + return 0; + } +-- +2.12.2 + +From c8693666856c0db4a1e07235d98ce0b3bde98d9e Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:58 +0100 +Subject: [PATCH 217/251] mips/ptrace: Preserve previous registers for short + regset write +Content-Length: 1082 +Lines: 28 + +commit d614fd58a2834cfe4efa472c33c8f3ce2338b09b upstream. + +Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET +to fill all the registers, the thread's old registers are preserved. + +Signed-off-by: Dave Martin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/kernel/ptrace.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c +index 74d581569778..c95bf18260f8 100644 +--- a/arch/mips/kernel/ptrace.c ++++ b/arch/mips/kernel/ptrace.c +@@ -485,7 +485,8 @@ static int fpr_set(struct task_struct *target, + &target->thread.fpu, + 0, sizeof(elf_fpregset_t)); + +- for (i = 0; i < NUM_FPU_REGS; i++) { ++ BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t)); ++ for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) { + err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &fpr_val, i * sizeof(elf_fpreg_t), + (i + 1) * sizeof(elf_fpreg_t)); +-- +2.12.2 + +From 962b95a88574359b081e24815fae6aba92fff98d Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:59 +0100 +Subject: [PATCH 218/251] sparc/ptrace: Preserve previous registers for short + regset write +Content-Length: 923 +Lines: 28 + +commit d3805c546b275c8cc7d40f759d029ae92c7175f2 upstream. + +Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET +to fill all the registers, the thread's old registers are preserved. + +Signed-off-by: Dave Martin +Acked-by: David S. Miller +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/ptrace_64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c +index 9ddc4928a089..c1566170964f 100644 +--- a/arch/sparc/kernel/ptrace_64.c ++++ b/arch/sparc/kernel/ptrace_64.c +@@ -311,7 +311,7 @@ static int genregs64_set(struct task_struct *target, + } + + if (!ret) { +- unsigned long y; ++ unsigned long y = regs->y; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &y, +-- +2.12.2 + +From 2d9bc3695012f1ef7465f56302c1e60c48dccde8 Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:55 +0100 +Subject: [PATCH 219/251] metag/ptrace: Preserve previous registers for short + regset write +Content-Length: 976 +Lines: 28 + +commit a78ce80d2c9178351b34d78fec805140c29c193e upstream. + +Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET +to fill all the registers, the thread's old registers are preserved. + +Signed-off-by: Dave Martin +Acked-by: James Hogan +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/metag/kernel/ptrace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/metag/kernel/ptrace.c b/arch/metag/kernel/ptrace.c +index 7563628822bd..ae659ba61948 100644 +--- a/arch/metag/kernel/ptrace.c ++++ b/arch/metag/kernel/ptrace.c +@@ -303,7 +303,7 @@ static int metag_tls_set(struct task_struct *target, + const void *kbuf, const void __user *ubuf) + { + int ret; +- void __user *tls; ++ void __user *tls = target->thread.tls_ptr; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); + if (ret) +-- +2.12.2 + +From e441102d8c074d63d44329a59f3278573cdc1477 Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:56 +0100 +Subject: [PATCH 220/251] metag/ptrace: Provide default TXSTATUS for short + NT_PRSTATUS +Content-Length: 1755 +Lines: 56 + +commit 5fe81fe98123ce41265c65e95d34418d30d005d1 upstream. + +Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET +to fill TXSTATUS, a well-defined default value is used, based on the +task's current value. + +Suggested-by: James Hogan +Signed-off-by: Dave Martin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/metag/kernel/ptrace.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/arch/metag/kernel/ptrace.c b/arch/metag/kernel/ptrace.c +index ae659ba61948..2e4dfc15abd3 100644 +--- a/arch/metag/kernel/ptrace.c ++++ b/arch/metag/kernel/ptrace.c +@@ -24,6 +24,16 @@ + * user_regset definitions. + */ + ++static unsigned long user_txstatus(const struct pt_regs *regs) ++{ ++ unsigned long data = (unsigned long)regs->ctx.Flags; ++ ++ if (regs->ctx.SaveMask & TBICTX_CBUF_BIT) ++ data |= USER_GP_REGS_STATUS_CATCH_BIT; ++ ++ return data; ++} ++ + int metag_gp_regs_copyout(const struct pt_regs *regs, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +@@ -62,9 +72,7 @@ int metag_gp_regs_copyout(const struct pt_regs *regs, + if (ret) + goto out; + /* TXSTATUS */ +- data = (unsigned long)regs->ctx.Flags; +- if (regs->ctx.SaveMask & TBICTX_CBUF_BIT) +- data |= USER_GP_REGS_STATUS_CATCH_BIT; ++ data = user_txstatus(regs); + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &data, 4*25, 4*26); + if (ret) +@@ -119,6 +127,7 @@ int metag_gp_regs_copyin(struct pt_regs *regs, + if (ret) + goto out; + /* TXSTATUS */ ++ data = user_txstatus(regs); + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &data, 4*25, 4*26); + if (ret) +-- +2.12.2 + +From 573341eba9c44b0b2198373cb453bbbb5b3f066a Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:57 +0100 +Subject: [PATCH 221/251] metag/ptrace: Reject partial NT_METAG_RPIPE writes +Content-Length: 1069 +Lines: 31 + +commit 7195ee3120d878259e8d94a5d9f808116f34d5ea upstream. + +It's not clear what behaviour is sensible when doing partial write of +NT_METAG_RPIPE, so just don't bother. + +This patch assumes that userspace will never rely on a partial SETREGSET +in this case, since it's not clear what should happen anyway. + +Signed-off-by: Dave Martin +Acked-by: James Hogan +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/metag/kernel/ptrace.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/metag/kernel/ptrace.c b/arch/metag/kernel/ptrace.c +index 2e4dfc15abd3..5e2dc7defd2c 100644 +--- a/arch/metag/kernel/ptrace.c ++++ b/arch/metag/kernel/ptrace.c +@@ -253,6 +253,8 @@ int metag_rp_state_copyin(struct pt_regs *regs, + unsigned long long *ptr; + int ret, i; + ++ if (count < 4*13) ++ return -EINVAL; + /* Read the entire pipeline before making any changes */ + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &rp, 0, 4*13); +-- +2.12.2 + +From 7a5202190810dde1467718235c1f650fcf57592a Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Tue, 21 Feb 2017 15:07:11 -0800 +Subject: [PATCH 222/251] fscrypt: remove broken support for detecting keyring + key revocation +Content-Length: 10256 +Lines: 300 + +commit 1b53cf9815bb4744958d41f3795d5d5a1d365e2d upstream. + +Filesystem encryption ostensibly supported revoking a keyring key that +had been used to "unlock" encrypted files, causing those files to become +"locked" again. This was, however, buggy for several reasons, the most +severe of which was that when key revocation happened to be detected for +an inode, its fscrypt_info was immediately freed, even while other +threads could be using it for encryption or decryption concurrently. +This could be exploited to crash the kernel or worse. + +This patch fixes the use-after-free by removing the code which detects +the keyring key having been revoked, invalidated, or expired. Instead, +an encrypted inode that is "unlocked" now simply remains unlocked until +it is evicted from memory. Note that this is no worse than the case for +block device-level encryption, e.g. dm-crypt, and it still remains +possible for a privileged user to evict unused pages, inodes, and +dentries by running 'sync; echo 3 > /proc/sys/vm/drop_caches', or by +simply unmounting the filesystem. In fact, one of those actions was +already needed anyway for key revocation to work even somewhat sanely. +This change is not expected to break any applications. + +In the future I'd like to implement a real API for fscrypt key +revocation that interacts sanely with ongoing filesystem operations --- +waiting for existing operations to complete and blocking new operations, +and invalidating and sanitizing key material and plaintext from the VFS +caches. But this is a hard problem, and for now this bug must be fixed. + +This bug affected almost all versions of ext4, f2fs, and ubifs +encryption, and it was potentially reachable in any kernel configured +with encryption support (CONFIG_EXT4_ENCRYPTION=y, +CONFIG_EXT4_FS_ENCRYPTION=y, CONFIG_F2FS_FS_ENCRYPTION=y, or +CONFIG_UBIFS_FS_ENCRYPTION=y). Note that older kernels did not use the +shared fs/crypto/ code, but due to the potential security implications +of this bug, it may still be worthwhile to backport this fix to them. + +Fixes: b7236e21d55f ("ext4 crypto: reorganize how we store keys in the inode") +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Acked-by: Michael Halcrow +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/crypto_key.c | 28 +++++++--------------------- + fs/ext4/ext4.h | 14 +------------- + fs/ext4/ext4_crypto.h | 1 - + fs/f2fs/crypto_key.c | 28 +++++++--------------------- + fs/f2fs/f2fs.h | 14 +------------- + fs/f2fs/f2fs_crypto.h | 1 - + 6 files changed, 16 insertions(+), 70 deletions(-) + +diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c +index 9a16d1e75a49..505f8afde57c 100644 +--- a/fs/ext4/crypto_key.c ++++ b/fs/ext4/crypto_key.c +@@ -88,8 +88,6 @@ void ext4_free_crypt_info(struct ext4_crypt_info *ci) + if (!ci) + return; + +- if (ci->ci_keyring_key) +- key_put(ci->ci_keyring_key); + crypto_free_ablkcipher(ci->ci_ctfm); + kmem_cache_free(ext4_crypt_info_cachep, ci); + } +@@ -111,7 +109,7 @@ void ext4_free_encryption_info(struct inode *inode, + ext4_free_crypt_info(ci); + } + +-int _ext4_get_encryption_info(struct inode *inode) ++int ext4_get_encryption_info(struct inode *inode) + { + struct ext4_inode_info *ei = EXT4_I(inode); + struct ext4_crypt_info *crypt_info; +@@ -128,22 +126,15 @@ int _ext4_get_encryption_info(struct inode *inode) + char mode; + int res; + ++ if (ei->i_crypt_info) ++ return 0; ++ + if (!ext4_read_workqueue) { + res = ext4_init_crypto(); + if (res) + return res; + } + +-retry: +- crypt_info = ACCESS_ONCE(ei->i_crypt_info); +- if (crypt_info) { +- if (!crypt_info->ci_keyring_key || +- key_validate(crypt_info->ci_keyring_key) == 0) +- return 0; +- ext4_free_encryption_info(inode, crypt_info); +- goto retry; +- } +- + res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION, + EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, + &ctx, sizeof(ctx)); +@@ -166,7 +157,6 @@ retry: + crypt_info->ci_data_mode = ctx.contents_encryption_mode; + crypt_info->ci_filename_mode = ctx.filenames_encryption_mode; + crypt_info->ci_ctfm = NULL; +- crypt_info->ci_keyring_key = NULL; + memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor, + sizeof(crypt_info->ci_master_key)); + if (S_ISREG(inode->i_mode)) +@@ -206,7 +196,6 @@ retry: + keyring_key = NULL; + goto out; + } +- crypt_info->ci_keyring_key = keyring_key; + if (keyring_key->type != &key_type_logon) { + printk_once(KERN_WARNING + "ext4: key type must be logon\n"); +@@ -253,16 +242,13 @@ got_key: + ext4_encryption_key_size(mode)); + if (res) + goto out; +- memzero_explicit(raw_key, sizeof(raw_key)); +- if (cmpxchg(&ei->i_crypt_info, NULL, crypt_info) != NULL) { +- ext4_free_crypt_info(crypt_info); +- goto retry; +- } +- return 0; + ++ if (cmpxchg(&ei->i_crypt_info, NULL, crypt_info) == NULL) ++ crypt_info = NULL; + out: + if (res == -ENOKEY) + res = 0; ++ key_put(keyring_key); + ext4_free_crypt_info(crypt_info); + memzero_explicit(raw_key, sizeof(raw_key)); + return res; +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index cd5914495ad7..362d59b24f1d 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -2330,23 +2330,11 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname) { } + /* crypto_key.c */ + void ext4_free_crypt_info(struct ext4_crypt_info *ci); + void ext4_free_encryption_info(struct inode *inode, struct ext4_crypt_info *ci); +-int _ext4_get_encryption_info(struct inode *inode); + + #ifdef CONFIG_EXT4_FS_ENCRYPTION + int ext4_has_encryption_key(struct inode *inode); + +-static inline int ext4_get_encryption_info(struct inode *inode) +-{ +- struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info; +- +- if (!ci || +- (ci->ci_keyring_key && +- (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | +- (1 << KEY_FLAG_REVOKED) | +- (1 << KEY_FLAG_DEAD))))) +- return _ext4_get_encryption_info(inode); +- return 0; +-} ++int ext4_get_encryption_info(struct inode *inode); + + static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode) + { +diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h +index ac7d4e813796..1b17b05b9f4d 100644 +--- a/fs/ext4/ext4_crypto.h ++++ b/fs/ext4/ext4_crypto.h +@@ -78,7 +78,6 @@ struct ext4_crypt_info { + char ci_filename_mode; + char ci_flags; + struct crypto_ablkcipher *ci_ctfm; +- struct key *ci_keyring_key; + char ci_master_key[EXT4_KEY_DESCRIPTOR_SIZE]; + }; + +diff --git a/fs/f2fs/crypto_key.c b/fs/f2fs/crypto_key.c +index 5de2d866a25c..18595d7a0efc 100644 +--- a/fs/f2fs/crypto_key.c ++++ b/fs/f2fs/crypto_key.c +@@ -92,7 +92,6 @@ static void f2fs_free_crypt_info(struct f2fs_crypt_info *ci) + if (!ci) + return; + +- key_put(ci->ci_keyring_key); + crypto_free_ablkcipher(ci->ci_ctfm); + kmem_cache_free(f2fs_crypt_info_cachep, ci); + } +@@ -113,7 +112,7 @@ void f2fs_free_encryption_info(struct inode *inode, struct f2fs_crypt_info *ci) + f2fs_free_crypt_info(ci); + } + +-int _f2fs_get_encryption_info(struct inode *inode) ++int f2fs_get_encryption_info(struct inode *inode) + { + struct f2fs_inode_info *fi = F2FS_I(inode); + struct f2fs_crypt_info *crypt_info; +@@ -129,18 +128,12 @@ int _f2fs_get_encryption_info(struct inode *inode) + char mode; + int res; + ++ if (fi->i_crypt_info) ++ return 0; ++ + res = f2fs_crypto_initialize(); + if (res) + return res; +-retry: +- crypt_info = ACCESS_ONCE(fi->i_crypt_info); +- if (crypt_info) { +- if (!crypt_info->ci_keyring_key || +- key_validate(crypt_info->ci_keyring_key) == 0) +- return 0; +- f2fs_free_encryption_info(inode, crypt_info); +- goto retry; +- } + + res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION, + F2FS_XATTR_NAME_ENCRYPTION_CONTEXT, +@@ -159,7 +152,6 @@ retry: + crypt_info->ci_data_mode = ctx.contents_encryption_mode; + crypt_info->ci_filename_mode = ctx.filenames_encryption_mode; + crypt_info->ci_ctfm = NULL; +- crypt_info->ci_keyring_key = NULL; + memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor, + sizeof(crypt_info->ci_master_key)); + if (S_ISREG(inode->i_mode)) +@@ -197,7 +189,6 @@ retry: + keyring_key = NULL; + goto out; + } +- crypt_info->ci_keyring_key = keyring_key; + BUG_ON(keyring_key->type != &key_type_logon); + ukp = user_key_payload(keyring_key); + if (ukp->datalen != sizeof(struct f2fs_encryption_key)) { +@@ -230,17 +221,12 @@ retry: + if (res) + goto out; + +- memzero_explicit(raw_key, sizeof(raw_key)); +- if (cmpxchg(&fi->i_crypt_info, NULL, crypt_info) != NULL) { +- f2fs_free_crypt_info(crypt_info); +- goto retry; +- } +- return 0; +- ++ if (cmpxchg(&fi->i_crypt_info, NULL, crypt_info) == NULL) ++ crypt_info = NULL; + out: + if (res == -ENOKEY && !S_ISREG(inode->i_mode)) + res = 0; +- ++ key_put(keyring_key); + f2fs_free_crypt_info(crypt_info); + memzero_explicit(raw_key, sizeof(raw_key)); + return res; +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index 9db5500d63d9..b1aeca83f4be 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -2149,7 +2149,6 @@ void f2fs_end_io_crypto_work(struct f2fs_crypto_ctx *, struct bio *); + + /* crypto_key.c */ + void f2fs_free_encryption_info(struct inode *, struct f2fs_crypt_info *); +-int _f2fs_get_encryption_info(struct inode *inode); + + /* crypto_fname.c */ + bool f2fs_valid_filenames_enc_mode(uint32_t); +@@ -2170,18 +2169,7 @@ void f2fs_exit_crypto(void); + + int f2fs_has_encryption_key(struct inode *); + +-static inline int f2fs_get_encryption_info(struct inode *inode) +-{ +- struct f2fs_crypt_info *ci = F2FS_I(inode)->i_crypt_info; +- +- if (!ci || +- (ci->ci_keyring_key && +- (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | +- (1 << KEY_FLAG_REVOKED) | +- (1 << KEY_FLAG_DEAD))))) +- return _f2fs_get_encryption_info(inode); +- return 0; +-} ++int f2fs_get_encryption_info(struct inode *inode); + + void f2fs_fname_crypto_free_buffer(struct f2fs_str *); + int f2fs_fname_setup_filename(struct inode *, const struct qstr *, +diff --git a/fs/f2fs/f2fs_crypto.h b/fs/f2fs/f2fs_crypto.h +index c2c1c2b63b25..f113f1a1e8c1 100644 +--- a/fs/f2fs/f2fs_crypto.h ++++ b/fs/f2fs/f2fs_crypto.h +@@ -79,7 +79,6 @@ struct f2fs_crypt_info { + char ci_filename_mode; + char ci_flags; + struct crypto_ablkcipher *ci_ctfm; +- struct key *ci_keyring_key; + char ci_master_key[F2FS_KEY_DESCRIPTOR_SIZE]; + }; + +-- +2.12.2 + +From 2bed5987692cb6dc3bf3ce15d8abeb79fdf4ab2a Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 24 Jan 2017 15:40:06 +0100 +Subject: [PATCH 223/251] sched/rt: Add a missing rescheduling point +Content-Length: 2699 +Lines: 74 + +commit 619bd4a71874a8fd78eb6ccf9f272c5e98bcc7b7 upstream. + +Since the change in commit: + + fd7a4bed1835 ("sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks") + +... we don't reschedule a task under certain circumstances: + +Lets say task-A, SCHED_OTHER, is running on CPU0 (and it may run only on +CPU0) and holds a PI lock. This task is removed from the CPU because it +used up its time slice and another SCHED_OTHER task is running. Task-B on +CPU1 runs at RT priority and asks for the lock owned by task-A. This +results in a priority boost for task-A. Task-B goes to sleep until the +lock has been made available. Task-A is already runnable (but not active), +so it receives no wake up. + +The reality now is that task-A gets on the CPU once the scheduler decides +to remove the current task despite the fact that a high priority task is +enqueued and waiting. This may take a long time. + +The desired behaviour is that CPU0 immediately reschedules after the +priority boost which made task-A the task with the lowest priority. + +Suggested-by: Peter Zijlstra +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Peter Zijlstra (Intel) +Cc: Linus Torvalds +Cc: Mike Galbraith +Cc: Thomas Gleixner +Fixes: fd7a4bed1835 ("sched, rt: Convert switched_{from, to}_rt() prio_changed_rt() to balance callbacks") +Link: http://lkml.kernel.org/r/20170124144006.29821-1-bigeasy@linutronix.de +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman +--- + kernel/sched/deadline.c | 3 +-- + kernel/sched/rt.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c +index 8b0a15e285f9..e984f059e5fc 100644 +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -1771,12 +1771,11 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p) + #ifdef CONFIG_SMP + if (p->nr_cpus_allowed > 1 && rq->dl.overloaded) + queue_push_tasks(rq); +-#else ++#endif + if (dl_task(rq->curr)) + check_preempt_curr_dl(rq, p, 0); + else + resched_curr(rq); +-#endif + } + } + +diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c +index 8ec86abe0ea1..78ae5c1d9412 100644 +--- a/kernel/sched/rt.c ++++ b/kernel/sched/rt.c +@@ -2136,10 +2136,9 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p) + #ifdef CONFIG_SMP + if (p->nr_cpus_allowed > 1 && rq->rt.overloaded) + queue_push_tasks(rq); +-#else ++#endif /* CONFIG_SMP */ + if (p->prio < rq->curr->prio) + resched_curr(rq); +-#endif /* CONFIG_SMP */ + } + } + +-- +2.12.2 + +From 61a4577c9a4419b99e647744923517d47255da35 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 31 Mar 2017 10:17:09 +0200 +Subject: [PATCH 224/251] Linux 4.4.59 +Content-Length: 301 +Lines: 18 + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 3efe2ea99e2d..083724c6ca4d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 58 ++SUBLEVEL = 59 + EXTRAVERSION = + NAME = Blurry Fish Butt + +-- +2.12.2 + +From ba46d8fab00a8e1538df241681d9161c8ec85778 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Tue, 21 Mar 2017 13:44:28 +0100 +Subject: [PATCH 225/251] libceph: force GFP_NOIO for socket allocations +Content-Length: 4579 +Lines: 104 + +commit 633ee407b9d15a75ac9740ba9d3338815e1fcb95 upstream. + +sock_alloc_inode() allocates socket+inode and socket_wq with +GFP_KERNEL, which is not allowed on the writeback path: + + Workqueue: ceph-msgr con_work [libceph] + ffff8810871cb018 0000000000000046 0000000000000000 ffff881085d40000 + 0000000000012b00 ffff881025cad428 ffff8810871cbfd8 0000000000012b00 + ffff880102fc1000 ffff881085d40000 ffff8810871cb038 ffff8810871cb148 + Call Trace: + [] schedule+0x29/0x70 + [] schedule_timeout+0x1bd/0x200 + [] ? ttwu_do_wakeup+0x2c/0x120 + [] ? ttwu_do_activate.constprop.135+0x66/0x70 + [] wait_for_completion+0xbf/0x180 + [] ? try_to_wake_up+0x390/0x390 + [] flush_work+0x165/0x250 + [] ? worker_detach_from_pool+0xd0/0xd0 + [] xlog_cil_force_lsn+0x81/0x200 [xfs] + [] ? __slab_free+0xee/0x234 + [] _xfs_log_force_lsn+0x4d/0x2c0 [xfs] + [] ? lookup_page_cgroup_used+0xe/0x30 + [] ? xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_log_force_lsn+0x3f/0xf0 [xfs] + [] ? xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_iunpin_wait+0xc6/0x1a0 [xfs] + [] ? wake_atomic_t_function+0x40/0x40 + [] xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_reclaim_inodes_ag+0x257/0x3d0 [xfs] + [] xfs_reclaim_inodes_nr+0x33/0x40 [xfs] + [] xfs_fs_free_cached_objects+0x15/0x20 [xfs] + [] super_cache_scan+0x178/0x180 + [] shrink_slab_node+0x14e/0x340 + [] ? mem_cgroup_iter+0x16b/0x450 + [] shrink_slab+0x100/0x140 + [] do_try_to_free_pages+0x335/0x490 + [] try_to_free_pages+0xb9/0x1f0 + [] ? __alloc_pages_direct_compact+0x69/0x1be + [] __alloc_pages_nodemask+0x69a/0xb40 + [] alloc_pages_current+0x9e/0x110 + [] new_slab+0x2c5/0x390 + [] __slab_alloc+0x33b/0x459 + [] ? sock_alloc_inode+0x2d/0xd0 + [] ? inet_sendmsg+0x71/0xc0 + [] ? sock_alloc_inode+0x2d/0xd0 + [] kmem_cache_alloc+0x1a2/0x1b0 + [] sock_alloc_inode+0x2d/0xd0 + [] alloc_inode+0x26/0xa0 + [] new_inode_pseudo+0x1a/0x70 + [] sock_alloc+0x1e/0x80 + [] __sock_create+0x95/0x220 + [] sock_create_kern+0x24/0x30 + [] con_work+0xef9/0x2050 [libceph] + [] ? rbd_img_request_submit+0x4c/0x60 [rbd] + [] process_one_work+0x159/0x4f0 + [] worker_thread+0x11b/0x530 + [] ? create_worker+0x1d0/0x1d0 + [] kthread+0xc9/0xe0 + [] ? flush_kthread_worker+0x90/0x90 + [] ret_from_fork+0x58/0x90 + [] ? flush_kthread_worker+0x90/0x90 + +Use memalloc_noio_{save,restore}() to temporarily force GFP_NOIO here. + +Link: http://tracker.ceph.com/issues/19309 +Reported-by: Sergey Jerusalimov +Signed-off-by: Ilya Dryomov +Reviewed-by: Jeff Layton +Signed-off-by: Greg Kroah-Hartman +--- + net/ceph/messenger.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c +index b8d927c56494..a6b2f2138c9d 100644 +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -478,11 +479,16 @@ static int ceph_tcp_connect(struct ceph_connection *con) + { + struct sockaddr_storage *paddr = &con->peer_addr.in_addr; + struct socket *sock; ++ unsigned int noio_flag; + int ret; + + BUG_ON(con->sock); ++ ++ /* sock_create_kern() allocates with GFP_KERNEL */ ++ noio_flag = memalloc_noio_save(); + ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family, + SOCK_STREAM, IPPROTO_TCP, &sock); ++ memalloc_noio_restore(noio_flag); + if (ret) + return ret; + sock->sk->sk_allocation = GFP_NOFS; +-- +2.12.2 + +From 1eed198ce16b6e05c05ee381e5d90fac35ea67a7 Mon Sep 17 00:00:00 2001 +From: Ross Lagerwall +Date: Mon, 12 Dec 2016 14:35:13 +0000 +Subject: [PATCH 226/251] xen/setup: Don't relocate p2m over existing one +Content-Length: 1354 +Lines: 45 + +commit 7ecec8503af37de6be4f96b53828d640a968705f upstream. + +When relocating the p2m, take special care not to relocate it so +that is overlaps with the current location of the p2m/initrd. This is +needed since the full extent of the current location is not marked as a +reserved region in the e820. + +This was seen to happen to a dom0 with a large initial p2m and a small +reserved region in the middle of the initial p2m. + +Signed-off-by: Ross Lagerwall +Reviewed-by: Juergen Gross +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/xen/setup.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c +index e345891450c3..df8844a1853a 100644 +--- a/arch/x86/xen/setup.c ++++ b/arch/x86/xen/setup.c +@@ -713,10 +713,9 @@ static void __init xen_reserve_xen_mfnlist(void) + size = PFN_PHYS(xen_start_info->nr_p2m_frames); + } + +- if (!xen_is_e820_reserved(start, size)) { +- memblock_reserve(start, size); ++ memblock_reserve(start, size); ++ if (!xen_is_e820_reserved(start, size)) + return; +- } + + #ifdef CONFIG_X86_32 + /* +@@ -727,6 +726,7 @@ static void __init xen_reserve_xen_mfnlist(void) + BUG(); + #else + xen_relocate_p2m(); ++ memblock_free(start, size); + #endif + } + +-- +2.12.2 + +From 18639c4bad72218954e728e9ca65c33b13ba673a Mon Sep 17 00:00:00 2001 +From: James Bottomley +Date: Sun, 1 Jan 2017 09:39:24 -0800 +Subject: [PATCH 227/251] scsi: mpt3sas: fix hang on ata passthrough commands +Content-Length: 5334 +Lines: 148 + +commit ffb58456589443ca572221fabbdef3db8483a779 upstream. + +mpt3sas has a firmware failure where it can only handle one pass through +ATA command at a time. If another comes in, contrary to the SAT +standard, it will hang until the first one completes (causing long +commands like secure erase to timeout). The original fix was to block +the device when an ATA command came in, but this caused a regression +with + +commit 669f044170d8933c3d66d231b69ea97cb8447338 +Author: Bart Van Assche +Date: Tue Nov 22 16:17:13 2016 -0800 + + scsi: srp_transport: Move queuecommand() wait code to SCSI core + +So fix the original fix of the secure erase timeout by properly +returning SAM_STAT_BUSY like the SAT recommends. The original patch +also had a concurrency problem since scsih_qcmd is lockless at that +point (this is fixed by using atomic bitops to set and test the flag). + +[mkp: addressed feedback wrt. test_bit and fixed whitespace] + +Fixes: 18f6084a989ba1b (mpt3sas: Fix secure erase premature termination) +Signed-off-by: James Bottomley +Acked-by: Sreekanth Reddy +Reviewed-by: Christoph Hellwig +Reported-by: Ingo Molnar +Tested-by: Ingo Molnar +Signed-off-by: Martin K. Petersen +Cc: Joe Korty +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 12 +++++++++++ + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 40 +++++++++++++++++++++++------------- + 2 files changed, 38 insertions(+), 14 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 92648a5ea2d2..63f5965acc89 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -390,6 +390,7 @@ struct MPT3SAS_TARGET { + * @eedp_enable: eedp support enable bit + * @eedp_type: 0(type_1), 1(type_2), 2(type_3) + * @eedp_block_length: block size ++ * @ata_command_pending: SATL passthrough outstanding for device + */ + struct MPT3SAS_DEVICE { + struct MPT3SAS_TARGET *sas_target; +@@ -398,6 +399,17 @@ struct MPT3SAS_DEVICE { + u8 configured_lun; + u8 block; + u8 tlr_snoop_check; ++ /* ++ * Bug workaround for SATL handling: the mpt2/3sas firmware ++ * doesn't return BUSY or TASK_SET_FULL for subsequent ++ * commands while a SATL pass through is in operation as the ++ * spec requires, it simply does nothing with them until the ++ * pass through completes, causing them possibly to timeout if ++ * the passthrough is a long executing command (like format or ++ * secure erase). This variable allows us to do the right ++ * thing while a SATL command is pending. ++ */ ++ unsigned long ata_command_pending; + }; + + #define MPT3_CMD_NOT_USED 0x8000 /* free */ +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index f6a8e9958e75..8a5fbdb45cfd 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -3707,9 +3707,18 @@ _scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc, + } + } + +-static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd) ++static int _scsih_set_satl_pending(struct scsi_cmnd *scmd, bool pending) + { +- return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16); ++ struct MPT3SAS_DEVICE *priv = scmd->device->hostdata; ++ ++ if (scmd->cmnd[0] != ATA_12 && scmd->cmnd[0] != ATA_16) ++ return 0; ++ ++ if (pending) ++ return test_and_set_bit(0, &priv->ata_command_pending); ++ ++ clear_bit(0, &priv->ata_command_pending); ++ return 0; + } + + /** +@@ -3733,9 +3742,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc) + if (!scmd) + continue; + count++; +- if (ata_12_16_cmd(scmd)) +- scsi_internal_device_unblock(scmd->device, +- SDEV_RUNNING); ++ _scsih_set_satl_pending(scmd, false); + mpt3sas_base_free_smid(ioc, smid); + scsi_dma_unmap(scmd); + if (ioc->pci_error_recovery) +@@ -3866,13 +3873,6 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) + if (ioc->logging_level & MPT_DEBUG_SCSI) + scsi_print_command(scmd); + +- /* +- * Lock the device for any subsequent command until command is +- * done. +- */ +- if (ata_12_16_cmd(scmd)) +- scsi_internal_device_block(scmd->device); +- + sas_device_priv_data = scmd->device->hostdata; + if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { + scmd->result = DID_NO_CONNECT << 16; +@@ -3886,6 +3886,19 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) + return 0; + } + ++ /* ++ * Bug work around for firmware SATL handling. The loop ++ * is based on atomic operations and ensures consistency ++ * since we're lockless at this point ++ */ ++ do { ++ if (test_bit(0, &sas_device_priv_data->ata_command_pending)) { ++ scmd->result = SAM_STAT_BUSY; ++ scmd->scsi_done(scmd); ++ return 0; ++ } ++ } while (_scsih_set_satl_pending(scmd, true)); ++ + sas_target_priv_data = sas_device_priv_data->sas_target; + + /* invalid device handle */ +@@ -4445,8 +4458,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) + if (scmd == NULL) + return 1; + +- if (ata_12_16_cmd(scmd)) +- scsi_internal_device_unblock(scmd->device, SDEV_RUNNING); ++ _scsih_set_satl_pending(scmd, false); + + mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); + +-- +2.12.2 + +From a92f411914cad6532e82e4607bc4075a5ffaa366 Mon Sep 17 00:00:00 2001 +From: peter chang +Date: Wed, 15 Feb 2017 14:11:54 -0800 +Subject: [PATCH 228/251] scsi: sg: check length passed to SG_NEXT_CMD_LEN +Content-Length: 932 +Lines: 29 + +commit bf33f87dd04c371ea33feb821b60d63d754e3124 upstream. + +The user can control the size of the next command passed along, but the +value passed to the ioctl isn't checked against the usable max command +size. + +Signed-off-by: Peter Chang +Acked-by: Douglas Gilbert +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/sg.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index dedcff9cabb5..6514636431ab 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -1008,6 +1008,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) + result = get_user(val, ip); + if (result) + return result; ++ if (val > SG_MAX_CDB_SIZE) ++ return -ENOMEM; + sfp->next_cmd_len = (val > 0) ? val : 0; + return 0; + case SG_GET_VERSION_NUM: +-- +2.12.2 + +From 75a03869c93a443ae068eae9aca0c0df8b33dff5 Mon Sep 17 00:00:00 2001 +From: John Garry +Date: Thu, 16 Mar 2017 23:07:28 +0800 +Subject: [PATCH 229/251] scsi: libsas: fix ata xfer length +Content-Length: 1328 +Lines: 36 + +commit 9702c67c6066f583b629cf037d2056245bb7a8e6 upstream. + +The total ata xfer length may not be calculated properly, in that we do +not use the proper method to get an sg element dma length. + +According to the code comment, sg_dma_len() should be used after +dma_map_sg() is called. + +This issue was found by turning on the SMMUv3 in front of the hisi_sas +controller in hip07. Multiple sg elements were being combined into a +single element, but the original first element length was being use as +the total xfer length. + +Fixes: ff2aeb1eb64c8a4770a6 ("libata: convert to chained sg") +Signed-off-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/libsas/sas_ata.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c +index 9c706d8c1441..6f5e2720ffad 100644 +--- a/drivers/scsi/libsas/sas_ata.c ++++ b/drivers/scsi/libsas/sas_ata.c +@@ -218,7 +218,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) + task->num_scatter = qc->n_elem; + } else { + for_each_sg(qc->sg, sg, qc->n_elem, si) +- xfer += sg->length; ++ xfer += sg_dma_len(sg); + + task->total_xfer_len = xfer; + task->num_scatter = si; +-- +2.12.2 + +From a90d7447e4a154ad26e3b9e09a0878680be49339 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 24 Mar 2017 17:07:57 +0100 +Subject: [PATCH 230/251] ALSA: seq: Fix race during FIFO resize +Content-Length: 1200 +Lines: 34 + +commit 2d7d54002e396c180db0c800c1046f0a3c471597 upstream. + +When a new event is queued while processing to resize the FIFO in +snd_seq_fifo_clear(), it may lead to a use-after-free, as the old pool +that is being queued gets removed. For avoiding this race, we need to +close the pool to be deleted and sync its usage before actually +deleting it. + +The issue was spotted by syzkaller. + +Reported-by: Dmitry Vyukov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/core/seq/seq_fifo.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c +index 3f4efcb85df5..3490d21ab9e7 100644 +--- a/sound/core/seq/seq_fifo.c ++++ b/sound/core/seq/seq_fifo.c +@@ -265,6 +265,10 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize) + /* NOTE: overflow flag is not cleared */ + spin_unlock_irqrestore(&f->lock, flags); + ++ /* close the old pool and wait until all users are gone */ ++ snd_seq_pool_mark_closing(oldpool); ++ snd_use_lock_sync(&f->use_lock); ++ + /* release cells in old pool */ + for (cell = oldhead; cell; cell = next) { + next = cell->next; +-- +2.12.2 + +From ce3dcfdbff04bab023806ef7a342c657ec08915d Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Fri, 31 Mar 2017 10:31:40 +0800 +Subject: [PATCH 231/251] ALSA: hda - fix a problem for lineout on a Dell AIO + machine +Content-Length: 2380 +Lines: 64 + +commit 2f726aec19a9d2c63bec9a8a53a3910ffdcd09f8 upstream. + +On this Dell AIO machine, the lineout jack does not work. + +We found the pin 0x1a is assigned to lineout on this machine, and in +the past, we applied ALC298_FIXUP_DELL1_MIC_NO_PRESENCE to fix the +heaset-set mic problem for this machine, this fixup will redefine +the pin 0x1a to headphone-mic, as a result the lineout doesn't +work anymore. + +After consulting with Dell, they told us this machine doesn't support +microphone via headset jack, so we add a new fixup which only defines +the pin 0x18 as the headset-mic. + +[rearranged the fixup insertion position by tiwai in order to make the + merge with other branches easier -- tiwai] + +Fixes: 59ec4b57bcae ("ALSA: hda - Fix headset mic detection problem for two dell machines") +Signed-off-by: Hui Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/hda/patch_realtek.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 1d4f34379f56..46a34039ecdc 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4831,6 +4831,7 @@ enum { + ALC292_FIXUP_DISABLE_AAMIX, + ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, + ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, ++ ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, + ALC275_FIXUP_DELL_XPS, + ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, + ALC293_FIXUP_LENOVO_SPK_NOISE, +@@ -5429,6 +5430,15 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE + }, ++ [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_HEADSET_MODE ++ }, + [ALC275_FIXUP_DELL_XPS] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { +@@ -5501,7 +5511,7 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc298_fixup_speaker_volume, + .chained = true, +- .chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, ++ .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, + }, + [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = { + .type = HDA_FIXUP_PINS, +-- +2.12.2 + +From ab48ab614b8c83f3a3b0f83f7882b1d2766962d3 Mon Sep 17 00:00:00 2001 +From: Songjun Wu +Date: Fri, 24 Feb 2017 15:10:43 +0800 +Subject: [PATCH 232/251] ASoC: atmel-classd: fix audio clock rate +Content-Length: 994 +Lines: 28 + +commit cd3ac9affc43b44f49d7af70d275f0bd426ba643 upstream. + +Fix the audio clock rate according to the datasheet. + +Reported-by: Dushara Jayasinghe +Signed-off-by: Songjun Wu +Acked-by: Nicolas Ferre +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/atmel/atmel-classd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c +index 8276675730ef..78a985629607 100644 +--- a/sound/soc/atmel/atmel-classd.c ++++ b/sound/soc/atmel/atmel-classd.c +@@ -343,7 +343,7 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai, + } + + #define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) +-#define CLASSD_ACLK_RATE_12M288_MPY_8 (12228 * 1000 * 8) ++#define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) + + static struct { + int rate; +-- +2.12.2 + +From 3342857ac074768e14e361392ac09fbbd70d840e Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf +Date: Thu, 16 Mar 2017 08:56:28 -0500 +Subject: [PATCH 233/251] ACPI: Fix incompatibility with mcount-based function + graph tracing +Content-Length: 1960 +Lines: 51 + +commit 61b79e16c68d703dde58c25d3935d67210b7d71b upstream. + +Paul Menzel reported a warning: + + WARNING: CPU: 0 PID: 774 at /build/linux-ROBWaj/linux-4.9.13/kernel/trace/trace_functions_graph.c:233 ftrace_return_to_handler+0x1aa/0x1e0 + Bad frame pointer: expected f6919d98, received f6919db0 + from func acpi_pm_device_sleep_wake return to c43b6f9d + +The warning means that function graph tracing is broken for the +acpi_pm_device_sleep_wake() function. That's because the ACPI Makefile +unconditionally sets the '-Os' gcc flag to optimize for size. That's an +issue because mcount-based function graph tracing is incompatible with +'-Os' on x86, thanks to the following gcc bug: + + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42109 + +I have another patch pending which will ensure that mcount-based +function graph tracing is never used with CONFIG_CC_OPTIMIZE_FOR_SIZE on +x86. + +But this patch is needed in addition to that one because the ACPI +Makefile overrides that config option for no apparent reason. It has +had this flag since the beginning of git history, and there's no related +comment, so I don't know why it's there. As far as I can tell, there's +no reason for it to be there. The appropriate behavior is for it to +honor CONFIG_CC_OPTIMIZE_FOR_{SIZE,PERFORMANCE} like the rest of the +kernel. + +Reported-by: Paul Menzel +Signed-off-by: Josh Poimboeuf +Acked-by: Steven Rostedt (VMware) +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/Makefile | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile +index 675eaf337178..b9cebca376f9 100644 +--- a/drivers/acpi/Makefile ++++ b/drivers/acpi/Makefile +@@ -2,7 +2,6 @@ + # Makefile for the Linux ACPI interpreter + # + +-ccflags-y := -Os + ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT + + # +-- +2.12.2 + +From 566a8711a7dd11960fa0bf3a4fd89c742eb359f3 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Wed, 22 Mar 2017 18:33:25 +0100 +Subject: [PATCH 234/251] ACPI: Do not create a platform_device for + IOAPIC/IOxAPIC +Content-Length: 1103 +Lines: 36 + +commit 08f63d97749185fab942a3a47ed80f5bd89b8b7d upstream. + +No platform-device is required for IO(x)APICs, so don't even +create them. + +[ rjw: This fixes a problem with leaking platform device objects + after IOAPIC/IOxAPIC hot-removal events.] + +Signed-off-by: Joerg Roedel +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/acpi_platform.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c +index 296b7a14893a..5365ff6e69c1 100644 +--- a/drivers/acpi/acpi_platform.c ++++ b/drivers/acpi/acpi_platform.c +@@ -24,9 +24,11 @@ + ACPI_MODULE_NAME("platform"); + + static const struct acpi_device_id forbidden_id_list[] = { +- {"PNP0000", 0}, /* PIC */ +- {"PNP0100", 0}, /* Timer */ +- {"PNP0200", 0}, /* AT DMA Controller */ ++ {"PNP0000", 0}, /* PIC */ ++ {"PNP0100", 0}, /* Timer */ ++ {"PNP0200", 0}, /* AT DMA Controller */ ++ {"ACPI0009", 0}, /* IOxAPIC */ ++ {"ACPI000A", 0}, /* IOAPIC */ + {"", 0}, + }; + +-- +2.12.2 + +From 74b8fc017d7689d1a60c9e234b2cfe3550b7f414 Mon Sep 17 00:00:00 2001 +From: Richard Genoud +Date: Mon, 20 Mar 2017 11:52:41 +0100 +Subject: [PATCH 235/251] tty/serial: atmel: fix race condition (TX+DMA) +Content-Length: 1106 +Lines: 33 + +commit 31ca2c63fdc0aee725cbd4f207c1256f5deaabde upstream. + +If uart_flush_buffer() is called between atmel_tx_dma() and +atmel_complete_tx_dma(), the circular buffer has been cleared, but not +atmel_port->tx_len. +That leads to a circular buffer overflow (dumping (UART_XMIT_SIZE - +atmel_port->tx_len) bytes). + +Tested-by: Nicolas Ferre +Signed-off-by: Richard Genoud +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/atmel_serial.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index a0f911641b04..156a262b6b65 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -1987,6 +1987,11 @@ static void atmel_flush_buffer(struct uart_port *port) + atmel_uart_writel(port, ATMEL_PDC_TCR, 0); + atmel_port->pdc_tx.ofs = 0; + } ++ /* ++ * in uart_flush_buffer(), the xmit circular buffer has just ++ * been cleared, so we have to reset tx_len accordingly. ++ */ ++ atmel_port->tx_len = 0; + } + + /* +-- +2.12.2 + +From 0a1757cfa5ba3b46f6ee7a74ddb7a5c0bd5d7c2f Mon Sep 17 00:00:00 2001 +From: Nicolas Ferre +Date: Mon, 20 Mar 2017 16:38:57 +0100 +Subject: [PATCH 236/251] tty/serial: atmel: fix TX path in + atmel_console_write() +Content-Length: 1304 +Lines: 31 + +commit 497e1e16f45c70574dc9922c7f75c642c2162119 upstream. + +A side effect of 89d8232411a8 ("tty/serial: atmel_serial: BUG: stop DMA +from transmitting in stop_tx") is that the console can be called with +TX path disabled. Then the system would hang trying to push charecters +out in atmel_console_putchar(). + +Signed-off-by: Nicolas Ferre +Fixes: 89d8232411a8 ("tty/serial: atmel_serial: BUG: stop DMA from transmitting in stop_tx") +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/atmel_serial.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index 156a262b6b65..a15070a7fcd6 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -2504,6 +2504,9 @@ static void atmel_console_write(struct console *co, const char *s, u_int count) + pdc_tx = atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN; + atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS); + ++ /* Make sure that tx path is actually able to send characters */ ++ atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN); ++ + uart_console_write(port, s, count, atmel_console_putchar); + + /* +-- +2.12.2 + +From eac3ab3e69151c21a0a71ec8711600022cc12fa3 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 24 Mar 2017 13:38:28 -0400 +Subject: [PATCH 237/251] USB: fix linked-list corruption in rh_call_control() +Content-Length: 1325 +Lines: 44 + +commit 1633682053a7ee8058e10c76722b9b28e97fb73f upstream. + +Using KASAN, Dmitry found a bug in the rh_call_control() routine: If +buffer allocation fails, the routine returns immediately without +unlinking its URB from the control endpoint, eventually leading to +linked-list corruption. + +This patch fixes the problem by jumping to the end of the routine +(where the URB is unlinked) when an allocation failure occurs. + +Signed-off-by: Alan Stern +Reported-and-tested-by: Dmitry Vyukov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hcd.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index 5724d7c41e29..ca2cbdb3aa67 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -499,8 +499,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) + */ + tbuf_size = max_t(u16, sizeof(struct usb_hub_descriptor), wLength); + tbuf = kzalloc(tbuf_size, GFP_KERNEL); +- if (!tbuf) +- return -ENOMEM; ++ if (!tbuf) { ++ status = -ENOMEM; ++ goto err_alloc; ++ } + + bufp = tbuf; + +@@ -705,6 +707,7 @@ error: + } + + kfree(tbuf); ++ err_alloc: + + /* any errors get returned through the urb completion */ + spin_lock_irq(&hcd_root_hub_lock); +-- +2.12.2 + +From 3eb392056aeb4a0beca5fcead9ad3d6b6ff0816e Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Wed, 15 Mar 2017 16:01:17 +0800 +Subject: [PATCH 238/251] KVM: x86: clear bus pointer when destroyed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1484 +Lines: 46 + +commit df630b8c1e851b5e265dc2ca9c87222e342c093b upstream. + +When releasing the bus, let's clear the bus pointers to mark it out. If +any further device unregister happens on this bus, we know that we're +done if we found the bus being released already. + +Signed-off-by: Peter Xu +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/kvm_main.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 336ed267c407..1ac5b7be7282 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -654,8 +654,10 @@ static void kvm_destroy_vm(struct kvm *kvm) + list_del(&kvm->vm_list); + spin_unlock(&kvm_lock); + kvm_free_irq_routing(kvm); +- for (i = 0; i < KVM_NR_BUSES; i++) ++ for (i = 0; i < KVM_NR_BUSES; i++) { + kvm_io_bus_destroy(kvm->buses[i]); ++ kvm->buses[i] = NULL; ++ } + kvm_coalesced_mmio_free(kvm); + #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER) + mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm); +@@ -3376,6 +3378,14 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, + struct kvm_io_bus *new_bus, *bus; + + bus = kvm->buses[bus_idx]; ++ ++ /* ++ * It's possible the bus being released before hand. If so, ++ * we're done here. ++ */ ++ if (!bus) ++ return 0; ++ + r = -ENOENT; + for (i = 0; i < bus->dev_count; i++) + if (bus->range[i].dev == dev) { +-- +2.12.2 + +From ef55c3df5dbd60eb3daab7797feac850bd1e6fe3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +Date: Fri, 24 Mar 2017 19:01:09 +0900 +Subject: [PATCH 239/251] drm/radeon: Override fpfn for all VRAM placements in + radeon_evict_flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1858 +Lines: 41 + +commit ce4b4f228e51219b0b79588caf73225b08b5b779 upstream. + +We were accidentally only overriding the first VRAM placement. For BOs +with the RADEON_GEM_NO_CPU_ACCESS flag set, +radeon_ttm_placement_from_domain creates a second VRAM placment with +fpfn == 0. If VRAM is almost full, the first VRAM placement with +fpfn > 0 may not work, but the second one with fpfn == 0 always will +(the BO's current location trivially satisfies it). Because "moving" +the BO to its current location puts it back on the LRU list, this +results in an infinite loop. + +Fixes: 2a85aedd117c ("drm/radeon: Try evicting from CPU accessible to + inaccessible VRAM first") +Reported-by: Zachary Michaels +Reported-and-Tested-by: Julien Isorce +Reviewed-by: Christian König +Reviewed-by: Alex Deucher +Signed-off-by: Michel Dänzer +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/radeon/radeon_ttm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c +index 35310336dd0a..d684e2b79d2b 100644 +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -213,8 +213,8 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, + rbo->placement.num_busy_placement = 0; + for (i = 0; i < rbo->placement.num_placement; i++) { + if (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) { +- if (rbo->placements[0].fpfn < fpfn) +- rbo->placements[0].fpfn = fpfn; ++ if (rbo->placements[i].fpfn < fpfn) ++ rbo->placements[i].fpfn = fpfn; + } else { + rbo->placement.busy_placement = + &rbo->placements[i]; +-- +2.12.2 + +From 47e2fe17d14d1a7da3a405b1f364c094c271d35c Mon Sep 17 00:00:00 2001 +From: Naoya Horiguchi +Date: Fri, 31 Mar 2017 15:11:55 -0700 +Subject: [PATCH 240/251] mm, hugetlb: use pte_present() instead of + pmd_present() in follow_huge_pmd() +Content-Length: 4587 +Lines: 99 + +commit c9d398fa237882ea07167e23bcfc5e6847066518 upstream. + +I found the race condition which triggers the following bug when +move_pages() and soft offline are called on a single hugetlb page +concurrently. + + Soft offlining page 0x119400 at 0x700000000000 + BUG: unable to handle kernel paging request at ffffea0011943820 + IP: follow_huge_pmd+0x143/0x190 + PGD 7ffd2067 + PUD 7ffd1067 + PMD 0 + [61163.582052] Oops: 0000 [#1] SMP + Modules linked in: binfmt_misc ppdev virtio_balloon parport_pc pcspkr i2c_piix4 parport i2c_core acpi_cpufreq ip_tables xfs libcrc32c ata_generic pata_acpi virtio_blk 8139too crc32c_intel ata_piix serio_raw libata virtio_pci 8139cp virtio_ring virtio mii floppy dm_mirror dm_region_hash dm_log dm_mod [last unloaded: cap_check] + CPU: 0 PID: 22573 Comm: iterate_numa_mo Tainted: P OE 4.11.0-rc2-mm1+ #2 + Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 + RIP: 0010:follow_huge_pmd+0x143/0x190 + RSP: 0018:ffffc90004bdbcd0 EFLAGS: 00010202 + RAX: 0000000465003e80 RBX: ffffea0004e34d30 RCX: 00003ffffffff000 + RDX: 0000000011943800 RSI: 0000000000080001 RDI: 0000000465003e80 + RBP: ffffc90004bdbd18 R08: 0000000000000000 R09: ffff880138d34000 + R10: ffffea0004650000 R11: 0000000000c363b0 R12: ffffea0011943800 + R13: ffff8801b8d34000 R14: ffffea0000000000 R15: 000077ff80000000 + FS: 00007fc977710740(0000) GS:ffff88007dc00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: ffffea0011943820 CR3: 000000007a746000 CR4: 00000000001406f0 + Call Trace: + follow_page_mask+0x270/0x550 + SYSC_move_pages+0x4ea/0x8f0 + SyS_move_pages+0xe/0x10 + do_syscall_64+0x67/0x180 + entry_SYSCALL64_slow_path+0x25/0x25 + RIP: 0033:0x7fc976e03949 + RSP: 002b:00007ffe72221d88 EFLAGS: 00000246 ORIG_RAX: 0000000000000117 + RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fc976e03949 + RDX: 0000000000c22390 RSI: 0000000000001400 RDI: 0000000000005827 + RBP: 00007ffe72221e00 R08: 0000000000c2c3a0 R09: 0000000000000004 + R10: 0000000000c363b0 R11: 0000000000000246 R12: 0000000000400650 + R13: 00007ffe72221ee0 R14: 0000000000000000 R15: 0000000000000000 + Code: 81 e4 ff ff 1f 00 48 21 c2 49 c1 ec 0c 48 c1 ea 0c 4c 01 e2 49 bc 00 00 00 00 00 ea ff ff 48 c1 e2 06 49 01 d4 f6 45 bc 04 74 90 <49> 8b 7c 24 20 40 f6 c7 01 75 2b 4c 89 e7 8b 47 1c 85 c0 7e 2a + RIP: follow_huge_pmd+0x143/0x190 RSP: ffffc90004bdbcd0 + CR2: ffffea0011943820 + ---[ end trace e4f81353a2d23232 ]--- + Kernel panic - not syncing: Fatal exception + Kernel Offset: disabled + +This bug is triggered when pmd_present() returns true for non-present +hugetlb, so fixing the present check in follow_huge_pmd() prevents it. +Using pmd_present() to determine present/non-present for hugetlb is not +correct, because pmd_present() checks multiple bits (not only +_PAGE_PRESENT) for historical reason and it can misjudge hugetlb state. + +Fixes: e66f17ff7177 ("mm/hugetlb: take page table lock in follow_huge_pmd()") +Link: http://lkml.kernel.org/r/1490149898-20231-1-git-send-email-n-horiguchi@ah.jp.nec.com +Signed-off-by: Naoya Horiguchi +Acked-by: Hillf Danton +Cc: Hugh Dickins +Cc: Michal Hocko +Cc: "Kirill A. Shutemov" +Cc: Mike Kravetz +Cc: Christian Borntraeger +Cc: Gerald Schaefer +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + mm/hugetlb.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index ea11123a9249..7294301d8495 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -4362,6 +4362,7 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, + { + struct page *page = NULL; + spinlock_t *ptl; ++ pte_t pte; + retry: + ptl = pmd_lockptr(mm, pmd); + spin_lock(ptl); +@@ -4371,12 +4372,13 @@ retry: + */ + if (!pmd_huge(*pmd)) + goto out; +- if (pmd_present(*pmd)) { ++ pte = huge_ptep_get((pte_t *)pmd); ++ if (pte_present(pte)) { + page = pmd_page(*pmd) + ((address & ~PMD_MASK) >> PAGE_SHIFT); + if (flags & FOLL_GET) + get_page(page); + } else { +- if (is_hugetlb_entry_migration(huge_ptep_get((pte_t *)pmd))) { ++ if (is_hugetlb_entry_migration(pte)) { + spin_unlock(ptl); + __migration_entry_wait(mm, (pte_t *)pmd, ptl); + goto retry; +-- +2.12.2 + +From 6280ac931a23d3fa40cd26057576abcf90a4f22d Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 19 Jan 2017 12:28:22 +0100 +Subject: [PATCH 241/251] MIPS: Lantiq: Fix cascaded IRQ setup +Content-Length: 3014 +Lines: 101 + +commit 6c356eda225e3ee134ed4176b9ae3a76f793f4dd upstream. + +With the IRQ stack changes integrated, the XRX200 devices started +emitting a constant stream of kernel messages like this: + +[ 565.415310] Spurious IRQ: CAUSE=0x1100c300 + +This is caused by IP0 getting handled by plat_irq_dispatch() rather than +its vectored interrupt handler, which is fixed by commit de856416e714 +("MIPS: IRQ Stack: Fix erroneous jal to plat_irq_dispatch"). + +Fix plat_irq_dispatch() to handle non-vectored IPI interrupts correctly +by setting up IP2-6 as proper chained IRQ handlers and calling do_IRQ +for all MIPS CPU interrupts. + +Signed-off-by: Felix Fietkau +Acked-by: John Crispin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15077/ +[james.hogan@imgtec.com: tweaked commit message] +Signed-off-by: James Hogan +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/lantiq/irq.c | 38 +++++++++++++++++--------------------- + 1 file changed, 17 insertions(+), 21 deletions(-) + +diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c +index 2e7f60c9fc5d..51cdc46a87e2 100644 +--- a/arch/mips/lantiq/irq.c ++++ b/arch/mips/lantiq/irq.c +@@ -269,6 +269,11 @@ static void ltq_hw5_irqdispatch(void) + DEFINE_HWx_IRQDISPATCH(5) + #endif + ++static void ltq_hw_irq_handler(struct irq_desc *desc) ++{ ++ ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2); ++} ++ + #ifdef CONFIG_MIPS_MT_SMP + void __init arch_init_ipiirq(int irq, struct irqaction *action) + { +@@ -313,23 +318,19 @@ static struct irqaction irq_call = { + asmlinkage void plat_irq_dispatch(void) + { + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; +- unsigned int i; +- +- if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) { +- do_IRQ(MIPS_CPU_TIMER_IRQ); +- goto out; +- } else { +- for (i = 0; i < MAX_IM; i++) { +- if (pending & (CAUSEF_IP2 << i)) { +- ltq_hw_irqdispatch(i); +- goto out; +- } +- } ++ int irq; ++ ++ if (!pending) { ++ spurious_interrupt(); ++ return; + } +- pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status()); + +-out: +- return; ++ pending >>= CAUSEB_IP; ++ while (pending) { ++ irq = fls(pending) - 1; ++ do_IRQ(MIPS_CPU_IRQ_BASE + irq); ++ pending &= ~BIT(irq); ++ } + } + + static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +@@ -354,11 +355,6 @@ static const struct irq_domain_ops irq_domain_ops = { + .map = icu_map, + }; + +-static struct irqaction cascade = { +- .handler = no_action, +- .name = "cascade", +-}; +- + int __init icu_of_init(struct device_node *node, struct device_node *parent) + { + struct device_node *eiu_node; +@@ -390,7 +386,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) + mips_cpu_irq_init(); + + for (i = 0; i < MAX_IM; i++) +- setup_irq(i + 2, &cascade); ++ irq_set_chained_handler(i + 2, ltq_hw_irq_handler); + + if (cpu_has_vint) { + pr_info("Setting up vectored interrupts\n"); +-- +2.12.2 + +From b3ed3864912e8809e228ddea259e8e0fa1deadf5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Sat, 2 Jul 2016 17:28:08 +0200 +Subject: [PATCH 242/251] rtc: s35390a: fix reading out alarm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 3107 +Lines: 91 + +commit f87e904ddd8f0ef120e46045b0addeb1cc88354e upstream. + +There are several issues fixed in this patch: + + - When alarm isn't enabled, set .enabled to zero instead of returning + -EINVAL. + - Ignore how IRQ1 is configured when determining if IRQ2 is on. + - The three alarm registers have an enable flag which must be + evaluated. + - The chip always triggers when the seconds register gets 0. + +Note that the rtc framework however doesn't handle the result correctly +because it doesn't check wday being initialized and so interprets an +alarm being set for 10:00 AM in three days as 10:00 AM tomorrow (or +today if that's not over yet). + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/rtc/rtc-s35390a.c | 40 +++++++++++++++++++++++++++++++--------- + 1 file changed, 31 insertions(+), 9 deletions(-) + +diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c +index f40afdd0e5f5..6507a01cf9ad 100644 +--- a/drivers/rtc/rtc-s35390a.c ++++ b/drivers/rtc/rtc-s35390a.c +@@ -242,6 +242,8 @@ static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) + + if (alm->time.tm_wday != -1) + buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80; ++ else ++ buf[S35390A_ALRM_BYTE_WDAY] = 0; + + buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a, + alm->time.tm_hour) | 0x80; +@@ -269,23 +271,43 @@ static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) + if (err < 0) + return err; + +- if (bitrev8(sts) != S35390A_INT2_MODE_ALARM) +- return -EINVAL; ++ if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) { ++ /* ++ * When the alarm isn't enabled, the register to configure ++ * the alarm time isn't accessible. ++ */ ++ alm->enabled = 0; ++ return 0; ++ } else { ++ alm->enabled = 1; ++ } + + err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf)); + if (err < 0) + return err; + + /* This chip returns the bits of each byte in reverse order */ +- for (i = 0; i < 3; ++i) { ++ for (i = 0; i < 3; ++i) + buf[i] = bitrev8(buf[i]); +- buf[i] &= ~0x80; +- } + +- alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]); +- alm->time.tm_hour = s35390a_reg2hr(s35390a, +- buf[S35390A_ALRM_BYTE_HOURS]); +- alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]); ++ /* ++ * B0 of the three matching registers is an enable flag. Iff it is set ++ * the configured value is used for matching. ++ */ ++ if (buf[S35390A_ALRM_BYTE_WDAY] & 0x80) ++ alm->time.tm_wday = ++ bcd2bin(buf[S35390A_ALRM_BYTE_WDAY] & ~0x80); ++ ++ if (buf[S35390A_ALRM_BYTE_HOURS] & 0x80) ++ alm->time.tm_hour = ++ s35390a_reg2hr(s35390a, ++ buf[S35390A_ALRM_BYTE_HOURS] & ~0x80); ++ ++ if (buf[S35390A_ALRM_BYTE_MINS] & 0x80) ++ alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS] & ~0x80); ++ ++ /* alarm triggers always at s=0 */ ++ alm->time.tm_sec = 0; + + dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n", + __func__, alm->time.tm_min, alm->time.tm_hour, +-- +2.12.2 + +From fdd4bc9313e59a1757cfc8ac5836cff55ec03eeb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 3 Apr 2017 23:32:38 +0200 +Subject: [PATCH 243/251] rtc: s35390a: make sure all members in the output are + set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 1582 +Lines: 45 + +The rtc core calls the .read_alarm with all fields initialized to 0. As +the s35390a driver doesn't touch some fields the returned date is +interpreted as a date in January 1900. So make sure all fields are set +to -1; some of them are then overwritten with the right data depending +on the hardware state. + +In mainline this is done by commit d68778b80dd7 ("rtc: initialize output +parameter for read alarm to "uninitialized"") in the core. This is +considered to dangerous for stable as it might have side effects for +other rtc drivers that might for example rely on alarm->time.tm_sec +being initialized to 0. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/rtc/rtc-s35390a.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c +index 6507a01cf9ad..47b88bbe4ce7 100644 +--- a/drivers/rtc/rtc-s35390a.c ++++ b/drivers/rtc/rtc-s35390a.c +@@ -267,6 +267,20 @@ static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) + char buf[3], sts; + int i, err; + ++ /* ++ * initialize all members to -1 to signal the core that they are not ++ * defined by the hardware. ++ */ ++ alm->time.tm_sec = -1; ++ alm->time.tm_min = -1; ++ alm->time.tm_hour = -1; ++ alm->time.tm_mday = -1; ++ alm->time.tm_mon = -1; ++ alm->time.tm_year = -1; ++ alm->time.tm_wday = -1; ++ alm->time.tm_yday = -1; ++ alm->time.tm_isdst = -1; ++ + err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); + if (err < 0) + return err; +-- +2.12.2 + +From a55ae9d1937b0bf4004e5416cfa15750cd6d2b22 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Sat, 2 Jul 2016 17:28:09 +0200 +Subject: [PATCH 244/251] rtc: s35390a: implement reset routine as suggested by + the reference +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 3792 +Lines: 124 + +commit 8e6583f1b5d1f5f129b873f1428b7e414263d847 upstream. + +There were two deviations from the reference manual: you have to wait +half a second when POC is active and you might have to repeat +initialization when POC or BLD are still set after the sequence. + +Note however that as POC and BLD are cleared by read the driver might +not be able to detect that a reset is necessary. I don't have a good +idea how to fix this. + +Additionally report the value read from STATUS1 to the caller. This +prepares the next patch. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/rtc/rtc-s35390a.c | 65 +++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 55 insertions(+), 10 deletions(-) + +diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c +index 47b88bbe4ce7..c7c1fce69635 100644 +--- a/drivers/rtc/rtc-s35390a.c ++++ b/drivers/rtc/rtc-s35390a.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #define S35390A_CMD_STATUS1 0 + #define S35390A_CMD_STATUS2 1 +@@ -94,19 +95,63 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len) + return 0; + } + +-static int s35390a_reset(struct s35390a *s35390a) ++/* ++ * Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset. ++ * To keep the information if an irq is pending, pass the value read from ++ * STATUS1 to the caller. ++ */ ++static int s35390a_reset(struct s35390a *s35390a, char *status1) + { +- char buf[1]; ++ char buf; ++ int ret; ++ unsigned initcount = 0; + +- if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0) +- return -EIO; ++ ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1); ++ if (ret < 0) ++ return ret; + +- if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD))) ++ if (*status1 & S35390A_FLAG_POC) ++ /* ++ * Do not communicate for 0.5 seconds since the power-on ++ * detection circuit is in operation. ++ */ ++ msleep(500); ++ else if (!(*status1 & S35390A_FLAG_BLD)) ++ /* ++ * If both POC and BLD are unset everything is fine. ++ */ + return 0; + +- buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H); +- buf[0] &= 0xf0; +- return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); ++ /* ++ * At least one of POC and BLD are set, so reinitialise chip. Keeping ++ * this information in the hardware to know later that the time isn't ++ * valid is unfortunately not possible because POC and BLD are cleared ++ * on read. So the reset is best done now. ++ * ++ * The 24H bit is kept over reset, so set it already here. ++ */ ++initialize: ++ *status1 = S35390A_FLAG_24H; ++ buf = S35390A_FLAG_RESET | S35390A_FLAG_24H; ++ ret = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1); ++ ++ if (ret < 0) ++ return ret; ++ ++ ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1); ++ if (ret < 0) ++ return ret; ++ ++ if (buf & (S35390A_FLAG_POC | S35390A_FLAG_BLD)) { ++ /* Try up to five times to reset the chip */ ++ if (initcount < 5) { ++ ++initcount; ++ goto initialize; ++ } else ++ return -EIO; ++ } ++ ++ return 1; + } + + static int s35390a_disable_test_mode(struct s35390a *s35390a) +@@ -367,7 +412,7 @@ static int s35390a_probe(struct i2c_client *client, + unsigned int i; + struct s35390a *s35390a; + struct rtc_time tm; +- char buf[1]; ++ char buf[1], status1; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + err = -ENODEV; +@@ -396,7 +441,7 @@ static int s35390a_probe(struct i2c_client *client, + } + } + +- err = s35390a_reset(s35390a); ++ err = s35390a_reset(s35390a, &status1); + if (err < 0) { + dev_err(&client->dev, "error resetting chip\n"); + goto exit_dummy; +-- +2.12.2 + +From 3a1246b46df5210164ee43d4c5c560d0dc9ed2ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Sat, 2 Jul 2016 17:28:10 +0200 +Subject: [PATCH 245/251] rtc: s35390a: improve irq handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Length: 3693 +Lines: 120 + +commit 3bd32722c827d00eafe8e6d5b83e9f3148ea7c7e upstream. + +On some QNAP NAS devices the rtc can wake the machine. Several people +noticed that once the machine was woken this way it fails to shut down. +That's because the driver fails to acknowledge the interrupt and so it +keeps active and restarts the machine immediatly after shutdown. See +https://bugs.debian.org/794266 for a bug report. + +Doing this correctly requires to interpret the INT2 flag of the first read +of the STATUS1 register because this bit is cleared by read. + +Note this is not maximally robust though because a pending irq isn't +detected when the STATUS1 register was already read (and so INT2 is not +set) but the irq was not disabled. But that is a hardware imposed problem +that cannot easily be fixed by software. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/rtc/rtc-s35390a.c | 48 ++++++++++++++++++++++++++++++----------------- + 1 file changed, 31 insertions(+), 17 deletions(-) + +diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c +index c7c1fce69635..00662dd28d66 100644 +--- a/drivers/rtc/rtc-s35390a.c ++++ b/drivers/rtc/rtc-s35390a.c +@@ -35,10 +35,14 @@ + #define S35390A_ALRM_BYTE_HOURS 1 + #define S35390A_ALRM_BYTE_MINS 2 + ++/* flags for STATUS1 */ + #define S35390A_FLAG_POC 0x01 + #define S35390A_FLAG_BLD 0x02 ++#define S35390A_FLAG_INT2 0x04 + #define S35390A_FLAG_24H 0x40 + #define S35390A_FLAG_RESET 0x80 ++ ++/* flag for STATUS2 */ + #define S35390A_FLAG_TEST 0x01 + + #define S35390A_INT2_MODE_MASK 0xF0 +@@ -408,11 +412,11 @@ static struct i2c_driver s35390a_driver; + static int s35390a_probe(struct i2c_client *client, + const struct i2c_device_id *id) + { +- int err; ++ int err, err_reset; + unsigned int i; + struct s35390a *s35390a; + struct rtc_time tm; +- char buf[1], status1; ++ char buf, status1; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + err = -ENODEV; +@@ -441,29 +445,35 @@ static int s35390a_probe(struct i2c_client *client, + } + } + +- err = s35390a_reset(s35390a, &status1); +- if (err < 0) { ++ err_reset = s35390a_reset(s35390a, &status1); ++ if (err_reset < 0) { ++ err = err_reset; + dev_err(&client->dev, "error resetting chip\n"); + goto exit_dummy; + } + +- err = s35390a_disable_test_mode(s35390a); +- if (err < 0) { +- dev_err(&client->dev, "error disabling test mode\n"); +- goto exit_dummy; +- } +- +- err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); +- if (err < 0) { +- dev_err(&client->dev, "error checking 12/24 hour mode\n"); +- goto exit_dummy; +- } +- if (buf[0] & S35390A_FLAG_24H) ++ if (status1 & S35390A_FLAG_24H) + s35390a->twentyfourhour = 1; + else + s35390a->twentyfourhour = 0; + +- if (s35390a_get_datetime(client, &tm) < 0) ++ if (status1 & S35390A_FLAG_INT2) { ++ /* disable alarm (and maybe test mode) */ ++ buf = 0; ++ err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1); ++ if (err < 0) { ++ dev_err(&client->dev, "error disabling alarm"); ++ goto exit_dummy; ++ } ++ } else { ++ err = s35390a_disable_test_mode(s35390a); ++ if (err < 0) { ++ dev_err(&client->dev, "error disabling test mode\n"); ++ goto exit_dummy; ++ } ++ } ++ ++ if (err_reset > 0 || s35390a_get_datetime(client, &tm) < 0) + dev_warn(&client->dev, "clock needs to be set\n"); + + device_set_wakeup_capable(&client->dev, 1); +@@ -476,6 +486,10 @@ static int s35390a_probe(struct i2c_client *client, + err = PTR_ERR(s35390a->rtc); + goto exit_dummy; + } ++ ++ if (status1 & S35390A_FLAG_INT2) ++ rtc_update_irq(s35390a->rtc, 1, RTC_AF); ++ + return 0; + + exit_dummy: +-- +2.12.2 + +From 42462d23e60b89a3c2f7d8d63f5f4e464ba77727 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Thu, 23 Mar 2017 18:24:19 +0100 +Subject: [PATCH 246/251] KVM: kvm_io_bus_unregister_dev() should never fail +Content-Length: 5392 +Lines: 167 + +commit 90db10434b163e46da413d34db8d0e77404cc645 upstream. + +No caller currently checks the return value of +kvm_io_bus_unregister_dev(). This is evil, as all callers silently go on +freeing their device. A stale reference will remain in the io_bus, +getting at least used again, when the iobus gets teared down on +kvm_destroy_vm() - leading to use after free errors. + +There is nothing the callers could do, except retrying over and over +again. + +So let's simply remove the bus altogether, print an error and make +sure no one can access this broken bus again (returning -ENOMEM on any +attempt to access it). + +Fixes: e93f8a0f821e ("KVM: convert io_bus to SRCU") +Reported-by: Dmitry Vyukov +Reviewed-by: Cornelia Huck +Signed-off-by: David Hildenbrand +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/kvm_host.h | 4 ++-- + virt/kvm/eventfd.c | 3 ++- + virt/kvm/kvm_main.c | 40 +++++++++++++++++++++++----------------- + 3 files changed, 27 insertions(+), 20 deletions(-) + +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index c923350ca20a..d7ce4e3280db 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -182,8 +182,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr, + int len, void *val); + int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, + int len, struct kvm_io_device *dev); +-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, +- struct kvm_io_device *dev); ++void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, ++ struct kvm_io_device *dev); + + #ifdef CONFIG_KVM_ASYNC_PF + struct kvm_async_pf { +diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c +index 46dbc0a7dfc1..49001fa84ead 100644 +--- a/virt/kvm/eventfd.c ++++ b/virt/kvm/eventfd.c +@@ -868,7 +868,8 @@ kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx, + continue; + + kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev); +- kvm->buses[bus_idx]->ioeventfd_count--; ++ if (kvm->buses[bus_idx]) ++ kvm->buses[bus_idx]->ioeventfd_count--; + ioeventfd_release(p); + ret = 0; + break; +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 1ac5b7be7282..cb092bd9965b 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -655,7 +655,8 @@ static void kvm_destroy_vm(struct kvm *kvm) + spin_unlock(&kvm_lock); + kvm_free_irq_routing(kvm); + for (i = 0; i < KVM_NR_BUSES; i++) { +- kvm_io_bus_destroy(kvm->buses[i]); ++ if (kvm->buses[i]) ++ kvm_io_bus_destroy(kvm->buses[i]); + kvm->buses[i] = NULL; + } + kvm_coalesced_mmio_free(kvm); +@@ -3273,6 +3274,8 @@ int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr, + }; + + bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu); ++ if (!bus) ++ return -ENOMEM; + r = __kvm_io_bus_write(vcpu, bus, &range, val); + return r < 0 ? r : 0; + } +@@ -3290,6 +3293,8 @@ int kvm_io_bus_write_cookie(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, + }; + + bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu); ++ if (!bus) ++ return -ENOMEM; + + /* First try the device referenced by cookie. */ + if ((cookie >= 0) && (cookie < bus->dev_count) && +@@ -3340,6 +3345,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr, + }; + + bus = srcu_dereference(vcpu->kvm->buses[bus_idx], &vcpu->kvm->srcu); ++ if (!bus) ++ return -ENOMEM; + r = __kvm_io_bus_read(vcpu, bus, &range, val); + return r < 0 ? r : 0; + } +@@ -3352,6 +3359,9 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, + struct kvm_io_bus *new_bus, *bus; + + bus = kvm->buses[bus_idx]; ++ if (!bus) ++ return -ENOMEM; ++ + /* exclude ioeventfd which is limited by maximum fd */ + if (bus->dev_count - bus->ioeventfd_count > NR_IOBUS_DEVS - 1) + return -ENOSPC; +@@ -3371,45 +3381,41 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, + } + + /* Caller must hold slots_lock. */ +-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, +- struct kvm_io_device *dev) ++void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, ++ struct kvm_io_device *dev) + { +- int i, r; ++ int i; + struct kvm_io_bus *new_bus, *bus; + + bus = kvm->buses[bus_idx]; +- +- /* +- * It's possible the bus being released before hand. If so, +- * we're done here. +- */ + if (!bus) +- return 0; ++ return; + +- r = -ENOENT; + for (i = 0; i < bus->dev_count; i++) + if (bus->range[i].dev == dev) { +- r = 0; + break; + } + +- if (r) +- return r; ++ if (i == bus->dev_count) ++ return; + + new_bus = kmalloc(sizeof(*bus) + ((bus->dev_count - 1) * + sizeof(struct kvm_io_range)), GFP_KERNEL); +- if (!new_bus) +- return -ENOMEM; ++ if (!new_bus) { ++ pr_err("kvm: failed to shrink bus, removing it completely\n"); ++ goto broken; ++ } + + memcpy(new_bus, bus, sizeof(*bus) + i * sizeof(struct kvm_io_range)); + new_bus->dev_count--; + memcpy(new_bus->range + i, bus->range + i + 1, + (new_bus->dev_count - i) * sizeof(struct kvm_io_range)); + ++broken: + rcu_assign_pointer(kvm->buses[bus_idx], new_bus); + synchronize_srcu_expedited(&kvm->srcu); + kfree(bus); +- return r; ++ return; + } + + static struct notifier_block kvm_cpu_notifier = { +-- +2.12.2 + +From 063d30f187f5c492aa4a6cca88b8afa08f5a170c Mon Sep 17 00:00:00 2001 +From: Alexandre Belloni +Date: Tue, 25 Oct 2016 11:37:59 +0200 +Subject: [PATCH 247/251] power: reset: at91-poweroff: timely shutdown LPDDR + memories +Content-Length: 3667 +Lines: 122 + +commit 0b0408745e7ff24757cbfd571d69026c0ddb803c upstream. + +LPDDR memories can only handle up to 400 uncontrolled power off. Ensure the +proper power off sequence is used before shutting down the platform. + +Signed-off-by: Alexandre Belloni +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/power/reset/at91-poweroff.c | 54 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 53 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c +index e9e24df35f26..2579f025b90b 100644 +--- a/drivers/power/reset/at91-poweroff.c ++++ b/drivers/power/reset/at91-poweroff.c +@@ -14,9 +14,12 @@ + #include + #include + #include ++#include + #include + #include + ++#include ++ + #define AT91_SHDW_CR 0x00 /* Shut Down Control Register */ + #define AT91_SHDW_SHDW BIT(0) /* Shut Down command */ + #define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ +@@ -50,6 +53,7 @@ static const char *shdwc_wakeup_modes[] = { + + static void __iomem *at91_shdwc_base; + static struct clk *sclk; ++static void __iomem *mpddrc_base; + + static void __init at91_wakeup_status(void) + { +@@ -73,6 +77,29 @@ static void at91_poweroff(void) + writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR); + } + ++static void at91_lpddr_poweroff(void) ++{ ++ asm volatile( ++ /* Align to cache lines */ ++ ".balign 32\n\t" ++ ++ /* Ensure AT91_SHDW_CR is in the TLB by reading it */ ++ " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t" ++ ++ /* Power down SDRAM0 */ ++ " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t" ++ /* Shutdown CPU */ ++ " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t" ++ ++ " b .\n\t" ++ : ++ : "r" (mpddrc_base), ++ "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF), ++ "r" (at91_shdwc_base), ++ "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW) ++ : "r0"); ++} ++ + static int at91_poweroff_get_wakeup_mode(struct device_node *np) + { + const char *pm; +@@ -124,6 +151,8 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev) + static int __init at91_poweroff_probe(struct platform_device *pdev) + { + struct resource *res; ++ struct device_node *np; ++ u32 ddr_type; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -150,12 +179,30 @@ static int __init at91_poweroff_probe(struct platform_device *pdev) + + pm_power_off = at91_poweroff; + ++ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc"); ++ if (!np) ++ return 0; ++ ++ mpddrc_base = of_iomap(np, 0); ++ of_node_put(np); ++ ++ if (!mpddrc_base) ++ return 0; ++ ++ ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD; ++ if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) || ++ (ddr_type == AT91_DDRSDRC_MD_LPDDR3)) ++ pm_power_off = at91_lpddr_poweroff; ++ else ++ iounmap(mpddrc_base); ++ + return 0; + } + + static int __exit at91_poweroff_remove(struct platform_device *pdev) + { +- if (pm_power_off == at91_poweroff) ++ if (pm_power_off == at91_poweroff || ++ pm_power_off == at91_lpddr_poweroff) + pm_power_off = NULL; + + clk_disable_unprepare(sclk); +@@ -163,6 +210,11 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev) + return 0; + } + ++static const struct of_device_id at91_ramc_of_match[] = { ++ { .compatible = "atmel,sama5d3-ddramc", }, ++ { /* sentinel */ } ++}; ++ + static const struct of_device_id at91_poweroff_of_match[] = { + { .compatible = "atmel,at91sam9260-shdwc", }, + { .compatible = "atmel,at91sam9rl-shdwc", }, +-- +2.12.2 + +From 2cbd78f4239bd28b86c6ff8e3b7867db72762f1a Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 8 Mar 2017 07:38:05 +1100 +Subject: [PATCH 248/251] blk: improve order of bio handling in + generic_make_request() +Content-Length: 5024 +Lines: 114 + +commit 79bd99596b7305ab08109a8bf44a6a4511dbf1cd upstream. + +To avoid recursion on the kernel stack when stacked block devices +are in use, generic_make_request() will, when called recursively, +queue new requests for later handling. They will be handled when the +make_request_fn for the current bio completes. + +If any bios are submitted by a make_request_fn, these will ultimately +be handled seqeuntially. If the handling of one of those generates +further requests, they will be added to the end of the queue. + +This strict first-in-first-out behaviour can lead to deadlocks in +various ways, normally because a request might need to wait for a +previous request to the same device to complete. This can happen when +they share a mempool, and can happen due to interdependencies +particular to the device. Both md and dm have examples where this happens. + +These deadlocks can be erradicated by more selective ordering of bios. +Specifically by handling them in depth-first order. That is: when the +handling of one bio generates one or more further bios, they are +handled immediately after the parent, before any siblings of the +parent. That way, when generic_make_request() calls make_request_fn +for some particular device, we can be certain that all previously +submited requests for that device have been completely handled and are +not waiting for anything in the queue of requests maintained in +generic_make_request(). + +An easy way to achieve this would be to use a last-in-first-out stack +instead of a queue. However this will change the order of consecutive +bios submitted by a make_request_fn, which could have unexpected consequences. +Instead we take a slightly more complex approach. +A fresh queue is created for each call to a make_request_fn. After it completes, +any bios for a different device are placed on the front of the main queue, followed +by any bios for the same device, followed by all bios that were already on +the queue before the make_request_fn was called. +This provides the depth-first approach without reordering bios on the same level. + +This, by itself, it not enough to remove all deadlocks. It just makes +it possible for drivers to take the extra step required themselves. + +To avoid deadlocks, drivers must never risk waiting for a request +after submitting one to generic_make_request. This includes never +allocing from a mempool twice in the one call to a make_request_fn. + +A common pattern in drivers is to call bio_split() in a loop, handling +the first part and then looping around to possibly split the next part. +Instead, a driver that finds it needs to split a bio should queue +(with generic_make_request) the second part, handle the first part, +and then return. The new code in generic_make_request will ensure the +requests to underlying bios are processed first, then the second bio +that was split off. If it splits again, the same process happens. In +each case one bio will be completely handled before the next one is attempted. + +With this is place, it should be possible to disable the +punt_bios_to_recover() recovery thread for many block devices, and +eventually it may be possible to remove it completely. + +Ref: http://www.spinics.net/lists/raid/msg54680.html +Tested-by: Jinpu Wang +Inspired-by: Lars Ellenberg +Signed-off-by: NeilBrown +Signed-off-by: Jens Axboe +[jwang: backport to 4.4] +Signed-off-by: Jack Wang +Signed-off-by: Greg Kroah-Hartman +--- + block/blk-core.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 4fab5d610805..7a58a22d1595 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -2063,18 +2063,33 @@ blk_qc_t generic_make_request(struct bio *bio) + struct request_queue *q = bdev_get_queue(bio->bi_bdev); + + if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) { ++ struct bio_list lower, same, hold; ++ ++ /* Create a fresh bio_list for all subordinate requests */ ++ hold = bio_list_on_stack; ++ bio_list_init(&bio_list_on_stack); + + ret = q->make_request_fn(q, bio); + + blk_queue_exit(q); +- +- bio = bio_list_pop(current->bio_list); ++ /* sort new bios into those for a lower level ++ * and those for the same level ++ */ ++ bio_list_init(&lower); ++ bio_list_init(&same); ++ while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL) ++ if (q == bdev_get_queue(bio->bi_bdev)) ++ bio_list_add(&same, bio); ++ else ++ bio_list_add(&lower, bio); ++ /* now assemble so we handle the lowest level first */ ++ bio_list_merge(&bio_list_on_stack, &lower); ++ bio_list_merge(&bio_list_on_stack, &same); ++ bio_list_merge(&bio_list_on_stack, &hold); + } else { +- struct bio *bio_next = bio_list_pop(current->bio_list); +- + bio_io_error(bio); +- bio = bio_next; + } ++ bio = bio_list_pop(current->bio_list); + } while (bio); + current->bio_list = NULL; /* deactivate */ + +-- +2.12.2 + +From 5cca175b6cda16b68b18967210872327b1cadf4f Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 10 Mar 2017 17:00:47 +1100 +Subject: [PATCH 249/251] blk: Ensure users for current->bio_list can see the + full list. +Content-Length: 7421 +Lines: 217 + +commit f5fe1b51905df7cfe4fdfd85c5fb7bc5b71a094f upstream. + +Commit 79bd99596b73 ("blk: improve order of bio handling in generic_make_request()") +changed current->bio_list so that it did not contain *all* of the +queued bios, but only those submitted by the currently running +make_request_fn. + +There are two places which walk the list and requeue selected bios, +and others that check if the list is empty. These are no longer +correct. + +So redefine current->bio_list to point to an array of two lists, which +contain all queued bios, and adjust various code to test or walk both +lists. + +Signed-off-by: NeilBrown +Fixes: 79bd99596b73 ("blk: improve order of bio handling in generic_make_request()") +Signed-off-by: Jens Axboe +[jwang: backport to 4.4] +Signed-off-by: Jack Wang +Signed-off-by: Greg Kroah-Hartman +[bwh: Restore changes in device-mapper from upstream version] +Signed-off-by: Ben Hutchings +--- + block/bio.c | 12 +++++++++--- + block/blk-core.c | 31 +++++++++++++++++++------------ + drivers/md/dm.c | 29 ++++++++++++++++------------- + drivers/md/raid1.c | 3 ++- + drivers/md/raid10.c | 3 ++- + 5 files changed, 48 insertions(+), 30 deletions(-) + +diff --git a/block/bio.c b/block/bio.c +index 46e2cc1d4016..14263fab94d3 100644 +--- a/block/bio.c ++++ b/block/bio.c +@@ -373,10 +373,14 @@ static void punt_bios_to_rescuer(struct bio_set *bs) + bio_list_init(&punt); + bio_list_init(&nopunt); + +- while ((bio = bio_list_pop(current->bio_list))) ++ while ((bio = bio_list_pop(¤t->bio_list[0]))) + bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); ++ current->bio_list[0] = nopunt; + +- *current->bio_list = nopunt; ++ bio_list_init(&nopunt); ++ while ((bio = bio_list_pop(¤t->bio_list[1]))) ++ bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); ++ current->bio_list[1] = nopunt; + + spin_lock(&bs->rescue_lock); + bio_list_merge(&bs->rescue_list, &punt); +@@ -464,7 +468,9 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) + * we retry with the original gfp_flags. + */ + +- if (current->bio_list && !bio_list_empty(current->bio_list)) ++ if (current->bio_list && ++ (!bio_list_empty(¤t->bio_list[0]) || ++ !bio_list_empty(¤t->bio_list[1]))) + gfp_mask &= ~__GFP_DIRECT_RECLAIM; + + p = mempool_alloc(bs->bio_pool, gfp_mask); +diff --git a/block/blk-core.c b/block/blk-core.c +index 7a58a22d1595..ef083e7a37c5 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -2021,7 +2021,14 @@ end_io: + */ + blk_qc_t generic_make_request(struct bio *bio) + { +- struct bio_list bio_list_on_stack; ++ /* ++ * bio_list_on_stack[0] contains bios submitted by the current ++ * make_request_fn. ++ * bio_list_on_stack[1] contains bios that were submitted before ++ * the current make_request_fn, but that haven't been processed ++ * yet. ++ */ ++ struct bio_list bio_list_on_stack[2]; + blk_qc_t ret = BLK_QC_T_NONE; + + if (!generic_make_request_checks(bio)) +@@ -2038,7 +2045,7 @@ blk_qc_t generic_make_request(struct bio *bio) + * should be added at the tail + */ + if (current->bio_list) { +- bio_list_add(current->bio_list, bio); ++ bio_list_add(¤t->bio_list[0], bio); + goto out; + } + +@@ -2057,17 +2064,17 @@ blk_qc_t generic_make_request(struct bio *bio) + * bio_list, and call into ->make_request() again. + */ + BUG_ON(bio->bi_next); +- bio_list_init(&bio_list_on_stack); +- current->bio_list = &bio_list_on_stack; ++ bio_list_init(&bio_list_on_stack[0]); ++ current->bio_list = bio_list_on_stack; + do { + struct request_queue *q = bdev_get_queue(bio->bi_bdev); + + if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) { +- struct bio_list lower, same, hold; ++ struct bio_list lower, same; + + /* Create a fresh bio_list for all subordinate requests */ +- hold = bio_list_on_stack; +- bio_list_init(&bio_list_on_stack); ++ bio_list_on_stack[1] = bio_list_on_stack[0]; ++ bio_list_init(&bio_list_on_stack[0]); + + ret = q->make_request_fn(q, bio); + +@@ -2077,19 +2084,19 @@ blk_qc_t generic_make_request(struct bio *bio) + */ + bio_list_init(&lower); + bio_list_init(&same); +- while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL) ++ while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL) + if (q == bdev_get_queue(bio->bi_bdev)) + bio_list_add(&same, bio); + else + bio_list_add(&lower, bio); + /* now assemble so we handle the lowest level first */ +- bio_list_merge(&bio_list_on_stack, &lower); +- bio_list_merge(&bio_list_on_stack, &same); +- bio_list_merge(&bio_list_on_stack, &hold); ++ bio_list_merge(&bio_list_on_stack[0], &lower); ++ bio_list_merge(&bio_list_on_stack[0], &same); ++ bio_list_merge(&bio_list_on_stack[0], &bio_list_on_stack[1]); + } else { + bio_io_error(bio); + } +- bio = bio_list_pop(current->bio_list); ++ bio = bio_list_pop(&bio_list_on_stack[0]); + } while (bio); + current->bio_list = NULL; /* deactivate */ + +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 397f0454100b..320eb3c4bb6b 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1481,26 +1481,29 @@ static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule) + struct dm_offload *o = container_of(cb, struct dm_offload, cb); + struct bio_list list; + struct bio *bio; ++ int i; + + INIT_LIST_HEAD(&o->cb.list); + + if (unlikely(!current->bio_list)) + return; + +- list = *current->bio_list; +- bio_list_init(current->bio_list); +- +- while ((bio = bio_list_pop(&list))) { +- struct bio_set *bs = bio->bi_pool; +- if (unlikely(!bs) || bs == fs_bio_set) { +- bio_list_add(current->bio_list, bio); +- continue; ++ for (i = 0; i < 2; i++) { ++ list = current->bio_list[i]; ++ bio_list_init(¤t->bio_list[i]); ++ ++ while ((bio = bio_list_pop(&list))) { ++ struct bio_set *bs = bio->bi_pool; ++ if (unlikely(!bs) || bs == fs_bio_set) { ++ bio_list_add(¤t->bio_list[i], bio); ++ continue; ++ } ++ ++ spin_lock(&bs->rescue_lock); ++ bio_list_add(&bs->rescue_list, bio); ++ queue_work(bs->rescue_workqueue, &bs->rescue_work); ++ spin_unlock(&bs->rescue_lock); + } +- +- spin_lock(&bs->rescue_lock); +- bio_list_add(&bs->rescue_list, bio); +- queue_work(bs->rescue_workqueue, &bs->rescue_work); +- spin_unlock(&bs->rescue_lock); + } + } + +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index 515554c7365b..9be39988bf06 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -877,7 +877,8 @@ static sector_t wait_barrier(struct r1conf *conf, struct bio *bio) + ((conf->start_next_window < + conf->next_resync + RESYNC_SECTORS) && + current->bio_list && +- !bio_list_empty(current->bio_list))), ++ (!bio_list_empty(¤t->bio_list[0]) || ++ !bio_list_empty(¤t->bio_list[1])))), + conf->resync_lock); + conf->nr_waiting--; + } +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index a92979e704e3..e5ee4e9e0ea5 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -946,7 +946,8 @@ static void wait_barrier(struct r10conf *conf) + !conf->barrier || + (conf->nr_pending && + current->bio_list && +- !bio_list_empty(current->bio_list)), ++ (!bio_list_empty(¤t->bio_list[0]) || ++ !bio_list_empty(¤t->bio_list[1]))), + conf->resync_lock); + conf->nr_waiting--; + } +-- +2.12.2 + +From 84bd21a708b83a24d26cd0010ea94106c96557de Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" +Date: Thu, 23 Mar 2017 12:24:43 +0100 +Subject: [PATCH 250/251] padata: avoid race in reordering +Content-Length: 3216 +Lines: 92 + +commit de5540d088fe97ad583cc7d396586437b32149a5 upstream. + +Under extremely heavy uses of padata, crashes occur, and with list +debugging turned on, this happens instead: + +[87487.298728] WARNING: CPU: 1 PID: 882 at lib/list_debug.c:33 +__list_add+0xae/0x130 +[87487.301868] list_add corruption. prev->next should be next +(ffffb17abfc043d0), but was ffff8dba70872c80. (prev=ffff8dba70872b00). +[87487.339011] [] dump_stack+0x68/0xa3 +[87487.342198] [] ? console_unlock+0x281/0x6d0 +[87487.345364] [] __warn+0xff/0x140 +[87487.348513] [] warn_slowpath_fmt+0x4a/0x50 +[87487.351659] [] __list_add+0xae/0x130 +[87487.354772] [] ? _raw_spin_lock+0x64/0x70 +[87487.357915] [] padata_reorder+0x1e6/0x420 +[87487.361084] [] padata_do_serial+0xa5/0x120 + +padata_reorder calls list_add_tail with the list to which its adding +locked, which seems correct: + +spin_lock(&squeue->serial.lock); +list_add_tail(&padata->list, &squeue->serial.list); +spin_unlock(&squeue->serial.lock); + +This therefore leaves only place where such inconsistency could occur: +if padata->list is added at the same time on two different threads. +This pdata pointer comes from the function call to +padata_get_next(pd), which has in it the following block: + +next_queue = per_cpu_ptr(pd->pqueue, cpu); +padata = NULL; +reorder = &next_queue->reorder; +if (!list_empty(&reorder->list)) { + padata = list_entry(reorder->list.next, + struct padata_priv, list); + spin_lock(&reorder->lock); + list_del_init(&padata->list); + atomic_dec(&pd->reorder_objects); + spin_unlock(&reorder->lock); + + pd->processed++; + + goto out; +} +out: +return padata; + +I strongly suspect that the problem here is that two threads can race +on reorder list. Even though the deletion is locked, call to +list_entry is not locked, which means it's feasible that two threads +pick up the same padata object and subsequently call list_add_tail on +them at the same time. The fix is thus be hoist that lock outside of +that block. + +Signed-off-by: Jason A. Donenfeld +Acked-by: Steffen Klassert +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + kernel/padata.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/kernel/padata.c b/kernel/padata.c +index b38bea9c466a..401227e3967c 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -189,19 +189,20 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd) + + reorder = &next_queue->reorder; + ++ spin_lock(&reorder->lock); + if (!list_empty(&reorder->list)) { + padata = list_entry(reorder->list.next, + struct padata_priv, list); + +- spin_lock(&reorder->lock); + list_del_init(&padata->list); + atomic_dec(&pd->reorder_objects); +- spin_unlock(&reorder->lock); + + pd->processed++; + ++ spin_unlock(&reorder->lock); + goto out; + } ++ spin_unlock(&reorder->lock); + + if (__this_cpu_read(pd->pqueue->cpu_index) == next_queue->cpu_index) { + padata = ERR_PTR(-ENODATA); +-- +2.12.2 + +From 8f8ee9706b0a64a3506b9d9789ace7c44f3d817d Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Sat, 8 Apr 2017 09:53:53 +0200 +Subject: [PATCH 251/251] Linux 4.4.60 +Content-Length: 301 +Lines: 18 + +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 083724c6ca4d..fb7c2b40753d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 59 ++SUBLEVEL = 60 + EXTRAVERSION = + NAME = Blurry Fish Butt + +-- +2.12.2 + -- 2.47.3