From 8b761400499b4a1d192809e68bcf9e0ba5cf4fb3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 3 May 2018 11:23:25 -0700 Subject: [PATCH] 4.9-stable patches added patches: arm-arm64-kvm-add-psci-version-selection-api.patch crypto-talitos-fix-ipsec-cipher-in-length.patch --- ...4-kvm-add-psci-version-selection-api.patch | 367 ++++++++++++++++++ ...o-talitos-fix-ipsec-cipher-in-length.patch | 116 ++++++ queue-4.9/series | 2 + 3 files changed, 485 insertions(+) create mode 100644 queue-4.9/arm-arm64-kvm-add-psci-version-selection-api.patch create mode 100644 queue-4.9/crypto-talitos-fix-ipsec-cipher-in-length.patch diff --git a/queue-4.9/arm-arm64-kvm-add-psci-version-selection-api.patch b/queue-4.9/arm-arm64-kvm-add-psci-version-selection-api.patch new file mode 100644 index 00000000000..c725af9f536 --- /dev/null +++ b/queue-4.9/arm-arm64-kvm-add-psci-version-selection-api.patch @@ -0,0 +1,367 @@ +From 85bd0ba1ff9875798fad94218b627ea9f768f3c3 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Sun, 21 Jan 2018 16:42:56 +0000 +Subject: arm/arm64: KVM: Add PSCI version selection API + +From: Marc Zyngier + +commit 85bd0ba1ff9875798fad94218b627ea9f768f3c3 upstream. + +Although we've implemented PSCI 0.1, 0.2 and 1.0, we expose either 0.1 +or 1.0 to a guest, defaulting to the latest version of the PSCI +implementation that is compatible with the requested version. This is +no different from doing a firmware upgrade on KVM. + +But in order to give a chance to hypothetical badly implemented guests +that would have a fit by discovering something other than PSCI 0.2, +let's provide a new API that allows userspace to pick one particular +version of the API. + +This is implemented as a new class of "firmware" registers, where +we expose the PSCI version. This allows the PSCI version to be +save/restored as part of a guest migration, and also set to +any supported version if the guest requires it. + +Cc: stable@vger.kernel.org #4.16 +Reviewed-by: Christoffer Dall +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/virtual/kvm/api.txt | 9 ++++ + Documentation/virtual/kvm/arm/psci.txt | 30 ++++++++++++++++ + arch/arm/include/asm/kvm_host.h | 3 + + arch/arm/include/uapi/asm/kvm.h | 6 +++ + arch/arm/kvm/guest.c | 13 +++++++ + arch/arm/kvm/psci.c | 60 +++++++++++++++++++++++++++++++++ + arch/arm64/include/asm/kvm_host.h | 3 + + arch/arm64/include/uapi/asm/kvm.h | 6 +++ + arch/arm64/kvm/guest.c | 14 +++++++ + include/kvm/arm_psci.h | 16 +++++++- + 10 files changed, 156 insertions(+), 4 deletions(-) + create mode 100644 Documentation/virtual/kvm/arm/psci.txt + +--- a/Documentation/virtual/kvm/api.txt ++++ b/Documentation/virtual/kvm/api.txt +@@ -2118,6 +2118,9 @@ ARM 32-bit VFP control registers have th + ARM 64-bit FP registers have the following id bit patterns: + 0x4030 0000 0012 0 + ++ARM firmware pseudo-registers have the following bit pattern: ++ 0x4030 0000 0014 ++ + + arm64 registers are mapped using the lower 32 bits. The upper 16 of + that is the register group type, or coprocessor number: +@@ -2134,6 +2137,9 @@ arm64 CCSIDR registers are demultiplexed + arm64 system registers have the following id bit patterns: + 0x6030 0000 0013 + ++arm64 firmware pseudo-registers have the following bit pattern: ++ 0x6030 0000 0014 ++ + + MIPS registers are mapped using the lower 32 bits. The upper 16 of that is + the register group type: +@@ -2656,7 +2662,8 @@ Possible features: + and execute guest code when KVM_RUN is called. + - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode. + Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only). +- - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU. ++ - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 (or a future revision ++ backward compatible with v0.2) for the CPU. + Depends on KVM_CAP_ARM_PSCI_0_2. + - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU. + Depends on KVM_CAP_ARM_PMU_V3. +--- /dev/null ++++ b/Documentation/virtual/kvm/arm/psci.txt +@@ -0,0 +1,30 @@ ++KVM implements the PSCI (Power State Coordination Interface) ++specification in order to provide services such as CPU on/off, reset ++and power-off to the guest. ++ ++The PSCI specification is regularly updated to provide new features, ++and KVM implements these updates if they make sense from a virtualization ++point of view. ++ ++This means that a guest booted on two different versions of KVM can ++observe two different "firmware" revisions. This could cause issues if ++a given guest is tied to a particular PSCI revision (unlikely), or if ++a migration causes a different PSCI version to be exposed out of the ++blue to an unsuspecting guest. ++ ++In order to remedy this situation, KVM exposes a set of "firmware ++pseudo-registers" that can be manipulated using the GET/SET_ONE_REG ++interface. These registers can be saved/restored by userspace, and set ++to a convenient value if required. ++ ++The following register is defined: ++ ++* KVM_REG_ARM_PSCI_VERSION: ++ ++ - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set ++ (and thus has already been initialized) ++ - Returns the current PSCI version on GET_ONE_REG (defaulting to the ++ highest PSCI version implemented by KVM and compatible with v0.2) ++ - Allows any PSCI version implemented by KVM and compatible with ++ v0.2 to be set with SET_ONE_REG ++ - Affects the whole VM (even if the register view is per-vcpu) +--- a/arch/arm/include/asm/kvm_host.h ++++ b/arch/arm/include/asm/kvm_host.h +@@ -78,6 +78,9 @@ struct kvm_arch { + /* Interrupt controller */ + struct vgic_dist vgic; + int max_vcpus; ++ ++ /* Mandated version of PSCI */ ++ u32 psci_version; + }; + + #define KVM_NR_MEM_OBJS 40 +--- a/arch/arm/include/uapi/asm/kvm.h ++++ b/arch/arm/include/uapi/asm/kvm.h +@@ -173,6 +173,12 @@ struct kvm_arch_memory_slot { + #define KVM_REG_ARM_VFP_FPINST 0x1009 + #define KVM_REG_ARM_VFP_FPINST2 0x100A + ++/* KVM-as-firmware specific pseudo-registers */ ++#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) ++#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \ ++ KVM_REG_ARM_FW | ((r) & 0xffff)) ++#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) ++ + /* Device Control API: ARM VGIC */ + #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 + #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 +--- a/arch/arm/kvm/guest.c ++++ b/arch/arm/kvm/guest.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -176,6 +177,7 @@ static unsigned long num_core_regs(void) + unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) + { + return num_core_regs() + kvm_arm_num_coproc_regs(vcpu) ++ + kvm_arm_get_fw_num_regs(vcpu) + + NUM_TIMER_REGS; + } + +@@ -196,6 +198,11 @@ int kvm_arm_copy_reg_indices(struct kvm_ + uindices++; + } + ++ ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices); ++ if (ret) ++ return ret; ++ uindices += kvm_arm_get_fw_num_regs(vcpu); ++ + ret = copy_timer_indices(vcpu, uindices); + if (ret) + return ret; +@@ -214,6 +221,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcp + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) + return get_core_reg(vcpu, reg); + ++ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) ++ return kvm_arm_get_fw_reg(vcpu, reg); ++ + if (is_timer_reg(reg->id)) + return get_timer_reg(vcpu, reg); + +@@ -230,6 +240,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcp + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) + return set_core_reg(vcpu, reg); + ++ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) ++ return kvm_arm_set_fw_reg(vcpu, reg); ++ + if (is_timer_reg(reg->id)) + return set_timer_reg(vcpu, reg); + +--- a/arch/arm/kvm/psci.c ++++ b/arch/arm/kvm/psci.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -425,3 +426,62 @@ int kvm_hvc_call_handler(struct kvm_vcpu + smccc_set_retval(vcpu, val, 0, 0, 0); + return 1; + } ++ ++int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) ++{ ++ return 1; /* PSCI version */ ++} ++ ++int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) ++{ ++ if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices)) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) ++{ ++ if (reg->id == KVM_REG_ARM_PSCI_VERSION) { ++ void __user *uaddr = (void __user *)(long)reg->addr; ++ u64 val; ++ ++ val = kvm_psci_version(vcpu, vcpu->kvm); ++ if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id))) ++ return -EFAULT; ++ ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) ++{ ++ if (reg->id == KVM_REG_ARM_PSCI_VERSION) { ++ void __user *uaddr = (void __user *)(long)reg->addr; ++ bool wants_02; ++ u64 val; ++ ++ if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id))) ++ return -EFAULT; ++ ++ wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features); ++ ++ switch (val) { ++ case KVM_ARM_PSCI_0_1: ++ if (wants_02) ++ return -EINVAL; ++ vcpu->kvm->arch.psci_version = val; ++ return 0; ++ case KVM_ARM_PSCI_0_2: ++ case KVM_ARM_PSCI_1_0: ++ if (!wants_02) ++ return -EINVAL; ++ vcpu->kvm->arch.psci_version = val; ++ return 0; ++ } ++ } ++ ++ return -EINVAL; ++} +--- a/arch/arm64/include/asm/kvm_host.h ++++ b/arch/arm64/include/asm/kvm_host.h +@@ -73,6 +73,9 @@ struct kvm_arch { + + /* Timer */ + struct arch_timer_kvm timer; ++ ++ /* Mandated version of PSCI */ ++ u32 psci_version; + }; + + #define KVM_NR_MEM_OBJS 40 +--- a/arch/arm64/include/uapi/asm/kvm.h ++++ b/arch/arm64/include/uapi/asm/kvm.h +@@ -195,6 +195,12 @@ struct kvm_arch_memory_slot { + #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) + #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2) + ++/* KVM-as-firmware specific pseudo-registers */ ++#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) ++#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ ++ KVM_REG_ARM_FW | ((r) & 0xffff)) ++#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) ++ + /* Device Control API: ARM VGIC */ + #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 + #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 +--- a/arch/arm64/kvm/guest.c ++++ b/arch/arm64/kvm/guest.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -205,7 +206,7 @@ static int get_timer_reg(struct kvm_vcpu + unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) + { + return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu) +- + NUM_TIMER_REGS; ++ + kvm_arm_get_fw_num_regs(vcpu) + NUM_TIMER_REGS; + } + + /** +@@ -225,6 +226,11 @@ int kvm_arm_copy_reg_indices(struct kvm_ + uindices++; + } + ++ ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices); ++ if (ret) ++ return ret; ++ uindices += kvm_arm_get_fw_num_regs(vcpu); ++ + ret = copy_timer_indices(vcpu, uindices); + if (ret) + return ret; +@@ -243,6 +249,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcp + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) + return get_core_reg(vcpu, reg); + ++ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) ++ return kvm_arm_get_fw_reg(vcpu, reg); ++ + if (is_timer_reg(reg->id)) + return get_timer_reg(vcpu, reg); + +@@ -259,6 +268,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcp + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) + return set_core_reg(vcpu, reg); + ++ if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) ++ return kvm_arm_set_fw_reg(vcpu, reg); ++ + if (is_timer_reg(reg->id)) + return set_timer_reg(vcpu, reg); + +--- a/include/kvm/arm_psci.h ++++ b/include/kvm/arm_psci.h +@@ -37,10 +37,15 @@ static inline int kvm_psci_version(struc + * Our PSCI implementation stays the same across versions from + * v0.2 onward, only adding the few mandatory functions (such + * as FEATURES with 1.0) that are required by newer +- * revisions. It is thus safe to return the latest. ++ * revisions. It is thus safe to return the latest, unless ++ * userspace has instructed us otherwise. + */ +- if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) ++ if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) { ++ if (vcpu->kvm->arch.psci_version) ++ return vcpu->kvm->arch.psci_version; ++ + return KVM_ARM_PSCI_LATEST; ++ } + + return KVM_ARM_PSCI_0_1; + } +@@ -48,4 +53,11 @@ static inline int kvm_psci_version(struc + + int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); + ++struct kvm_one_reg; ++ ++int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu); ++int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); ++int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); ++int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); ++ + #endif /* __KVM_ARM_PSCI_H__ */ diff --git a/queue-4.9/crypto-talitos-fix-ipsec-cipher-in-length.patch b/queue-4.9/crypto-talitos-fix-ipsec-cipher-in-length.patch new file mode 100644 index 00000000000..df9482db50e --- /dev/null +++ b/queue-4.9/crypto-talitos-fix-ipsec-cipher-in-length.patch @@ -0,0 +1,116 @@ +From 2b1227301a8e4729409694e323b72c064c47cb6b Mon Sep 17 00:00:00 2001 +From: LEROY Christophe +Date: Thu, 22 Mar 2018 10:57:01 +0100 +Subject: crypto: talitos - fix IPsec cipher in length +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: LEROY Christophe + +commit 2b1227301a8e4729409694e323b72c064c47cb6b upstream. + +For SEC 2.x+, cipher in length must contain only the ciphertext length. +In case of using hardware ICV checking, the ICV length is provided via +the "extent" field of the descriptor pointer. + +Cc: # 4.8+ +Fixes: 549bd8bc5987 ("crypto: talitos - Implement AEAD for SEC1 using HMAC_SNOOP_NO_AFEU") +Reported-by: Horia Geantă +Signed-off-by: Christophe Leroy +Tested-by: Horia Geantă +Signed-off-by: Herbert Xu +[backported to 4.9.y, 4.14.y] +Signed-off-by: Horia Geantă +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/talitos.c | 41 +++++++++++++++++++++-------------------- + 1 file changed, 21 insertions(+), 20 deletions(-) + +--- a/drivers/crypto/talitos.c ++++ b/drivers/crypto/talitos.c +@@ -1116,10 +1116,10 @@ next: + return count; + } + +-int talitos_sg_map(struct device *dev, struct scatterlist *src, +- unsigned int len, struct talitos_edesc *edesc, +- struct talitos_ptr *ptr, +- int sg_count, unsigned int offset, int tbl_off) ++static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src, ++ unsigned int len, struct talitos_edesc *edesc, ++ struct talitos_ptr *ptr, int sg_count, ++ unsigned int offset, int tbl_off, int elen) + { + struct talitos_private *priv = dev_get_drvdata(dev); + bool is_sec1 = has_ftr_sec1(priv); +@@ -1130,7 +1130,7 @@ int talitos_sg_map(struct device *dev, s + } + + to_talitos_ptr_len(ptr, len, is_sec1); +- to_talitos_ptr_ext_set(ptr, 0, is_sec1); ++ to_talitos_ptr_ext_set(ptr, elen, is_sec1); + + if (sg_count == 1) { + to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1); +@@ -1140,7 +1140,7 @@ int talitos_sg_map(struct device *dev, s + to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, is_sec1); + return sg_count; + } +- sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len, ++ sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen, + &edesc->link_tbl[tbl_off]); + if (sg_count == 1) { + /* Only one segment now, so no link tbl needed*/ +@@ -1154,6 +1154,15 @@ int talitos_sg_map(struct device *dev, s + return sg_count; + } + ++static int talitos_sg_map(struct device *dev, struct scatterlist *src, ++ unsigned int len, struct talitos_edesc *edesc, ++ struct talitos_ptr *ptr, int sg_count, ++ unsigned int offset, int tbl_off) ++{ ++ return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset, ++ tbl_off, 0); ++} ++ + /* + * fill in and submit ipsec_esp descriptor + */ +@@ -1171,7 +1180,7 @@ static int ipsec_esp(struct talitos_edes + unsigned int ivsize = crypto_aead_ivsize(aead); + int tbl_off = 0; + int sg_count, ret; +- int sg_link_tbl_len; ++ int elen = 0; + bool sync_needed = false; + struct talitos_private *priv = dev_get_drvdata(dev); + bool is_sec1 = has_ftr_sec1(priv); +@@ -1225,20 +1234,12 @@ static int ipsec_esp(struct talitos_edes + * extent is bytes of HMAC postpended to ciphertext, + * typically 12 for ipsec + */ +- to_talitos_ptr_len(&desc->ptr[4], cryptlen, is_sec1); +- to_talitos_ptr_ext_set(&desc->ptr[4], 0, is_sec1); +- +- sg_link_tbl_len = cryptlen; +- +- if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) { +- to_talitos_ptr_ext_set(&desc->ptr[4], authsize, is_sec1); +- +- if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) +- sg_link_tbl_len += authsize; +- } ++ if ((desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) && ++ (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)) ++ elen = authsize; + +- ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc, +- &desc->ptr[4], sg_count, areq->assoclen, tbl_off); ++ ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4], ++ sg_count, areq->assoclen, tbl_off, elen); + + if (ret > 1) { + tbl_off += ret; diff --git a/queue-4.9/series b/queue-4.9/series index 35bf1b030a8..799190b5edb 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -393,3 +393,5 @@ kdb-make-mdr-command-repeat.patch bpf-map_get_next_key-to-return-first-key-on-null.patch tpm-do-not-suspend-resume-if-power-stays-on.patch tpm-self-test-failure-should-not-cause-suspend-to-fail.patch +arm-arm64-kvm-add-psci-version-selection-api.patch +crypto-talitos-fix-ipsec-cipher-in-length.patch -- 2.47.3