]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Mar 2016 05:07:33 +0000 (21:07 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Mar 2016 05:07:33 +0000 (21:07 -0800)
added patches:
arm-debug-ll-fix-bcm63xx-entry-for-multiplatform.patch
arm64-errata-add-mpc-relative-literal-loads-to-build-flags.patch
ext4-fix-bh-b_state-corruption.patch
kvm-s390-fix-guest-fprs-memory-leak.patch
kvm-s390-fix-memory-overwrites-when-vx-is-disabled.patch

queue-4.4/arm-debug-ll-fix-bcm63xx-entry-for-multiplatform.patch [new file with mode: 0644]
queue-4.4/arm64-errata-add-mpc-relative-literal-loads-to-build-flags.patch [new file with mode: 0644]
queue-4.4/ext4-fix-bh-b_state-corruption.patch [new file with mode: 0644]
queue-4.4/kvm-s390-fix-guest-fprs-memory-leak.patch [new file with mode: 0644]
queue-4.4/kvm-s390-fix-memory-overwrites-when-vx-is-disabled.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/arm-debug-ll-fix-bcm63xx-entry-for-multiplatform.patch b/queue-4.4/arm-debug-ll-fix-bcm63xx-entry-for-multiplatform.patch
new file mode 100644 (file)
index 0000000..8ed5a7b
--- /dev/null
@@ -0,0 +1,100 @@
+From 6c54809977de3c9e2ef9e9934a2c6625f7e161e7 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 18 Jan 2016 10:45:00 +0100
+Subject: ARM: debug-ll: fix BCM63xx entry for multiplatform
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 6c54809977de3c9e2ef9e9934a2c6625f7e161e7 upstream.
+
+During my randconfig build testing, I found that a kernel with
+DEBUG_AT91_UART and ARCH_BCM_63XX fails to build:
+
+arch/arm/include/debug/at91.S:18:0: error: "CONFIG_DEBUG_UART_VIRT" redefined [-Werror]
+
+It turns out that the DEBUG_UART_BCM63XX option is enabled whenever
+the ARCH_BCM_63XX is, and that breaks multiplatform kernels because
+we then end up using the UART address from BCM63XX rather than the
+one we actually configured (if any).
+
+This changes the BCM63XX options to only have one Kconfig option,
+and only enable that if the user explicitly turns it on.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Fixes: b51312bebfa4 ("ARM: BCM63XX: add low-level UART debug support")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/Kconfig.debug |   17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+--- a/arch/arm/Kconfig.debug
++++ b/arch/arm/Kconfig.debug
+@@ -162,10 +162,9 @@ choice
+                 mobile SoCs in the Kona family of chips (e.g. bcm28155,
+                 bcm11351, etc...)
+-      config DEBUG_BCM63XX
++      config DEBUG_BCM63XX_UART
+               bool "Kernel low-level debugging on BCM63XX UART"
+               depends on ARCH_BCM_63XX
+-              select DEBUG_UART_BCM63XX
+       config DEBUG_BERLIN_UART
+               bool "Marvell Berlin SoC Debug UART"
+@@ -1348,7 +1347,7 @@ config DEBUG_LL_INCLUDE
+       default "debug/vf.S" if DEBUG_VF_UART
+       default "debug/vt8500.S" if DEBUG_VT8500_UART0
+       default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
+-      default "debug/bcm63xx.S" if DEBUG_UART_BCM63XX
++      default "debug/bcm63xx.S" if DEBUG_BCM63XX_UART
+       default "debug/digicolor.S" if DEBUG_DIGICOLOR_UA0
+       default "mach/debug-macro.S"
+@@ -1364,10 +1363,6 @@ config DEBUG_UART_8250
+               ARCH_IOP33X || ARCH_IXP4XX || \
+               ARCH_LPC32XX || ARCH_MV78XX0 || ARCH_ORION5X || ARCH_RPC
+-# Compatibility options for BCM63xx
+-config DEBUG_UART_BCM63XX
+-      def_bool ARCH_BCM_63XX
+-
+ config DEBUG_UART_PHYS
+       hex "Physical base address of debug UART"
+       default 0x00100a00 if DEBUG_NETX_UART
+@@ -1462,7 +1457,7 @@ config DEBUG_UART_PHYS
+       default 0xfffb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
+       default 0xfffb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
+       default 0xfffb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
+-      default 0xfffe8600 if DEBUG_UART_BCM63XX
++      default 0xfffe8600 if DEBUG_BCM63XX_UART
+       default 0xfffff700 if ARCH_IOP33X
+       depends on ARCH_EP93XX || \
+               DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
+@@ -1474,7 +1469,7 @@ config DEBUG_UART_PHYS
+               DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
+               DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
+               DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
+-              DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
++              DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
+               DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
+               DEBUG_AT91_UART
+@@ -1515,7 +1510,7 @@ config DEBUG_UART_VIRT
+       default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
+       default 0xfc40ab00 if DEBUG_BRCMSTB_UART
+       default 0xfc705000 if DEBUG_ZTE_ZX
+-      default 0xfcfe8600 if DEBUG_UART_BCM63XX
++      default 0xfcfe8600 if DEBUG_BCM63XX_UART
+       default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
+       default 0xfd000000 if ARCH_SPEAR13XX
+       default 0xfd012000 if ARCH_MV78XX0
+@@ -1566,7 +1561,7 @@ config DEBUG_UART_VIRT
+               DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
+               DEBUG_NETX_UART || \
+               DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
+-              DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
++              DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
+               DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
+ config DEBUG_UART_8250_SHIFT
diff --git a/queue-4.4/arm64-errata-add-mpc-relative-literal-loads-to-build-flags.patch b/queue-4.4/arm64-errata-add-mpc-relative-literal-loads-to-build-flags.patch
new file mode 100644 (file)
index 0000000..c888d20
--- /dev/null
@@ -0,0 +1,42 @@
+From 67dfa1751ce71e629aad7c438e1678ad41054677 Mon Sep 17 00:00:00 2001
+From: dann frazier <dann.frazier@canonical.com>
+Date: Mon, 25 Jan 2016 16:52:16 -0700
+Subject: arm64: errata: Add -mpc-relative-literal-loads to build flags
+
+From: dann frazier <dann.frazier@canonical.com>
+
+commit 67dfa1751ce71e629aad7c438e1678ad41054677 upstream.
+
+GCC6 (and Linaro's 2015.12 snapshot of GCC5) has a new default that uses
+adrp/ldr or adrp/add to address literal pools. When CONFIG_ARM64_ERRATUM_843419
+is enabled, modules built with this toolchain fail to load:
+
+  module libahci: unsupported RELA relocation: 275
+
+This patch fixes the problem by passing '-mpc-relative-literal-loads'
+to the compiler.
+
+Cc: stable@vger.kernel.org
+Fixes: df057cc7b4fa ("arm64: errata: add module build workaround for erratum #843419")
+BugLink: http://bugs.launchpad.net/bugs/1533009
+Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Suggested-by: Christophe Lyon <christophe.lyon@linaro.org>
+Signed-off-by: Dann Frazier <dann.frazier@canonical.com>
+[will: backport to 4.4-stable]
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/Makefile |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/Makefile
++++ b/arch/arm64/Makefile
+@@ -27,6 +27,7 @@ $(warning LSE atomics not supported by b
+ endif
+ KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr)
++KBUILD_CFLAGS += $(call cc-option, -mpc-relative-literal-loads)
+ KBUILD_AFLAGS += $(lseinstr)
+ ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
diff --git a/queue-4.4/ext4-fix-bh-b_state-corruption.patch b/queue-4.4/ext4-fix-bh-b_state-corruption.patch
new file mode 100644 (file)
index 0000000..0ec1826
--- /dev/null
@@ -0,0 +1,92 @@
+From ed8ad83808f009ade97ebbf6519bc3a97fefbc0c Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.com>
+Date: Fri, 19 Feb 2016 00:18:25 -0500
+Subject: ext4: fix bh->b_state corruption
+
+From: Jan Kara <jack@suse.com>
+
+commit ed8ad83808f009ade97ebbf6519bc3a97fefbc0c upstream.
+
+ext4 can update bh->b_state non-atomically in _ext4_get_block() and
+ext4_da_get_block_prep(). Usually this is fine since bh is just a
+temporary storage for mapping information on stack but in some cases it
+can be fully living bh attached to a page. In such case non-atomic
+update of bh->b_state can race with an atomic update which then gets
+lost. Usually when we are mapping bh and thus updating bh->b_state
+non-atomically, nobody else touches the bh and so things work out fine
+but there is one case to especially worry about: ext4_finish_bio() uses
+BH_Uptodate_Lock on the first bh in the page to synchronize handling of
+PageWriteback state. So when blocksize < pagesize, we can be atomically
+modifying bh->b_state of a buffer that actually isn't under IO and thus
+can race e.g. with delalloc trying to map that buffer. The result is
+that we can mistakenly set / clear BH_Uptodate_Lock bit resulting in the
+corruption of PageWriteback state or missed unlock of BH_Uptodate_Lock.
+
+Fix the problem by always updating bh->b_state bits atomically.
+
+Reported-by: Nikolay Borisov <kernel@kyup.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Nikolay Borisov <kernel@kyup.com>
+[NB: Backported to 4.4.2]
+Acked-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c |   32 ++++++++++++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -657,6 +657,34 @@ has_zeroout:
+       return retval;
+ }
++/*
++ * Update EXT4_MAP_FLAGS in bh->b_state. For buffer heads attached to pages
++ * we have to be careful as someone else may be manipulating b_state as well.
++ */
++static void ext4_update_bh_state(struct buffer_head *bh, unsigned long flags)
++{
++      unsigned long old_state;
++      unsigned long new_state;
++
++      flags &= EXT4_MAP_FLAGS;
++
++      /* Dummy buffer_head? Set non-atomically. */
++      if (!bh->b_page) {
++              bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | flags;
++              return;
++      }
++      /*
++       * Someone else may be modifying b_state. Be careful! This is ugly but
++       * once we get rid of using bh as a container for mapping information
++       * to pass to / from get_block functions, this can go away.
++       */
++      do {
++              old_state = READ_ONCE(bh->b_state);
++              new_state = (old_state & ~EXT4_MAP_FLAGS) | flags;
++      } while (unlikely(
++               cmpxchg(&bh->b_state, old_state, new_state) != old_state));
++}
++
+ /* Maximum number of blocks we map for direct IO at once. */
+ #define DIO_MAX_BLOCKS 4096
+@@ -693,7 +721,7 @@ static int _ext4_get_block(struct inode
+               ext4_io_end_t *io_end = ext4_inode_aio(inode);
+               map_bh(bh, inode->i_sb, map.m_pblk);
+-              bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
++              ext4_update_bh_state(bh, map.m_flags);
+               if (IS_DAX(inode) && buffer_unwritten(bh)) {
+                       /*
+                        * dgc: I suspect unwritten conversion on ext4+DAX is
+@@ -1669,7 +1697,7 @@ int ext4_da_get_block_prep(struct inode
+               return ret;
+       map_bh(bh, inode->i_sb, map.m_pblk);
+-      bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
++      ext4_update_bh_state(bh, map.m_flags);
+       if (buffer_unwritten(bh)) {
+               /* A delayed write to unwritten bh should be marked
diff --git a/queue-4.4/kvm-s390-fix-guest-fprs-memory-leak.patch b/queue-4.4/kvm-s390-fix-guest-fprs-memory-leak.patch
new file mode 100644 (file)
index 0000000..d7b3c6f
--- /dev/null
@@ -0,0 +1,49 @@
+From 9c7ebb613bffea2feef4ec562ba1dbcaa810942b Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <dahi@linux.vnet.ibm.com>
+Date: Fri, 22 Jan 2016 14:55:56 +0100
+Subject: KVM: s390: fix guest fprs memory leak
+
+From: David Hildenbrand <dahi@linux.vnet.ibm.com>
+
+commit 9c7ebb613bffea2feef4ec562ba1dbcaa810942b upstream.
+
+fprs is never freed, therefore resulting in a memory leak if
+kvm_vcpu_init() fails or the vcpu is destroyed.
+
+Fixes: 9977e886cbbc ("s390/kernel: lazy restore fpu registers")
+Reported-by: Eric Farman <farman@linux.vnet.ibm.com>
+Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
+Reviewed-by: Eric Farman <farman@linux.vnet.ibm.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/kvm/kvm-s390.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -1202,6 +1202,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vc
+       if (vcpu->kvm->arch.use_cmma)
+               kvm_s390_vcpu_unsetup_cmma(vcpu);
++      kfree(vcpu->arch.guest_fpregs.fprs);
+       free_page((unsigned long)(vcpu->arch.sie_block));
+       kvm_vcpu_uninit(vcpu);
+@@ -1516,12 +1517,14 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
+       rc = kvm_vcpu_init(vcpu, kvm, id);
+       if (rc)
+-              goto out_free_sie_block;
++              goto out_free_fprs;
+       VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
+                vcpu->arch.sie_block);
+       trace_kvm_s390_create_vcpu(id, vcpu, vcpu->arch.sie_block);
+       return vcpu;
++out_free_fprs:
++      kfree(vcpu->arch.guest_fpregs.fprs);
+ out_free_sie_block:
+       free_page((unsigned long)(vcpu->arch.sie_block));
+ out_free_cpu:
diff --git a/queue-4.4/kvm-s390-fix-memory-overwrites-when-vx-is-disabled.patch b/queue-4.4/kvm-s390-fix-memory-overwrites-when-vx-is-disabled.patch
new file mode 100644 (file)
index 0000000..d836120
--- /dev/null
@@ -0,0 +1,276 @@
+From 9abc2a08a7d665b02bdde974fd6c44aae86e923e Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <dahi@linux.vnet.ibm.com>
+Date: Thu, 14 Jan 2016 22:12:47 +0100
+Subject: KVM: s390: fix memory overwrites when vx is disabled
+
+From: David Hildenbrand <dahi@linux.vnet.ibm.com>
+
+commit 9abc2a08a7d665b02bdde974fd6c44aae86e923e upstream.
+
+The kernel now always uses vector registers when available, however KVM
+has special logic if support is really enabled for a guest. If support
+is disabled, guest_fpregs.fregs will only contain memory for the fpu.
+The kernel, however, will store vector registers into that area,
+resulting in crazy memory overwrites.
+
+Simply extending that area is not enough, because the format of the
+registers also changes. We would have to do additional conversions, making
+the code even more complex. Therefore let's directly use one place for
+the vector/fpu registers + fpc (in kvm_run). We just have to convert the
+data properly when accessing it. This makes current code much easier.
+
+Please note that vector/fpu registers are now always stored to
+vcpu->run->s.regs.vrs. Although this data is visible to QEMU and
+used for migration, we only guarantee valid values to user space  when
+KVM_SYNC_VRS is set. As that is only the case when we have vector
+register support, we are on the safe side.
+
+Fixes: b5510d9b68c3 ("s390/fpu: always enable the vector facility if it is available")
+Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+[adopt to d9a3a09af54d]
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
+index efaac2c..e9a983f 100644
+--- a/arch/s390/include/asm/kvm_host.h
++++ b/arch/s390/include/asm/kvm_host.h
+@@ -506,7 +506,6 @@ struct kvm_vcpu_arch {
+       struct kvm_s390_sie_block *sie_block;
+       unsigned int      host_acrs[NUM_ACRS];
+       struct fpu        host_fpregs;
+-      struct fpu        guest_fpregs;
+       struct kvm_s390_local_interrupt local_int;
+       struct hrtimer    ckc_timer;
+       struct kvm_s390_pgm_info pgm;
+diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
+index db7cca5..a08d0af 100644
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -1202,7 +1202,6 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
+       if (vcpu->kvm->arch.use_cmma)
+               kvm_s390_vcpu_unsetup_cmma(vcpu);
+-      kfree(vcpu->arch.guest_fpregs.fprs);
+       free_page((unsigned long)(vcpu->arch.sie_block));
+       kvm_vcpu_uninit(vcpu);
+@@ -1269,44 +1268,18 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
+       return 0;
+ }
+-/*
+- * Backs up the current FP/VX register save area on a particular
+- * destination.  Used to switch between different register save
+- * areas.
+- */
+-static inline void save_fpu_to(struct fpu *dst)
+-{
+-      dst->fpc = current->thread.fpu.fpc;
+-      dst->regs = current->thread.fpu.regs;
+-}
+-
+-/*
+- * Switches the FP/VX register save area from which to lazy
+- * restore register contents.
+- */
+-static inline void load_fpu_from(struct fpu *from)
+-{
+-      current->thread.fpu.fpc = from->fpc;
+-      current->thread.fpu.regs = from->regs;
+-}
+-
+ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ {
+       /* Save host register state */
+       save_fpu_regs();
+-      save_fpu_to(&vcpu->arch.host_fpregs);
+-
+-      if (test_kvm_facility(vcpu->kvm, 129)) {
+-              current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
+-              /*
+-               * Use the register save area in the SIE-control block
+-               * for register restore and save in kvm_arch_vcpu_put()
+-               */
+-              current->thread.fpu.vxrs =
+-                      (__vector128 *)&vcpu->run->s.regs.vrs;
+-      } else
+-              load_fpu_from(&vcpu->arch.guest_fpregs);
++      vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc;
++      vcpu->arch.host_fpregs.regs = current->thread.fpu.regs;
++      /* Depending on MACHINE_HAS_VX, data stored to vrs either
++       * has vector register or floating point register format.
++       */
++      current->thread.fpu.regs = vcpu->run->s.regs.vrs;
++      current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
+       if (test_fp_ctl(current->thread.fpu.fpc))
+               /* User space provided an invalid FPC, let's clear it */
+               current->thread.fpu.fpc = 0;
+@@ -1322,19 +1295,13 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
+       atomic_andnot(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
+       gmap_disable(vcpu->arch.gmap);
++      /* Save guest register state */
+       save_fpu_regs();
++      vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
+-      if (test_kvm_facility(vcpu->kvm, 129))
+-              /*
+-               * kvm_arch_vcpu_load() set up the register save area to
+-               * the &vcpu->run->s.regs.vrs and, thus, the vector registers
+-               * are already saved.  Only the floating-point control must be
+-               * copied.
+-               */
+-              vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
+-      else
+-              save_fpu_to(&vcpu->arch.guest_fpregs);
+-      load_fpu_from(&vcpu->arch.host_fpregs);
++      /* Restore host register state */
++      current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc;
++      current->thread.fpu.regs = vcpu->arch.host_fpregs.regs;
+       save_access_regs(vcpu->run->s.regs.acrs);
+       restore_access_regs(vcpu->arch.host_acrs);
+@@ -1352,8 +1319,9 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
+       memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
+       vcpu->arch.sie_block->gcr[0]  = 0xE0UL;
+       vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
+-      vcpu->arch.guest_fpregs.fpc = 0;
+-      asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
++      /* make sure the new fpc will be lazily loaded */
++      save_fpu_regs();
++      current->thread.fpu.fpc = 0;
+       vcpu->arch.sie_block->gbea = 1;
+       vcpu->arch.sie_block->pp = 0;
+       vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
+@@ -1502,29 +1470,14 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
+       vcpu->arch.local_int.wq = &vcpu->wq;
+       vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
+-      /*
+-       * Allocate a save area for floating-point registers.  If the vector
+-       * extension is available, register contents are saved in the SIE
+-       * control block.  The allocated save area is still required in
+-       * particular places, for example, in kvm_s390_vcpu_store_status().
+-       */
+-      vcpu->arch.guest_fpregs.fprs = kzalloc(sizeof(freg_t) * __NUM_FPRS,
+-                                             GFP_KERNEL);
+-      if (!vcpu->arch.guest_fpregs.fprs) {
+-              rc = -ENOMEM;
+-              goto out_free_sie_block;
+-      }
+-
+       rc = kvm_vcpu_init(vcpu, kvm, id);
+       if (rc)
+-              goto out_free_fprs;
++              goto out_free_sie_block;
+       VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
+                vcpu->arch.sie_block);
+       trace_kvm_s390_create_vcpu(id, vcpu, vcpu->arch.sie_block);
+       return vcpu;
+-out_free_fprs:
+-      kfree(vcpu->arch.guest_fpregs.fprs);
+ out_free_sie_block:
+       free_page((unsigned long)(vcpu->arch.sie_block));
+ out_free_cpu:
+@@ -1737,19 +1690,27 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
+ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+ {
++      /* make sure the new values will be lazily loaded */
++      save_fpu_regs();
+       if (test_fp_ctl(fpu->fpc))
+               return -EINVAL;
+-      memcpy(vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
+-      vcpu->arch.guest_fpregs.fpc = fpu->fpc;
+-      save_fpu_regs();
+-      load_fpu_from(&vcpu->arch.guest_fpregs);
++      current->thread.fpu.fpc = fpu->fpc;
++      if (MACHINE_HAS_VX)
++              convert_fp_to_vx(current->thread.fpu.vxrs, (freg_t *)fpu->fprs);
++      else
++              memcpy(current->thread.fpu.fprs, &fpu->fprs, sizeof(fpu->fprs));
+       return 0;
+ }
+ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+ {
+-      memcpy(&fpu->fprs, vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
+-      fpu->fpc = vcpu->arch.guest_fpregs.fpc;
++      /* make sure we have the latest values */
++      save_fpu_regs();
++      if (MACHINE_HAS_VX)
++              convert_vx_to_fp((freg_t *)fpu->fprs, current->thread.fpu.vxrs);
++      else
++              memcpy(fpu->fprs, current->thread.fpu.fprs, sizeof(fpu->fprs));
++      fpu->fpc = current->thread.fpu.fpc;
+       return 0;
+ }
+@@ -2269,6 +2230,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
+ {
+       unsigned char archmode = 1;
++      freg_t fprs[NUM_FPRS];
+       unsigned int px;
+       u64 clkcomp;
+       int rc;
+@@ -2284,8 +2246,16 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
+               gpa = px;
+       } else
+               gpa -= __LC_FPREGS_SAVE_AREA;
+-      rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA,
+-                           vcpu->arch.guest_fpregs.fprs, 128);
++
++      /* manually convert vector registers if necessary */
++      if (MACHINE_HAS_VX) {
++              convert_vx_to_fp(fprs, current->thread.fpu.vxrs);
++              rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA,
++                                   fprs, 128);
++      } else {
++              rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA,
++                                   vcpu->run->s.regs.vrs, 128);
++      }
+       rc |= write_guest_abs(vcpu, gpa + __LC_GPREGS_SAVE_AREA,
+                             vcpu->run->s.regs.gprs, 128);
+       rc |= write_guest_abs(vcpu, gpa + __LC_PSW_SAVE_AREA,
+@@ -2293,7 +2263,7 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
+       rc |= write_guest_abs(vcpu, gpa + __LC_PREFIX_SAVE_AREA,
+                             &px, 4);
+       rc |= write_guest_abs(vcpu, gpa + __LC_FP_CREG_SAVE_AREA,
+-                            &vcpu->arch.guest_fpregs.fpc, 4);
++                            &vcpu->run->s.regs.fpc, 4);
+       rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA,
+                             &vcpu->arch.sie_block->todpr, 4);
+       rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA,
+@@ -2316,19 +2286,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
+        * it into the save area
+        */
+       save_fpu_regs();
+-      if (test_kvm_facility(vcpu->kvm, 129)) {
+-              /*
+-               * If the vector extension is available, the vector registers
+-               * which overlaps with floating-point registers are saved in
+-               * the SIE-control block.  Hence, extract the floating-point
+-               * registers and the FPC value and store them in the
+-               * guest_fpregs structure.
+-               */
+-              vcpu->arch.guest_fpregs.fpc = current->thread.fpu.fpc;
+-              convert_vx_to_fp(vcpu->arch.guest_fpregs.fprs,
+-                               current->thread.fpu.vxrs);
+-      } else
+-              save_fpu_to(&vcpu->arch.guest_fpregs);
++      vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
+       save_access_regs(vcpu->run->s.regs.acrs);
+       return kvm_s390_store_status_unloaded(vcpu, addr);
+-- 
+2.3.9
+
+--
+To unsubscribe from this list: send the line "unsubscribe stable" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
index 8cd673135653f7fe341c66509fc2883d39ba3b80..4fc18474a689ce1b0d4405ff7a170b1c9fd7db5d 100644 (file)
@@ -45,3 +45,8 @@ rtnl-rtm_getnetconf-fix-wrong-return-value.patch
 tipc-unlock-in-error-path.patch
 unix_diag-fix-incorrect-sign-extension-in-unix_lookup_by_ino.patch
 sctp-fix-port-hash-table-size-computation.patch
+ext4-fix-bh-b_state-corruption.patch
+arm-debug-ll-fix-bcm63xx-entry-for-multiplatform.patch
+arm64-errata-add-mpc-relative-literal-loads-to-build-flags.patch
+kvm-s390-fix-guest-fprs-memory-leak.patch
+kvm-s390-fix-memory-overwrites-when-vx-is-disabled.patch