]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Mar 2017 08:54:16 +0000 (10:54 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Mar 2017 08:54:16 +0000 (10:54 +0200)
added patches:
fscrypt-remove-broken-support-for-detecting-keyring-key-revocation.patch
sched-rt-add-a-missing-rescheduling-point.patch

queue-4.4/fscrypt-remove-broken-support-for-detecting-keyring-key-revocation.patch [new file with mode: 0644]
queue-4.4/kvm-nvmx-fix-nested-vpid-vmx-exec-control.patch [deleted file]
queue-4.4/kvm-nvmx-invvpid-handling-improvements.patch [deleted file]
queue-4.4/sched-rt-add-a-missing-rescheduling-point.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/fscrypt-remove-broken-support-for-detecting-keyring-key-revocation.patch b/queue-4.4/fscrypt-remove-broken-support-for-detecting-keyring-key-revocation.patch
new file mode 100644 (file)
index 0000000..290a4fa
--- /dev/null
@@ -0,0 +1,294 @@
+From 1b53cf9815bb4744958d41f3795d5d5a1d365e2d Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Tue, 21 Feb 2017 15:07:11 -0800
+Subject: fscrypt: remove broken support for detecting keyring key revocation
+
+From: Eric Biggers <ebiggers@google.com>
+
+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 <ebiggers@google.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Acked-by: Michael Halcrow <mhalcrow@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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(-)
+
+--- a/fs/ext4/crypto_key.c
++++ b/fs/ext4/crypto_key.c
+@@ -88,8 +88,6 @@ void ext4_free_crypt_info(struct ext4_cr
+       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 in
+       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 ino
+       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;
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2330,23 +2330,11 @@ static inline void ext4_fname_free_filen
+ /* 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)
+ {
+--- 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];
+ };
+--- a/fs/f2fs/crypto_key.c
++++ b/fs/f2fs/crypto_key.c
+@@ -92,7 +92,6 @@ static void f2fs_free_crypt_info(struct
+       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 in
+       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 ino
+       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;
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -2149,7 +2149,6 @@ void f2fs_end_io_crypto_work(struct f2fs
+ /* 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 *,
+--- 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];
+ };
diff --git a/queue-4.4/kvm-nvmx-fix-nested-vpid-vmx-exec-control.patch b/queue-4.4/kvm-nvmx-fix-nested-vpid-vmx-exec-control.patch
deleted file mode 100644 (file)
index f8d6167..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-From 63cb6d5f004ca44f9b8e562b6dd191f717a4960e Mon Sep 17 00:00:00 2001
-From: Wanpeng Li <wanpeng.li@hotmail.com>
-Date: Mon, 20 Mar 2017 21:18:53 -0700
-Subject: KVM: nVMX: Fix nested VPID vmx exec control
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Wanpeng Li <wanpeng.li@hotmail.com>
-
-commit 63cb6d5f004ca44f9b8e562b6dd191f717a4960e upstream.
-
-This can be reproduced by running kvm-unit-tests/vmx.flat on L0 w/ vpid disabled.
-
-Test suite: VPID
-Unhandled exception 6 #UD at ip 00000000004051a6
-error_code=0000      rflags=00010047      cs=00000008
-rax=0000000000000000 rcx=0000000000000001 rdx=0000000000000047 rbx=0000000000402f79
-rbp=0000000000456240 rsi=0000000000000001 rdi=0000000000000000
-r8=000000000000000a  r9=00000000000003f8 r10=0000000080010011 r11=0000000000000000
-r12=0000000000000003 r13=0000000000000708 r14=0000000000000000 r15=0000000000000000
-cr0=0000000080010031 cr2=0000000000000000 cr3=0000000007fff000 cr4=0000000000002020
-cr8=0000000000000000
-STACK: @4051a6 40523e 400f7f 402059 40028f
-
-We should hide and forbid VPID in L1 if it is disabled on L0. However, nested VPID
-enable bit is set unconditionally during setup nested vmx exec controls though VPID
-is not exposed through nested VMX capablity. This patch fixes it by don't set nested
-VPID enable bit if it is disabled on L0.
-
-Cc: Paolo Bonzini <pbonzini@redhat.com>
-Cc: Radim Krčmář <rkrcmar@redhat.com>
-Fixes: 5c614b3583e (KVM: nVMX: nested VPID emulation)
-Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- arch/x86/kvm/vmx.c |    7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
---- a/arch/x86/kvm/vmx.c
-+++ b/arch/x86/kvm/vmx.c
-@@ -2620,7 +2620,6 @@ static void nested_vmx_setup_ctls_msrs(s
-               SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
-               SECONDARY_EXEC_RDTSCP |
-               SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
--              SECONDARY_EXEC_ENABLE_VPID |
-               SECONDARY_EXEC_APIC_REGISTER_VIRT |
-               SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
-               SECONDARY_EXEC_WBINVD_EXITING |
-@@ -2650,10 +2649,12 @@ static void nested_vmx_setup_ctls_msrs(s
-        * though it is treated as global context.  The alternative is
-        * not failing the single-context invvpid, and it is worse.
-        */
--      if (enable_vpid)
-+      if (enable_vpid) {
-+              vmx->nested.nested_vmx_secondary_ctls_high |=
-+                      SECONDARY_EXEC_ENABLE_VPID;
-               vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
-                       VMX_VPID_EXTENT_SUPPORTED_MASK;
--      else
-+      } else
-               vmx->nested.nested_vmx_vpid_caps = 0;
-       if (enable_unrestricted_guest)
diff --git a/queue-4.4/kvm-nvmx-invvpid-handling-improvements.patch b/queue-4.4/kvm-nvmx-invvpid-handling-improvements.patch
deleted file mode 100644 (file)
index 30ab6fb..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-From bcdde302b8268ef7dbc4ddbdaffb5b44eafe9a1e Mon Sep 17 00:00:00 2001
-From: Jan Dakinevich <jan.dakinevich@gmail.com>
-Date: Fri, 28 Oct 2016 07:00:30 +0300
-Subject: KVM: nVMX: invvpid handling improvements
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Jan Dakinevich <jan.dakinevich@gmail.com>
-
-commit bcdde302b8268ef7dbc4ddbdaffb5b44eafe9a1e upstream.
-
- - Expose all invalidation types to the L1
-
- - Reject invvpid instruction, if L1 passed zero vpid value to single
-   context invalidations
-
-Signed-off-by: Jan Dakinevich <jan.dakinevich@gmail.com>
-Tested-by: Ladi Prosek <lprosek@redhat.com>
-Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- arch/x86/kvm/vmx.c |   36 ++++++++++++++++++++++++------------
- 1 file changed, 24 insertions(+), 12 deletions(-)
-
---- a/arch/x86/kvm/vmx.c
-+++ b/arch/x86/kvm/vmx.c
-@@ -124,6 +124,12 @@ module_param_named(pml, enable_pml, bool
- #define VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE 5
-+#define VMX_VPID_EXTENT_SUPPORTED_MASK                \
-+      (VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT |  \
-+      VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT |    \
-+      VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT |    \
-+      VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT)
-+
- /*
-  * These 2 parameters are used to config the controls for Pause-Loop Exiting:
-  * ple_gap:    upper bound on the amount of time between two successive
-@@ -2646,8 +2652,7 @@ static void nested_vmx_setup_ctls_msrs(s
-        */
-       if (enable_vpid)
-               vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT |
--                              VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT |
--                              VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
-+                      VMX_VPID_EXTENT_SUPPORTED_MASK;
-       else
-               vmx->nested.nested_vmx_vpid_caps = 0;
-@@ -7407,7 +7412,8 @@ static int handle_invvpid(struct kvm_vcp
-       vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
-       type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf);
--      types = (vmx->nested.nested_vmx_vpid_caps >> 8) & 0x7;
-+      types = (vmx->nested.nested_vmx_vpid_caps &
-+                      VMX_VPID_EXTENT_SUPPORTED_MASK) >> 8;
-       if (!(types & (1UL << type))) {
-               nested_vmx_failValid(vcpu,
-@@ -7429,21 +7435,27 @@ static int handle_invvpid(struct kvm_vcp
-       }
-       switch (type) {
-+      case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
-       case VMX_VPID_EXTENT_SINGLE_CONTEXT:
--              /*
--               * Old versions of KVM use the single-context version so we
--               * have to support it; just treat it the same as all-context.
--               */
-+      case VMX_VPID_EXTENT_SINGLE_NON_GLOBAL:
-+              if (!vpid) {
-+                      nested_vmx_failValid(vcpu,
-+                              VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
-+                      skip_emulated_instruction(vcpu);
-+                      return 1;
-+              }
-+              break;
-       case VMX_VPID_EXTENT_ALL_CONTEXT:
--              __vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
--              nested_vmx_succeed(vcpu);
-               break;
-       default:
--              /* Trap individual address invalidation invvpid calls */
--              BUG_ON(1);
--              break;
-+              WARN_ON_ONCE(1);
-+              skip_emulated_instruction(vcpu);
-+              return 1;
-       }
-+      __vmx_flush_tlb(vcpu, vmx->nested.vpid02);
-+      nested_vmx_succeed(vcpu);
-+
-       skip_emulated_instruction(vcpu);
-       return 1;
- }
diff --git a/queue-4.4/sched-rt-add-a-missing-rescheduling-point.patch b/queue-4.4/sched-rt-add-a-missing-rescheduling-point.patch
new file mode 100644 (file)
index 0000000..4f26db5
--- /dev/null
@@ -0,0 +1,76 @@
+From 619bd4a71874a8fd78eb6ccf9f272c5e98bcc7b7 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Tue, 24 Jan 2017 15:40:06 +0100
+Subject: sched/rt: Add a missing rescheduling point
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+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 <peterz@infradead.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+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 <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sched/deadline.c |    3 +--
+ kernel/sched/rt.c       |    3 +--
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -1771,12 +1771,11 @@ static void switched_to_dl(struct rq *rq
+ #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
+       }
+ }
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -2136,10 +2136,9 @@ static void switched_to_rt(struct rq *rq
+ #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 */
+       }
+ }
index 154508155d62c60f7231e4599bb47390bde8f082..6f76a7d7cc74ff5a684a612a366a71a0181d9579 100644 (file)
@@ -1,8 +1,6 @@
 xfrm-policy-init-locks-early.patch
 xfrm_user-validate-xfrm_msg_newae-xfrma_replay_esn_val-replay_window.patch
 xfrm_user-validate-xfrm_msg_newae-incoming-esn-size-harder.patch
-kvm-nvmx-invvpid-handling-improvements.patch
-kvm-nvmx-fix-nested-vpid-vmx-exec-control.patch
 virtio_balloon-init-1st-buffer-in-stats-vq.patch
 pinctrl-qcom-don-t-clear-status-bit-on-irq_unmask.patch
 c6x-ptrace-remove-useless-ptrace_setregset-implementation.patch
@@ -12,3 +10,5 @@ sparc-ptrace-preserve-previous-registers-for-short-regset-write.patch
 metag-ptrace-preserve-previous-registers-for-short-regset-write.patch
 metag-ptrace-provide-default-txstatus-for-short-nt_prstatus.patch
 metag-ptrace-reject-partial-nt_metag_rpipe-writes.patch
+fscrypt-remove-broken-support-for-detecting-keyring-key-revocation.patch
+sched-rt-add-a-missing-rescheduling-point.patch