--- /dev/null
+From 5e9e38d0db1d29efed1dd4cf9a70115d33521be7 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Mon, 14 Jan 2019 14:07:19 -0800
+Subject: acpi/nfit: Block function zero DSMs
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 5e9e38d0db1d29efed1dd4cf9a70115d33521be7 upstream.
+
+In preparation for using function number 0 as an error value, prevent it
+from being considered a valid function value by acpi_nfit_ctl().
+
+Cc: <stable@vger.kernel.org>
+Cc: stuart hayes <stuart.w.hayes@gmail.com>
+Fixes: e02fb7264d8a ("nfit: add Microsoft NVDIMM DSM command set...")
+Reported-by: Jeff Moyer <jmoyer@redhat.com>
+Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/nfit/core.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -1503,6 +1503,13 @@ static int acpi_nfit_add_dimm(struct acp
+ return 0;
+ }
+
++ /*
++ * Function 0 is the command interrogation function, don't
++ * export it to potential userspace use, and enable it to be
++ * used as an error value in acpi_nfit_ctl().
++ */
++ dsm_mask &= ~1UL;
++
+ guid = to_nfit_uuid(nfit_mem->family);
+ for_each_set_bit(i, &dsm_mask, BITS_PER_LONG)
+ if (acpi_check_dsm(adev_dimm->handle, guid, 1, 1ULL << i))
--- /dev/null
+From 11189c1089da413aa4b5fd6be4c4d47c78968819 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Sat, 19 Jan 2019 10:55:04 -0800
+Subject: acpi/nfit: Fix command-supported detection
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 11189c1089da413aa4b5fd6be4c4d47c78968819 upstream.
+
+The _DSM function number validation only happens to succeed when the
+generic Linux command number translation corresponds with a
+DSM-family-specific function number. This breaks NVDIMM-N
+implementations that correctly implement _LSR, _LSW, and _LSI, but do
+not happen to publish support for DSM function numbers 4, 5, and 6.
+
+Recall that the support for _LS{I,R,W} family of methods results in the
+DIMM being marked as supporting those command numbers at
+acpi_nfit_register_dimms() time. The DSM function mask is only used for
+ND_CMD_CALL support of non-NVDIMM_FAMILY_INTEL devices.
+
+Fixes: 31eca76ba2fc ("nfit, libnvdimm: limited/whitelisted dimm command...")
+Cc: <stable@vger.kernel.org>
+Link: https://github.com/pmem/ndctl/issues/78
+Reported-by: Sujith Pandel <sujith_pandel@dell.com>
+Tested-by: Sujith Pandel <sujith_pandel@dell.com>
+Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
+Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/nfit/core.c | 54 ++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 40 insertions(+), 14 deletions(-)
+
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -208,6 +208,32 @@ static int xlat_status(struct nvdimm *nv
+ return xlat_nvdimm_status(buf, cmd, status);
+ }
+
++static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
++ struct nd_cmd_pkg *call_pkg)
++{
++ if (call_pkg) {
++ int i;
++
++ if (nfit_mem->family != call_pkg->nd_family)
++ return -ENOTTY;
++
++ for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
++ if (call_pkg->nd_reserved2[i])
++ return -EINVAL;
++ return call_pkg->nd_command;
++ }
++
++ /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
++ if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
++ return cmd;
++
++ /*
++ * Force function number validation to fail since 0 is never
++ * published as a valid function in dsm_mask.
++ */
++ return 0;
++}
++
+ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
+ unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc)
+ {
+@@ -220,21 +246,11 @@ int acpi_nfit_ctl(struct nvdimm_bus_desc
+ unsigned long cmd_mask, dsm_mask;
+ u32 offset, fw_status = 0;
+ acpi_handle handle;
+- unsigned int func;
+ const guid_t *guid;
+- int rc, i;
++ int func, rc, i;
+
+ if (cmd_rc)
+ *cmd_rc = -EINVAL;
+- func = cmd;
+- if (cmd == ND_CMD_CALL) {
+- call_pkg = buf;
+- func = call_pkg->nd_command;
+-
+- for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
+- if (call_pkg->nd_reserved2[i])
+- return -EINVAL;
+- }
+
+ if (nvdimm) {
+ struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
+@@ -242,9 +258,12 @@ int acpi_nfit_ctl(struct nvdimm_bus_desc
+
+ if (!adev)
+ return -ENOTTY;
+- if (call_pkg && nfit_mem->family != call_pkg->nd_family)
+- return -ENOTTY;
+
++ if (cmd == ND_CMD_CALL)
++ call_pkg = buf;
++ func = cmd_to_func(nfit_mem, cmd, call_pkg);
++ if (func < 0)
++ return func;
+ dimm_name = nvdimm_name(nvdimm);
+ cmd_name = nvdimm_cmd_name(cmd);
+ cmd_mask = nvdimm_cmd_mask(nvdimm);
+@@ -255,6 +274,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_desc
+ } else {
+ struct acpi_device *adev = to_acpi_dev(acpi_desc);
+
++ func = cmd;
+ cmd_name = nvdimm_bus_cmd_name(cmd);
+ cmd_mask = nd_desc->cmd_mask;
+ dsm_mask = cmd_mask;
+@@ -269,7 +289,13 @@ int acpi_nfit_ctl(struct nvdimm_bus_desc
+ if (!desc || (cmd && (desc->out_num + desc->in_num == 0)))
+ return -ENOTTY;
+
+- if (!test_bit(cmd, &cmd_mask) || !test_bit(func, &dsm_mask))
++ /*
++ * Check for a valid command. For ND_CMD_CALL, we also have to
++ * make sure that the DSM function is supported.
++ */
++ if (cmd == ND_CMD_CALL && !test_bit(func, &dsm_mask))
++ return -ENOTTY;
++ else if (!test_bit(cmd, &cmd_mask))
+ return -ENOTTY;
+
+ in_obj.type = ACPI_TYPE_PACKAGE;
--- /dev/null
+From f0907827a8a9152aedac2833ed1b674a7b2a44f2 Mon Sep 17 00:00:00 2001
+From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Date: Tue, 8 May 2018 00:36:27 +0200
+Subject: compiler.h: enable builtin overflow checkers and add fallback code
+
+From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+
+commit f0907827a8a9152aedac2833ed1b674a7b2a44f2 upstream.
+
+This adds wrappers for the __builtin overflow checkers present in gcc
+5.1+ as well as fallback implementations for earlier compilers. It's not
+that easy to implement the fully generic __builtin_X_overflow(T1 a, T2
+b, T3 *d) in macros, so the fallback code assumes that T1, T2 and T3 are
+the same. We obviously don't want the wrappers to have different
+semantics depending on $GCC_VERSION, so we also insist on that even when
+using the builtins.
+
+There are a few problems with the 'a+b < a' idiom for checking for
+overflow: For signed types, it relies on undefined behaviour and is
+not actually complete (it doesn't check underflow;
+e.g. INT_MIN+INT_MIN == 0 isn't caught). Due to type promotion it
+is wrong for all types (signed and unsigned) narrower than
+int. Similarly, when a and b does not have the same type, there are
+subtle cases like
+
+ u32 a;
+
+ if (a + sizeof(foo) < a)
+ return -EOVERFLOW;
+ a += sizeof(foo);
+
+where the test is always false on 64 bit platforms. Add to that that it
+is not always possible to determine the types involved at a glance.
+
+The new overflow.h is somewhat bulky, but that's mostly a result of
+trying to be type-generic, complete (e.g. catching not only overflow
+but also signed underflow) and not relying on undefined behaviour.
+
+Linus is of course right [1] that for unsigned subtraction a-b, the
+right way to check for overflow (underflow) is "b > a" and not
+"__builtin_sub_overflow(a, b, &d)", but that's just one out of six cases
+covered here, and included mostly for completeness.
+
+So is it worth it? I think it is, if nothing else for the documentation
+value of seeing
+
+ if (check_add_overflow(a, b, &d))
+ return -EGOAWAY;
+ do_stuff_with(d);
+
+instead of the open-coded (and possibly wrong and/or incomplete and/or
+UBsan-tickling)
+
+ if (a+b < a)
+ return -EGOAWAY;
+ do_stuff_with(a+b);
+
+While gcc does recognize the 'a+b < a' idiom for testing unsigned add
+overflow, it doesn't do nearly as good for unsigned multiplication
+(there's also no single well-established idiom). So using
+check_mul_overflow in kcalloc and friends may also make gcc generate
+slightly better code.
+
+[1] https://lkml.org/lkml/2015/11/2/658
+
+Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/compiler-clang.h | 14 ++
+ include/linux/compiler-gcc.h | 4
+ include/linux/compiler-intel.h | 4
+ include/linux/overflow.h | 205 +++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 227 insertions(+)
+
+--- a/include/linux/compiler-clang.h
++++ b/include/linux/compiler-clang.h
+@@ -24,3 +24,17 @@
+ #ifdef __noretpoline
+ #undef __noretpoline
+ #endif
++
++/*
++ * Not all versions of clang implement the the type-generic versions
++ * of the builtin overflow checkers. Fortunately, clang implements
++ * __has_builtin allowing us to avoid awkward version
++ * checks. Unfortunately, we don't know which version of gcc clang
++ * pretends to be, so the macro may or may not be defined.
++ */
++#undef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
++#if __has_builtin(__builtin_mul_overflow) && \
++ __has_builtin(__builtin_add_overflow) && \
++ __has_builtin(__builtin_sub_overflow)
++#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
++#endif
+--- a/include/linux/compiler-gcc.h
++++ b/include/linux/compiler-gcc.h
+@@ -358,3 +358,7 @@
+ * code
+ */
+ #define uninitialized_var(x) x = x
++
++#if GCC_VERSION >= 50100
++#define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
++#endif
+--- a/include/linux/compiler-intel.h
++++ b/include/linux/compiler-intel.h
+@@ -44,3 +44,7 @@
+ #define __builtin_bswap16 _bswap16
+ #endif
+
++/*
++ * icc defines __GNUC__, but does not implement the builtin overflow checkers.
++ */
++#undef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
+--- /dev/null
++++ b/include/linux/overflow.h
+@@ -0,0 +1,205 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++#ifndef __LINUX_OVERFLOW_H
++#define __LINUX_OVERFLOW_H
++
++#include <linux/compiler.h>
++
++/*
++ * In the fallback code below, we need to compute the minimum and
++ * maximum values representable in a given type. These macros may also
++ * be useful elsewhere, so we provide them outside the
++ * COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW block.
++ *
++ * It would seem more obvious to do something like
++ *
++ * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0)
++ * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0)
++ *
++ * Unfortunately, the middle expressions, strictly speaking, have
++ * undefined behaviour, and at least some versions of gcc warn about
++ * the type_max expression (but not if -fsanitize=undefined is in
++ * effect; in that case, the warning is deferred to runtime...).
++ *
++ * The slightly excessive casting in type_min is to make sure the
++ * macros also produce sensible values for the exotic type _Bool. [The
++ * overflow checkers only almost work for _Bool, but that's
++ * a-feature-not-a-bug, since people shouldn't be doing arithmetic on
++ * _Bools. Besides, the gcc builtins don't allow _Bool* as third
++ * argument.]
++ *
++ * Idea stolen from
++ * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html -
++ * credit to Christian Biere.
++ */
++#define is_signed_type(type) (((type)(-1)) < (type)1)
++#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
++#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
++#define type_min(T) ((T)((T)-type_max(T)-(T)1))
++
++
++#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
++/*
++ * For simplicity and code hygiene, the fallback code below insists on
++ * a, b and *d having the same type (similar to the min() and max()
++ * macros), whereas gcc's type-generic overflow checkers accept
++ * different types. Hence we don't just make check_add_overflow an
++ * alias for __builtin_add_overflow, but add type checks similar to
++ * below.
++ */
++#define check_add_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ __builtin_add_overflow(__a, __b, __d); \
++})
++
++#define check_sub_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ __builtin_sub_overflow(__a, __b, __d); \
++})
++
++#define check_mul_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ __builtin_mul_overflow(__a, __b, __d); \
++})
++
++#else
++
++
++/* Checking for unsigned overflow is relatively easy without causing UB. */
++#define __unsigned_add_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ *__d = __a + __b; \
++ *__d < __a; \
++})
++#define __unsigned_sub_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ *__d = __a - __b; \
++ __a < __b; \
++})
++/*
++ * If one of a or b is a compile-time constant, this avoids a division.
++ */
++#define __unsigned_mul_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ *__d = __a * __b; \
++ __builtin_constant_p(__b) ? \
++ __b > 0 && __a > type_max(typeof(__a)) / __b : \
++ __a > 0 && __b > type_max(typeof(__b)) / __a; \
++})
++
++/*
++ * For signed types, detecting overflow is much harder, especially if
++ * we want to avoid UB. But the interface of these macros is such that
++ * we must provide a result in *d, and in fact we must produce the
++ * result promised by gcc's builtins, which is simply the possibly
++ * wrapped-around value. Fortunately, we can just formally do the
++ * operations in the widest relevant unsigned type (u64) and then
++ * truncate the result - gcc is smart enough to generate the same code
++ * with and without the (u64) casts.
++ */
++
++/*
++ * Adding two signed integers can overflow only if they have the same
++ * sign, and overflow has happened iff the result has the opposite
++ * sign.
++ */
++#define __signed_add_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ *__d = (u64)__a + (u64)__b; \
++ (((~(__a ^ __b)) & (*__d ^ __a)) \
++ & type_min(typeof(__a))) != 0; \
++})
++
++/*
++ * Subtraction is similar, except that overflow can now happen only
++ * when the signs are opposite. In this case, overflow has happened if
++ * the result has the opposite sign of a.
++ */
++#define __signed_sub_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ *__d = (u64)__a - (u64)__b; \
++ ((((__a ^ __b)) & (*__d ^ __a)) \
++ & type_min(typeof(__a))) != 0; \
++})
++
++/*
++ * Signed multiplication is rather hard. gcc always follows C99, so
++ * division is truncated towards 0. This means that we can write the
++ * overflow check like this:
++ *
++ * (a > 0 && (b > MAX/a || b < MIN/a)) ||
++ * (a < -1 && (b > MIN/a || b < MAX/a) ||
++ * (a == -1 && b == MIN)
++ *
++ * The redundant casts of -1 are to silence an annoying -Wtype-limits
++ * (included in -Wextra) warning: When the type is u8 or u16, the
++ * __b_c_e in check_mul_overflow obviously selects
++ * __unsigned_mul_overflow, but unfortunately gcc still parses this
++ * code and warns about the limited range of __b.
++ */
++
++#define __signed_mul_overflow(a, b, d) ({ \
++ typeof(a) __a = (a); \
++ typeof(b) __b = (b); \
++ typeof(d) __d = (d); \
++ typeof(a) __tmax = type_max(typeof(a)); \
++ typeof(a) __tmin = type_min(typeof(a)); \
++ (void) (&__a == &__b); \
++ (void) (&__a == __d); \
++ *__d = (u64)__a * (u64)__b; \
++ (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \
++ (__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \
++ (__b == (typeof(__b))-1 && __a == __tmin); \
++})
++
++
++#define check_add_overflow(a, b, d) \
++ __builtin_choose_expr(is_signed_type(typeof(a)), \
++ __signed_add_overflow(a, b, d), \
++ __unsigned_add_overflow(a, b, d))
++
++#define check_sub_overflow(a, b, d) \
++ __builtin_choose_expr(is_signed_type(typeof(a)), \
++ __signed_sub_overflow(a, b, d), \
++ __unsigned_sub_overflow(a, b, d))
++
++#define check_mul_overflow(a, b, d) \
++ __builtin_choose_expr(is_signed_type(typeof(a)), \
++ __signed_mul_overflow(a, b, d), \
++ __unsigned_mul_overflow(a, b, d))
++
++
++#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
++
++#endif /* __LINUX_OVERFLOW_H */
--- /dev/null
+From 1856b9f7bcc8e9bdcccc360aabb56fbd4dd6c565 Mon Sep 17 00:00:00 2001
+From: Milan Broz <gmazyland@gmail.com>
+Date: Wed, 9 Jan 2019 11:57:14 +0100
+Subject: dm crypt: fix parsing of extended IV arguments
+
+From: Milan Broz <gmazyland@gmail.com>
+
+commit 1856b9f7bcc8e9bdcccc360aabb56fbd4dd6c565 upstream.
+
+The dm-crypt cipher specification in a mapping table is defined as:
+ cipher[:keycount]-chainmode-ivmode[:ivopts]
+or (new crypt API format):
+ capi:cipher_api_spec-ivmode[:ivopts]
+
+For ESSIV, the parameter includes hash specification, for example:
+aes-cbc-essiv:sha256
+
+The implementation expected that additional IV option to never include
+another dash '-' character.
+
+But, with SHA3, there are names like sha3-256; so the mapping table
+parser fails:
+
+dmsetup create test --table "0 8 crypt aes-cbc-essiv:sha3-256 9c1185a5c5e9fc54612808977ee8f5b9e 0 /dev/sdb 0"
+ or (new crypt API format)
+dmsetup create test --table "0 8 crypt capi:cbc(aes)-essiv:sha3-256 9c1185a5c5e9fc54612808977ee8f5b9e 0 /dev/sdb 0"
+
+ device-mapper: crypt: Ignoring unexpected additional cipher options
+ device-mapper: table: 253:0: crypt: Error creating IV
+ device-mapper: ioctl: error adding target to table
+
+Fix the dm-crypt constructor to ignore additional dash in IV options and
+also remove a bogus warning (that is ignored anyway).
+
+Cc: stable@vger.kernel.org # 4.12+
+Signed-off-by: Milan Broz <gmazyland@gmail.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-crypt.c | 25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -2413,9 +2413,21 @@ static int crypt_ctr_cipher_new(struct d
+ * capi:cipher_api_spec-iv:ivopts
+ */
+ tmp = &cipher_in[strlen("capi:")];
+- cipher_api = strsep(&tmp, "-");
+- *ivmode = strsep(&tmp, ":");
+- *ivopts = tmp;
++
++ /* Separate IV options if present, it can contain another '-' in hash name */
++ *ivopts = strrchr(tmp, ':');
++ if (*ivopts) {
++ **ivopts = '\0';
++ (*ivopts)++;
++ }
++ /* Parse IV mode */
++ *ivmode = strrchr(tmp, '-');
++ if (*ivmode) {
++ **ivmode = '\0';
++ (*ivmode)++;
++ }
++ /* The rest is crypto API spec */
++ cipher_api = tmp;
+
+ if (*ivmode && !strcmp(*ivmode, "lmk"))
+ cc->tfms_count = 64;
+@@ -2485,11 +2497,8 @@ static int crypt_ctr_cipher_old(struct d
+ goto bad_mem;
+
+ chainmode = strsep(&tmp, "-");
+- *ivopts = strsep(&tmp, "-");
+- *ivmode = strsep(&*ivopts, ":");
+-
+- if (tmp)
+- DMWARN("Ignoring unexpected additional cipher options");
++ *ivmode = strsep(&tmp, ":");
++ *ivopts = tmp;
+
+ /*
+ * For compatibility with the original dm-crypt mapping format, if
--- /dev/null
+From d445bd9cec1a850c2100fcf53684c13b3fd934f2 Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Tue, 15 Jan 2019 13:27:01 -0500
+Subject: dm thin: fix passdown_double_checking_shared_status()
+
+From: Joe Thornber <ejt@redhat.com>
+
+commit d445bd9cec1a850c2100fcf53684c13b3fd934f2 upstream.
+
+Commit 00a0ea33b495 ("dm thin: do not queue freed thin mapping for next
+stage processing") changed process_prepared_discard_passdown_pt1() to
+increment all the blocks being discarded until after the passdown had
+completed to avoid them being prematurely reused.
+
+IO issued to a thin device that breaks sharing with a snapshot, followed
+by a discard issued to snapshot(s) that previously shared the block(s),
+results in passdown_double_checking_shared_status() being called to
+iterate through the blocks double checking their reference count is zero
+and issuing the passdown if so. So a side effect of commit 00a0ea33b495
+is passdown_double_checking_shared_status() was broken.
+
+Fix this by checking if the block reference count is greater than 1.
+Also, rename dm_pool_block_is_used() to dm_pool_block_is_shared().
+
+Fixes: 00a0ea33b495 ("dm thin: do not queue freed thin mapping for next stage processing")
+Cc: stable@vger.kernel.org # 4.9+
+Reported-by: ryan.p.norwood@gmail.com
+Signed-off-by: Joe Thornber <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-thin-metadata.c | 4 ++--
+ drivers/md/dm-thin-metadata.h | 2 +-
+ drivers/md/dm-thin.c | 10 +++++-----
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/md/dm-thin-metadata.c
++++ b/drivers/md/dm-thin-metadata.c
+@@ -1687,7 +1687,7 @@ int dm_thin_remove_range(struct dm_thin_
+ return r;
+ }
+
+-int dm_pool_block_is_used(struct dm_pool_metadata *pmd, dm_block_t b, bool *result)
++int dm_pool_block_is_shared(struct dm_pool_metadata *pmd, dm_block_t b, bool *result)
+ {
+ int r;
+ uint32_t ref_count;
+@@ -1695,7 +1695,7 @@ int dm_pool_block_is_used(struct dm_pool
+ down_read(&pmd->root_lock);
+ r = dm_sm_get_count(pmd->data_sm, b, &ref_count);
+ if (!r)
+- *result = (ref_count != 0);
++ *result = (ref_count > 1);
+ up_read(&pmd->root_lock);
+
+ return r;
+--- a/drivers/md/dm-thin-metadata.h
++++ b/drivers/md/dm-thin-metadata.h
+@@ -195,7 +195,7 @@ int dm_pool_get_metadata_dev_size(struct
+
+ int dm_pool_get_data_dev_size(struct dm_pool_metadata *pmd, dm_block_t *result);
+
+-int dm_pool_block_is_used(struct dm_pool_metadata *pmd, dm_block_t b, bool *result);
++int dm_pool_block_is_shared(struct dm_pool_metadata *pmd, dm_block_t b, bool *result);
+
+ int dm_pool_inc_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_t e);
+ int dm_pool_dec_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_t e);
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -1042,7 +1042,7 @@ static void passdown_double_checking_sha
+ * passdown we have to check that these blocks are now unused.
+ */
+ int r = 0;
+- bool used = true;
++ bool shared = true;
+ struct thin_c *tc = m->tc;
+ struct pool *pool = tc->pool;
+ dm_block_t b = m->data_block, e, end = m->data_block + m->virt_end - m->virt_begin;
+@@ -1052,11 +1052,11 @@ static void passdown_double_checking_sha
+ while (b != end) {
+ /* find start of unmapped run */
+ for (; b < end; b++) {
+- r = dm_pool_block_is_used(pool->pmd, b, &used);
++ r = dm_pool_block_is_shared(pool->pmd, b, &shared);
+ if (r)
+ goto out;
+
+- if (!used)
++ if (!shared)
+ break;
+ }
+
+@@ -1065,11 +1065,11 @@ static void passdown_double_checking_sha
+
+ /* find end of run */
+ for (e = b + 1; e != end; e++) {
+- r = dm_pool_block_is_used(pool->pmd, e, &used);
++ r = dm_pool_block_is_shared(pool->pmd, e, &shared);
+ if (r)
+ goto out;
+
+- if (used)
++ if (shared)
+ break;
+ }
+
--- /dev/null
+From d77651a227f8920dd7ec179b84e400cce844eeb3 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 14 Jan 2019 13:54:55 -0800
+Subject: Input: uinput - fix undefined behavior in uinput_validate_absinfo()
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit d77651a227f8920dd7ec179b84e400cce844eeb3 upstream.
+
+An integer overflow may arise in uinput_validate_absinfo() if "max - min"
+can't be represented by an "int". We should check for overflow before
+trying to use the result.
+
+Reported-by: Kyungtae Kim <kt0755@gmail.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/misc/uinput.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/input/misc/uinput.c
++++ b/drivers/input/misc/uinput.c
+@@ -39,6 +39,7 @@
+ #include <linux/fs.h>
+ #include <linux/miscdevice.h>
+ #include <linux/uinput.h>
++#include <linux/overflow.h>
+ #include <linux/input/mt.h>
+ #include "../input-compat.h"
+
+@@ -356,7 +357,7 @@ static int uinput_open(struct inode *ino
+ static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code,
+ const struct input_absinfo *abs)
+ {
+- int min, max;
++ int min, max, range;
+
+ min = abs->minimum;
+ max = abs->maximum;
+@@ -368,7 +369,7 @@ static int uinput_validate_absinfo(struc
+ return -EINVAL;
+ }
+
+- if (abs->flat > max - min) {
++ if (!check_sub_overflow(max, min, &range) && abs->flat > range) {
+ printk(KERN_DEBUG
+ "%s: abs_flat #%02x out of range: %d (min:%d/max:%d)\n",
+ UINPUT_NAME, code, abs->flat, min, max);
--- /dev/null
+From fe2bfd0d40c935763812973ce15f5764f1c12833 Mon Sep 17 00:00:00 2001
+From: Tom Panfil <tom@steelseries.com>
+Date: Fri, 11 Jan 2019 17:49:40 -0800
+Subject: Input: xpad - add support for SteelSeries Stratus Duo
+
+From: Tom Panfil <tom@steelseries.com>
+
+commit fe2bfd0d40c935763812973ce15f5764f1c12833 upstream.
+
+Add support for the SteelSeries Stratus Duo, a wireless Xbox 360
+controller. The Stratus Duo ships with a USB dongle to enable wireless
+connectivity, but it can also function as a wired controller by connecting
+it directly to a PC via USB, hence the need for two USD PIDs. 0x1430 is the
+dongle, and 0x1431 is the controller.
+
+Signed-off-by: Tom Panfil <tom@steelseries.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/joystick/xpad.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -255,6 +255,8 @@ static const struct xpad_device {
+ { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
+ { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
+ { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX },
++ { 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
++ { 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
+ { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 },
+ { 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x12ab, 0x0301, "PDP AFTERGLOW AX.1", 0, XTYPE_XBOX360 },
+@@ -431,6 +433,7 @@ static const struct usb_device_id xpad_t
+ XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */
+ XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
+ XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */
++ XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries Controllers */
+ XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */
+ XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */
+ XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
--- /dev/null
+From 5cc244a20b86090c087073c124284381cdf47234 Mon Sep 17 00:00:00 2001
+From: Alexander Popov <alex.popov@linux.com>
+Date: Mon, 21 Jan 2019 15:48:40 +0300
+Subject: KVM: x86: Fix single-step debugging
+
+From: Alexander Popov <alex.popov@linux.com>
+
+commit 5cc244a20b86090c087073c124284381cdf47234 upstream.
+
+The single-step debugging of KVM guests on x86 is broken: if we run
+gdb 'stepi' command at the breakpoint when the guest interrupts are
+enabled, RIP always jumps to native_apic_mem_write(). Then other
+nasty effects follow.
+
+Long investigation showed that on Jun 7, 2017 the
+commit c8401dda2f0a00cd25c0 ("KVM: x86: fix singlestepping over syscall")
+introduced the kvm_run.debug corruption: kvm_vcpu_do_singlestep() can
+be called without X86_EFLAGS_TF set.
+
+Let's fix it. Please consider that for -stable.
+
+Signed-off-by: Alexander Popov <alex.popov@linux.com>
+Cc: stable@vger.kernel.org
+Fixes: c8401dda2f0a00cd25c0 ("KVM: x86: fix singlestepping over syscall")
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/x86.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -5923,8 +5923,7 @@ restart:
+ toggle_interruptibility(vcpu, ctxt->interruptibility);
+ vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
+ kvm_rip_write(vcpu, ctxt->eip);
+- if (r == EMULATE_DONE &&
+- (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
++ if (r == EMULATE_DONE && ctxt->tf)
+ kvm_vcpu_do_singlestep(vcpu, &r);
+ if (!ctxt->have_exception ||
+ exception_type(ctxt->exception.vector) == EXCPT_TRAP)
cifs-fix-credits-calculations-for-reads-with-errors.patch
cifs-fix-credit-calculation-for-encrypted-reads-with-errors.patch
cifs-do-not-reconnect-tcp-session-in-add_credits.patch
+input-xpad-add-support-for-steelseries-stratus-duo.patch
+compiler.h-enable-builtin-overflow-checkers-and-add-fallback-code.patch
+input-uinput-fix-undefined-behavior-in-uinput_validate_absinfo.patch
+acpi-nfit-block-function-zero-dsms.patch
+acpi-nfit-fix-command-supported-detection.patch
+dm-thin-fix-passdown_double_checking_shared_status.patch
+dm-crypt-fix-parsing-of-extended-iv-arguments.patch
+kvm-x86-fix-single-step-debugging.patch
+x86-pkeys-properly-copy-pkey-state-at-fork.patch
+x86-selftests-pkeys-fork-to-check-for-state-being-preserved.patch
+x86-kaslr-fix-incorrect-i8254-outb-parameters.patch
--- /dev/null
+From 7e6fc2f50a3197d0e82d1c0e86282976c9e6c8a4 Mon Sep 17 00:00:00 2001
+From: Daniel Drake <drake@endlessm.com>
+Date: Mon, 7 Jan 2019 11:40:24 +0800
+Subject: x86/kaslr: Fix incorrect i8254 outb() parameters
+
+From: Daniel Drake <drake@endlessm.com>
+
+commit 7e6fc2f50a3197d0e82d1c0e86282976c9e6c8a4 upstream.
+
+The outb() function takes parameters value and port, in that order. Fix
+the parameters used in the kalsr i8254 fallback code.
+
+Fixes: 5bfce5ef55cb ("x86, kaslr: Provide randomness functions")
+Signed-off-by: Daniel Drake <drake@endlessm.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: bp@alien8.de
+Cc: hpa@zytor.com
+Cc: linux@endlessm.com
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20190107034024.15005-1-drake@endlessm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/lib/kaslr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/lib/kaslr.c
++++ b/arch/x86/lib/kaslr.c
+@@ -36,8 +36,8 @@ static inline u16 i8254(void)
+ u16 status, timer;
+
+ do {
+- outb(I8254_PORT_CONTROL,
+- I8254_CMD_READBACK | I8254_SELECT_COUNTER0);
++ outb(I8254_CMD_READBACK | I8254_SELECT_COUNTER0,
++ I8254_PORT_CONTROL);
+ status = inb(I8254_PORT_COUNTER0);
+ timer = inb(I8254_PORT_COUNTER0);
+ timer |= inb(I8254_PORT_COUNTER0) << 8;
--- /dev/null
+From a31e184e4f69965c99c04cc5eb8a4920e0c63737 Mon Sep 17 00:00:00 2001
+From: Dave Hansen <dave.hansen@linux.intel.com>
+Date: Wed, 2 Jan 2019 13:56:55 -0800
+Subject: x86/pkeys: Properly copy pkey state at fork()
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+commit a31e184e4f69965c99c04cc5eb8a4920e0c63737 upstream.
+
+Memory protection key behavior should be the same in a child as it was
+in the parent before a fork. But, there is a bug that resets the
+state in the child at fork instead of preserving it.
+
+The creation of new mm's is a bit convoluted. At fork(), the code
+does:
+
+ 1. memcpy() the parent mm to initialize child
+ 2. mm_init() to initalize some select stuff stuff
+ 3. dup_mmap() to create true copies that memcpy() did not do right
+
+For pkeys two bits of state need to be preserved across a fork:
+'execute_only_pkey' and 'pkey_allocation_map'.
+
+Those are preserved by the memcpy(), but mm_init() invokes
+init_new_context() which overwrites 'execute_only_pkey' and
+'pkey_allocation_map' with "new" values.
+
+The author of the code erroneously believed that init_new_context is *only*
+called at execve()-time. But, alas, init_new_context() is used at execve()
+and fork().
+
+The result is that, after a fork(), the child's pkey state ends up looking
+like it does after an execve(), which is totally wrong. pkeys that are
+already allocated can be allocated again, for instance.
+
+To fix this, add code called by dup_mmap() to copy the pkey state from
+parent to child explicitly. Also add a comment above init_new_context() to
+make it more clear to the next poor sod what this code is used for.
+
+Fixes: e8c24d3a23a ("x86/pkeys: Allocation/free syscalls")
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: bp@alien8.de
+Cc: hpa@zytor.com
+Cc: peterz@infradead.org
+Cc: mpe@ellerman.id.au
+Cc: will.deacon@arm.com
+Cc: luto@kernel.org
+Cc: jroedel@suse.de
+Cc: stable@vger.kernel.org
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Will Deacon <will.deacon@arm.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Joerg Roedel <jroedel@suse.de>
+Link: https://lkml.kernel.org/r/20190102215655.7A69518C@viggo.jf.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/mmu_context.h | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/arch/x86/include/asm/mmu_context.h
++++ b/arch/x86/include/asm/mmu_context.h
+@@ -182,6 +182,10 @@ static inline void switch_ldt(struct mm_
+
+ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk);
+
++/*
++ * Init a new mm. Used on mm copies, like at fork()
++ * and on mm's that are brand-new, like at execve().
++ */
+ static inline int init_new_context(struct task_struct *tsk,
+ struct mm_struct *mm)
+ {
+@@ -232,8 +236,22 @@ do { \
+ } while (0)
+ #endif
+
++static inline void arch_dup_pkeys(struct mm_struct *oldmm,
++ struct mm_struct *mm)
++{
++#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
++ if (!cpu_feature_enabled(X86_FEATURE_OSPKE))
++ return;
++
++ /* Duplicate the oldmm pkey state in mm: */
++ mm->context.pkey_allocation_map = oldmm->context.pkey_allocation_map;
++ mm->context.execute_only_pkey = oldmm->context.execute_only_pkey;
++#endif
++}
++
+ static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
+ {
++ arch_dup_pkeys(oldmm, mm);
+ paravirt_arch_dup_mmap(oldmm, mm);
+ return ldt_dup_context(oldmm, mm);
+ }
--- /dev/null
+From e1812933b17be7814f51b6c310c5d1ced7a9a5f5 Mon Sep 17 00:00:00 2001
+From: Dave Hansen <dave.hansen@linux.intel.com>
+Date: Wed, 2 Jan 2019 13:56:57 -0800
+Subject: x86/selftests/pkeys: Fork() to check for state being preserved
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+commit e1812933b17be7814f51b6c310c5d1ced7a9a5f5 upstream.
+
+There was a bug where the per-mm pkey state was not being preserved across
+fork() in the child. fork() is performed in the pkey selftests, but all of
+the pkey activity is performed in the parent. The child does not perform
+any actions sensitive to pkey state.
+
+To make the test more sensitive to these kinds of bugs, add a fork() where
+the parent exits, and execution continues in the child.
+
+To achieve this let the key exhaustion test not terminate at the first
+allocation failure and fork after 2*NR_PKEYS loops and continue in the
+child.
+
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: bp@alien8.de
+Cc: hpa@zytor.com
+Cc: peterz@infradead.org
+Cc: mpe@ellerman.id.au
+Cc: will.deacon@arm.com
+Cc: luto@kernel.org
+Cc: jroedel@suse.de
+Cc: stable@vger.kernel.org
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Will Deacon <will.deacon@arm.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Joerg Roedel <jroedel@suse.de>
+Link: https://lkml.kernel.org/r/20190102215657.585704B7@viggo.jf.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/testing/selftests/x86/protection_keys.c | 41 +++++++++++++++++++-------
+ 1 file changed, 31 insertions(+), 10 deletions(-)
+
+--- a/tools/testing/selftests/x86/protection_keys.c
++++ b/tools/testing/selftests/x86/protection_keys.c
+@@ -1133,6 +1133,21 @@ void test_pkey_syscalls_bad_args(int *pt
+ pkey_assert(err);
+ }
+
++void become_child(void)
++{
++ pid_t forkret;
++
++ forkret = fork();
++ pkey_assert(forkret >= 0);
++ dprintf3("[%d] fork() ret: %d\n", getpid(), forkret);
++
++ if (!forkret) {
++ /* in the child */
++ return;
++ }
++ exit(0);
++}
++
+ /* Assumes that all pkeys other than 'pkey' are unallocated */
+ void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
+ {
+@@ -1141,7 +1156,7 @@ void test_pkey_alloc_exhaust(int *ptr, u
+ int nr_allocated_pkeys = 0;
+ int i;
+
+- for (i = 0; i < NR_PKEYS*2; i++) {
++ for (i = 0; i < NR_PKEYS*3; i++) {
+ int new_pkey;
+ dprintf1("%s() alloc loop: %d\n", __func__, i);
+ new_pkey = alloc_pkey();
+@@ -1152,21 +1167,27 @@ void test_pkey_alloc_exhaust(int *ptr, u
+ if ((new_pkey == -1) && (errno == ENOSPC)) {
+ dprintf2("%s() failed to allocate pkey after %d tries\n",
+ __func__, nr_allocated_pkeys);
+- break;
++ } else {
++ /*
++ * Ensure the number of successes never
++ * exceeds the number of keys supported
++ * in the hardware.
++ */
++ pkey_assert(nr_allocated_pkeys < NR_PKEYS);
++ allocated_pkeys[nr_allocated_pkeys++] = new_pkey;
+ }
+- pkey_assert(nr_allocated_pkeys < NR_PKEYS);
+- allocated_pkeys[nr_allocated_pkeys++] = new_pkey;
++
++ /*
++ * Make sure that allocation state is properly
++ * preserved across fork().
++ */
++ if (i == NR_PKEYS*2)
++ become_child();
+ }
+
+ dprintf3("%s()::%d\n", __func__, __LINE__);
+
+ /*
+- * ensure it did not reach the end of the loop without
+- * failure:
+- */
+- pkey_assert(i < NR_PKEYS*2);
+-
+- /*
+ * There are 16 pkeys supported in hardware. Three are
+ * allocated by the time we get here:
+ * 1. The default key (0)