powerpc/pseries/svm: Unshare all pages before kexecing a new kernel
authorRam Pai <linuxram@us.ibm.com>
Tue, 20 Aug 2019 02:13:20 +0000 (23:13 -0300)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 29 Aug 2019 23:55:40 +0000 (09:55 +1000)
A new kernel deserves a clean slate. Any pages shared with the hypervisor
is unshared before invoking the new kernel. However there are exceptions.
If the new kernel is invoked to dump the current kernel, or if there is a
explicit request to preserve the state of the current kernel, unsharing
of pages is skipped.

NOTE: While testing crashkernel, make sure at least 256M is reserved for
crashkernel. Otherwise SWIOTLB allocation will fail and crash kernel will
fail to boot.

Signed-off-by: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190820021326.6884-11-bauerman@linux.ibm.com
arch/powerpc/include/asm/ultravisor-api.h
arch/powerpc/include/asm/ultravisor.h
arch/powerpc/kernel/machine_kexec_64.c

index 0f5b2d718bfcd104f7129be7e5749bb1755b61aa..4fcda1d5793da9ae178b04c718912277c7e1f554 100644 (file)
@@ -28,5 +28,6 @@
 #define UV_ESM                         0xF110
 #define UV_SHARE_PAGE                  0xF130
 #define UV_UNSHARE_PAGE                        0xF134
+#define UV_UNSHARE_ALL_PAGES           0xF140
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
index e5c8413de06f109c046ded1eaa1388ab1ded410a..b1bc2e043ed483d686a0995ade4c3620b7346c70 100644 (file)
@@ -41,4 +41,9 @@ static inline int uv_unshare_page(u64 pfn, u64 npages)
        return ucall_norets(UV_UNSHARE_PAGE, pfn, npages);
 }
 
+static inline int uv_unshare_all_pages(void)
+{
+       return ucall_norets(UV_UNSHARE_ALL_PAGES);
+}
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
index 18481b0e2788a4d2194656574665899742f1cae0..04a7cba58eff4fc13a13030400a57176776fdbf7 100644 (file)
@@ -29,6 +29,8 @@
 #include <asm/smp.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/asm-prototypes.h>
+#include <asm/svm.h>
+#include <asm/ultravisor.h>
 
 int default_machine_kexec_prepare(struct kimage *image)
 {
@@ -327,6 +329,13 @@ void default_machine_kexec(struct kimage *image)
 #ifdef CONFIG_PPC_PSERIES
        kexec_paca.lppaca_ptr = NULL;
 #endif
+
+       if (is_secure_guest() && !(image->preserve_context ||
+                                  image->type == KEXEC_TYPE_CRASH)) {
+               uv_unshare_all_pages();
+               printk("kexec: Unshared all shared pages.\n");
+       }
+
        paca_ptrs[kexec_paca.paca_index] = &kexec_paca;
 
        setup_paca(&kexec_paca);