Home Home > GIT Browse > openSUSE-15.0
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKernel Build Daemon <kbuild@suse.de>2018-09-12 07:08:27 +0200
committerKernel Build Daemon <kbuild@suse.de>2018-09-12 07:08:27 +0200
commit4a89ece28a2a21e6ddf042f9d1a1d67e2b5b7811 (patch)
tree50e7713817e0c471e4fa106e0de628855972d240
parent866f06d403a2e8954c8da5ea2bf4047458983e53 (diff)
parent570b813da49e6636fd40f4d9cc8f8d90b8a4482a (diff)
Merge branch 'SLE12-SP3' into SLE12-SP3-AZURErpm-4.4.155-4.16
-rw-r--r--blacklist.conf1
-rw-r--r--patches.arch/00-jump_label-remove-bug-h-atomic-h-dependencies-for-have_jump_label.patch203
-rw-r--r--patches.arch/01-jump_label-reduce-the-size-of-struct-static_key-kabi.patch315
-rw-r--r--patches.arch/02-jump_label-reorder-hotplug-lock-and-jump_label_lock.patch194
-rw-r--r--patches.arch/03-jump_label-fix-concurrent-static_key_enable-disable.patch143
-rw-r--r--patches.arch/04-jump_label-add-release-barrier-after-text-changes.patch50
-rw-r--r--patches.arch/05-jump_label-move-cpu-hotplug-locking.patch50
-rw-r--r--patches.arch/06-jump_label-split-out-code-under-the-hotplug-lock.patch104
-rw-r--r--patches.arch/07-jump_label-provide-hotplug-context-variants.patch147
-rw-r--r--patches.arch/08-s390-add-explicit-linux-stringify-h-for-jump-label.patch30
-rw-r--r--patches.drivers/ibmvnic-Include-missing-return-code-checks-in-reset-.patch49
-rw-r--r--patches.suse/xen-disable_hotplug_cpu.patch36
-rw-r--r--patches.suse/xfs-don-t-call-xfs_da_shrink_inode-with-NULL-bp.patch47
-rw-r--r--patches.suse/xfs-fix-a-null-pointer-dereference-in-xfs_bmap_exten.patch69
-rw-r--r--patches.suse/xfs-validate-cached-inodes-are-free-when-allocated.patch142
-rwxr-xr-xscripts/bugzilla-create4
-rwxr-xr-xscripts/cvs-wd-timestamp2
-rw-r--r--scripts/git_sort/README.md4
-rwxr-xr-xscripts/git_sort/clean_header.sh2
-rwxr-xr-xscripts/git_sort/clone_all.py45
-rwxr-xr-xscripts/git_sort/git_sort.py89
-rw-r--r--scripts/git_sort/lib.py87
-rw-r--r--scripts/git_sort/patch.py106
-rwxr-xr-xscripts/git_sort/qcp.py11
-rwxr-xr-xscripts/git_sort/qdupcheck.py6
-rw-r--r--scripts/git_sort/quilt-mode.sh16
-rwxr-xr-xscripts/git_sort/refs_in_series.sh2
-rwxr-xr-xscripts/git_sort/series_conf.py20
-rwxr-xr-xscripts/git_sort/series_insert.py3
-rwxr-xr-xscripts/git_sort/series_sort.py1
-rw-r--r--scripts/git_sort/tag.py112
-rw-r--r--scripts/git_sort/tests/opensuse-15.0/Dockerfile25
-rw-r--r--scripts/git_sort/tests/opensuse-42.3/Dockerfile4
-rw-r--r--scripts/git_sort/tests/opensuse-tumbleweed/Dockerfile4
-rwxr-xr-xscripts/git_sort/tests/run_all.sh9
-rw-r--r--scripts/git_sort/tests/sle12-sp3/Dockerfile4
-rw-r--r--scripts/git_sort/tests/sle15/Dockerfile25
-rw-r--r--scripts/git_sort/tests/support.py5
-rwxr-xr-xscripts/git_sort/tests/test_quilt_mode.py152
-rwxr-xr-xscripts/git_sort/tests/test_series_sort.py15
-rwxr-xr-xscripts/git_sort/update_clone.py99
-rwxr-xr-xscripts/install-git-hooks4
-rwxr-xr-xscripts/linux_git.sh9
-rwxr-xr-xscripts/log230
-rwxr-xr-xscripts/patch-tags-from-git2
-rwxr-xr-xscripts/python/check-patchhdr6
-rwxr-xr-xscripts/python/suse_git/header.py2
-rw-r--r--scripts/python/suse_git/patch.py2
-rwxr-xr-xscripts/run_oldconfig.sh5
-rwxr-xr-xscripts/sequence-patch.sh3
-rwxr-xr-xscripts/tar-up.sh4
-rwxr-xr-xscripts/tests/test_linux_git.py53
-rwxr-xr-xscripts/tests/test_log2.py105
-rw-r--r--scripts/wd-functions.sh9
-rw-r--r--series.conf15
55 files changed, 2387 insertions, 294 deletions
diff --git a/blacklist.conf b/blacklist.conf
index bf87a69188..3c3baf1cf2 100644
--- a/blacklist.conf
+++ b/blacklist.conf
@@ -462,3 +462,4 @@ a6f572084fbee8b30f91465f4a085d7a90901c57 # bnc#1107070
974f6c046ad90d071f96c76ff8ab29355a798c41 # dup
6291c608a908a9d62be650373bce7f734311d07c # dup
fc16f56b7bfd5bfe812ba2cd3a4c8943977e8306 # dup
+cd8d860dcce906cd477be7d0648ba6f56a52eaa6 # we don't care about older (< 4.6) compilers
diff --git a/patches.arch/00-jump_label-remove-bug-h-atomic-h-dependencies-for-have_jump_label.patch b/patches.arch/00-jump_label-remove-bug-h-atomic-h-dependencies-for-have_jump_label.patch
new file mode 100644
index 0000000000..cfc20b8abd
--- /dev/null
+++ b/patches.arch/00-jump_label-remove-bug-h-atomic-h-dependencies-for-have_jump_label.patch
@@ -0,0 +1,203 @@
+From: Jason Baron <jbaron@akamai.com>
+Date: Wed, 3 Aug 2016 13:46:36 -0700
+Subject: jump_label: remove bug.h, atomic.h dependencies for HAVE_JUMP_LABEL
+Git-commit: 1f69bf9c6137602cd028c96b4f8329121ec89231
+Patch-mainline: v4.8-rc1
+References: bsc#1105271
+
+The current jump_label.h includes bug.h for things such as WARN_ON().
+This makes the header problematic for inclusion by kernel.h or any
+headers that kernel.h includes, since bug.h includes kernel.h (circular
+dependency). The inclusion of atomic.h is similarly problematic. Thus,
+this should make jump_label.h 'includable' from most places.
+
+Link: http://lkml.kernel.org/r/7060ce35ddd0d20b33bf170685e6b0fab816bdf2.1467837322.git.jbaron@akamai.com
+Signed-off-by: Jason Baron <jbaron@akamai.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Chris Metcalf <cmetcalf@mellanox.com>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Joe Perches <joe@perches.com>
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ include/linux/jump_label.h | 48 ++++++++++++++++++++--------------------
+ kernel/jump_label.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 77 insertions(+), 24 deletions(-)
+
+--- a/include/linux/jump_label.h
++++ b/include/linux/jump_label.h
+@@ -78,7 +78,6 @@
+
+ #include <linux/types.h>
+ #include <linux/compiler.h>
+-#include <linux/bug.h>
+
+ extern bool static_key_initialized;
+
+@@ -117,20 +116,8 @@ enum jump_label_type {
+
+ struct module;
+
+-#include <linux/atomic.h>
+-
+ #ifdef HAVE_JUMP_LABEL
+
+-static inline int static_key_count(struct static_key *key)
+-{
+- /*
+- * -1 means the first static_key_slow_inc() is in progress.
+- * static_key_enabled() must return true, so return 1 here.
+- */
+- int n = atomic_read(&key->enabled);
+- return n >= 0 ? n : 1;
+-}
+-
+ #define JUMP_TYPE_FALSE 0UL
+ #define JUMP_TYPE_TRUE 1UL
+ #define JUMP_TYPE_MASK 1UL
+@@ -159,16 +146,29 @@ extern int jump_label_text_reserved(void
+ extern void static_key_slow_inc(struct static_key *key);
+ extern void static_key_slow_dec(struct static_key *key);
+ extern void jump_label_apply_nops(struct module *mod);
+-
++extern int static_key_count(struct static_key *key);
++extern void static_key_enable(struct static_key *key);
++extern void static_key_disable(struct static_key *key);
++
++/*
++ * We should be using ATOMIC_INIT() for initializing .enabled, but
++ * the inclusion of atomic.h is problematic for inclusion of jump_label.h
++ * in 'low-level' headers. Thus, we are initializing .enabled with a
++ * raw value, but have added a BUILD_BUG_ON() to catch any issues in
++ * jump_label_init() see: kernel/jump_label.c.
++ */
+ #define STATIC_KEY_INIT_TRUE \
+- { .enabled = ATOMIC_INIT(1), \
++ { .enabled = { 1 }, \
+ .entries = (void *)JUMP_TYPE_TRUE }
+ #define STATIC_KEY_INIT_FALSE \
+- { .enabled = ATOMIC_INIT(0), \
++ { .enabled = { 0 }, \
+ .entries = (void *)JUMP_TYPE_FALSE }
+
+ #else /* !HAVE_JUMP_LABEL */
+
++#include <linux/atomic.h>
++#include <linux/bug.h>
++
+ static inline int static_key_count(struct static_key *key)
+ {
+ return atomic_read(&key->enabled);
+@@ -218,14 +218,6 @@ static inline int jump_label_apply_nops(
+ return 0;
+ }
+
+-#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
+-#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) }
+-
+-#endif /* HAVE_JUMP_LABEL */
+-
+-#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
+-#define jump_label_enabled static_key_enabled
+-
+ static inline void static_key_enable(struct static_key *key)
+ {
+ int count = static_key_count(key);
+@@ -246,6 +238,14 @@ static inline void static_key_disable(st
+ static_key_slow_dec(key);
+ }
+
++#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
++#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) }
++
++#endif /* HAVE_JUMP_LABEL */
++
++#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
++#define jump_label_enabled static_key_enabled
++
+ /* -------------------------------------------------------------------------- */
+
+ /*
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -14,6 +14,7 @@
+ #include <linux/err.h>
+ #include <linux/static_key.h>
+ #include <linux/jump_label_ratelimit.h>
++#include <linux/bug.h>
+
+ #ifdef HAVE_JUMP_LABEL
+
+@@ -56,6 +57,49 @@ jump_label_sort_entries(struct jump_entr
+
+ static void jump_label_update(struct static_key *key);
+
++/*
++ * There are similar definitions for the !HAVE_JUMP_LABEL case in jump_label.h.
++ * The use of 'atomic_read()' requires atomic.h and its problematic for some
++ * kernel headers such as kernel.h and others. Since static_key_count() is not
++ * used in the branch statements as it is for the !HAVE_JUMP_LABEL case its ok
++ * to have it be a function here. Similarly, for 'static_key_enable()' and
++ * 'static_key_disable()', which require bug.h. This should allow jump_label.h
++ * to be included from most/all places for HAVE_JUMP_LABEL.
++ */
++int static_key_count(struct static_key *key)
++{
++ /*
++ * -1 means the first static_key_slow_inc() is in progress.
++ * static_key_enabled() must return true, so return 1 here.
++ */
++ int n = atomic_read(&key->enabled);
++
++ return n >= 0 ? n : 1;
++}
++EXPORT_SYMBOL_GPL(static_key_count);
++
++void static_key_enable(struct static_key *key)
++{
++ int count = static_key_count(key);
++
++ WARN_ON_ONCE(count < 0 || count > 1);
++
++ if (!count)
++ static_key_slow_inc(key);
++}
++EXPORT_SYMBOL_GPL(static_key_enable);
++
++void static_key_disable(struct static_key *key)
++{
++ int count = static_key_count(key);
++
++ WARN_ON_ONCE(count < 0 || count > 1);
++
++ if (count)
++ static_key_slow_dec(key);
++}
++EXPORT_SYMBOL_GPL(static_key_disable);
++
+ void static_key_slow_inc(struct static_key *key)
+ {
+ int v, v1;
+@@ -242,6 +286,15 @@ void __init jump_label_init(void)
+ struct static_key *key = NULL;
+ struct jump_entry *iter;
+
++ /*
++ * Since we are initializing the static_key.enabled field with
++ * with the 'raw' int values (to avoid pulling in atomic.h) in
++ * jump_label.h, let's make sure that is safe. There are only two
++ * cases to check since we initialize to 0 or 1.
++ */
++ BUILD_BUG_ON((int)ATOMIC_INIT(0) != 0);
++ BUILD_BUG_ON((int)ATOMIC_INIT(1) != 1);
++
+ if (static_key_initialized)
+ return;
+
diff --git a/patches.arch/01-jump_label-reduce-the-size-of-struct-static_key-kabi.patch b/patches.arch/01-jump_label-reduce-the-size-of-struct-static_key-kabi.patch
new file mode 100644
index 0000000000..ba6c5cf64f
--- /dev/null
+++ b/patches.arch/01-jump_label-reduce-the-size-of-struct-static_key-kabi.patch
@@ -0,0 +1,315 @@
+From: Jason Baron <jbaron@akamai.com>
+Date: Fri, 3 Feb 2017 15:42:24 -0500
+Subject: jump_label: Reduce the size of struct static_key
+Git-commit: 3821fd35b58dba449bd894014fbf4e1c43c9e951
+Patch-mainline: v4.11-rc1
+References: bsc#1105271
+
+The static_key->next field goes mostly unused. The field is used for
+associating module uses with a static key. Most uses of struct static_key
+define a static key in the core kernel and make use of it entirely within
+the core kernel, or define the static key in a module and make use of it
+only from within that module. In fact, of the ~3,000 static keys defined,
+I found only about 5 or so that did not fit this pattern.
+
+Thus, we can remove the static_key->next field entirely and overload
+the static_key->entries field. That is, when all the static_key uses
+are contained within the same module, static_key->entries continues
+to point to those uses. However, if the static_key uses are not contained
+within the module where the static_key is defined, then we allocate a
+struct static_key_mod, store a pointer to the uses within that
+struct static_key_mod, and have the static key point at the static_key_mod.
+This does incur some extra memory usage when a static_key is used in a
+module that does not define it, but since there are only a handful of such
+cases there is a net savings.
+
+In order to identify if the static_key->entries pointer contains a
+struct static_key_mod or a struct jump_entry pointer, bit 1 of
+static_key->entries is set to 1 if it points to a struct static_key_mod and
+is 0 if it points to a struct jump_entry. We were already using bit 0 in a
+similar way to store the initial value of the static_key. This does mean
+that allocations of struct static_key_mod and that the struct jump_entry
+tables need to be at least 4-byte aligned in memory. As far as I can tell
+all arches meet this criteria.
+
+For my .config, the patch increased the text by 778 bytes, but reduced
+the data + bss size by 14912, for a net savings of 14,134 bytes.
+
+ text data bss dec hex filename
+8092427 5016512 790528 13899467 d416cb vmlinux.pre
+8093205 5001600 790528 13885333 d3df95 vmlinux.post
+
+Link: http://lkml.kernel.org/r/1486154544-4321-1-git-send-email-jbaron@akamai.com
+
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Joe Perches <joe@perches.com>
+Signed-off-by: Jason Baron <jbaron@akamai.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+[ Avoid the kABI breakage. ]
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ Documentation/static-keys.txt | 4 -
+ include/linux/jump_label.h | 7 +-
+ kernel/jump_label.c | 131 +++++++++++++++++++++++++++++++++---------
+ 3 files changed, 113 insertions(+), 29 deletions(-)
+
+--- a/Documentation/static-keys.txt
++++ b/Documentation/static-keys.txt
+@@ -155,7 +155,9 @@ or:
+
+ There are a few functions and macros that architectures must implement in order
+ to take advantage of this optimization. If there is no architecture support, we
+-simply fall back to a traditional, load, test, and jump sequence.
++simply fall back to a traditional, load, test, and jump sequence. Also, the
++struct jump_entry table must be at least 4-byte aligned because the
++static_key->entry field makes use of the two least significant bits.
+
+ * select HAVE_ARCH_JUMP_LABEL, see: arch/x86/Kconfig
+
+--- a/include/linux/jump_label.h
++++ b/include/linux/jump_label.h
+@@ -118,9 +118,10 @@ struct module;
+
+ #ifdef HAVE_JUMP_LABEL
+
+-#define JUMP_TYPE_FALSE 0UL
+-#define JUMP_TYPE_TRUE 1UL
+-#define JUMP_TYPE_MASK 1UL
++#define JUMP_TYPE_FALSE 0UL
++#define JUMP_TYPE_TRUE 1UL
++#define JUMP_TYPE_LINKED 2UL
++#define JUMP_TYPE_MASK 3UL
+
+ static __always_inline bool static_key_false(struct static_key *key)
+ {
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -241,7 +241,22 @@ static inline struct jump_entry *static_
+
+ static inline bool static_key_type(struct static_key *key)
+ {
+- return (unsigned long)key->entries & JUMP_TYPE_MASK;
++ return (unsigned long)key->entries & JUMP_TYPE_TRUE;
++}
++
++static inline bool static_key_linked(struct static_key *key)
++{
++ return (unsigned long)key->entries & JUMP_TYPE_LINKED;
++}
++
++static inline void static_key_clear_linked(struct static_key *key)
++{
++ *(unsigned long *)&key->entries &= ~JUMP_TYPE_LINKED;
++}
++
++static inline void static_key_set_linked(struct static_key *key)
++{
++ *(unsigned long *)&key->entries |= JUMP_TYPE_LINKED;
+ }
+
+ static inline struct static_key *jump_entry_key(struct jump_entry *entry)
+@@ -254,6 +269,13 @@ static bool jump_entry_branch(struct jum
+ return (unsigned long)entry->key & 1UL;
+ }
+
++static void static_key_set_entries(struct static_key *key,
++ struct jump_entry *entries)
++{
++ WARN_ON_ONCE((unsigned long)entries & JUMP_TYPE_MASK);
++ key->entries = entries;
++}
++
+ static enum jump_label_type jump_label_type(struct jump_entry *entry)
+ {
+ struct static_key *key = jump_entry_key(entry);
+@@ -313,13 +335,7 @@ void __init jump_label_init(void)
+ continue;
+
+ key = iterk;
+- /*
+- * Set key->entries to iter, but preserve JUMP_LABEL_TRUE_BRANCH.
+- */
+- *((unsigned long *)&key->entries) += (unsigned long)iter;
+-#ifdef CONFIG_MODULES
+- key->next = NULL;
+-#endif
++ static_key_set_entries(key, iter);
+ }
+ static_key_initialized = true;
+ jump_label_unlock();
+@@ -343,6 +359,23 @@ struct static_key_mod {
+ struct module *mod;
+ };
+
++static inline struct static_key_mod *static_key_mod(struct static_key *key)
++{
++ WARN_ON_ONCE(!static_key_linked(key));
++
++ /*
++ * bp: ->next is defined only under CONFIG_MODULES but we do only such
++ * kernels so simplify it here.
++ */
++ return key->next;
++}
++
++static void static_key_set_mod(struct static_key *key,
++ struct static_key_mod *mod)
++{
++ key->next = mod;
++}
++
+ static int __jump_label_mod_text_reserved(void *start, void *end)
+ {
+ struct module *mod;
+@@ -362,11 +395,23 @@ static void __jump_label_mod_update(stru
+ {
+ struct static_key_mod *mod;
+
+- for (mod = key->next; mod; mod = mod->next) {
+- struct module *m = mod->mod;
++ for (mod = static_key_mod(key); mod; mod = mod->next) {
++ struct jump_entry *stop;
++ struct module *m;
+
+- __jump_label_update(key, mod->entries,
+- m->jump_entries + m->num_jump_entries);
++ /*
++ * NULL if the static_key is defined in a module
++ * that does not use it
++ */
++ if (!mod->entries)
++ continue;
++
++ m = mod->mod;
++ if (!m)
++ stop = __stop___jump_table;
++ else
++ stop = m->jump_entries + m->num_jump_entries;
++ __jump_label_update(key, mod->entries, stop);
+ }
+ }
+
+@@ -401,7 +446,7 @@ static int jump_label_add_module(struct
+ struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
+ struct jump_entry *iter;
+ struct static_key *key = NULL;
+- struct static_key_mod *jlm;
++ struct static_key_mod *jlm, *jlm2;
+
+ /* if the module doesn't have jump label entries, just return */
+ if (iter_start == iter_stop)
+@@ -418,20 +463,32 @@ static int jump_label_add_module(struct
+
+ key = iterk;
+ if (within_module(iter->key, mod)) {
+- /*
+- * Set key->entries to iter, but preserve JUMP_LABEL_TRUE_BRANCH.
+- */
+- *((unsigned long *)&key->entries) += (unsigned long)iter;
+- key->next = NULL;
++ static_key_set_entries(key, iter);
+ continue;
+ }
+ jlm = kzalloc(sizeof(struct static_key_mod), GFP_KERNEL);
+ if (!jlm)
+ return -ENOMEM;
++ if (!static_key_linked(key)) {
++ jlm2 = kzalloc(sizeof(struct static_key_mod),
++ GFP_KERNEL);
++ if (!jlm2) {
++ kfree(jlm);
++ return -ENOMEM;
++ }
++ preempt_disable();
++ jlm2->mod = __module_address((unsigned long)key);
++ preempt_enable();
++ jlm2->entries = static_key_entries(key);
++ jlm2->next = NULL;
++ static_key_set_mod(key, jlm2);
++ static_key_set_linked(key);
++ }
+ jlm->mod = mod;
+ jlm->entries = iter;
+- jlm->next = key->next;
+- key->next = jlm;
++ jlm->next = static_key_mod(key);
++ static_key_set_mod(key, jlm);
++ static_key_set_linked(key);
+
+ /* Only update if we've changed from our initial state */
+ if (jump_label_type(iter) != jump_label_init_type(iter))
+@@ -458,16 +515,34 @@ static void jump_label_del_module(struct
+ if (within_module(iter->key, mod))
+ continue;
+
++ /* No memory during module load */
++ if (WARN_ON(!static_key_linked(key)))
++ continue;
++
+ prev = &key->next;
+- jlm = key->next;
++ jlm = static_key_mod(key);
+
+ while (jlm && jlm->mod != mod) {
+ prev = &jlm->next;
+ jlm = jlm->next;
+ }
+
+- if (jlm) {
++ /* No memory during module load */
++ if (WARN_ON(!jlm))
++ continue;
++
++ if (prev == &key->next)
++ static_key_set_mod(key, jlm->next);
++ else
+ *prev = jlm->next;
++
++ kfree(jlm);
++
++ jlm = static_key_mod(key);
++ /* if only one etry is left, fold it back into the static_key */
++ if (jlm->next == NULL) {
++ static_key_set_entries(key, jlm->entries);
++ static_key_clear_linked(key);
+ kfree(jlm);
+ }
+ }
+@@ -496,8 +571,10 @@ jump_label_module_notify(struct notifier
+ case MODULE_STATE_COMING:
+ jump_label_lock();
+ ret = jump_label_add_module(mod);
+- if (ret)
++ if (ret) {
++ WARN(1, "Failed to allocatote memory: jump_label may not work properly.\n");
+ jump_label_del_module(mod);
++ }
+ jump_label_unlock();
+ break;
+ case MODULE_STATE_GOING:
+@@ -558,11 +635,14 @@ int jump_label_text_reserved(void *start
+ static void jump_label_update(struct static_key *key)
+ {
+ struct jump_entry *stop = __stop___jump_table;
+- struct jump_entry *entry = static_key_entries(key);
++ struct jump_entry *entry;
+ #ifdef CONFIG_MODULES
+ struct module *mod;
+
+- __jump_label_mod_update(key);
++ if (static_key_linked(key)) {
++ __jump_label_mod_update(key);
++ return;
++ }
+
+ preempt_disable();
+ mod = __module_address((unsigned long)key);
+@@ -570,6 +650,7 @@ static void jump_label_update(struct sta
+ stop = mod->jump_entries + mod->num_jump_entries;
+ preempt_enable();
+ #endif
++ entry = static_key_entries(key);
+ /* if there are no users, entry can be NULL */
+ if (entry)
+ __jump_label_update(key, entry, stop);
diff --git a/patches.arch/02-jump_label-reorder-hotplug-lock-and-jump_label_lock.patch b/patches.arch/02-jump_label-reorder-hotplug-lock-and-jump_label_lock.patch
new file mode 100644
index 0000000000..3359bcc739
--- /dev/null
+++ b/patches.arch/02-jump_label-reorder-hotplug-lock-and-jump_label_lock.patch
@@ -0,0 +1,194 @@
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Wed, 24 May 2017 10:15:35 +0200
+Subject: jump_label: Reorder hotplug lock and jump_label_lock
+Git-commit: f2545b2d4ce13e068897ef60ae64dffe215f4152
+Patch-mainline: v4.13-rc1
+References: bsc#1105271
+
+The conversion of the hotplug locking to a percpu rwsem unearthed lock
+ordering issues all over the place.
+
+The jump_label code has two issues:
+
+ 1) Nested get_online_cpus() invocations
+
+ 2) Ordering problems vs. the cpus rwsem and the jump_label_mutex
+
+To cure these, the following lock order has been established;
+
+ cpus_rwsem -> jump_label_lock -> text_mutex
+
+Even if not all architectures need protection against CPU hotplug, taking
+cpus_rwsem before jump_label_lock is now mandatory in code pathes which
+actually modify code and therefor need text_mutex protection.
+
+Move the get_online_cpus() invocations into the core jump label code and
+establish the proper lock order where required.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: "David S. Miller" <davem@davemloft.net>
+Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Cc: Chris Metcalf <cmetcalf@mellanox.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Sebastian Siewior <bigeasy@linutronix.de>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Jason Baron <jbaron@akamai.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Link: http://lkml.kernel.org/r/20170524081549.025830817@linutronix.de
+
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ arch/mips/kernel/jump_label.c | 2 --
+ arch/sparc/kernel/jump_label.c | 2 --
+ arch/x86/kernel/jump_label.c | 2 --
+ kernel/jump_label.c | 20 ++++++++++++++------
+ 4 files changed, 14 insertions(+), 12 deletions(-)
+
+--- a/arch/mips/kernel/jump_label.c
++++ b/arch/mips/kernel/jump_label.c
+@@ -58,7 +58,6 @@ void arch_jump_label_transform(struct ju
+ insn.word = 0; /* nop */
+ }
+
+- get_online_cpus();
+ mutex_lock(&text_mutex);
+ if (IS_ENABLED(CONFIG_CPU_MICROMIPS)) {
+ insn_p->halfword[0] = insn.word >> 16;
+@@ -70,7 +69,6 @@ void arch_jump_label_transform(struct ju
+ (unsigned long)insn_p + sizeof(*insn_p));
+
+ mutex_unlock(&text_mutex);
+- put_online_cpus();
+ }
+
+ #endif /* HAVE_JUMP_LABEL */
+--- a/arch/sparc/kernel/jump_label.c
++++ b/arch/sparc/kernel/jump_label.c
+@@ -41,12 +41,10 @@ void arch_jump_label_transform(struct ju
+ val = 0x01000000;
+ }
+
+- get_online_cpus();
+ mutex_lock(&text_mutex);
+ *insn = val;
+ flushi(insn);
+ mutex_unlock(&text_mutex);
+- put_online_cpus();
+ }
+
+ #endif
+--- a/arch/x86/kernel/jump_label.c
++++ b/arch/x86/kernel/jump_label.c
+@@ -105,11 +105,9 @@ static void __jump_label_transform(struc
+ void arch_jump_label_transform(struct jump_entry *entry,
+ enum jump_label_type type)
+ {
+- get_online_cpus();
+ mutex_lock(&text_mutex);
+ __jump_label_transform(entry, type, NULL, 0);
+ mutex_unlock(&text_mutex);
+- put_online_cpus();
+ }
+
+ static enum {
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -15,6 +15,7 @@
+ #include <linux/static_key.h>
+ #include <linux/jump_label_ratelimit.h>
+ #include <linux/bug.h>
++#include <linux/cpu.h>
+
+ #ifdef HAVE_JUMP_LABEL
+
+@@ -124,6 +125,7 @@ void static_key_slow_inc(struct static_k
+ return;
+ }
+
++ get_online_cpus();
+ jump_label_lock();
+ if (atomic_read(&key->enabled) == 0) {
+ atomic_set(&key->enabled, -1);
+@@ -133,12 +135,14 @@ void static_key_slow_inc(struct static_k
+ atomic_inc(&key->enabled);
+ }
+ jump_label_unlock();
++ put_online_cpus();
+ }
+ EXPORT_SYMBOL_GPL(static_key_slow_inc);
+
+ static void __static_key_slow_dec(struct static_key *key,
+ unsigned long rate_limit, struct delayed_work *work)
+ {
++ get_online_cpus();
+ /*
+ * The negative count check is valid even when a negative
+ * key->enabled is in use by static_key_slow_inc(); a
+@@ -149,6 +153,7 @@ static void __static_key_slow_dec(struct
+ if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) {
+ WARN(atomic_read(&key->enabled) < 0,
+ "jump label: negative count!\n");
++ put_online_cpus();
+ return;
+ }
+
+@@ -159,6 +164,7 @@ static void __static_key_slow_dec(struct
+ jump_label_update(key);
+ }
+ jump_label_unlock();
++ put_online_cpus();
+ }
+
+ static void jump_label_update_timeout(struct work_struct *work)
+@@ -320,6 +326,7 @@ void __init jump_label_init(void)
+ if (static_key_initialized)
+ return;
+
++ get_online_cpus();
+ jump_label_lock();
+ jump_label_sort_entries(iter_start, iter_stop);
+
+@@ -339,6 +346,7 @@ void __init jump_label_init(void)
+ }
+ static_key_initialized = true;
+ jump_label_unlock();
++ put_online_cpus();
+ }
+
+ #ifdef CONFIG_MODULES
+@@ -567,28 +575,28 @@ jump_label_module_notify(struct notifier
+ struct module *mod = data;
+ int ret = 0;
+
++ get_online_cpus();
++ jump_label_lock();
++
+ switch (val) {
+ case MODULE_STATE_COMING:
+- jump_label_lock();
+ ret = jump_label_add_module(mod);
+ if (ret) {
+ WARN(1, "Failed to allocatote memory: jump_label may not work properly.\n");
+ jump_label_del_module(mod);
+ }
+- jump_label_unlock();
+ break;
+ case MODULE_STATE_GOING:
+- jump_label_lock();
+ jump_label_del_module(mod);
+- jump_label_unlock();
+ break;
+ case MODULE_STATE_LIVE:
+- jump_label_lock();
+ jump_label_invalidate_module_init(mod);
+- jump_label_unlock();
+ break;
+ }
+
++ jump_label_unlock();
++ put_online_cpus();
++
+ return notifier_from_errno(ret);
+ }
+
diff --git a/patches.arch/03-jump_label-fix-concurrent-static_key_enable-disable.patch b/patches.arch/03-jump_label-fix-concurrent-static_key_enable-disable.patch
new file mode 100644
index 0000000000..36d7da552f
--- /dev/null
+++ b/patches.arch/03-jump_label-fix-concurrent-static_key_enable-disable.patch
@@ -0,0 +1,143 @@
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Tue, 1 Aug 2017 17:24:04 +0200
+Subject: jump_label: Fix concurrent static_key_enable/disable()
+Git-commit: 1dbb6704de91b169a58d0c8221624afd6a95cfc7
+Patch-mainline: v4.14-rc1
+References: bsc#1105271
+
+static_key_enable/disable are trying to cap the static key count to
+0/1. However, their use of key->enabled is outside jump_label_lock
+so they do not really ensure that.
+
+Rewrite them to do a quick check for an already enabled (respectively,
+already disabled), and then recheck under the jump label lock. Unlike
+static_key_slow_inc/dec, a failed check under the jump label lock does
+not modify key->enabled.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Cc: Jason Baron <jbaron@akamai.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/1501601046-35683-2-git-send-email-pbonzini@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ include/linux/jump_label.h | 22 +++++++++-------
+ kernel/jump_label.c | 59 ++++++++++++++++++++++++++++-----------------
+ 2 files changed, 49 insertions(+), 32 deletions(-)
+
+--- a/include/linux/jump_label.h
++++ b/include/linux/jump_label.h
+@@ -221,22 +221,24 @@ static inline int jump_label_apply_nops(
+
+ static inline void static_key_enable(struct static_key *key)
+ {
+- int count = static_key_count(key);
++ STATIC_KEY_CHECK_USE();
+
+- WARN_ON_ONCE(count < 0 || count > 1);
+-
+- if (!count)
+- static_key_slow_inc(key);
++ if (atomic_read(&key->enabled) != 0) {
++ WARN_ON_ONCE(atomic_read(&key->enabled) != 1);
++ return;
++ }
++ atomic_set(&key->enabled, 1);
+ }
+
+ static inline void static_key_disable(struct static_key *key)
+ {
+- int count = static_key_count(key);
+-
+- WARN_ON_ONCE(count < 0 || count > 1);
++ STATIC_KEY_CHECK_USE();
+
+- if (count)
+- static_key_slow_dec(key);
++ if (atomic_read(&key->enabled) != 1) {
++ WARN_ON_ONCE(atomic_read(&key->enabled) != 0);
++ return;
++ }
++ atomic_set(&key->enabled, 0);
+ }
+
+ #define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -79,28 +79,6 @@ int static_key_count(struct static_key *
+ }
+ EXPORT_SYMBOL_GPL(static_key_count);
+
+-void static_key_enable(struct static_key *key)
+-{
+- int count = static_key_count(key);
+-
+- WARN_ON_ONCE(count < 0 || count > 1);
+-
+- if (!count)
+- static_key_slow_inc(key);
+-}
+-EXPORT_SYMBOL_GPL(static_key_enable);
+-
+-void static_key_disable(struct static_key *key)
+-{
+- int count = static_key_count(key);
+-
+- WARN_ON_ONCE(count < 0 || count > 1);
+-
+- if (count)
+- static_key_slow_dec(key);
+-}
+-EXPORT_SYMBOL_GPL(static_key_disable);
+-
+ void static_key_slow_inc(struct static_key *key)
+ {
+ int v, v1;
+@@ -139,6 +117,43 @@ void static_key_slow_inc(struct static_k
+ }
+ EXPORT_SYMBOL_GPL(static_key_slow_inc);
+
++void static_key_enable(struct static_key *key)
++{
++ STATIC_KEY_CHECK_USE();
++ if (atomic_read(&key->enabled) > 0) {
++ WARN_ON_ONCE(atomic_read(&key->enabled) != 1);
++ return;
++ }
++
++ get_online_cpus();
++ jump_label_lock();
++ if (atomic_read(&key->enabled) == 0) {
++ atomic_set(&key->enabled, -1);
++ jump_label_update(key);
++ atomic_set(&key->enabled, 1);
++ }
++ jump_label_unlock();
++ put_online_cpus();
++}
++EXPORT_SYMBOL_GPL(static_key_enable);
++
++void static_key_disable(struct static_key *key)
++{
++ STATIC_KEY_CHECK_USE();
++ if (atomic_read(&key->enabled) != 1) {
++ WARN_ON_ONCE(atomic_read(&key->enabled) != 0);
++ return;
++ }
++
++ get_online_cpus();
++ jump_label_lock();
++ if (atomic_cmpxchg(&key->enabled, 1, 0))
++ jump_label_update(key);
++ jump_label_unlock();
++ put_online_cpus();
++}
++EXPORT_SYMBOL_GPL(static_key_disable);
++
+ static void __static_key_slow_dec(struct static_key *key,
+ unsigned long rate_limit, struct delayed_work *work)
+ {
diff --git a/patches.arch/04-jump_label-add-release-barrier-after-text-changes.patch b/patches.arch/04-jump_label-add-release-barrier-after-text-changes.patch
new file mode 100644
index 0000000000..2bdd850a43
--- /dev/null
+++ b/patches.arch/04-jump_label-add-release-barrier-after-text-changes.patch
@@ -0,0 +1,50 @@
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Tue, 1 Aug 2017 23:58:50 +0200
+Subject: jump_label: Add RELEASE barrier after text changes
+Git-commit: d0646a6f5533226ceb7620c20717286d3a372794
+Patch-mainline: v4.14-rc1
+References: bsc#1105271
+
+In the unlikely case text modification does not fully order things,
+add some extra ordering of our own to ensure we only enabled the fast
+path after all text is visible.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Jason Baron <jbaron@akamai.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ kernel/jump_label.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -108,7 +108,11 @@ void static_key_slow_inc(struct static_k
+ if (atomic_read(&key->enabled) == 0) {
+ atomic_set(&key->enabled, -1);
+ jump_label_update(key);
+- atomic_set(&key->enabled, 1);
++ /*
++ * Ensure that if the above cmpxchg loop observes our positive
++ * value, it must also observe all the text changes.
++ */
++ atomic_set_release(&key->enabled, 1);
+ } else {
+ atomic_inc(&key->enabled);
+ }
+@@ -130,7 +134,10 @@ void static_key_enable(struct static_key
+ if (atomic_read(&key->enabled) == 0) {
+ atomic_set(&key->enabled, -1);
+ jump_label_update(key);
+- atomic_set(&key->enabled, 1);
++ /*
++ * See static_key_slow_inc().
++ */
++ atomic_set_release(&key->enabled, 1);
+ }
+ jump_label_unlock();
+ put_online_cpus();
diff --git a/patches.arch/05-jump_label-move-cpu-hotplug-locking.patch b/patches.arch/05-jump_label-move-cpu-hotplug-locking.patch
new file mode 100644
index 0000000000..8e878b9250
--- /dev/null
+++ b/patches.arch/05-jump_label-move-cpu-hotplug-locking.patch
@@ -0,0 +1,50 @@
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Tue, 1 Aug 2017 09:02:54 +0100
+Subject: jump_label: Move CPU hotplug locking
+Git-commit: b70cecf4b6b72a9977576ab32cca0e24f286f517
+Patch-mainline: v4.14-rc1
+References: bsc#1105271
+
+As we're about to rework the locking, let's move the taking and
+release of the CPU hotplug lock to locations that will make its
+reworking completely obvious.
+
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-arm-kernel@lists.infradead.org
+Link: http://lkml.kernel.org/r/20170801080257.5056-2-marc.zyngier@arm.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ kernel/jump_label.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -83,6 +83,7 @@ void static_key_slow_inc(struct static_k
+ {
+ int v, v1;
+
++ get_online_cpus();
+ STATIC_KEY_CHECK_USE();
+
+ /*
+@@ -99,11 +100,12 @@ void static_key_slow_inc(struct static_k
+ */
+ for (v = atomic_read(&key->enabled); v > 0; v = v1) {
+ v1 = atomic_cmpxchg(&key->enabled, v, v + 1);
+- if (likely(v1 == v))
++ if (likely(v1 == v)) {
++ put_online_cpus();
+ return;
++ }
+ }
+
+- get_online_cpus();
+ jump_label_lock();
+ if (atomic_read(&key->enabled) == 0) {
+ atomic_set(&key->enabled, -1);
diff --git a/patches.arch/06-jump_label-split-out-code-under-the-hotplug-lock.patch b/patches.arch/06-jump_label-split-out-code-under-the-hotplug-lock.patch
new file mode 100644
index 0000000000..0d303008e4
--- /dev/null
+++ b/patches.arch/06-jump_label-split-out-code-under-the-hotplug-lock.patch
@@ -0,0 +1,104 @@
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Tue, 1 Aug 2017 09:02:55 +0100
+Subject: jump_label: Split out code under the hotplug lock
+Git-commit: 8b7b412807053ab5f059ffae426a280e769a5bda
+Patch-mainline: v4.14-rc1
+References: bsc#1105271
+
+In order to later introduce an "already locked" version of some
+of the static key funcions, let's split the code into the core stuff
+(the *_cpuslocked functions) and the usual helpers, which now
+take/release the hotplug lock and call into the _cpuslocked
+versions.
+
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-arm-kernel@lists.infradead.org
+Link: http://lkml.kernel.org/r/20170801080257.5056-3-marc.zyngier@arm.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ kernel/jump_label.c | 28 +++++++++++++++++++---------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -79,11 +79,10 @@ int static_key_count(struct static_key *
+ }
+ EXPORT_SYMBOL_GPL(static_key_count);
+
+-void static_key_slow_inc(struct static_key *key)
++static void static_key_slow_inc_cpuslocked(struct static_key *key)
+ {
+ int v, v1;
+
+- get_online_cpus();
+ STATIC_KEY_CHECK_USE();
+
+ /*
+@@ -100,10 +99,8 @@ void static_key_slow_inc(struct static_k
+ */
+ for (v = atomic_read(&key->enabled); v > 0; v = v1) {
+ v1 = atomic_cmpxchg(&key->enabled, v, v + 1);
+- if (likely(v1 == v)) {
+- put_online_cpus();
++ if (likely(v1 == v))
+ return;
+- }
+ }
+
+ jump_label_lock();
+@@ -119,6 +116,12 @@ void static_key_slow_inc(struct static_k
+ atomic_inc(&key->enabled);
+ }
+ jump_label_unlock();
++}
++
++void static_key_slow_inc(struct static_key *key)
++{
++ get_online_cpus();
++ static_key_slow_inc_cpuslocked(key);
+ put_online_cpus();
+ }
+ EXPORT_SYMBOL_GPL(static_key_slow_inc);
+@@ -163,10 +166,10 @@ void static_key_disable(struct static_ke
+ }
+ EXPORT_SYMBOL_GPL(static_key_disable);
+
+-static void __static_key_slow_dec(struct static_key *key,
+- unsigned long rate_limit, struct delayed_work *work)
++static void static_key_slow_dec_cpuslocked(struct static_key *key,
++ unsigned long rate_limit,
++ struct delayed_work *work)
+ {
+- get_online_cpus();
+ /*
+ * The negative count check is valid even when a negative
+ * key->enabled is in use by static_key_slow_inc(); a
+@@ -177,7 +180,6 @@ static void __static_key_slow_dec(struct
+ if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) {
+ WARN(atomic_read(&key->enabled) < 0,
+ "jump label: negative count!\n");
+- put_online_cpus();
+ return;
+ }
+
+@@ -188,6 +190,14 @@ static void __static_key_slow_dec(struct
+ jump_label_update(key);
+ }
+ jump_label_unlock();
++}
++
++static void __static_key_slow_dec(struct static_key *key,
++ unsigned long rate_limit,
++ struct delayed_work *work)
++{
++ get_online_cpus();
++ static_key_slow_dec_cpuslocked(key, rate_limit, work);
+ put_online_cpus();
+ }
+
diff --git a/patches.arch/07-jump_label-provide-hotplug-context-variants.patch b/patches.arch/07-jump_label-provide-hotplug-context-variants.patch
new file mode 100644
index 0000000000..d898558917
--- /dev/null
+++ b/patches.arch/07-jump_label-provide-hotplug-context-variants.patch
@@ -0,0 +1,147 @@
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Tue, 1 Aug 2017 09:02:56 +0100
+Subject: jump_label: Provide hotplug context variants
+Git-commit: 5a40527f8f0798553764fc8db4111d7d9c33ea51
+Patch-mainline: v4.14-rc1
+References: bsc#1105271
+
+As using the normal static key API under the hotplug lock is
+pretty much impossible, let's provide a variant of some of them
+that require the hotplug lock to have already been taken.
+
+These function are only meant to be used in CPU hotplug callbacks.
+
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-arm-kernel@lists.infradead.org
+Link: http://lkml.kernel.org/r/20170801080257.5056-4-marc.zyngier@arm.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ Documentation/static-keys.txt | 15 +++++++++++++++
+ include/linux/jump_label.h | 11 +++++++++--
+ kernel/jump_label.c | 22 ++++++++++++++++++----
+ 3 files changed, 42 insertions(+), 6 deletions(-)
+
+--- a/Documentation/static-keys.txt
++++ b/Documentation/static-keys.txt
+@@ -142,6 +142,21 @@ static_branch_inc(), will change the bra
+ key is initialized false, a 'static_branch_inc()', will change the branch to
+ true. And then a 'static_branch_dec()', will again make the branch false.
+
++Note that switching branches results in some locks being taken,
++particularly the CPU hotplug lock (in order to avoid races against
++CPUs being brought in the kernel whilst the kernel is getting
++patched). Calling the static key API from within a hotplug notifier is
++thus a sure deadlock recipe. In order to still allow use of the
++functionnality, the following functions are provided:
++
++ static_key_enable_cpuslocked()
++ static_key_disable_cpuslocked()
++ static_branch_enable_cpuslocked()
++ static_branch_disable_cpuslocked()
++
++These functions are *not* general purpose, and must only be used when
++you really know that you're in the above context, and no other.
++
+ Where an array of keys is required, it can be defined as:
+
+ DEFINE_STATIC_KEY_ARRAY_TRUE(keys, count);
+--- a/include/linux/jump_label.h
++++ b/include/linux/jump_label.h
+@@ -150,6 +150,8 @@ extern void jump_label_apply_nops(struct
+ extern int static_key_count(struct static_key *key);
+ extern void static_key_enable(struct static_key *key);
+ extern void static_key_disable(struct static_key *key);
++extern void static_key_enable_cpuslocked(struct static_key *key);
++extern void static_key_disable_cpuslocked(struct static_key *key);
+
+ /*
+ * We should be using ATOMIC_INIT() for initializing .enabled, but
+@@ -241,6 +243,9 @@ static inline void static_key_disable(st
+ atomic_set(&key->enabled, 0);
+ }
+
++#define static_key_enable_cpuslocked(k) static_key_enable((k))
++#define static_key_disable_cpuslocked(k) static_key_disable((k))
++
+ #define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) }
+ #define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) }
+
+@@ -402,8 +407,10 @@ extern bool ____wrong_branch_error(void)
+ * Normal usage; boolean enable/disable.
+ */
+
+-#define static_branch_enable(x) static_key_enable(&(x)->key)
+-#define static_branch_disable(x) static_key_disable(&(x)->key)
++#define static_branch_enable(x) static_key_enable(&(x)->key)
++#define static_branch_disable(x) static_key_disable(&(x)->key)
++#define static_branch_enable_cpuslocked(x) static_key_enable_cpuslocked(&(x)->key)
++#define static_branch_disable_cpuslocked(x) static_key_disable_cpuslocked(&(x)->key)
+
+ #endif /* _LINUX_JUMP_LABEL_H */
+
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -126,15 +126,15 @@ void static_key_slow_inc(struct static_k
+ }
+ EXPORT_SYMBOL_GPL(static_key_slow_inc);
+
+-void static_key_enable(struct static_key *key)
++void static_key_enable_cpuslocked(struct static_key *key)
+ {
+ STATIC_KEY_CHECK_USE();
++
+ if (atomic_read(&key->enabled) > 0) {
+ WARN_ON_ONCE(atomic_read(&key->enabled) != 1);
+ return;
+ }
+
+- get_online_cpus();
+ jump_label_lock();
+ if (atomic_read(&key->enabled) == 0) {
+ atomic_set(&key->enabled, -1);
+@@ -145,23 +145,37 @@ void static_key_enable(struct static_key
+ atomic_set_release(&key->enabled, 1);
+ }
+ jump_label_unlock();
++}
++EXPORT_SYMBOL_GPL(static_key_enable_cpuslocked);
++
++void static_key_enable(struct static_key *key)
++{
++ get_online_cpus();
++ static_key_enable_cpuslocked(key);
+ put_online_cpus();
+ }
+ EXPORT_SYMBOL_GPL(static_key_enable);
+
+-void static_key_disable(struct static_key *key)
++void static_key_disable_cpuslocked(struct static_key *key)
+ {
+ STATIC_KEY_CHECK_USE();
++
+ if (atomic_read(&key->enabled) != 1) {
+ WARN_ON_ONCE(atomic_read(&key->enabled) != 0);
+ return;
+ }
+
+- get_online_cpus();
+ jump_label_lock();
+ if (atomic_cmpxchg(&key->enabled, 1, 0))
+ jump_label_update(key);
+ jump_label_unlock();
++}
++EXPORT_SYMBOL_GPL(static_key_disable_cpuslocked);
++
++void static_key_disable(struct static_key *key)
++{
++ get_online_cpus();
++ static_key_disable_cpuslocked(key);
+ put_online_cpus();
+ }
+ EXPORT_SYMBOL_GPL(static_key_disable);
diff --git a/patches.arch/08-s390-add-explicit-linux-stringify-h-for-jump-label.patch b/patches.arch/08-s390-add-explicit-linux-stringify-h-for-jump-label.patch
new file mode 100644
index 0000000000..2adcc17524
--- /dev/null
+++ b/patches.arch/08-s390-add-explicit-linux-stringify-h-for-jump-label.patch
@@ -0,0 +1,30 @@
+From: Jason Baron <jbaron@akamai.com>
+Date: Fri, 20 May 2016 17:16:35 -0400
+Subject: s390: add explicit <linux/stringify.h> for jump label
+Git-commit: ac31418445597573538571d9b6610406a6cd66ab
+Patch-mainline: v4.8-rc1
+References: bsc#1105271
+
+Ensure that we always have __stringify().
+
+Signed-off-by: Jason Baron <jbaron@akamai.com>
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ arch/s390/include/asm/jump_label.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/s390/include/asm/jump_label.h b/arch/s390/include/asm/jump_label.h
+index 7f9fd5e3f1bf..9be198f5ee79 100644
+--- a/arch/s390/include/asm/jump_label.h
++++ b/arch/s390/include/asm/jump_label.h
+@@ -4,6 +4,7 @@
+ #ifndef __ASSEMBLY__
+
+ #include <linux/types.h>
++#include <linux/stringify.h>
+
+ #define JUMP_LABEL_NOP_SIZE 6
+ #define JUMP_LABEL_NOP_OFFSET 2
+
diff --git a/patches.drivers/ibmvnic-Include-missing-return-code-checks-in-reset-.patch b/patches.drivers/ibmvnic-Include-missing-return-code-checks-in-reset-.patch
new file mode 100644
index 0000000000..d780eda7a8
--- /dev/null
+++ b/patches.drivers/ibmvnic-Include-missing-return-code-checks-in-reset-.patch
@@ -0,0 +1,49 @@
+From f611a5b4a51fa36a0aa792be474f5d6aacaef7e3 Mon Sep 17 00:00:00 2001
+From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Date: Thu, 30 Aug 2018 13:19:53 -0500
+Subject: [PATCH] ibmvnic: Include missing return code checks in reset function
+
+References: bnc#1107966
+Patch-mainline: v4.19-rc3
+Git-commit: f611a5b4a51fa36a0aa792be474f5d6aacaef7e3
+
+Check the return codes of these functions and halt reset
+in case of failure. The driver will remain in a dormant state
+until the next reset event, when device initialization will be
+re-attempted.
+
+Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Michal Suchanek <msuchanek@suse.de>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index dafdd4ade705..4f0daf67b18d 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -1823,11 +1823,17 @@ static int do_reset(struct ibmvnic_adapter *adapter,
+ adapter->map_id = 1;
+ release_rx_pools(adapter);
+ release_tx_pools(adapter);
+- init_rx_pools(netdev);
+- init_tx_pools(netdev);
++ rc = init_rx_pools(netdev);
++ if (rc)
++ return rc;
++ rc = init_tx_pools(netdev);
++ if (rc)
++ return rc;
+
+ release_napi(adapter);
+- init_napi(adapter);
++ rc = init_napi(adapter);
++ if (rc)
++ return rc;
+ } else {
+ rc = reset_tx_pools(adapter);
+ if (rc)
+--
+2.13.7
+
diff --git a/patches.suse/xen-disable_hotplug_cpu.patch b/patches.suse/xen-disable_hotplug_cpu.patch
new file mode 100644
index 0000000000..f9d87aefc8
--- /dev/null
+++ b/patches.suse/xen-disable_hotplug_cpu.patch
@@ -0,0 +1,36 @@
+From: Olaf Hering <ohering@suse.de>
+Subject: xen: avoid crash in disable_hotplug_cpu
+Patch-mainline: never, different patch required
+References: bsc#1106594
+
+The command 'xl vcpu-set 0 0', issued in dom0, will crash dom0:
+
+BUG: unable to handle kernel NULL pointer dereference at 00000000000002d8
+RIP: e030:device_offline+0x9/0xb0
+Call Trace:
+ handle_vcpu_hotplug_event+0xb5/0xc0
+
+This happens because handle_vcpu_hotplug_event is called twice. In the
+first iteration cpu_present is still true, in the second iteration
+cpu_present is false which causes get_cpu_device to return NULL.
+In case of cpu#0, cpu_online is apparently always true.
+
+Fix this crash by checking if the cpu was actually offlined by
+device_offline, otherwise leave the cpu_present state as it is.
+
+--- a/drivers/xen/cpu_hotplug.c
++++ b/drivers/xen/cpu_hotplug.c
+@@ -23,10 +23,13 @@ static void disable_hotplug_cpu(int cpu)
+ lock_device_hotplug();
+ if (cpu_online(cpu))
+ device_offline(get_cpu_device(cpu));
++ if (cpu_online(cpu))
++ goto unlock;
+ if (cpu_present(cpu))
+ xen_arch_unregister_cpu(cpu);
+
+ set_cpu_present(cpu, false);
++unlock:
+ unlock_device_hotplug();
+ }
+
diff --git a/patches.suse/xfs-don-t-call-xfs_da_shrink_inode-with-NULL-bp.patch b/patches.suse/xfs-don-t-call-xfs_da_shrink_inode-with-NULL-bp.patch
new file mode 100644
index 0000000000..420b07b583
--- /dev/null
+++ b/patches.suse/xfs-don-t-call-xfs_da_shrink_inode-with-NULL-bp.patch
@@ -0,0 +1,47 @@
+From 724c0ca296c9e12431654f336fa370e6e71c7102 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@sandeen.net>
+Date: Fri, 8 Jun 2018 09:53:49 -0700
+Subject: [PATCH 2/3] xfs: don't call xfs_da_shrink_inode with NULL bp
+Git-commit: bb3d48dcf86a97dc25fe9fc2c11938e19cb4399a
+Patch-mainline: v4.18-rc1
+References: bsc#1100000, CVE-2018-13094
+
+xfs_attr3_leaf_create may have errored out before instantiating a buffer,
+for example if the blkno is out of range. In that case there is no work
+to do to remove it, and in fact xfs_da_shrink_inode will lead to an oops
+if we try.
+
+This also seems to fix a flaw where the original error from
+xfs_attr3_leaf_create gets overwritten in the cleanup case, and it
+removes a pointless assignment to bp which isn't used after this.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199969
+Reported-by: Xu, Wen <wen.xu@gatech.edu>
+Tested-by: Xu, Wen <wen.xu@gatech.edu>
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/libxfs/xfs_attr_leaf.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
+index 01a5ecfedfcf..445a3f2f871f 100644
+--- a/fs/xfs/libxfs/xfs_attr_leaf.c
++++ b/fs/xfs/libxfs/xfs_attr_leaf.c
+@@ -779,9 +779,8 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
+ ASSERT(blkno == 0);
+ error = xfs_attr3_leaf_create(args, blkno, &bp);
+ if (error) {
+- error = xfs_da_shrink_inode(args, 0, bp);
+- bp = NULL;
+- if (error)
++ /* xfs_attr3_leaf_create may not have instantiated a block */
++ if (bp && (xfs_da_shrink_inode(args, 0, bp) != 0))
+ goto out;
+ xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */
+ memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */
+--
+2.7.4
+
diff --git a/patches.suse/xfs-fix-a-null-pointer-dereference-in-xfs_bmap_exten.patch b/patches.suse/xfs-fix-a-null-pointer-dereference-in-xfs_bmap_exten.patch
new file mode 100644
index 0000000000..da932df90d
--- /dev/null
+++ b/patches.suse/xfs-fix-a-null-pointer-dereference-in-xfs_bmap_exten.patch
@@ -0,0 +1,69 @@
+From de62810c69e2459831b45956630de80304d50626 Mon Sep 17 00:00:00 2001
+From: Shan Hai <shan.hai@oracle.com>
+Date: Fri, 10 Aug 2018 17:55:55 -0700
+Subject: [PATCH 1/3] xfs: fix a null pointer dereference in
+ xfs_bmap_extents_to_btree
+Git-commit: 01239d77b9dd978863d1a75f0d095ab942a1fe66
+Patch-mainline: v4.19-rc1
+References: bsc#1099999, CVE-2018-13095
+
+Fuzzing tool reports a write to null pointer error in the
+xfs_bmap_extents_to_btree, fix it by bailing out on encountering
+a null pointer.
+
+Signed-off-by: Shan Hai <shan.hai@oracle.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/libxfs/xfs_bmap.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
+index 2d78127ad051..324af47121aa 100644
+--- a/fs/xfs/libxfs/xfs_bmap.c
++++ b/fs/xfs/libxfs/xfs_bmap.c
+@@ -793,10 +793,10 @@ xfs_bmap_extents_to_btree(
+ args.wasdel = wasdel;
+ *logflagsp = 0;
+ if ((error = xfs_alloc_vextent(&args))) {
+- xfs_iroot_realloc(ip, -1, whichfork);
+- xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
+- return error;
++ ASSERT(ifp->if_broot == NULL);
++ goto err1;
+ }
++
+ /*
+ * Allocation can't fail, the space was reserved.
+ */
+@@ -810,6 +810,10 @@ xfs_bmap_extents_to_btree(
+ ip->i_d.di_nblocks++;
+ xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
+ abp = xfs_btree_get_bufl(mp, tp, args.fsbno, 0);
++ if (!abp) {
++ error = -ENOSPC;
++ goto err2;
++ }
+ /*
+ * Fill in the child block.
+ */
+@@ -857,6 +861,15 @@ xfs_bmap_extents_to_btree(
+ *curp = cur;
+ *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork);
+ return 0;
++
++err2:
++ xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
++err1:
++ xfs_iroot_realloc(ip, -1, whichfork);
++ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
++ xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
++
++ return error;
+ }
+
+ /*
+--
+2.7.4
+
diff --git a/patches.suse/xfs-validate-cached-inodes-are-free-when-allocated.patch b/patches.suse/xfs-validate-cached-inodes-are-free-when-allocated.patch
new file mode 100644
index 0000000000..a5ea6de4fb
--- /dev/null
+++ b/patches.suse/xfs-validate-cached-inodes-are-free-when-allocated.patch
@@ -0,0 +1,142 @@
+From bc93ffd50afe559ef67fa6ea2f45747026d4853e Mon Sep 17 00:00:00 2001
+From: Dave Chinner <dchinner@redhat.com>
+Date: Tue, 17 Apr 2018 17:17:34 -0700
+Subject: [PATCH 3/3] xfs: validate cached inodes are free when allocated
+Git-commit: afca6c5b2595fc44383919fba740c194b0b76aff
+Patch-mainline: v4.18-rc1
+References: bsc#1100001, CVE-2018-13093
+
+A recent fuzzed filesystem image cached random dcache corruption
+when the reproducer was run. This often showed up as panics in
+lookup_slow() on a null inode->i_ops pointer when doing pathwalks.
+
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
+....
+Call Trace:
+ lookup_slow+0x44/0x60
+ walk_component+0x3dd/0x9f0
+ link_path_walk+0x4a7/0x830
+ path_lookupat+0xc1/0x470
+ filename_lookup+0x129/0x270
+ user_path_at_empty+0x36/0x40
+ path_listxattr+0x98/0x110
+ SyS_listxattr+0x13/0x20
+ do_syscall_64+0xf5/0x280
+ entry_SYSCALL_64_after_hwframe+0x42/0xb7
+
+but had many different failure modes including deadlocks trying to
+lock the inode that was just allocated or KASAN reports of
+use-after-free violations.
+
+The cause of the problem was a corrupt INOBT on a v4 fs where the
+root inode was marked as free in the inobt record. Hence when we
+allocated an inode, it chose the root inode to allocate, found it in
+the cache and re-initialised it.
+
+We recently fixed a similar inode allocation issue caused by inobt
+record corruption problem in xfs_iget_cache_miss() in commit
+ee457001ed6c ("xfs: catch inode allocation state mismatch
+corruption"). This change adds similar checks to the cache-hit path
+to catch it, and turns the reproducer into a corruption shutdown
+situation.
+
+Reported-by: Wen Xu <wen.xu@gatech.edu>
+Signed-Off-By: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+[darrick: fix typos in comment]
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/xfs_icache.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 50 insertions(+), 7 deletions(-)
+
+diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
+index adbc1f59969a..2db6b02eba42 100644
+--- a/fs/xfs/xfs_icache.c
++++ b/fs/xfs/xfs_icache.c
+@@ -135,6 +135,46 @@ xfs_inode_free(
+ }
+
+ /*
++ * If we are allocating a new inode, then check what was returned is
++ * actually a free, empty inode. If we are not allocating an inode,
++ * then check we didn't find a free inode.
++ *
++ * Returns:
++ * 0 if the inode free state matches the lookup context
++ * -ENOENT if the inode is free and we are not allocating
++ * -EFSCORRUPTED if there is any state mismatch at all
++ */
++static int
++xfs_iget_check_free_state(
++ struct xfs_inode *ip,
++ int flags)
++{
++ if (flags & XFS_IGET_CREATE) {
++ /* should be a free inode */
++ if (ip->i_d.di_mode != 0) {
++ xfs_warn(ip->i_mount,
++"Corruption detected! Free inode 0x%llx not marked free! (mode 0x%x)",
++ ip->i_ino, VFS_I(ip)->i_mode);
++ return -EFSCORRUPTED;
++ }
++
++ if (ip->i_d.di_nblocks != 0) {
++ xfs_warn(ip->i_mount,
++"Corruption detected! Free inode 0x%llx has blocks allocated!",
++ ip->i_ino);
++ return -EFSCORRUPTED;
++ }
++ return 0;
++ }
++
++ /* should be an allocated inode */
++ if (ip->i_d.di_mode == 0)
++ return -ENOENT;
++
++ return 0;
++}
++
++/*
+ * Check the validity of the inode we just found it the cache
+ */
+ static int
+@@ -183,12 +223,12 @@ xfs_iget_cache_hit(
+ }
+
+ /*
+- * If lookup is racing with unlink return an error immediately.
++ * Check the inode free state is valid. This also detects lookup
++ * racing with unlinks.
+ */
+- if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) {
+- error = -ENOENT;
++ error = xfs_iget_check_free_state(ip, flags);
++ if (error)
+ goto out_error;
+- }
+
+ /*
+ * If IRECLAIMABLE is set, we've torn down the VFS inode already.
+@@ -298,10 +338,13 @@ xfs_iget_cache_miss(
+
+ trace_xfs_iget_miss(ip);
+
+- if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
+- error = -ENOENT;
++ /*
++ * Check the inode free state is valid. This also detects lookup
++ * racing with unlinks.
++ */
++ error = xfs_iget_check_free_state(ip, flags);
++ if (error)
+ goto out_destroy;
+- }
+
+ /*
+ * Preload the radix tree so we can insert safely under the
+--
+2.7.4
+
diff --git a/scripts/bugzilla-create b/scripts/bugzilla-create
index e8cc22c210..6036c60cd9 100755
--- a/scripts/bugzilla-create
+++ b/scripts/bugzilla-create
@@ -19,7 +19,7 @@ handle_one_patch() {
exit 1
fi
- VERSION=$(cat ${tmpdir}/version | tail -1)
+ VERSION=$(grep -v unspecified ${tmpdir}/version | tail -1)
${BUGZILLA} new -p "${PRODUCT}" -c "${COMPONENT}" -a "${EMAIL}" \
${QA_EMAIL} -t "${SUBJ}" -v "${VERSION}" \
@@ -71,7 +71,7 @@ handle_one_patch() {
usage () {
cat <<END
-usage: $(basename $0) [options...] BUGID [BUGID ...]
+usage: $(basename $0) [options...] PATCH [PATCH ...]
Options:
-e | --email <address>
* Email address to which this report will be assigned
diff --git a/scripts/cvs-wd-timestamp b/scripts/cvs-wd-timestamp
index c89dbd77d4..d41262cb55 100755
--- a/scripts/cvs-wd-timestamp
+++ b/scripts/cvs-wd-timestamp
@@ -28,7 +28,7 @@
if $using_git; then
# Just echo the commit timestamp of HEAD
ts=$(git show --pretty=format:%ct HEAD | head -n 1)
- date "+%Y-%m-%d %H:%M:%S %z" -d "1970-01-01 00:00 UTC $ts seconds"
+ TZ=UTC date "+%Y-%m-%d %H:%M:%S %z" -d "1970-01-01 00:00 UTC $ts seconds"
exit
fi
diff --git a/scripts/git_sort/README.md b/scripts/git_sort/README.md
index 13dc00a893..ce349495c7 100644
--- a/scripts/git_sort/README.md
+++ b/scripts/git_sort/README.md
@@ -31,6 +31,10 @@ https://build.opensuse.org/package/show/home:benjamin_poirier:series_sort/quilt-
Source is avaible from
https://gitlab.suse.de/benjamin_poirier/quilt
+The packages in home:benjamin_poirier:series_sort are signed with the key
+from home:benjamin_poirier which has the following fingerprint:
+6075 E129 2ACD 9732 A079 7B40 3F6E 17FC 4A3D 5625
+
quilt depends on diffstat from the package with the same name. For SLE12-SP2
and SLE12-SP3, the diffstat package is available in the SDK module. For
openSUSE 42.3 and Tumbleweed, the diffstat package is available in the normal
diff --git a/scripts/git_sort/clean_header.sh b/scripts/git_sort/clean_header.sh
index 371f584bf5..dd185e403c 100755
--- a/scripts/git_sort/clean_header.sh
+++ b/scripts/git_sort/clean_header.sh
@@ -8,7 +8,7 @@ progname=$(basename "$0")
libdir=$(dirname "$(readlink -f "$0")")
git_dir=$("$libdir"/../linux_git.sh) || exit 1
-export GIT_DIR="$git_dir"/.git
+export GIT_DIR=$git_dir
: ${EDITOR:=${VISUAL:=vi}}
. "$libdir"/lib_from.sh
diff --git a/scripts/git_sort/clone_all.py b/scripts/git_sort/clone_all.py
deleted file mode 100755
index 8fa572a87a..0000000000
--- a/scripts/git_sort/clone_all.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/python3
-# -*- coding: utf-8 -*-
-
-import argparse
-import re
-
-import git_sort
-
-
-proto_match = re.compile("^(git|https?)://")
-invalid_match = re.compile("~")
-ext = ".git"
-
-
-def transform(name):
- name = proto_match.sub("", name, 1)
- name = invalid_match.sub("_", name)
- if name.endswith(ext):
- name = name[:-1 * len(ext)]
-
- return name
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(
- description="Print commands to clone the mainline Linux repository "
- "and add all remotes configured for git-sort. That repository can "
- "then be used as an ultimate reference for patch ordering in "
- "series.conf.")
- parser.add_argument("directory", nargs="?", default="linux",
- help="Directory name to clone into. Default: linux")
- args = parser.parse_args()
-
- print("git clone %s %s" % (repr(git_sort.remotes[0].repo_url),
- args.directory,))
- print("cd %s" % (args.directory,))
- repo_urls = []
- for head in git_sort.remotes[1:]:
- repo_url = head.repo_url
- if repo_url not in repo_urls:
- repo_urls.append(repo_url)
- print("\n".join(["git remote add --no-tags %s %s" % (
- transform(str(repo_url)), repr(repo_url),)
- for repo_url in repo_urls]))
- print("git fetch --all")
diff --git a/scripts/git_sort/git_sort.py b/scripts/git_sort/git_sort.py
index 0cd7e99231..e832e906a6 100755
--- a/scripts/git_sort/git_sort.py
+++ b/scripts/git_sort/git_sort.py
@@ -183,8 +183,6 @@ remotes = (
Head(RepoURL("tip/tip.git")),
Head(RepoURL("shli/md.git"), "for-next"),
Head(RepoURL("dhowells/linux-fs.git"), "keys-uefi"),
- Head(RepoURL("git://git.infradead.org/nvme.git"), "nvme-4.16"),
- Head(RepoURL("git://git.infradead.org/nvme.git"), "nvme-4.17"),
Head(RepoURL("tytso/ext4.git"), "dev"),
Head(RepoURL("s390/linux.git"), "for-linus"),
Head(RepoURL("tj/libata.git"), "for-next"),
@@ -198,46 +196,23 @@ remotes = (
Head(RepoURL("horms/ipvs-next.git")),
Head(RepoURL("klassert/ipsec.git")),
Head(RepoURL("klassert/ipsec-next.git")),
- Head(RepoURL("mkp/scsi.git"), "4.15/scsi-fixes"),
- Head(RepoURL("mkp/scsi.git"), "4.16/scsi-fixes"),
- Head(RepoURL("mkp/scsi.git"), "4.17/scsi-queue"),
- Head(RepoURL("mkp/scsi.git"), "queue"),
+ Head(RepoURL("mkp/scsi.git"), "4.19/scsi-queue"),
Head(RepoURL("git://git.kernel.dk/linux-block.git"), "for-next"),
Head(RepoURL("git://git.kernel.org/pub/scm/virt/kvm/kvm.git"), "queue"),
- Head(RepoURL("git://git.infradead.org/nvme.git"), "nvme-4.16-rc"),
+ Head(RepoURL("git://git.infradead.org/nvme.git"), "nvme-4.18"),
+ Head(RepoURL("git://git.infradead.org/nvme.git"), "nvme-4.19"),
Head(RepoURL("dhowells/linux-fs.git")),
Head(RepoURL("herbert/cryptodev-2.6.git")),
Head(RepoURL("helgaas/pci.git"), "next"),
Head(RepoURL("viro/vfs.git"), "for-linus"),
+ Head(RepoURL("jeyu/linux.git"), "modules-next"),
+ Head(RepoURL("nvdimm/nvdimm.git"), "libnvdimm-for-next"),
)
remote_index = dict(zip(remotes, list(range(len(remotes)))))
oot = Head(RepoURL(None), "out-of-tree patches")
-remote_match = re.compile("remote\..+\.url")
-
-
-def config_keys(repo):
- """
- With libgit < 0.27, pygit2's Config.__iter__() elements are str.
- With libgit 0.27, the same elements are ConfigEntry instances.
-
- This function is an adaptation layer to support both interfaces.
- """
- try:
- first = repo.config.__iter__().next()
- except StopIteration:
- return
-
- if isinstance(first, pygit2.config.ConfigEntry):
- transform = lambda config_entry: config_entry.name
- else:
- transform = lambda name: name
-
- for entry in repo.config:
- yield transform(entry)
-
def get_heads(repo):
"""
@@ -246,28 +221,38 @@ def get_heads(repo):
sha1
"""
result = collections.OrderedDict()
- repo_remotes = collections.OrderedDict([
- (RepoURL(repo.config[name]), ".".join(name.split(".")[1:-1]))
- for name in config_keys(repo)
- if remote_match.match(name)])
+ repo_remotes = collections.OrderedDict(
+ ((RepoURL(remote.url), remote,) for remote in repo.remotes))
for head in remotes:
if head in result:
raise GSException("head \"%s\" is not unique." % (head,))
try:
- remote_name = repo_remotes[head.repo_url]
+ remote = repo_remotes[head.repo_url]
except KeyError:
continue
- rev = "remotes/%s/%s" % (remote_name, head.rev,)
+ lhs = "refs/heads/%s" % (head.rev,)
+ rhs = None
+ nb = len(remote.fetch_refspecs)
+ if nb == 0:
+ # `git clone --bare` case
+ rhs = lhs
+ else:
+ for i in range(nb):
+ r = remote.get_refspec(i)
+ if r.src_matches(lhs):
+ rhs = r.transform(lhs)
+ break
+ if rhs is None:
+ raise GSError("No matching fetch refspec for head \"%s\"." %
+ (head,))
try:
- commit = repo.revparse_single(rev)
+ commit = repo.revparse_single(rhs)
except KeyError:
- raise GSError(
- "Could not read revision \"%s\". Perhaps you need to "
- "fetch from remote \"%s\", ie. `git fetch %s`." % (
- rev, remote_name, remote_name,))
+ raise GSError("Could not read revision \"%s\". Perhaps you need "
+ "to fetch from remote \"%s\"" % (rhs, remote.name,))
result[head] = str(commit.id)
if len(result) == 0 or list(result.keys())[0] != remotes[0]:
@@ -581,28 +566,6 @@ class SortIndex(object):
raise GSKeyError
- def sort(self, mapping):
- """
- Returns an OrderedDict
- result[Head][]
- sorted values from the mapping which are found in Head
- """
- result = collections.OrderedDict([(head, [],) for head in self.history])
- for commit in list(mapping.keys()):
- try:
- ic = self.lookup(commit)
- except GSKeyError:
- continue
- else:
- result[ic.head].append((ic.index, mapping.pop(commit),))
-
- for head, entries in result.items():
- entries.sort(key=operator.itemgetter(0))
- result[head] = [e[1] for e in entries]
-
- return result
-
-
def describe(self, index):
"""
index must come from the mainline head (remotes[0]).
diff --git a/scripts/git_sort/lib.py b/scripts/git_sort/lib.py
index a6c0193439..191e4b486f 100644
--- a/scripts/git_sort/lib.py
+++ b/scripts/git_sort/lib.py
@@ -13,8 +13,8 @@ import sys
import exc
import git_sort
+from patch import Patch
import series_conf
-import tag
# https://stackoverflow.com/a/952952
@@ -32,6 +32,12 @@ def libdir():
def check_series():
+ """
+ Check that the "series" file used by quilt looks like a series.conf file and
+ not a simplified version. If using the modified quilt, it will be a symlink
+ to the actual "series.conf" file and doing things like `quilt import` will
+ automatically update series.conf.
+ """
def check():
return (open("series").readline().strip() ==
"# Kernel patches configuration file")
@@ -63,6 +69,10 @@ def check_series():
def repo_path():
+ """
+ Get the path to the git_dir of the mainline linux git repository to use.
+ Typically obtained from the LINUX_GIT environment variable.
+ """
try:
search_path = subprocess.check_output(
os.path.join(libdir(), "..",
@@ -75,6 +85,11 @@ def repo_path():
def series_header(series):
+ """
+ Return the block of lines at the top of series that are not patch files
+ entries or automatically generated comments. These lines should be prepended
+ to the output.
+ """
header = []
for line in series:
@@ -98,6 +113,11 @@ def series_footer(series):
def parse_section_header(line):
+ """
+ Parse a series.conf line to identify if it's a comment denoting the
+ beginning of a subsystem section. In that case, return the Head object it
+ corresponds to.
+ """
oot_text = git_sort.oot.rev
line = line.strip()
@@ -129,6 +149,11 @@ def parse_section_header(line):
def patches_per_section(inside_lines):
+ """
+ Returns an OrderedDict
+ result[Head][]
+ patch file name
+ """
result = collections.OrderedDict([
(head, [],)
for head in flatten((git_sort.remotes, (git_sort.oot,),))])
@@ -154,6 +179,9 @@ def patches_per_section(inside_lines):
def parse_inside(index, inside_lines, move_upstream):
+ """
+ Parse series.conf lines to generate InputEntry objects.
+ """
result = []
for head, names in patches_per_section(inside_lines).items():
for name in names:
@@ -165,6 +193,10 @@ def parse_inside(index, inside_lines, move_upstream):
def list_moved_patches(base_lines, remote_lines):
+ """
+ Return a list of patch file names which are in different subsystem sections
+ between base and remote.
+ """
base = {}
result = []
@@ -181,6 +213,10 @@ def list_moved_patches(base_lines, remote_lines):
class InputEntry(object):
+ """
+ A patch line entry (usually from series.conf) and associated data about the
+ commit it backports.
+ """
commit_match = re.compile("[0-9a-f]{40}")
@@ -192,11 +228,21 @@ class InputEntry(object):
def from_patch(self, index, name, current_head, move_upstream):
+ """
+ This is where we decide a patch line's fate in the sorted series.conf
+ The following factors determine how a patch is sorted:
+ * commit found in index
+ * patch's series.conf current_head is indexed (ie. the local repo
+ fetches from that remote)
+ * patch appears to have moved downstream/didn't move/upstream
+ * patch's tag is good ("Git-repo:" == current_head.url)
+ * patches may be moved upstream between subsystem sections
+ """
self.name = name
if not os.path.exists(name):
raise exc.KSError("Could not find patch \"%s\"" % (name,))
- with tag.Patch(name) as patch:
+ with Patch(open(name, mode="rb")) as patch:
commit_tags = patch.get("Git-commit")
repo_tags = patch.get("Git-repo")
@@ -204,11 +250,22 @@ class InputEntry(object):
self.dest_head = git_sort.oot
return
- self.revs = [series_conf.firstword(ct) for ct in commit_tags]
- for rev in self.revs:
- if not self.commit_match.match(rev):
- raise exc.KSError("Git-commit tag \"%s\" in patch \"%s\" is not a "
- "valid revision." % (rev, name,))
+ class BadTag(Exception):
+ pass
+
+ def get_commit(value):
+ if not value:
+ raise BadTag(value)
+ tag = series_conf.firstword(value)
+ if not self.commit_match.match(tag):
+ raise BadTag(tag)
+ return tag
+
+ try:
+ self.revs = [get_commit(value) for value in commit_tags]
+ except BadTag as e:
+ raise exc.KSError("Git-commit tag \"%s\" in patch \"%s\" is not a "
+ "valid revision." % (e.args[0], name,))
rev = self.revs[0]
if len(repo_tags) > 1:
@@ -220,7 +277,6 @@ class InputEntry(object):
repo = git_sort.remotes[0].repo_url
self.new_url = None
- # this is where we decide a patch line's fate in the sorted series.conf
try:
ic = index.lookup(rev)
except git_sort.GSKeyError: # commit not found
@@ -324,8 +380,8 @@ def series_sort(index, entries):
entries is a list of InputEntry objects
Returns an OrderedDict
- result[Head][]
- series.conf line with a patch name
+ result[Head][]
+ patch file name
Note that Head may be a "virtual head" like "out-of-tree patches".
"""
@@ -360,9 +416,9 @@ def series_sort(index, entries):
def series_format(entries):
"""
- entries is an OrderedDict
- entries[Head][]
- series.conf line with a patch name
+ entries is an OrderedDict, typically the output of series_sort()
+ result[Head][]
+ patch file name
"""
result = []
@@ -384,8 +440,11 @@ def tag_needs_update(entry):
def update_tags(index, entries):
+ """
+ Update the Git-repo tag (possibly by removing it) of patches.
+ """
for entry in entries:
- with tag.Patch(entry.name) as patch:
+ with Patch(open(entry.name, mode="r+b")) as patch:
message = "Failed to update tag \"%s\" in patch \"%s\". This " \
"tag is not found."
if entry.dest_head == git_sort.remotes[0]:
diff --git a/scripts/git_sort/patch.py b/scripts/git_sort/patch.py
new file mode 100644
index 0000000000..b400b5db0b
--- /dev/null
+++ b/scripts/git_sort/patch.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+import io
+import re
+import sys
+
+import exc
+
+
+class Patch(object):
+ # This pattern was copied from quilt/scripts/patchfns.in:patch_header() in
+ # the quilt sources
+ break_matcher = re.compile(b"(---|\*\*\*|Index:)[ \t][^ \t]|^diff -")
+
+ def __init__(self, f):
+ assert(f.tell() == 0)
+ assert(isinstance(f, io.BufferedIOBase)) # binary (bytes) io object
+
+ self.modified = False
+ self.f = f
+ self.head = []
+ self.body = b""
+ for line in f:
+ if self.break_matcher.match(line):
+ self.body = line
+ break
+ self.head.append(line.decode())
+
+
+ def __del__(self):
+ self.writeback()
+
+
+ def __enter__(self):
+ return self
+
+
+ def __exit__(self, *args):
+ self.writeback()
+
+
+ def writeback(self):
+ if not self.modified:
+ return
+
+ self.body = self.body + self.f.read()
+ self.f.seek(0)
+ self.f.writelines([line.encode() for line in self.head])
+ self.f.write(self.body)
+ self.f.truncate()
+
+ self.modified = False
+
+
+ def get(self, tag):
+ """
+ tag does not contain the terminal ": ". It is case insensitive.
+
+ Returns a list with the value for each instance of the tag.
+ """
+ start = "%s: " % (tag.lower(),)
+ return [line[len(start):].strip()
+ for line in self.head
+ if line.lower().startswith(start)]
+
+
+ def remove(self, tag):
+ """
+ Removes all instances of the tag.
+
+ tag does not contain the terminal ": ". It is case insensitive.
+ """
+ if not self.f.writable():
+ raise exc.KSException("Modification of read-only Patch")
+
+ if len(self.get(tag)):
+ self.modified = True
+ start = "%s: " % (tag.lower(),)
+ self.head = [line
+ for line in self.head
+ if not line.lower().startswith(start)]
+
+
+ def change(self, tag, value):
+ """
+ Changes the value of all instances of the tag.
+
+ tag does not contain the terminal ": ". It is case insensitive.
+ """
+ if not self.f.writable():
+ raise exc.KSException("Modification of read-only Patch")
+
+ if len(self.get(tag)):
+ self.modified = True
+ start = "%s: " % (tag.lower(),)
+
+ def change_value(line):
+ if line.lower().startswith(start):
+ return "%s%s\n" % (line[:len(start)], value.strip(),)
+ else:
+ return line
+
+ self.head = [change_value(line) for line in self.head]
+ else:
+ raise KeyError("Tag \"%s\" not found" % (tag,))
diff --git a/scripts/git_sort/qcp.py b/scripts/git_sort/qcp.py
index 4cbbc9544a..233425610a 100755
--- a/scripts/git_sort/qcp.py
+++ b/scripts/git_sort/qcp.py
@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
import argparse
+import io
import os
import os.path
import pygit2
@@ -12,8 +13,8 @@ import tempfile
import exc
import lib
+from patch import Patch
import series_conf
-import tag
def format_import(references, tmpdir, dstdir, rev, poi=[]):
@@ -83,7 +84,7 @@ if __name__ == "__main__":
sys.exit(1)
if args.followup:
- with tag.Patch(content=commit.message) as patch:
+ with Patch(io.BytesIO(commit.message.encode())) as patch:
try:
fixes = series_conf.firstword(patch.get("Fixes")[0])
except IndexError:
@@ -96,8 +97,8 @@ if __name__ == "__main__":
cwd = os.getcwd()
os.chdir("patches")
try:
- with series_conf.find_commit_in_series(fixes, series) as patch:
- destination = os.path.dirname(patch.name)
+ with series_conf.find_commit(fixes, series) as (name, patch,):
+ destination = os.path.dirname(name)
references = " ".join(patch.get("References"))
except exc.KSNotFound:
print("Error: no patch found which contains commit %s." %
@@ -106,7 +107,7 @@ if __name__ == "__main__":
os.chdir(cwd)
print("Info: using references \"%s\" from patch \"%s\" which contains "
- "commit %s." % (references, patch, fixes[:12]), file=sys.stderr)
+ "commit %s." % (references, name, fixes[:12]))
else:
destination = args.destination
references = args.references
diff --git a/scripts/git_sort/qdupcheck.py b/scripts/git_sort/qdupcheck.py
index 2191ee2775..72c5de79fb 100755
--- a/scripts/git_sort/qdupcheck.py
+++ b/scripts/git_sort/qdupcheck.py
@@ -36,9 +36,9 @@ if __name__ == "__main__":
cwd = os.getcwd()
os.chdir("patches")
try:
- with series_conf.find_commit_in_series(commit, series) as patch:
+ with series_conf.find_commit(commit, series) as (name, patch,):
print("Commit %s already present in patch\n\t%s" % (
- commit[:12], patch.name,))
+ commit[:12], name,))
references = " ".join(patch.get("References"))
if references:
print("for\n\t%s" % (references,))
@@ -52,7 +52,7 @@ if __name__ == "__main__":
top = None
else:
raise
- if top == patch.name:
+ if top == name:
print("This is the top patch.")
sys.exit(1)
except exc.KSNotFound:
diff --git a/scripts/git_sort/quilt-mode.sh b/scripts/git_sort/quilt-mode.sh
index 5104fc9a96..c9f0b7bbaf 100644
--- a/scripts/git_sort/quilt-mode.sh
+++ b/scripts/git_sort/quilt-mode.sh
@@ -134,8 +134,8 @@ qdupcheck () {
qdiffcheck () {
local git_dir
git_dir=$("$_libdir"/../linux_git.sh) || return 1
- local rev=$(tag_get git-commit < $(q top) | GIT_DIR="$git_dir"/.git expand_git_ref)
- interdiff <(GIT_DIR="$git_dir"/.git $_libdir/git-f1 $rev) $(q top)
+ local rev=$(tag_get git-commit < $(q top) | GIT_DIR=$git_dir expand_git_ref)
+ interdiff <(GIT_DIR=$git_dir $_libdir/git-f1 $rev) $(q top)
}
@@ -240,7 +240,7 @@ qadd () {
(
[ ${#series[@]} -gt 0 ] && printf "%s\n" "${series[@]}"
[ -n "$_series" ] && echo "$_series"
- ) | GIT_DIR="$git_dir"/.git "$_libdir"/git-sort
+ ) | GIT_DIR=$git_dir "$_libdir"/git-sort
)"
if [ -z "${series[0]}" ]; then
@@ -264,7 +264,7 @@ qedit () {
${EDITOR:-${VISUAL:-vi}} "$tmpfile"
mapfile -t series <<< "$(grep . "$tmpfile" |
- GIT_DIR="$git_dir"/.git $_libdir/git-sort)"
+ GIT_DIR=$git_dir $_libdir/git-sort)"
if [ -z "${series[0]}" ]; then
unset series[0]
@@ -314,7 +314,7 @@ _stablecheck () {
local entry=$1
local patch=$2
local git_dir
- local git_dir=$("$_libdir"/../linux_git.sh) || return 1
+ git_dir=$("$_libdir"/../linux_git.sh) || return 1
local rev=$(echo "$patch" | awk '{
match($0, "patch-([[:digit:]]+\\.[[:digit:]]+)\\.([[:digit:]]+)(-([[:digit:]]+))?", a)
@@ -324,15 +324,15 @@ _stablecheck () {
print "v" a[1] "..v" a[1] "." a[2]
}
}')
- local output=$(GIT_DIR="$git_dir"/.git git log "$rev" --pretty=tformat:%H --grep "$entry")
+ local output=$(GIT_DIR=$git_dir git log "$rev" --pretty=tformat:%H --grep "$entry")
local nb=$(echo "$output" | wc -l)
if [ "$output" -a $nb -eq 1 ]; then
echo -en "This commit was backported to a stable branch as\n\t"
- GIT_DIR="$git_dir"/.git $_libdir/git-overview -m "$output"
+ GIT_DIR=$git_dir $_libdir/git-overview -m "$output"
echo
elif [ $nb -gt 1 ]; then
echo "Warning: $nb potential stable commits found:" > /dev/stderr
- GIT_DIR="$git_dir"/.git git log "$rev" --oneline --grep "$entry" > /dev/stderr
+ GIT_DIR=$git_dir git log "$rev" --oneline --grep "$entry" > /dev/stderr
else
echo "Warning: no potential stable commit found." > /dev/stderr
fi
diff --git a/scripts/git_sort/refs_in_series.sh b/scripts/git_sort/refs_in_series.sh
index 17dd783f1c..cb58b7320f 100755
--- a/scripts/git_sort/refs_in_series.sh
+++ b/scripts/git_sort/refs_in_series.sh
@@ -64,7 +64,7 @@ series=$(
while read line; do
set $line
ref=$1
- orig_stat_nb=$(GIT_DIR="$git_dir"/.git git format-patch --stdout -n1 $ref | eval git apply --numstat "$includeargs" | wc -l)
+ orig_stat_nb=$(GIT_DIR=$git_dir git format-patch --stdout -n1 $ref | eval git apply --numstat "$includeargs" | wc -l)
found=
while read patch; do
if [ ! "$patch" ]; then
diff --git a/scripts/git_sort/series_conf.py b/scripts/git_sort/series_conf.py
index aea36d1348..a3ea04e3cf 100755
--- a/scripts/git_sort/series_conf.py
+++ b/scripts/git_sort/series_conf.py
@@ -15,7 +15,7 @@ import errno
import sys
import exc
-import tag
+from patch import Patch
start_text = "sorted patches"
@@ -92,17 +92,25 @@ filter_series = lambda lines : [firstword(line) for line in lines
@contextlib.contextmanager
-def find_commit_in_series(commit, series):
+def find_commit(commit, series, mode="rb"):
"""
+ commit: unabbreviated git commit id
+ series: list of lines from series.conf
+ mode: mode to open the patch files in, should be "rb" or "r+b"
+
Caller must chdir to where the entries in series can be found.
+
+ Returns patch.Patch instances
"""
for name in filter_series(series):
- patch = tag.Patch(name)
+ patch = Patch(open(name, mode=mode))
found = False
- if commit in [firstword(value) for value in patch.get("Git-commit")]:
+ if commit in [firstword(value)
+ for value in patch.get("Git-commit")
+ if value]:
found = True
- yield patch
- patch.close()
+ yield name, patch
+ patch.writeback()
if found:
return
raise exc.KSNotFound()
diff --git a/scripts/git_sort/series_insert.py b/scripts/git_sort/series_insert.py
index 5600dee359..622b1cbea4 100755
--- a/scripts/git_sort/series_insert.py
+++ b/scripts/git_sort/series_insert.py
@@ -11,11 +11,10 @@ import collections
import pygit2
import sys
-import git_sort
import exc
+import git_sort
import lib
import series_conf
-import tag
if __name__ == "__main__":
diff --git a/scripts/git_sort/series_sort.py b/scripts/git_sort/series_sort.py
index 4420401181..dc62a4a2f3 100755
--- a/scripts/git_sort/series_sort.py
+++ b/scripts/git_sort/series_sort.py
@@ -33,7 +33,6 @@ import exc
import git_sort
import lib
import series_conf
-import tag
if __name__ == "__main__":
diff --git a/scripts/git_sort/tag.py b/scripts/git_sort/tag.py
deleted file mode 100644
index e2a453ccff..0000000000
--- a/scripts/git_sort/tag.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/python3
-# -*- coding: utf-8 -*-
-
-import sys
-
-
-class Patch(object):
- def __init__(self, name=None, content=None):
- self.name = None
- if name:
- self.name = name
- self.head = open(name).readlines()
- self.modified = False
- self.closed = False
- elif content:
- self.head = ["%s\n" % (l,) for l in content.splitlines()]
- self.closed = True
- else:
- self.head = sys.stdin.readlines()
- self.modified = False
- self.closed = False
-
- self.body = []
- for i in range(len(self.head)):
- # These patterns were copied from
- # quilt/scripts/patchfns.in:patch_header()
- # in the quilt sources
- if self.head[i].startswith(("---", "***", "Index:", "diff -",)):
- self.body = self.head[i:]
- self.head = self.head[:i]
- break
-
-
- def __del__(self):
- self.close()
-
-
- def __enter__(self):
- return self
-
-
- def __exit__(self, *args):
- self.close()
-
-
- def close(self):
- if not self.closed:
- self.writeback()
- self.closed = True
-
-
- def writeback(self):
- if self.name:
- if self.modified:
- with open(self.name, mode="w") as output:
- output.writelines(self.head)
- output.writelines(self.body)
- else:
- sys.stdout.writelines(self.head)
- sys.stdout.writelines(self.body)
- sys.stdout.flush()
-
-
- def get(self, tag):
- """
- tag does not contain the terminal ": ". It is case insensitive.
-
- Returns a list with the value for each instance of the tag.
- """
- start = "%s: " % (tag.lower(),)
- return [line[len(start):-1].strip() for line in self.head
- if line.lower().startswith(start)]
-
-
- def remove(self, tag):
- """
- Removes all instances of the tag.
-
- tag does not contain the terminal ": ". It is case insensitive.
- """
- if self.closed:
- raise ValueError("Modification of closed Patch")
-
- if len(self.get(tag)):
- self.modified = True
- start = "%s: " % (tag.lower(),)
- self.head = [line for line in self.head
- if not line.lower().startswith(start)]
-
-
- def change(self, tag, value):
- """
- Changes the value of all instances of the tag.
-
- tag does not contain the terminal ": ". It is case insensitive.
- """
- if self.closed:
- raise ValueError("Modification of closed Patch")
-
- if len(self.get(tag)):
- self.modified = True
- start = "%s: " % (tag.lower(),)
-
- def change_value(line):
- if line.lower().startswith(start):
- return "%s%s\n" % (line[:len(start)], value.strip(),)
- else:
- return line
-
- self.head = list(map(change_value, self.head))
- else:
- raise KeyError("Tag \"%s\" not found" % (tag,))
diff --git a/scripts/git_sort/tests/opensuse-15.0/Dockerfile b/scripts/git_sort/tests/opensuse-15.0/Dockerfile
new file mode 100644
index 0000000000..0959660370
--- /dev/null
+++ b/scripts/git_sort/tests/opensuse-15.0/Dockerfile
@@ -0,0 +1,25 @@
+# https://hub.docker.com/r/opensuse/leap/
+FROM opensuse/leap:15.0 AS base
+
+RUN zypper -n ref
+
+FROM base AS packages
+
+RUN zypper -n in git python3 python3-dbm rcs
+
+RUN git config --global user.email "you@example.com"
+RUN git config --global user.name "Your Name"
+
+RUN zypper -n ar -G https://download.opensuse.org/repositories/Kernel:/tools/openSUSE_Leap_15.0/Kernel:tools.repo
+RUN zypper -n in python3-pygit2
+
+RUN zypper -n ar -G https://download.opensuse.org/repositories/home:/benjamin_poirier:/series_sort/openSUSE_Leap_15.0/home:benjamin_poirier:series_sort.repo
+RUN zypper -n in --from home_benjamin_poirier_series_sort quilt
+
+FROM packages
+
+VOLUME /scripts
+
+WORKDIR /scripts/git_sort
+
+CMD python3 -m unittest discover -v
diff --git a/scripts/git_sort/tests/opensuse-42.3/Dockerfile b/scripts/git_sort/tests/opensuse-42.3/Dockerfile
index a7ebaff7b3..cb369809ac 100644
--- a/scripts/git_sort/tests/opensuse-42.3/Dockerfile
+++ b/scripts/git_sort/tests/opensuse-42.3/Dockerfile
@@ -1,5 +1,5 @@
-# https://store.docker.com/images/opensuse
-FROM opensuse:42.3 AS base
+# https://hub.docker.com/r/opensuse/leap/
+FROM opensuse/leap:42.3 AS base
RUN zypper -n ref
diff --git a/scripts/git_sort/tests/opensuse-tumbleweed/Dockerfile b/scripts/git_sort/tests/opensuse-tumbleweed/Dockerfile
index 19c438c8e0..182c8d0689 100644
--- a/scripts/git_sort/tests/opensuse-tumbleweed/Dockerfile
+++ b/scripts/git_sort/tests/opensuse-tumbleweed/Dockerfile
@@ -1,5 +1,5 @@
-# https://store.docker.com/images/opensuse
-FROM opensuse:tumbleweed AS base
+# https://hub.docker.com/r/opensuse/tumbleweed/
+FROM opensuse/tumbleweed AS base
RUN zypper -n ref
diff --git a/scripts/git_sort/tests/run_all.sh b/scripts/git_sort/tests/run_all.sh
index 692f8b3d4f..12235a28d2 100755
--- a/scripts/git_sort/tests/run_all.sh
+++ b/scripts/git_sort/tests/run_all.sh
@@ -10,7 +10,14 @@ if [ $(docker image ls -q benjamin_poirier/docker_images/sle-12-sp2:latest | wc
docker import - benjamin_poirier/docker_images/sle-12-sp2
fi
-for release in sle12-sp2 sle12-sp3 opensuse-42.3 opensuse-tumbleweed; do
+for release in \
+ sle12-sp2 \
+ sle12-sp3 \
+ sle15 \
+ opensuse-42.3 \
+ opensuse-15.0 \
+ opensuse-tumbleweed \
+ ; do
echo "Building container image for $release..."
docker build -q -t gs-test-$release "$libdir/$release"
echo "Running tests in $release:"
diff --git a/scripts/git_sort/tests/sle12-sp3/Dockerfile b/scripts/git_sort/tests/sle12-sp3/Dockerfile
index 651270094b..df097b6b9f 100644
--- a/scripts/git_sort/tests/sle12-sp3/Dockerfile
+++ b/scripts/git_sort/tests/sle12-sp3/Dockerfile
@@ -1,5 +1,5 @@
-# http://registry.suse.de/cgi-bin/overview.pl
-FROM registry.suse.de/home/benjamin_poirier/docker_images/sle-12-sp3/images/x86_64/suse/sles12sp3:2.0.3 AS base
+# http://registry.suse.de/
+FROM registry.suse.de/home/benjamin_poirier/docker_images/sle-12-sp3/images/suse/sles12sp3:2.0.3 AS base
RUN zypper -n ref
diff --git a/scripts/git_sort/tests/sle15/Dockerfile b/scripts/git_sort/tests/sle15/Dockerfile
new file mode 100644
index 0000000000..3b08991cd6
--- /dev/null
+++ b/scripts/git_sort/tests/sle15/Dockerfile
@@ -0,0 +1,25 @@
+# http://registry.suse.de/
+FROM registry.suse.de/home/david_chang/branches/devel/docker/images/sle15/images/suse/sles15:2.0.3 AS base
+
+RUN zypper -n ref
+
+FROM base AS packages
+
+RUN zypper -n in git python3 python3-dbm rcs awk
+
+RUN git config --global user.email "you@example.com"
+RUN git config --global user.name "Your Name"
+
+RUN zypper -n ar -G https://download.opensuse.org/repositories/Kernel:/tools/SLE_15/Kernel:tools.repo
+RUN zypper -n in python3-pygit2
+
+RUN zypper -n ar -G https://download.opensuse.org/repositories/home:/benjamin_poirier:/series_sort/SLE_15/home:benjamin_poirier:series_sort.repo
+RUN zypper -n in --from home_benjamin_poirier_series_sort quilt
+
+FROM packages
+
+VOLUME /scripts
+
+WORKDIR /scripts/git_sort
+
+CMD python3 -m unittest discover -v
diff --git a/scripts/git_sort/tests/support.py b/scripts/git_sort/tests/support.py
index 0e5febbd86..dfff2b855f 100644
--- a/scripts/git_sort/tests/support.py
+++ b/scripts/git_sort/tests/support.py
@@ -56,7 +56,8 @@ def format_sanitized_subject(message):
return "".join(result[:52])
-def format_patch(commit, mainline=None, repo=None, directory=""):
+def format_patch(commit, mainline=None, repo=None, references=None,
+ directory=""):
name = os.path.join(directory, format_sanitized_subject(commit.message) +
".patch")
@@ -74,6 +75,8 @@ def format_patch(commit, mainline=None, repo=None, directory=""):
f.write("Git-commit: %s\n" % (str(commit.id),))
else:
f.write("Patch-mainline: No\n")
+ if references is not None:
+ f.write("References: %s\n" % (references,))
f.write("Subject: %s" % (commit.message,))
if not commit.message.endswith("\n"):
f.write("\n")
diff --git a/scripts/git_sort/tests/test_quilt_mode.py b/scripts/git_sort/tests/test_quilt_mode.py
index 4967c5e761..95f35a74b4 100755
--- a/scripts/git_sort/tests/test_quilt_mode.py
+++ b/scripts/git_sort/tests/test_quilt_mode.py
@@ -25,7 +25,6 @@ class TestQuiltMode(unittest.TestCase):
self.repo = pygit2.init_repository(os.environ["LINUX_GIT"])
self.repo.config["user.email"] = "agraf@suse.de"
self.repo.config["user.name"] = "Alexander Graf"
- readme_path = os.path.join(os.environ["LINUX_GIT"], "README")
author = pygit2.Signature("Alice Author", "alice@authors.tld")
committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
@@ -572,7 +571,156 @@ class TestMergeTool(unittest.TestCase):
self.assertEqual(retval.decode().strip(), "M series.conf")
+class TestQCP(unittest.TestCase):
+ def setUp(self):
+ os.environ["XDG_CACHE_HOME"] = tempfile.mkdtemp(prefix="gs_cache")
+
+ # setup stub linux repository
+ os.environ["LINUX_GIT"] = tempfile.mkdtemp(prefix="gs_repo")
+ self.repo = pygit2.init_repository(os.environ["LINUX_GIT"])
+ self.repo.config["user.email"] = "author1@example.com"
+ self.repo.config["user.name"] = "Author One"
+
+ author = pygit2.Signature("Author One", "author1@example.com")
+ committer = pygit2.Signature("Maintainer One", "maintainer1@example.com")
+ tree = self.repo.TreeBuilder()
+
+ tree.insert("driver.c",
+ self.repo.create_blob("#include <bad.h>\n"),
+ pygit2.GIT_FILEMODE_BLOB)
+ self.commits = []
+ self.commits.append(self.repo.create_commit(
+ "refs/heads/mainline",
+ author,
+ committer,
+ """Add a very small module
+
+... which was not tested.
+
+Signed-off-by: Author One <author1@example.com>
+Signed-off-by: Maintainer One <maintainer@example.com>
+""",
+ tree.write(),
+ []
+ ))
+
+ tree.insert("driver.c",
+ self.repo.create_blob("#include <linux/module.h>\n"),
+ pygit2.GIT_FILEMODE_BLOB)
+ self.commits.append(self.repo.create_commit(
+ "refs/heads/mainline",
+ author,
+ committer,
+ """Fix the very small module
+
+syzbot is reporting deadlocks at __blkdev_get() [1].
+
+----------------------------------------
+[ 92.493919] systemd-udevd D12696 525 1 0x00000000
+[ 92.495891] Call Trace:
+[ 92.501560] schedule+0x23/0x80
+[ 92.502923] schedule_preempt_disabled+0x5/0x10
+[ 92.504645] __mutex_lock+0x416/0x9e0
+[ 92.510760] __blkdev_get+0x73/0x4f0
+[ 92.512220] blkdev_get+0x12e/0x390
+[ 92.518151] do_dentry_open+0x1c3/0x2f0
+[ 92.519815] path_openat+0x5d9/0xdc0
+[ 92.521437] do_filp_open+0x7d/0xf0
+[ 92.527365] do_sys_open+0x1b8/0x250
+[ 92.528831] do_syscall_64+0x6e/0x270
+[ 92.530341] entry_SYSCALL_64_after_hwframe+0x42/0xb7
+
+[ 92.931922] 1 lock held by systemd-udevd/525:
+[ 92.933642] #0: 00000000a2849e25 (&bdev->bd_mutex){+.+.}, at: __blkdev_get+0x73/0x4f0
+----------------------------------------
+
+The reason of deadlock turned out that wait_event_interruptible() in
+
+Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de>
+Fixes: %s ("Add a very small module")
+Signed-off-by: Author One <author1@example.com>
+Signed-off-by: Maintainer One <maintainer@example.com>
+""" % (str(self.commits[-1],)),
+ tree.write(),
+ [self.commits[-1]]
+ ))
+
+ self.repo.create_tag("v4.10-rc6", self.commits[-1], pygit2.GIT_REF_OID,
+ committer, "Linux 4.10-rc6")
+
+ self.repo.remotes.create(
+ "origin",
+ "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git")
+ self.repo.references.create("refs/remotes/origin/master",
+ self.commits[-1])
+
+ # setup stub kernel-source content
+ self.ks_dir = tempfile.mkdtemp(prefix="gs_ks")
+ patch_dir = os.path.join(self.ks_dir, "patches.suse")
+ os.mkdir(patch_dir)
+ os.chdir(patch_dir)
+ with open(os.path.join(self.ks_dir, "series.conf"), mode="w") as f:
+ f.write(
+"""# Kernel patches configuration file
+
+ ########################################################
+ # sorted patches
+ ########################################################
+""")
+ f.write("\tpatches.suse/%s\n" % (
+ tests.support.format_patch(self.repo.get(self.commits[0]),
+ mainline="v4.9",
+ references="bsc#123"),))
+ f.write(
+"""
+ ########################################################
+ # end of sorted patches
+ ########################################################
+""")
+
+ ss_path = os.path.join(lib.libdir(), "series_sort.py")
+ os.chdir(self.ks_dir)
+
+ # This overlaps what is tested by test_series_sort, hence, not put in a
+ # test of its own.
+ subprocess.check_call([ss_path, "-c", "series.conf"])
+ with open("series.conf") as f:
+ content1 = f.read()
+ subprocess.check_call([ss_path, "series.conf"])
+ with open("series.conf") as f:
+ content2 = f.read()
+ self.assertEqual(content2, content1)
+
+ os.makedirs("tmp/current")
+ os.chdir("tmp/current")
+ subprocess.check_call(
+ ["quilt", "setup", "--sourcedir", "../../", "../../series.conf"])
+
+
+ def tearDown(self):
+ shutil.rmtree(os.environ["XDG_CACHE_HOME"])
+ shutil.rmtree(os.environ["LINUX_GIT"])
+ shutil.rmtree(self.ks_dir)
+
+
+ def test_fixup(self):
+ qm_path = os.path.join(lib.libdir(), "quilt-mode.sh")
+
+ # import commits[1]
+ subprocess.check_call(
+ ". %s; qgoto %s" % (qm_path, str(self.commits[1])), shell=True,
+ stdout=subprocess.DEVNULL, executable="/bin/bash")
+ subprocess.check_call(
+ """. %s; qcp -f %s""" % (
+ qm_path, str(self.commits[1])),
+ shell=True, stdout=subprocess.DEVNULL, executable="/bin/bash")
+
+ retval = subprocess.check_output(("quilt", "--quiltrc", "-", "next",))
+ name = "patches.suse/Fix-the-very-small-module.patch"
+ self.assertEqual(retval.decode().strip(), name)
+
+
if __name__ == '__main__':
# Run a single testcase
- suite = unittest.TestLoader().loadTestsFromTestCase(TestMergeTool)
+ suite = unittest.TestLoader().loadTestsFromTestCase(TestQCP)
unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/scripts/git_sort/tests/test_series_sort.py b/scripts/git_sort/tests/test_series_sort.py
index 18475bcdd0..66317c2025 100755
--- a/scripts/git_sort/tests/test_series_sort.py
+++ b/scripts/git_sort/tests/test_series_sort.py
@@ -745,6 +745,16 @@ class TestFromPatch(unittest.TestCase):
return name, series2
+ @staticmethod
+ def filter_out_tags(name):
+ with open(name) as f:
+ result = [line
+ for line in f
+ if not line.startswith(("Git-repo", "Patch-mainline",))]
+
+ return result
+
+
def test_found_notindexed_upstream_good_moveupstream(self):
"""
patch sorted in net (not fetched), commit found in mainline
@@ -752,12 +762,17 @@ class TestFromPatch(unittest.TestCase):
tag is updated
"""
name, series2 = self.prepare_found_notindexed_upstream_good()
+ before = self.filter_out_tags(name)
self.check_outdated(name,
"Input is not sorted.\nGit-repo tags are outdated.\n", series2,
True)
self.check_tag(name, "Git-repo: ", self.mainline_repo)
+ # check that only the expected tags changed
+ after = self.filter_out_tags(name)
+ self.assertEqual(before, after)
+
def test_found_notindexed_upstream_good_nomoveupstream(self):
"""
diff --git a/scripts/git_sort/update_clone.py b/scripts/git_sort/update_clone.py
new file mode 100755
index 0000000000..7039d70c10
--- /dev/null
+++ b/scripts/git_sort/update_clone.py
@@ -0,0 +1,99 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+import argparse
+import collections
+import pygit2
+import re
+import shlex
+
+import git_sort
+import lib
+
+
+proto_match = re.compile("^(git|https?)://")
+invalid_match = re.compile("~")
+ext = ".git"
+
+
+def transform(name):
+ """
+ Transform a remote url into a string that can be used as a git remote name.
+ Useful for remotes that do not start with the kernel.org canonical prefix.
+ """
+ name = proto_match.sub("", name, 1)
+ name = invalid_match.sub("_", name)
+ if name.endswith(ext):
+ name = name[:-1 * len(ext)]
+
+ return name
+
+
+def sync_remote_list(directory):
+ quoted_directory = shlex.quote(directory)
+ commands = []
+
+ try:
+ repo = pygit2.Repository(directory)
+ except pygit2.GitError:
+ commands.append("git init %s\n" % (quoted_directory,))
+ current_remotes = {}
+ else:
+ current_remotes = {remote.name : git_sort.RepoURL(remote.url)
+ for remote in repo.remotes}
+
+ commands.append("cd %s\n" % (quoted_directory,))
+
+ new_remotes = collections.OrderedDict(
+ ((transform(str(head.repo_url)), head.repo_url,)
+ for head in git_sort.remotes))
+
+ # modify existing remotes whose url has changed
+ commands.extend(["git remote set-url %s %s\n" % (
+ shlex.quote(name), shlex.quote(repr(repo_url)),)
+ for name, repo_url in new_remotes.items()
+ if name in current_remotes and repo_url != current_remotes[name]
+ ])
+
+ # add missing remotes
+ current = set(current_remotes)
+ new = set(new_remotes)
+
+ mainline = str(git_sort.remotes[0].repo_url)
+ def option(name):
+ if name == mainline:
+ return ""
+ else:
+ return " --no-tags"
+
+ commands.extend(["git remote add%s %s %s\n" % (
+ option(name), shlex.quote(name), shlex.quote(repr(new_remotes[name])),)
+ for name in new_remotes
+ if name in new - current
+ ])
+
+ # remove superfluous remotes
+ commands.extend(["git remote remove %s\n" % (
+ shlex.quote(name),)
+ for name in sorted(current - new)
+ ])
+
+ return commands
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="Print commands to clone the mainline Linux repository "
+ "and add all remotes configured for git-sort. "
+ "If the target directory is already a git repository, print commands "
+ "to add or remove remotes to match with the remotes from the list "
+ "configured for git-sort. "
+ "That repository can then be used as an ultimate reference for patch "
+ "ordering in series.conf.")
+ parser.add_argument("directory", nargs="?", default="linux",
+ help="Directory name to clone into. Default: linux")
+ args = parser.parse_args()
+
+ print("".join(sync_remote_list(args.directory)), end="")
+
+ print("git fetch --all")
diff --git a/scripts/install-git-hooks b/scripts/install-git-hooks
index 1e309208a3..0c129b09ee 100755
--- a/scripts/install-git-hooks
+++ b/scripts/install-git-hooks
@@ -35,7 +35,8 @@ check_snippet()
install_snippet()
{
- local hook="$GIT_DIR"/hooks/pre-commit
+ local hookdir="$GIT_DIR"/hooks
+ local hook="$hookdir"/pre-commit
local snippet='
# runs kernel-source-patch-check for each added or modified patch
. "$(dirname "$0")"/kernel-source-pre-commit'
@@ -47,6 +48,7 @@ install_snippet()
if check_snippet; then
return
fi
+ mkdir -p "$hookdir"
if ! test -x "$hook"; then
# if the hook was not enabled before, don't run the example code that
# is usually there
diff --git a/scripts/linux_git.sh b/scripts/linux_git.sh
index 063b9b8e42..71698f3745 100755
--- a/scripts/linux_git.sh
+++ b/scripts/linux_git.sh
@@ -4,8 +4,13 @@
# reference by other scripts.
gitdir=${LINUX_GIT:-$HOME/linux-2.6}
-if ! [ -d "$gitdir/.git" ]; then
+if ! cd "$gitdir" 2>/dev/null; then
+ echo "Error: could not change to LINUX_GIT directory" >&2
+ exit 1
+fi
+unset GIT_DIR
+if ! result=$(git rev-parse --git-dir 2>/dev/null); then
echo "No linux git tree found (please set the \"LINUX_GIT\" environment variable)" >&2
exit 1
fi
-echo "$gitdir"
+readlink -f "$result"
diff --git a/scripts/log2 b/scripts/log2
index 60281faf99..21b681010f 100755
--- a/scripts/log2
+++ b/scripts/log2
@@ -254,19 +254,37 @@ splice_series()
read -r -u 4 new || new_eof=1
if [ "$new_eof" ]; then
break
- elif [ "$new" = "$old" ]; then
+ elif [ ! "$old_eof" -a "$new" = "$old" ]; then
echo "$old"
state="after patch"
elif [ -z "$(trim "$new")" ]; then
echo "$new"
+ state="whitespace seen"
fi
- elif [ $state = "after patch" ]; then
- read -r -u 3 old || old_eof=1
- #echo "@@ state $state old <$old> eof <$old_eof> new <$new> eof <$new_eof>"
- if [ "$old_eof" ]; then
+ elif [ $state = "whitespace seen" ]; then
+ read -r -u 4 new || new_eof=1
+ if [ "$new_eof" ]; then
break
+ elif [ ! "$old_eof" -a "$new" = "$old" ]; then
+ echo "$old"
+ state="after patch"
+ elif [ -z "$(trim "$new")" ]; then
+ echo "$new"
+ else
+ state="after whitespace"
fi
- echo "$old"
+ elif [ $state = "after whitespace" ]; then
+ read -r -u 4 new || new_eof=1
+ if [ "$new_eof" ]; then
+ break
+ elif [ ! "$old_eof" -a "$new" = "$old" ]; then
+ echo "$old"
+ state="after patch"
+ fi
+ elif [ $state = "after patch" ]; then
+ #echo "@@ state $state old <$old> eof <$old_eof> new <$new> eof <$new_eof>" > /dev/stderr
+ cat <&3
+ break
fi
done
diff --git a/scripts/patch-tags-from-git b/scripts/patch-tags-from-git
index a24f8b5961..032c20bde5 100755
--- a/scripts/patch-tags-from-git
+++ b/scripts/patch-tags-from-git
@@ -60,7 +60,7 @@ if [ "z$commit" = "z" ]; then
exit 3
fi
-export GIT_DIR=$DIR/.git
+export GIT_DIR=$DIR
if [ ! -d $GIT_DIR ]; then
echo "No such directory $GIT_DIR"
diff --git a/scripts/python/check-patchhdr b/scripts/python/check-patchhdr
index 66f7b56d34..bfa28fca08 100755
--- a/scripts/python/check-patchhdr
+++ b/scripts/python/check-patchhdr
@@ -1,6 +1,10 @@
-#!/usr/bin/python3
+#!/usr/bin/python
# -*- coding: utf-8 -*-,
+from __future__ import absolute_import
+from __future__ import print_function
+from __future__ import division
+
import sys
from optparse import OptionParser
from suse_git import header
diff --git a/scripts/python/suse_git/header.py b/scripts/python/suse_git/header.py
index f6ced9bcfe..e820bb56fd 100755
--- a/scripts/python/suse_git/header.py
+++ b/scripts/python/suse_git/header.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/python
# -*- coding: utf-8 -*-,
import sys
diff --git a/scripts/python/suse_git/patch.py b/scripts/python/suse_git/patch.py
index c60ffd8472..13ff659a4d 100644
--- a/scripts/python/suse_git/patch.py
+++ b/scripts/python/suse_git/patch.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/python
# -*- coding: utf-8 -*-,
import sys
diff --git a/scripts/run_oldconfig.sh b/scripts/run_oldconfig.sh
index a7a9fba122..fadac621ee 100755
--- a/scripts/run_oldconfig.sh
+++ b/scripts/run_oldconfig.sh
@@ -356,7 +356,7 @@ ask_reuse_config()
filter_config()
{
- sed -e '/^# .* is not set$/p' -e '/^$\|^#/d' "$@" | sort
+ sed -e '/CONFIG_GCC_VERSION/ d' -e '/^# .* is not set$/p' -e '/^$\|^#/d' "$@" | sort
}
# Keep these in the -vanilla fragment even if -default has the same values.
@@ -401,6 +401,9 @@ for config in $config_files; do
MAKE_ARGS="ARCH=$cpu_arch"
;;
esac
+ if [ -n "$CC" ]; then
+ MAKE_ARGS="$MAKE_ARGS CC=$CC"
+ fi
if $silent; then
MAKE_ARGS="$MAKE_ARGS -s"
fi
diff --git a/scripts/sequence-patch.sh b/scripts/sequence-patch.sh
index 725dea8e18..a1bd7b817f 100755
--- a/scripts/sequence-patch.sh
+++ b/scripts/sequence-patch.sh
@@ -324,6 +324,8 @@ if test -z "$CONFIG"; then
CONFIG=$machine-smp
elif test -e "config/$machine/pae"; then
CONFIG=$machine-pae
+ elif test -e "config/$machine/azure"; then
+ CONFIG=$machine-azure
elif test -e "config/$machine/default"; then
CONFIG=$machine-default
elif test -n "$VARIANT" -a -e "config/$machine/${VARIANT#-}"; then
@@ -392,6 +394,7 @@ export TMPDIR
ORIG_DIR=$SCRATCH_AREA/linux-$SRCVERSION.orig
TAG=$(get_branch_name)
TAG=${TAG//\//_}
+TAG=${TAG//\#/_}
if $VANILLA; then
TAG=${TAG}-vanilla
fi
diff --git a/scripts/tar-up.sh b/scripts/tar-up.sh
index b933faab7d..54014a8c99 100755
--- a/scripts/tar-up.sh
+++ b/scripts/tar-up.sh
@@ -207,7 +207,7 @@ fi
if grep -q '^Source.*:[[:space:]]*log\.sh[[:space:]]*$' rpm/kernel-source.spec.in; then
cp -p scripts/rpm-log.sh "$build_dir"/log.sh
fi
-rm -f "$build_dir/kernel-source.changes.old" "$build_dir/gitlog-fixups"
+rm -f "$build_dir/kernel-source.changes.old" "$build_dir/gitlog-fixups" "$build_dir/gitlog-excludes"
if test -e "$build_dir"/config-options.changes; then
# Rename to avoid triggering a build service rule error
mv "$build_dir"/config-options.changes \
@@ -243,7 +243,7 @@ elif $using_git; then
echo "expected \"last commit: <commit>\" in rpm/kernel-source.changes.old" >&2
exit 1
esac
- if test -d rpm/gitlog-excludes; then
+ if test -e rpm/gitlog-excludes; then
exclude=(--excludes "$_" "${exclude[@]}")
fi
if test -e rpm/gitlog-fixups; then
diff --git a/scripts/tests/test_linux_git.py b/scripts/tests/test_linux_git.py
new file mode 100755
index 0000000000..ea678ff927
--- /dev/null
+++ b/scripts/tests/test_linux_git.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+import os.path
+import shutil
+import subprocess
+import tempfile
+import unittest
+
+import lib
+
+
+class TestLinuxGit(unittest.TestCase):
+ def setUp(self):
+ self.tmpdir = tempfile.mkdtemp(prefix="ks_linux_git")
+ self.lg_path = os.path.join(lib.libdir(), "../linux_git.sh")
+
+
+ def tearDown(self):
+ shutil.rmtree(self.tmpdir)
+
+
+ def run_one(self, *, bare, var, output):
+ args = ["git", "init", "--quiet"]
+ if bare:
+ args.append("--bare")
+ args.append(self.tmpdir)
+
+ subprocess.check_call(args, env={})
+
+ retval = subprocess.check_output((self.lg_path,),
+ env={"LINUX_GIT" : var})
+ self.assertEqual(output, retval.decode())
+
+
+ def test_bare(self):
+ self.run_one(bare=True, var=self.tmpdir, output=self.tmpdir + "\n")
+
+
+ def test_nonbare(self):
+ self.run_one(bare=False, var=self.tmpdir,
+ output=os.path.join(self.tmpdir, ".git") + "\n")
+
+
+ def test_nonbare_git(self):
+ self.run_one(bare=False, var=os.path.join(self.tmpdir, ".git"),
+ output=os.path.join(self.tmpdir, ".git") + "\n")
+
+
+if __name__ == '__main__':
+ # Run a single testcase
+ suite = unittest.TestLoader().loadTestsFromTestCase(TestLinuxGit)
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/scripts/tests/test_log2.py b/scripts/tests/test_log2.py
index cd5028c6c5..8c592efa19 100755
--- a/scripts/tests/test_log2.py
+++ b/scripts/tests/test_log2.py
@@ -434,6 +434,111 @@ class TestSpliceSeries(unittest.TestCase):
patches.drivers/0
patches.drivers/1
""",),
+ # two new sections
+ (
+""" patches.fixes/0
+
+ # out-of-tree patches
+ patches.suse/0
+ patches.suse/1
+""",
+""" patches.fixes/0
+
+ # davem/net
+ patches.drivers/1
+ patches.drivers/2
+
+ # davem/net-next
+ patches.drivers/3
+ patches.drivers/4
+
+ # out-of-tree patches
+ patches.suse/0
+ patches.suse/1
+""",
+ "patches.drivers/1",
+""" patches.fixes/0
+
+ # davem/net
+ patches.drivers/1
+
+ # out-of-tree patches
+ patches.suse/0
+ patches.suse/1
+""",),
+ # eof in whitespace
+ (
+""" patches.fixes/0
+""",
+""" patches.fixes/0
+
+ # davem/net
+ patches.drivers/1
+ patches.drivers/2
+
+""",
+ "patches.drivers/1",
+""" patches.fixes/0
+
+ # davem/net
+ patches.drivers/1
+
+""",),
+ # two new sections, multi-line whitespace
+ (
+""" patches.fixes/0
+
+ # out-of-tree patches
+ patches.suse/0
+ patches.suse/1
+""",
+""" patches.fixes/0
+
+ # davem/net
+ patches.drivers/1
+ patches.drivers/2
+
+
+ # davem/net-next
+ patches.drivers/3
+ patches.drivers/4
+
+ # out-of-tree patches
+ patches.suse/0
+ patches.suse/1
+""",
+ "patches.drivers/1",
+""" patches.fixes/0
+
+ # davem/net
+ patches.drivers/1
+
+
+ # out-of-tree patches
+ patches.suse/0
+ patches.suse/1
+""",),
+ # two new sections, eof in new
+ (
+""" patches.fixes/0
+""",
+""" patches.fixes/0
+
+ # davem/net
+ patches.drivers/1
+ patches.drivers/2
+
+ # davem/net-next
+ patches.drivers/3
+ patches.drivers/4
+""",
+ "patches.drivers/1",
+""" patches.fixes/0
+
+ # davem/net
+ patches.drivers/1
+
+""",),
)
for i in range(len(vectors)):
diff --git a/scripts/wd-functions.sh b/scripts/wd-functions.sh
index cb36d48969..b5109e171b 100644
--- a/scripts/wd-functions.sh
+++ b/scripts/wd-functions.sh
@@ -72,6 +72,7 @@ _get_tarball_from_git()
{
local version=$1 tag url=$2 default_url
local libdir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
+ local git
git=$("$libdir"/linux_git.sh) || exit 1
case "$version" in
@@ -88,18 +89,18 @@ _get_tarball_from_git()
default_url=git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
esac
[ -z "$url" ] && url=$default_url
- if ! git --git-dir="$git/.git" cat-file -e "$tag" 2>/dev/null; then
+ if ! git --git-dir="$git" cat-file -e "$tag" 2>/dev/null; then
case "$tag" in
refs/tags/*)
- git --git-dir="$git/.git" fetch "$url" "$tag:$tag"
+ git --git-dir="$git" fetch "$url" "$tag:$tag"
;;
*)
# v2.6.X.Y-rcZ-gabcdef1, not a real tag
- git --git-dir="$git/.git" fetch --tags "$url" \
+ git --git-dir="$git" fetch --tags "$url" \
refs/heads/master:refs/tags/latest
esac
fi
- git --git-dir="$git/.git" archive --prefix="linux-$version/" "$tag"
+ git --git-dir="$git" archive --prefix="linux-$version/" "$tag"
}
get_tarball()
diff --git a/series.conf b/series.conf
index fc9cc7177d..491241faaa 100644
--- a/series.conf
+++ b/series.conf
@@ -8777,6 +8777,10 @@
patches.fixes/0001-xfs-toggle-readonly-state-around-xfs_log_mount_finis.patch
patches.fixes/0002-xfs-write-unmount-record-for-ro-mounts.patch
+ patches.suse/xfs-don-t-call-xfs_da_shrink_inode-with-NULL-bp.patch
+ patches.suse/xfs-fix-a-null-pointer-dereference-in-xfs_bmap_exten.patch
+ patches.suse/xfs-validate-cached-inodes-are-free-when-allocated.patch
+
########################################################
# cephfs
########################################################
@@ -11229,6 +11233,7 @@
# bsc#1042422
patches.fixes/xen-hold-lock_device_hotplug-throughout-vcpu-hotplug.patch
+ patches.suse/xen-disable_hotplug_cpu.patch
#bsc#1005745
patches.drivers/0001-efi-runtime-wrappers-Add-__-efi_call_virt-templates.patch
@@ -17084,6 +17089,7 @@
patches.drivers/scsi-ipr-Format-HCAM-overlay-ID-0x41.patch
patches.fixes/0001-fbdev-omapfb-off-by-one-in-omapfb_register_client.patch
patches.fixes/qlge-Fix-netdev-features-configuration.patch
+ patches.drivers/ibmvnic-Include-missing-return-code-checks-in-reset-.patch
# out-of-tree patches
patches.fixes/xfs-repair-malformed-inode-items-during-log-recovery.patch
@@ -24829,6 +24835,15 @@
# nosmt
+ patches.arch/00-jump_label-remove-bug-h-atomic-h-dependencies-for-have_jump_label.patch
+ patches.arch/01-jump_label-reduce-the-size-of-struct-static_key-kabi.patch
+ patches.arch/02-jump_label-reorder-hotplug-lock-and-jump_label_lock.patch
+ patches.arch/03-jump_label-fix-concurrent-static_key_enable-disable.patch
+ patches.arch/04-jump_label-add-release-barrier-after-text-changes.patch
+ patches.arch/05-jump_label-move-cpu-hotplug-locking.patch
+ patches.arch/06-jump_label-split-out-code-under-the-hotplug-lock.patch
+ patches.arch/07-jump_label-provide-hotplug-context-variants.patch
+ patches.arch/08-s390-add-explicit-linux-stringify-h-for-jump-label.patch
patches.arch/01-sched-smt-update-sched_smt_present-at-runtime.patch
patches.arch/02-x86-smp-provide-topology_is_primary_thread.patch
patches.arch/03-x86-topology-provide-topology_smt_supported.patch