All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-16  8:27 ` Lianbo Jiang
  0 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: iommu, kexec, thomas.lendacky, dyoung

It is convenient to remap the old memory encrypted to the second kernel by
calling ioremap_encrypted().

When sme enabled on AMD server, we also need to support kdump. Because
the memory is encrypted in the first kernel, we will remap the old memory
encrypted to the second kernel(crash kernel), and sme is also enabled in
the second kernel, otherwise the old memory encrypted can not be decrypted.
Because simply changing the value of a C-bit on a page will not
automatically encrypt the existing contents of a page, and any data in the
page prior to the C-bit modification will become unintelligible. A page of
memory that is marked encrypted will be automatically decrypted when read
from DRAM and will be automatically encrypted when written to DRAM.

For the kdump, it is necessary to distinguish whether the memory is
encrypted. Furthermore, we should also know which part of the memory is
encrypted or decrypted. We will appropriately remap the memory according
to the specific situation in order to tell cpu how to deal with the
data(encrypted or decrypted). For example, when sme enabled, if the old
memory is encrypted, we will remap the old memory in encrypted way, which
will automatically decrypt the old memory encrypted when we read those data
from the remapping address.

 ----------------------------------------------
| first-kernel | second-kernel | kdump support |
|      (mem_encrypt=on|off)    |   (yes|no)    |
|--------------+---------------+---------------|
|     on       |     on        |     yes       |
|     off      |     off       |     yes       |
|     on       |     off       |     no        |
|     off      |     on        |     no        |
|______________|_______________|_______________|

This patch is only for SME kdump, it is not support SEV kdump.

Test tools:
makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
Author: Lianbo Jiang <lijiang@redhat.com>
Date:   Mon May 14 17:02:40 2018 +0800
Note: This patch can only dump vmcore in the case of SME enabled.

crash-7.2.1: https://github.com/crash-utility/crash.git
commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
Author: Dave Anderson <anderson@redhat.com>
Date:   Fri May 11 15:54:32 2018 -0400

Test environment:
HP ProLiant DL385Gen10 AMD EPYC 7251
8-Core Processor
32768 MB memory
600 GB disk space

Linux 4.17-rc7:
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
commit b04e217704b7 ("Linux 4.17-rc7")
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sun May 27 13:01:47 2018 -0700

Reference:
AMD64 Architecture Programmer's Manual
https://support.amd.com/TechDocs/24593.pdf

Some changes:
1. remove the sme_active() check in __ioremap_caller().
2. remove the '#ifdef' stuff throughout this patch.
3. put some logic into the early_memremap_pgprot_adjust() and clean the
previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
4. add a new file and modify Makefile.
5. clean compile warning in copy_device_table() and some compile error.
6. split the original patch into four patches, it will be better for
review.

Some known issues:
1. about SME
Upstream kernel doesn't work when we use kexec in the follow command. The
system will hang.
(This issue doesn't matter with the kdump patch.)

Reproduce steps:
 # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
 # kexec -e (or reboot)

The system will hang:
[ 1248.932239] kexec_core: Starting new kernel
early console in extract_kernel
input_data: 0x000000087e91c3b4
input_len: 0x000000000067fcbd
output: 0x000000087d400000
output_len: 0x0000000001b6fa90
kernel_total_size: 0x0000000001a9d000
trampoline_32bit: 0x0000000000099000

Decompressing Linux...
Parsing ELF...        [-here the system will hang]

2. about SEV
Upstream kernel(Host OS) doesn't work in host side, some drivers about
SEV always go wrong in host side. We can't boot SEV Guest OS to test
kdump patch. Maybe it is more reasonable to improve SEV in another
patch. When some drivers can work in host side and it can also boot
Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.

[  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
[  369.433177]       Not tainted 4.17.0-rc5+ #60
[  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  369.445783] systemd-udevd   D    0   865    813 0x80000004
[  369.451323] Call Trace:
[  369.453815]  ? __schedule+0x290/0x870
[  369.457523]  schedule+0x32/0x80
[  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
[  369.465556]  ? cleanup_uevent_env+0x10/0x10
[  369.470084]  ? remove_wait_queue+0x60/0x60
[  369.474219]  ? 0xffffffffc0247000
[  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
[  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
[  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
[  369.491380]  ? 0xffffffffc0247000
[  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
[  369.499071]  do_one_initcall+0x4e/0x1d4
[  369.502944]  ? _cond_resched+0x15/0x30
[  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
[  369.511386]  ? do_init_module+0x22/0x220
[  369.515345]  do_init_module+0x5a/0x220
[  369.519444]  load_module+0x21cb/0x2a50
[  369.523227]  ? m_show+0x1c0/0x1c0
[  369.526571]  ? security_capable+0x3f/0x60
[  369.530611]  __do_sys_finit_module+0x94/0xe0
[  369.534915]  do_syscall_64+0x5b/0x180
[  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  369.543698] RIP: 0033:0x7f708e6311b9
[  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
[  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
[  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
[  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
[  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000

Lianbo Jiang (4):
  Add a function(ioremap_encrypted) for kdump when AMD sme enabled
  Allocate pages for kdump without encryption when SME is enabled
  Remap the device table of IOMMU in encrypted manner for kdump
  Help to dump the old memory encrypted into vmcore file

 arch/x86/include/asm/io.h            |  3 ++
 arch/x86/kernel/Makefile             |  1 +
 arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
 arch/x86/mm/ioremap.c                | 28 +++++++++++++------
 drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
 fs/proc/vmcore.c                     | 20 ++++++++++----
 include/linux/crash_dump.h           | 11 ++++++++
 kernel/kexec_core.c                  | 12 ++++++++
 8 files changed, 128 insertions(+), 15 deletions(-)
 create mode 100644 arch/x86/kernel/crash_dump_encrypt.c

-- 
2.9.5


^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-16  8:27 ` Lianbo Jiang
  0 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: thomas.lendacky, iommu, dyoung, kexec

It is convenient to remap the old memory encrypted to the second kernel by
calling ioremap_encrypted().

When sme enabled on AMD server, we also need to support kdump. Because
the memory is encrypted in the first kernel, we will remap the old memory
encrypted to the second kernel(crash kernel), and sme is also enabled in
the second kernel, otherwise the old memory encrypted can not be decrypted.
Because simply changing the value of a C-bit on a page will not
automatically encrypt the existing contents of a page, and any data in the
page prior to the C-bit modification will become unintelligible. A page of
memory that is marked encrypted will be automatically decrypted when read
from DRAM and will be automatically encrypted when written to DRAM.

For the kdump, it is necessary to distinguish whether the memory is
encrypted. Furthermore, we should also know which part of the memory is
encrypted or decrypted. We will appropriately remap the memory according
to the specific situation in order to tell cpu how to deal with the
data(encrypted or decrypted). For example, when sme enabled, if the old
memory is encrypted, we will remap the old memory in encrypted way, which
will automatically decrypt the old memory encrypted when we read those data
from the remapping address.

 ----------------------------------------------
| first-kernel | second-kernel | kdump support |
|      (mem_encrypt=on|off)    |   (yes|no)    |
|--------------+---------------+---------------|
|     on       |     on        |     yes       |
|     off      |     off       |     yes       |
|     on       |     off       |     no        |
|     off      |     on        |     no        |
|______________|_______________|_______________|

This patch is only for SME kdump, it is not support SEV kdump.

Test tools:
makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
Author: Lianbo Jiang <lijiang@redhat.com>
Date:   Mon May 14 17:02:40 2018 +0800
Note: This patch can only dump vmcore in the case of SME enabled.

crash-7.2.1: https://github.com/crash-utility/crash.git
commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
Author: Dave Anderson <anderson@redhat.com>
Date:   Fri May 11 15:54:32 2018 -0400

Test environment:
HP ProLiant DL385Gen10 AMD EPYC 7251
8-Core Processor
32768 MB memory
600 GB disk space

Linux 4.17-rc7:
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
commit b04e217704b7 ("Linux 4.17-rc7")
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sun May 27 13:01:47 2018 -0700

Reference:
AMD64 Architecture Programmer's Manual
https://support.amd.com/TechDocs/24593.pdf

Some changes:
1. remove the sme_active() check in __ioremap_caller().
2. remove the '#ifdef' stuff throughout this patch.
3. put some logic into the early_memremap_pgprot_adjust() and clean the
previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
4. add a new file and modify Makefile.
5. clean compile warning in copy_device_table() and some compile error.
6. split the original patch into four patches, it will be better for
review.

Some known issues:
1. about SME
Upstream kernel doesn't work when we use kexec in the follow command. The
system will hang.
(This issue doesn't matter with the kdump patch.)

Reproduce steps:
 # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
 # kexec -e (or reboot)

The system will hang:
[ 1248.932239] kexec_core: Starting new kernel
early console in extract_kernel
input_data: 0x000000087e91c3b4
input_len: 0x000000000067fcbd
output: 0x000000087d400000
output_len: 0x0000000001b6fa90
kernel_total_size: 0x0000000001a9d000
trampoline_32bit: 0x0000000000099000

Decompressing Linux...
Parsing ELF...        [-here the system will hang]

2. about SEV
Upstream kernel(Host OS) doesn't work in host side, some drivers about
SEV always go wrong in host side. We can't boot SEV Guest OS to test
kdump patch. Maybe it is more reasonable to improve SEV in another
patch. When some drivers can work in host side and it can also boot
Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.

[  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
[  369.433177]       Not tainted 4.17.0-rc5+ #60
[  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  369.445783] systemd-udevd   D    0   865    813 0x80000004
[  369.451323] Call Trace:
[  369.453815]  ? __schedule+0x290/0x870
[  369.457523]  schedule+0x32/0x80
[  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
[  369.465556]  ? cleanup_uevent_env+0x10/0x10
[  369.470084]  ? remove_wait_queue+0x60/0x60
[  369.474219]  ? 0xffffffffc0247000
[  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
[  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
[  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
[  369.491380]  ? 0xffffffffc0247000
[  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
[  369.499071]  do_one_initcall+0x4e/0x1d4
[  369.502944]  ? _cond_resched+0x15/0x30
[  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
[  369.511386]  ? do_init_module+0x22/0x220
[  369.515345]  do_init_module+0x5a/0x220
[  369.519444]  load_module+0x21cb/0x2a50
[  369.523227]  ? m_show+0x1c0/0x1c0
[  369.526571]  ? security_capable+0x3f/0x60
[  369.530611]  __do_sys_finit_module+0x94/0xe0
[  369.534915]  do_syscall_64+0x5b/0x180
[  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  369.543698] RIP: 0033:0x7f708e6311b9
[  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
[  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
[  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
[  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
[  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000

Lianbo Jiang (4):
  Add a function(ioremap_encrypted) for kdump when AMD sme enabled
  Allocate pages for kdump without encryption when SME is enabled
  Remap the device table of IOMMU in encrypted manner for kdump
  Help to dump the old memory encrypted into vmcore file

 arch/x86/include/asm/io.h            |  3 ++
 arch/x86/kernel/Makefile             |  1 +
 arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
 arch/x86/mm/ioremap.c                | 28 +++++++++++++------
 drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
 fs/proc/vmcore.c                     | 20 ++++++++++----
 include/linux/crash_dump.h           | 11 ++++++++
 kernel/kexec_core.c                  | 12 ++++++++
 8 files changed, 128 insertions(+), 15 deletions(-)
 create mode 100644 arch/x86/kernel/crash_dump_encrypt.c

-- 
2.9.5


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled
  2018-06-16  8:27 ` Lianbo Jiang
@ 2018-06-16  8:27   ` Lianbo Jiang
  -1 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: iommu, kexec, thomas.lendacky, dyoung

It is convenient to remap the old memory encrypted to the second
kernel by calling ioremap_encrypted().

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
Some changes:
1. remove the sme_active() check in __ioremap_caller().
2. put some logic into the early_memremap_pgprot_adjust() for
early memremap.

 arch/x86/include/asm/io.h |  3 +++
 arch/x86/mm/ioremap.c     | 28 ++++++++++++++++++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index f6e5b93..989d60b 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -192,6 +192,9 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
 #define ioremap_cache ioremap_cache
 extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
 #define ioremap_prot ioremap_prot
+extern void __iomem *ioremap_encrypted(resource_size_t phys_addr,
+					unsigned long size);
+#define ioremap_encrypted ioremap_encrypted
 
 /**
  * ioremap     -   map bus memory into CPU space
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index c63a545..e365fc4 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -24,6 +24,7 @@
 #include <asm/pgalloc.h>
 #include <asm/pat.h>
 #include <asm/setup.h>
+#include <linux/crash_dump.h>
 
 #include "physaddr.h"
 
@@ -131,7 +132,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
  * caller shouldn't need to know that small detail.
  */
 static void __iomem *__ioremap_caller(resource_size_t phys_addr,
-		unsigned long size, enum page_cache_mode pcm, void *caller)
+		unsigned long size, enum page_cache_mode pcm,
+		void *caller, bool encrypted)
 {
 	unsigned long offset, vaddr;
 	resource_size_t last_addr;
@@ -199,7 +201,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
 	 * resulting mapping.
 	 */
 	prot = PAGE_KERNEL_IO;
-	if (sev_active() && mem_flags.desc_other)
+	if ((sev_active() && mem_flags.desc_other) || encrypted)
 		prot = pgprot_encrypted(prot);
 
 	switch (pcm) {
@@ -291,7 +293,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
 	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
 
 	return __ioremap_caller(phys_addr, size, pcm,
-				__builtin_return_address(0));
+				__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_nocache);
 
@@ -324,7 +326,7 @@ void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
 	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
 
 	return __ioremap_caller(phys_addr, size, pcm,
-				__builtin_return_address(0));
+				__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL_GPL(ioremap_uc);
 
@@ -341,7 +343,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
 void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
 {
 	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
-					__builtin_return_address(0));
+					__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_wc);
 
@@ -358,14 +360,21 @@ EXPORT_SYMBOL(ioremap_wc);
 void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
 {
 	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
-					__builtin_return_address(0));
+					__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_wt);
 
+void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
+{
+	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
+				__builtin_return_address(0), true);
+}
+EXPORT_SYMBOL(ioremap_encrypted);
+
 void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
 {
 	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
-				__builtin_return_address(0));
+				__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_cache);
 
@@ -374,7 +383,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
 {
 	return __ioremap_caller(phys_addr, size,
 				pgprot2cachemode(__pgprot(prot_val)),
-				__builtin_return_address(0));
+				__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_prot);
 
@@ -688,6 +697,9 @@ pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
 	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
 		encrypted_prot = false;
 
+	if (sme_active() && is_kdump_kernel())
+		encrypted_prot = false;
+
 	return encrypted_prot ? pgprot_encrypted(prot)
 			      : pgprot_decrypted(prot);
 }
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled
@ 2018-06-16  8:27   ` Lianbo Jiang
  0 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: thomas.lendacky, iommu, dyoung, kexec

It is convenient to remap the old memory encrypted to the second
kernel by calling ioremap_encrypted().

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
Some changes:
1. remove the sme_active() check in __ioremap_caller().
2. put some logic into the early_memremap_pgprot_adjust() for
early memremap.

 arch/x86/include/asm/io.h |  3 +++
 arch/x86/mm/ioremap.c     | 28 ++++++++++++++++++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index f6e5b93..989d60b 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -192,6 +192,9 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
 #define ioremap_cache ioremap_cache
 extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
 #define ioremap_prot ioremap_prot
+extern void __iomem *ioremap_encrypted(resource_size_t phys_addr,
+					unsigned long size);
+#define ioremap_encrypted ioremap_encrypted
 
 /**
  * ioremap     -   map bus memory into CPU space
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index c63a545..e365fc4 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -24,6 +24,7 @@
 #include <asm/pgalloc.h>
 #include <asm/pat.h>
 #include <asm/setup.h>
+#include <linux/crash_dump.h>
 
 #include "physaddr.h"
 
@@ -131,7 +132,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
  * caller shouldn't need to know that small detail.
  */
 static void __iomem *__ioremap_caller(resource_size_t phys_addr,
-		unsigned long size, enum page_cache_mode pcm, void *caller)
+		unsigned long size, enum page_cache_mode pcm,
+		void *caller, bool encrypted)
 {
 	unsigned long offset, vaddr;
 	resource_size_t last_addr;
@@ -199,7 +201,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
 	 * resulting mapping.
 	 */
 	prot = PAGE_KERNEL_IO;
-	if (sev_active() && mem_flags.desc_other)
+	if ((sev_active() && mem_flags.desc_other) || encrypted)
 		prot = pgprot_encrypted(prot);
 
 	switch (pcm) {
@@ -291,7 +293,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
 	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
 
 	return __ioremap_caller(phys_addr, size, pcm,
-				__builtin_return_address(0));
+				__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_nocache);
 
@@ -324,7 +326,7 @@ void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
 	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
 
 	return __ioremap_caller(phys_addr, size, pcm,
-				__builtin_return_address(0));
+				__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL_GPL(ioremap_uc);
 
@@ -341,7 +343,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
 void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
 {
 	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
-					__builtin_return_address(0));
+					__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_wc);
 
@@ -358,14 +360,21 @@ EXPORT_SYMBOL(ioremap_wc);
 void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
 {
 	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
-					__builtin_return_address(0));
+					__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_wt);
 
+void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
+{
+	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
+				__builtin_return_address(0), true);
+}
+EXPORT_SYMBOL(ioremap_encrypted);
+
 void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
 {
 	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
-				__builtin_return_address(0));
+				__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_cache);
 
@@ -374,7 +383,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
 {
 	return __ioremap_caller(phys_addr, size,
 				pgprot2cachemode(__pgprot(prot_val)),
-				__builtin_return_address(0));
+				__builtin_return_address(0), false);
 }
 EXPORT_SYMBOL(ioremap_prot);
 
@@ -688,6 +697,9 @@ pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
 	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
 		encrypted_prot = false;
 
+	if (sme_active() && is_kdump_kernel())
+		encrypted_prot = false;
+
 	return encrypted_prot ? pgprot_encrypted(prot)
 			      : pgprot_decrypted(prot);
 }
-- 
2.9.5


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-16  8:27   ` Lianbo Jiang
  0 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: iommu, kexec, thomas.lendacky, dyoung

When SME is enabled in the first kernel, we will allocate pages
for kdump without encryption in order to be able to boot the
second kernel in the same manner as kexec, which helps to keep
the same code style.

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
 kernel/kexec_core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 20fef1a..3c22a9b 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
 		}
 	}
 
+	if (pages) {
+		unsigned int count, i;
+
+		pages->mapping = NULL;
+		set_page_private(pages, order);
+		count = 1 << order;
+		for (i = 0; i < count; i++)
+			SetPageReserved(pages + i);
+		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
+	}
 	return pages;
 }
 
@@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
 			result  = -ENOMEM;
 			goto out;
 		}
+		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
 		ptr = kmap(page);
 		ptr += maddr & ~PAGE_MASK;
 		mchunk = min_t(size_t, mbytes,
@@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
 			result = copy_from_user(ptr, buf, uchunk);
 		kexec_flush_icache_page(page);
 		kunmap(page);
+		arch_kexec_pre_free_pages(page_address(page), 1);
 		if (result) {
 			result = -EFAULT;
 			goto out;
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-16  8:27   ` Lianbo Jiang
  0 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: thomas.lendacky-5C7GfCeVMHo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

When SME is enabled in the first kernel, we will allocate pages
for kdump without encryption in order to be able to boot the
second kernel in the same manner as kexec, which helps to keep
the same code style.

Signed-off-by: Lianbo Jiang <lijiang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 kernel/kexec_core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 20fef1a..3c22a9b 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
 		}
 	}
 
+	if (pages) {
+		unsigned int count, i;
+
+		pages->mapping = NULL;
+		set_page_private(pages, order);
+		count = 1 << order;
+		for (i = 0; i < count; i++)
+			SetPageReserved(pages + i);
+		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
+	}
 	return pages;
 }
 
@@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
 			result  = -ENOMEM;
 			goto out;
 		}
+		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
 		ptr = kmap(page);
 		ptr += maddr & ~PAGE_MASK;
 		mchunk = min_t(size_t, mbytes,
@@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
 			result = copy_from_user(ptr, buf, uchunk);
 		kexec_flush_icache_page(page);
 		kunmap(page);
+		arch_kexec_pre_free_pages(page_address(page), 1);
 		if (result) {
 			result = -EFAULT;
 			goto out;
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-16  8:27   ` Lianbo Jiang
  0 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: thomas.lendacky, iommu, dyoung, kexec

When SME is enabled in the first kernel, we will allocate pages
for kdump without encryption in order to be able to boot the
second kernel in the same manner as kexec, which helps to keep
the same code style.

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
 kernel/kexec_core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 20fef1a..3c22a9b 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
 		}
 	}
 
+	if (pages) {
+		unsigned int count, i;
+
+		pages->mapping = NULL;
+		set_page_private(pages, order);
+		count = 1 << order;
+		for (i = 0; i < count; i++)
+			SetPageReserved(pages + i);
+		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
+	}
 	return pages;
 }
 
@@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
 			result  = -ENOMEM;
 			goto out;
 		}
+		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
 		ptr = kmap(page);
 		ptr += maddr & ~PAGE_MASK;
 		mchunk = min_t(size_t, mbytes,
@@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
 			result = copy_from_user(ptr, buf, uchunk);
 		kexec_flush_icache_page(page);
 		kunmap(page);
+		arch_kexec_pre_free_pages(page_address(page), 1);
 		if (result) {
 			result = -EFAULT;
 			goto out;
-- 
2.9.5


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
  2018-06-16  8:27 ` Lianbo Jiang
@ 2018-06-16  8:27   ` Lianbo Jiang
  -1 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: iommu, kexec, thomas.lendacky, dyoung

In kdump mode, it will copy the device table of IOMMU from the old
device table, which is encrypted when SME is enabled in the first
kernel. So we must remap it in encrypted manner in order to be
automatically decrypted when we read.

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
Some changes:
1. add some comments
2. clean compile warning.

 drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575..a20af4c 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -889,11 +889,24 @@ static bool copy_device_table(void)
 	}
 
 	old_devtb_phys = entry & PAGE_MASK;
+
+	/*
+	 *  When sme enable in the first kernel, old_devtb_phys includes the
+	 *  memory encryption mask(sme_me_mask), we must remove the memory
+	 *  encryption mask to obtain the true physical address in kdump mode.
+	 */
+	if (mem_encrypt_active() && is_kdump_kernel())
+		old_devtb_phys = __sme_clr(old_devtb_phys);
+
 	if (old_devtb_phys >= 0x100000000ULL) {
 		pr_err("The address of old device table is above 4G, not trustworthy!\n");
 		return false;
 	}
-	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
+	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
+		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
+							dev_table_size)
+		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
+
 	if (!old_devtb)
 		return false;
 
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-16  8:27   ` Lianbo Jiang
  0 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: thomas.lendacky, iommu, dyoung, kexec

In kdump mode, it will copy the device table of IOMMU from the old
device table, which is encrypted when SME is enabled in the first
kernel. So we must remap it in encrypted manner in order to be
automatically decrypted when we read.

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
Some changes:
1. add some comments
2. clean compile warning.

 drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575..a20af4c 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -889,11 +889,24 @@ static bool copy_device_table(void)
 	}
 
 	old_devtb_phys = entry & PAGE_MASK;
+
+	/*
+	 *  When sme enable in the first kernel, old_devtb_phys includes the
+	 *  memory encryption mask(sme_me_mask), we must remove the memory
+	 *  encryption mask to obtain the true physical address in kdump mode.
+	 */
+	if (mem_encrypt_active() && is_kdump_kernel())
+		old_devtb_phys = __sme_clr(old_devtb_phys);
+
 	if (old_devtb_phys >= 0x100000000ULL) {
 		pr_err("The address of old device table is above 4G, not trustworthy!\n");
 		return false;
 	}
-	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
+	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
+		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
+							dev_table_size)
+		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
+
 	if (!old_devtb)
 		return false;
 
-- 
2.9.5


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
  2018-06-16  8:27 ` Lianbo Jiang
@ 2018-06-16  8:27   ` Lianbo Jiang
  -1 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: iommu, kexec, thomas.lendacky, dyoung

In kdump mode, we need to dump the old memory into vmcore file,
if SME is enabled in the first kernel, we must remap the old
memory in encrypted manner, which will be automatically decrypted
when we read from DRAM. It helps to parse the vmcore for some tools.

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
Some changes:
1. add a new file and modify Makefile.
2. remove some code in sev_active().

 arch/x86/kernel/Makefile             |  1 +
 arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
 fs/proc/vmcore.c                     | 20 ++++++++++----
 include/linux/crash_dump.h           | 11 ++++++++
 4 files changed, 79 insertions(+), 6 deletions(-)
 create mode 100644 arch/x86/kernel/crash_dump_encrypt.c

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 02d6f5c..afb5bad 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
 obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
+obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
 obj-y				+= kprobes/
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
new file mode 100644
index 0000000..e44ef33
--- /dev/null
+++ b/arch/x86/kernel/crash_dump_encrypt.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *	Memory preserving reboot related code.
+ *
+ *	Created by: Lianbo Jiang (lijiang@redhat.com)
+ *	Copyright (C) RedHat Corporation, 2018. All rights reserved
+ */
+
+#include <linux/errno.h>
+#include <linux/crash_dump.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+/**
+ * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
+ * @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)
+ * @csize: number of bytes to copy
+ * @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().
+ *
+ * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
+		size_t csize, unsigned long offset, int userbuf)
+{
+	void  *vaddr;
+
+	if (!csize)
+		return 0;
+
+	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
+						  PAGE_SIZE);
+	if (!vaddr)
+		return -ENOMEM;
+
+	if (userbuf) {
+		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((void __iomem *)vaddr);
+	return csize;
+}
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index a45f0af..5200266 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -25,6 +25,8 @@
 #include <linux/uaccess.h>
 #include <asm/io.h>
 #include "internal.h"
+#include <linux/mem_encrypt.h>
+#include <asm/pgtable.h>
 
 /* List representing chunks of contiguous memory areas and their offsets in
  * vmcore file.
@@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
 
 /* Reads a page from the oldmem device from given offset. */
 static ssize_t read_from_oldmem(char *buf, size_t count,
-				u64 *ppos, int userbuf)
+				u64 *ppos, int userbuf,
+				bool encrypted)
 {
 	unsigned long pfn, offset;
 	size_t nr_bytes;
@@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
 		if (pfn_is_ram(pfn) == 0)
 			memset(buf, 0, nr_bytes);
 		else {
-			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
-						offset, userbuf);
+			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
+					    buf, nr_bytes, offset, userbuf)
+					: copy_oldmem_page(pfn, buf, nr_bytes,
+							   offset, userbuf);
+
 			if (tmp < 0)
 				return tmp;
 		}
@@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
  */
 ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
 {
-	return read_from_oldmem(buf, count, ppos, 0);
+	return read_from_oldmem(buf, count, ppos, 0, false);
 }
 
 /*
@@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
  */
 ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
 {
-	return read_from_oldmem(buf, count, ppos, 0);
+	return read_from_oldmem(buf, count, ppos, 0, sme_active());
 }
 
 /*
@@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
 				  unsigned long from, unsigned long pfn,
 				  unsigned long size, pgprot_t prot)
 {
+	prot = pgprot_encrypted(prot);
 	return remap_pfn_range(vma, from, pfn, size, prot);
 }
 
@@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
 					    m->offset + m->size - *fpos,
 					    buflen);
 			start = m->paddr + *fpos - m->offset;
-			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
+			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
+						sme_active());
 			if (tmp < 0)
 				return tmp;
 			buflen -= tsz;
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index f7ac2aa..f3414ff 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
 
 extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
 						unsigned long, int);
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
+					   size_t csize, unsigned long offset,
+					   int userbuf);
+#else
+static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
+					size_t csize, unsigned long offset,
+					int userbuf) {
+	return csize;
+}
+#endif
 void vmcore_cleanup(void);
 
 /* Architecture code defines this if there are other possible ELF
-- 
2.9.5


^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-16  8:27   ` Lianbo Jiang
  0 siblings, 0 replies; 70+ messages in thread
From: Lianbo Jiang @ 2018-06-16  8:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: thomas.lendacky, iommu, dyoung, kexec

In kdump mode, we need to dump the old memory into vmcore file,
if SME is enabled in the first kernel, we must remap the old
memory in encrypted manner, which will be automatically decrypted
when we read from DRAM. It helps to parse the vmcore for some tools.

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
Some changes:
1. add a new file and modify Makefile.
2. remove some code in sev_active().

 arch/x86/kernel/Makefile             |  1 +
 arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
 fs/proc/vmcore.c                     | 20 ++++++++++----
 include/linux/crash_dump.h           | 11 ++++++++
 4 files changed, 79 insertions(+), 6 deletions(-)
 create mode 100644 arch/x86/kernel/crash_dump_encrypt.c

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 02d6f5c..afb5bad 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
 obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
+obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
 obj-y				+= kprobes/
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
new file mode 100644
index 0000000..e44ef33
--- /dev/null
+++ b/arch/x86/kernel/crash_dump_encrypt.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *	Memory preserving reboot related code.
+ *
+ *	Created by: Lianbo Jiang (lijiang@redhat.com)
+ *	Copyright (C) RedHat Corporation, 2018. All rights reserved
+ */
+
+#include <linux/errno.h>
+#include <linux/crash_dump.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+/**
+ * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
+ * @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)
+ * @csize: number of bytes to copy
+ * @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().
+ *
+ * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
+		size_t csize, unsigned long offset, int userbuf)
+{
+	void  *vaddr;
+
+	if (!csize)
+		return 0;
+
+	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
+						  PAGE_SIZE);
+	if (!vaddr)
+		return -ENOMEM;
+
+	if (userbuf) {
+		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((void __iomem *)vaddr);
+	return csize;
+}
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index a45f0af..5200266 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -25,6 +25,8 @@
 #include <linux/uaccess.h>
 #include <asm/io.h>
 #include "internal.h"
+#include <linux/mem_encrypt.h>
+#include <asm/pgtable.h>
 
 /* List representing chunks of contiguous memory areas and their offsets in
  * vmcore file.
@@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
 
 /* Reads a page from the oldmem device from given offset. */
 static ssize_t read_from_oldmem(char *buf, size_t count,
-				u64 *ppos, int userbuf)
+				u64 *ppos, int userbuf,
+				bool encrypted)
 {
 	unsigned long pfn, offset;
 	size_t nr_bytes;
@@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
 		if (pfn_is_ram(pfn) == 0)
 			memset(buf, 0, nr_bytes);
 		else {
-			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
-						offset, userbuf);
+			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
+					    buf, nr_bytes, offset, userbuf)
+					: copy_oldmem_page(pfn, buf, nr_bytes,
+							   offset, userbuf);
+
 			if (tmp < 0)
 				return tmp;
 		}
@@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
  */
 ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
 {
-	return read_from_oldmem(buf, count, ppos, 0);
+	return read_from_oldmem(buf, count, ppos, 0, false);
 }
 
 /*
@@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
  */
 ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
 {
-	return read_from_oldmem(buf, count, ppos, 0);
+	return read_from_oldmem(buf, count, ppos, 0, sme_active());
 }
 
 /*
@@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
 				  unsigned long from, unsigned long pfn,
 				  unsigned long size, pgprot_t prot)
 {
+	prot = pgprot_encrypted(prot);
 	return remap_pfn_range(vma, from, pfn, size, prot);
 }
 
@@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
 					    m->offset + m->size - *fpos,
 					    buflen);
 			start = m->paddr + *fpos - m->offset;
-			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
+			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
+						sme_active());
 			if (tmp < 0)
 				return tmp;
 			buflen -= tsz;
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index f7ac2aa..f3414ff 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
 
 extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
 						unsigned long, int);
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
+					   size_t csize, unsigned long offset,
+					   int userbuf);
+#else
+static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
+					size_t csize, unsigned long offset,
+					int userbuf) {
+	return csize;
+}
+#endif
 void vmcore_cleanup(void);
 
 /* Architecture code defines this if there are other possible ELF
-- 
2.9.5


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-19  3:16     ` Dave Young
  0 siblings, 0 replies; 70+ messages in thread
From: Dave Young @ 2018-06-19  3:16 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: linux-kernel, thomas.lendacky, iommu, kexec

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> In kdump mode, we need to dump the old memory into vmcore file,
> if SME is enabled in the first kernel, we must remap the old
> memory in encrypted manner, which will be automatically decrypted
> when we read from DRAM. It helps to parse the vmcore for some tools.
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. add a new file and modify Makefile.
> 2. remove some code in sev_active().
> 
>  arch/x86/kernel/Makefile             |  1 +
>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>  fs/proc/vmcore.c                     | 20 ++++++++++----
>  include/linux/crash_dump.h           | 11 ++++++++
>  4 files changed, 79 insertions(+), 6 deletions(-)
>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> 
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index 02d6f5c..afb5bad 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>  obj-y				+= kprobes/
>  obj-$(CONFIG_MODULES)		+= module.o
>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
> new file mode 100644
> index 0000000..e44ef33
> --- /dev/null
> +++ b/arch/x86/kernel/crash_dump_encrypt.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + *	Memory preserving reboot related code.
> + *
> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/crash_dump.h>
> +#include <linux/uaccess.h>
> +#include <linux/io.h>
> +
> +/**
> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
> + * @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)
> + * @csize: number of bytes to copy
> + * @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().
> + *
> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
> +		size_t csize, unsigned long offset, int userbuf)
> +{
> +	void  *vaddr;
> +
> +	if (!csize)
> +		return 0;
> +
> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
> +						  PAGE_SIZE);
> +	if (!vaddr)
> +		return -ENOMEM;
> +
> +	if (userbuf) {
> +		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((void __iomem *)vaddr);
> +	return csize;
> +}
> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
> index a45f0af..5200266 100644
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -25,6 +25,8 @@
>  #include <linux/uaccess.h>
>  #include <asm/io.h>
>  #include "internal.h"
> +#include <linux/mem_encrypt.h>
> +#include <asm/pgtable.h>
>  
>  /* List representing chunks of contiguous memory areas and their offsets in
>   * vmcore file.
> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>  
>  /* Reads a page from the oldmem device from given offset. */
>  static ssize_t read_from_oldmem(char *buf, size_t count,
> -				u64 *ppos, int userbuf)
> +				u64 *ppos, int userbuf,
> +				bool encrypted)
>  {
>  	unsigned long pfn, offset;
>  	size_t nr_bytes;
> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>  		if (pfn_is_ram(pfn) == 0)
>  			memset(buf, 0, nr_bytes);
>  		else {
> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
> -						offset, userbuf);
> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
> +					    buf, nr_bytes, offset, userbuf)
> +					: copy_oldmem_page(pfn, buf, nr_bytes,
> +							   offset, userbuf);
> +
>  			if (tmp < 0)
>  				return tmp;
>  		}
> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>   */
>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, false);

The elf header actually stays in kdump kernel reserved memory so it is
not "oldmem", the original function is misleading and doing unnecessary
things.  But as for your patch maybe using it as is is good for the time
being and add a code comment why the encrypted is "false".

	/* elfcorehdr stays in kdump kernel memory and it is not encrypted. */
	return read_from_oldmem(buf, count, ppos, 0, false);


I'm thinking to move the function to something like below, still not sure
memremap works on every arches or not, still need more test

diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index cfb6674331fd..40c01cc42b38 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -136,6 +136,24 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
 	return read;
 }
 
+static ssize_t read_from_mem(char *buf, size_t count, u64 *ppos)
+{
+	resource_size_t offset = (resource_size_t)*ppos;
+	char *kbuf;
+
+	if (!count)
+		return 0;
+
+	kbuf = memremap(offset, count, MEMREMAP_WB);
+	if (!kbuf)
+		return 0;
+
+	memcpy(buf, kbuf, count);
+	memunmap(kbuf);
+
+	return count;
+}
+
 /*
  * Architectures may override this function to allocate ELF header in 2nd kernel
  */
@@ -155,7 +173,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
  */
 ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
 {
-	return read_from_oldmem(buf, count, ppos, 0);
+	return read_from_mem(buf, count, ppos);
 }
 
 /*
 

>  }
>  
>  /*
> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>   */
>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>  }
>  
>  /*
> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  				  unsigned long from, unsigned long pfn,
>  				  unsigned long size, pgprot_t prot)
>  {
> +	prot = pgprot_encrypted(prot);
>  	return remap_pfn_range(vma, from, pfn, size, prot);
>  }
>  
> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>  					    m->offset + m->size - *fpos,
>  					    buflen);
>  			start = m->paddr + *fpos - m->offset;
> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
> +						sme_active());
>  			if (tmp < 0)
>  				return tmp;
>  			buflen -= tsz;
> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
> index f7ac2aa..f3414ff 100644
> --- a/include/linux/crash_dump.h
> +++ b/include/linux/crash_dump.h
> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  
>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>  						unsigned long, int);
> +#ifdef CONFIG_AMD_MEM_ENCRYPT
> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					   size_t csize, unsigned long offset,
> +					   int userbuf);
> +#else
> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					size_t csize, unsigned long offset,
> +					int userbuf) {

Personally I prefer below because it is too long:

static inline
ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
				   unsigned long offset, int userbuf)
{
	return 0;
}
			

> +	return csize;

As above it should be return 0;

> +}
> +#endif
>  void vmcore_cleanup(void);
>  
>  /* Architecture code defines this if there are other possible ELF
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

Thanks
Dave

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-19  3:16     ` Dave Young
  0 siblings, 0 replies; 70+ messages in thread
From: Dave Young @ 2018-06-19  3:16 UTC (permalink / raw)
  To: Lianbo Jiang
  Cc: thomas.lendacky-5C7GfCeVMHo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> In kdump mode, we need to dump the old memory into vmcore file,
> if SME is enabled in the first kernel, we must remap the old
> memory in encrypted manner, which will be automatically decrypted
> when we read from DRAM. It helps to parse the vmcore for some tools.
> 
> Signed-off-by: Lianbo Jiang <lijiang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> Some changes:
> 1. add a new file and modify Makefile.
> 2. remove some code in sev_active().
> 
>  arch/x86/kernel/Makefile             |  1 +
>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>  fs/proc/vmcore.c                     | 20 ++++++++++----
>  include/linux/crash_dump.h           | 11 ++++++++
>  4 files changed, 79 insertions(+), 6 deletions(-)
>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> 
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index 02d6f5c..afb5bad 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>  obj-y				+= kprobes/
>  obj-$(CONFIG_MODULES)		+= module.o
>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
> new file mode 100644
> index 0000000..e44ef33
> --- /dev/null
> +++ b/arch/x86/kernel/crash_dump_encrypt.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + *	Memory preserving reboot related code.
> + *
> + *	Created by: Lianbo Jiang (lijiang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org)
> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/crash_dump.h>
> +#include <linux/uaccess.h>
> +#include <linux/io.h>
> +
> +/**
> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
> + * @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)
> + * @csize: number of bytes to copy
> + * @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().
> + *
> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
> +		size_t csize, unsigned long offset, int userbuf)
> +{
> +	void  *vaddr;
> +
> +	if (!csize)
> +		return 0;
> +
> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
> +						  PAGE_SIZE);
> +	if (!vaddr)
> +		return -ENOMEM;
> +
> +	if (userbuf) {
> +		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((void __iomem *)vaddr);
> +	return csize;
> +}
> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
> index a45f0af..5200266 100644
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -25,6 +25,8 @@
>  #include <linux/uaccess.h>
>  #include <asm/io.h>
>  #include "internal.h"
> +#include <linux/mem_encrypt.h>
> +#include <asm/pgtable.h>
>  
>  /* List representing chunks of contiguous memory areas and their offsets in
>   * vmcore file.
> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>  
>  /* Reads a page from the oldmem device from given offset. */
>  static ssize_t read_from_oldmem(char *buf, size_t count,
> -				u64 *ppos, int userbuf)
> +				u64 *ppos, int userbuf,
> +				bool encrypted)
>  {
>  	unsigned long pfn, offset;
>  	size_t nr_bytes;
> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>  		if (pfn_is_ram(pfn) == 0)
>  			memset(buf, 0, nr_bytes);
>  		else {
> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
> -						offset, userbuf);
> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
> +					    buf, nr_bytes, offset, userbuf)
> +					: copy_oldmem_page(pfn, buf, nr_bytes,
> +							   offset, userbuf);
> +
>  			if (tmp < 0)
>  				return tmp;
>  		}
> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>   */
>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, false);

The elf header actually stays in kdump kernel reserved memory so it is
not "oldmem", the original function is misleading and doing unnecessary
things.  But as for your patch maybe using it as is is good for the time
being and add a code comment why the encrypted is "false".

	/* elfcorehdr stays in kdump kernel memory and it is not encrypted. */
	return read_from_oldmem(buf, count, ppos, 0, false);


I'm thinking to move the function to something like below, still not sure
memremap works on every arches or not, still need more test

diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index cfb6674331fd..40c01cc42b38 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -136,6 +136,24 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
 	return read;
 }
 
+static ssize_t read_from_mem(char *buf, size_t count, u64 *ppos)
+{
+	resource_size_t offset = (resource_size_t)*ppos;
+	char *kbuf;
+
+	if (!count)
+		return 0;
+
+	kbuf = memremap(offset, count, MEMREMAP_WB);
+	if (!kbuf)
+		return 0;
+
+	memcpy(buf, kbuf, count);
+	memunmap(kbuf);
+
+	return count;
+}
+
 /*
  * Architectures may override this function to allocate ELF header in 2nd kernel
  */
@@ -155,7 +173,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
  */
 ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
 {
-	return read_from_oldmem(buf, count, ppos, 0);
+	return read_from_mem(buf, count, ppos);
 }
 
 /*
 

>  }
>  
>  /*
> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>   */
>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>  }
>  
>  /*
> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  				  unsigned long from, unsigned long pfn,
>  				  unsigned long size, pgprot_t prot)
>  {
> +	prot = pgprot_encrypted(prot);
>  	return remap_pfn_range(vma, from, pfn, size, prot);
>  }
>  
> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>  					    m->offset + m->size - *fpos,
>  					    buflen);
>  			start = m->paddr + *fpos - m->offset;
> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
> +						sme_active());
>  			if (tmp < 0)
>  				return tmp;
>  			buflen -= tsz;
> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
> index f7ac2aa..f3414ff 100644
> --- a/include/linux/crash_dump.h
> +++ b/include/linux/crash_dump.h
> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  
>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>  						unsigned long, int);
> +#ifdef CONFIG_AMD_MEM_ENCRYPT
> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					   size_t csize, unsigned long offset,
> +					   int userbuf);
> +#else
> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					size_t csize, unsigned long offset,
> +					int userbuf) {

Personally I prefer below because it is too long:

static inline
ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
				   unsigned long offset, int userbuf)
{
	return 0;
}
			

> +	return csize;

As above it should be return 0;

> +}
> +#endif
>  void vmcore_cleanup(void);
>  
>  /* Architecture code defines this if there are other possible ELF
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/kexec

Thanks
Dave

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-19  3:16     ` Dave Young
  0 siblings, 0 replies; 70+ messages in thread
From: Dave Young @ 2018-06-19  3:16 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: thomas.lendacky, iommu, kexec, linux-kernel

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> In kdump mode, we need to dump the old memory into vmcore file,
> if SME is enabled in the first kernel, we must remap the old
> memory in encrypted manner, which will be automatically decrypted
> when we read from DRAM. It helps to parse the vmcore for some tools.
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. add a new file and modify Makefile.
> 2. remove some code in sev_active().
> 
>  arch/x86/kernel/Makefile             |  1 +
>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>  fs/proc/vmcore.c                     | 20 ++++++++++----
>  include/linux/crash_dump.h           | 11 ++++++++
>  4 files changed, 79 insertions(+), 6 deletions(-)
>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> 
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index 02d6f5c..afb5bad 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>  obj-y				+= kprobes/
>  obj-$(CONFIG_MODULES)		+= module.o
>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
> new file mode 100644
> index 0000000..e44ef33
> --- /dev/null
> +++ b/arch/x86/kernel/crash_dump_encrypt.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + *	Memory preserving reboot related code.
> + *
> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/crash_dump.h>
> +#include <linux/uaccess.h>
> +#include <linux/io.h>
> +
> +/**
> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
> + * @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)
> + * @csize: number of bytes to copy
> + * @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().
> + *
> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
> +		size_t csize, unsigned long offset, int userbuf)
> +{
> +	void  *vaddr;
> +
> +	if (!csize)
> +		return 0;
> +
> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
> +						  PAGE_SIZE);
> +	if (!vaddr)
> +		return -ENOMEM;
> +
> +	if (userbuf) {
> +		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((void __iomem *)vaddr);
> +	return csize;
> +}
> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
> index a45f0af..5200266 100644
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -25,6 +25,8 @@
>  #include <linux/uaccess.h>
>  #include <asm/io.h>
>  #include "internal.h"
> +#include <linux/mem_encrypt.h>
> +#include <asm/pgtable.h>
>  
>  /* List representing chunks of contiguous memory areas and their offsets in
>   * vmcore file.
> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>  
>  /* Reads a page from the oldmem device from given offset. */
>  static ssize_t read_from_oldmem(char *buf, size_t count,
> -				u64 *ppos, int userbuf)
> +				u64 *ppos, int userbuf,
> +				bool encrypted)
>  {
>  	unsigned long pfn, offset;
>  	size_t nr_bytes;
> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>  		if (pfn_is_ram(pfn) == 0)
>  			memset(buf, 0, nr_bytes);
>  		else {
> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
> -						offset, userbuf);
> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
> +					    buf, nr_bytes, offset, userbuf)
> +					: copy_oldmem_page(pfn, buf, nr_bytes,
> +							   offset, userbuf);
> +
>  			if (tmp < 0)
>  				return tmp;
>  		}
> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>   */
>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, false);

The elf header actually stays in kdump kernel reserved memory so it is
not "oldmem", the original function is misleading and doing unnecessary
things.  But as for your patch maybe using it as is is good for the time
being and add a code comment why the encrypted is "false".

	/* elfcorehdr stays in kdump kernel memory and it is not encrypted. */
	return read_from_oldmem(buf, count, ppos, 0, false);


I'm thinking to move the function to something like below, still not sure
memremap works on every arches or not, still need more test

diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index cfb6674331fd..40c01cc42b38 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -136,6 +136,24 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
 	return read;
 }
 
+static ssize_t read_from_mem(char *buf, size_t count, u64 *ppos)
+{
+	resource_size_t offset = (resource_size_t)*ppos;
+	char *kbuf;
+
+	if (!count)
+		return 0;
+
+	kbuf = memremap(offset, count, MEMREMAP_WB);
+	if (!kbuf)
+		return 0;
+
+	memcpy(buf, kbuf, count);
+	memunmap(kbuf);
+
+	return count;
+}
+
 /*
  * Architectures may override this function to allocate ELF header in 2nd kernel
  */
@@ -155,7 +173,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
  */
 ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
 {
-	return read_from_oldmem(buf, count, ppos, 0);
+	return read_from_mem(buf, count, ppos);
 }
 
 /*
 

>  }
>  
>  /*
> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>   */
>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>  }
>  
>  /*
> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  				  unsigned long from, unsigned long pfn,
>  				  unsigned long size, pgprot_t prot)
>  {
> +	prot = pgprot_encrypted(prot);
>  	return remap_pfn_range(vma, from, pfn, size, prot);
>  }
>  
> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>  					    m->offset + m->size - *fpos,
>  					    buflen);
>  			start = m->paddr + *fpos - m->offset;
> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
> +						sme_active());
>  			if (tmp < 0)
>  				return tmp;
>  			buflen -= tsz;
> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
> index f7ac2aa..f3414ff 100644
> --- a/include/linux/crash_dump.h
> +++ b/include/linux/crash_dump.h
> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  
>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>  						unsigned long, int);
> +#ifdef CONFIG_AMD_MEM_ENCRYPT
> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					   size_t csize, unsigned long offset,
> +					   int userbuf);
> +#else
> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					size_t csize, unsigned long offset,
> +					int userbuf) {

Personally I prefer below because it is too long:

static inline
ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
				   unsigned long offset, int userbuf)
{
	return 0;
}
			

> +	return csize;

As above it should be return 0;

> +}
> +#endif
>  void vmcore_cleanup(void);
>  
>  /* Architecture code defines this if there are other possible ELF
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

Thanks
Dave

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
  2018-06-19  3:16     ` Dave Young
@ 2018-06-19 14:46       ` lijiang
  -1 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-19 14:46 UTC (permalink / raw)
  To: Dave Young; +Cc: linux-kernel, thomas.lendacky, iommu, kexec

在 2018年06月19日 11:16, Dave Young 写道:
> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>> In kdump mode, we need to dump the old memory into vmcore file,
>> if SME is enabled in the first kernel, we must remap the old
>> memory in encrypted manner, which will be automatically decrypted
>> when we read from DRAM. It helps to parse the vmcore for some tools.
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>> Some changes:
>> 1. add a new file and modify Makefile.
>> 2. remove some code in sev_active().
>>
>>  arch/x86/kernel/Makefile             |  1 +
>>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>>  fs/proc/vmcore.c                     | 20 ++++++++++----
>>  include/linux/crash_dump.h           | 11 ++++++++
>>  4 files changed, 79 insertions(+), 6 deletions(-)
>>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
>>
>> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
>> index 02d6f5c..afb5bad 100644
>> --- a/arch/x86/kernel/Makefile
>> +++ b/arch/x86/kernel/Makefile
>> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
>> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>>  obj-y				+= kprobes/
>>  obj-$(CONFIG_MODULES)		+= module.o
>>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
>> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
>> new file mode 100644
>> index 0000000..e44ef33
>> --- /dev/null
>> +++ b/arch/x86/kernel/crash_dump_encrypt.c
>> @@ -0,0 +1,53 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + *	Memory preserving reboot related code.
>> + *
>> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
>> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
>> + */
>> +
>> +#include <linux/errno.h>
>> +#include <linux/crash_dump.h>
>> +#include <linux/uaccess.h>
>> +#include <linux/io.h>
>> +
>> +/**
>> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
>> + * @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)
>> + * @csize: number of bytes to copy
>> + * @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().
>> + *
>> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
>> +		size_t csize, unsigned long offset, int userbuf)
>> +{
>> +	void  *vaddr;
>> +
>> +	if (!csize)
>> +		return 0;
>> +
>> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
>> +						  PAGE_SIZE);
>> +	if (!vaddr)
>> +		return -ENOMEM;
>> +
>> +	if (userbuf) {
>> +		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((void __iomem *)vaddr);
>> +	return csize;
>> +}
>> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
>> index a45f0af..5200266 100644
>> --- a/fs/proc/vmcore.c
>> +++ b/fs/proc/vmcore.c
>> @@ -25,6 +25,8 @@
>>  #include <linux/uaccess.h>
>>  #include <asm/io.h>
>>  #include "internal.h"
>> +#include <linux/mem_encrypt.h>
>> +#include <asm/pgtable.h>
>>  
>>  /* List representing chunks of contiguous memory areas and their offsets in
>>   * vmcore file.
>> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>>  
>>  /* Reads a page from the oldmem device from given offset. */
>>  static ssize_t read_from_oldmem(char *buf, size_t count,
>> -				u64 *ppos, int userbuf)
>> +				u64 *ppos, int userbuf,
>> +				bool encrypted)
>>  {
>>  	unsigned long pfn, offset;
>>  	size_t nr_bytes;
>> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>>  		if (pfn_is_ram(pfn) == 0)
>>  			memset(buf, 0, nr_bytes);
>>  		else {
>> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
>> -						offset, userbuf);
>> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
>> +					    buf, nr_bytes, offset, userbuf)
>> +					: copy_oldmem_page(pfn, buf, nr_bytes,
>> +							   offset, userbuf);
>> +
>>  			if (tmp < 0)
>>  				return tmp;
>>  		}
>> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>>   */
>>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>  {
>> -	return read_from_oldmem(buf, count, ppos, 0);
>> +	return read_from_oldmem(buf, count, ppos, 0, false);
> 
> The elf header actually stays in kdump kernel reserved memory so it is
> not "oldmem", the original function is misleading and doing unnecessary
> things.  But as for your patch maybe using it as is is good for the time
> being and add a code comment why the encrypted is "false".
> 
Thank you, Dave. It is a good idea to add some comments for the code.
I rechecked the code, the elf header should be still the old memory in the first kernel,
but why is the old memory unencrypted? Because it copies the elf header from the memory
encrypted(user space) to the memory unencrypted(kernel space) when SME is activated in the
first kernel, this operation just leads to decryption.

Thanks.
Lianbo
> 	/* elfcorehdr stays in kdump kernel memory and it is not encrypted. */
> 	return read_from_oldmem(buf, count, ppos, 0, false);
> 
> 
> I'm thinking to move the function to something like below, still not sure
> memremap works on every arches or not, still need more test
> 
> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
> index cfb6674331fd..40c01cc42b38 100644
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -136,6 +136,24 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>  	return read;
>  }
>  
> +static ssize_t read_from_mem(char *buf, size_t count, u64 *ppos)
> +{
> +	resource_size_t offset = (resource_size_t)*ppos;
> +	char *kbuf;
> +
> +	if (!count)
> +		return 0;
> +
> +	kbuf = memremap(offset, count, MEMREMAP_WB);
> +	if (!kbuf)
> +		return 0;
> +
> +	memcpy(buf, kbuf, count);
> +	memunmap(kbuf);
> +
> +	return count;
> +}
> +
>  /*
>   * Architectures may override this function to allocate ELF header in 2nd kernel
>   */
> @@ -155,7 +173,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>   */
>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_mem(buf, count, ppos);
>  }
>  
>  /*
>  
> 
>>  }
>>  
>>  /*
>> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>   */
>>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>>  {
>> -	return read_from_oldmem(buf, count, ppos, 0);
>> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>>  }
>>  
>>  /*
>> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>  				  unsigned long from, unsigned long pfn,
>>  				  unsigned long size, pgprot_t prot)
>>  {
>> +	prot = pgprot_encrypted(prot);
>>  	return remap_pfn_range(vma, from, pfn, size, prot);
>>  }
>>  
>> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>>  					    m->offset + m->size - *fpos,
>>  					    buflen);
>>  			start = m->paddr + *fpos - m->offset;
>> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
>> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
>> +						sme_active());
>>  			if (tmp < 0)
>>  				return tmp;
>>  			buflen -= tsz;
>> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
>> index f7ac2aa..f3414ff 100644
>> --- a/include/linux/crash_dump.h
>> +++ b/include/linux/crash_dump.h
>> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>  
>>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>>  						unsigned long, int);
>> +#ifdef CONFIG_AMD_MEM_ENCRYPT
>> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>> +					   size_t csize, unsigned long offset,
>> +					   int userbuf);
>> +#else
>> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>> +					size_t csize, unsigned long offset,
>> +					int userbuf) {
> 
> Personally I prefer below because it is too long:
> 
> static inline
> ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
> 				   unsigned long offset, int userbuf)
> {
> 	return 0;
> }
> 			
> 
>> +	return csize;
> 
> As above it should be return 0;
> 
>> +}
>> +#endif
>>  void vmcore_cleanup(void);
>>  
>>  /* Architecture code defines this if there are other possible ELF
>> -- 
>> 2.9.5
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
> 
> Thanks
> Dave
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-19 14:46       ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-19 14:46 UTC (permalink / raw)
  To: Dave Young; +Cc: thomas.lendacky, iommu, kexec, linux-kernel

在 2018年06月19日 11:16, Dave Young 写道:
> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>> In kdump mode, we need to dump the old memory into vmcore file,
>> if SME is enabled in the first kernel, we must remap the old
>> memory in encrypted manner, which will be automatically decrypted
>> when we read from DRAM. It helps to parse the vmcore for some tools.
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>> Some changes:
>> 1. add a new file and modify Makefile.
>> 2. remove some code in sev_active().
>>
>>  arch/x86/kernel/Makefile             |  1 +
>>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>>  fs/proc/vmcore.c                     | 20 ++++++++++----
>>  include/linux/crash_dump.h           | 11 ++++++++
>>  4 files changed, 79 insertions(+), 6 deletions(-)
>>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
>>
>> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
>> index 02d6f5c..afb5bad 100644
>> --- a/arch/x86/kernel/Makefile
>> +++ b/arch/x86/kernel/Makefile
>> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
>> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>>  obj-y				+= kprobes/
>>  obj-$(CONFIG_MODULES)		+= module.o
>>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
>> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
>> new file mode 100644
>> index 0000000..e44ef33
>> --- /dev/null
>> +++ b/arch/x86/kernel/crash_dump_encrypt.c
>> @@ -0,0 +1,53 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + *	Memory preserving reboot related code.
>> + *
>> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
>> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
>> + */
>> +
>> +#include <linux/errno.h>
>> +#include <linux/crash_dump.h>
>> +#include <linux/uaccess.h>
>> +#include <linux/io.h>
>> +
>> +/**
>> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
>> + * @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)
>> + * @csize: number of bytes to copy
>> + * @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().
>> + *
>> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
>> +		size_t csize, unsigned long offset, int userbuf)
>> +{
>> +	void  *vaddr;
>> +
>> +	if (!csize)
>> +		return 0;
>> +
>> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
>> +						  PAGE_SIZE);
>> +	if (!vaddr)
>> +		return -ENOMEM;
>> +
>> +	if (userbuf) {
>> +		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((void __iomem *)vaddr);
>> +	return csize;
>> +}
>> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
>> index a45f0af..5200266 100644
>> --- a/fs/proc/vmcore.c
>> +++ b/fs/proc/vmcore.c
>> @@ -25,6 +25,8 @@
>>  #include <linux/uaccess.h>
>>  #include <asm/io.h>
>>  #include "internal.h"
>> +#include <linux/mem_encrypt.h>
>> +#include <asm/pgtable.h>
>>  
>>  /* List representing chunks of contiguous memory areas and their offsets in
>>   * vmcore file.
>> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>>  
>>  /* Reads a page from the oldmem device from given offset. */
>>  static ssize_t read_from_oldmem(char *buf, size_t count,
>> -				u64 *ppos, int userbuf)
>> +				u64 *ppos, int userbuf,
>> +				bool encrypted)
>>  {
>>  	unsigned long pfn, offset;
>>  	size_t nr_bytes;
>> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>>  		if (pfn_is_ram(pfn) == 0)
>>  			memset(buf, 0, nr_bytes);
>>  		else {
>> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
>> -						offset, userbuf);
>> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
>> +					    buf, nr_bytes, offset, userbuf)
>> +					: copy_oldmem_page(pfn, buf, nr_bytes,
>> +							   offset, userbuf);
>> +
>>  			if (tmp < 0)
>>  				return tmp;
>>  		}
>> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>>   */
>>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>  {
>> -	return read_from_oldmem(buf, count, ppos, 0);
>> +	return read_from_oldmem(buf, count, ppos, 0, false);
> 
> The elf header actually stays in kdump kernel reserved memory so it is
> not "oldmem", the original function is misleading and doing unnecessary
> things.  But as for your patch maybe using it as is is good for the time
> being and add a code comment why the encrypted is "false".
> 
Thank you, Dave. It is a good idea to add some comments for the code.
I rechecked the code, the elf header should be still the old memory in the first kernel,
but why is the old memory unencrypted? Because it copies the elf header from the memory
encrypted(user space) to the memory unencrypted(kernel space) when SME is activated in the
first kernel, this operation just leads to decryption.

Thanks.
Lianbo
> 	/* elfcorehdr stays in kdump kernel memory and it is not encrypted. */
> 	return read_from_oldmem(buf, count, ppos, 0, false);
> 
> 
> I'm thinking to move the function to something like below, still not sure
> memremap works on every arches or not, still need more test
> 
> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
> index cfb6674331fd..40c01cc42b38 100644
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -136,6 +136,24 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>  	return read;
>  }
>  
> +static ssize_t read_from_mem(char *buf, size_t count, u64 *ppos)
> +{
> +	resource_size_t offset = (resource_size_t)*ppos;
> +	char *kbuf;
> +
> +	if (!count)
> +		return 0;
> +
> +	kbuf = memremap(offset, count, MEMREMAP_WB);
> +	if (!kbuf)
> +		return 0;
> +
> +	memcpy(buf, kbuf, count);
> +	memunmap(kbuf);
> +
> +	return count;
> +}
> +
>  /*
>   * Architectures may override this function to allocate ELF header in 2nd kernel
>   */
> @@ -155,7 +173,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>   */
>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_mem(buf, count, ppos);
>  }
>  
>  /*
>  
> 
>>  }
>>  
>>  /*
>> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>   */
>>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>>  {
>> -	return read_from_oldmem(buf, count, ppos, 0);
>> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>>  }
>>  
>>  /*
>> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>  				  unsigned long from, unsigned long pfn,
>>  				  unsigned long size, pgprot_t prot)
>>  {
>> +	prot = pgprot_encrypted(prot);
>>  	return remap_pfn_range(vma, from, pfn, size, prot);
>>  }
>>  
>> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>>  					    m->offset + m->size - *fpos,
>>  					    buflen);
>>  			start = m->paddr + *fpos - m->offset;
>> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
>> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
>> +						sme_active());
>>  			if (tmp < 0)
>>  				return tmp;
>>  			buflen -= tsz;
>> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
>> index f7ac2aa..f3414ff 100644
>> --- a/include/linux/crash_dump.h
>> +++ b/include/linux/crash_dump.h
>> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>  
>>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>>  						unsigned long, int);
>> +#ifdef CONFIG_AMD_MEM_ENCRYPT
>> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>> +					   size_t csize, unsigned long offset,
>> +					   int userbuf);
>> +#else
>> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>> +					size_t csize, unsigned long offset,
>> +					int userbuf) {
> 
> Personally I prefer below because it is too long:
> 
> static inline
> ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
> 				   unsigned long offset, int userbuf)
> {
> 	return 0;
> }
> 			
> 
>> +	return csize;
> 
> As above it should be return 0;
> 
>> +}
>> +#endif
>>  void vmcore_cleanup(void);
>>  
>>  /* Architecture code defines this if there are other possible ELF
>> -- 
>> 2.9.5
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
> 
> Thanks
> Dave
> 

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-20  4:50         ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-20  4:50 UTC (permalink / raw)
  To: Dave Young; +Cc: linux-kernel, thomas.lendacky, iommu, kexec

在 2018年06月19日 22:46, lijiang 写道:
> 在 2018年06月19日 11:16, Dave Young 写道:
>> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>>> In kdump mode, we need to dump the old memory into vmcore file,
>>> if SME is enabled in the first kernel, we must remap the old
>>> memory in encrypted manner, which will be automatically decrypted
>>> when we read from DRAM. It helps to parse the vmcore for some tools.
>>>
>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>> ---
>>> Some changes:
>>> 1. add a new file and modify Makefile.
>>> 2. remove some code in sev_active().
>>>
>>>  arch/x86/kernel/Makefile             |  1 +
>>>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>>>  fs/proc/vmcore.c                     | 20 ++++++++++----
>>>  include/linux/crash_dump.h           | 11 ++++++++
>>>  4 files changed, 79 insertions(+), 6 deletions(-)
>>>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
>>>
>>> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
>>> index 02d6f5c..afb5bad 100644
>>> --- a/arch/x86/kernel/Makefile
>>> +++ b/arch/x86/kernel/Makefile
>>> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>>>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>>>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>>>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
>>> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>>>  obj-y				+= kprobes/
>>>  obj-$(CONFIG_MODULES)		+= module.o
>>>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
>>> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
>>> new file mode 100644
>>> index 0000000..e44ef33
>>> --- /dev/null
>>> +++ b/arch/x86/kernel/crash_dump_encrypt.c
>>> @@ -0,0 +1,53 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + *	Memory preserving reboot related code.
>>> + *
>>> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
>>> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
>>> + */
>>> +
>>> +#include <linux/errno.h>
>>> +#include <linux/crash_dump.h>
>>> +#include <linux/uaccess.h>
>>> +#include <linux/io.h>
>>> +
>>> +/**
>>> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
>>> + * @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)
>>> + * @csize: number of bytes to copy
>>> + * @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().
>>> + *
>>> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
>>> +		size_t csize, unsigned long offset, int userbuf)
>>> +{
>>> +	void  *vaddr;
>>> +
>>> +	if (!csize)
>>> +		return 0;
>>> +
>>> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
>>> +						  PAGE_SIZE);
>>> +	if (!vaddr)
>>> +		return -ENOMEM;
>>> +
>>> +	if (userbuf) {
>>> +		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((void __iomem *)vaddr);
>>> +	return csize;
>>> +}
>>> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
>>> index a45f0af..5200266 100644
>>> --- a/fs/proc/vmcore.c
>>> +++ b/fs/proc/vmcore.c
>>> @@ -25,6 +25,8 @@
>>>  #include <linux/uaccess.h>
>>>  #include <asm/io.h>
>>>  #include "internal.h"
>>> +#include <linux/mem_encrypt.h>
>>> +#include <asm/pgtable.h>
>>>  
>>>  /* List representing chunks of contiguous memory areas and their offsets in
>>>   * vmcore file.
>>> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>>>  
>>>  /* Reads a page from the oldmem device from given offset. */
>>>  static ssize_t read_from_oldmem(char *buf, size_t count,
>>> -				u64 *ppos, int userbuf)
>>> +				u64 *ppos, int userbuf,
>>> +				bool encrypted)
>>>  {
>>>  	unsigned long pfn, offset;
>>>  	size_t nr_bytes;
>>> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>>>  		if (pfn_is_ram(pfn) == 0)
>>>  			memset(buf, 0, nr_bytes);
>>>  		else {
>>> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
>>> -						offset, userbuf);
>>> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
>>> +					    buf, nr_bytes, offset, userbuf)
>>> +					: copy_oldmem_page(pfn, buf, nr_bytes,
>>> +							   offset, userbuf);
>>> +
>>>  			if (tmp < 0)
>>>  				return tmp;
>>>  		}
>>> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>>>   */
>>>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>>  {
>>> -	return read_from_oldmem(buf, count, ppos, 0);
>>> +	return read_from_oldmem(buf, count, ppos, 0, false);
>>
>> The elf header actually stays in kdump kernel reserved memory so it is
>> not "oldmem", the original function is misleading and doing unnecessary
>> things.  But as for your patch maybe using it as is is good for the time
>> being and add a code comment why the encrypted is "false".
>>
> Thank you, Dave. It is a good idea to add some comments for the code.
> I rechecked the code, the elf header should be still the old memory in the first kernel,
> but why is the old memory unencrypted? Because it copies the elf header from the memory
> encrypted(user space) to the memory unencrypted(kernel space) when SME is activated in the
> first kernel, this operation just leads to decryption.
> 
I just know your means, we allocated the memory unencrypted(kernel space) in reserved
crash memory, from this point of view, it is not "oldmem". Thanks for your comments.

Thanks.
Lianbo

> Thanks.
> Lianbo
>> 	/* elfcorehdr stays in kdump kernel memory and it is not encrypted. */
>> 	return read_from_oldmem(buf, count, ppos, 0, false);
>>
>>
>> I'm thinking to move the function to something like below, still not sure
>> memremap works on every arches or not, still need more test
>>
>> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
>> index cfb6674331fd..40c01cc42b38 100644
>> --- a/fs/proc/vmcore.c
>> +++ b/fs/proc/vmcore.c
>> @@ -136,6 +136,24 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>>  	return read;
>>  }
>>  
>> +static ssize_t read_from_mem(char *buf, size_t count, u64 *ppos)
>> +{
>> +	resource_size_t offset = (resource_size_t)*ppos;
>> +	char *kbuf;
>> +
>> +	if (!count)
>> +		return 0;
>> +
>> +	kbuf = memremap(offset, count, MEMREMAP_WB);
>> +	if (!kbuf)
>> +		return 0;
>> +
>> +	memcpy(buf, kbuf, count);
>> +	memunmap(kbuf);
>> +
>> +	return count;
>> +}
>> +
>>  /*
>>   * Architectures may override this function to allocate ELF header in 2nd kernel
>>   */
>> @@ -155,7 +173,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>>   */
>>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>  {
>> -	return read_from_oldmem(buf, count, ppos, 0);
>> +	return read_from_mem(buf, count, ppos);
>>  }
>>  
>>  /*
>>  
>>
>>>  }
>>>  
>>>  /*
>>> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>>   */
>>>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>>>  {
>>> -	return read_from_oldmem(buf, count, ppos, 0);
>>> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>>>  }
>>>  
>>>  /*
>>> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>>  				  unsigned long from, unsigned long pfn,
>>>  				  unsigned long size, pgprot_t prot)
>>>  {
>>> +	prot = pgprot_encrypted(prot);
>>>  	return remap_pfn_range(vma, from, pfn, size, prot);
>>>  }
>>>  
>>> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>>>  					    m->offset + m->size - *fpos,
>>>  					    buflen);
>>>  			start = m->paddr + *fpos - m->offset;
>>> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
>>> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
>>> +						sme_active());
>>>  			if (tmp < 0)
>>>  				return tmp;
>>>  			buflen -= tsz;
>>> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
>>> index f7ac2aa..f3414ff 100644
>>> --- a/include/linux/crash_dump.h
>>> +++ b/include/linux/crash_dump.h
>>> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>>  
>>>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>>>  						unsigned long, int);
>>> +#ifdef CONFIG_AMD_MEM_ENCRYPT
>>> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>>> +					   size_t csize, unsigned long offset,
>>> +					   int userbuf);
>>> +#else
>>> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>>> +					size_t csize, unsigned long offset,
>>> +					int userbuf) {
>>
>> Personally I prefer below because it is too long:
>>
>> static inline
>> ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
>> 				   unsigned long offset, int userbuf)
>> {
>> 	return 0;
>> }
>> 			
>>
>>> +	return csize;
>>
>> As above it should be return 0;
>>
Great, Thank you, Dave.

Lianbo
>>> +}
>>> +#endif
>>>  void vmcore_cleanup(void);
>>>  
>>>  /* Architecture code defines this if there are other possible ELF
>>> -- 
>>> 2.9.5
>>>
>>>
>>> _______________________________________________
>>> kexec mailing list
>>> kexec@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/kexec
>>
>> Thanks
>> Dave
>>

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-20  4:50         ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-20  4:50 UTC (permalink / raw)
  To: Dave Young
  Cc: thomas.lendacky-5C7GfCeVMHo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

在 2018年06月19日 22:46, lijiang 写道:
> 在 2018年06月19日 11:16, Dave Young 写道:
>> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>>> In kdump mode, we need to dump the old memory into vmcore file,
>>> if SME is enabled in the first kernel, we must remap the old
>>> memory in encrypted manner, which will be automatically decrypted
>>> when we read from DRAM. It helps to parse the vmcore for some tools.
>>>
>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>> ---
>>> Some changes:
>>> 1. add a new file and modify Makefile.
>>> 2. remove some code in sev_active().
>>>
>>>  arch/x86/kernel/Makefile             |  1 +
>>>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>>>  fs/proc/vmcore.c                     | 20 ++++++++++----
>>>  include/linux/crash_dump.h           | 11 ++++++++
>>>  4 files changed, 79 insertions(+), 6 deletions(-)
>>>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
>>>
>>> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
>>> index 02d6f5c..afb5bad 100644
>>> --- a/arch/x86/kernel/Makefile
>>> +++ b/arch/x86/kernel/Makefile
>>> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>>>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>>>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>>>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
>>> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>>>  obj-y				+= kprobes/
>>>  obj-$(CONFIG_MODULES)		+= module.o
>>>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
>>> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
>>> new file mode 100644
>>> index 0000000..e44ef33
>>> --- /dev/null
>>> +++ b/arch/x86/kernel/crash_dump_encrypt.c
>>> @@ -0,0 +1,53 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + *	Memory preserving reboot related code.
>>> + *
>>> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
>>> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
>>> + */
>>> +
>>> +#include <linux/errno.h>
>>> +#include <linux/crash_dump.h>
>>> +#include <linux/uaccess.h>
>>> +#include <linux/io.h>
>>> +
>>> +/**
>>> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
>>> + * @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)
>>> + * @csize: number of bytes to copy
>>> + * @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().
>>> + *
>>> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
>>> +		size_t csize, unsigned long offset, int userbuf)
>>> +{
>>> +	void  *vaddr;
>>> +
>>> +	if (!csize)
>>> +		return 0;
>>> +
>>> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
>>> +						  PAGE_SIZE);
>>> +	if (!vaddr)
>>> +		return -ENOMEM;
>>> +
>>> +	if (userbuf) {
>>> +		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((void __iomem *)vaddr);
>>> +	return csize;
>>> +}
>>> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
>>> index a45f0af..5200266 100644
>>> --- a/fs/proc/vmcore.c
>>> +++ b/fs/proc/vmcore.c
>>> @@ -25,6 +25,8 @@
>>>  #include <linux/uaccess.h>
>>>  #include <asm/io.h>
>>>  #include "internal.h"
>>> +#include <linux/mem_encrypt.h>
>>> +#include <asm/pgtable.h>
>>>  
>>>  /* List representing chunks of contiguous memory areas and their offsets in
>>>   * vmcore file.
>>> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>>>  
>>>  /* Reads a page from the oldmem device from given offset. */
>>>  static ssize_t read_from_oldmem(char *buf, size_t count,
>>> -				u64 *ppos, int userbuf)
>>> +				u64 *ppos, int userbuf,
>>> +				bool encrypted)
>>>  {
>>>  	unsigned long pfn, offset;
>>>  	size_t nr_bytes;
>>> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>>>  		if (pfn_is_ram(pfn) == 0)
>>>  			memset(buf, 0, nr_bytes);
>>>  		else {
>>> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
>>> -						offset, userbuf);
>>> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
>>> +					    buf, nr_bytes, offset, userbuf)
>>> +					: copy_oldmem_page(pfn, buf, nr_bytes,
>>> +							   offset, userbuf);
>>> +
>>>  			if (tmp < 0)
>>>  				return tmp;
>>>  		}
>>> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>>>   */
>>>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>>  {
>>> -	return read_from_oldmem(buf, count, ppos, 0);
>>> +	return read_from_oldmem(buf, count, ppos, 0, false);
>>
>> The elf header actually stays in kdump kernel reserved memory so it is
>> not "oldmem", the original function is misleading and doing unnecessary
>> things.  But as for your patch maybe using it as is is good for the time
>> being and add a code comment why the encrypted is "false".
>>
> Thank you, Dave. It is a good idea to add some comments for the code.
> I rechecked the code, the elf header should be still the old memory in the first kernel,
> but why is the old memory unencrypted? Because it copies the elf header from the memory
> encrypted(user space) to the memory unencrypted(kernel space) when SME is activated in the
> first kernel, this operation just leads to decryption.
> 
I just know your means, we allocated the memory unencrypted(kernel space) in reserved
crash memory, from this point of view, it is not "oldmem". Thanks for your comments.

Thanks.
Lianbo

> Thanks.
> Lianbo
>> 	/* elfcorehdr stays in kdump kernel memory and it is not encrypted. */
>> 	return read_from_oldmem(buf, count, ppos, 0, false);
>>
>>
>> I'm thinking to move the function to something like below, still not sure
>> memremap works on every arches or not, still need more test
>>
>> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
>> index cfb6674331fd..40c01cc42b38 100644
>> --- a/fs/proc/vmcore.c
>> +++ b/fs/proc/vmcore.c
>> @@ -136,6 +136,24 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>>  	return read;
>>  }
>>  
>> +static ssize_t read_from_mem(char *buf, size_t count, u64 *ppos)
>> +{
>> +	resource_size_t offset = (resource_size_t)*ppos;
>> +	char *kbuf;
>> +
>> +	if (!count)
>> +		return 0;
>> +
>> +	kbuf = memremap(offset, count, MEMREMAP_WB);
>> +	if (!kbuf)
>> +		return 0;
>> +
>> +	memcpy(buf, kbuf, count);
>> +	memunmap(kbuf);
>> +
>> +	return count;
>> +}
>> +
>>  /*
>>   * Architectures may override this function to allocate ELF header in 2nd kernel
>>   */
>> @@ -155,7 +173,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>>   */
>>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>  {
>> -	return read_from_oldmem(buf, count, ppos, 0);
>> +	return read_from_mem(buf, count, ppos);
>>  }
>>  
>>  /*
>>  
>>
>>>  }
>>>  
>>>  /*
>>> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>>   */
>>>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>>>  {
>>> -	return read_from_oldmem(buf, count, ppos, 0);
>>> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>>>  }
>>>  
>>>  /*
>>> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>>  				  unsigned long from, unsigned long pfn,
>>>  				  unsigned long size, pgprot_t prot)
>>>  {
>>> +	prot = pgprot_encrypted(prot);
>>>  	return remap_pfn_range(vma, from, pfn, size, prot);
>>>  }
>>>  
>>> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>>>  					    m->offset + m->size - *fpos,
>>>  					    buflen);
>>>  			start = m->paddr + *fpos - m->offset;
>>> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
>>> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
>>> +						sme_active());
>>>  			if (tmp < 0)
>>>  				return tmp;
>>>  			buflen -= tsz;
>>> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
>>> index f7ac2aa..f3414ff 100644
>>> --- a/include/linux/crash_dump.h
>>> +++ b/include/linux/crash_dump.h
>>> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>>  
>>>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>>>  						unsigned long, int);
>>> +#ifdef CONFIG_AMD_MEM_ENCRYPT
>>> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>>> +					   size_t csize, unsigned long offset,
>>> +					   int userbuf);
>>> +#else
>>> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>>> +					size_t csize, unsigned long offset,
>>> +					int userbuf) {
>>
>> Personally I prefer below because it is too long:
>>
>> static inline
>> ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
>> 				   unsigned long offset, int userbuf)
>> {
>> 	return 0;
>> }
>> 			
>>
>>> +	return csize;
>>
>> As above it should be return 0;
>>
Great, Thank you, Dave.

Lianbo
>>> +}
>>> +#endif
>>>  void vmcore_cleanup(void);
>>>  
>>>  /* Architecture code defines this if there are other possible ELF
>>> -- 
>>> 2.9.5
>>>
>>>
>>> _______________________________________________
>>> kexec mailing list
>>> kexec@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/kexec
>>
>> Thanks
>> Dave
>>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-20  4:50         ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-20  4:50 UTC (permalink / raw)
  To: Dave Young; +Cc: thomas.lendacky, iommu, kexec, linux-kernel

在 2018年06月19日 22:46, lijiang 写道:
> 在 2018年06月19日 11:16, Dave Young 写道:
>> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>>> In kdump mode, we need to dump the old memory into vmcore file,
>>> if SME is enabled in the first kernel, we must remap the old
>>> memory in encrypted manner, which will be automatically decrypted
>>> when we read from DRAM. It helps to parse the vmcore for some tools.
>>>
>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>> ---
>>> Some changes:
>>> 1. add a new file and modify Makefile.
>>> 2. remove some code in sev_active().
>>>
>>>  arch/x86/kernel/Makefile             |  1 +
>>>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>>>  fs/proc/vmcore.c                     | 20 ++++++++++----
>>>  include/linux/crash_dump.h           | 11 ++++++++
>>>  4 files changed, 79 insertions(+), 6 deletions(-)
>>>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
>>>
>>> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
>>> index 02d6f5c..afb5bad 100644
>>> --- a/arch/x86/kernel/Makefile
>>> +++ b/arch/x86/kernel/Makefile
>>> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>>>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>>>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>>>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
>>> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>>>  obj-y				+= kprobes/
>>>  obj-$(CONFIG_MODULES)		+= module.o
>>>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
>>> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
>>> new file mode 100644
>>> index 0000000..e44ef33
>>> --- /dev/null
>>> +++ b/arch/x86/kernel/crash_dump_encrypt.c
>>> @@ -0,0 +1,53 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + *	Memory preserving reboot related code.
>>> + *
>>> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
>>> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
>>> + */
>>> +
>>> +#include <linux/errno.h>
>>> +#include <linux/crash_dump.h>
>>> +#include <linux/uaccess.h>
>>> +#include <linux/io.h>
>>> +
>>> +/**
>>> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
>>> + * @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)
>>> + * @csize: number of bytes to copy
>>> + * @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().
>>> + *
>>> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
>>> +		size_t csize, unsigned long offset, int userbuf)
>>> +{
>>> +	void  *vaddr;
>>> +
>>> +	if (!csize)
>>> +		return 0;
>>> +
>>> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
>>> +						  PAGE_SIZE);
>>> +	if (!vaddr)
>>> +		return -ENOMEM;
>>> +
>>> +	if (userbuf) {
>>> +		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((void __iomem *)vaddr);
>>> +	return csize;
>>> +}
>>> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
>>> index a45f0af..5200266 100644
>>> --- a/fs/proc/vmcore.c
>>> +++ b/fs/proc/vmcore.c
>>> @@ -25,6 +25,8 @@
>>>  #include <linux/uaccess.h>
>>>  #include <asm/io.h>
>>>  #include "internal.h"
>>> +#include <linux/mem_encrypt.h>
>>> +#include <asm/pgtable.h>
>>>  
>>>  /* List representing chunks of contiguous memory areas and their offsets in
>>>   * vmcore file.
>>> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>>>  
>>>  /* Reads a page from the oldmem device from given offset. */
>>>  static ssize_t read_from_oldmem(char *buf, size_t count,
>>> -				u64 *ppos, int userbuf)
>>> +				u64 *ppos, int userbuf,
>>> +				bool encrypted)
>>>  {
>>>  	unsigned long pfn, offset;
>>>  	size_t nr_bytes;
>>> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>>>  		if (pfn_is_ram(pfn) == 0)
>>>  			memset(buf, 0, nr_bytes);
>>>  		else {
>>> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
>>> -						offset, userbuf);
>>> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
>>> +					    buf, nr_bytes, offset, userbuf)
>>> +					: copy_oldmem_page(pfn, buf, nr_bytes,
>>> +							   offset, userbuf);
>>> +
>>>  			if (tmp < 0)
>>>  				return tmp;
>>>  		}
>>> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>>>   */
>>>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>>  {
>>> -	return read_from_oldmem(buf, count, ppos, 0);
>>> +	return read_from_oldmem(buf, count, ppos, 0, false);
>>
>> The elf header actually stays in kdump kernel reserved memory so it is
>> not "oldmem", the original function is misleading and doing unnecessary
>> things.  But as for your patch maybe using it as is is good for the time
>> being and add a code comment why the encrypted is "false".
>>
> Thank you, Dave. It is a good idea to add some comments for the code.
> I rechecked the code, the elf header should be still the old memory in the first kernel,
> but why is the old memory unencrypted? Because it copies the elf header from the memory
> encrypted(user space) to the memory unencrypted(kernel space) when SME is activated in the
> first kernel, this operation just leads to decryption.
> 
I just know your means, we allocated the memory unencrypted(kernel space) in reserved
crash memory, from this point of view, it is not "oldmem". Thanks for your comments.

Thanks.
Lianbo

> Thanks.
> Lianbo
>> 	/* elfcorehdr stays in kdump kernel memory and it is not encrypted. */
>> 	return read_from_oldmem(buf, count, ppos, 0, false);
>>
>>
>> I'm thinking to move the function to something like below, still not sure
>> memremap works on every arches or not, still need more test
>>
>> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
>> index cfb6674331fd..40c01cc42b38 100644
>> --- a/fs/proc/vmcore.c
>> +++ b/fs/proc/vmcore.c
>> @@ -136,6 +136,24 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>>  	return read;
>>  }
>>  
>> +static ssize_t read_from_mem(char *buf, size_t count, u64 *ppos)
>> +{
>> +	resource_size_t offset = (resource_size_t)*ppos;
>> +	char *kbuf;
>> +
>> +	if (!count)
>> +		return 0;
>> +
>> +	kbuf = memremap(offset, count, MEMREMAP_WB);
>> +	if (!kbuf)
>> +		return 0;
>> +
>> +	memcpy(buf, kbuf, count);
>> +	memunmap(kbuf);
>> +
>> +	return count;
>> +}
>> +
>>  /*
>>   * Architectures may override this function to allocate ELF header in 2nd kernel
>>   */
>> @@ -155,7 +173,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>>   */
>>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>  {
>> -	return read_from_oldmem(buf, count, ppos, 0);
>> +	return read_from_mem(buf, count, ppos);
>>  }
>>  
>>  /*
>>  
>>
>>>  }
>>>  
>>>  /*
>>> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>>>   */
>>>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>>>  {
>>> -	return read_from_oldmem(buf, count, ppos, 0);
>>> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>>>  }
>>>  
>>>  /*
>>> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>>  				  unsigned long from, unsigned long pfn,
>>>  				  unsigned long size, pgprot_t prot)
>>>  {
>>> +	prot = pgprot_encrypted(prot);
>>>  	return remap_pfn_range(vma, from, pfn, size, prot);
>>>  }
>>>  
>>> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>>>  					    m->offset + m->size - *fpos,
>>>  					    buflen);
>>>  			start = m->paddr + *fpos - m->offset;
>>> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
>>> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
>>> +						sme_active());
>>>  			if (tmp < 0)
>>>  				return tmp;
>>>  			buflen -= tsz;
>>> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
>>> index f7ac2aa..f3414ff 100644
>>> --- a/include/linux/crash_dump.h
>>> +++ b/include/linux/crash_dump.h
>>> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>>>  
>>>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>>>  						unsigned long, int);
>>> +#ifdef CONFIG_AMD_MEM_ENCRYPT
>>> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>>> +					   size_t csize, unsigned long offset,
>>> +					   int userbuf);
>>> +#else
>>> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
>>> +					size_t csize, unsigned long offset,
>>> +					int userbuf) {
>>
>> Personally I prefer below because it is too long:
>>
>> static inline
>> ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
>> 				   unsigned long offset, int userbuf)
>> {
>> 	return 0;
>> }
>> 			
>>
>>> +	return csize;
>>
>> As above it should be return 0;
>>
Great, Thank you, Dave.

Lianbo
>>> +}
>>> +#endif
>>>  void vmcore_cleanup(void);
>>>  
>>>  /* Architecture code defines this if there are other possible ELF
>>> -- 
>>> 2.9.5
>>>
>>>
>>> _______________________________________________
>>> kexec mailing list
>>> kexec@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/kexec
>>
>> Thanks
>> Dave
>>

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled
@ 2018-06-20 16:00     ` Tom Lendacky
  0 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-20 16:00 UTC (permalink / raw)
  To: Lianbo Jiang, linux-kernel; +Cc: iommu, kexec, dyoung

On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> It is convenient to remap the old memory encrypted to the second
> kernel by calling ioremap_encrypted().
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. remove the sme_active() check in __ioremap_caller().
> 2. put some logic into the early_memremap_pgprot_adjust() for
> early memremap.
> 
>  arch/x86/include/asm/io.h |  3 +++
>  arch/x86/mm/ioremap.c     | 28 ++++++++++++++++++++--------
>  2 files changed, 23 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
> index f6e5b93..989d60b 100644
> --- a/arch/x86/include/asm/io.h
> +++ b/arch/x86/include/asm/io.h
> @@ -192,6 +192,9 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
>  #define ioremap_cache ioremap_cache
>  extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
>  #define ioremap_prot ioremap_prot
> +extern void __iomem *ioremap_encrypted(resource_size_t phys_addr,
> +					unsigned long size);
> +#define ioremap_encrypted ioremap_encrypted
>  
>  /**
>   * ioremap     -   map bus memory into CPU space
> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> index c63a545..e365fc4 100644
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -24,6 +24,7 @@
>  #include <asm/pgalloc.h>
>  #include <asm/pat.h>
>  #include <asm/setup.h>
> +#include <linux/crash_dump.h>
>  
>  #include "physaddr.h"
>  
> @@ -131,7 +132,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
>   * caller shouldn't need to know that small detail.
>   */
>  static void __iomem *__ioremap_caller(resource_size_t phys_addr,
> -		unsigned long size, enum page_cache_mode pcm, void *caller)
> +		unsigned long size, enum page_cache_mode pcm,
> +		void *caller, bool encrypted)
>  {
>  	unsigned long offset, vaddr;
>  	resource_size_t last_addr;
> @@ -199,7 +201,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>  	 * resulting mapping.
>  	 */
>  	prot = PAGE_KERNEL_IO;
> -	if (sev_active() && mem_flags.desc_other)
> +	if ((sev_active() && mem_flags.desc_other) || encrypted)
>  		prot = pgprot_encrypted(prot);
>  
>  	switch (pcm) {
> @@ -291,7 +293,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
>  
>  	return __ioremap_caller(phys_addr, size, pcm,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_nocache);
>  
> @@ -324,7 +326,7 @@ void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
>  
>  	return __ioremap_caller(phys_addr, size, pcm,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL_GPL(ioremap_uc);
>  
> @@ -341,7 +343,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
>  void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
> -					__builtin_return_address(0));
> +					__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_wc);
>  
> @@ -358,14 +360,21 @@ EXPORT_SYMBOL(ioremap_wc);
>  void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
> -					__builtin_return_address(0));
> +					__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_wt);
>  
> +void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
> +{
> +	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
> +				__builtin_return_address(0), true);
> +}
> +EXPORT_SYMBOL(ioremap_encrypted);
> +
>  void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_cache);
>  
> @@ -374,7 +383,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
>  {
>  	return __ioremap_caller(phys_addr, size,
>  				pgprot2cachemode(__pgprot(prot_val)),
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_prot);
>  
> @@ -688,6 +697,9 @@ pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
>  	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
>  		encrypted_prot = false;
>  
> +	if (sme_active() && is_kdump_kernel())
> +		encrypted_prot = false;
> +

This change doesn't seem to go with the patch description.  Maybe it
should be a separate patch?  Or provide more detail in the description
for this change.

What is this change addressing?  What early_memremap() calls were failing
that required this?  If this truly is required, you can probably move it
up into the "if (sme_active())" block a few lines higher in the function.

Thanks,
Tom

>  	return encrypted_prot ? pgprot_encrypted(prot)
>  			      : pgprot_decrypted(prot);
>  }
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled
@ 2018-06-20 16:00     ` Tom Lendacky
  0 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-20 16:00 UTC (permalink / raw)
  To: Lianbo Jiang, linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> It is convenient to remap the old memory encrypted to the second
> kernel by calling ioremap_encrypted().
> 
> Signed-off-by: Lianbo Jiang <lijiang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> Some changes:
> 1. remove the sme_active() check in __ioremap_caller().
> 2. put some logic into the early_memremap_pgprot_adjust() for
> early memremap.
> 
>  arch/x86/include/asm/io.h |  3 +++
>  arch/x86/mm/ioremap.c     | 28 ++++++++++++++++++++--------
>  2 files changed, 23 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
> index f6e5b93..989d60b 100644
> --- a/arch/x86/include/asm/io.h
> +++ b/arch/x86/include/asm/io.h
> @@ -192,6 +192,9 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
>  #define ioremap_cache ioremap_cache
>  extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
>  #define ioremap_prot ioremap_prot
> +extern void __iomem *ioremap_encrypted(resource_size_t phys_addr,
> +					unsigned long size);
> +#define ioremap_encrypted ioremap_encrypted
>  
>  /**
>   * ioremap     -   map bus memory into CPU space
> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> index c63a545..e365fc4 100644
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -24,6 +24,7 @@
>  #include <asm/pgalloc.h>
>  #include <asm/pat.h>
>  #include <asm/setup.h>
> +#include <linux/crash_dump.h>
>  
>  #include "physaddr.h"
>  
> @@ -131,7 +132,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
>   * caller shouldn't need to know that small detail.
>   */
>  static void __iomem *__ioremap_caller(resource_size_t phys_addr,
> -		unsigned long size, enum page_cache_mode pcm, void *caller)
> +		unsigned long size, enum page_cache_mode pcm,
> +		void *caller, bool encrypted)
>  {
>  	unsigned long offset, vaddr;
>  	resource_size_t last_addr;
> @@ -199,7 +201,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>  	 * resulting mapping.
>  	 */
>  	prot = PAGE_KERNEL_IO;
> -	if (sev_active() && mem_flags.desc_other)
> +	if ((sev_active() && mem_flags.desc_other) || encrypted)
>  		prot = pgprot_encrypted(prot);
>  
>  	switch (pcm) {
> @@ -291,7 +293,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
>  
>  	return __ioremap_caller(phys_addr, size, pcm,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_nocache);
>  
> @@ -324,7 +326,7 @@ void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
>  
>  	return __ioremap_caller(phys_addr, size, pcm,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL_GPL(ioremap_uc);
>  
> @@ -341,7 +343,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
>  void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
> -					__builtin_return_address(0));
> +					__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_wc);
>  
> @@ -358,14 +360,21 @@ EXPORT_SYMBOL(ioremap_wc);
>  void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
> -					__builtin_return_address(0));
> +					__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_wt);
>  
> +void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
> +{
> +	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
> +				__builtin_return_address(0), true);
> +}
> +EXPORT_SYMBOL(ioremap_encrypted);
> +
>  void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_cache);
>  
> @@ -374,7 +383,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
>  {
>  	return __ioremap_caller(phys_addr, size,
>  				pgprot2cachemode(__pgprot(prot_val)),
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_prot);
>  
> @@ -688,6 +697,9 @@ pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
>  	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
>  		encrypted_prot = false;
>  
> +	if (sme_active() && is_kdump_kernel())
> +		encrypted_prot = false;
> +

This change doesn't seem to go with the patch description.  Maybe it
should be a separate patch?  Or provide more detail in the description
for this change.

What is this change addressing?  What early_memremap() calls were failing
that required this?  If this truly is required, you can probably move it
up into the "if (sme_active())" block a few lines higher in the function.

Thanks,
Tom

>  	return encrypted_prot ? pgprot_encrypted(prot)
>  			      : pgprot_decrypted(prot);
>  }
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled
@ 2018-06-20 16:00     ` Tom Lendacky
  0 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-20 16:00 UTC (permalink / raw)
  To: Lianbo Jiang, linux-kernel; +Cc: dyoung, iommu, kexec

On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> It is convenient to remap the old memory encrypted to the second
> kernel by calling ioremap_encrypted().
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. remove the sme_active() check in __ioremap_caller().
> 2. put some logic into the early_memremap_pgprot_adjust() for
> early memremap.
> 
>  arch/x86/include/asm/io.h |  3 +++
>  arch/x86/mm/ioremap.c     | 28 ++++++++++++++++++++--------
>  2 files changed, 23 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
> index f6e5b93..989d60b 100644
> --- a/arch/x86/include/asm/io.h
> +++ b/arch/x86/include/asm/io.h
> @@ -192,6 +192,9 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
>  #define ioremap_cache ioremap_cache
>  extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
>  #define ioremap_prot ioremap_prot
> +extern void __iomem *ioremap_encrypted(resource_size_t phys_addr,
> +					unsigned long size);
> +#define ioremap_encrypted ioremap_encrypted
>  
>  /**
>   * ioremap     -   map bus memory into CPU space
> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> index c63a545..e365fc4 100644
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -24,6 +24,7 @@
>  #include <asm/pgalloc.h>
>  #include <asm/pat.h>
>  #include <asm/setup.h>
> +#include <linux/crash_dump.h>
>  
>  #include "physaddr.h"
>  
> @@ -131,7 +132,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
>   * caller shouldn't need to know that small detail.
>   */
>  static void __iomem *__ioremap_caller(resource_size_t phys_addr,
> -		unsigned long size, enum page_cache_mode pcm, void *caller)
> +		unsigned long size, enum page_cache_mode pcm,
> +		void *caller, bool encrypted)
>  {
>  	unsigned long offset, vaddr;
>  	resource_size_t last_addr;
> @@ -199,7 +201,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>  	 * resulting mapping.
>  	 */
>  	prot = PAGE_KERNEL_IO;
> -	if (sev_active() && mem_flags.desc_other)
> +	if ((sev_active() && mem_flags.desc_other) || encrypted)
>  		prot = pgprot_encrypted(prot);
>  
>  	switch (pcm) {
> @@ -291,7 +293,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
>  
>  	return __ioremap_caller(phys_addr, size, pcm,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_nocache);
>  
> @@ -324,7 +326,7 @@ void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
>  
>  	return __ioremap_caller(phys_addr, size, pcm,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL_GPL(ioremap_uc);
>  
> @@ -341,7 +343,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
>  void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
> -					__builtin_return_address(0));
> +					__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_wc);
>  
> @@ -358,14 +360,21 @@ EXPORT_SYMBOL(ioremap_wc);
>  void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
> -					__builtin_return_address(0));
> +					__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_wt);
>  
> +void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
> +{
> +	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
> +				__builtin_return_address(0), true);
> +}
> +EXPORT_SYMBOL(ioremap_encrypted);
> +
>  void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
>  {
>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_cache);
>  
> @@ -374,7 +383,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
>  {
>  	return __ioremap_caller(phys_addr, size,
>  				pgprot2cachemode(__pgprot(prot_val)),
> -				__builtin_return_address(0));
> +				__builtin_return_address(0), false);
>  }
>  EXPORT_SYMBOL(ioremap_prot);
>  
> @@ -688,6 +697,9 @@ pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
>  	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
>  		encrypted_prot = false;
>  
> +	if (sme_active() && is_kdump_kernel())
> +		encrypted_prot = false;
> +

This change doesn't seem to go with the patch description.  Maybe it
should be a separate patch?  Or provide more detail in the description
for this change.

What is this change addressing?  What early_memremap() calls were failing
that required this?  If this truly is required, you can probably move it
up into the "if (sme_active())" block a few lines higher in the function.

Thanks,
Tom

>  	return encrypted_prot ? pgprot_encrypted(prot)
>  			      : pgprot_decrypted(prot);
>  }
> 

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-20 16:42     ` Tom Lendacky
  0 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-20 16:42 UTC (permalink / raw)
  To: Lianbo Jiang, linux-kernel; +Cc: iommu, kexec, dyoung

On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> In kdump mode, it will copy the device table of IOMMU from the old
> device table, which is encrypted when SME is enabled in the first
> kernel. So we must remap it in encrypted manner in order to be
> automatically decrypted when we read.
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. add some comments
> 2. clean compile warning.
> 
>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> index 904c575..a20af4c 100644
> --- a/drivers/iommu/amd_iommu_init.c
> +++ b/drivers/iommu/amd_iommu_init.c
> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>  	}
>  
>  	old_devtb_phys = entry & PAGE_MASK;
> +
> +	/*
> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> +	 *  encryption mask to obtain the true physical address in kdump mode.
> +	 */
> +	if (mem_encrypt_active() && is_kdump_kernel())
> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> +

You can probably just use "if (is_kdump_kernel())" here, since memory
encryption is either on in both the first and second kernel or off in
both the first and second kernel.  At which point __sme_clr() will do
the proper thing.

Actually, this needs to be done no matter what.  When doing either the
ioremap_encrypted() or the memremap(), the physical address should not
include the encryption bit/mask.

Thanks,
Tom

>  	if (old_devtb_phys >= 0x100000000ULL) {
>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>  		return false;
>  	}
> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> +							dev_table_size)
> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>  	if (!old_devtb)
>  		return false;
>  
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-20 16:42     ` Tom Lendacky
  0 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-20 16:42 UTC (permalink / raw)
  To: Lianbo Jiang, linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> In kdump mode, it will copy the device table of IOMMU from the old
> device table, which is encrypted when SME is enabled in the first
> kernel. So we must remap it in encrypted manner in order to be
> automatically decrypted when we read.
> 
> Signed-off-by: Lianbo Jiang <lijiang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> Some changes:
> 1. add some comments
> 2. clean compile warning.
> 
>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> index 904c575..a20af4c 100644
> --- a/drivers/iommu/amd_iommu_init.c
> +++ b/drivers/iommu/amd_iommu_init.c
> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>  	}
>  
>  	old_devtb_phys = entry & PAGE_MASK;
> +
> +	/*
> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> +	 *  encryption mask to obtain the true physical address in kdump mode.
> +	 */
> +	if (mem_encrypt_active() && is_kdump_kernel())
> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> +

You can probably just use "if (is_kdump_kernel())" here, since memory
encryption is either on in both the first and second kernel or off in
both the first and second kernel.  At which point __sme_clr() will do
the proper thing.

Actually, this needs to be done no matter what.  When doing either the
ioremap_encrypted() or the memremap(), the physical address should not
include the encryption bit/mask.

Thanks,
Tom

>  	if (old_devtb_phys >= 0x100000000ULL) {
>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>  		return false;
>  	}
> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> +							dev_table_size)
> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>  	if (!old_devtb)
>  		return false;
>  
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-20 16:42     ` Tom Lendacky
  0 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-20 16:42 UTC (permalink / raw)
  To: Lianbo Jiang, linux-kernel; +Cc: dyoung, iommu, kexec

On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> In kdump mode, it will copy the device table of IOMMU from the old
> device table, which is encrypted when SME is enabled in the first
> kernel. So we must remap it in encrypted manner in order to be
> automatically decrypted when we read.
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. add some comments
> 2. clean compile warning.
> 
>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> index 904c575..a20af4c 100644
> --- a/drivers/iommu/amd_iommu_init.c
> +++ b/drivers/iommu/amd_iommu_init.c
> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>  	}
>  
>  	old_devtb_phys = entry & PAGE_MASK;
> +
> +	/*
> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> +	 *  encryption mask to obtain the true physical address in kdump mode.
> +	 */
> +	if (mem_encrypt_active() && is_kdump_kernel())
> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> +

You can probably just use "if (is_kdump_kernel())" here, since memory
encryption is either on in both the first and second kernel or off in
both the first and second kernel.  At which point __sme_clr() will do
the proper thing.

Actually, this needs to be done no matter what.  When doing either the
ioremap_encrypted() or the memremap(), the physical address should not
include the encryption bit/mask.

Thanks,
Tom

>  	if (old_devtb_phys >= 0x100000000ULL) {
>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>  		return false;
>  	}
> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> +							dev_table_size)
> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>  	if (!old_devtb)
>  		return false;
>  
> 

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-21  1:21   ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:21 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec, akpm

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> It is convenient to remap the old memory encrypted to the second kernel by
> calling ioremap_encrypted().
> 
> When sme enabled on AMD server, we also need to support kdump. Because
> the memory is encrypted in the first kernel, we will remap the old memory
> encrypted to the second kernel(crash kernel), and sme is also enabled in
> the second kernel, otherwise the old memory encrypted can not be decrypted.
> Because simply changing the value of a C-bit on a page will not
> automatically encrypt the existing contents of a page, and any data in the
> page prior to the C-bit modification will become unintelligible. A page of
> memory that is marked encrypted will be automatically decrypted when read
> from DRAM and will be automatically encrypted when written to DRAM.
> 
> For the kdump, it is necessary to distinguish whether the memory is
> encrypted. Furthermore, we should also know which part of the memory is
> encrypted or decrypted. We will appropriately remap the memory according
> to the specific situation in order to tell cpu how to deal with the
> data(encrypted or decrypted). For example, when sme enabled, if the old
> memory is encrypted, we will remap the old memory in encrypted way, which
> will automatically decrypt the old memory encrypted when we read those data
> from the remapping address.
> 
>  ----------------------------------------------
> | first-kernel | second-kernel | kdump support |
> |      (mem_encrypt=on|off)    |   (yes|no)    |
> |--------------+---------------+---------------|
> |     on       |     on        |     yes       |
> |     off      |     off       |     yes       |
> |     on       |     off       |     no        |


> |     off      |     on        |     no        |

It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
you remap the old memory with non-sme mode, why did it fail?

And please run scripts/get_maintainer.pl and add maintainers of
component which is affected in patch to CC list.

> |______________|_______________|_______________|
> 
> This patch is only for SME kdump, it is not support SEV kdump.
> 
> Test tools:
> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
> Author: Lianbo Jiang <lijiang@redhat.com>
> Date:   Mon May 14 17:02:40 2018 +0800
> Note: This patch can only dump vmcore in the case of SME enabled.
> 
> crash-7.2.1: https://github.com/crash-utility/crash.git
> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
> Author: Dave Anderson <anderson@redhat.com>
> Date:   Fri May 11 15:54:32 2018 -0400
> 
> Test environment:
> HP ProLiant DL385Gen10 AMD EPYC 7251
> 8-Core Processor
> 32768 MB memory
> 600 GB disk space
> 
> Linux 4.17-rc7:
> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> commit b04e217704b7 ("Linux 4.17-rc7")
> Author: Linus Torvalds <torvalds@linux-foundation.org>
> Date:   Sun May 27 13:01:47 2018 -0700
> 
> Reference:
> AMD64 Architecture Programmer's Manual
> https://support.amd.com/TechDocs/24593.pdf
> 
> Some changes:
> 1. remove the sme_active() check in __ioremap_caller().
> 2. remove the '#ifdef' stuff throughout this patch.
> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
> 4. add a new file and modify Makefile.
> 5. clean compile warning in copy_device_table() and some compile error.
> 6. split the original patch into four patches, it will be better for
> review.
> 
> Some known issues:
> 1. about SME
> Upstream kernel doesn't work when we use kexec in the follow command. The
> system will hang.
> (This issue doesn't matter with the kdump patch.)
> 
> Reproduce steps:
>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
>  # kexec -e (or reboot)
> 
> The system will hang:
> [ 1248.932239] kexec_core: Starting new kernel
> early console in extract_kernel
> input_data: 0x000000087e91c3b4
> input_len: 0x000000000067fcbd
> output: 0x000000087d400000
> output_len: 0x0000000001b6fa90
> kernel_total_size: 0x0000000001a9d000
> trampoline_32bit: 0x0000000000099000
> 
> Decompressing Linux...
> Parsing ELF...        [-here the system will hang]
> 
> 2. about SEV
> Upstream kernel(Host OS) doesn't work in host side, some drivers about
> SEV always go wrong in host side. We can't boot SEV Guest OS to test
> kdump patch. Maybe it is more reasonable to improve SEV in another
> patch. When some drivers can work in host side and it can also boot
> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
> 
> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
> [  369.433177]       Not tainted 4.17.0-rc5+ #60
> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
> [  369.451323] Call Trace:
> [  369.453815]  ? __schedule+0x290/0x870
> [  369.457523]  schedule+0x32/0x80
> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
> [  369.470084]  ? remove_wait_queue+0x60/0x60
> [  369.474219]  ? 0xffffffffc0247000
> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
> [  369.491380]  ? 0xffffffffc0247000
> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
> [  369.499071]  do_one_initcall+0x4e/0x1d4
> [  369.502944]  ? _cond_resched+0x15/0x30
> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
> [  369.511386]  ? do_init_module+0x22/0x220
> [  369.515345]  do_init_module+0x5a/0x220
> [  369.519444]  load_module+0x21cb/0x2a50
> [  369.523227]  ? m_show+0x1c0/0x1c0
> [  369.526571]  ? security_capable+0x3f/0x60
> [  369.530611]  __do_sys_finit_module+0x94/0xe0
> [  369.534915]  do_syscall_64+0x5b/0x180
> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> [  369.543698] RIP: 0033:0x7f708e6311b9
> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
> 
> Lianbo Jiang (4):
>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
>   Allocate pages for kdump without encryption when SME is enabled
>   Remap the device table of IOMMU in encrypted manner for kdump
>   Help to dump the old memory encrypted into vmcore file
> 
>  arch/x86/include/asm/io.h            |  3 ++
>  arch/x86/kernel/Makefile             |  1 +
>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
>  fs/proc/vmcore.c                     | 20 ++++++++++----
>  include/linux/crash_dump.h           | 11 ++++++++
>  kernel/kexec_core.c                  | 12 ++++++++
>  8 files changed, 128 insertions(+), 15 deletions(-)
>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> 
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-21  1:21   ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:21 UTC (permalink / raw)
  To: Lianbo Jiang
  Cc: thomas.lendacky-5C7GfCeVMHo,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> It is convenient to remap the old memory encrypted to the second kernel by
> calling ioremap_encrypted().
> 
> When sme enabled on AMD server, we also need to support kdump. Because
> the memory is encrypted in the first kernel, we will remap the old memory
> encrypted to the second kernel(crash kernel), and sme is also enabled in
> the second kernel, otherwise the old memory encrypted can not be decrypted.
> Because simply changing the value of a C-bit on a page will not
> automatically encrypt the existing contents of a page, and any data in the
> page prior to the C-bit modification will become unintelligible. A page of
> memory that is marked encrypted will be automatically decrypted when read
> from DRAM and will be automatically encrypted when written to DRAM.
> 
> For the kdump, it is necessary to distinguish whether the memory is
> encrypted. Furthermore, we should also know which part of the memory is
> encrypted or decrypted. We will appropriately remap the memory according
> to the specific situation in order to tell cpu how to deal with the
> data(encrypted or decrypted). For example, when sme enabled, if the old
> memory is encrypted, we will remap the old memory in encrypted way, which
> will automatically decrypt the old memory encrypted when we read those data
> from the remapping address.
> 
>  ----------------------------------------------
> | first-kernel | second-kernel | kdump support |
> |      (mem_encrypt=on|off)    |   (yes|no)    |
> |--------------+---------------+---------------|
> |     on       |     on        |     yes       |
> |     off      |     off       |     yes       |
> |     on       |     off       |     no        |


> |     off      |     on        |     no        |

It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
you remap the old memory with non-sme mode, why did it fail?

And please run scripts/get_maintainer.pl and add maintainers of
component which is affected in patch to CC list.

> |______________|_______________|_______________|
> 
> This patch is only for SME kdump, it is not support SEV kdump.
> 
> Test tools:
> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
> Author: Lianbo Jiang <lijiang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Date:   Mon May 14 17:02:40 2018 +0800
> Note: This patch can only dump vmcore in the case of SME enabled.
> 
> crash-7.2.1: https://github.com/crash-utility/crash.git
> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
> Author: Dave Anderson <anderson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Date:   Fri May 11 15:54:32 2018 -0400
> 
> Test environment:
> HP ProLiant DL385Gen10 AMD EPYC 7251
> 8-Core Processor
> 32768 MB memory
> 600 GB disk space
> 
> Linux 4.17-rc7:
> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> commit b04e217704b7 ("Linux 4.17-rc7")
> Author: Linus Torvalds <torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
> Date:   Sun May 27 13:01:47 2018 -0700
> 
> Reference:
> AMD64 Architecture Programmer's Manual
> https://support.amd.com/TechDocs/24593.pdf
> 
> Some changes:
> 1. remove the sme_active() check in __ioremap_caller().
> 2. remove the '#ifdef' stuff throughout this patch.
> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
> 4. add a new file and modify Makefile.
> 5. clean compile warning in copy_device_table() and some compile error.
> 6. split the original patch into four patches, it will be better for
> review.
> 
> Some known issues:
> 1. about SME
> Upstream kernel doesn't work when we use kexec in the follow command. The
> system will hang.
> (This issue doesn't matter with the kdump patch.)
> 
> Reproduce steps:
>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
>  # kexec -e (or reboot)
> 
> The system will hang:
> [ 1248.932239] kexec_core: Starting new kernel
> early console in extract_kernel
> input_data: 0x000000087e91c3b4
> input_len: 0x000000000067fcbd
> output: 0x000000087d400000
> output_len: 0x0000000001b6fa90
> kernel_total_size: 0x0000000001a9d000
> trampoline_32bit: 0x0000000000099000
> 
> Decompressing Linux...
> Parsing ELF...        [-here the system will hang]
> 
> 2. about SEV
> Upstream kernel(Host OS) doesn't work in host side, some drivers about
> SEV always go wrong in host side. We can't boot SEV Guest OS to test
> kdump patch. Maybe it is more reasonable to improve SEV in another
> patch. When some drivers can work in host side and it can also boot
> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
> 
> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
> [  369.433177]       Not tainted 4.17.0-rc5+ #60
> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
> [  369.451323] Call Trace:
> [  369.453815]  ? __schedule+0x290/0x870
> [  369.457523]  schedule+0x32/0x80
> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
> [  369.470084]  ? remove_wait_queue+0x60/0x60
> [  369.474219]  ? 0xffffffffc0247000
> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
> [  369.491380]  ? 0xffffffffc0247000
> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
> [  369.499071]  do_one_initcall+0x4e/0x1d4
> [  369.502944]  ? _cond_resched+0x15/0x30
> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
> [  369.511386]  ? do_init_module+0x22/0x220
> [  369.515345]  do_init_module+0x5a/0x220
> [  369.519444]  load_module+0x21cb/0x2a50
> [  369.523227]  ? m_show+0x1c0/0x1c0
> [  369.526571]  ? security_capable+0x3f/0x60
> [  369.530611]  __do_sys_finit_module+0x94/0xe0
> [  369.534915]  do_syscall_64+0x5b/0x180
> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> [  369.543698] RIP: 0033:0x7f708e6311b9
> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
> 
> Lianbo Jiang (4):
>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
>   Allocate pages for kdump without encryption when SME is enabled
>   Remap the device table of IOMMU in encrypted manner for kdump
>   Help to dump the old memory encrypted into vmcore file
> 
>  arch/x86/include/asm/io.h            |  3 ++
>  arch/x86/kernel/Makefile             |  1 +
>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
>  fs/proc/vmcore.c                     | 20 ++++++++++----
>  include/linux/crash_dump.h           | 11 ++++++++
>  kernel/kexec_core.c                  | 12 ++++++++
>  8 files changed, 128 insertions(+), 15 deletions(-)
>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> 
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-21  1:21   ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:21 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: thomas.lendacky, kexec, linux-kernel, iommu, akpm, dyoung

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> It is convenient to remap the old memory encrypted to the second kernel by
> calling ioremap_encrypted().
> 
> When sme enabled on AMD server, we also need to support kdump. Because
> the memory is encrypted in the first kernel, we will remap the old memory
> encrypted to the second kernel(crash kernel), and sme is also enabled in
> the second kernel, otherwise the old memory encrypted can not be decrypted.
> Because simply changing the value of a C-bit on a page will not
> automatically encrypt the existing contents of a page, and any data in the
> page prior to the C-bit modification will become unintelligible. A page of
> memory that is marked encrypted will be automatically decrypted when read
> from DRAM and will be automatically encrypted when written to DRAM.
> 
> For the kdump, it is necessary to distinguish whether the memory is
> encrypted. Furthermore, we should also know which part of the memory is
> encrypted or decrypted. We will appropriately remap the memory according
> to the specific situation in order to tell cpu how to deal with the
> data(encrypted or decrypted). For example, when sme enabled, if the old
> memory is encrypted, we will remap the old memory in encrypted way, which
> will automatically decrypt the old memory encrypted when we read those data
> from the remapping address.
> 
>  ----------------------------------------------
> | first-kernel | second-kernel | kdump support |
> |      (mem_encrypt=on|off)    |   (yes|no)    |
> |--------------+---------------+---------------|
> |     on       |     on        |     yes       |
> |     off      |     off       |     yes       |
> |     on       |     off       |     no        |


> |     off      |     on        |     no        |

It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
you remap the old memory with non-sme mode, why did it fail?

And please run scripts/get_maintainer.pl and add maintainers of
component which is affected in patch to CC list.

> |______________|_______________|_______________|
> 
> This patch is only for SME kdump, it is not support SEV kdump.
> 
> Test tools:
> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
> Author: Lianbo Jiang <lijiang@redhat.com>
> Date:   Mon May 14 17:02:40 2018 +0800
> Note: This patch can only dump vmcore in the case of SME enabled.
> 
> crash-7.2.1: https://github.com/crash-utility/crash.git
> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
> Author: Dave Anderson <anderson@redhat.com>
> Date:   Fri May 11 15:54:32 2018 -0400
> 
> Test environment:
> HP ProLiant DL385Gen10 AMD EPYC 7251
> 8-Core Processor
> 32768 MB memory
> 600 GB disk space
> 
> Linux 4.17-rc7:
> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> commit b04e217704b7 ("Linux 4.17-rc7")
> Author: Linus Torvalds <torvalds@linux-foundation.org>
> Date:   Sun May 27 13:01:47 2018 -0700
> 
> Reference:
> AMD64 Architecture Programmer's Manual
> https://support.amd.com/TechDocs/24593.pdf
> 
> Some changes:
> 1. remove the sme_active() check in __ioremap_caller().
> 2. remove the '#ifdef' stuff throughout this patch.
> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
> 4. add a new file and modify Makefile.
> 5. clean compile warning in copy_device_table() and some compile error.
> 6. split the original patch into four patches, it will be better for
> review.
> 
> Some known issues:
> 1. about SME
> Upstream kernel doesn't work when we use kexec in the follow command. The
> system will hang.
> (This issue doesn't matter with the kdump patch.)
> 
> Reproduce steps:
>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
>  # kexec -e (or reboot)
> 
> The system will hang:
> [ 1248.932239] kexec_core: Starting new kernel
> early console in extract_kernel
> input_data: 0x000000087e91c3b4
> input_len: 0x000000000067fcbd
> output: 0x000000087d400000
> output_len: 0x0000000001b6fa90
> kernel_total_size: 0x0000000001a9d000
> trampoline_32bit: 0x0000000000099000
> 
> Decompressing Linux...
> Parsing ELF...        [-here the system will hang]
> 
> 2. about SEV
> Upstream kernel(Host OS) doesn't work in host side, some drivers about
> SEV always go wrong in host side. We can't boot SEV Guest OS to test
> kdump patch. Maybe it is more reasonable to improve SEV in another
> patch. When some drivers can work in host side and it can also boot
> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
> 
> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
> [  369.433177]       Not tainted 4.17.0-rc5+ #60
> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
> [  369.451323] Call Trace:
> [  369.453815]  ? __schedule+0x290/0x870
> [  369.457523]  schedule+0x32/0x80
> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
> [  369.470084]  ? remove_wait_queue+0x60/0x60
> [  369.474219]  ? 0xffffffffc0247000
> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
> [  369.491380]  ? 0xffffffffc0247000
> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
> [  369.499071]  do_one_initcall+0x4e/0x1d4
> [  369.502944]  ? _cond_resched+0x15/0x30
> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
> [  369.511386]  ? do_init_module+0x22/0x220
> [  369.515345]  do_init_module+0x5a/0x220
> [  369.519444]  load_module+0x21cb/0x2a50
> [  369.523227]  ? m_show+0x1c0/0x1c0
> [  369.526571]  ? security_capable+0x3f/0x60
> [  369.530611]  __do_sys_finit_module+0x94/0xe0
> [  369.534915]  do_syscall_64+0x5b/0x180
> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> [  369.543698] RIP: 0033:0x7f708e6311b9
> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
> 
> Lianbo Jiang (4):
>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
>   Allocate pages for kdump without encryption when SME is enabled
>   Remap the device table of IOMMU in encrypted manner for kdump
>   Help to dump the old memory encrypted into vmcore file
> 
>  arch/x86/include/asm/io.h            |  3 ++
>  arch/x86/kernel/Makefile             |  1 +
>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
>  fs/proc/vmcore.c                     | 20 ++++++++++----
>  include/linux/crash_dump.h           | 11 ++++++++
>  kernel/kexec_core.c                  | 12 ++++++++
>  8 files changed, 128 insertions(+), 15 deletions(-)
>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> 
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21  1:53     ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:53 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> When SME is enabled in the first kernel, we will allocate pages
> for kdump without encryption in order to be able to boot the
> second kernel in the same manner as kexec, which helps to keep
> the same code style.
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
>  kernel/kexec_core.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> index 20fef1a..3c22a9b 100644
> --- a/kernel/kexec_core.c
> +++ b/kernel/kexec_core.c
> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>  		}
>  	}
>  
> +	if (pages) {
> +		unsigned int count, i;
> +
> +		pages->mapping = NULL;
> +		set_page_private(pages, order);
> +		count = 1 << order;
> +		for (i = 0; i < count; i++)
> +			SetPageReserved(pages + i);

I guess you might imitate the kexec case, however kexec get pages from
buddy. Crash pages are reserved in memblock, these codes might make no sense.

> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
> +	}
>  	return pages;
>  }
>  
> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>  			result  = -ENOMEM;
>  			goto out;
>  		}
> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>  		ptr = kmap(page);
>  		ptr += maddr & ~PAGE_MASK;
>  		mchunk = min_t(size_t, mbytes,
> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>  			result = copy_from_user(ptr, buf, uchunk);
>  		kexec_flush_icache_page(page);
>  		kunmap(page);
> +		arch_kexec_pre_free_pages(page_address(page), 1);
>  		if (result) {
>  			result = -EFAULT;
>  			goto out;
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21  1:53     ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:53 UTC (permalink / raw)
  To: Lianbo Jiang
  Cc: thomas.lendacky-5C7GfCeVMHo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> When SME is enabled in the first kernel, we will allocate pages
> for kdump without encryption in order to be able to boot the
> second kernel in the same manner as kexec, which helps to keep
> the same code style.
> 
> Signed-off-by: Lianbo Jiang <lijiang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  kernel/kexec_core.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> index 20fef1a..3c22a9b 100644
> --- a/kernel/kexec_core.c
> +++ b/kernel/kexec_core.c
> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>  		}
>  	}
>  
> +	if (pages) {
> +		unsigned int count, i;
> +
> +		pages->mapping = NULL;
> +		set_page_private(pages, order);
> +		count = 1 << order;
> +		for (i = 0; i < count; i++)
> +			SetPageReserved(pages + i);

I guess you might imitate the kexec case, however kexec get pages from
buddy. Crash pages are reserved in memblock, these codes might make no sense.

> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
> +	}
>  	return pages;
>  }
>  
> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>  			result  = -ENOMEM;
>  			goto out;
>  		}
> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>  		ptr = kmap(page);
>  		ptr += maddr & ~PAGE_MASK;
>  		mchunk = min_t(size_t, mbytes,
> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>  			result = copy_from_user(ptr, buf, uchunk);
>  		kexec_flush_icache_page(page);
>  		kunmap(page);
> +		arch_kexec_pre_free_pages(page_address(page), 1);
>  		if (result) {
>  			result = -EFAULT;
>  			goto out;
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21  1:53     ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:53 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: thomas.lendacky, iommu, dyoung, linux-kernel, kexec

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> When SME is enabled in the first kernel, we will allocate pages
> for kdump without encryption in order to be able to boot the
> second kernel in the same manner as kexec, which helps to keep
> the same code style.
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
>  kernel/kexec_core.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> index 20fef1a..3c22a9b 100644
> --- a/kernel/kexec_core.c
> +++ b/kernel/kexec_core.c
> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>  		}
>  	}
>  
> +	if (pages) {
> +		unsigned int count, i;
> +
> +		pages->mapping = NULL;
> +		set_page_private(pages, order);
> +		count = 1 << order;
> +		for (i = 0; i < count; i++)
> +			SetPageReserved(pages + i);

I guess you might imitate the kexec case, however kexec get pages from
buddy. Crash pages are reserved in memblock, these codes might make no sense.

> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
> +	}
>  	return pages;
>  }
>  
> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>  			result  = -ENOMEM;
>  			goto out;
>  		}
> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>  		ptr = kmap(page);
>  		ptr += maddr & ~PAGE_MASK;
>  		mchunk = min_t(size_t, mbytes,
> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>  			result = copy_from_user(ptr, buf, uchunk);
>  		kexec_flush_icache_page(page);
>  		kunmap(page);
> +		arch_kexec_pre_free_pages(page_address(page), 1);
>  		if (result) {
>  			result = -EFAULT;
>  			goto out;
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  1:57     ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:57 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> In kdump mode, it will copy the device table of IOMMU from the old
> device table, which is encrypted when SME is enabled in the first
> kernel. So we must remap it in encrypted manner in order to be
> automatically decrypted when we read.
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. add some comments
> 2. clean compile warning.
> 
>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> index 904c575..a20af4c 100644
> --- a/drivers/iommu/amd_iommu_init.c
> +++ b/drivers/iommu/amd_iommu_init.c
> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>  	}
>  
>  	old_devtb_phys = entry & PAGE_MASK;
> +
> +	/*
> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> +	 *  encryption mask to obtain the true physical address in kdump mode.
> +	 */
> +	if (mem_encrypt_active() && is_kdump_kernel())
> +		old_devtb_phys = __sme_clr(old_devtb_phys);

This is my question asked in cover letter. If 1st kernel sme is off, 2nd
kernel sme is on, you remap it with sme enabled or disabled on purpose,
why does that not work? It's not concern to this patch.

> +
>  	if (old_devtb_phys >= 0x100000000ULL) {
>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>  		return false;
>  	}
> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> +							dev_table_size)
> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +
>  	if (!old_devtb)
>  		return false;
>  
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  1:57     ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:57 UTC (permalink / raw)
  To: Lianbo Jiang
  Cc: thomas.lendacky-5C7GfCeVMHo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> In kdump mode, it will copy the device table of IOMMU from the old
> device table, which is encrypted when SME is enabled in the first
> kernel. So we must remap it in encrypted manner in order to be
> automatically decrypted when we read.
> 
> Signed-off-by: Lianbo Jiang <lijiang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> Some changes:
> 1. add some comments
> 2. clean compile warning.
> 
>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> index 904c575..a20af4c 100644
> --- a/drivers/iommu/amd_iommu_init.c
> +++ b/drivers/iommu/amd_iommu_init.c
> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>  	}
>  
>  	old_devtb_phys = entry & PAGE_MASK;
> +
> +	/*
> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> +	 *  encryption mask to obtain the true physical address in kdump mode.
> +	 */
> +	if (mem_encrypt_active() && is_kdump_kernel())
> +		old_devtb_phys = __sme_clr(old_devtb_phys);

This is my question asked in cover letter. If 1st kernel sme is off, 2nd
kernel sme is on, you remap it with sme enabled or disabled on purpose,
why does that not work? It's not concern to this patch.

> +
>  	if (old_devtb_phys >= 0x100000000ULL) {
>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>  		return false;
>  	}
> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> +							dev_table_size)
> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +
>  	if (!old_devtb)
>  		return false;
>  
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  1:57     ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  1:57 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: thomas.lendacky, iommu, dyoung, linux-kernel, kexec

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> In kdump mode, it will copy the device table of IOMMU from the old
> device table, which is encrypted when SME is enabled in the first
> kernel. So we must remap it in encrypted manner in order to be
> automatically decrypted when we read.
> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. add some comments
> 2. clean compile warning.
> 
>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> index 904c575..a20af4c 100644
> --- a/drivers/iommu/amd_iommu_init.c
> +++ b/drivers/iommu/amd_iommu_init.c
> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>  	}
>  
>  	old_devtb_phys = entry & PAGE_MASK;
> +
> +	/*
> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> +	 *  encryption mask to obtain the true physical address in kdump mode.
> +	 */
> +	if (mem_encrypt_active() && is_kdump_kernel())
> +		old_devtb_phys = __sme_clr(old_devtb_phys);

This is my question asked in cover letter. If 1st kernel sme is off, 2nd
kernel sme is on, you remap it with sme enabled or disabled on purpose,
why does that not work? It's not concern to this patch.

> +
>  	if (old_devtb_phys >= 0x100000000ULL) {
>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>  		return false;
>  	}
> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> +							dev_table_size)
> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> +
>  	if (!old_devtb)
>  		return false;
>  
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
  2018-06-16  8:27   ` Lianbo Jiang
@ 2018-06-21  2:47     ` Baoquan He
  -1 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  2:47 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> In kdump mode, we need to dump the old memory into vmcore file,
> if SME is enabled in the first kernel, we must remap the old
> memory in encrypted manner, which will be automatically decrypted
> when we read from DRAM. It helps to parse the vmcore for some tools.

It implies 2nd kernel is sme enabled, right?

Then what if 1st kernel has no sme enabled?

> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. add a new file and modify Makefile.
> 2. remove some code in sev_active().
> 
>  arch/x86/kernel/Makefile             |  1 +
>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>  fs/proc/vmcore.c                     | 20 ++++++++++----
>  include/linux/crash_dump.h           | 11 ++++++++
>  4 files changed, 79 insertions(+), 6 deletions(-)
>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> 
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index 02d6f5c..afb5bad 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>  obj-y				+= kprobes/
>  obj-$(CONFIG_MODULES)		+= module.o
>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
> new file mode 100644
> index 0000000..e44ef33
> --- /dev/null
> +++ b/arch/x86/kernel/crash_dump_encrypt.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + *	Memory preserving reboot related code.
> + *
> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/crash_dump.h>
> +#include <linux/uaccess.h>
> +#include <linux/io.h>
> +
> +/**
> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
> + * @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)
> + * @csize: number of bytes to copy
> + * @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().
> + *
> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
> +		size_t csize, unsigned long offset, int userbuf)
> +{
> +	void  *vaddr;
> +
> +	if (!csize)
> +		return 0;
> +
> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
> +						  PAGE_SIZE);
> +	if (!vaddr)
> +		return -ENOMEM;
> +
> +	if (userbuf) {
> +		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((void __iomem *)vaddr);
> +	return csize;
> +}
> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
> index a45f0af..5200266 100644
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -25,6 +25,8 @@
>  #include <linux/uaccess.h>
>  #include <asm/io.h>
>  #include "internal.h"
> +#include <linux/mem_encrypt.h>
> +#include <asm/pgtable.h>
>  
>  /* List representing chunks of contiguous memory areas and their offsets in
>   * vmcore file.
> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>  
>  /* Reads a page from the oldmem device from given offset. */
>  static ssize_t read_from_oldmem(char *buf, size_t count,
> -				u64 *ppos, int userbuf)
> +				u64 *ppos, int userbuf,
> +				bool encrypted)
>  {
>  	unsigned long pfn, offset;
>  	size_t nr_bytes;
> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>  		if (pfn_is_ram(pfn) == 0)
>  			memset(buf, 0, nr_bytes);
>  		else {
> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
> -						offset, userbuf);
> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
> +					    buf, nr_bytes, offset, userbuf)
> +					: copy_oldmem_page(pfn, buf, nr_bytes,
> +							   offset, userbuf);
> +
>  			if (tmp < 0)
>  				return tmp;
>  		}
> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>   */
>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, false);
>  }
>  
>  /*
> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>   */
>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>  }
>  
>  /*
> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  				  unsigned long from, unsigned long pfn,
>  				  unsigned long size, pgprot_t prot)
>  {
> +	prot = pgprot_encrypted(prot);
>  	return remap_pfn_range(vma, from, pfn, size, prot);
>  }
>  
> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>  					    m->offset + m->size - *fpos,
>  					    buflen);
>  			start = m->paddr + *fpos - m->offset;
> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
> +						sme_active());
>  			if (tmp < 0)
>  				return tmp;
>  			buflen -= tsz;
> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
> index f7ac2aa..f3414ff 100644
> --- a/include/linux/crash_dump.h
> +++ b/include/linux/crash_dump.h
> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  
>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>  						unsigned long, int);
> +#ifdef CONFIG_AMD_MEM_ENCRYPT
> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					   size_t csize, unsigned long offset,
> +					   int userbuf);
> +#else
> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					size_t csize, unsigned long offset,
> +					int userbuf) {
> +	return csize;
> +}
> +#endif
>  void vmcore_cleanup(void);
>  
>  /* Architecture code defines this if there are other possible ELF
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file
@ 2018-06-21  2:47     ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  2:47 UTC (permalink / raw)
  To: Lianbo Jiang; +Cc: thomas.lendacky, iommu, dyoung, linux-kernel, kexec

On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> In kdump mode, we need to dump the old memory into vmcore file,
> if SME is enabled in the first kernel, we must remap the old
> memory in encrypted manner, which will be automatically decrypted
> when we read from DRAM. It helps to parse the vmcore for some tools.

It implies 2nd kernel is sme enabled, right?

Then what if 1st kernel has no sme enabled?

> 
> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> ---
> Some changes:
> 1. add a new file and modify Makefile.
> 2. remove some code in sev_active().
> 
>  arch/x86/kernel/Makefile             |  1 +
>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>  fs/proc/vmcore.c                     | 20 ++++++++++----
>  include/linux/crash_dump.h           | 11 ++++++++
>  4 files changed, 79 insertions(+), 6 deletions(-)
>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> 
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index 02d6f5c..afb5bad 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -96,6 +96,7 @@ obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec_$(BITS).o
>  obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o
>  obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o
>  obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= crash_dump_encrypt.o
>  obj-y				+= kprobes/
>  obj-$(CONFIG_MODULES)		+= module.o
>  obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
> diff --git a/arch/x86/kernel/crash_dump_encrypt.c b/arch/x86/kernel/crash_dump_encrypt.c
> new file mode 100644
> index 0000000..e44ef33
> --- /dev/null
> +++ b/arch/x86/kernel/crash_dump_encrypt.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + *	Memory preserving reboot related code.
> + *
> + *	Created by: Lianbo Jiang (lijiang@redhat.com)
> + *	Copyright (C) RedHat Corporation, 2018. All rights reserved
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/crash_dump.h>
> +#include <linux/uaccess.h>
> +#include <linux/io.h>
> +
> +/**
> + * copy_oldmem_page_encrypted - copy one page from "oldmem encrypted"
> + * @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)
> + * @csize: number of bytes to copy
> + * @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().
> + *
> + * Copy a page from "oldmem encrypted". 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_encrypted(unsigned long pfn, char *buf,
> +		size_t csize, unsigned long offset, int userbuf)
> +{
> +	void  *vaddr;
> +
> +	if (!csize)
> +		return 0;
> +
> +	vaddr = (__force void *)ioremap_encrypted(pfn << PAGE_SHIFT,
> +						  PAGE_SIZE);
> +	if (!vaddr)
> +		return -ENOMEM;
> +
> +	if (userbuf) {
> +		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((void __iomem *)vaddr);
> +	return csize;
> +}
> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
> index a45f0af..5200266 100644
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -25,6 +25,8 @@
>  #include <linux/uaccess.h>
>  #include <asm/io.h>
>  #include "internal.h"
> +#include <linux/mem_encrypt.h>
> +#include <asm/pgtable.h>
>  
>  /* List representing chunks of contiguous memory areas and their offsets in
>   * vmcore file.
> @@ -86,7 +88,8 @@ static int pfn_is_ram(unsigned long pfn)
>  
>  /* Reads a page from the oldmem device from given offset. */
>  static ssize_t read_from_oldmem(char *buf, size_t count,
> -				u64 *ppos, int userbuf)
> +				u64 *ppos, int userbuf,
> +				bool encrypted)
>  {
>  	unsigned long pfn, offset;
>  	size_t nr_bytes;
> @@ -108,8 +111,11 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
>  		if (pfn_is_ram(pfn) == 0)
>  			memset(buf, 0, nr_bytes);
>  		else {
> -			tmp = copy_oldmem_page(pfn, buf, nr_bytes,
> -						offset, userbuf);
> +			tmp = encrypted ? copy_oldmem_page_encrypted(pfn,
> +					    buf, nr_bytes, offset, userbuf)
> +					: copy_oldmem_page(pfn, buf, nr_bytes,
> +							   offset, userbuf);
> +
>  			if (tmp < 0)
>  				return tmp;
>  		}
> @@ -143,7 +149,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
>   */
>  ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, false);
>  }
>  
>  /*
> @@ -151,7 +157,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
>   */
>  ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
>  {
> -	return read_from_oldmem(buf, count, ppos, 0);
> +	return read_from_oldmem(buf, count, ppos, 0, sme_active());
>  }
>  
>  /*
> @@ -161,6 +167,7 @@ int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  				  unsigned long from, unsigned long pfn,
>  				  unsigned long size, pgprot_t prot)
>  {
> +	prot = pgprot_encrypted(prot);
>  	return remap_pfn_range(vma, from, pfn, size, prot);
>  }
>  
> @@ -235,7 +242,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
>  					    m->offset + m->size - *fpos,
>  					    buflen);
>  			start = m->paddr + *fpos - m->offset;
> -			tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
> +			tmp = read_from_oldmem(buffer, tsz, &start, userbuf,
> +						sme_active());
>  			if (tmp < 0)
>  				return tmp;
>  			buflen -= tsz;
> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
> index f7ac2aa..f3414ff 100644
> --- a/include/linux/crash_dump.h
> +++ b/include/linux/crash_dump.h
> @@ -25,6 +25,17 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
>  
>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>  						unsigned long, int);
> +#ifdef CONFIG_AMD_MEM_ENCRYPT
> +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					   size_t csize, unsigned long offset,
> +					   int userbuf);
> +#else
> +static inline ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
> +					size_t csize, unsigned long offset,
> +					int userbuf) {
> +	return csize;
> +}
> +#endif
>  void vmcore_cleanup(void);
>  
>  /* Architecture code defines this if there are other possible ELF
> -- 
> 2.9.5
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
  2018-06-21  1:21   ` Baoquan He
  (?)
@ 2018-06-21  3:18     ` lijiang
  -1 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  3:18 UTC (permalink / raw)
  To: Baoquan He; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec, akpm

在 2018年06月21日 09:21, Baoquan He 写道:
> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>> It is convenient to remap the old memory encrypted to the second kernel by
>> calling ioremap_encrypted().
>>
>> When sme enabled on AMD server, we also need to support kdump. Because
>> the memory is encrypted in the first kernel, we will remap the old memory
>> encrypted to the second kernel(crash kernel), and sme is also enabled in
>> the second kernel, otherwise the old memory encrypted can not be decrypted.
>> Because simply changing the value of a C-bit on a page will not
>> automatically encrypt the existing contents of a page, and any data in the
>> page prior to the C-bit modification will become unintelligible. A page of
>> memory that is marked encrypted will be automatically decrypted when read
>> from DRAM and will be automatically encrypted when written to DRAM.
>>
>> For the kdump, it is necessary to distinguish whether the memory is
>> encrypted. Furthermore, we should also know which part of the memory is
>> encrypted or decrypted. We will appropriately remap the memory according
>> to the specific situation in order to tell cpu how to deal with the
>> data(encrypted or decrypted). For example, when sme enabled, if the old
>> memory is encrypted, we will remap the old memory in encrypted way, which
>> will automatically decrypt the old memory encrypted when we read those data
>> from the remapping address.
>>
>>  ----------------------------------------------
>> | first-kernel | second-kernel | kdump support |
>> |      (mem_encrypt=on|off)    |   (yes|no)    |
>> |--------------+---------------+---------------|
>> |     on       |     on        |     yes       |
>> |     off      |     off       |     yes       |
>> |     on       |     off       |     no        |
> 
> 
>> |     off      |     on        |     no        |
> 
> It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
> you remap the old memory with non-sme mode, why did it fail?
> 
Thank you, Baoquan.
For kdump, there are two cases that doesn't need to support:

1. SME on(first kernel), but SME off(second kernel).
Because the old memory is encrypted, we can't decrypt the old memory if SME is off
in the second kernel(in kdump mode).

2. SME off(first kernel), but SME on(second kernel)
Maybe this situation doesn't have significance in actual deployment, furthermore, it
will also increase the complexity of the code. It's just for testing, maybe it is
unnecessary to support it, because the old memory is unencrypted.

Thanks.
Lianbo
> And please run scripts/get_maintainer.pl and add maintainers of
> component which is affected in patch to CC list.
Great! I forgot CC maintainers, thanks for your reminder.

Lianbo
> 
>> |______________|_______________|_______________|
>>
>> This patch is only for SME kdump, it is not support SEV kdump.
>>
>> Test tools:
>> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
>> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
>> Author: Lianbo Jiang <lijiang@redhat.com>
>> Date:   Mon May 14 17:02:40 2018 +0800
>> Note: This patch can only dump vmcore in the case of SME enabled.
>>
>> crash-7.2.1: https://github.com/crash-utility/crash.git
>> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
>> Author: Dave Anderson <anderson@redhat.com>
>> Date:   Fri May 11 15:54:32 2018 -0400
>>
>> Test environment:
>> HP ProLiant DL385Gen10 AMD EPYC 7251
>> 8-Core Processor
>> 32768 MB memory
>> 600 GB disk space
>>
>> Linux 4.17-rc7:
>> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
>> commit b04e217704b7 ("Linux 4.17-rc7")
>> Author: Linus Torvalds <torvalds@linux-foundation.org>
>> Date:   Sun May 27 13:01:47 2018 -0700
>>
>> Reference:
>> AMD64 Architecture Programmer's Manual
>> https://support.amd.com/TechDocs/24593.pdf
>>
>> Some changes:
>> 1. remove the sme_active() check in __ioremap_caller().
>> 2. remove the '#ifdef' stuff throughout this patch.
>> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
>> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
>> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
>> 4. add a new file and modify Makefile.
>> 5. clean compile warning in copy_device_table() and some compile error.
>> 6. split the original patch into four patches, it will be better for
>> review.
>>
>> Some known issues:
>> 1. about SME
>> Upstream kernel doesn't work when we use kexec in the follow command. The
>> system will hang.
>> (This issue doesn't matter with the kdump patch.)
>>
>> Reproduce steps:
>>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
>>  # kexec -e (or reboot)
>>
>> The system will hang:
>> [ 1248.932239] kexec_core: Starting new kernel
>> early console in extract_kernel
>> input_data: 0x000000087e91c3b4
>> input_len: 0x000000000067fcbd
>> output: 0x000000087d400000
>> output_len: 0x0000000001b6fa90
>> kernel_total_size: 0x0000000001a9d000
>> trampoline_32bit: 0x0000000000099000
>>
>> Decompressing Linux...
>> Parsing ELF...        [-here the system will hang]
>>
>> 2. about SEV
>> Upstream kernel(Host OS) doesn't work in host side, some drivers about
>> SEV always go wrong in host side. We can't boot SEV Guest OS to test
>> kdump patch. Maybe it is more reasonable to improve SEV in another
>> patch. When some drivers can work in host side and it can also boot
>> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
>>
>> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
>> [  369.433177]       Not tainted 4.17.0-rc5+ #60
>> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
>> [  369.451323] Call Trace:
>> [  369.453815]  ? __schedule+0x290/0x870
>> [  369.457523]  schedule+0x32/0x80
>> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
>> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
>> [  369.470084]  ? remove_wait_queue+0x60/0x60
>> [  369.474219]  ? 0xffffffffc0247000
>> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
>> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
>> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
>> [  369.491380]  ? 0xffffffffc0247000
>> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
>> [  369.499071]  do_one_initcall+0x4e/0x1d4
>> [  369.502944]  ? _cond_resched+0x15/0x30
>> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
>> [  369.511386]  ? do_init_module+0x22/0x220
>> [  369.515345]  do_init_module+0x5a/0x220
>> [  369.519444]  load_module+0x21cb/0x2a50
>> [  369.523227]  ? m_show+0x1c0/0x1c0
>> [  369.526571]  ? security_capable+0x3f/0x60
>> [  369.530611]  __do_sys_finit_module+0x94/0xe0
>> [  369.534915]  do_syscall_64+0x5b/0x180
>> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>> [  369.543698] RIP: 0033:0x7f708e6311b9
>> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
>> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
>> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
>> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
>> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
>> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
>>
>> Lianbo Jiang (4):
>>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
>>   Allocate pages for kdump without encryption when SME is enabled
>>   Remap the device table of IOMMU in encrypted manner for kdump
>>   Help to dump the old memory encrypted into vmcore file
>>
>>  arch/x86/include/asm/io.h            |  3 ++
>>  arch/x86/kernel/Makefile             |  1 +
>>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
>>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
>>  fs/proc/vmcore.c                     | 20 ++++++++++----
>>  include/linux/crash_dump.h           | 11 ++++++++
>>  kernel/kexec_core.c                  | 12 ++++++++
>>  8 files changed, 128 insertions(+), 15 deletions(-)
>>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
>>
>> -- 
>> 2.9.5
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-21  3:18     ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  3:18 UTC (permalink / raw)
  To: Baoquan He
  Cc: thomas.lendacky-5C7GfCeVMHo,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA

在 2018年06月21日 09:21, Baoquan He 写道:
> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>> It is convenient to remap the old memory encrypted to the second kernel by
>> calling ioremap_encrypted().
>>
>> When sme enabled on AMD server, we also need to support kdump. Because
>> the memory is encrypted in the first kernel, we will remap the old memory
>> encrypted to the second kernel(crash kernel), and sme is also enabled in
>> the second kernel, otherwise the old memory encrypted can not be decrypted.
>> Because simply changing the value of a C-bit on a page will not
>> automatically encrypt the existing contents of a page, and any data in the
>> page prior to the C-bit modification will become unintelligible. A page of
>> memory that is marked encrypted will be automatically decrypted when read
>> from DRAM and will be automatically encrypted when written to DRAM.
>>
>> For the kdump, it is necessary to distinguish whether the memory is
>> encrypted. Furthermore, we should also know which part of the memory is
>> encrypted or decrypted. We will appropriately remap the memory according
>> to the specific situation in order to tell cpu how to deal with the
>> data(encrypted or decrypted). For example, when sme enabled, if the old
>> memory is encrypted, we will remap the old memory in encrypted way, which
>> will automatically decrypt the old memory encrypted when we read those data
>> from the remapping address.
>>
>>  ----------------------------------------------
>> | first-kernel | second-kernel | kdump support |
>> |      (mem_encrypt=on|off)    |   (yes|no)    |
>> |--------------+---------------+---------------|
>> |     on       |     on        |     yes       |
>> |     off      |     off       |     yes       |
>> |     on       |     off       |     no        |
> 
> 
>> |     off      |     on        |     no        |
> 
> It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
> you remap the old memory with non-sme mode, why did it fail?
> 
Thank you, Baoquan.
For kdump, there are two cases that doesn't need to support:

1. SME on(first kernel), but SME off(second kernel).
Because the old memory is encrypted, we can't decrypt the old memory if SME is off
in the second kernel(in kdump mode).

2. SME off(first kernel), but SME on(second kernel)
Maybe this situation doesn't have significance in actual deployment, furthermore, it
will also increase the complexity of the code. It's just for testing, maybe it is
unnecessary to support it, because the old memory is unencrypted.

Thanks.
Lianbo
> And please run scripts/get_maintainer.pl and add maintainers of
> component which is affected in patch to CC list.
Great! I forgot CC maintainers, thanks for your reminder.

Lianbo
> 
>> |______________|_______________|_______________|
>>
>> This patch is only for SME kdump, it is not support SEV kdump.
>>
>> Test tools:
>> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
>> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
>> Author: Lianbo Jiang <lijiang@redhat.com>
>> Date:   Mon May 14 17:02:40 2018 +0800
>> Note: This patch can only dump vmcore in the case of SME enabled.
>>
>> crash-7.2.1: https://github.com/crash-utility/crash.git
>> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
>> Author: Dave Anderson <anderson@redhat.com>
>> Date:   Fri May 11 15:54:32 2018 -0400
>>
>> Test environment:
>> HP ProLiant DL385Gen10 AMD EPYC 7251
>> 8-Core Processor
>> 32768 MB memory
>> 600 GB disk space
>>
>> Linux 4.17-rc7:
>> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
>> commit b04e217704b7 ("Linux 4.17-rc7")
>> Author: Linus Torvalds <torvalds@linux-foundation.org>
>> Date:   Sun May 27 13:01:47 2018 -0700
>>
>> Reference:
>> AMD64 Architecture Programmer's Manual
>> https://support.amd.com/TechDocs/24593.pdf
>>
>> Some changes:
>> 1. remove the sme_active() check in __ioremap_caller().
>> 2. remove the '#ifdef' stuff throughout this patch.
>> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
>> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
>> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
>> 4. add a new file and modify Makefile.
>> 5. clean compile warning in copy_device_table() and some compile error.
>> 6. split the original patch into four patches, it will be better for
>> review.
>>
>> Some known issues:
>> 1. about SME
>> Upstream kernel doesn't work when we use kexec in the follow command. The
>> system will hang.
>> (This issue doesn't matter with the kdump patch.)
>>
>> Reproduce steps:
>>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
>>  # kexec -e (or reboot)
>>
>> The system will hang:
>> [ 1248.932239] kexec_core: Starting new kernel
>> early console in extract_kernel
>> input_data: 0x000000087e91c3b4
>> input_len: 0x000000000067fcbd
>> output: 0x000000087d400000
>> output_len: 0x0000000001b6fa90
>> kernel_total_size: 0x0000000001a9d000
>> trampoline_32bit: 0x0000000000099000
>>
>> Decompressing Linux...
>> Parsing ELF...        [-here the system will hang]
>>
>> 2. about SEV
>> Upstream kernel(Host OS) doesn't work in host side, some drivers about
>> SEV always go wrong in host side. We can't boot SEV Guest OS to test
>> kdump patch. Maybe it is more reasonable to improve SEV in another
>> patch. When some drivers can work in host side and it can also boot
>> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
>>
>> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
>> [  369.433177]       Not tainted 4.17.0-rc5+ #60
>> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
>> [  369.451323] Call Trace:
>> [  369.453815]  ? __schedule+0x290/0x870
>> [  369.457523]  schedule+0x32/0x80
>> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
>> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
>> [  369.470084]  ? remove_wait_queue+0x60/0x60
>> [  369.474219]  ? 0xffffffffc0247000
>> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
>> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
>> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
>> [  369.491380]  ? 0xffffffffc0247000
>> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
>> [  369.499071]  do_one_initcall+0x4e/0x1d4
>> [  369.502944]  ? _cond_resched+0x15/0x30
>> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
>> [  369.511386]  ? do_init_module+0x22/0x220
>> [  369.515345]  do_init_module+0x5a/0x220
>> [  369.519444]  load_module+0x21cb/0x2a50
>> [  369.523227]  ? m_show+0x1c0/0x1c0
>> [  369.526571]  ? security_capable+0x3f/0x60
>> [  369.530611]  __do_sys_finit_module+0x94/0xe0
>> [  369.534915]  do_syscall_64+0x5b/0x180
>> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>> [  369.543698] RIP: 0033:0x7f708e6311b9
>> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
>> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
>> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
>> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
>> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
>> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
>>
>> Lianbo Jiang (4):
>>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
>>   Allocate pages for kdump without encryption when SME is enabled
>>   Remap the device table of IOMMU in encrypted manner for kdump
>>   Help to dump the old memory encrypted into vmcore file
>>
>>  arch/x86/include/asm/io.h            |  3 ++
>>  arch/x86/kernel/Makefile             |  1 +
>>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
>>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
>>  fs/proc/vmcore.c                     | 20 ++++++++++----
>>  include/linux/crash_dump.h           | 11 ++++++++
>>  kernel/kexec_core.c                  | 12 ++++++++
>>  8 files changed, 128 insertions(+), 15 deletions(-)
>>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
>>
>> -- 
>> 2.9.5
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-21  3:18     ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  3:18 UTC (permalink / raw)
  To: Baoquan He; +Cc: thomas.lendacky, kexec, linux-kernel, iommu, akpm, dyoung

在 2018年06月21日 09:21, Baoquan He 写道:
> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>> It is convenient to remap the old memory encrypted to the second kernel by
>> calling ioremap_encrypted().
>>
>> When sme enabled on AMD server, we also need to support kdump. Because
>> the memory is encrypted in the first kernel, we will remap the old memory
>> encrypted to the second kernel(crash kernel), and sme is also enabled in
>> the second kernel, otherwise the old memory encrypted can not be decrypted.
>> Because simply changing the value of a C-bit on a page will not
>> automatically encrypt the existing contents of a page, and any data in the
>> page prior to the C-bit modification will become unintelligible. A page of
>> memory that is marked encrypted will be automatically decrypted when read
>> from DRAM and will be automatically encrypted when written to DRAM.
>>
>> For the kdump, it is necessary to distinguish whether the memory is
>> encrypted. Furthermore, we should also know which part of the memory is
>> encrypted or decrypted. We will appropriately remap the memory according
>> to the specific situation in order to tell cpu how to deal with the
>> data(encrypted or decrypted). For example, when sme enabled, if the old
>> memory is encrypted, we will remap the old memory in encrypted way, which
>> will automatically decrypt the old memory encrypted when we read those data
>> from the remapping address.
>>
>>  ----------------------------------------------
>> | first-kernel | second-kernel | kdump support |
>> |      (mem_encrypt=on|off)    |   (yes|no)    |
>> |--------------+---------------+---------------|
>> |     on       |     on        |     yes       |
>> |     off      |     off       |     yes       |
>> |     on       |     off       |     no        |
> 
> 
>> |     off      |     on        |     no        |
> 
> It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
> you remap the old memory with non-sme mode, why did it fail?
> 
Thank you, Baoquan.
For kdump, there are two cases that doesn't need to support:

1. SME on(first kernel), but SME off(second kernel).
Because the old memory is encrypted, we can't decrypt the old memory if SME is off
in the second kernel(in kdump mode).

2. SME off(first kernel), but SME on(second kernel)
Maybe this situation doesn't have significance in actual deployment, furthermore, it
will also increase the complexity of the code. It's just for testing, maybe it is
unnecessary to support it, because the old memory is unencrypted.

Thanks.
Lianbo
> And please run scripts/get_maintainer.pl and add maintainers of
> component which is affected in patch to CC list.
Great! I forgot CC maintainers, thanks for your reminder.

Lianbo
> 
>> |______________|_______________|_______________|
>>
>> This patch is only for SME kdump, it is not support SEV kdump.
>>
>> Test tools:
>> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
>> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
>> Author: Lianbo Jiang <lijiang@redhat.com>
>> Date:   Mon May 14 17:02:40 2018 +0800
>> Note: This patch can only dump vmcore in the case of SME enabled.
>>
>> crash-7.2.1: https://github.com/crash-utility/crash.git
>> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
>> Author: Dave Anderson <anderson@redhat.com>
>> Date:   Fri May 11 15:54:32 2018 -0400
>>
>> Test environment:
>> HP ProLiant DL385Gen10 AMD EPYC 7251
>> 8-Core Processor
>> 32768 MB memory
>> 600 GB disk space
>>
>> Linux 4.17-rc7:
>> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
>> commit b04e217704b7 ("Linux 4.17-rc7")
>> Author: Linus Torvalds <torvalds@linux-foundation.org>
>> Date:   Sun May 27 13:01:47 2018 -0700
>>
>> Reference:
>> AMD64 Architecture Programmer's Manual
>> https://support.amd.com/TechDocs/24593.pdf
>>
>> Some changes:
>> 1. remove the sme_active() check in __ioremap_caller().
>> 2. remove the '#ifdef' stuff throughout this patch.
>> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
>> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
>> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
>> 4. add a new file and modify Makefile.
>> 5. clean compile warning in copy_device_table() and some compile error.
>> 6. split the original patch into four patches, it will be better for
>> review.
>>
>> Some known issues:
>> 1. about SME
>> Upstream kernel doesn't work when we use kexec in the follow command. The
>> system will hang.
>> (This issue doesn't matter with the kdump patch.)
>>
>> Reproduce steps:
>>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
>>  # kexec -e (or reboot)
>>
>> The system will hang:
>> [ 1248.932239] kexec_core: Starting new kernel
>> early console in extract_kernel
>> input_data: 0x000000087e91c3b4
>> input_len: 0x000000000067fcbd
>> output: 0x000000087d400000
>> output_len: 0x0000000001b6fa90
>> kernel_total_size: 0x0000000001a9d000
>> trampoline_32bit: 0x0000000000099000
>>
>> Decompressing Linux...
>> Parsing ELF...        [-here the system will hang]
>>
>> 2. about SEV
>> Upstream kernel(Host OS) doesn't work in host side, some drivers about
>> SEV always go wrong in host side. We can't boot SEV Guest OS to test
>> kdump patch. Maybe it is more reasonable to improve SEV in another
>> patch. When some drivers can work in host side and it can also boot
>> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
>>
>> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
>> [  369.433177]       Not tainted 4.17.0-rc5+ #60
>> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
>> [  369.451323] Call Trace:
>> [  369.453815]  ? __schedule+0x290/0x870
>> [  369.457523]  schedule+0x32/0x80
>> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
>> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
>> [  369.470084]  ? remove_wait_queue+0x60/0x60
>> [  369.474219]  ? 0xffffffffc0247000
>> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
>> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
>> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
>> [  369.491380]  ? 0xffffffffc0247000
>> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
>> [  369.499071]  do_one_initcall+0x4e/0x1d4
>> [  369.502944]  ? _cond_resched+0x15/0x30
>> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
>> [  369.511386]  ? do_init_module+0x22/0x220
>> [  369.515345]  do_init_module+0x5a/0x220
>> [  369.519444]  load_module+0x21cb/0x2a50
>> [  369.523227]  ? m_show+0x1c0/0x1c0
>> [  369.526571]  ? security_capable+0x3f/0x60
>> [  369.530611]  __do_sys_finit_module+0x94/0xe0
>> [  369.534915]  do_syscall_64+0x5b/0x180
>> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>> [  369.543698] RIP: 0033:0x7f708e6311b9
>> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
>> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
>> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
>> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
>> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
>> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
>>
>> Lianbo Jiang (4):
>>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
>>   Allocate pages for kdump without encryption when SME is enabled
>>   Remap the device table of IOMMU in encrypted manner for kdump
>>   Help to dump the old memory encrypted into vmcore file
>>
>>  arch/x86/include/asm/io.h            |  3 ++
>>  arch/x86/kernel/Makefile             |  1 +
>>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
>>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
>>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
>>  fs/proc/vmcore.c                     | 20 ++++++++++----
>>  include/linux/crash_dump.h           | 11 ++++++++
>>  kernel/kexec_core.c                  | 12 ++++++++
>>  8 files changed, 128 insertions(+), 15 deletions(-)
>>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
>>
>> -- 
>> 2.9.5
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
  2018-06-21  1:53     ` Baoquan He
  (?)
@ 2018-06-21  5:06       ` lijiang
  -1 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  5:06 UTC (permalink / raw)
  To: Baoquan He; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec

在 2018年06月21日 09:53, Baoquan He 写道:
> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>> When SME is enabled in the first kernel, we will allocate pages
>> for kdump without encryption in order to be able to boot the
>> second kernel in the same manner as kexec, which helps to keep
>> the same code style.
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>>  kernel/kexec_core.c | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>> index 20fef1a..3c22a9b 100644
>> --- a/kernel/kexec_core.c
>> +++ b/kernel/kexec_core.c
>> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>>  		}
>>  	}
>>  
>> +	if (pages) {
>> +		unsigned int count, i;
>> +
>> +		pages->mapping = NULL;
>> +		set_page_private(pages, order);
>> +		count = 1 << order;
>> +		for (i = 0; i < count; i++)
>> +			SetPageReserved(pages + i);
> 
> I guess you might imitate the kexec case, however kexec get pages from
> buddy. Crash pages are reserved in memblock, these codes might make no sense.
> 
Thanks for your comments.
We have changed the attribute of pages, so the original attribute of pages will be
restored when they free.

Thanks.
Lianbo
>> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
>> +	}
>>  	return pages;
>>  }
>>  
>> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>  			result  = -ENOMEM;
>>  			goto out;
>>  		}
>> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>>  		ptr = kmap(page);
>>  		ptr += maddr & ~PAGE_MASK;
>>  		mchunk = min_t(size_t, mbytes,
>> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>  			result = copy_from_user(ptr, buf, uchunk);
>>  		kexec_flush_icache_page(page);
>>  		kunmap(page);
>> +		arch_kexec_pre_free_pages(page_address(page), 1);
>>  		if (result) {
>>  			result = -EFAULT;
>>  			goto out;
>> -- 
>> 2.9.5
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21  5:06       ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  5:06 UTC (permalink / raw)
  To: Baoquan He
  Cc: thomas.lendacky-5C7GfCeVMHo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

在 2018年06月21日 09:53, Baoquan He 写道:
> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>> When SME is enabled in the first kernel, we will allocate pages
>> for kdump without encryption in order to be able to boot the
>> second kernel in the same manner as kexec, which helps to keep
>> the same code style.
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>>  kernel/kexec_core.c | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>> index 20fef1a..3c22a9b 100644
>> --- a/kernel/kexec_core.c
>> +++ b/kernel/kexec_core.c
>> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>>  		}
>>  	}
>>  
>> +	if (pages) {
>> +		unsigned int count, i;
>> +
>> +		pages->mapping = NULL;
>> +		set_page_private(pages, order);
>> +		count = 1 << order;
>> +		for (i = 0; i < count; i++)
>> +			SetPageReserved(pages + i);
> 
> I guess you might imitate the kexec case, however kexec get pages from
> buddy. Crash pages are reserved in memblock, these codes might make no sense.
> 
Thanks for your comments.
We have changed the attribute of pages, so the original attribute of pages will be
restored when they free.

Thanks.
Lianbo
>> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
>> +	}
>>  	return pages;
>>  }
>>  
>> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>  			result  = -ENOMEM;
>>  			goto out;
>>  		}
>> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>>  		ptr = kmap(page);
>>  		ptr += maddr & ~PAGE_MASK;
>>  		mchunk = min_t(size_t, mbytes,
>> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>  			result = copy_from_user(ptr, buf, uchunk);
>>  		kexec_flush_icache_page(page);
>>  		kunmap(page);
>> +		arch_kexec_pre_free_pages(page_address(page), 1);
>>  		if (result) {
>>  			result = -EFAULT;
>>  			goto out;
>> -- 
>> 2.9.5
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21  5:06       ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  5:06 UTC (permalink / raw)
  To: Baoquan He; +Cc: thomas.lendacky, iommu, dyoung, linux-kernel, kexec

在 2018年06月21日 09:53, Baoquan He 写道:
> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>> When SME is enabled in the first kernel, we will allocate pages
>> for kdump without encryption in order to be able to boot the
>> second kernel in the same manner as kexec, which helps to keep
>> the same code style.
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>>  kernel/kexec_core.c | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>> index 20fef1a..3c22a9b 100644
>> --- a/kernel/kexec_core.c
>> +++ b/kernel/kexec_core.c
>> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>>  		}
>>  	}
>>  
>> +	if (pages) {
>> +		unsigned int count, i;
>> +
>> +		pages->mapping = NULL;
>> +		set_page_private(pages, order);
>> +		count = 1 << order;
>> +		for (i = 0; i < count; i++)
>> +			SetPageReserved(pages + i);
> 
> I guess you might imitate the kexec case, however kexec get pages from
> buddy. Crash pages are reserved in memblock, these codes might make no sense.
> 
Thanks for your comments.
We have changed the attribute of pages, so the original attribute of pages will be
restored when they free.

Thanks.
Lianbo
>> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
>> +	}
>>  	return pages;
>>  }
>>  
>> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>  			result  = -ENOMEM;
>>  			goto out;
>>  		}
>> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>>  		ptr = kmap(page);
>>  		ptr += maddr & ~PAGE_MASK;
>>  		mchunk = min_t(size_t, mbytes,
>> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>  			result = copy_from_user(ptr, buf, uchunk);
>>  		kexec_flush_icache_page(page);
>>  		kunmap(page);
>> +		arch_kexec_pre_free_pages(page_address(page), 1);
>>  		if (result) {
>>  			result = -EFAULT;
>>  			goto out;
>> -- 
>> 2.9.5
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
  2018-06-20 16:42     ` Tom Lendacky
@ 2018-06-21  5:42       ` lijiang
  -1 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  5:42 UTC (permalink / raw)
  To: Tom Lendacky, linux-kernel; +Cc: iommu, kexec, dyoung

在 2018年06月21日 00:42, Tom Lendacky 写道:
> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>> In kdump mode, it will copy the device table of IOMMU from the old
>> device table, which is encrypted when SME is enabled in the first
>> kernel. So we must remap it in encrypted manner in order to be
>> automatically decrypted when we read.
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>> Some changes:
>> 1. add some comments
>> 2. clean compile warning.
>>
>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
>> index 904c575..a20af4c 100644
>> --- a/drivers/iommu/amd_iommu_init.c
>> +++ b/drivers/iommu/amd_iommu_init.c
>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>>  	}
>>  
>>  	old_devtb_phys = entry & PAGE_MASK;
>> +
>> +	/*
>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
>> +	 *  encryption mask to obtain the true physical address in kdump mode.
>> +	 */
>> +	if (mem_encrypt_active() && is_kdump_kernel())
>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
>> +
> 
> You can probably just use "if (is_kdump_kernel())" here, since memory
> encryption is either on in both the first and second kernel or off in
> both the first and second kernel.  At which point __sme_clr() will do
> the proper thing.
> 
> Actually, this needs to be done no matter what.  When doing either the
> ioremap_encrypted() or the memremap(), the physical address should not
> include the encryption bit/mask.
> 
> Thanks,
> Tom
> 
Thanks for your comments. If we don't remove the memory encryption mask, it will
return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.

Lianbo
>>  	if (old_devtb_phys >= 0x100000000ULL) {
>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>>  		return false;
>>  	}
>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
>> +							dev_table_size)
>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>>  	if (!old_devtb)
>>  		return false;
>>  
>>

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  5:42       ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  5:42 UTC (permalink / raw)
  To: Tom Lendacky, linux-kernel; +Cc: dyoung, iommu, kexec

在 2018年06月21日 00:42, Tom Lendacky 写道:
> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>> In kdump mode, it will copy the device table of IOMMU from the old
>> device table, which is encrypted when SME is enabled in the first
>> kernel. So we must remap it in encrypted manner in order to be
>> automatically decrypted when we read.
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>> Some changes:
>> 1. add some comments
>> 2. clean compile warning.
>>
>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
>> index 904c575..a20af4c 100644
>> --- a/drivers/iommu/amd_iommu_init.c
>> +++ b/drivers/iommu/amd_iommu_init.c
>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>>  	}
>>  
>>  	old_devtb_phys = entry & PAGE_MASK;
>> +
>> +	/*
>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
>> +	 *  encryption mask to obtain the true physical address in kdump mode.
>> +	 */
>> +	if (mem_encrypt_active() && is_kdump_kernel())
>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
>> +
> 
> You can probably just use "if (is_kdump_kernel())" here, since memory
> encryption is either on in both the first and second kernel or off in
> both the first and second kernel.  At which point __sme_clr() will do
> the proper thing.
> 
> Actually, this needs to be done no matter what.  When doing either the
> ioremap_encrypted() or the memremap(), the physical address should not
> include the encryption bit/mask.
> 
> Thanks,
> Tom
> 
Thanks for your comments. If we don't remove the memory encryption mask, it will
return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.

Lianbo
>>  	if (old_devtb_phys >= 0x100000000ULL) {
>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>>  		return false;
>>  	}
>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
>> +							dev_table_size)
>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>>  	if (!old_devtb)
>>  		return false;
>>  
>>

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-21  7:30       ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  7:30 UTC (permalink / raw)
  To: lijiang; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec, akpm

On 06/21/18 at 11:18am, lijiang wrote:
> 在 2018年06月21日 09:21, Baoquan He 写道:
> > On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> >> It is convenient to remap the old memory encrypted to the second kernel by
> >> calling ioremap_encrypted().
> >>
> >> When sme enabled on AMD server, we also need to support kdump. Because
> >> the memory is encrypted in the first kernel, we will remap the old memory
> >> encrypted to the second kernel(crash kernel), and sme is also enabled in
> >> the second kernel, otherwise the old memory encrypted can not be decrypted.
> >> Because simply changing the value of a C-bit on a page will not
> >> automatically encrypt the existing contents of a page, and any data in the
> >> page prior to the C-bit modification will become unintelligible. A page of
> >> memory that is marked encrypted will be automatically decrypted when read
> >> from DRAM and will be automatically encrypted when written to DRAM.
> >>
> >> For the kdump, it is necessary to distinguish whether the memory is
> >> encrypted. Furthermore, we should also know which part of the memory is
> >> encrypted or decrypted. We will appropriately remap the memory according
> >> to the specific situation in order to tell cpu how to deal with the
> >> data(encrypted or decrypted). For example, when sme enabled, if the old
> >> memory is encrypted, we will remap the old memory in encrypted way, which
> >> will automatically decrypt the old memory encrypted when we read those data
> >> from the remapping address.
> >>
> >>  ----------------------------------------------
> >> | first-kernel | second-kernel | kdump support |
> >> |      (mem_encrypt=on|off)    |   (yes|no)    |
> >> |--------------+---------------+---------------|
> >> |     on       |     on        |     yes       |
> >> |     off      |     off       |     yes       |
> >> |     on       |     off       |     no        |
> > 
> > 
> >> |     off      |     on        |     no        |
> > 
> > It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
> > you remap the old memory with non-sme mode, why did it fail?
> > 
> Thank you, Baoquan.
> For kdump, there are two cases that doesn't need to support:
> 
> 1. SME on(first kernel), but SME off(second kernel).
> Because the old memory is encrypted, we can't decrypt the old memory if SME is off
> in the second kernel(in kdump mode).
> 
> 2. SME off(first kernel), but SME on(second kernel)
> Maybe this situation doesn't have significance in actual deployment, furthermore, it
> will also increase the complexity of the code. It's just for testing, maybe it is
> unnecessary to support it, because the old memory is unencrypted.

Hmm, sorry, I don't get why it is unnecessary because the old memory is
unencrypted. We developers should cover all cases unless a certain case
is no way to fix, or fixing it is not cost-effective. Otherwise there's
no execuse for us to not fix. When QE try their best to cover all test
cases, they don't consider its significance because even corner case
need be swept out, that is their job. There isn't a rule for developers
to decide if it's significant.

Or could you point out what complexity it will bring to defend your
point?

Thanks
Baoquan

> > And please run scripts/get_maintainer.pl and add maintainers of
> > component which is affected in patch to CC list.
> Great! I forgot CC maintainers, thanks for your reminder.
> 
> Lianbo
> > 
> >> |______________|_______________|_______________|
> >>
> >> This patch is only for SME kdump, it is not support SEV kdump.
> >>
> >> Test tools:
> >> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
> >> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
> >> Author: Lianbo Jiang <lijiang@redhat.com>
> >> Date:   Mon May 14 17:02:40 2018 +0800
> >> Note: This patch can only dump vmcore in the case of SME enabled.
> >>
> >> crash-7.2.1: https://github.com/crash-utility/crash.git
> >> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
> >> Author: Dave Anderson <anderson@redhat.com>
> >> Date:   Fri May 11 15:54:32 2018 -0400
> >>
> >> Test environment:
> >> HP ProLiant DL385Gen10 AMD EPYC 7251
> >> 8-Core Processor
> >> 32768 MB memory
> >> 600 GB disk space
> >>
> >> Linux 4.17-rc7:
> >> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> >> commit b04e217704b7 ("Linux 4.17-rc7")
> >> Author: Linus Torvalds <torvalds@linux-foundation.org>
> >> Date:   Sun May 27 13:01:47 2018 -0700
> >>
> >> Reference:
> >> AMD64 Architecture Programmer's Manual
> >> https://support.amd.com/TechDocs/24593.pdf
> >>
> >> Some changes:
> >> 1. remove the sme_active() check in __ioremap_caller().
> >> 2. remove the '#ifdef' stuff throughout this patch.
> >> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
> >> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
> >> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
> >> 4. add a new file and modify Makefile.
> >> 5. clean compile warning in copy_device_table() and some compile error.
> >> 6. split the original patch into four patches, it will be better for
> >> review.
> >>
> >> Some known issues:
> >> 1. about SME
> >> Upstream kernel doesn't work when we use kexec in the follow command. The
> >> system will hang.
> >> (This issue doesn't matter with the kdump patch.)
> >>
> >> Reproduce steps:
> >>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
> >>  # kexec -e (or reboot)
> >>
> >> The system will hang:
> >> [ 1248.932239] kexec_core: Starting new kernel
> >> early console in extract_kernel
> >> input_data: 0x000000087e91c3b4
> >> input_len: 0x000000000067fcbd
> >> output: 0x000000087d400000
> >> output_len: 0x0000000001b6fa90
> >> kernel_total_size: 0x0000000001a9d000
> >> trampoline_32bit: 0x0000000000099000
> >>
> >> Decompressing Linux...
> >> Parsing ELF...        [-here the system will hang]
> >>
> >> 2. about SEV
> >> Upstream kernel(Host OS) doesn't work in host side, some drivers about
> >> SEV always go wrong in host side. We can't boot SEV Guest OS to test
> >> kdump patch. Maybe it is more reasonable to improve SEV in another
> >> patch. When some drivers can work in host side and it can also boot
> >> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
> >>
> >> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
> >> [  369.433177]       Not tainted 4.17.0-rc5+ #60
> >> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> >> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
> >> [  369.451323] Call Trace:
> >> [  369.453815]  ? __schedule+0x290/0x870
> >> [  369.457523]  schedule+0x32/0x80
> >> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
> >> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
> >> [  369.470084]  ? remove_wait_queue+0x60/0x60
> >> [  369.474219]  ? 0xffffffffc0247000
> >> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
> >> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
> >> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
> >> [  369.491380]  ? 0xffffffffc0247000
> >> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
> >> [  369.499071]  do_one_initcall+0x4e/0x1d4
> >> [  369.502944]  ? _cond_resched+0x15/0x30
> >> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
> >> [  369.511386]  ? do_init_module+0x22/0x220
> >> [  369.515345]  do_init_module+0x5a/0x220
> >> [  369.519444]  load_module+0x21cb/0x2a50
> >> [  369.523227]  ? m_show+0x1c0/0x1c0
> >> [  369.526571]  ? security_capable+0x3f/0x60
> >> [  369.530611]  __do_sys_finit_module+0x94/0xe0
> >> [  369.534915]  do_syscall_64+0x5b/0x180
> >> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> >> [  369.543698] RIP: 0033:0x7f708e6311b9
> >> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
> >> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
> >> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
> >> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
> >> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
> >> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
> >>
> >> Lianbo Jiang (4):
> >>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
> >>   Allocate pages for kdump without encryption when SME is enabled
> >>   Remap the device table of IOMMU in encrypted manner for kdump
> >>   Help to dump the old memory encrypted into vmcore file
> >>
> >>  arch/x86/include/asm/io.h            |  3 ++
> >>  arch/x86/kernel/Makefile             |  1 +
> >>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
> >>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
> >>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
> >>  fs/proc/vmcore.c                     | 20 ++++++++++----
> >>  include/linux/crash_dump.h           | 11 ++++++++
> >>  kernel/kexec_core.c                  | 12 ++++++++
> >>  8 files changed, 128 insertions(+), 15 deletions(-)
> >>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> >>
> >> -- 
> >> 2.9.5
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-21  7:30       ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  7:30 UTC (permalink / raw)
  To: lijiang
  Cc: thomas.lendacky-5C7GfCeVMHo,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA

On 06/21/18 at 11:18am, lijiang wrote:
> 在 2018年06月21日 09:21, Baoquan He 写道:
> > On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> >> It is convenient to remap the old memory encrypted to the second kernel by
> >> calling ioremap_encrypted().
> >>
> >> When sme enabled on AMD server, we also need to support kdump. Because
> >> the memory is encrypted in the first kernel, we will remap the old memory
> >> encrypted to the second kernel(crash kernel), and sme is also enabled in
> >> the second kernel, otherwise the old memory encrypted can not be decrypted.
> >> Because simply changing the value of a C-bit on a page will not
> >> automatically encrypt the existing contents of a page, and any data in the
> >> page prior to the C-bit modification will become unintelligible. A page of
> >> memory that is marked encrypted will be automatically decrypted when read
> >> from DRAM and will be automatically encrypted when written to DRAM.
> >>
> >> For the kdump, it is necessary to distinguish whether the memory is
> >> encrypted. Furthermore, we should also know which part of the memory is
> >> encrypted or decrypted. We will appropriately remap the memory according
> >> to the specific situation in order to tell cpu how to deal with the
> >> data(encrypted or decrypted). For example, when sme enabled, if the old
> >> memory is encrypted, we will remap the old memory in encrypted way, which
> >> will automatically decrypt the old memory encrypted when we read those data
> >> from the remapping address.
> >>
> >>  ----------------------------------------------
> >> | first-kernel | second-kernel | kdump support |
> >> |      (mem_encrypt=on|off)    |   (yes|no)    |
> >> |--------------+---------------+---------------|
> >> |     on       |     on        |     yes       |
> >> |     off      |     off       |     yes       |
> >> |     on       |     off       |     no        |
> > 
> > 
> >> |     off      |     on        |     no        |
> > 
> > It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
> > you remap the old memory with non-sme mode, why did it fail?
> > 
> Thank you, Baoquan.
> For kdump, there are two cases that doesn't need to support:
> 
> 1. SME on(first kernel), but SME off(second kernel).
> Because the old memory is encrypted, we can't decrypt the old memory if SME is off
> in the second kernel(in kdump mode).
> 
> 2. SME off(first kernel), but SME on(second kernel)
> Maybe this situation doesn't have significance in actual deployment, furthermore, it
> will also increase the complexity of the code. It's just for testing, maybe it is
> unnecessary to support it, because the old memory is unencrypted.

Hmm, sorry, I don't get why it is unnecessary because the old memory is
unencrypted. We developers should cover all cases unless a certain case
is no way to fix, or fixing it is not cost-effective. Otherwise there's
no execuse for us to not fix. When QE try their best to cover all test
cases, they don't consider its significance because even corner case
need be swept out, that is their job. There isn't a rule for developers
to decide if it's significant.

Or could you point out what complexity it will bring to defend your
point?

Thanks
Baoquan

> > And please run scripts/get_maintainer.pl and add maintainers of
> > component which is affected in patch to CC list.
> Great! I forgot CC maintainers, thanks for your reminder.
> 
> Lianbo
> > 
> >> |______________|_______________|_______________|
> >>
> >> This patch is only for SME kdump, it is not support SEV kdump.
> >>
> >> Test tools:
> >> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
> >> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
> >> Author: Lianbo Jiang <lijiang@redhat.com>
> >> Date:   Mon May 14 17:02:40 2018 +0800
> >> Note: This patch can only dump vmcore in the case of SME enabled.
> >>
> >> crash-7.2.1: https://github.com/crash-utility/crash.git
> >> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
> >> Author: Dave Anderson <anderson@redhat.com>
> >> Date:   Fri May 11 15:54:32 2018 -0400
> >>
> >> Test environment:
> >> HP ProLiant DL385Gen10 AMD EPYC 7251
> >> 8-Core Processor
> >> 32768 MB memory
> >> 600 GB disk space
> >>
> >> Linux 4.17-rc7:
> >> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> >> commit b04e217704b7 ("Linux 4.17-rc7")
> >> Author: Linus Torvalds <torvalds@linux-foundation.org>
> >> Date:   Sun May 27 13:01:47 2018 -0700
> >>
> >> Reference:
> >> AMD64 Architecture Programmer's Manual
> >> https://support.amd.com/TechDocs/24593.pdf
> >>
> >> Some changes:
> >> 1. remove the sme_active() check in __ioremap_caller().
> >> 2. remove the '#ifdef' stuff throughout this patch.
> >> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
> >> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
> >> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
> >> 4. add a new file and modify Makefile.
> >> 5. clean compile warning in copy_device_table() and some compile error.
> >> 6. split the original patch into four patches, it will be better for
> >> review.
> >>
> >> Some known issues:
> >> 1. about SME
> >> Upstream kernel doesn't work when we use kexec in the follow command. The
> >> system will hang.
> >> (This issue doesn't matter with the kdump patch.)
> >>
> >> Reproduce steps:
> >>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
> >>  # kexec -e (or reboot)
> >>
> >> The system will hang:
> >> [ 1248.932239] kexec_core: Starting new kernel
> >> early console in extract_kernel
> >> input_data: 0x000000087e91c3b4
> >> input_len: 0x000000000067fcbd
> >> output: 0x000000087d400000
> >> output_len: 0x0000000001b6fa90
> >> kernel_total_size: 0x0000000001a9d000
> >> trampoline_32bit: 0x0000000000099000
> >>
> >> Decompressing Linux...
> >> Parsing ELF...        [-here the system will hang]
> >>
> >> 2. about SEV
> >> Upstream kernel(Host OS) doesn't work in host side, some drivers about
> >> SEV always go wrong in host side. We can't boot SEV Guest OS to test
> >> kdump patch. Maybe it is more reasonable to improve SEV in another
> >> patch. When some drivers can work in host side and it can also boot
> >> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
> >>
> >> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
> >> [  369.433177]       Not tainted 4.17.0-rc5+ #60
> >> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> >> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
> >> [  369.451323] Call Trace:
> >> [  369.453815]  ? __schedule+0x290/0x870
> >> [  369.457523]  schedule+0x32/0x80
> >> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
> >> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
> >> [  369.470084]  ? remove_wait_queue+0x60/0x60
> >> [  369.474219]  ? 0xffffffffc0247000
> >> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
> >> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
> >> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
> >> [  369.491380]  ? 0xffffffffc0247000
> >> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
> >> [  369.499071]  do_one_initcall+0x4e/0x1d4
> >> [  369.502944]  ? _cond_resched+0x15/0x30
> >> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
> >> [  369.511386]  ? do_init_module+0x22/0x220
> >> [  369.515345]  do_init_module+0x5a/0x220
> >> [  369.519444]  load_module+0x21cb/0x2a50
> >> [  369.523227]  ? m_show+0x1c0/0x1c0
> >> [  369.526571]  ? security_capable+0x3f/0x60
> >> [  369.530611]  __do_sys_finit_module+0x94/0xe0
> >> [  369.534915]  do_syscall_64+0x5b/0x180
> >> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> >> [  369.543698] RIP: 0033:0x7f708e6311b9
> >> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
> >> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
> >> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
> >> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
> >> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
> >> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
> >>
> >> Lianbo Jiang (4):
> >>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
> >>   Allocate pages for kdump without encryption when SME is enabled
> >>   Remap the device table of IOMMU in encrypted manner for kdump
> >>   Help to dump the old memory encrypted into vmcore file
> >>
> >>  arch/x86/include/asm/io.h            |  3 ++
> >>  arch/x86/kernel/Makefile             |  1 +
> >>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
> >>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
> >>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
> >>  fs/proc/vmcore.c                     | 20 ++++++++++----
> >>  include/linux/crash_dump.h           | 11 ++++++++
> >>  kernel/kexec_core.c                  | 12 ++++++++
> >>  8 files changed, 128 insertions(+), 15 deletions(-)
> >>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> >>
> >> -- 
> >> 2.9.5
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME)
@ 2018-06-21  7:30       ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  7:30 UTC (permalink / raw)
  To: lijiang; +Cc: thomas.lendacky, kexec, linux-kernel, iommu, akpm, dyoung

On 06/21/18 at 11:18am, lijiang wrote:
> 在 2018年06月21日 09:21, Baoquan He 写道:
> > On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> >> It is convenient to remap the old memory encrypted to the second kernel by
> >> calling ioremap_encrypted().
> >>
> >> When sme enabled on AMD server, we also need to support kdump. Because
> >> the memory is encrypted in the first kernel, we will remap the old memory
> >> encrypted to the second kernel(crash kernel), and sme is also enabled in
> >> the second kernel, otherwise the old memory encrypted can not be decrypted.
> >> Because simply changing the value of a C-bit on a page will not
> >> automatically encrypt the existing contents of a page, and any data in the
> >> page prior to the C-bit modification will become unintelligible. A page of
> >> memory that is marked encrypted will be automatically decrypted when read
> >> from DRAM and will be automatically encrypted when written to DRAM.
> >>
> >> For the kdump, it is necessary to distinguish whether the memory is
> >> encrypted. Furthermore, we should also know which part of the memory is
> >> encrypted or decrypted. We will appropriately remap the memory according
> >> to the specific situation in order to tell cpu how to deal with the
> >> data(encrypted or decrypted). For example, when sme enabled, if the old
> >> memory is encrypted, we will remap the old memory in encrypted way, which
> >> will automatically decrypt the old memory encrypted when we read those data
> >> from the remapping address.
> >>
> >>  ----------------------------------------------
> >> | first-kernel | second-kernel | kdump support |
> >> |      (mem_encrypt=on|off)    |   (yes|no)    |
> >> |--------------+---------------+---------------|
> >> |     on       |     on        |     yes       |
> >> |     off      |     off       |     yes       |
> >> |     on       |     off       |     no        |
> > 
> > 
> >> |     off      |     on        |     no        |
> > 
> > It's not clear to me here. If 1st kernel sme is off, in 2nd kernel, when
> > you remap the old memory with non-sme mode, why did it fail?
> > 
> Thank you, Baoquan.
> For kdump, there are two cases that doesn't need to support:
> 
> 1. SME on(first kernel), but SME off(second kernel).
> Because the old memory is encrypted, we can't decrypt the old memory if SME is off
> in the second kernel(in kdump mode).
> 
> 2. SME off(first kernel), but SME on(second kernel)
> Maybe this situation doesn't have significance in actual deployment, furthermore, it
> will also increase the complexity of the code. It's just for testing, maybe it is
> unnecessary to support it, because the old memory is unencrypted.

Hmm, sorry, I don't get why it is unnecessary because the old memory is
unencrypted. We developers should cover all cases unless a certain case
is no way to fix, or fixing it is not cost-effective. Otherwise there's
no execuse for us to not fix. When QE try their best to cover all test
cases, they don't consider its significance because even corner case
need be swept out, that is their job. There isn't a rule for developers
to decide if it's significant.

Or could you point out what complexity it will bring to defend your
point?

Thanks
Baoquan

> > And please run scripts/get_maintainer.pl and add maintainers of
> > component which is affected in patch to CC list.
> Great! I forgot CC maintainers, thanks for your reminder.
> 
> Lianbo
> > 
> >> |______________|_______________|_______________|
> >>
> >> This patch is only for SME kdump, it is not support SEV kdump.
> >>
> >> Test tools:
> >> makedumpfile[v1.6.3]: https://github.com/LianboJ/makedumpfile
> >> commit e1de103eca8f (A draft for kdump vmcore about AMD SME)
> >> Author: Lianbo Jiang <lijiang@redhat.com>
> >> Date:   Mon May 14 17:02:40 2018 +0800
> >> Note: This patch can only dump vmcore in the case of SME enabled.
> >>
> >> crash-7.2.1: https://github.com/crash-utility/crash.git
> >> commit 1e1bd9c4c1be (Fix for the "bpf" command display on Linux 4.17-rc1)
> >> Author: Dave Anderson <anderson@redhat.com>
> >> Date:   Fri May 11 15:54:32 2018 -0400
> >>
> >> Test environment:
> >> HP ProLiant DL385Gen10 AMD EPYC 7251
> >> 8-Core Processor
> >> 32768 MB memory
> >> 600 GB disk space
> >>
> >> Linux 4.17-rc7:
> >> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> >> commit b04e217704b7 ("Linux 4.17-rc7")
> >> Author: Linus Torvalds <torvalds@linux-foundation.org>
> >> Date:   Sun May 27 13:01:47 2018 -0700
> >>
> >> Reference:
> >> AMD64 Architecture Programmer's Manual
> >> https://support.amd.com/TechDocs/24593.pdf
> >>
> >> Some changes:
> >> 1. remove the sme_active() check in __ioremap_caller().
> >> 2. remove the '#ifdef' stuff throughout this patch.
> >> 3. put some logic into the early_memremap_pgprot_adjust() and clean the
> >> previous unnecessary changes, for example: arch/x86/include/asm/dmi.h,
> >> arch/x86/kernel/acpi/boot.c, drivers/acpi/tables.c.
> >> 4. add a new file and modify Makefile.
> >> 5. clean compile warning in copy_device_table() and some compile error.
> >> 6. split the original patch into four patches, it will be better for
> >> review.
> >>
> >> Some known issues:
> >> 1. about SME
> >> Upstream kernel doesn't work when we use kexec in the follow command. The
> >> system will hang.
> >> (This issue doesn't matter with the kdump patch.)
> >>
> >> Reproduce steps:
> >>  # kexec -l /boot/vmlinuz-4.17.0-rc7+ --initrd=/boot/initramfs-4.17.0-rc7+.img --command-line="root=/dev/mapper/rhel_hp--dl385g10--03-root ro mem_encrypt=on rd.lvm.lv=rhel_hp-dl385g10-03/root rd.lvm.lv=rhel_hp-dl385g10-03/swap console=ttyS0,115200n81 LANG=en_US.UTF-8 earlyprintk=serial debug nokaslr"
> >>  # kexec -e (or reboot)
> >>
> >> The system will hang:
> >> [ 1248.932239] kexec_core: Starting new kernel
> >> early console in extract_kernel
> >> input_data: 0x000000087e91c3b4
> >> input_len: 0x000000000067fcbd
> >> output: 0x000000087d400000
> >> output_len: 0x0000000001b6fa90
> >> kernel_total_size: 0x0000000001a9d000
> >> trampoline_32bit: 0x0000000000099000
> >>
> >> Decompressing Linux...
> >> Parsing ELF...        [-here the system will hang]
> >>
> >> 2. about SEV
> >> Upstream kernel(Host OS) doesn't work in host side, some drivers about
> >> SEV always go wrong in host side. We can't boot SEV Guest OS to test
> >> kdump patch. Maybe it is more reasonable to improve SEV in another
> >> patch. When some drivers can work in host side and it can also boot
> >> Virtual Machine(SEV Guest OS), it will be suitable to fix SEV for kdump.
> >>
> >> [  369.426131] INFO: task systemd-udevd:865 blocked for more than 120 seconds.
> >> [  369.433177]       Not tainted 4.17.0-rc5+ #60
> >> [  369.437585] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> >> [  369.445783] systemd-udevd   D    0   865    813 0x80000004
> >> [  369.451323] Call Trace:
> >> [  369.453815]  ? __schedule+0x290/0x870
> >> [  369.457523]  schedule+0x32/0x80
> >> [  369.460714]  __sev_do_cmd_locked+0x1f6/0x2a0 [ccp]
> >> [  369.465556]  ? cleanup_uevent_env+0x10/0x10
> >> [  369.470084]  ? remove_wait_queue+0x60/0x60
> >> [  369.474219]  ? 0xffffffffc0247000
> >> [  369.477572]  __sev_platform_init_locked+0x2b/0x70 [ccp]
> >> [  369.482843]  sev_platform_init+0x1d/0x30 [ccp]
> >> [  369.487333]  psp_pci_init+0x40/0xe0 [ccp]
> >> [  369.491380]  ? 0xffffffffc0247000
> >> [  369.494936]  sp_mod_init+0x18/0x1000 [ccp]
> >> [  369.499071]  do_one_initcall+0x4e/0x1d4
> >> [  369.502944]  ? _cond_resched+0x15/0x30
> >> [  369.506728]  ? kmem_cache_alloc_trace+0xae/0x1d0
> >> [  369.511386]  ? do_init_module+0x22/0x220
> >> [  369.515345]  do_init_module+0x5a/0x220
> >> [  369.519444]  load_module+0x21cb/0x2a50
> >> [  369.523227]  ? m_show+0x1c0/0x1c0
> >> [  369.526571]  ? security_capable+0x3f/0x60
> >> [  369.530611]  __do_sys_finit_module+0x94/0xe0
> >> [  369.534915]  do_syscall_64+0x5b/0x180
> >> [  369.538607]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> >> [  369.543698] RIP: 0033:0x7f708e6311b9
> >> [  369.547536] RSP: 002b:00007ffff9d32aa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
> >> [  369.555162] RAX: ffffffffffffffda RBX: 000055602a04c2d0 RCX: 00007f708e6311b9
> >> [  369.562346] RDX: 0000000000000000 RSI: 00007f708ef52039 RDI: 0000000000000008
> >> [  369.569801] RBP: 00007f708ef52039 R08: 0000000000000000 R09: 000055602a048b20
> >> [  369.576988] R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000000
> >> [  369.584177] R13: 000055602a075260 R14: 0000000000020000 R15: 0000000000000000
> >>
> >> Lianbo Jiang (4):
> >>   Add a function(ioremap_encrypted) for kdump when AMD sme enabled
> >>   Allocate pages for kdump without encryption when SME is enabled
> >>   Remap the device table of IOMMU in encrypted manner for kdump
> >>   Help to dump the old memory encrypted into vmcore file
> >>
> >>  arch/x86/include/asm/io.h            |  3 ++
> >>  arch/x86/kernel/Makefile             |  1 +
> >>  arch/x86/kernel/crash_dump_encrypt.c | 53 ++++++++++++++++++++++++++++++++++++
> >>  arch/x86/mm/ioremap.c                | 28 +++++++++++++------
> >>  drivers/iommu/amd_iommu_init.c       | 15 +++++++++-
> >>  fs/proc/vmcore.c                     | 20 ++++++++++----
> >>  include/linux/crash_dump.h           | 11 ++++++++
> >>  kernel/kexec_core.c                  | 12 ++++++++
> >>  8 files changed, 128 insertions(+), 15 deletions(-)
> >>  create mode 100644 arch/x86/kernel/crash_dump_encrypt.c
> >>
> >> -- 
> >> 2.9.5
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  8:39         ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  8:39 UTC (permalink / raw)
  To: lijiang; +Cc: Tom Lendacky, linux-kernel, dyoung, iommu, kexec

On 06/21/18 at 01:42pm, lijiang wrote:
> 在 2018年06月21日 00:42, Tom Lendacky 写道:
> > On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> >> In kdump mode, it will copy the device table of IOMMU from the old
> >> device table, which is encrypted when SME is enabled in the first
> >> kernel. So we must remap it in encrypted manner in order to be
> >> automatically decrypted when we read.
> >>
> >> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >> ---
> >> Some changes:
> >> 1. add some comments
> >> 2. clean compile warning.
> >>
> >>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
> >>  1 file changed, 14 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> >> index 904c575..a20af4c 100644
> >> --- a/drivers/iommu/amd_iommu_init.c
> >> +++ b/drivers/iommu/amd_iommu_init.c
> >> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
> >>  	}
> >>  
> >>  	old_devtb_phys = entry & PAGE_MASK;
> >> +
> >> +	/*
> >> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> >> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> >> +	 *  encryption mask to obtain the true physical address in kdump mode.
> >> +	 */
> >> +	if (mem_encrypt_active() && is_kdump_kernel())
> >> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> >> +
> > 
> > You can probably just use "if (is_kdump_kernel())" here, since memory
> > encryption is either on in both the first and second kernel or off in
> > both the first and second kernel.  At which point __sme_clr() will do
> > the proper thing.
> > 
> > Actually, this needs to be done no matter what.  When doing either the
> > ioremap_encrypted() or the memremap(), the physical address should not
> > include the encryption bit/mask.
> > 
> > Thanks,
> > Tom
> > 
> Thanks for your comments. If we don't remove the memory encryption mask, it will
> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.

Lianbo, you may not get what Tom suggested. Tom means no matter what it
is, encrypted or not in 1st kernel, we need get pure physicall address,
and using below code is always right for both cases.

	if (is_kdump_kernel())
		old_devtb_phys = __sme_clr(old_devtb_phys);

And this is simpler. You even can add one line of code comment to say
like "Physical address w/o encryption mask is needed here."
> 
> Lianbo
> >>  	if (old_devtb_phys >= 0x100000000ULL) {
> >>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
> >>  		return false;
> >>  	}
> >> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> >> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> >> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> >> +							dev_table_size)
> >> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
> >>  	if (!old_devtb)
> >>  		return false;
> >>  
> >>
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  8:39         ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  8:39 UTC (permalink / raw)
  To: lijiang
  Cc: Tom Lendacky, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/21/18 at 01:42pm, lijiang wrote:
> 在 2018年06月21日 00:42, Tom Lendacky 写道:
> > On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> >> In kdump mode, it will copy the device table of IOMMU from the old
> >> device table, which is encrypted when SME is enabled in the first
> >> kernel. So we must remap it in encrypted manner in order to be
> >> automatically decrypted when we read.
> >>
> >> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >> ---
> >> Some changes:
> >> 1. add some comments
> >> 2. clean compile warning.
> >>
> >>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
> >>  1 file changed, 14 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> >> index 904c575..a20af4c 100644
> >> --- a/drivers/iommu/amd_iommu_init.c
> >> +++ b/drivers/iommu/amd_iommu_init.c
> >> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
> >>  	}
> >>  
> >>  	old_devtb_phys = entry & PAGE_MASK;
> >> +
> >> +	/*
> >> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> >> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> >> +	 *  encryption mask to obtain the true physical address in kdump mode.
> >> +	 */
> >> +	if (mem_encrypt_active() && is_kdump_kernel())
> >> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> >> +
> > 
> > You can probably just use "if (is_kdump_kernel())" here, since memory
> > encryption is either on in both the first and second kernel or off in
> > both the first and second kernel.  At which point __sme_clr() will do
> > the proper thing.
> > 
> > Actually, this needs to be done no matter what.  When doing either the
> > ioremap_encrypted() or the memremap(), the physical address should not
> > include the encryption bit/mask.
> > 
> > Thanks,
> > Tom
> > 
> Thanks for your comments. If we don't remove the memory encryption mask, it will
> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.

Lianbo, you may not get what Tom suggested. Tom means no matter what it
is, encrypted or not in 1st kernel, we need get pure physicall address,
and using below code is always right for both cases.

	if (is_kdump_kernel())
		old_devtb_phys = __sme_clr(old_devtb_phys);

And this is simpler. You even can add one line of code comment to say
like "Physical address w/o encryption mask is needed here."
> 
> Lianbo
> >>  	if (old_devtb_phys >= 0x100000000ULL) {
> >>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
> >>  		return false;
> >>  	}
> >> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> >> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> >> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> >> +							dev_table_size)
> >> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
> >>  	if (!old_devtb)
> >>  		return false;
> >>  
> >>
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  8:39         ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21  8:39 UTC (permalink / raw)
  To: lijiang; +Cc: Tom Lendacky, iommu, dyoung, linux-kernel, kexec

On 06/21/18 at 01:42pm, lijiang wrote:
> 在 2018年06月21日 00:42, Tom Lendacky 写道:
> > On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> >> In kdump mode, it will copy the device table of IOMMU from the old
> >> device table, which is encrypted when SME is enabled in the first
> >> kernel. So we must remap it in encrypted manner in order to be
> >> automatically decrypted when we read.
> >>
> >> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >> ---
> >> Some changes:
> >> 1. add some comments
> >> 2. clean compile warning.
> >>
> >>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
> >>  1 file changed, 14 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> >> index 904c575..a20af4c 100644
> >> --- a/drivers/iommu/amd_iommu_init.c
> >> +++ b/drivers/iommu/amd_iommu_init.c
> >> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
> >>  	}
> >>  
> >>  	old_devtb_phys = entry & PAGE_MASK;
> >> +
> >> +	/*
> >> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> >> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> >> +	 *  encryption mask to obtain the true physical address in kdump mode.
> >> +	 */
> >> +	if (mem_encrypt_active() && is_kdump_kernel())
> >> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> >> +
> > 
> > You can probably just use "if (is_kdump_kernel())" here, since memory
> > encryption is either on in both the first and second kernel or off in
> > both the first and second kernel.  At which point __sme_clr() will do
> > the proper thing.
> > 
> > Actually, this needs to be done no matter what.  When doing either the
> > ioremap_encrypted() or the memremap(), the physical address should not
> > include the encryption bit/mask.
> > 
> > Thanks,
> > Tom
> > 
> Thanks for your comments. If we don't remove the memory encryption mask, it will
> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.

Lianbo, you may not get what Tom suggested. Tom means no matter what it
is, encrypted or not in 1st kernel, we need get pure physicall address,
and using below code is always right for both cases.

	if (is_kdump_kernel())
		old_devtb_phys = __sme_clr(old_devtb_phys);

And this is simpler. You even can add one line of code comment to say
like "Physical address w/o encryption mask is needed here."
> 
> Lianbo
> >>  	if (old_devtb_phys >= 0x100000000ULL) {
> >>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
> >>  		return false;
> >>  	}
> >> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> >> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> >> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> >> +							dev_table_size)
> >> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
> >>  	if (!old_devtb)
> >>  		return false;
> >>  
> >>
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled
@ 2018-06-21  9:13       ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  9:13 UTC (permalink / raw)
  To: Tom Lendacky, linux-kernel; +Cc: iommu, kexec, dyoung

在 2018年06月21日 00:00, Tom Lendacky 写道:
> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>> It is convenient to remap the old memory encrypted to the second
>> kernel by calling ioremap_encrypted().
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>> Some changes:
>> 1. remove the sme_active() check in __ioremap_caller().
>> 2. put some logic into the early_memremap_pgprot_adjust() for
>> early memremap.
>>
>>  arch/x86/include/asm/io.h |  3 +++
>>  arch/x86/mm/ioremap.c     | 28 ++++++++++++++++++++--------
>>  2 files changed, 23 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
>> index f6e5b93..989d60b 100644
>> --- a/arch/x86/include/asm/io.h
>> +++ b/arch/x86/include/asm/io.h
>> @@ -192,6 +192,9 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
>>  #define ioremap_cache ioremap_cache
>>  extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
>>  #define ioremap_prot ioremap_prot
>> +extern void __iomem *ioremap_encrypted(resource_size_t phys_addr,
>> +					unsigned long size);
>> +#define ioremap_encrypted ioremap_encrypted
>>  
>>  /**
>>   * ioremap     -   map bus memory into CPU space
>> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
>> index c63a545..e365fc4 100644
>> --- a/arch/x86/mm/ioremap.c
>> +++ b/arch/x86/mm/ioremap.c
>> @@ -24,6 +24,7 @@
>>  #include <asm/pgalloc.h>
>>  #include <asm/pat.h>
>>  #include <asm/setup.h>
>> +#include <linux/crash_dump.h>
>>  
>>  #include "physaddr.h"
>>  
>> @@ -131,7 +132,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
>>   * caller shouldn't need to know that small detail.
>>   */
>>  static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>> -		unsigned long size, enum page_cache_mode pcm, void *caller)
>> +		unsigned long size, enum page_cache_mode pcm,
>> +		void *caller, bool encrypted)
>>  {
>>  	unsigned long offset, vaddr;
>>  	resource_size_t last_addr;
>> @@ -199,7 +201,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>>  	 * resulting mapping.
>>  	 */
>>  	prot = PAGE_KERNEL_IO;
>> -	if (sev_active() && mem_flags.desc_other)
>> +	if ((sev_active() && mem_flags.desc_other) || encrypted)
>>  		prot = pgprot_encrypted(prot);
>>  
>>  	switch (pcm) {
>> @@ -291,7 +293,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
>>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
>>  
>>  	return __ioremap_caller(phys_addr, size, pcm,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_nocache);
>>  
>> @@ -324,7 +326,7 @@ void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
>>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
>>  
>>  	return __ioremap_caller(phys_addr, size, pcm,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL_GPL(ioremap_uc);
>>  
>> @@ -341,7 +343,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
>>  void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
>> -					__builtin_return_address(0));
>> +					__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_wc);
>>  
>> @@ -358,14 +360,21 @@ EXPORT_SYMBOL(ioremap_wc);
>>  void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
>> -					__builtin_return_address(0));
>> +					__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_wt);
>>  
>> +void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
>> +{
>> +	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
>> +				__builtin_return_address(0), true);
>> +}
>> +EXPORT_SYMBOL(ioremap_encrypted);
>> +
>>  void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_cache);
>>  
>> @@ -374,7 +383,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
>>  {
>>  	return __ioremap_caller(phys_addr, size,
>>  				pgprot2cachemode(__pgprot(prot_val)),
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_prot);
>>  
>> @@ -688,6 +697,9 @@ pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
>>  	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
>>  		encrypted_prot = false;
>>  
>> +	if (sme_active() && is_kdump_kernel())
>> +		encrypted_prot = false;
>> +
> 
> This change doesn't seem to go with the patch description.  Maybe it
> should be a separate patch?  Or provide more detail in the description
> for this change.
> 
> What is this change addressing?  What early_memremap() calls were failing
> that required this?  If this truly is required, you can probably move it
> up into the "if (sme_active())" block a few lines higher in the function.
> 
Thanks. About this issue, you could read the description of cover letter, we put some
logic into the early_memremap_pgprot_adjust() in order to avoid the previous changes,
such as arch/x86/include/asm/dmi.h, arch/x86/kernel/acpi/boot.c and drivers/acpi/tables.c.					
They will call early_memremap() to remap the memory, but we need to remap the memory
without encryption.

Lianbo

> Thanks,
> Tom
> 
>>  	return encrypted_prot ? pgprot_encrypted(prot)
>>  			      : pgprot_decrypted(prot);
>>  }
>>

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled
@ 2018-06-21  9:13       ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  9:13 UTC (permalink / raw)
  To: Tom Lendacky, linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

在 2018年06月21日 00:00, Tom Lendacky 写道:
> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>> It is convenient to remap the old memory encrypted to the second
>> kernel by calling ioremap_encrypted().
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>> Some changes:
>> 1. remove the sme_active() check in __ioremap_caller().
>> 2. put some logic into the early_memremap_pgprot_adjust() for
>> early memremap.
>>
>>  arch/x86/include/asm/io.h |  3 +++
>>  arch/x86/mm/ioremap.c     | 28 ++++++++++++++++++++--------
>>  2 files changed, 23 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
>> index f6e5b93..989d60b 100644
>> --- a/arch/x86/include/asm/io.h
>> +++ b/arch/x86/include/asm/io.h
>> @@ -192,6 +192,9 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
>>  #define ioremap_cache ioremap_cache
>>  extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
>>  #define ioremap_prot ioremap_prot
>> +extern void __iomem *ioremap_encrypted(resource_size_t phys_addr,
>> +					unsigned long size);
>> +#define ioremap_encrypted ioremap_encrypted
>>  
>>  /**
>>   * ioremap     -   map bus memory into CPU space
>> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
>> index c63a545..e365fc4 100644
>> --- a/arch/x86/mm/ioremap.c
>> +++ b/arch/x86/mm/ioremap.c
>> @@ -24,6 +24,7 @@
>>  #include <asm/pgalloc.h>
>>  #include <asm/pat.h>
>>  #include <asm/setup.h>
>> +#include <linux/crash_dump.h>
>>  
>>  #include "physaddr.h"
>>  
>> @@ -131,7 +132,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
>>   * caller shouldn't need to know that small detail.
>>   */
>>  static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>> -		unsigned long size, enum page_cache_mode pcm, void *caller)
>> +		unsigned long size, enum page_cache_mode pcm,
>> +		void *caller, bool encrypted)
>>  {
>>  	unsigned long offset, vaddr;
>>  	resource_size_t last_addr;
>> @@ -199,7 +201,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>>  	 * resulting mapping.
>>  	 */
>>  	prot = PAGE_KERNEL_IO;
>> -	if (sev_active() && mem_flags.desc_other)
>> +	if ((sev_active() && mem_flags.desc_other) || encrypted)
>>  		prot = pgprot_encrypted(prot);
>>  
>>  	switch (pcm) {
>> @@ -291,7 +293,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
>>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
>>  
>>  	return __ioremap_caller(phys_addr, size, pcm,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_nocache);
>>  
>> @@ -324,7 +326,7 @@ void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
>>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
>>  
>>  	return __ioremap_caller(phys_addr, size, pcm,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL_GPL(ioremap_uc);
>>  
>> @@ -341,7 +343,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
>>  void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
>> -					__builtin_return_address(0));
>> +					__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_wc);
>>  
>> @@ -358,14 +360,21 @@ EXPORT_SYMBOL(ioremap_wc);
>>  void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
>> -					__builtin_return_address(0));
>> +					__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_wt);
>>  
>> +void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
>> +{
>> +	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
>> +				__builtin_return_address(0), true);
>> +}
>> +EXPORT_SYMBOL(ioremap_encrypted);
>> +
>>  void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_cache);
>>  
>> @@ -374,7 +383,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
>>  {
>>  	return __ioremap_caller(phys_addr, size,
>>  				pgprot2cachemode(__pgprot(prot_val)),
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_prot);
>>  
>> @@ -688,6 +697,9 @@ pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
>>  	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
>>  		encrypted_prot = false;
>>  
>> +	if (sme_active() && is_kdump_kernel())
>> +		encrypted_prot = false;
>> +
> 
> This change doesn't seem to go with the patch description.  Maybe it
> should be a separate patch?  Or provide more detail in the description
> for this change.
> 
> What is this change addressing?  What early_memremap() calls were failing
> that required this?  If this truly is required, you can probably move it
> up into the "if (sme_active())" block a few lines higher in the function.
> 
Thanks. About this issue, you could read the description of cover letter, we put some
logic into the early_memremap_pgprot_adjust() in order to avoid the previous changes,
such as arch/x86/include/asm/dmi.h, arch/x86/kernel/acpi/boot.c and drivers/acpi/tables.c.					
They will call early_memremap() to remap the memory, but we need to remap the memory
without encryption.

Lianbo

> Thanks,
> Tom
> 
>>  	return encrypted_prot ? pgprot_encrypted(prot)
>>  			      : pgprot_decrypted(prot);
>>  }
>>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled
@ 2018-06-21  9:13       ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  9:13 UTC (permalink / raw)
  To: Tom Lendacky, linux-kernel; +Cc: dyoung, iommu, kexec

在 2018年06月21日 00:00, Tom Lendacky 写道:
> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>> It is convenient to remap the old memory encrypted to the second
>> kernel by calling ioremap_encrypted().
>>
>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>> ---
>> Some changes:
>> 1. remove the sme_active() check in __ioremap_caller().
>> 2. put some logic into the early_memremap_pgprot_adjust() for
>> early memremap.
>>
>>  arch/x86/include/asm/io.h |  3 +++
>>  arch/x86/mm/ioremap.c     | 28 ++++++++++++++++++++--------
>>  2 files changed, 23 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
>> index f6e5b93..989d60b 100644
>> --- a/arch/x86/include/asm/io.h
>> +++ b/arch/x86/include/asm/io.h
>> @@ -192,6 +192,9 @@ extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
>>  #define ioremap_cache ioremap_cache
>>  extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
>>  #define ioremap_prot ioremap_prot
>> +extern void __iomem *ioremap_encrypted(resource_size_t phys_addr,
>> +					unsigned long size);
>> +#define ioremap_encrypted ioremap_encrypted
>>  
>>  /**
>>   * ioremap     -   map bus memory into CPU space
>> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
>> index c63a545..e365fc4 100644
>> --- a/arch/x86/mm/ioremap.c
>> +++ b/arch/x86/mm/ioremap.c
>> @@ -24,6 +24,7 @@
>>  #include <asm/pgalloc.h>
>>  #include <asm/pat.h>
>>  #include <asm/setup.h>
>> +#include <linux/crash_dump.h>
>>  
>>  #include "physaddr.h"
>>  
>> @@ -131,7 +132,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
>>   * caller shouldn't need to know that small detail.
>>   */
>>  static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>> -		unsigned long size, enum page_cache_mode pcm, void *caller)
>> +		unsigned long size, enum page_cache_mode pcm,
>> +		void *caller, bool encrypted)
>>  {
>>  	unsigned long offset, vaddr;
>>  	resource_size_t last_addr;
>> @@ -199,7 +201,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
>>  	 * resulting mapping.
>>  	 */
>>  	prot = PAGE_KERNEL_IO;
>> -	if (sev_active() && mem_flags.desc_other)
>> +	if ((sev_active() && mem_flags.desc_other) || encrypted)
>>  		prot = pgprot_encrypted(prot);
>>  
>>  	switch (pcm) {
>> @@ -291,7 +293,7 @@ void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
>>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
>>  
>>  	return __ioremap_caller(phys_addr, size, pcm,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_nocache);
>>  
>> @@ -324,7 +326,7 @@ void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
>>  	enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
>>  
>>  	return __ioremap_caller(phys_addr, size, pcm,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL_GPL(ioremap_uc);
>>  
>> @@ -341,7 +343,7 @@ EXPORT_SYMBOL_GPL(ioremap_uc);
>>  void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
>> -					__builtin_return_address(0));
>> +					__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_wc);
>>  
>> @@ -358,14 +360,21 @@ EXPORT_SYMBOL(ioremap_wc);
>>  void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
>> -					__builtin_return_address(0));
>> +					__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_wt);
>>  
>> +void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size)
>> +{
>> +	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
>> +				__builtin_return_address(0), true);
>> +}
>> +EXPORT_SYMBOL(ioremap_encrypted);
>> +
>>  void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
>>  {
>>  	return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_cache);
>>  
>> @@ -374,7 +383,7 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
>>  {
>>  	return __ioremap_caller(phys_addr, size,
>>  				pgprot2cachemode(__pgprot(prot_val)),
>> -				__builtin_return_address(0));
>> +				__builtin_return_address(0), false);
>>  }
>>  EXPORT_SYMBOL(ioremap_prot);
>>  
>> @@ -688,6 +697,9 @@ pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
>>  	if (encrypted_prot && memremap_should_map_decrypted(phys_addr, size))
>>  		encrypted_prot = false;
>>  
>> +	if (sme_active() && is_kdump_kernel())
>> +		encrypted_prot = false;
>> +
> 
> This change doesn't seem to go with the patch description.  Maybe it
> should be a separate patch?  Or provide more detail in the description
> for this change.
> 
> What is this change addressing?  What early_memremap() calls were failing
> that required this?  If this truly is required, you can probably move it
> up into the "if (sme_active())" block a few lines higher in the function.
> 
Thanks. About this issue, you could read the description of cover letter, we put some
logic into the early_memremap_pgprot_adjust() in order to avoid the previous changes,
such as arch/x86/include/asm/dmi.h, arch/x86/kernel/acpi/boot.c and drivers/acpi/tables.c.					
They will call early_memremap() to remap the memory, but we need to remap the memory
without encryption.

Lianbo

> Thanks,
> Tom
> 
>>  	return encrypted_prot ? pgprot_encrypted(prot)
>>  			      : pgprot_decrypted(prot);
>>  }
>>

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
  2018-06-21  8:39         ` Baoquan He
  (?)
@ 2018-06-21  9:45           ` lijiang
  -1 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  9:45 UTC (permalink / raw)
  To: Baoquan He; +Cc: Tom Lendacky, linux-kernel, dyoung, iommu, kexec

在 2018年06月21日 16:39, Baoquan He 写道:
> On 06/21/18 at 01:42pm, lijiang wrote:
>> 在 2018年06月21日 00:42, Tom Lendacky 写道:
>>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>>>> In kdump mode, it will copy the device table of IOMMU from the old
>>>> device table, which is encrypted when SME is enabled in the first
>>>> kernel. So we must remap it in encrypted manner in order to be
>>>> automatically decrypted when we read.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>> Some changes:
>>>> 1. add some comments
>>>> 2. clean compile warning.
>>>>
>>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
>>>> index 904c575..a20af4c 100644
>>>> --- a/drivers/iommu/amd_iommu_init.c
>>>> +++ b/drivers/iommu/amd_iommu_init.c
>>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>>>>  	}
>>>>  
>>>>  	old_devtb_phys = entry & PAGE_MASK;
>>>> +
>>>> +	/*
>>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
>>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
>>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
>>>> +	 */
>>>> +	if (mem_encrypt_active() && is_kdump_kernel())
>>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
>>>> +
>>>
>>> You can probably just use "if (is_kdump_kernel())" here, since memory
>>> encryption is either on in both the first and second kernel or off in
>>> both the first and second kernel.  At which point __sme_clr() will do
>>> the proper thing.
>>>
>>> Actually, this needs to be done no matter what.  When doing either the
>>> ioremap_encrypted() or the memremap(), the physical address should not
>>> include the encryption bit/mask.
>>>
>>> Thanks,
>>> Tom
>>>
>> Thanks for your comments. If we don't remove the memory encryption mask, it will
>> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> 
> Lianbo, you may not get what Tom suggested. Tom means no matter what it
> is, encrypted or not in 1st kernel, we need get pure physicall address,
> and using below code is always right for both cases.
> 
> 	if (is_kdump_kernel())
> 		old_devtb_phys = __sme_clr(old_devtb_phys);
> 
Thank you, Baoquan. I understood what Tom said. I just want to explain why removing
the memory encryption mask is necessary before the 'old_devtb_phys >= 0x100000000ULL'.

Lianbo
> And this is simpler. You even can add one line of code comment to say
> like "Physical address w/o encryption mask is needed here."
>>
>> Lianbo
>>>>  	if (old_devtb_phys >= 0x100000000ULL) {
>>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>>>>  		return false;
>>>>  	}
>>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
>>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
>>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
>>>> +							dev_table_size)
>>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>>>>  	if (!old_devtb)
>>>>  		return false;
>>>>  
>>>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  9:45           ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  9:45 UTC (permalink / raw)
  To: Baoquan He
  Cc: Tom Lendacky, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

在 2018年06月21日 16:39, Baoquan He 写道:
> On 06/21/18 at 01:42pm, lijiang wrote:
>> 在 2018年06月21日 00:42, Tom Lendacky 写道:
>>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>>>> In kdump mode, it will copy the device table of IOMMU from the old
>>>> device table, which is encrypted when SME is enabled in the first
>>>> kernel. So we must remap it in encrypted manner in order to be
>>>> automatically decrypted when we read.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>> Some changes:
>>>> 1. add some comments
>>>> 2. clean compile warning.
>>>>
>>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
>>>> index 904c575..a20af4c 100644
>>>> --- a/drivers/iommu/amd_iommu_init.c
>>>> +++ b/drivers/iommu/amd_iommu_init.c
>>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>>>>  	}
>>>>  
>>>>  	old_devtb_phys = entry & PAGE_MASK;
>>>> +
>>>> +	/*
>>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
>>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
>>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
>>>> +	 */
>>>> +	if (mem_encrypt_active() && is_kdump_kernel())
>>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
>>>> +
>>>
>>> You can probably just use "if (is_kdump_kernel())" here, since memory
>>> encryption is either on in both the first and second kernel or off in
>>> both the first and second kernel.  At which point __sme_clr() will do
>>> the proper thing.
>>>
>>> Actually, this needs to be done no matter what.  When doing either the
>>> ioremap_encrypted() or the memremap(), the physical address should not
>>> include the encryption bit/mask.
>>>
>>> Thanks,
>>> Tom
>>>
>> Thanks for your comments. If we don't remove the memory encryption mask, it will
>> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> 
> Lianbo, you may not get what Tom suggested. Tom means no matter what it
> is, encrypted or not in 1st kernel, we need get pure physicall address,
> and using below code is always right for both cases.
> 
> 	if (is_kdump_kernel())
> 		old_devtb_phys = __sme_clr(old_devtb_phys);
> 
Thank you, Baoquan. I understood what Tom said. I just want to explain why removing
the memory encryption mask is necessary before the 'old_devtb_phys >= 0x100000000ULL'.

Lianbo
> And this is simpler. You even can add one line of code comment to say
> like "Physical address w/o encryption mask is needed here."
>>
>> Lianbo
>>>>  	if (old_devtb_phys >= 0x100000000ULL) {
>>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>>>>  		return false;
>>>>  	}
>>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
>>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
>>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
>>>> +							dev_table_size)
>>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>>>>  	if (!old_devtb)
>>>>  		return false;
>>>>  
>>>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21  9:45           ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21  9:45 UTC (permalink / raw)
  To: Baoquan He; +Cc: Tom Lendacky, iommu, dyoung, linux-kernel, kexec

在 2018年06月21日 16:39, Baoquan He 写道:
> On 06/21/18 at 01:42pm, lijiang wrote:
>> 在 2018年06月21日 00:42, Tom Lendacky 写道:
>>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>>>> In kdump mode, it will copy the device table of IOMMU from the old
>>>> device table, which is encrypted when SME is enabled in the first
>>>> kernel. So we must remap it in encrypted manner in order to be
>>>> automatically decrypted when we read.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>> Some changes:
>>>> 1. add some comments
>>>> 2. clean compile warning.
>>>>
>>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
>>>> index 904c575..a20af4c 100644
>>>> --- a/drivers/iommu/amd_iommu_init.c
>>>> +++ b/drivers/iommu/amd_iommu_init.c
>>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>>>>  	}
>>>>  
>>>>  	old_devtb_phys = entry & PAGE_MASK;
>>>> +
>>>> +	/*
>>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
>>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
>>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
>>>> +	 */
>>>> +	if (mem_encrypt_active() && is_kdump_kernel())
>>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
>>>> +
>>>
>>> You can probably just use "if (is_kdump_kernel())" here, since memory
>>> encryption is either on in both the first and second kernel or off in
>>> both the first and second kernel.  At which point __sme_clr() will do
>>> the proper thing.
>>>
>>> Actually, this needs to be done no matter what.  When doing either the
>>> ioremap_encrypted() or the memremap(), the physical address should not
>>> include the encryption bit/mask.
>>>
>>> Thanks,
>>> Tom
>>>
>> Thanks for your comments. If we don't remove the memory encryption mask, it will
>> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> 
> Lianbo, you may not get what Tom suggested. Tom means no matter what it
> is, encrypted or not in 1st kernel, we need get pure physicall address,
> and using below code is always right for both cases.
> 
> 	if (is_kdump_kernel())
> 		old_devtb_phys = __sme_clr(old_devtb_phys);
> 
Thank you, Baoquan. I understood what Tom said. I just want to explain why removing
the memory encryption mask is necessary before the 'old_devtb_phys >= 0x100000000ULL'.

Lianbo
> And this is simpler. You even can add one line of code comment to say
> like "Physical address w/o encryption mask is needed here."
>>
>> Lianbo
>>>>  	if (old_devtb_phys >= 0x100000000ULL) {
>>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>>>>  		return false;
>>>>  	}
>>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
>>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
>>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
>>>> +							dev_table_size)
>>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>>>>  	if (!old_devtb)
>>>>  		return false;
>>>>  
>>>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21 10:23         ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21 10:23 UTC (permalink / raw)
  To: lijiang; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec

On 06/21/18 at 01:06pm, lijiang wrote:
> 在 2018年06月21日 09:53, Baoquan He 写道:
> > On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> >> When SME is enabled in the first kernel, we will allocate pages
> >> for kdump without encryption in order to be able to boot the
> >> second kernel in the same manner as kexec, which helps to keep
> >> the same code style.
> >>
> >> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >> ---
> >>  kernel/kexec_core.c | 12 ++++++++++++
> >>  1 file changed, 12 insertions(+)
> >>
> >> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> >> index 20fef1a..3c22a9b 100644
> >> --- a/kernel/kexec_core.c
> >> +++ b/kernel/kexec_core.c
> >> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
> >>  		}
> >>  	}
> >>  
> >> +	if (pages) {
> >> +		unsigned int count, i;
> >> +
> >> +		pages->mapping = NULL;
> >> +		set_page_private(pages, order);
> >> +		count = 1 << order;
> >> +		for (i = 0; i < count; i++)
> >> +			SetPageReserved(pages + i);
> > 
> > I guess you might imitate the kexec case, however kexec get pages from
> > buddy. Crash pages are reserved in memblock, these codes might make no sense.
> > 
> Thanks for your comments.
> We have changed the attribute of pages, so the original attribute of pages will be
> restored when they free.

Hmm, you can check what kimage_free() is doing, and where
kimage->control_pages, dest_pages, unusable_pages is assigned. Do you
know where these original attribute of pages comes from and they are
used/needed in CRASH case, if you care about them?

> 
> >> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
> >> +	}
> >>  	return pages;
> >>  }
> >>  
> >> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>  			result  = -ENOMEM;
> >>  			goto out;
> >>  		}
> >> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
> >>  		ptr = kmap(page);
> >>  		ptr += maddr & ~PAGE_MASK;
> >>  		mchunk = min_t(size_t, mbytes,
> >> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>  			result = copy_from_user(ptr, buf, uchunk);
> >>  		kexec_flush_icache_page(page);
> >>  		kunmap(page);
> >> +		arch_kexec_pre_free_pages(page_address(page), 1);
> >>  		if (result) {
> >>  			result = -EFAULT;
> >>  			goto out;
> >> -- 
> >> 2.9.5
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21 10:23         ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21 10:23 UTC (permalink / raw)
  To: lijiang
  Cc: thomas.lendacky-5C7GfCeVMHo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 06/21/18 at 01:06pm, lijiang wrote:
> 在 2018年06月21日 09:53, Baoquan He 写道:
> > On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> >> When SME is enabled in the first kernel, we will allocate pages
> >> for kdump without encryption in order to be able to boot the
> >> second kernel in the same manner as kexec, which helps to keep
> >> the same code style.
> >>
> >> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >> ---
> >>  kernel/kexec_core.c | 12 ++++++++++++
> >>  1 file changed, 12 insertions(+)
> >>
> >> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> >> index 20fef1a..3c22a9b 100644
> >> --- a/kernel/kexec_core.c
> >> +++ b/kernel/kexec_core.c
> >> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
> >>  		}
> >>  	}
> >>  
> >> +	if (pages) {
> >> +		unsigned int count, i;
> >> +
> >> +		pages->mapping = NULL;
> >> +		set_page_private(pages, order);
> >> +		count = 1 << order;
> >> +		for (i = 0; i < count; i++)
> >> +			SetPageReserved(pages + i);
> > 
> > I guess you might imitate the kexec case, however kexec get pages from
> > buddy. Crash pages are reserved in memblock, these codes might make no sense.
> > 
> Thanks for your comments.
> We have changed the attribute of pages, so the original attribute of pages will be
> restored when they free.

Hmm, you can check what kimage_free() is doing, and where
kimage->control_pages, dest_pages, unusable_pages is assigned. Do you
know where these original attribute of pages comes from and they are
used/needed in CRASH case, if you care about them?

> 
> >> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
> >> +	}
> >>  	return pages;
> >>  }
> >>  
> >> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>  			result  = -ENOMEM;
> >>  			goto out;
> >>  		}
> >> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
> >>  		ptr = kmap(page);
> >>  		ptr += maddr & ~PAGE_MASK;
> >>  		mchunk = min_t(size_t, mbytes,
> >> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>  			result = copy_from_user(ptr, buf, uchunk);
> >>  		kexec_flush_icache_page(page);
> >>  		kunmap(page);
> >> +		arch_kexec_pre_free_pages(page_address(page), 1);
> >>  		if (result) {
> >>  			result = -EFAULT;
> >>  			goto out;
> >> -- 
> >> 2.9.5
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21 10:23         ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-21 10:23 UTC (permalink / raw)
  To: lijiang; +Cc: thomas.lendacky, iommu, dyoung, linux-kernel, kexec

On 06/21/18 at 01:06pm, lijiang wrote:
> 在 2018年06月21日 09:53, Baoquan He 写道:
> > On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> >> When SME is enabled in the first kernel, we will allocate pages
> >> for kdump without encryption in order to be able to boot the
> >> second kernel in the same manner as kexec, which helps to keep
> >> the same code style.
> >>
> >> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >> ---
> >>  kernel/kexec_core.c | 12 ++++++++++++
> >>  1 file changed, 12 insertions(+)
> >>
> >> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> >> index 20fef1a..3c22a9b 100644
> >> --- a/kernel/kexec_core.c
> >> +++ b/kernel/kexec_core.c
> >> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
> >>  		}
> >>  	}
> >>  
> >> +	if (pages) {
> >> +		unsigned int count, i;
> >> +
> >> +		pages->mapping = NULL;
> >> +		set_page_private(pages, order);
> >> +		count = 1 << order;
> >> +		for (i = 0; i < count; i++)
> >> +			SetPageReserved(pages + i);
> > 
> > I guess you might imitate the kexec case, however kexec get pages from
> > buddy. Crash pages are reserved in memblock, these codes might make no sense.
> > 
> Thanks for your comments.
> We have changed the attribute of pages, so the original attribute of pages will be
> restored when they free.

Hmm, you can check what kimage_free() is doing, and where
kimage->control_pages, dest_pages, unusable_pages is assigned. Do you
know where these original attribute of pages comes from and they are
used/needed in CRASH case, if you care about them?

> 
> >> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
> >> +	}
> >>  	return pages;
> >>  }
> >>  
> >> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>  			result  = -ENOMEM;
> >>  			goto out;
> >>  		}
> >> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
> >>  		ptr = kmap(page);
> >>  		ptr += maddr & ~PAGE_MASK;
> >>  		mchunk = min_t(size_t, mbytes,
> >> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>  			result = copy_from_user(ptr, buf, uchunk);
> >>  		kexec_flush_icache_page(page);
> >>  		kunmap(page);
> >> +		arch_kexec_pre_free_pages(page_address(page), 1);
> >>  		if (result) {
> >>  			result = -EFAULT;
> >>  			goto out;
> >> -- 
> >> 2.9.5
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
  2018-06-21  8:39         ` Baoquan He
  (?)
@ 2018-06-21 13:12           ` Tom Lendacky
  -1 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-21 13:12 UTC (permalink / raw)
  To: Baoquan He, lijiang; +Cc: linux-kernel, dyoung, iommu, kexec

On 6/21/2018 3:39 AM, Baoquan He wrote:
> On 06/21/18 at 01:42pm, lijiang wrote:
>> 在 2018年06月21日 00:42, Tom Lendacky 写道:
>>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>>>> In kdump mode, it will copy the device table of IOMMU from the old
>>>> device table, which is encrypted when SME is enabled in the first
>>>> kernel. So we must remap it in encrypted manner in order to be
>>>> automatically decrypted when we read.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>> Some changes:
>>>> 1. add some comments
>>>> 2. clean compile warning.
>>>>
>>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
>>>> index 904c575..a20af4c 100644
>>>> --- a/drivers/iommu/amd_iommu_init.c
>>>> +++ b/drivers/iommu/amd_iommu_init.c
>>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>>>>  	}
>>>>  
>>>>  	old_devtb_phys = entry & PAGE_MASK;
>>>> +
>>>> +	/*
>>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
>>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
>>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
>>>> +	 */
>>>> +	if (mem_encrypt_active() && is_kdump_kernel())
>>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
>>>> +
>>>
>>> You can probably just use "if (is_kdump_kernel())" here, since memory
>>> encryption is either on in both the first and second kernel or off in
>>> both the first and second kernel.  At which point __sme_clr() will do
>>> the proper thing.
>>>
>>> Actually, this needs to be done no matter what.  When doing either the
>>> ioremap_encrypted() or the memremap(), the physical address should not
>>> include the encryption bit/mask.
>>>
>>> Thanks,
>>> Tom
>>>
>> Thanks for your comments. If we don't remove the memory encryption mask, it will
>> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> 
> Lianbo, you may not get what Tom suggested. Tom means no matter what it
> is, encrypted or not in 1st kernel, we need get pure physicall address,
> and using below code is always right for both cases.
> 
> 	if (is_kdump_kernel())
> 		old_devtb_phys = __sme_clr(old_devtb_phys);
> 
> And this is simpler. You even can add one line of code comment to say
> like "Physical address w/o encryption mask is needed here."

Even simpler, there's no need to even check for is_kdump_kernel().  The
__sme_clr() should always be done if the physical address is going to be
used for some form of io or memory remapping.

So you could just change the existing:

	old_devtb_phys = entry & PAGE_MASK;

to:

	old_devtb_phys = __sme_clr(entry) & PAGE_MASK;

Thanks,
Tom

>>
>> Lianbo
>>>>  	if (old_devtb_phys >= 0x100000000ULL) {
>>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>>>>  		return false;
>>>>  	}
>>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
>>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
>>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
>>>> +							dev_table_size)
>>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>>>>  	if (!old_devtb)
>>>>  		return false;
>>>>  
>>>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21 13:12           ` Tom Lendacky
  0 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-21 13:12 UTC (permalink / raw)
  To: Baoquan He, lijiang
  Cc: kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 6/21/2018 3:39 AM, Baoquan He wrote:
> On 06/21/18 at 01:42pm, lijiang wrote:
>> 在 2018年06月21日 00:42, Tom Lendacky 写道:
>>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>>>> In kdump mode, it will copy the device table of IOMMU from the old
>>>> device table, which is encrypted when SME is enabled in the first
>>>> kernel. So we must remap it in encrypted manner in order to be
>>>> automatically decrypted when we read.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>> Some changes:
>>>> 1. add some comments
>>>> 2. clean compile warning.
>>>>
>>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
>>>> index 904c575..a20af4c 100644
>>>> --- a/drivers/iommu/amd_iommu_init.c
>>>> +++ b/drivers/iommu/amd_iommu_init.c
>>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>>>>  	}
>>>>  
>>>>  	old_devtb_phys = entry & PAGE_MASK;
>>>> +
>>>> +	/*
>>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
>>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
>>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
>>>> +	 */
>>>> +	if (mem_encrypt_active() && is_kdump_kernel())
>>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
>>>> +
>>>
>>> You can probably just use "if (is_kdump_kernel())" here, since memory
>>> encryption is either on in both the first and second kernel or off in
>>> both the first and second kernel.  At which point __sme_clr() will do
>>> the proper thing.
>>>
>>> Actually, this needs to be done no matter what.  When doing either the
>>> ioremap_encrypted() or the memremap(), the physical address should not
>>> include the encryption bit/mask.
>>>
>>> Thanks,
>>> Tom
>>>
>> Thanks for your comments. If we don't remove the memory encryption mask, it will
>> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> 
> Lianbo, you may not get what Tom suggested. Tom means no matter what it
> is, encrypted or not in 1st kernel, we need get pure physicall address,
> and using below code is always right for both cases.
> 
> 	if (is_kdump_kernel())
> 		old_devtb_phys = __sme_clr(old_devtb_phys);
> 
> And this is simpler. You even can add one line of code comment to say
> like "Physical address w/o encryption mask is needed here."

Even simpler, there's no need to even check for is_kdump_kernel().  The
__sme_clr() should always be done if the physical address is going to be
used for some form of io or memory remapping.

So you could just change the existing:

	old_devtb_phys = entry & PAGE_MASK;

to:

	old_devtb_phys = __sme_clr(entry) & PAGE_MASK;

Thanks,
Tom

>>
>> Lianbo
>>>>  	if (old_devtb_phys >= 0x100000000ULL) {
>>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>>>>  		return false;
>>>>  	}
>>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
>>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
>>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
>>>> +							dev_table_size)
>>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>>>>  	if (!old_devtb)
>>>>  		return false;
>>>>  
>>>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-21 13:12           ` Tom Lendacky
  0 siblings, 0 replies; 70+ messages in thread
From: Tom Lendacky @ 2018-06-21 13:12 UTC (permalink / raw)
  To: Baoquan He, lijiang; +Cc: kexec, iommu, dyoung, linux-kernel

On 6/21/2018 3:39 AM, Baoquan He wrote:
> On 06/21/18 at 01:42pm, lijiang wrote:
>> 在 2018年06月21日 00:42, Tom Lendacky 写道:
>>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
>>>> In kdump mode, it will copy the device table of IOMMU from the old
>>>> device table, which is encrypted when SME is enabled in the first
>>>> kernel. So we must remap it in encrypted manner in order to be
>>>> automatically decrypted when we read.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>> Some changes:
>>>> 1. add some comments
>>>> 2. clean compile warning.
>>>>
>>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
>>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
>>>> index 904c575..a20af4c 100644
>>>> --- a/drivers/iommu/amd_iommu_init.c
>>>> +++ b/drivers/iommu/amd_iommu_init.c
>>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
>>>>  	}
>>>>  
>>>>  	old_devtb_phys = entry & PAGE_MASK;
>>>> +
>>>> +	/*
>>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
>>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
>>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
>>>> +	 */
>>>> +	if (mem_encrypt_active() && is_kdump_kernel())
>>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
>>>> +
>>>
>>> You can probably just use "if (is_kdump_kernel())" here, since memory
>>> encryption is either on in both the first and second kernel or off in
>>> both the first and second kernel.  At which point __sme_clr() will do
>>> the proper thing.
>>>
>>> Actually, this needs to be done no matter what.  When doing either the
>>> ioremap_encrypted() or the memremap(), the physical address should not
>>> include the encryption bit/mask.
>>>
>>> Thanks,
>>> Tom
>>>
>> Thanks for your comments. If we don't remove the memory encryption mask, it will
>> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> 
> Lianbo, you may not get what Tom suggested. Tom means no matter what it
> is, encrypted or not in 1st kernel, we need get pure physicall address,
> and using below code is always right for both cases.
> 
> 	if (is_kdump_kernel())
> 		old_devtb_phys = __sme_clr(old_devtb_phys);
> 
> And this is simpler. You even can add one line of code comment to say
> like "Physical address w/o encryption mask is needed here."

Even simpler, there's no need to even check for is_kdump_kernel().  The
__sme_clr() should always be done if the physical address is going to be
used for some form of io or memory remapping.

So you could just change the existing:

	old_devtb_phys = entry & PAGE_MASK;

to:

	old_devtb_phys = __sme_clr(entry) & PAGE_MASK;

Thanks,
Tom

>>
>> Lianbo
>>>>  	if (old_devtb_phys >= 0x100000000ULL) {
>>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
>>>>  		return false;
>>>>  	}
>>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
>>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
>>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
>>>> +							dev_table_size)
>>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
>>>>  	if (!old_devtb)
>>>>  		return false;
>>>>  
>>>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
  2018-06-21 10:23         ` Baoquan He
  (?)
@ 2018-06-21 13:27           ` lijiang
  -1 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21 13:27 UTC (permalink / raw)
  To: Baoquan He; +Cc: linux-kernel, thomas.lendacky, iommu, dyoung, kexec

在 2018年06月21日 18:23, Baoquan He 写道:
> On 06/21/18 at 01:06pm, lijiang wrote:
>> 在 2018年06月21日 09:53, Baoquan He 写道:
>>> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>>>> When SME is enabled in the first kernel, we will allocate pages
>>>> for kdump without encryption in order to be able to boot the
>>>> second kernel in the same manner as kexec, which helps to keep
>>>> the same code style.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>>  kernel/kexec_core.c | 12 ++++++++++++
>>>>  1 file changed, 12 insertions(+)
>>>>
>>>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>>>> index 20fef1a..3c22a9b 100644
>>>> --- a/kernel/kexec_core.c
>>>> +++ b/kernel/kexec_core.c
>>>> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>>>>  		}
>>>>  	}
>>>>  
>>>> +	if (pages) {
>>>> +		unsigned int count, i;
>>>> +
>>>> +		pages->mapping = NULL;
>>>> +		set_page_private(pages, order);
>>>> +		count = 1 << order;
>>>> +		for (i = 0; i < count; i++)
>>>> +			SetPageReserved(pages + i);
>>>
>>> I guess you might imitate the kexec case, however kexec get pages from
>>> buddy. Crash pages are reserved in memblock, these codes might make no sense.
>>>
>> Thanks for your comments.
>> We have changed the attribute of pages, so the original attribute of pages will be
>> restored when they free.
> 
> Hmm, you can check what kimage_free() is doing, and where
> kimage->control_pages, dest_pages, unusable_pages is assigned. Do you
> know where these original attribute of pages comes from and they are
> used/needed in CRASH case, if you care about them?
> 
Originally, we want to have an opportunity to restore the previous attribute of pages, that
should be more better if the pages are remembered in 'image->control_pages'.
If we remove these codes, it is also harmless for kdump, but it will become strange, maybe
someone could ask where to restore the previous attribute of pages.

Thanks.
>>
>>>> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
>>>> +	}
>>>>  	return pages;
>>>>  }
>>>>  
>>>> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>>>  			result  = -ENOMEM;
>>>>  			goto out;
>>>>  		}
>>>> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>>>>  		ptr = kmap(page);
>>>>  		ptr += maddr & ~PAGE_MASK;
>>>>  		mchunk = min_t(size_t, mbytes,
>>>> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>>>  			result = copy_from_user(ptr, buf, uchunk);
>>>>  		kexec_flush_icache_page(page);
>>>>  		kunmap(page);
>>>> +		arch_kexec_pre_free_pages(page_address(page), 1);
>>>>  		if (result) {
>>>>  			result = -EFAULT;
>>>>  			goto out;
>>>> -- 
>>>> 2.9.5
>>>>
>>>>
>>>> _______________________________________________
>>>> kexec mailing list
>>>> kexec@lists.infradead.org
>>>> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21 13:27           ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21 13:27 UTC (permalink / raw)
  To: Baoquan He
  Cc: thomas.lendacky-5C7GfCeVMHo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

在 2018年06月21日 18:23, Baoquan He 写道:
> On 06/21/18 at 01:06pm, lijiang wrote:
>> 在 2018年06月21日 09:53, Baoquan He 写道:
>>> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>>>> When SME is enabled in the first kernel, we will allocate pages
>>>> for kdump without encryption in order to be able to boot the
>>>> second kernel in the same manner as kexec, which helps to keep
>>>> the same code style.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>>  kernel/kexec_core.c | 12 ++++++++++++
>>>>  1 file changed, 12 insertions(+)
>>>>
>>>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>>>> index 20fef1a..3c22a9b 100644
>>>> --- a/kernel/kexec_core.c
>>>> +++ b/kernel/kexec_core.c
>>>> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>>>>  		}
>>>>  	}
>>>>  
>>>> +	if (pages) {
>>>> +		unsigned int count, i;
>>>> +
>>>> +		pages->mapping = NULL;
>>>> +		set_page_private(pages, order);
>>>> +		count = 1 << order;
>>>> +		for (i = 0; i < count; i++)
>>>> +			SetPageReserved(pages + i);
>>>
>>> I guess you might imitate the kexec case, however kexec get pages from
>>> buddy. Crash pages are reserved in memblock, these codes might make no sense.
>>>
>> Thanks for your comments.
>> We have changed the attribute of pages, so the original attribute of pages will be
>> restored when they free.
> 
> Hmm, you can check what kimage_free() is doing, and where
> kimage->control_pages, dest_pages, unusable_pages is assigned. Do you
> know where these original attribute of pages comes from and they are
> used/needed in CRASH case, if you care about them?
> 
Originally, we want to have an opportunity to restore the previous attribute of pages, that
should be more better if the pages are remembered in 'image->control_pages'.
If we remove these codes, it is also harmless for kdump, but it will become strange, maybe
someone could ask where to restore the previous attribute of pages.

Thanks.
>>
>>>> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
>>>> +	}
>>>>  	return pages;
>>>>  }
>>>>  
>>>> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>>>  			result  = -ENOMEM;
>>>>  			goto out;
>>>>  		}
>>>> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>>>>  		ptr = kmap(page);
>>>>  		ptr += maddr & ~PAGE_MASK;
>>>>  		mchunk = min_t(size_t, mbytes,
>>>> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>>>  			result = copy_from_user(ptr, buf, uchunk);
>>>>  		kexec_flush_icache_page(page);
>>>>  		kunmap(page);
>>>> +		arch_kexec_pre_free_pages(page_address(page), 1);
>>>>  		if (result) {
>>>>  			result = -EFAULT;
>>>>  			goto out;
>>>> -- 
>>>> 2.9.5
>>>>
>>>>
>>>> _______________________________________________
>>>> kexec mailing list
>>>> kexec@lists.infradead.org
>>>> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-21 13:27           ` lijiang
  0 siblings, 0 replies; 70+ messages in thread
From: lijiang @ 2018-06-21 13:27 UTC (permalink / raw)
  To: Baoquan He; +Cc: thomas.lendacky, iommu, dyoung, linux-kernel, kexec

在 2018年06月21日 18:23, Baoquan He 写道:
> On 06/21/18 at 01:06pm, lijiang wrote:
>> 在 2018年06月21日 09:53, Baoquan He 写道:
>>> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
>>>> When SME is enabled in the first kernel, we will allocate pages
>>>> for kdump without encryption in order to be able to boot the
>>>> second kernel in the same manner as kexec, which helps to keep
>>>> the same code style.
>>>>
>>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
>>>> ---
>>>>  kernel/kexec_core.c | 12 ++++++++++++
>>>>  1 file changed, 12 insertions(+)
>>>>
>>>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
>>>> index 20fef1a..3c22a9b 100644
>>>> --- a/kernel/kexec_core.c
>>>> +++ b/kernel/kexec_core.c
>>>> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
>>>>  		}
>>>>  	}
>>>>  
>>>> +	if (pages) {
>>>> +		unsigned int count, i;
>>>> +
>>>> +		pages->mapping = NULL;
>>>> +		set_page_private(pages, order);
>>>> +		count = 1 << order;
>>>> +		for (i = 0; i < count; i++)
>>>> +			SetPageReserved(pages + i);
>>>
>>> I guess you might imitate the kexec case, however kexec get pages from
>>> buddy. Crash pages are reserved in memblock, these codes might make no sense.
>>>
>> Thanks for your comments.
>> We have changed the attribute of pages, so the original attribute of pages will be
>> restored when they free.
> 
> Hmm, you can check what kimage_free() is doing, and where
> kimage->control_pages, dest_pages, unusable_pages is assigned. Do you
> know where these original attribute of pages comes from and they are
> used/needed in CRASH case, if you care about them?
> 
Originally, we want to have an opportunity to restore the previous attribute of pages, that
should be more better if the pages are remembered in 'image->control_pages'.
If we remove these codes, it is also harmless for kdump, but it will become strange, maybe
someone could ask where to restore the previous attribute of pages.

Thanks.
>>
>>>> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
>>>> +	}
>>>>  	return pages;
>>>>  }
>>>>  
>>>> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>>>  			result  = -ENOMEM;
>>>>  			goto out;
>>>>  		}
>>>> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
>>>>  		ptr = kmap(page);
>>>>  		ptr += maddr & ~PAGE_MASK;
>>>>  		mchunk = min_t(size_t, mbytes,
>>>> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
>>>>  			result = copy_from_user(ptr, buf, uchunk);
>>>>  		kexec_flush_icache_page(page);
>>>>  		kunmap(page);
>>>> +		arch_kexec_pre_free_pages(page_address(page), 1);
>>>>  		if (result) {
>>>>  			result = -EFAULT;
>>>>  			goto out;
>>>> -- 
>>>> 2.9.5
>>>>
>>>>
>>>> _______________________________________________
>>>> kexec mailing list
>>>> kexec@lists.infradead.org
>>>> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
  2018-06-21 13:27           ` lijiang
@ 2018-06-22  2:51             ` Baoquan He
  -1 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-22  2:51 UTC (permalink / raw)
  To: lijiang; +Cc: thomas.lendacky, iommu, dyoung, linux-kernel, kexec

On 06/21/18 at 09:27pm, lijiang wrote:
> 在 2018年06月21日 18:23, Baoquan He 写道:
> > On 06/21/18 at 01:06pm, lijiang wrote:
> >> 在 2018年06月21日 09:53, Baoquan He 写道:
> >>> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> >>>> When SME is enabled in the first kernel, we will allocate pages
> >>>> for kdump without encryption in order to be able to boot the
> >>>> second kernel in the same manner as kexec, which helps to keep
> >>>> the same code style.
> >>>>
> >>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >>>> ---
> >>>>  kernel/kexec_core.c | 12 ++++++++++++
> >>>>  1 file changed, 12 insertions(+)
> >>>>
> >>>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> >>>> index 20fef1a..3c22a9b 100644
> >>>> --- a/kernel/kexec_core.c
> >>>> +++ b/kernel/kexec_core.c
> >>>> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
> >>>>  		}
> >>>>  	}
> >>>>  
> >>>> +	if (pages) {
> >>>> +		unsigned int count, i;
> >>>> +
> >>>> +		pages->mapping = NULL;
> >>>> +		set_page_private(pages, order);
> >>>> +		count = 1 << order;
> >>>> +		for (i = 0; i < count; i++)
> >>>> +			SetPageReserved(pages + i);
> >>>
> >>> I guess you might imitate the kexec case, however kexec get pages from
> >>> buddy. Crash pages are reserved in memblock, these codes might make no sense.
> >>>
> >> Thanks for your comments.
> >> We have changed the attribute of pages, so the original attribute of pages will be
> >> restored when they free.
> > 
> > Hmm, you can check what kimage_free() is doing, and where
> > kimage->control_pages, dest_pages, unusable_pages is assigned. Do you
> > know where these original attribute of pages comes from and they are
> > used/needed in CRASH case, if you care about them?
> > 
> Originally, we want to have an opportunity to restore the previous attribute of pages, that
> should be more better if the pages are remembered in 'image->control_pages'.

Again, please check who assigns value for 'image->control_pages'.

> If we remove these codes, it is also harmless for kdump, but it will become strange, maybe
> someone could ask where to restore the previous attribute of pages.
> 
> Thanks.
> >>
> >>>> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
> >>>> +	}
> >>>>  	return pages;
> >>>>  }
> >>>>  
> >>>> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>>>  			result  = -ENOMEM;
> >>>>  			goto out;
> >>>>  		}
> >>>> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
> >>>>  		ptr = kmap(page);
> >>>>  		ptr += maddr & ~PAGE_MASK;
> >>>>  		mchunk = min_t(size_t, mbytes,
> >>>> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>>>  			result = copy_from_user(ptr, buf, uchunk);
> >>>>  		kexec_flush_icache_page(page);
> >>>>  		kunmap(page);
> >>>> +		arch_kexec_pre_free_pages(page_address(page), 1);
> >>>>  		if (result) {
> >>>>  			result = -EFAULT;
> >>>>  			goto out;
> >>>> -- 
> >>>> 2.9.5
> >>>>
> >>>>
> >>>> _______________________________________________
> >>>> kexec mailing list
> >>>> kexec@lists.infradead.org
> >>>> http://lists.infradead.org/mailman/listinfo/kexec
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled
@ 2018-06-22  2:51             ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-22  2:51 UTC (permalink / raw)
  To: lijiang; +Cc: thomas.lendacky, iommu, dyoung, linux-kernel, kexec

On 06/21/18 at 09:27pm, lijiang wrote:
> 在 2018年06月21日 18:23, Baoquan He 写道:
> > On 06/21/18 at 01:06pm, lijiang wrote:
> >> 在 2018年06月21日 09:53, Baoquan He 写道:
> >>> On 06/16/18 at 04:27pm, Lianbo Jiang wrote:
> >>>> When SME is enabled in the first kernel, we will allocate pages
> >>>> for kdump without encryption in order to be able to boot the
> >>>> second kernel in the same manner as kexec, which helps to keep
> >>>> the same code style.
> >>>>
> >>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >>>> ---
> >>>>  kernel/kexec_core.c | 12 ++++++++++++
> >>>>  1 file changed, 12 insertions(+)
> >>>>
> >>>> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> >>>> index 20fef1a..3c22a9b 100644
> >>>> --- a/kernel/kexec_core.c
> >>>> +++ b/kernel/kexec_core.c
> >>>> @@ -471,6 +471,16 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
> >>>>  		}
> >>>>  	}
> >>>>  
> >>>> +	if (pages) {
> >>>> +		unsigned int count, i;
> >>>> +
> >>>> +		pages->mapping = NULL;
> >>>> +		set_page_private(pages, order);
> >>>> +		count = 1 << order;
> >>>> +		for (i = 0; i < count; i++)
> >>>> +			SetPageReserved(pages + i);
> >>>
> >>> I guess you might imitate the kexec case, however kexec get pages from
> >>> buddy. Crash pages are reserved in memblock, these codes might make no sense.
> >>>
> >> Thanks for your comments.
> >> We have changed the attribute of pages, so the original attribute of pages will be
> >> restored when they free.
> > 
> > Hmm, you can check what kimage_free() is doing, and where
> > kimage->control_pages, dest_pages, unusable_pages is assigned. Do you
> > know where these original attribute of pages comes from and they are
> > used/needed in CRASH case, if you care about them?
> > 
> Originally, we want to have an opportunity to restore the previous attribute of pages, that
> should be more better if the pages are remembered in 'image->control_pages'.

Again, please check who assigns value for 'image->control_pages'.

> If we remove these codes, it is also harmless for kdump, but it will become strange, maybe
> someone could ask where to restore the previous attribute of pages.
> 
> Thanks.
> >>
> >>>> +		arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);
> >>>> +	}
> >>>>  	return pages;
> >>>>  }
> >>>>  
> >>>> @@ -865,6 +875,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>>>  			result  = -ENOMEM;
> >>>>  			goto out;
> >>>>  		}
> >>>> +		arch_kexec_post_alloc_pages(page_address(page), 1, 0);
> >>>>  		ptr = kmap(page);
> >>>>  		ptr += maddr & ~PAGE_MASK;
> >>>>  		mchunk = min_t(size_t, mbytes,
> >>>> @@ -882,6 +893,7 @@ static int kimage_load_crash_segment(struct kimage *image,
> >>>>  			result = copy_from_user(ptr, buf, uchunk);
> >>>>  		kexec_flush_icache_page(page);
> >>>>  		kunmap(page);
> >>>> +		arch_kexec_pre_free_pages(page_address(page), 1);
> >>>>  		if (result) {
> >>>>  			result = -EFAULT;
> >>>>  			goto out;
> >>>> -- 
> >>>> 2.9.5
> >>>>
> >>>>
> >>>> _______________________________________________
> >>>> kexec mailing list
> >>>> kexec@lists.infradead.org
> >>>> http://lists.infradead.org/mailman/listinfo/kexec
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-22  2:52             ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-22  2:52 UTC (permalink / raw)
  To: Tom Lendacky; +Cc: lijiang, kexec, iommu, dyoung, linux-kernel

On 06/21/18 at 08:12am, Tom Lendacky wrote:
> On 6/21/2018 3:39 AM, Baoquan He wrote:
> > On 06/21/18 at 01:42pm, lijiang wrote:
> >> 在 2018年06月21日 00:42, Tom Lendacky 写道:
> >>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> >>>> In kdump mode, it will copy the device table of IOMMU from the old
> >>>> device table, which is encrypted when SME is enabled in the first
> >>>> kernel. So we must remap it in encrypted manner in order to be
> >>>> automatically decrypted when we read.
> >>>>
> >>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >>>> ---
> >>>> Some changes:
> >>>> 1. add some comments
> >>>> 2. clean compile warning.
> >>>>
> >>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
> >>>>  1 file changed, 14 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> >>>> index 904c575..a20af4c 100644
> >>>> --- a/drivers/iommu/amd_iommu_init.c
> >>>> +++ b/drivers/iommu/amd_iommu_init.c
> >>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
> >>>>  	}
> >>>>  
> >>>>  	old_devtb_phys = entry & PAGE_MASK;
> >>>> +
> >>>> +	/*
> >>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> >>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> >>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
> >>>> +	 */
> >>>> +	if (mem_encrypt_active() && is_kdump_kernel())
> >>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> >>>> +
> >>>
> >>> You can probably just use "if (is_kdump_kernel())" here, since memory
> >>> encryption is either on in both the first and second kernel or off in
> >>> both the first and second kernel.  At which point __sme_clr() will do
> >>> the proper thing.
> >>>
> >>> Actually, this needs to be done no matter what.  When doing either the
> >>> ioremap_encrypted() or the memremap(), the physical address should not
> >>> include the encryption bit/mask.
> >>>
> >>> Thanks,
> >>> Tom
> >>>
> >> Thanks for your comments. If we don't remove the memory encryption mask, it will
> >> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> > 
> > Lianbo, you may not get what Tom suggested. Tom means no matter what it
> > is, encrypted or not in 1st kernel, we need get pure physicall address,
> > and using below code is always right for both cases.
> > 
> > 	if (is_kdump_kernel())
> > 		old_devtb_phys = __sme_clr(old_devtb_phys);
> > 
> > And this is simpler. You even can add one line of code comment to say
> > like "Physical address w/o encryption mask is needed here."
> 
> Even simpler, there's no need to even check for is_kdump_kernel().  The
> __sme_clr() should always be done if the physical address is going to be
> used for some form of io or memory remapping.
> 
> So you could just change the existing:
> 
> 	old_devtb_phys = entry & PAGE_MASK;
> 
> to:
> 
> 	old_devtb_phys = __sme_clr(entry) & PAGE_MASK;

Agree, this is even better.

> 
> >>
> >> Lianbo
> >>>>  	if (old_devtb_phys >= 0x100000000ULL) {
> >>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
> >>>>  		return false;
> >>>>  	}
> >>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> >>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> >>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> >>>> +							dev_table_size)
> >>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
> >>>>  	if (!old_devtb)
> >>>>  		return false;
> >>>>  
> >>>>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-22  2:52             ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-22  2:52 UTC (permalink / raw)
  To: Tom Lendacky
  Cc: dyoung-H+wXaHxf7aLQT0dZR+AlfA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, lijiang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 06/21/18 at 08:12am, Tom Lendacky wrote:
> On 6/21/2018 3:39 AM, Baoquan He wrote:
> > On 06/21/18 at 01:42pm, lijiang wrote:
> >> 在 2018年06月21日 00:42, Tom Lendacky 写道:
> >>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> >>>> In kdump mode, it will copy the device table of IOMMU from the old
> >>>> device table, which is encrypted when SME is enabled in the first
> >>>> kernel. So we must remap it in encrypted manner in order to be
> >>>> automatically decrypted when we read.
> >>>>
> >>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >>>> ---
> >>>> Some changes:
> >>>> 1. add some comments
> >>>> 2. clean compile warning.
> >>>>
> >>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
> >>>>  1 file changed, 14 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> >>>> index 904c575..a20af4c 100644
> >>>> --- a/drivers/iommu/amd_iommu_init.c
> >>>> +++ b/drivers/iommu/amd_iommu_init.c
> >>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
> >>>>  	}
> >>>>  
> >>>>  	old_devtb_phys = entry & PAGE_MASK;
> >>>> +
> >>>> +	/*
> >>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> >>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> >>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
> >>>> +	 */
> >>>> +	if (mem_encrypt_active() && is_kdump_kernel())
> >>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> >>>> +
> >>>
> >>> You can probably just use "if (is_kdump_kernel())" here, since memory
> >>> encryption is either on in both the first and second kernel or off in
> >>> both the first and second kernel.  At which point __sme_clr() will do
> >>> the proper thing.
> >>>
> >>> Actually, this needs to be done no matter what.  When doing either the
> >>> ioremap_encrypted() or the memremap(), the physical address should not
> >>> include the encryption bit/mask.
> >>>
> >>> Thanks,
> >>> Tom
> >>>
> >> Thanks for your comments. If we don't remove the memory encryption mask, it will
> >> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> > 
> > Lianbo, you may not get what Tom suggested. Tom means no matter what it
> > is, encrypted or not in 1st kernel, we need get pure physicall address,
> > and using below code is always right for both cases.
> > 
> > 	if (is_kdump_kernel())
> > 		old_devtb_phys = __sme_clr(old_devtb_phys);
> > 
> > And this is simpler. You even can add one line of code comment to say
> > like "Physical address w/o encryption mask is needed here."
> 
> Even simpler, there's no need to even check for is_kdump_kernel().  The
> __sme_clr() should always be done if the physical address is going to be
> used for some form of io or memory remapping.
> 
> So you could just change the existing:
> 
> 	old_devtb_phys = entry & PAGE_MASK;
> 
> to:
> 
> 	old_devtb_phys = __sme_clr(entry) & PAGE_MASK;

Agree, this is even better.

> 
> >>
> >> Lianbo
> >>>>  	if (old_devtb_phys >= 0x100000000ULL) {
> >>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
> >>>>  		return false;
> >>>>  	}
> >>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> >>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> >>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> >>>> +							dev_table_size)
> >>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
> >>>>  	if (!old_devtb)
> >>>>  		return false;
> >>>>  
> >>>>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump
@ 2018-06-22  2:52             ` Baoquan He
  0 siblings, 0 replies; 70+ messages in thread
From: Baoquan He @ 2018-06-22  2:52 UTC (permalink / raw)
  To: Tom Lendacky; +Cc: dyoung, iommu, kexec, lijiang, linux-kernel

On 06/21/18 at 08:12am, Tom Lendacky wrote:
> On 6/21/2018 3:39 AM, Baoquan He wrote:
> > On 06/21/18 at 01:42pm, lijiang wrote:
> >> 在 2018年06月21日 00:42, Tom Lendacky 写道:
> >>> On 6/16/2018 3:27 AM, Lianbo Jiang wrote:
> >>>> In kdump mode, it will copy the device table of IOMMU from the old
> >>>> device table, which is encrypted when SME is enabled in the first
> >>>> kernel. So we must remap it in encrypted manner in order to be
> >>>> automatically decrypted when we read.
> >>>>
> >>>> Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
> >>>> ---
> >>>> Some changes:
> >>>> 1. add some comments
> >>>> 2. clean compile warning.
> >>>>
> >>>>  drivers/iommu/amd_iommu_init.c | 15 ++++++++++++++-
> >>>>  1 file changed, 14 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> >>>> index 904c575..a20af4c 100644
> >>>> --- a/drivers/iommu/amd_iommu_init.c
> >>>> +++ b/drivers/iommu/amd_iommu_init.c
> >>>> @@ -889,11 +889,24 @@ static bool copy_device_table(void)
> >>>>  	}
> >>>>  
> >>>>  	old_devtb_phys = entry & PAGE_MASK;
> >>>> +
> >>>> +	/*
> >>>> +	 *  When sme enable in the first kernel, old_devtb_phys includes the
> >>>> +	 *  memory encryption mask(sme_me_mask), we must remove the memory
> >>>> +	 *  encryption mask to obtain the true physical address in kdump mode.
> >>>> +	 */
> >>>> +	if (mem_encrypt_active() && is_kdump_kernel())
> >>>> +		old_devtb_phys = __sme_clr(old_devtb_phys);
> >>>> +
> >>>
> >>> You can probably just use "if (is_kdump_kernel())" here, since memory
> >>> encryption is either on in both the first and second kernel or off in
> >>> both the first and second kernel.  At which point __sme_clr() will do
> >>> the proper thing.
> >>>
> >>> Actually, this needs to be done no matter what.  When doing either the
> >>> ioremap_encrypted() or the memremap(), the physical address should not
> >>> include the encryption bit/mask.
> >>>
> >>> Thanks,
> >>> Tom
> >>>
> >> Thanks for your comments. If we don't remove the memory encryption mask, it will
> >> return false because the 'old_devtb_phys >= 0x100000000ULL' may become true.
> > 
> > Lianbo, you may not get what Tom suggested. Tom means no matter what it
> > is, encrypted or not in 1st kernel, we need get pure physicall address,
> > and using below code is always right for both cases.
> > 
> > 	if (is_kdump_kernel())
> > 		old_devtb_phys = __sme_clr(old_devtb_phys);
> > 
> > And this is simpler. You even can add one line of code comment to say
> > like "Physical address w/o encryption mask is needed here."
> 
> Even simpler, there's no need to even check for is_kdump_kernel().  The
> __sme_clr() should always be done if the physical address is going to be
> used for some form of io or memory remapping.
> 
> So you could just change the existing:
> 
> 	old_devtb_phys = entry & PAGE_MASK;
> 
> to:
> 
> 	old_devtb_phys = __sme_clr(entry) & PAGE_MASK;

Agree, this is even better.

> 
> >>
> >> Lianbo
> >>>>  	if (old_devtb_phys >= 0x100000000ULL) {
> >>>>  		pr_err("The address of old device table is above 4G, not trustworthy!\n");
> >>>>  		return false;
> >>>>  	}
> >>>> -	old_devtb = memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
> >>>> +	old_devtb = (mem_encrypt_active() && is_kdump_kernel())
> >>>> +		    ? (__force void *)ioremap_encrypted(old_devtb_phys,
> >>>> +							dev_table_size)
> >>>> +		    : memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);> +
> >>>>  	if (!old_devtb)
> >>>>  		return false;
> >>>>  
> >>>>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 70+ messages in thread

end of thread, other threads:[~2018-06-22  2:52 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-16  8:27 [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME) Lianbo Jiang
2018-06-16  8:27 ` Lianbo Jiang
2018-06-16  8:27 ` [PATCH 1/4 V3] Add a function(ioremap_encrypted) for kdump when AMD sme enabled Lianbo Jiang
2018-06-16  8:27   ` Lianbo Jiang
2018-06-20 16:00   ` Tom Lendacky
2018-06-20 16:00     ` Tom Lendacky
2018-06-20 16:00     ` Tom Lendacky
2018-06-21  9:13     ` lijiang
2018-06-21  9:13       ` lijiang
2018-06-21  9:13       ` lijiang
2018-06-16  8:27 ` [PATCH 2/4 V3] Allocate pages for kdump without encryption when SME is enabled Lianbo Jiang
2018-06-16  8:27   ` Lianbo Jiang
2018-06-16  8:27   ` Lianbo Jiang
2018-06-21  1:53   ` Baoquan He
2018-06-21  1:53     ` Baoquan He
2018-06-21  1:53     ` Baoquan He
2018-06-21  5:06     ` lijiang
2018-06-21  5:06       ` lijiang
2018-06-21  5:06       ` lijiang
2018-06-21 10:23       ` Baoquan He
2018-06-21 10:23         ` Baoquan He
2018-06-21 10:23         ` Baoquan He
2018-06-21 13:27         ` lijiang
2018-06-21 13:27           ` lijiang
2018-06-21 13:27           ` lijiang
2018-06-22  2:51           ` Baoquan He
2018-06-22  2:51             ` Baoquan He
2018-06-16  8:27 ` [PATCH 3/4 V3] Remap the device table of IOMMU in encrypted manner for kdump Lianbo Jiang
2018-06-16  8:27   ` Lianbo Jiang
2018-06-20 16:42   ` Tom Lendacky
2018-06-20 16:42     ` Tom Lendacky
2018-06-20 16:42     ` Tom Lendacky
2018-06-21  5:42     ` lijiang
2018-06-21  5:42       ` lijiang
2018-06-21  8:39       ` Baoquan He
2018-06-21  8:39         ` Baoquan He
2018-06-21  8:39         ` Baoquan He
2018-06-21  9:45         ` lijiang
2018-06-21  9:45           ` lijiang
2018-06-21  9:45           ` lijiang
2018-06-21 13:12         ` Tom Lendacky
2018-06-21 13:12           ` Tom Lendacky
2018-06-21 13:12           ` Tom Lendacky
2018-06-22  2:52           ` Baoquan He
2018-06-22  2:52             ` Baoquan He
2018-06-22  2:52             ` Baoquan He
2018-06-21  1:57   ` Baoquan He
2018-06-21  1:57     ` Baoquan He
2018-06-21  1:57     ` Baoquan He
2018-06-16  8:27 ` [PATCH 4/4 V3] Help to dump the old memory encrypted into vmcore file Lianbo Jiang
2018-06-16  8:27   ` Lianbo Jiang
2018-06-19  3:16   ` Dave Young
2018-06-19  3:16     ` Dave Young
2018-06-19  3:16     ` Dave Young
2018-06-19 14:46     ` lijiang
2018-06-19 14:46       ` lijiang
2018-06-20  4:50       ` lijiang
2018-06-20  4:50         ` lijiang
2018-06-20  4:50         ` lijiang
2018-06-21  2:47   ` Baoquan He
2018-06-21  2:47     ` Baoquan He
2018-06-21  1:21 ` [PATCH 0/4 V3] Support kdump for AMD secure memory encryption(SME) Baoquan He
2018-06-21  1:21   ` Baoquan He
2018-06-21  1:21   ` Baoquan He
2018-06-21  3:18   ` lijiang
2018-06-21  3:18     ` lijiang
2018-06-21  3:18     ` lijiang
2018-06-21  7:30     ` Baoquan He
2018-06-21  7:30       ` Baoquan He
2018-06-21  7:30       ` Baoquan He

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.