summaryrefslogtreecommitdiffstats
path: root/arch/m68k/lib/uaccess.c
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2026-09-23 09:37:21 -0700
committerPaolo Bonzini <pbonzini@redhat.com>2026-09-26 00:39:55 -0400
commit93de2a6a4b91b72607136dd656edf03fb399d27f (patch)
tree9220c76eb23cb39a146fac9692ee69afa4aa3135 /arch/m68k/lib/uaccess.c
downloadlinux-stable-93de2a6a4b91b72607136dd656edf03fb399d27f.tar.gz
linux-stable-93de2a6a4b91b72607136dd656edf03fb399d27f.zip
KVM: SEV: Do cache maintenance on the source VM during intra-host migrationgrafted
Manually perform cache maintenance on the source VM during intra-host migration to ensure no stale data is left in CPU caches after the VM is destroyed. Because the source VM is "converted" to a non-SEV VM, KVM's memory reclaim flows won't trigger cache maintenance, e.g. when all guest memory is reclaimed in response to detaching from the mmu_notifier. Note, relying on the destination VM to do cache maintenance isn't an option as KVM doesn't require identical guest memory configurations, i.e. the source VM may have access to memory that the destination VM does not. Enforcing equivalent memory configurations is infeasible, as it would require a *deep* comparison of memslots, e.g. to verify that not only are the memslot identical, but what the memslots point at is also identical. Fixes: b56639318bb2 ("KVM: SEV: Add support for SEV intra host migration") Cc: stable@vger.kernel.org Reported-by: Stefan Teodorescu <fane@google.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20260923163721.1584779-3-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/m68k/lib/uaccess.c')
-rw-r--r--arch/m68k/lib/uaccess.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/arch/m68k/lib/uaccess.c b/arch/m68k/lib/uaccess.c
new file mode 100644
index 000000000..7646e461a
--- /dev/null
+++ b/arch/m68k/lib/uaccess.c
@@ -0,0 +1,142 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+
+unsigned long __generic_copy_from_user(void *to, const void __user *from,
+ unsigned long n)
+{
+ unsigned long tmp, res;
+
+ asm volatile ("\n"
+ " tst.l %0\n"
+ " jeq 2f\n"
+ "1: "MOVES".l (%1)+,%3\n"
+ " move.l %3,(%2)+\n"
+ " subq.l #1,%0\n"
+ " jne 1b\n"
+ "2: btst #1,%5\n"
+ " jeq 4f\n"
+ "3: "MOVES".w (%1)+,%3\n"
+ " move.w %3,(%2)+\n"
+ "4: btst #0,%5\n"
+ " jeq 6f\n"
+ "5: "MOVES".b (%1)+,%3\n"
+ " move.b %3,(%2)+\n"
+ "6:\n"
+ " .section .fixup,\"ax\"\n"
+ " .even\n"
+ "10: lsl.l #2,%0\n"
+ " btst #1,%5\n"
+ " jeq 8f\n"
+ "30: addq.l #2,%0\n"
+ "8: btst #0,%5\n"
+ " jeq 6b\n"
+ "50: addq.l #1,%0\n"
+ " jra 6b\n"
+ " .previous\n"
+ "\n"
+ " .section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,10b\n"
+ " .long 3b,30b\n"
+ " .long 5b,50b\n"
+ " .previous"
+ : "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
+ : "0" (n / 4), "d" (n & 3));
+
+ return res;
+}
+EXPORT_SYMBOL(__generic_copy_from_user);
+
+unsigned long __generic_copy_to_user(void __user *to, const void *from,
+ unsigned long n)
+{
+ unsigned long tmp, res;
+
+ asm volatile ("\n"
+ " tst.l %0\n"
+ " jeq 4f\n"
+ "1: move.l (%1)+,%3\n"
+ "2: "MOVES".l %3,(%2)+\n"
+ "3: subq.l #1,%0\n"
+ " jne 1b\n"
+ "4: btst #1,%5\n"
+ " jeq 6f\n"
+ " move.w (%1)+,%3\n"
+ "5: "MOVES".w %3,(%2)+\n"
+ "6: btst #0,%5\n"
+ " jeq 8f\n"
+ " move.b (%1)+,%3\n"
+ "7: "MOVES".b %3,(%2)+\n"
+ "8:\n"
+ " .section .fixup,\"ax\"\n"
+ " .even\n"
+ "20: lsl.l #2,%0\n"
+ "50: add.l %5,%0\n"
+ " jra 8b\n"
+ " .previous\n"
+ "\n"
+ " .section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 2b,20b\n"
+ " .long 3b,20b\n"
+ " .long 5b,50b\n"
+ " .long 6b,50b\n"
+ " .long 7b,50b\n"
+ " .long 8b,50b\n"
+ " .previous"
+ : "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
+ : "0" (n / 4), "d" (n & 3));
+
+ return res;
+}
+EXPORT_SYMBOL(__generic_copy_to_user);
+
+/*
+ * Zero Userspace
+ */
+
+unsigned long __clear_user(void __user *to, unsigned long n)
+{
+ unsigned long res;
+
+ asm volatile ("\n"
+ " tst.l %0\n"
+ " jeq 3f\n"
+ "1: "MOVES".l %2,(%1)+\n"
+ "2: subq.l #1,%0\n"
+ " jne 1b\n"
+ "3: btst #1,%4\n"
+ " jeq 5f\n"
+ "4: "MOVES".w %2,(%1)+\n"
+ "5: btst #0,%4\n"
+ " jeq 7f\n"
+ "6: "MOVES".b %2,(%1)\n"
+ "7:\n"
+ " .section .fixup,\"ax\"\n"
+ " .even\n"
+ "10: lsl.l #2,%0\n"
+ "40: add.l %4,%0\n"
+ " jra 7b\n"
+ " .previous\n"
+ "\n"
+ " .section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,10b\n"
+ " .long 2b,10b\n"
+ " .long 4b,40b\n"
+ " .long 5b,40b\n"
+ " .long 6b,40b\n"
+ " .long 7b,40b\n"
+ " .previous"
+ : "=d" (res), "+a" (to)
+ : "d" (0), "0" (n / 4), "d" (n & 3));
+
+ return res;
+}
+EXPORT_SYMBOL(__clear_user);