--- /dev/null
+From foo@baz Tue Jun 8 05:36:16 PM CEST 2021
+From: Anand Jain <anand.jain@oracle.com>
+Date: Fri, 30 Apr 2021 19:59:51 +0800
+Subject: btrfs: fix unmountable seed device after fstrim
+
+From: Anand Jain <anand.jain@oracle.com>
+
+commit 5e753a817b2d5991dfe8a801b7b1e8e79a1c5a20 upstream.
+
+The following test case reproduces an issue of wrongly freeing in-use
+blocks on the readonly seed device when fstrim is called on the rw sprout
+device. As shown below.
+
+Create a seed device and add a sprout device to it:
+
+ $ mkfs.btrfs -fq -dsingle -msingle /dev/loop0
+ $ btrfstune -S 1 /dev/loop0
+ $ mount /dev/loop0 /btrfs
+ $ btrfs dev add -f /dev/loop1 /btrfs
+ BTRFS info (device loop0): relocating block group 290455552 flags system
+ BTRFS info (device loop0): relocating block group 1048576 flags system
+ BTRFS info (device loop0): disk added /dev/loop1
+ $ umount /btrfs
+
+Mount the sprout device and run fstrim:
+
+ $ mount /dev/loop1 /btrfs
+ $ fstrim /btrfs
+ $ umount /btrfs
+
+Now try to mount the seed device, and it fails:
+
+ $ mount /dev/loop0 /btrfs
+ mount: /btrfs: wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error.
+
+Block 5292032 is missing on the readonly seed device:
+
+ $ dmesg -kt | tail
+ <snip>
+ BTRFS error (device loop0): bad tree block start, want 5292032 have 0
+ BTRFS warning (device loop0): couldn't read-tree root
+ BTRFS error (device loop0): open_ctree failed
+
+>From the dump-tree of the seed device (taken before the fstrim). Block
+5292032 belonged to the block group starting at 5242880:
+
+ $ btrfs inspect dump-tree -e /dev/loop0 | grep -A1 BLOCK_GROUP
+ <snip>
+ item 3 key (5242880 BLOCK_GROUP_ITEM 8388608) itemoff 16169 itemsize 24
+ block group used 114688 chunk_objectid 256 flags METADATA
+ <snip>
+
+>From the dump-tree of the sprout device (taken before the fstrim).
+fstrim used block-group 5242880 to find the related free space to free:
+
+ $ btrfs inspect dump-tree -e /dev/loop1 | grep -A1 BLOCK_GROUP
+ <snip>
+ item 1 key (5242880 BLOCK_GROUP_ITEM 8388608) itemoff 16226 itemsize 24
+ block group used 32768 chunk_objectid 256 flags METADATA
+ <snip>
+
+BPF kernel tracing the fstrim command finds the missing block 5292032
+within the range of the discarded blocks as below:
+
+ kprobe:btrfs_discard_extent {
+ printf("freeing start %llu end %llu num_bytes %llu:\n",
+ arg1, arg1+arg2, arg2);
+ }
+
+ freeing start 5259264 end 5406720 num_bytes 147456
+ <snip>
+
+Fix this by avoiding the discard command to the readonly seed device.
+
+Reported-by: Chris Murphy <lists@colorremedies.com>
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Anand Jain <anand.jain@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent-tree.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -1984,16 +1984,20 @@ int btrfs_discard_extent(struct btrfs_fs
+ for (i = 0; i < bbio->num_stripes; i++, stripe++) {
+ u64 bytes;
+ struct request_queue *req_q;
++ struct btrfs_device *device = stripe->dev;
+
+- if (!stripe->dev->bdev) {
++ if (!device->bdev) {
+ ASSERT(btrfs_test_opt(fs_info, DEGRADED));
+ continue;
+ }
+- req_q = bdev_get_queue(stripe->dev->bdev);
++ req_q = bdev_get_queue(device->bdev);
+ if (!blk_queue_discard(req_q))
+ continue;
+
+- ret = btrfs_issue_discard(stripe->dev->bdev,
++ if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state))
++ continue;
++
++ ret = btrfs_issue_discard(device->bdev,
+ stripe->physical,
+ stripe->length,
+ &bytes);
--- /dev/null
+From cb853ded1d25e5b026ce115dbcde69e3d7e2e831 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Fri, 14 May 2021 09:05:41 +0100
+Subject: KVM: arm64: Fix debug register indexing
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit cb853ded1d25e5b026ce115dbcde69e3d7e2e831 upstream.
+
+Commit 03fdfb2690099 ("KVM: arm64: Don't write junk to sysregs on
+reset") flipped the register number to 0 for all the debug registers
+in the sysreg table, hereby indicating that these registers live
+in a separate shadow structure.
+
+However, the author of this patch failed to realise that all the
+accessors are using that particular index instead of the register
+encoding, resulting in all the registers hitting index 0. Not quite
+a valid implementation of the architecture...
+
+Address the issue by fixing all the accessors to use the CRm field
+of the encoding, which contains the debug register index.
+
+Fixes: 03fdfb2690099 ("KVM: arm64: Don't write junk to sysregs on reset")
+Reported-by: Ricardo Koller <ricarkol@google.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/sys_regs.c | 42 +++++++++++++++++++++---------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+--- a/arch/arm64/kvm/sys_regs.c
++++ b/arch/arm64/kvm/sys_regs.c
+@@ -426,14 +426,14 @@ static bool trap_bvr(struct kvm_vcpu *vc
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
+ {
+- u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
++ u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm];
+
+ if (p->is_write)
+ reg_to_dbg(vcpu, p, dbg_reg);
+ else
+ dbg_to_reg(vcpu, p, dbg_reg);
+
+- trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
++ trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg);
+
+ return true;
+ }
+@@ -441,7 +441,7 @@ static bool trap_bvr(struct kvm_vcpu *vc
+ static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+ {
+- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm];
+
+ if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0)
+ return -EFAULT;
+@@ -451,7 +451,7 @@ static int set_bvr(struct kvm_vcpu *vcpu
+ static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+ {
+- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm];
+
+ if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+ return -EFAULT;
+@@ -461,21 +461,21 @@ static int get_bvr(struct kvm_vcpu *vcpu
+ static void reset_bvr(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+ {
+- vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg] = rd->val;
++ vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = rd->val;
+ }
+
+ static bool trap_bcr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
+ {
+- u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
++ u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm];
+
+ if (p->is_write)
+ reg_to_dbg(vcpu, p, dbg_reg);
+ else
+ dbg_to_reg(vcpu, p, dbg_reg);
+
+- trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
++ trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg);
+
+ return true;
+ }
+@@ -483,7 +483,7 @@ static bool trap_bcr(struct kvm_vcpu *vc
+ static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+ {
+- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm];
+
+ if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0)
+ return -EFAULT;
+@@ -494,7 +494,7 @@ static int set_bcr(struct kvm_vcpu *vcpu
+ static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+ {
+- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm];
+
+ if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+ return -EFAULT;
+@@ -504,22 +504,22 @@ static int get_bcr(struct kvm_vcpu *vcpu
+ static void reset_bcr(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+ {
+- vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg] = rd->val;
++ vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = rd->val;
+ }
+
+ static bool trap_wvr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
+ {
+- u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
++ u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm];
+
+ if (p->is_write)
+ reg_to_dbg(vcpu, p, dbg_reg);
+ else
+ dbg_to_reg(vcpu, p, dbg_reg);
+
+- trace_trap_reg(__func__, rd->reg, p->is_write,
+- vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]);
++ trace_trap_reg(__func__, rd->CRm, p->is_write,
++ vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]);
+
+ return true;
+ }
+@@ -527,7 +527,7 @@ static bool trap_wvr(struct kvm_vcpu *vc
+ static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+ {
+- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm];
+
+ if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0)
+ return -EFAULT;
+@@ -537,7 +537,7 @@ static int set_wvr(struct kvm_vcpu *vcpu
+ static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+ {
+- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm];
+
+ if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+ return -EFAULT;
+@@ -547,21 +547,21 @@ static int get_wvr(struct kvm_vcpu *vcpu
+ static void reset_wvr(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+ {
+- vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg] = rd->val;
++ vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = rd->val;
+ }
+
+ static bool trap_wcr(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *rd)
+ {
+- u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
++ u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm];
+
+ if (p->is_write)
+ reg_to_dbg(vcpu, p, dbg_reg);
+ else
+ dbg_to_reg(vcpu, p, dbg_reg);
+
+- trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
++ trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg);
+
+ return true;
+ }
+@@ -569,7 +569,7 @@ static bool trap_wcr(struct kvm_vcpu *vc
+ static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+ {
+- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm];
+
+ if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0)
+ return -EFAULT;
+@@ -579,7 +579,7 @@ static int set_wcr(struct kvm_vcpu *vcpu
+ static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+ const struct kvm_one_reg *reg, void __user *uaddr)
+ {
+- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm];
+
+ if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+ return -EFAULT;
+@@ -589,7 +589,7 @@ static int get_wcr(struct kvm_vcpu *vcpu
+ static void reset_wcr(struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+ {
+- vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg] = rd->val;
++ vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = rd->val;
+ }
+
+ static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
--- /dev/null
+From foo@baz Tue Jun 8 05:38:40 PM CEST 2021
+From: Sean Christopherson <seanjc@google.com>
+Date: Wed, 21 Apr 2021 19:21:22 -0700
+Subject: KVM: SVM: Truncate GPR value for DR and CR accesses in !64-bit mode
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 0884335a2e653b8a045083aa1d57ce74269ac81d upstream.
+
+Drop bits 63:32 on loads/stores to/from DRs and CRs when the vCPU is not
+in 64-bit mode. The APM states bits 63:32 are dropped for both DRs and
+CRs:
+
+ In 64-bit mode, the operand size is fixed at 64 bits without the need
+ for a REX prefix. In non-64-bit mode, the operand size is fixed at 32
+ bits and the upper 32 bits of the destination are forced to 0.
+
+Fixes: 7ff76d58a9dc ("KVM: SVM: enhance MOV CR intercept handler")
+Fixes: cae3797a4639 ("KVM: SVM: enhance mov DR intercept handler")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210422022128.3464144-4-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+[sudip: manual backport to old file]
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -4033,7 +4033,7 @@ static int cr_interception(struct vcpu_s
+ err = 0;
+ if (cr >= 16) { /* mov to cr */
+ cr -= 16;
+- val = kvm_register_read(&svm->vcpu, reg);
++ val = kvm_register_readl(&svm->vcpu, reg);
+ switch (cr) {
+ case 0:
+ if (!check_selective_cr0_intercepted(svm, val))
+@@ -4078,7 +4078,7 @@ static int cr_interception(struct vcpu_s
+ kvm_queue_exception(&svm->vcpu, UD_VECTOR);
+ return 1;
+ }
+- kvm_register_write(&svm->vcpu, reg, val);
++ kvm_register_writel(&svm->vcpu, reg, val);
+ }
+ return kvm_complete_insn_gp(&svm->vcpu, err);
+ }
+@@ -4108,13 +4108,13 @@ static int dr_interception(struct vcpu_s
+ if (dr >= 16) { /* mov to DRn */
+ if (!kvm_require_dr(&svm->vcpu, dr - 16))
+ return 1;
+- val = kvm_register_read(&svm->vcpu, reg);
++ val = kvm_register_readl(&svm->vcpu, reg);
+ kvm_set_dr(&svm->vcpu, dr - 16, val);
+ } else {
+ if (!kvm_require_dr(&svm->vcpu, dr))
+ return 1;
+ kvm_get_dr(&svm->vcpu, dr, &val);
+- kvm_register_write(&svm->vcpu, reg, val);
++ kvm_register_writel(&svm->vcpu, reg, val);
+ }
+
+ return kvm_skip_emulated_instruction(&svm->vcpu);