Re: [PATCH 4/4 v8] kdump/vmcore: support encrypted old memory with SME enabled
Hi Lianbo, Thank you for the patch! Yet something to improve: [auto build test ERROR on sof-driver-fuweitax/master] [also build test ERROR on v4.19-rc5 next-20180928] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Lianbo-Jiang/Support-kdump-for-AMD-secure-memory-encryption-SME/20180930-001539 base: https://github.com/fuweitax/linux master config: i386-randconfig-x0-09300051 (attached as .config) compiler: gcc-5 (Debian 5.5.0-3) 5.4.1 20171010 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): fs/proc/vmcore.o: In function `read_from_oldmem': >> fs/proc/vmcore.c:115: undefined reference to `copy_oldmem_page_encrypted' vim +115 fs/proc/vmcore.c 88 89 /* Reads a page from the oldmem device from given offset. */ 90 static ssize_t read_from_oldmem(char *buf, size_t count, 91 u64 *ppos, int userbuf, 92 bool encrypted) 93 { 94 unsigned long pfn, offset; 95 size_t nr_bytes; 96 ssize_t read = 0, tmp; 97 98 if (!count) 99 return 0; 100 101 offset = (unsigned long)(*ppos % PAGE_SIZE); 102 pfn = (unsigned long)(*ppos / PAGE_SIZE); 103 104 do { 105 if (count > (PAGE_SIZE - offset)) 106 nr_bytes = PAGE_SIZE - offset; 107 else 108 nr_bytes = count; 109 110 /* If pfn is not ram, return zeros for sparse dump files */ 111 if (pfn_is_ram(pfn) == 0) 112 memset(buf, 0, nr_bytes); 113 else { 114 if (encrypted) > 115 tmp = copy_oldmem_page_encrypted(pfn, > buf, 116 nr_bytes, 117 offset, 118 userbuf); 119 else 120 tmp = copy_oldmem_page(pfn, buf, nr_bytes, 121 offset, userbuf); 122 123 if (tmp < 0) 124 return tmp; 125 } 126 *ppos += nr_bytes; 127 count -= nr_bytes; 128 buf += nr_bytes; 129 read += nr_bytes; 130 ++pfn; 131 offset = 0; 132 } while (count); 133 134 return read; 135 } 136 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH 4/4 v8] kdump/vmcore: support encrypted old memory with SME enabled
在 2018年09月30日 02:25, kbuild test robot 写道: > Hi Lianbo, > > Thank you for the patch! Yet something to improve: > > [auto build test ERROR on sof-driver-fuweitax/master] > [also build test ERROR on v4.19-rc5 next-20180928] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Lianbo-Jiang/Support-kdump-for-AMD-secure-memory-encryption-SME/20180930-001539 > base: https://github.com/fuweitax/linux master > config: i386-randconfig-x0-09300051 (attached as .config) > compiler: gcc-5 (Debian 5.5.0-3) 5.4.1 20171010 > reproduce: > # save the attached .config to linux build tree > make ARCH=i386 > > All errors (new ones prefixed by >>): > >fs/proc/vmcore.o: In function `read_from_oldmem': >>> fs/proc/vmcore.c:115: undefined reference to `copy_oldmem_page_encrypted' > Ok, i will fix this compile error, and post again later. Thanks. > vim +115 fs/proc/vmcore.c > > 88 > 89/* Reads a page from the oldmem device from given offset. */ > 90static ssize_t read_from_oldmem(char *buf, size_t count, > 91u64 *ppos, int userbuf, > 92bool encrypted) > 93{ > 94unsigned long pfn, offset; > 95size_t nr_bytes; > 96ssize_t read = 0, tmp; > 97 > 98if (!count) > 99return 0; >100 >101offset = (unsigned long)(*ppos % PAGE_SIZE); >102pfn = (unsigned long)(*ppos / PAGE_SIZE); >103 >104do { >105if (count > (PAGE_SIZE - offset)) >106nr_bytes = PAGE_SIZE - offset; >107else >108nr_bytes = count; >109 >110/* If pfn is not ram, return zeros for sparse > dump files */ >111if (pfn_is_ram(pfn) == 0) >112memset(buf, 0, nr_bytes); >113else { >114if (encrypted) > > 115tmp = > copy_oldmem_page_encrypted(pfn, buf, >116 > nr_bytes, >117 > offset, >118 > userbuf); >119else >120tmp = copy_oldmem_page(pfn, > buf, nr_bytes, >121 offset, > userbuf); >122 >123if (tmp < 0) >124return tmp; >125} >126*ppos += nr_bytes; >127count -= nr_bytes; >128buf += nr_bytes; >129read += nr_bytes; >130++pfn; >131offset = 0; >132} while (count); >133 >134return read; >135} >136 > > --- > 0-DAY kernel test infrastructureOpen Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation > ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH 4/4 v8] kdump/vmcore: support encrypted old memory with SME enabled
In kdump kernel, the old memory needs to be dumped into vmcore file. If SME is enabled in the first kernel, the old memory has to be remapped with the memory encryption mask, which will be automatically decrypted when read from DRAM. For SME kdump, there are two cases that doesn't support: -- | first-kernel | second-kernel | kdump support | | (mem_encrypt=on|off)| (yes|no)| |--+---+---| | on | on| yes | | off | off | yes | | on | off | no| | off | on| no| |__|___|___| 1. SME is enabled in the first kernel, but SME is disabled in kdump kernel In this case, because the old memory is encrypted, it can't be decrypted. The root cause is that the encryption key is not visible to any software runnint on the CPU cores(AMD cpu with SME), and is randomly generated on eache system reset. That is to say, kdump kernel won't have a chance to get the encryption key. So the encrypted memory can not be decrypted unless SME is active. 2. SME is disabled in the first kernel, but SME is enabled in kdump kernel On the one hand, the old memory is decrypted, the old memory can be dumped as usual, so SME doesn't need to be enabled in kdump kernel; On the other hand, it will increase the complexity of the code, because that will have to consider how to pass the SME flag from the first kernel to the kdump kernel, it is really too expensive to do this. This patches are only for SME kdump, the patches don't support SEV kdump. Signed-off-by: Lianbo Jiang Reviewed-by: Tom Lendacky --- Changes since v7: 1. Delete a file arch/x86/kernel/crash_dump_encrypt.c, and move the copy_oldmem_page_encrypted() to arch/x86/kernel/crash_dump_64.c, also rewrite some functions.(Suggested by Borislav) 2. Modify all code style issue.(Suggested by Borislav) 3. Remove a reduntant header file.(Suggested by Borislav) 4. Improve patch log.(Suggested by Borislav) arch/x86/kernel/crash_dump_64.c | 65 - fs/proc/vmcore.c| 24 +--- include/linux/crash_dump.h | 3 ++ 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index 4f2e0778feac..6adbde592c44 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -12,7 +12,7 @@ #include /** - * copy_oldmem_page - copy one page from "oldmem" + * __copy_oldmem_page - copy one page from "old memory encrypted or decrypted" * @pfn: page frame number to be copied * @buf: target memory address for the copy; this can be in kernel address * space or user address space (see @userbuf) @@ -20,31 +20,78 @@ * @offset: offset in bytes into the page (based on pfn) to begin the copy * @userbuf: if set, @buf is in user address space, use copy_to_user(), * otherwise @buf is in kernel address space, use memcpy(). + * @encrypted: if true, the old memory is encrypted. + * if false, the old memory is decrypted. * - * Copy a page from "oldmem". For this page, there is no pte mapped - * in the current kernel. We stitch up a pte, similar to kmap_atomic. + * Copy a page from "old memory encrypted or decrypted". For this page, there + * is no pte mapped in the current kernel. We stitch up a pte, similar to + * kmap_atomic. */ -ssize_t copy_oldmem_page(unsigned long pfn, char *buf, - size_t csize, unsigned long offset, int userbuf) +static ssize_t __copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, + unsigned long offset, int userbuf, + bool encrypted) { void *vaddr; if (!csize) return 0; - vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE); + if (encrypted) + vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT, PAGE_SIZE); + else + vaddr = (__force void *)ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE); + if (!vaddr) return -ENOMEM; if (userbuf) { - if (copy_to_user(buf, vaddr + offset, csize)) { - iounmap(vaddr); + if (copy_to_user((void __user *)buf, vaddr + offset, csize)) { + iounmap((void __iomem *)vaddr); return -EFAULT; } } else memcpy(buf, vaddr + offset, csize); set_iounmap_nonlazy(); - iounmap(vaddr); + iounmap((void __iomem *)vaddr); return csize; } + +/** + * copy_oldmem_page - copy one page from "old memory decrypted" + * @pfn: page frame number to be copied + * @buf: target memory address for the copy; this can be in kernel address + * space or user address space (see @userbuf) + *