Skip to content

Commit

Permalink
s390/nvme: support firmware-assisted dump to NVMe disks
Browse files Browse the repository at this point in the history
From the kernel perspective NVMe dump works exactly like zFCP dump.
Therefore, adapt all places where code explicitly tests only for
IPL of type FCP DUMP. And also set the memory end correctly in this case.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
  • Loading branch information
Alexander Egorenkov authored and Vasily Gorbik committed Oct 2, 2020
1 parent d9f12e4 commit bd37b36
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 25 deletions.
15 changes: 12 additions & 3 deletions arch/s390/boot/ipl_parm.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,23 @@ void parse_boot_command_line(void)
}
}

static inline bool is_ipl_block_dump(void)
{
if (ipl_block.pb0_hdr.pbt == IPL_PBT_FCP &&
ipl_block.fcp.opt == IPL_PB0_FCP_OPT_DUMP)
return true;
if (ipl_block.pb0_hdr.pbt == IPL_PBT_NVME &&
ipl_block.nvme.opt == IPL_PB0_NVME_OPT_DUMP)
return true;
return false;
}

void setup_memory_end(void)
{
#ifdef CONFIG_CRASH_DUMP
if (OLDMEM_BASE) {
kaslr_enabled = 0;
} else if (ipl_block_valid &&
ipl_block.pb0_hdr.pbt == IPL_PBT_FCP &&
ipl_block.fcp.opt == IPL_PB0_FCP_OPT_DUMP) {
} else if (ipl_block_valid && is_ipl_block_dump()) {
kaslr_enabled = 0;
if (!sclp_early_get_hsa_size(&memory_end) && memory_end)
memory_end_set = 1;
Expand Down
6 changes: 6 additions & 0 deletions arch/s390/include/asm/ipl.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ extern struct ipl_info ipl_info;
extern void setup_ipl(void);
extern void set_os_info_reipl_block(void);

static inline bool is_ipl_type_dump(void)
{
return (ipl_info.type == IPL_TYPE_FCP_DUMP) ||
(ipl_info.type == IPL_TYPE_NVME_DUMP);
}

struct ipl_report {
struct ipl_parameter_block *ipib;
struct list_head components;
Expand Down
16 changes: 8 additions & 8 deletions arch/s390/kernel/crash_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count)
while (count) {
from = __pa(src);
if (!OLDMEM_BASE && from < sclp.hsa_size) {
/* Copy from zfcpdump HSA area */
/* Copy from zfcp/nvme dump HSA area */
len = min(count, sclp.hsa_size - from);
rc = memcpy_hsa_kernel(dst, from, len);
if (rc)
Expand Down Expand Up @@ -184,7 +184,7 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count)
while (count) {
from = __pa(src);
if (!OLDMEM_BASE && from < sclp.hsa_size) {
/* Copy from zfcpdump HSA area */
/* Copy from zfcp/nvme dump HSA area */
len = min(count, sclp.hsa_size - from);
rc = memcpy_hsa_user(dst, from, len);
if (rc)
Expand Down Expand Up @@ -258,7 +258,7 @@ static int remap_oldmem_pfn_range_kdump(struct vm_area_struct *vma,
}

/*
* Remap "oldmem" for zfcpdump
* Remap "oldmem" for zfcp/nvme dump
*
* We only map available memory above HSA size. Memory below HSA size
* is read on demand using the copy_oldmem_page() function.
Expand All @@ -283,7 +283,7 @@ static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct *vma,
}

/*
* Remap "oldmem" for kdump or zfcpdump
* Remap "oldmem" for kdump or zfcp/nvme dump
*/
int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from,
unsigned long pfn, unsigned long size, pgprot_t prot)
Expand Down Expand Up @@ -632,11 +632,11 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
u32 alloc_size;
u64 hdr_off;

/* If we are not in kdump or zfcpdump mode return */
if (!OLDMEM_BASE && ipl_info.type != IPL_TYPE_FCP_DUMP)
/* If we are not in kdump or zfcp/nvme dump mode return */
if (!OLDMEM_BASE && !is_ipl_type_dump())
return 0;
/* If we cannot get HSA size for zfcpdump return error */
if (ipl_info.type == IPL_TYPE_FCP_DUMP && !sclp.hsa_size)
/* If we cannot get HSA size for zfcp/nvme dump return error */
if (is_ipl_type_dump() && !sclp.hsa_size)
return -ENODEV;

/* For kdump, exclude previous crashkernel memory */
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ static void __init conmode_default(void)
#ifdef CONFIG_CRASH_DUMP
static void __init setup_zfcpdump(void)
{
if (ipl_info.type != IPL_TYPE_FCP_DUMP)
if (!is_ipl_type_dump())
return;
if (OLDMEM_BASE)
return;
Expand Down Expand Up @@ -1175,7 +1175,7 @@ void __init setup_arch(char **cmdline_p)
if (IS_ENABLED(CONFIG_EXPOLINE))
nospec_init_branches();

/* Setup zfcpdump support */
/* Setup zfcp/nvme dump support */
setup_zfcpdump();

/* Add system specific data to the random pool */
Expand Down
12 changes: 6 additions & 6 deletions arch/s390/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,14 +606,14 @@ int smp_store_status(int cpu)
/*
* Collect CPU state of the previous, crashed system.
* There are four cases:
* 1) standard zfcp dump
* condition: OLDMEM_BASE == NULL && ipl_info.type == IPL_TYPE_FCP_DUMP
* 1) standard zfcp/nvme dump
* condition: OLDMEM_BASE == NULL && is_ipl_type_dump() == true
* The state for all CPUs except the boot CPU needs to be collected
* with sigp stop-and-store-status. The boot CPU state is located in
* the absolute lowcore of the memory stored in the HSA. The zcore code
* will copy the boot CPU state from the HSA.
* 2) stand-alone kdump for SCSI (zfcp dump with swapped memory)
* condition: OLDMEM_BASE != NULL && ipl_info.type == IPL_TYPE_FCP_DUMP
* 2) stand-alone kdump for SCSI/NVMe (zfcp/nvme dump with swapped memory)
* condition: OLDMEM_BASE != NULL && is_ipl_type_dump() == true
* The state for all CPUs except the boot CPU needs to be collected
* with sigp stop-and-store-status. The firmware or the boot-loader
* stored the registers of the boot CPU in the absolute lowcore in the
Expand Down Expand Up @@ -660,7 +660,7 @@ void __init smp_save_dump_cpus(void)
unsigned long page;
bool is_boot_cpu;

if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP))
if (!(OLDMEM_BASE || is_ipl_type_dump()))
/* No previous system present, normal boot. */
return;
/* Allocate a page as dumping area for the store status sigps */
Expand All @@ -686,7 +686,7 @@ void __init smp_save_dump_cpus(void)
/* Get the vector registers */
smp_save_cpu_vxrs(sa, addr, is_boot_cpu, page);
/*
* For a zfcp dump OLDMEM_BASE == NULL and the registers
* For a zfcp/nvme dump OLDMEM_BASE == NULL and the registers
* of the boot CPU are stored in the HSA. To retrieve
* these registers an SCLP request is required which is
* done by drivers/s390/char/zcore.c:init_cpu_info()
Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/char/sclp_sdias.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ static int __init sclp_sdias_init_async(void)

int __init sclp_sdias_init(void)
{
if (ipl_info.type != IPL_TYPE_FCP_DUMP)
if (!is_ipl_type_dump())
return 0;
sclp_sdias_sccb = (void *) __get_free_page(GFP_KERNEL | GFP_DMA);
BUG_ON(!sclp_sdias_sccb);
Expand Down
17 changes: 12 additions & 5 deletions drivers/s390/char/zcore.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-1.0+
/*
* zcore module to export memory content and register sets for creating system
* dumps on SCSI disks (zfcpdump).
* dumps on SCSI/NVMe disks (zfcp/nvme dump).
*
* For more information please refer to Documentation/s390/zfcpdump.rst
*
Expand Down Expand Up @@ -243,7 +243,7 @@ static int __init zcore_init(void)
unsigned char arch;
int rc;

if (ipl_info.type != IPL_TYPE_FCP_DUMP)
if (!is_ipl_type_dump())
return -ENODATA;
if (OLDMEM_BASE)
return -ENODATA;
Expand All @@ -252,9 +252,16 @@ static int __init zcore_init(void)
debug_register_view(zcore_dbf, &debug_sprintf_view);
debug_set_level(zcore_dbf, 6);

TRACE("devno: %x\n", ipl_info.data.fcp.dev_id.devno);
TRACE("wwpn: %llx\n", (unsigned long long) ipl_info.data.fcp.wwpn);
TRACE("lun: %llx\n", (unsigned long long) ipl_info.data.fcp.lun);
if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
TRACE("type: fcp\n");
TRACE("devno: %x\n", ipl_info.data.fcp.dev_id.devno);
TRACE("wwpn: %llx\n", (unsigned long long) ipl_info.data.fcp.wwpn);
TRACE("lun: %llx\n", (unsigned long long) ipl_info.data.fcp.lun);
} else if (ipl_info.type == IPL_TYPE_NVME_DUMP) {
TRACE("type: nvme\n");
TRACE("fid: %x\n", ipl_info.data.nvme.fid);
TRACE("nsid: %x\n", ipl_info.data.nvme.nsid);
}

rc = sclp_sdias_init();
if (rc)
Expand Down

0 comments on commit bd37b36

Please sign in to comment.