--- /dev/null
+From 44330ab516c15dda8a1e660eeaf0003f84e43e3f Mon Sep 17 00:00:00 2001
+From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
+Date: Tue, 13 May 2014 13:45:15 +0100
+Subject: ASoC: wm8962: Update register CLASS_D_CONTROL_1 to be non-volatile
+
+From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
+
+commit 44330ab516c15dda8a1e660eeaf0003f84e43e3f upstream.
+
+The register CLASS_D_CONTROL_1 is marked as volatile because it contains
+a bit, DAC_MUTE, which is also mirrored in the ADC_DAC_CONTROL_1
+register. This causes problems for the "Speaker Switch" control, which
+will report an error if the CODEC is suspended because it relies on a
+volatile register.
+
+To resolve this issue mark CLASS_D_CONTROL_1 as non-volatile and
+manually keep the register cache in sync by updating both bits when
+changing the mute status.
+
+Reported-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
+Tested-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm8962.c | 15 ++++++++++++---
+ sound/soc/codecs/wm8962.h | 4 ++++
+ 2 files changed, 16 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/codecs/wm8962.c
++++ b/sound/soc/codecs/wm8962.c
+@@ -153,6 +153,7 @@ static struct reg_default wm8962_reg[] =
+ { 40, 0x0000 }, /* R40 - SPKOUTL volume */
+ { 41, 0x0000 }, /* R41 - SPKOUTR volume */
+
++ { 49, 0x0010 }, /* R49 - Class D Control 1 */
+ { 51, 0x0003 }, /* R51 - Class D Control 2 */
+
+ { 56, 0x0506 }, /* R56 - Clocking 4 */
+@@ -794,7 +795,6 @@ static bool wm8962_volatile_register(str
+ case WM8962_ALC2:
+ case WM8962_THERMAL_SHUTDOWN_STATUS:
+ case WM8962_ADDITIONAL_CONTROL_4:
+- case WM8962_CLASS_D_CONTROL_1:
+ case WM8962_DC_SERVO_6:
+ case WM8962_INTERRUPT_STATUS_1:
+ case WM8962_INTERRUPT_STATUS_2:
+@@ -2901,13 +2901,22 @@ static int wm8962_set_fll(struct snd_soc
+ static int wm8962_mute(struct snd_soc_dai *dai, int mute)
+ {
+ struct snd_soc_codec *codec = dai->codec;
+- int val;
++ int val, ret;
+
+ if (mute)
+- val = WM8962_DAC_MUTE;
++ val = WM8962_DAC_MUTE | WM8962_DAC_MUTE_ALT;
+ else
+ val = 0;
+
++ /**
++ * The DAC mute bit is mirrored in two registers, update both to keep
++ * the register cache consistent.
++ */
++ ret = snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_1,
++ WM8962_DAC_MUTE_ALT, val);
++ if (ret < 0)
++ return ret;
++
+ return snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
+ WM8962_DAC_MUTE, val);
+ }
+--- a/sound/soc/codecs/wm8962.h
++++ b/sound/soc/codecs/wm8962.h
+@@ -1954,6 +1954,10 @@
+ #define WM8962_SPKOUTL_ENA_MASK 0x0040 /* SPKOUTL_ENA */
+ #define WM8962_SPKOUTL_ENA_SHIFT 6 /* SPKOUTL_ENA */
+ #define WM8962_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
++#define WM8962_DAC_MUTE_ALT 0x0010 /* DAC_MUTE */
++#define WM8962_DAC_MUTE_ALT_MASK 0x0010 /* DAC_MUTE */
++#define WM8962_DAC_MUTE_ALT_SHIFT 4 /* DAC_MUTE */
++#define WM8962_DAC_MUTE_ALT_WIDTH 1 /* DAC_MUTE */
+ #define WM8962_SPKOUTL_PGA_MUTE 0x0002 /* SPKOUTL_PGA_MUTE */
+ #define WM8962_SPKOUTL_PGA_MUTE_MASK 0x0002 /* SPKOUTL_PGA_MUTE */
+ #define WM8962_SPKOUTL_PGA_MUTE_SHIFT 1 /* SPKOUTL_PGA_MUTE */
--- /dev/null
+From 83f7a85f1134c6e914453f5747435415a23d516b Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Sun, 13 Apr 2014 16:03:11 +0300
+Subject: iwlwifi: pcie: disable interrupts upon PCIe alloc
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit 83f7a85f1134c6e914453f5747435415a23d516b upstream.
+
+In case RFKILL is in KILL position, the NIC will issue an
+interrupt straight away. This interrupt won't be sent
+because it is masked in the hardware.
+But if our interrupt service routine is called for another
+reason (SHARED_IRQ), then we'll look at the interrupt cause
+and service it. This can cause bad things if we are not
+ready yet.
+Explicitly clean the interrupt cause register to make sure
+we won't service anything before we are ready to.
+
+Reported-and-tested-by: Alexander Monakov <amonakov@gmail.com>
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/pcie/trans.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
+@@ -1538,6 +1538,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(s
+ * PCI Tx retries from interfering with C3 CPU state */
+ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
+
++ trans->dev = &pdev->dev;
++ trans_pcie->pci_dev = pdev;
++ iwl_disable_interrupts(trans);
++
+ err = pci_enable_msi(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err);
+@@ -1549,8 +1553,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(s
+ }
+ }
+
+- trans->dev = &pdev->dev;
+- trans_pcie->pci_dev = pdev;
+ trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
+ trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
+ snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
+@@ -1574,8 +1576,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(s
+ if (!trans->dev_cmd_pool)
+ goto out_pci_disable_msi;
+
+- trans_pcie->inta_mask = CSR_INI_SET_MASK;
+-
+ if (iwl_pcie_alloc_ict(trans))
+ goto out_free_cmd_pool;
+
+@@ -1586,6 +1586,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(s
+ goto out_free_ict;
+ }
+
++ trans_pcie->inta_mask = CSR_INI_SET_MASK;
++
+ return trans;
+
+ out_free_ict:
--- /dev/null
+From 2425ce84026c385b73ae72039f90d042d49e0394 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Thu, 8 May 2014 15:51:37 -0400
+Subject: metag: fix memory barriers
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 2425ce84026c385b73ae72039f90d042d49e0394 upstream.
+
+Volatile access doesn't really imply the compiler barrier. Volatile access
+is only ordered with respect to other volatile accesses, it isn't ordered
+with respect to general memory accesses. Gcc may reorder memory accesses
+around volatile access, as we can see in this simple example (if we
+compile it with optimization, both increments of *b will be collapsed to
+just one):
+
+void fn(volatile int *a, long *b)
+{
+ (*b)++;
+ *a = 10;
+ (*b)++;
+}
+
+Consequently, we need the compiler barrier after a write to the volatile
+variable, to make sure that the compiler doesn't reorder the volatile
+write with something else.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/metag/include/asm/barrier.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/metag/include/asm/barrier.h
++++ b/arch/metag/include/asm/barrier.h
+@@ -15,6 +15,7 @@ static inline void wr_fence(void)
+ volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_FENCE;
+ barrier();
+ *flushptr = 0;
++ barrier();
+ }
+
+ #else /* CONFIG_METAG_META21 */
+@@ -35,6 +36,7 @@ static inline void wr_fence(void)
+ *flushptr = 0;
+ *flushptr = 0;
+ *flushptr = 0;
++ barrier();
+ }
+
+ #endif /* !CONFIG_METAG_META21 */
+@@ -68,6 +70,7 @@ static inline void fence(void)
+ volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_ATOMIC_UNLOCK;
+ barrier();
+ *flushptr = 0;
++ barrier();
+ }
+ #define smp_mb() fence()
+ #define smp_rmb() fence()
--- /dev/null
+From d71f290b4e98a39f49f2595a13be3b4d5ce8e1f1 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Tue, 13 May 2014 23:58:24 +0100
+Subject: metag: Reduce maximum stack size to 256MB
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit d71f290b4e98a39f49f2595a13be3b4d5ce8e1f1 upstream.
+
+Specify the maximum stack size for arches where the stack grows upward
+(parisc and metag) in asm/processor.h rather than hard coding in
+fs/exec.c so that metag can specify a smaller value of 256MB rather than
+1GB.
+
+This fixes a BUG on metag if the RLIMIT_STACK hard limit is increased
+beyond a safe value by root. E.g. when starting a process after running
+"ulimit -H -s unlimited" it will then attempt to use a stack size of the
+maximum 1GB which is far too big for metag's limited user virtual
+address space (stack_top is usually 0x3ffff000):
+
+BUG: failure at fs/exec.c:589/shift_arg_pages()!
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Helge Deller <deller@gmx.de>
+Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
+Cc: linux-parisc@vger.kernel.org
+Cc: linux-metag@vger.kernel.org
+Cc: John David Anglin <dave.anglin@bell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/metag/include/asm/processor.h | 2 ++
+ arch/parisc/include/asm/processor.h | 2 ++
+ fs/exec.c | 6 +++---
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+
+--- a/arch/metag/include/asm/processor.h
++++ b/arch/metag/include/asm/processor.h
+@@ -22,6 +22,8 @@
+ /* Add an extra page of padding at the top of the stack for the guard page. */
+ #define STACK_TOP (TASK_SIZE - PAGE_SIZE)
+ #define STACK_TOP_MAX STACK_TOP
++/* Maximum virtual space for stack */
++#define STACK_SIZE_MAX (1 << 28) /* 256 MB */
+
+ /* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+--- a/arch/parisc/include/asm/processor.h
++++ b/arch/parisc/include/asm/processor.h
+@@ -53,6 +53,8 @@
+ #define STACK_TOP TASK_SIZE
+ #define STACK_TOP_MAX DEFAULT_TASK_SIZE
+
++#define STACK_SIZE_MAX (1 << 30) /* 1 GB */
++
+ #endif
+
+ #ifndef __ASSEMBLY__
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -654,10 +654,10 @@ int setup_arg_pages(struct linux_binprm
+ unsigned long rlim_stack;
+
+ #ifdef CONFIG_STACK_GROWSUP
+- /* Limit stack size to 1GB */
++ /* Limit stack size */
+ stack_base = rlimit_max(RLIMIT_STACK);
+- if (stack_base > (1 << 30))
+- stack_base = 1 << 30;
++ if (stack_base > STACK_SIZE_MAX)
++ stack_base = STACK_SIZE_MAX;
+
+ /* Make sure we didn't let the argument array grow too large. */
+ if (vma->vm_end - vma->vm_start > stack_base)
workqueue-make-rescuer_thread-empty-wq-maydays-list-before-exiting.patch
bus-mvebu-mbus-allow-several-windows-with-the-same-target-attribute.patch
percpu-make-pcpu_alloc_chunk-use-pcpu_mem_free-instead-of-kfree.patch
+xen-blkfront-revoke-foreign-access-for-grants-not-mapped-by-the-backend.patch
+xen-blkfront-restore-the-non-persistent-data-path.patch
+iwlwifi-pcie-disable-interrupts-upon-pcie-alloc.patch
+asoc-wm8962-update-register-class_d_control_1-to-be-non-volatile.patch
+metag-fix-memory-barriers.patch
+metag-reduce-maximum-stack-size-to-256mb.patch
+x86-64-modify_ldt-make-support-for-16-bit-segments-a-runtime-option.patch
--- /dev/null
+From fa81511bb0bbb2b1aace3695ce869da9762624ff Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Wed, 14 May 2014 16:33:54 -0700
+Subject: x86-64, modify_ldt: Make support for 16-bit segments a runtime option
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit fa81511bb0bbb2b1aace3695ce869da9762624ff upstream.
+
+Checkin:
+
+b3b42ac2cbae x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels
+
+disabled 16-bit segments on 64-bit kernels due to an information
+leak. However, it does seem that people are genuinely using Wine to
+run old 16-bit Windows programs on Linux.
+
+A proper fix for this ("espfix64") is coming in the upcoming merge
+window, but as a temporary fix, create a sysctl to allow the
+administrator to re-enable support for 16-bit segments.
+
+It adds a "/proc/sys/abi/ldt16" sysctl that defaults to zero (off). If
+you hit this issue and care about your old Windows program more than
+you care about a kernel stack address information leak, you can do
+
+ echo 1 > /proc/sys/abi/ldt16
+
+as root (add it to your startup scripts), and you should be ok.
+
+The sysctl table is only added if you have COMPAT support enabled on
+x86-64, but I assume anybody who runs old windows binaries very much
+does that ;)
+
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Link: http://lkml.kernel.org/r/CA%2B55aFw9BPoD10U1LfHbOMpHWZkvJTkMcfCs9s3urPr1YyWBxw@mail.gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/ldt.c | 4 +++-
+ arch/x86/vdso/vdso32-setup.c | 8 ++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/ldt.c
++++ b/arch/x86/kernel/ldt.c
+@@ -20,6 +20,8 @@
+ #include <asm/mmu_context.h>
+ #include <asm/syscalls.h>
+
++int sysctl_ldt16 = 0;
++
+ #ifdef CONFIG_SMP
+ static void flush_ldt(void *current_mm)
+ {
+@@ -234,7 +236,7 @@ static int write_ldt(void __user *ptr, u
+ * IRET leaking the high bits of the kernel stack address.
+ */
+ #ifdef CONFIG_X86_64
+- if (!ldt_info.seg_32bit) {
++ if (!ldt_info.seg_32bit && !sysctl_ldt16) {
+ error = -EINVAL;
+ goto out_unlock;
+ }
+--- a/arch/x86/vdso/vdso32-setup.c
++++ b/arch/x86/vdso/vdso32-setup.c
+@@ -41,6 +41,7 @@ enum {
+ #ifdef CONFIG_X86_64
+ #define vdso_enabled sysctl_vsyscall32
+ #define arch_setup_additional_pages syscall32_setup_pages
++extern int sysctl_ldt16;
+ #endif
+
+ /*
+@@ -379,6 +380,13 @@ static ctl_table abi_table2[] = {
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
++ },
++ {
++ .procname = "ldt16",
++ .data = &sysctl_ldt16,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec
+ },
+ {}
+ };
--- /dev/null
+From bfe11d6de1c416cea4f3f0f35f864162063ce3fa Mon Sep 17 00:00:00 2001
+From: Roger Pau Monne <roger.pau@citrix.com>
+Date: Tue, 29 Oct 2013 18:31:14 +0100
+Subject: xen-blkfront: restore the non-persistent data path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+commit bfe11d6de1c416cea4f3f0f35f864162063ce3fa upstream.
+
+When persistent grants were added they were always used, even if the
+backend doesn't have this feature (there's no harm in always using the
+same set of pages). This restores the old data path when the backend
+doesn't have persistent grants, removing the burden of doing a memcpy
+when it is not actually needed.
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reported-by: Felipe Franciosi <felipe.franciosi@citrix.com>
+Cc: Felipe Franciosi <felipe.franciosi@citrix.com>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Cc: David Vrabel <david.vrabel@citrix.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+[v2: Fix up whitespace issues]
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/xen-blkfront.c | 105 ++++++++++++++++++++++++++++++-------------
+ 1 file changed, 74 insertions(+), 31 deletions(-)
+
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -104,7 +104,7 @@ struct blkfront_info
+ struct work_struct work;
+ struct gnttab_free_callback callback;
+ struct blk_shadow shadow[BLK_RING_SIZE];
+- struct list_head persistent_gnts;
++ struct list_head grants;
+ unsigned int persistent_gnts_c;
+ unsigned long shadow_free;
+ unsigned int feature_flush;
+@@ -175,15 +175,17 @@ static int fill_grant_buffer(struct blkf
+ if (!gnt_list_entry)
+ goto out_of_memory;
+
+- granted_page = alloc_page(GFP_NOIO);
+- if (!granted_page) {
+- kfree(gnt_list_entry);
+- goto out_of_memory;
++ if (info->feature_persistent) {
++ granted_page = alloc_page(GFP_NOIO);
++ if (!granted_page) {
++ kfree(gnt_list_entry);
++ goto out_of_memory;
++ }
++ gnt_list_entry->pfn = page_to_pfn(granted_page);
+ }
+
+- gnt_list_entry->pfn = page_to_pfn(granted_page);
+ gnt_list_entry->gref = GRANT_INVALID_REF;
+- list_add(&gnt_list_entry->node, &info->persistent_gnts);
++ list_add(&gnt_list_entry->node, &info->grants);
+ i++;
+ }
+
+@@ -191,9 +193,10 @@ static int fill_grant_buffer(struct blkf
+
+ out_of_memory:
+ list_for_each_entry_safe(gnt_list_entry, n,
+- &info->persistent_gnts, node) {
++ &info->grants, node) {
+ list_del(&gnt_list_entry->node);
+- __free_page(pfn_to_page(gnt_list_entry->pfn));
++ if (info->feature_persistent)
++ __free_page(pfn_to_page(gnt_list_entry->pfn));
+ kfree(gnt_list_entry);
+ i--;
+ }
+@@ -202,14 +205,14 @@ out_of_memory:
+ }
+
+ static struct grant *get_grant(grant_ref_t *gref_head,
++ unsigned long pfn,
+ struct blkfront_info *info)
+ {
+ struct grant *gnt_list_entry;
+ unsigned long buffer_mfn;
+
+- BUG_ON(list_empty(&info->persistent_gnts));
+- gnt_list_entry = list_first_entry(&info->persistent_gnts, struct grant,
+- node);
++ BUG_ON(list_empty(&info->grants));
++ gnt_list_entry = list_first_entry(&info->grants, struct grant, node);
+ list_del(&gnt_list_entry->node);
+
+ if (gnt_list_entry->gref != GRANT_INVALID_REF) {
+@@ -220,6 +223,10 @@ static struct grant *get_grant(grant_ref
+ /* Assign a gref to this page */
+ gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
+ BUG_ON(gnt_list_entry->gref == -ENOSPC);
++ if (!info->feature_persistent) {
++ BUG_ON(!pfn);
++ gnt_list_entry->pfn = pfn;
++ }
+ buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
+ gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
+ info->xbdev->otherend_id,
+@@ -430,12 +437,12 @@ static int blkif_queue_request(struct re
+ fsect = sg->offset >> 9;
+ lsect = fsect + (sg->length >> 9) - 1;
+
+- gnt_list_entry = get_grant(&gref_head, info);
++ gnt_list_entry = get_grant(&gref_head, page_to_pfn(sg_page(sg)), info);
+ ref = gnt_list_entry->gref;
+
+ info->shadow[id].grants_used[i] = gnt_list_entry;
+
+- if (rq_data_dir(req)) {
++ if (rq_data_dir(req) && info->feature_persistent) {
+ char *bvec_data;
+ void *shared_data;
+
+@@ -828,16 +835,17 @@ static void blkif_free(struct blkfront_i
+ blk_stop_queue(info->rq);
+
+ /* Remove all persistent grants */
+- if (!list_empty(&info->persistent_gnts)) {
++ if (!list_empty(&info->grants)) {
+ list_for_each_entry_safe(persistent_gnt, n,
+- &info->persistent_gnts, node) {
++ &info->grants, node) {
+ list_del(&persistent_gnt->node);
+ if (persistent_gnt->gref != GRANT_INVALID_REF) {
+ gnttab_end_foreign_access(persistent_gnt->gref,
+ 0, 0UL);
+ info->persistent_gnts_c--;
+ }
+- __free_page(pfn_to_page(persistent_gnt->pfn));
++ if (info->feature_persistent)
++ __free_page(pfn_to_page(persistent_gnt->pfn));
+ kfree(persistent_gnt);
+ }
+ }
+@@ -874,7 +882,7 @@ static void blkif_completion(struct blk_
+
+ nseg = s->req.u.rw.nr_segments;
+
+- if (bret->operation == BLKIF_OP_READ) {
++ if (bret->operation == BLKIF_OP_READ && info->feature_persistent) {
+ /*
+ * Copy the data received from the backend into the bvec.
+ * Since bv_offset can be different than 0, and bv_len different
+@@ -902,7 +910,10 @@ static void blkif_completion(struct blk_
+ * we add it at the head of the list, so it will be
+ * reused first.
+ */
+- list_add(&s->grants_used[i]->node, &info->persistent_gnts);
++ if (!info->feature_persistent)
++ pr_alert_ratelimited("backed has not unmapped grant: %u\n",
++ s->grants_used[i]->gref);
++ list_add(&s->grants_used[i]->node, &info->grants);
+ info->persistent_gnts_c++;
+ } else {
+ /*
+@@ -913,7 +924,7 @@ static void blkif_completion(struct blk_
+ */
+ gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
+ s->grants_used[i]->gref = GRANT_INVALID_REF;
+- list_add_tail(&s->grants_used[i]->node, &info->persistent_gnts);
++ list_add_tail(&s->grants_used[i]->node, &info->grants);
+ }
+ }
+ }
+@@ -1052,12 +1063,6 @@ static int setup_blkring(struct xenbus_d
+ for (i = 0; i < BLK_RING_SIZE; i++)
+ sg_init_table(info->shadow[i].sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+
+- /* Allocate memory for grants */
+- err = fill_grant_buffer(info, BLK_RING_SIZE *
+- BLKIF_MAX_SEGMENTS_PER_REQUEST);
+- if (err)
+- goto fail;
+-
+ err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
+ if (err < 0) {
+ free_page((unsigned long)sring);
+@@ -1216,7 +1221,7 @@ static int blkfront_probe(struct xenbus_
+ spin_lock_init(&info->io_lock);
+ info->xbdev = dev;
+ info->vdevice = vdevice;
+- INIT_LIST_HEAD(&info->persistent_gnts);
++ INIT_LIST_HEAD(&info->grants);
+ info->persistent_gnts_c = 0;
+ info->connected = BLKIF_STATE_DISCONNECTED;
+ INIT_WORK(&info->work, blkif_restart_queue);
+@@ -1245,7 +1250,8 @@ static int blkif_recover(struct blkfront
+ int i;
+ struct blkif_request *req;
+ struct blk_shadow *copy;
+- int j;
++ unsigned int persistent;
++ int j, rc;
+
+ /* Stage 1: Make a safe copy of the shadow state. */
+ copy = kmemdup(info->shadow, sizeof(info->shadow),
+@@ -1260,6 +1266,24 @@ static int blkif_recover(struct blkfront
+ info->shadow_free = info->ring.req_prod_pvt;
+ info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
+
++ /* Check if the backend supports persistent grants */
++ rc = xenbus_gather(XBT_NIL, info->xbdev->otherend,
++ "feature-persistent", "%u", &persistent,
++ NULL);
++ if (rc)
++ info->feature_persistent = 0;
++ else
++ info->feature_persistent = persistent;
++
++ /* Allocate memory for grants */
++ rc = fill_grant_buffer(info, BLK_RING_SIZE *
++ BLKIF_MAX_SEGMENTS_PER_REQUEST);
++ if (rc) {
++ xenbus_dev_fatal(info->xbdev, rc, "setting grant buffer failed");
++ kfree(copy);
++ return rc;
++ }
++
+ /* Stage 3: Find pending requests and requeue them. */
+ for (i = 0; i < BLK_RING_SIZE; i++) {
+ /* Not in use? */
+@@ -1324,8 +1348,12 @@ static int blkfront_resume(struct xenbus
+ blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
+
+ err = talk_to_blkback(dev, info);
+- if (info->connected == BLKIF_STATE_SUSPENDED && !err)
+- err = blkif_recover(info);
++
++ /*
++ * We have to wait for the backend to switch to
++ * connected state, since we want to read which
++ * features it supports.
++ */
+
+ return err;
+ }
+@@ -1429,9 +1457,16 @@ static void blkfront_connect(struct blkf
+ sectors);
+ set_capacity(info->gd, sectors);
+ revalidate_disk(info->gd);
++ return;
+
+- /* fall through */
+ case BLKIF_STATE_SUSPENDED:
++ /*
++ * If we are recovering from suspension, we need to wait
++ * for the backend to announce it's features before
++ * reconnecting, we need to know if the backend supports
++ * persistent grants.
++ */
++ blkif_recover(info);
+ return;
+
+ default:
+@@ -1499,6 +1534,14 @@ static void blkfront_connect(struct blkf
+ else
+ info->feature_persistent = persistent;
+
++ /* Allocate memory for grants */
++ err = fill_grant_buffer(info, BLK_RING_SIZE *
++ BLKIF_MAX_SEGMENTS_PER_REQUEST);
++ if (err) {
++ xenbus_dev_fatal(info->xbdev, err, "setting grant buffer failed");
++ return;
++ }
++
+ err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
+ if (err) {
+ xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
--- /dev/null
+From fbe363c476afe8ec992d3baf682670a4bd1b6ce6 Mon Sep 17 00:00:00 2001
+From: Roger Pau Monne <roger.pau@citrix.com>
+Date: Mon, 12 Aug 2013 12:53:44 +0200
+Subject: xen-blkfront: revoke foreign access for grants not mapped by the backend
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Roger Pau Monne <roger.pau@citrix.com>
+
+commit fbe363c476afe8ec992d3baf682670a4bd1b6ce6 upstream.
+
+There's no need to keep the foreign access in a grant if it is not
+persistently mapped by the backend. This allows us to free grants that
+are not mapped by the backend, thus preventing blkfront from hoarding
+all grants.
+
+The main effect of this is that blkfront will only persistently map
+the same grants as the backend, and it will always try to use grants
+that are already mapped by the backend. Also the number of persistent
+grants in blkfront is the same as in blkback (and is controlled by the
+value in blkback).
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: David Vrabel <david.vrabel@citrix.com>
+Acked-by: Matt Wilson <msw@amazon.com>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Cc: David Vrabel <david.vrabel@citrix.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/block/xen-blkfront.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -894,9 +894,27 @@ static void blkif_completion(struct blk_
+ }
+ }
+ /* Add the persistent grant into the list of free grants */
+- for (i = 0; i < s->req.u.rw.nr_segments; i++) {
+- list_add(&s->grants_used[i]->node, &info->persistent_gnts);
+- info->persistent_gnts_c++;
++ for (i = 0; i < nseg; i++) {
++ if (gnttab_query_foreign_access(s->grants_used[i]->gref)) {
++ /*
++ * If the grant is still mapped by the backend (the
++ * backend has chosen to make this grant persistent)
++ * we add it at the head of the list, so it will be
++ * reused first.
++ */
++ list_add(&s->grants_used[i]->node, &info->persistent_gnts);
++ info->persistent_gnts_c++;
++ } else {
++ /*
++ * If the grant is not mapped by the backend we end the
++ * foreign access and add it to the tail of the list,
++ * so it will not be picked again unless we run out of
++ * persistent grants.
++ */
++ gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL);
++ s->grants_used[i]->gref = GRANT_INVALID_REF;
++ list_add_tail(&s->grants_used[i]->node, &info->persistent_gnts);
++ }
+ }
+ }
+