--- /dev/null
+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
--- /dev/null
+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)
--- /dev/null
+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
--- /dev/null
+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:
--- /dev/null
+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
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