Re: [PATCH 4/4 v8] kdump/vmcore: support encrypted old memory with SME enabled

2018-10-01 Thread 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'

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-29 Thread lijiang
在 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

2018-09-29 Thread Lianbo Jiang
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)
+ *