]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Oct 2012 21:54:28 +0000 (14:54 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Oct 2012 21:54:28 +0000 (14:54 -0700)
added patches:
e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch
ecryptfs-call-lower-flush-from-ecryptfs_flush.patch
ecryptfs-initialize-empty-lower-files-when-opening-them.patch
ecryptfs-revert-to-a-writethrough-cache-model.patch
ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch
ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch
jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch
tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch
usb-gadget-at91_udc-fix-dt-support.patch

queue-3.4/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch [new file with mode: 0644]
queue-3.4/ecryptfs-call-lower-flush-from-ecryptfs_flush.patch [new file with mode: 0644]
queue-3.4/ecryptfs-initialize-empty-lower-files-when-opening-them.patch [new file with mode: 0644]
queue-3.4/ecryptfs-revert-to-a-writethrough-cache-model.patch [new file with mode: 0644]
queue-3.4/ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch [new file with mode: 0644]
queue-3.4/ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch [new file with mode: 0644]
queue-3.4/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch [new file with mode: 0644]
queue-3.4/usb-gadget-at91_udc-fix-dt-support.patch [new file with mode: 0644]

diff --git a/queue-3.4/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch b/queue-3.4/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch
new file mode 100644 (file)
index 0000000..46ab082
--- /dev/null
@@ -0,0 +1,81 @@
+From 8edc0e624db3756783233e464879eb2e3b904c13 Mon Sep 17 00:00:00 2001
+From: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
+Date: Wed, 10 Oct 2012 15:34:20 +0000
+Subject: e1000e: Change wthresh to 1 to avoid possible Tx stalls
+
+From: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
+
+commit 8edc0e624db3756783233e464879eb2e3b904c13 upstream.
+
+This patch originated from Hiroaki SHIMODA but has been modified
+by Intel with some minor cleanups and additional commit log text.
+
+Denys Fedoryshchenko and others reported Tx stalls on e1000e with
+BQL enabled.  Issue was root caused to hardware delays. They were
+introduced because some of the e1000e hardware with transmit
+writeback bursting enabled, waits until the driver does an
+explict flush OR there are WTHRESH descriptors to write back.
+
+Sometimes the delays in question were on the order of seconds,
+causing visible lag for ssh sessions and unacceptable tx
+completion latency, especially for BQL enabled kernels.
+
+To avoid possible Tx stalls, change WTHRESH back to 1.
+
+The current plan is to investigate a method for re-enabling
+WTHRESH while not harming BQL, but those patches will be later
+for net-next if they work.
+
+please enqueue for stable since v3.3 as this bug was introduced in
+commit 3f0cfa3bc11e7f00c9994e0f469cbc0e7da7b00c
+Author: Tom Herbert <therbert@google.com>
+Date:   Mon Nov 28 16:33:16 2011 +0000
+
+    e1000e: Support for byte queue limits
+
+    Changes to e1000e to use byte queue limits.
+
+Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
+Tested-by: Denys Fedoryshchenko <denys@visp.net.lb>
+Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
+CC: eric.dumazet@gmail.com
+CC: therbert@google.com
+Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/intel/e1000e/e1000.h  |    6 +++---
+ drivers/net/ethernet/intel/e1000e/netdev.c |    2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/intel/e1000e/e1000.h
++++ b/drivers/net/ethernet/intel/e1000e/e1000.h
+@@ -175,13 +175,13 @@ struct e1000_info;
+ /*
+  * in the case of WTHRESH, it appears at least the 82571/2 hardware
+  * writes back 4 descriptors when WTHRESH=5, and 3 descriptors when
+- * WTHRESH=4, and since we want 64 bytes at a time written back, set
+- * it to 5
++ * WTHRESH=4, so a setting of 5 gives the most efficient bus
++ * utilization but to avoid possible Tx stalls, set it to 1
+  */
+ #define E1000_TXDCTL_DMA_BURST_ENABLE                          \
+       (E1000_TXDCTL_GRAN | /* set descriptor granularity */  \
+        E1000_TXDCTL_COUNT_DESC |                             \
+-       (5 << 16) | /* wthresh must be +1 more than desired */\
++       (1 << 16) | /* wthresh must be +1 more than desired */\
+        (1 << 8)  | /* hthresh */                             \
+        0x1f)       /* pthresh */
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -2806,7 +2806,7 @@ static void e1000_configure_tx(struct e1
+                * set up some performance related parameters to encourage the
+                * hardware to use the bus more efficiently in bursts, depends
+                * on the tx_int_delay to be enabled,
+-               * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time
++               * wthresh = 1 ==> burst write is disabled to avoid Tx stalls
+                * hthresh = 1 ==> prefetch when one or more available
+                * pthresh = 0x1f ==> prefetch if internal cache 31 or less
+                * BEWARE: this seems to work but should be considered first if
diff --git a/queue-3.4/ecryptfs-call-lower-flush-from-ecryptfs_flush.patch b/queue-3.4/ecryptfs-call-lower-flush-from-ecryptfs_flush.patch
new file mode 100644 (file)
index 0000000..e9488a5
--- /dev/null
@@ -0,0 +1,45 @@
+From 64e6651dcc10e9d2cc6230208a8e6c2cfd19ae18 Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Wed, 12 Sep 2012 18:38:00 -0700
+Subject: eCryptfs: Call lower ->flush() from ecryptfs_flush()
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit 64e6651dcc10e9d2cc6230208a8e6c2cfd19ae18 upstream.
+
+Since eCryptfs only calls fput() on the lower file in
+ecryptfs_release(), eCryptfs should call the lower filesystem's
+->flush() from ecryptfs_flush().
+
+If the lower filesystem implements ->flush(), then eCryptfs should try
+to flush out any dirty pages prior to calling the lower ->flush(). If
+the lower filesystem does not implement ->flush(), then eCryptfs has no
+need to do anything in ecryptfs_flush() since dirty pages are now
+written out to the lower filesystem in ecryptfs_release().
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ecryptfs/file.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/fs/ecryptfs/file.c
++++ b/fs/ecryptfs/file.c
+@@ -275,8 +275,14 @@ out:
+ static int ecryptfs_flush(struct file *file, fl_owner_t td)
+ {
+-      return file->f_mode & FMODE_WRITE
+-             ? filemap_write_and_wait(file->f_mapping) : 0;
++      struct file *lower_file = ecryptfs_file_to_lower(file);
++
++      if (lower_file->f_op && lower_file->f_op->flush) {
++              filemap_write_and_wait(file->f_mapping);
++              return lower_file->f_op->flush(lower_file, td);
++      }
++
++      return 0;
+ }
+ static int ecryptfs_release(struct inode *inode, struct file *file)
diff --git a/queue-3.4/ecryptfs-initialize-empty-lower-files-when-opening-them.patch b/queue-3.4/ecryptfs-initialize-empty-lower-files-when-opening-them.patch
new file mode 100644 (file)
index 0000000..3be490d
--- /dev/null
@@ -0,0 +1,157 @@
+From e3ccaa9761200952cc269b1f4b7d7bb77a5e071b Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Wed, 20 Jun 2012 23:50:59 -0700
+Subject: eCryptfs: Initialize empty lower files when opening them
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit e3ccaa9761200952cc269b1f4b7d7bb77a5e071b upstream.
+
+Historically, eCryptfs has only initialized lower files in the
+ecryptfs_create() path. Lower file initialization is the act of writing
+the cryptographic metadata from the inode's crypt_stat to the header of
+the file. The ecryptfs_open() path already expects that metadata to be
+in the header of the file.
+
+A number of users have reported empty lower files in beneath their
+eCryptfs mounts. Most of the causes for those empty files being left
+around have been addressed, but the presence of empty files causes
+problems due to the lack of proper cryptographic metadata.
+
+To transparently solve this problem, this patch initializes empty lower
+files in the ecryptfs_open() error path. If the metadata is unreadable
+due to the lower inode size being 0, plaintext passthrough support is
+not in use, and the metadata is stored in the header of the file (as
+opposed to the user.ecryptfs extended attribute), the lower file will be
+initialized.
+
+The number of nested conditionals in ecryptfs_open() was getting out of
+hand, so a helper function was created. To avoid the same nested
+conditional problem, the conditional logic was reversed inside of the
+helper function.
+
+https://launchpad.net/bugs/911507
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Cc: John Johansen <john.johansen@canonical.com>
+Cc: Colin Ian King <colin.king@canonical.com>
+Cc: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ecryptfs/ecryptfs_kernel.h |    2 +
+ fs/ecryptfs/file.c            |   71 ++++++++++++++++++++++++++----------------
+ fs/ecryptfs/inode.c           |    4 +-
+ 3 files changed, 49 insertions(+), 28 deletions(-)
+
+--- a/fs/ecryptfs/ecryptfs_kernel.h
++++ b/fs/ecryptfs/ecryptfs_kernel.h
+@@ -568,6 +568,8 @@ struct ecryptfs_open_req {
+ struct inode *ecryptfs_get_inode(struct inode *lower_inode,
+                                struct super_block *sb);
+ void ecryptfs_i_size_init(const char *page_virt, struct inode *inode);
++int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
++                           struct inode *ecryptfs_inode);
+ int ecryptfs_decode_and_decrypt_filename(char **decrypted_name,
+                                        size_t *decrypted_name_size,
+                                        struct dentry *ecryptfs_dentry,
+--- a/fs/ecryptfs/file.c
++++ b/fs/ecryptfs/file.c
+@@ -161,6 +161,48 @@ static int ecryptfs_file_mmap(struct fil
+ struct kmem_cache *ecryptfs_file_info_cache;
++static int read_or_initialize_metadata(struct dentry *dentry)
++{
++      struct inode *inode = dentry->d_inode;
++      struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
++      struct ecryptfs_crypt_stat *crypt_stat;
++      int rc;
++
++      crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
++      mount_crypt_stat = &ecryptfs_superblock_to_private(
++                                              inode->i_sb)->mount_crypt_stat;
++      mutex_lock(&crypt_stat->cs_mutex);
++
++      if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED &&
++          crypt_stat->flags & ECRYPTFS_KEY_VALID) {
++              rc = 0;
++              goto out;
++      }
++
++      rc = ecryptfs_read_metadata(dentry);
++      if (!rc)
++              goto out;
++
++      if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) {
++              crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
++                                     | ECRYPTFS_ENCRYPTED);
++              rc = 0;
++              goto out;
++      }
++
++      if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) &&
++          !i_size_read(ecryptfs_inode_to_lower(inode))) {
++              rc = ecryptfs_initialize_file(dentry, inode);
++              if (!rc)
++                      goto out;
++      }
++
++      rc = -EIO;
++out:
++      mutex_unlock(&crypt_stat->cs_mutex);
++      return rc;
++}
++
+ /**
+  * ecryptfs_open
+  * @inode: inode speciying file to open
+@@ -236,32 +278,9 @@ static int ecryptfs_open(struct inode *i
+               rc = 0;
+               goto out;
+       }
+-      mutex_lock(&crypt_stat->cs_mutex);
+-      if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
+-          || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
+-              rc = ecryptfs_read_metadata(ecryptfs_dentry);
+-              if (rc) {
+-                      ecryptfs_printk(KERN_DEBUG,
+-                                      "Valid headers not found\n");
+-                      if (!(mount_crypt_stat->flags
+-                            & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
+-                              rc = -EIO;
+-                              printk(KERN_WARNING "Either the lower file "
+-                                     "is not in a valid eCryptfs format, "
+-                                     "or the key could not be retrieved. "
+-                                     "Plaintext passthrough mode is not "
+-                                     "enabled; returning -EIO\n");
+-                              mutex_unlock(&crypt_stat->cs_mutex);
+-                              goto out_put;
+-                      }
+-                      rc = 0;
+-                      crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
+-                                             | ECRYPTFS_ENCRYPTED);
+-                      mutex_unlock(&crypt_stat->cs_mutex);
+-                      goto out;
+-              }
+-      }
+-      mutex_unlock(&crypt_stat->cs_mutex);
++      rc = read_or_initialize_metadata(ecryptfs_dentry);
++      if (rc)
++              goto out_put;
+       ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = "
+                       "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino,
+                       (unsigned long long)i_size_read(inode));
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -227,8 +227,8 @@ out:
+  *
+  * Returns zero on success
+  */
+-static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
+-                                  struct inode *ecryptfs_inode)
++int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
++                           struct inode *ecryptfs_inode)
+ {
+       struct ecryptfs_crypt_stat *crypt_stat =
+               &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
diff --git a/queue-3.4/ecryptfs-revert-to-a-writethrough-cache-model.patch b/queue-3.4/ecryptfs-revert-to-a-writethrough-cache-model.patch
new file mode 100644 (file)
index 0000000..3697bd8
--- /dev/null
@@ -0,0 +1,187 @@
+From 821f7494a77627fb1ab539591c57b22cdca702d6 Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Tue, 3 Jul 2012 16:50:57 -0700
+Subject: eCryptfs: Revert to a writethrough cache model
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit 821f7494a77627fb1ab539591c57b22cdca702d6 upstream.
+
+A change was made about a year ago to get eCryptfs to better utilize its
+page cache during writes. The idea was to do the page encryption
+operations during page writeback, rather than doing them when initially
+writing into the page cache, to reduce the number of page encryption
+operations during sequential writes. This meant that the encrypted page
+would only be written to the lower filesystem during page writeback,
+which was a change from how eCryptfs had previously wrote to the lower
+filesystem in ecryptfs_write_end().
+
+The change caused a few eCryptfs-internal bugs that were shook out.
+Unfortunately, more grave side effects have been identified that will
+force changes outside of eCryptfs. Because the lower filesystem isn't
+consulted until page writeback, eCryptfs has no way to pass lower write
+errors (ENOSPC, mainly) back to userspace. Additionaly, it was reported
+that quotas could be bypassed because of the way eCryptfs may sometimes
+open the lower filesystem using a privileged kthread.
+
+It would be nice to resolve the latest issues, but it is best if the
+eCryptfs commits be reverted to the old behavior in the meantime.
+
+This reverts:
+32001d6f "eCryptfs: Flush file in vma close"
+5be79de2 "eCryptfs: Flush dirty pages in setattr"
+57db4e8d "ecryptfs: modify write path to encrypt page in writepage"
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Tested-by: Colin King <colin.king@canonical.com>
+Cc: Colin King <colin.king@canonical.com>
+Cc: Thieu Le <thieule@google.com>
+Cc: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ecryptfs/file.c  |   33 ++-------------------------------
+ fs/ecryptfs/inode.c |    6 ------
+ fs/ecryptfs/mmap.c  |   39 +++++++++++++--------------------------
+ 3 files changed, 15 insertions(+), 63 deletions(-)
+
+--- a/fs/ecryptfs/file.c
++++ b/fs/ecryptfs/file.c
+@@ -138,27 +138,6 @@ out:
+       return rc;
+ }
+-static void ecryptfs_vma_close(struct vm_area_struct *vma)
+-{
+-      filemap_write_and_wait(vma->vm_file->f_mapping);
+-}
+-
+-static const struct vm_operations_struct ecryptfs_file_vm_ops = {
+-      .close          = ecryptfs_vma_close,
+-      .fault          = filemap_fault,
+-};
+-
+-static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+-{
+-      int rc;
+-
+-      rc = generic_file_mmap(file, vma);
+-      if (!rc)
+-              vma->vm_ops = &ecryptfs_file_vm_ops;
+-
+-      return rc;
+-}
+-
+ struct kmem_cache *ecryptfs_file_info_cache;
+ static int read_or_initialize_metadata(struct dentry *dentry)
+@@ -311,15 +290,7 @@ static int ecryptfs_release(struct inode
+ static int
+ ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
+ {
+-      int rc = 0;
+-
+-      rc = generic_file_fsync(file, start, end, datasync);
+-      if (rc)
+-              goto out;
+-      rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end,
+-                           datasync);
+-out:
+-      return rc;
++      return vfs_fsync(ecryptfs_file_to_lower(file), datasync);
+ }
+ static int ecryptfs_fasync(int fd, struct file *file, int flag)
+@@ -388,7 +359,7 @@ const struct file_operations ecryptfs_ma
+ #ifdef CONFIG_COMPAT
+       .compat_ioctl = ecryptfs_compat_ioctl,
+ #endif
+-      .mmap = ecryptfs_file_mmap,
++      .mmap = generic_file_mmap,
+       .open = ecryptfs_open,
+       .flush = ecryptfs_flush,
+       .release = ecryptfs_release,
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -1016,12 +1016,6 @@ static int ecryptfs_setattr(struct dentr
+                       goto out;
+       }
+-      if (S_ISREG(inode->i_mode)) {
+-              rc = filemap_write_and_wait(inode->i_mapping);
+-              if (rc)
+-                      goto out;
+-              fsstack_copy_attr_all(inode, lower_inode);
+-      }
+       memcpy(&lower_ia, ia, sizeof(lower_ia));
+       if (ia->ia_valid & ATTR_FILE)
+               lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file);
+--- a/fs/ecryptfs/mmap.c
++++ b/fs/ecryptfs/mmap.c
+@@ -66,18 +66,6 @@ static int ecryptfs_writepage(struct pag
+ {
+       int rc;
+-      /*
+-       * Refuse to write the page out if we are called from reclaim context
+-       * since our writepage() path may potentially allocate memory when
+-       * calling into the lower fs vfs_write() which may in turn invoke
+-       * us again.
+-       */
+-      if (current->flags & PF_MEMALLOC) {
+-              redirty_page_for_writepage(wbc, page);
+-              rc = 0;
+-              goto out;
+-      }
+-
+       rc = ecryptfs_encrypt_page(page);
+       if (rc) {
+               ecryptfs_printk(KERN_WARNING, "Error encrypting "
+@@ -498,7 +486,6 @@ static int ecryptfs_write_end(struct fil
+       struct ecryptfs_crypt_stat *crypt_stat =
+               &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
+       int rc;
+-      int need_unlock_page = 1;
+       ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
+                       "(page w/ index = [0x%.16lx], to = [%d])\n", index, to);
+@@ -519,26 +506,26 @@ static int ecryptfs_write_end(struct fil
+                       "zeros in page with index = [0x%.16lx]\n", index);
+               goto out;
+       }
+-      set_page_dirty(page);
+-      unlock_page(page);
+-      need_unlock_page = 0;
++      rc = ecryptfs_encrypt_page(page);
++      if (rc) {
++              ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
++                              "index [0x%.16lx])\n", index);
++              goto out;
++      }
+       if (pos + copied > i_size_read(ecryptfs_inode)) {
+               i_size_write(ecryptfs_inode, pos + copied);
+               ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
+                       "[0x%.16llx]\n",
+                       (unsigned long long)i_size_read(ecryptfs_inode));
+-              balance_dirty_pages_ratelimited(mapping);
+-              rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
+-              if (rc) {
+-                      printk(KERN_ERR "Error writing inode size to metadata; "
+-                             "rc = [%d]\n", rc);
+-                      goto out;
+-              }
+       }
+-      rc = copied;
++      rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
++      if (rc)
++              printk(KERN_ERR "Error writing inode size to metadata; "
++                     "rc = [%d]\n", rc);
++      else
++              rc = copied;
+ out:
+-      if (need_unlock_page)
+-              unlock_page(page);
++      unlock_page(page);
+       page_cache_release(page);
+       return rc;
+ }
diff --git a/queue-3.4/ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch b/queue-3.4/ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch
new file mode 100644 (file)
index 0000000..7616987
--- /dev/null
@@ -0,0 +1,120 @@
+From 8bc2d3cf612994a960c2e8eaea37f6676f67082a Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Tue, 22 May 2012 15:09:50 -0500
+Subject: eCryptfs: Unlink lower inode when ecryptfs_create() fails
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit 8bc2d3cf612994a960c2e8eaea37f6676f67082a upstream.
+
+ecryptfs_create() creates a lower inode, allocates an eCryptfs inode,
+initializes the eCryptfs inode and cryptographic metadata attached to
+the inode, and then writes the metadata to the header of the file.
+
+If an error was to occur after the lower inode was created, an empty
+lower file would be left in the lower filesystem. This is a problem
+because ecryptfs_open() refuses to open any lower files which do not
+have the appropriate metadata in the file header.
+
+This patch properly unlinks the lower inode when an error occurs in the
+later stages of ecryptfs_create(), reducing the chance that an empty
+lower file will be left in the lower filesystem.
+
+https://launchpad.net/bugs/872905
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Cc: John Johansen <john.johansen@canonical.com>
+Cc: Colin Ian King <colin.king@canonical.com>
+Cc: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ecryptfs/inode.c |   55 ++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 32 insertions(+), 23 deletions(-)
+
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -143,6 +143,31 @@ static int ecryptfs_interpose(struct den
+       return 0;
+ }
++static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
++                            struct inode *inode)
++{
++      struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
++      struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
++      struct dentry *lower_dir_dentry;
++      int rc;
++
++      dget(lower_dentry);
++      lower_dir_dentry = lock_parent(lower_dentry);
++      rc = vfs_unlink(lower_dir_inode, lower_dentry);
++      if (rc) {
++              printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
++              goto out_unlock;
++      }
++      fsstack_copy_attr_times(dir, lower_dir_inode);
++      set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink);
++      inode->i_ctime = dir->i_ctime;
++      d_drop(dentry);
++out_unlock:
++      unlock_dir(lower_dir_dentry);
++      dput(lower_dentry);
++      return rc;
++}
++
+ /**
+  * ecryptfs_do_create
+  * @directory_inode: inode of the new file's dentry's parent in ecryptfs
+@@ -182,8 +207,10 @@ ecryptfs_do_create(struct inode *directo
+       }
+       inode = __ecryptfs_get_inode(lower_dentry->d_inode,
+                                    directory_inode->i_sb);
+-      if (IS_ERR(inode))
++      if (IS_ERR(inode)) {
++              vfs_unlink(lower_dir_dentry->d_inode, lower_dentry);
+               goto out_lock;
++      }
+       fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode);
+       fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode);
+ out_lock:
+@@ -265,7 +292,9 @@ ecryptfs_create(struct inode *directory_
+        * that this on disk file is prepared to be an ecryptfs file */
+       rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode);
+       if (rc) {
+-              drop_nlink(ecryptfs_inode);
++              ecryptfs_do_unlink(directory_inode, ecryptfs_dentry,
++                                 ecryptfs_inode);
++              make_bad_inode(ecryptfs_inode);
+               unlock_new_inode(ecryptfs_inode);
+               iput(ecryptfs_inode);
+               goto out;
+@@ -477,27 +506,7 @@ out_lock:
+ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
+ {
+-      int rc = 0;
+-      struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+-      struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
+-      struct dentry *lower_dir_dentry;
+-
+-      dget(lower_dentry);
+-      lower_dir_dentry = lock_parent(lower_dentry);
+-      rc = vfs_unlink(lower_dir_inode, lower_dentry);
+-      if (rc) {
+-              printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
+-              goto out_unlock;
+-      }
+-      fsstack_copy_attr_times(dir, lower_dir_inode);
+-      set_nlink(dentry->d_inode,
+-                ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink);
+-      dentry->d_inode->i_ctime = dir->i_ctime;
+-      d_drop(dentry);
+-out_unlock:
+-      unlock_dir(lower_dir_dentry);
+-      dput(lower_dentry);
+-      return rc;
++      return ecryptfs_do_unlink(dir, dentry, dentry->d_inode);
+ }
+ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
diff --git a/queue-3.4/ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch b/queue-3.4/ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch
new file mode 100644 (file)
index 0000000..96dd71a
--- /dev/null
@@ -0,0 +1,46 @@
+From 7149f2558d5b5b988726662fe58b1c388337805b Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Wed, 12 Sep 2012 18:02:46 -0700
+Subject: eCryptfs: Write out all dirty pages just before releasing the lower file
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit 7149f2558d5b5b988726662fe58b1c388337805b upstream.
+
+Fixes a regression caused by:
+
+821f749 eCryptfs: Revert to a writethrough cache model
+
+That patch reverted some code (specifically, 32001d6f) that was
+necessary to properly handle open() -> mmap() -> close() -> dirty pages
+-> munmap(), because the lower file could be closed before the dirty
+pages are written out.
+
+Rather than reapplying 32001d6f, this approach is a better way of
+ensuring that the lower file is still open in order to handle writing
+out the dirty pages. It is called from ecryptfs_release(), while we have
+a lock on the lower file pointer, just before the lower file gets the
+final fput() and we overwrite the pointer.
+
+https://launchpad.net/bugs/1047261
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Reported-by: Artemy Tregubenko <me@arty.name>
+Tested-by: Artemy Tregubenko <me@arty.name>
+Tested-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ecryptfs/main.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ecryptfs/main.c
++++ b/fs/ecryptfs/main.c
+@@ -162,6 +162,7 @@ void ecryptfs_put_lower_file(struct inod
+       inode_info = ecryptfs_inode_to_private(inode);
+       if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count,
+                                     &inode_info->lower_file_mutex)) {
++              filemap_write_and_wait(inode->i_mapping);
+               fput(inode_info->lower_file);
+               inode_info->lower_file = NULL;
+               mutex_unlock(&inode_info->lower_file_mutex);
diff --git a/queue-3.4/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch b/queue-3.4/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch
new file mode 100644 (file)
index 0000000..f28d028
--- /dev/null
@@ -0,0 +1,230 @@
+From 09e05d4805e6c524c1af74e524e5d0528bb3fef3 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 11 Jul 2012 23:16:25 +0200
+Subject: jbd: Fix assertion failure in commit code due to lacking transaction credits
+
+From: Jan Kara <jack@suse.cz>
+
+commit 09e05d4805e6c524c1af74e524e5d0528bb3fef3 upstream.
+
+ext3 users of data=journal mode with blocksize < pagesize were occasionally
+hitting assertion failure in journal_commit_transaction() checking whether the
+transaction has at least as many credits reserved as buffers attached.  The
+core of the problem is that when a file gets truncated, buffers that still need
+checkpointing or that are attached to the committing transaction are left with
+buffer_mapped set. When this happens to buffers beyond i_size attached to a
+page stradding i_size, subsequent write extending the file will see these
+buffers and as they are mapped (but underlying blocks were freed) things go
+awry from here.
+
+The assertion failure just coincidentally (and in this case luckily as we would
+start corrupting filesystem) triggers due to journal_head not being properly
+cleaned up as well.
+
+Under some rare circumstances this bug could even hit data=ordered mode users.
+There the assertion won't trigger and we would end up corrupting the
+filesystem.
+
+We fix the problem by unmapping buffers if possible (in lots of cases we just
+need a buffer attached to a transaction as a place holder but it must not be
+written out anyway). And in one case, we just have to bite the bullet and wait
+for transaction commit to finish.
+
+Reviewed-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jbd/commit.c      |   45 +++++++++++++++++++++++++++--------
+ fs/jbd/transaction.c |   64 +++++++++++++++++++++++++++++++++++----------------
+ 2 files changed, 78 insertions(+), 31 deletions(-)
+
+--- a/fs/jbd/commit.c
++++ b/fs/jbd/commit.c
+@@ -86,7 +86,12 @@ nope:
+ static void release_data_buffer(struct buffer_head *bh)
+ {
+       if (buffer_freed(bh)) {
++              WARN_ON_ONCE(buffer_dirty(bh));
+               clear_buffer_freed(bh);
++              clear_buffer_mapped(bh);
++              clear_buffer_new(bh);
++              clear_buffer_req(bh);
++              bh->b_bdev = NULL;
+               release_buffer_page(bh);
+       } else
+               put_bh(bh);
+@@ -853,17 +858,35 @@ restart_loop:
+                * there's no point in keeping a checkpoint record for
+                * it. */
+-              /* A buffer which has been freed while still being
+-               * journaled by a previous transaction may end up still
+-               * being dirty here, but we want to avoid writing back
+-               * that buffer in the future after the "add to orphan"
+-               * operation been committed,  That's not only a performance
+-               * gain, it also stops aliasing problems if the buffer is
+-               * left behind for writeback and gets reallocated for another
+-               * use in a different page. */
+-              if (buffer_freed(bh) && !jh->b_next_transaction) {
+-                      clear_buffer_freed(bh);
+-                      clear_buffer_jbddirty(bh);
++              /*
++               * A buffer which has been freed while still being journaled by
++               * a previous transaction.
++               */
++              if (buffer_freed(bh)) {
++                      /*
++                       * If the running transaction is the one containing
++                       * "add to orphan" operation (b_next_transaction !=
++                       * NULL), we have to wait for that transaction to
++                       * commit before we can really get rid of the buffer.
++                       * So just clear b_modified to not confuse transaction
++                       * credit accounting and refile the buffer to
++                       * BJ_Forget of the running transaction. If the just
++                       * committed transaction contains "add to orphan"
++                       * operation, we can completely invalidate the buffer
++                       * now. We are rather throughout in that since the
++                       * buffer may be still accessible when blocksize <
++                       * pagesize and it is attached to the last partial
++                       * page.
++                       */
++                      jh->b_modified = 0;
++                      if (!jh->b_next_transaction) {
++                              clear_buffer_freed(bh);
++                              clear_buffer_jbddirty(bh);
++                              clear_buffer_mapped(bh);
++                              clear_buffer_new(bh);
++                              clear_buffer_req(bh);
++                              bh->b_bdev = NULL;
++                      }
+               }
+               if (buffer_jbddirty(bh)) {
+--- a/fs/jbd/transaction.c
++++ b/fs/jbd/transaction.c
+@@ -1845,15 +1845,16 @@ static int __dispose_buffer(struct journ
+  * We're outside-transaction here.  Either or both of j_running_transaction
+  * and j_committing_transaction may be NULL.
+  */
+-static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
++static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
++                              int partial_page)
+ {
+       transaction_t *transaction;
+       struct journal_head *jh;
+       int may_free = 1;
+-      int ret;
+       BUFFER_TRACE(bh, "entry");
++retry:
+       /*
+        * It is safe to proceed here without the j_list_lock because the
+        * buffers cannot be stolen by try_to_free_buffers as long as we are
+@@ -1881,10 +1882,18 @@ static int journal_unmap_buffer(journal_
+        * clear the buffer dirty bit at latest at the moment when the
+        * transaction marking the buffer as freed in the filesystem
+        * structures is committed because from that moment on the
+-       * buffer can be reallocated and used by a different page.
++       * block can be reallocated and used by a different page.
+        * Since the block hasn't been freed yet but the inode has
+        * already been added to orphan list, it is safe for us to add
+        * the buffer to BJ_Forget list of the newest transaction.
++       *
++       * Also we have to clear buffer_mapped flag of a truncated buffer
++       * because the buffer_head may be attached to the page straddling
++       * i_size (can happen only when blocksize < pagesize) and thus the
++       * buffer_head can be reused when the file is extended again. So we end
++       * up keeping around invalidated buffers attached to transactions'
++       * BJ_Forget list just to stop checkpointing code from cleaning up
++       * the transaction this buffer was modified in.
+        */
+       transaction = jh->b_transaction;
+       if (transaction == NULL) {
+@@ -1911,13 +1920,9 @@ static int journal_unmap_buffer(journal_
+                        * committed, the buffer won't be needed any
+                        * longer. */
+                       JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget");
+-                      ret = __dispose_buffer(jh,
++                      may_free = __dispose_buffer(jh,
+                                       journal->j_running_transaction);
+-                      journal_put_journal_head(jh);
+-                      spin_unlock(&journal->j_list_lock);
+-                      jbd_unlock_bh_state(bh);
+-                      spin_unlock(&journal->j_state_lock);
+-                      return ret;
++                      goto zap_buffer;
+               } else {
+                       /* There is no currently-running transaction. So the
+                        * orphan record which we wrote for this file must have
+@@ -1925,13 +1930,9 @@ static int journal_unmap_buffer(journal_
+                        * the committing transaction, if it exists. */
+                       if (journal->j_committing_transaction) {
+                               JBUFFER_TRACE(jh, "give to committing trans");
+-                              ret = __dispose_buffer(jh,
++                              may_free = __dispose_buffer(jh,
+                                       journal->j_committing_transaction);
+-                              journal_put_journal_head(jh);
+-                              spin_unlock(&journal->j_list_lock);
+-                              jbd_unlock_bh_state(bh);
+-                              spin_unlock(&journal->j_state_lock);
+-                              return ret;
++                              goto zap_buffer;
+                       } else {
+                               /* The orphan record's transaction has
+                                * committed.  We can cleanse this buffer */
+@@ -1952,10 +1953,24 @@ static int journal_unmap_buffer(journal_
+               }
+               /*
+                * The buffer is committing, we simply cannot touch
+-               * it. So we just set j_next_transaction to the
+-               * running transaction (if there is one) and mark
+-               * buffer as freed so that commit code knows it should
+-               * clear dirty bits when it is done with the buffer.
++               * it. If the page is straddling i_size we have to wait
++               * for commit and try again.
++               */
++              if (partial_page) {
++                      tid_t tid = journal->j_committing_transaction->t_tid;
++
++                      journal_put_journal_head(jh);
++                      spin_unlock(&journal->j_list_lock);
++                      jbd_unlock_bh_state(bh);
++                      spin_unlock(&journal->j_state_lock);
++                      log_wait_commit(journal, tid);
++                      goto retry;
++              }
++              /*
++               * OK, buffer won't be reachable after truncate. We just set
++               * j_next_transaction to the running transaction (if there is
++               * one) and mark buffer as freed so that commit code knows it
++               * should clear dirty bits when it is done with the buffer.
+                */
+               set_buffer_freed(bh);
+               if (journal->j_running_transaction && buffer_jbddirty(bh))
+@@ -1978,6 +1993,14 @@ static int journal_unmap_buffer(journal_
+       }
+ zap_buffer:
++      /*
++       * This is tricky. Although the buffer is truncated, it may be reused
++       * if blocksize < pagesize and it is attached to the page straddling
++       * EOF. Since the buffer might have been added to BJ_Forget list of the
++       * running transaction, journal_get_write_access() won't clear
++       * b_modified and credit accounting gets confused. So clear b_modified
++       * here. */
++      jh->b_modified = 0;
+       journal_put_journal_head(jh);
+ zap_buffer_no_jh:
+       spin_unlock(&journal->j_list_lock);
+@@ -2026,7 +2049,8 @@ void journal_invalidatepage(journal_t *j
+               if (offset <= curr_off) {
+                       /* This block is wholly outside the truncation point */
+                       lock_buffer(bh);
+-                      may_free &= journal_unmap_buffer(journal, bh);
++                      may_free &= journal_unmap_buffer(journal, bh,
++                                                       offset > 0);
+                       unlock_buffer(bh);
+               }
+               curr_off = next_off;
index a4bfd644d738ebb6c0f858cca5c78d6a25d9c92f..1a6fa04be1521abc9088d869de9d9ad8050778b5 100644 (file)
@@ -44,3 +44,12 @@ netfilter-xt_limit-have-r-cost-0-case-work.patch
 add-cdc-acm-support-for-the-cx93010-2x-ucmxx-usb-modem.patch
 drm-radeon-don-t-destroy-i2c-bus-rec-in-radeon_ext_tmds_enc_destroy.patch
 drm-i915-use-adjusted_mode-instead-of-mode-for-checking-the-6bpc-force-flag.patch
+jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch
+e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch
+tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch
+ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch
+ecryptfs-initialize-empty-lower-files-when-opening-them.patch
+ecryptfs-revert-to-a-writethrough-cache-model.patch
+ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch
+ecryptfs-call-lower-flush-from-ecryptfs_flush.patch
+usb-gadget-at91_udc-fix-dt-support.patch
diff --git a/queue-3.4/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch b/queue-3.4/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch
new file mode 100644 (file)
index 0000000..6d4e56b
--- /dev/null
@@ -0,0 +1,95 @@
+From abce9ac292e13da367bbd22c1f7669f988d931ac Mon Sep 17 00:00:00 2001
+From: Peter Huewe <peter.huewe@infineon.com>
+Date: Thu, 27 Sep 2012 16:09:33 +0200
+Subject: tpm: Propagate error from tpm_transmit to fix a timeout hang
+
+From: Peter Huewe <peter.huewe@infineon.com>
+
+commit abce9ac292e13da367bbd22c1f7669f988d931ac upstream.
+
+tpm_write calls tpm_transmit without checking the return value and
+assigns the return value unconditionally to chip->pending_data, even if
+it's an error value.
+This causes three bugs.
+
+So if we write to /dev/tpm0 with a tpm_param_size bigger than
+TPM_BUFSIZE=0x1000 (e.g. 0x100a)
+and a bufsize also bigger than TPM_BUFSIZE (e.g. 0x100a)
+tpm_transmit returns -E2BIG which is assigned to chip->pending_data as
+-7, but tpm_write returns that TPM_BUFSIZE bytes have been successfully
+been written to the TPM, altough this is not true (bug #1).
+
+As we did write more than than TPM_BUFSIZE bytes but tpm_write reports
+that only TPM_BUFSIZE bytes have been written the vfs tries to write
+the remaining bytes (in this case 10 bytes) to the tpm device driver via
+tpm_write which then blocks at
+
+ /* cannot perform a write until the read has cleared
+ either via tpm_read or a user_read_timer timeout */
+ while (atomic_read(&chip->data_pending) != 0)
+        msleep(TPM_TIMEOUT);
+
+for 60 seconds, since data_pending is -7 and nobody is able to
+read it (since tpm_read luckily checks if data_pending is greater than
+0) (#bug 2).
+
+After that the remaining bytes are written to the TPM which are
+interpreted by the tpm as a normal command. (bug #3)
+So if the last bytes of the command stream happen to be a e.g.
+tpm_force_clear this gets accidentally sent to the TPM.
+
+This patch fixes all three bugs, by propagating the error code of
+tpm_write and returning -E2BIG if the input buffer is too big,
+since the response from the tpm for a truncated value is bogus anyway.
+Moreover it returns -EBUSY to userspace if there is a response ready to be
+read.
+
+Signed-off-by: Peter Huewe <peter.huewe@infineon.com>
+Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm.c |   21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+--- a/drivers/char/tpm/tpm.c
++++ b/drivers/char/tpm/tpm.c
+@@ -1186,17 +1186,20 @@ ssize_t tpm_write(struct file *file, con
+                 size_t size, loff_t *off)
+ {
+       struct tpm_chip *chip = file->private_data;
+-      size_t in_size = size, out_size;
++      size_t in_size = size;
++      ssize_t out_size;
+       /* cannot perform a write until the read has cleared
+-         either via tpm_read or a user_read_timer timeout */
+-      while (atomic_read(&chip->data_pending) != 0)
+-              msleep(TPM_TIMEOUT);
+-
+-      mutex_lock(&chip->buffer_mutex);
++         either via tpm_read or a user_read_timer timeout.
++         This also prevents splitted buffered writes from blocking here.
++      */
++      if (atomic_read(&chip->data_pending) != 0)
++              return -EBUSY;
+       if (in_size > TPM_BUFSIZE)
+-              in_size = TPM_BUFSIZE;
++              return -E2BIG;
++
++      mutex_lock(&chip->buffer_mutex);
+       if (copy_from_user
+           (chip->data_buffer, (void __user *) buf, in_size)) {
+@@ -1206,6 +1209,10 @@ ssize_t tpm_write(struct file *file, con
+       /* atomic tpm command send and result receive */
+       out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
++      if (out_size < 0) {
++              mutex_unlock(&chip->buffer_mutex);
++              return out_size;
++      }
+       atomic_set(&chip->data_pending, out_size);
+       mutex_unlock(&chip->buffer_mutex);
diff --git a/queue-3.4/usb-gadget-at91_udc-fix-dt-support.patch b/queue-3.4/usb-gadget-at91_udc-fix-dt-support.patch
new file mode 100644 (file)
index 0000000..414946d
--- /dev/null
@@ -0,0 +1,31 @@
+From 9c6d196d5aa35e07482f23c3e37755e7a82140e0 Mon Sep 17 00:00:00 2001
+From: Fabio Porcedda <fabio.porcedda@gmail.com>
+Date: Fri, 7 Sep 2012 15:27:42 +0200
+Subject: usb: gadget: at91_udc: fix dt support
+
+From: Fabio Porcedda <fabio.porcedda@gmail.com>
+
+commit 9c6d196d5aa35e07482f23c3e37755e7a82140e0 upstream.
+
+Don't fail the initialization check for the platform_data
+if there is avaiable an associated device tree node.
+
+Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/at91_udc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/at91_udc.c
++++ b/drivers/usb/gadget/at91_udc.c
+@@ -1735,7 +1735,7 @@ static int __devinit at91udc_probe(struc
+       int             retval;
+       struct resource *res;
+-      if (!dev->platform_data) {
++      if (!dev->platform_data && !pdev->dev.of_node) {
+               /* small (so we copy it) but critical! */
+               DBG("missing platform_data\n");
+               return -ENODEV;