[Crash-utility] [PATCH 5/5] memory, zram: introduce and export readswap()

HATAYAMA Daisuke d.hatayama at fujitsu.com
Sun Oct 11 01:34:38 UTC 2020


try_zram_decompress() is currently exported to extension modules, but
from a viewpoint of author of extension modules, it's better to export
an interface to read memory on swap; difference of decompressor are
then hidden within the interface and there is no need for extension
modules to update accordingly each time new decompressor are added in
the future.

So let's introduce function readswap() as an interface to read memory
on swap.

Signed-off-by: HATAYAMA Daisuke <d.hatayama at fujitsu.com>
---
 defs.h     |  1 +
 diskdump.c | 67 ++++++++++++++++++++++++++++++++++++++++++++------------------
 memory.c   |  5 ++++-
 3 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/defs.h b/defs.h
index c899fe2..8bb5618 100644
--- a/defs.h
+++ b/defs.h
@@ -6506,6 +6506,7 @@ int diskdump_kaslr_check(void);
 QEMUCPUState *diskdump_get_qemucpustate(int);
 void diskdump_device_dump_info(FILE *);
 void diskdump_device_dump_extract(int, char *, FILE *);
+ulong readswap(ulonglong pte_val, char *buf, ulong len, ulonglong vaddr);
 /*support for zram*/
 ulong try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong vaddr);
 #ifdef LZO
diff --git a/diskdump.c b/diskdump.c
index cdbc2d5..3762314 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2704,24 +2704,15 @@ lookup_swap_cache(ulonglong pte_val, unsigned char *zram_buf)
 	return NULL;
 }
 
-ulong (*decompressor)(unsigned char *in_addr, ulong in_size, unsigned char *out_addr, ulong *out_size, void *other/* NOT USED */);
-/*
- * If userspace address was swapped out to zram, this function is called to decompress the object.
- * try_zram_decompress returns decompressed page data and data length
- */
-ulong 
-try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong vaddr)
+static int get_disk_name_private_data(ulonglong pte_val,
+				       ulonglong vaddr,
+				       char *name,
+				       ulong *private_data)
 {
-	char name[32] = {0};
-	ulonglong swp_offset;
-	ulong swap_info, bdev, bd_disk, zram, zram_table_entry, sector, index, entry, flags, size, outsize, off;
-	unsigned char *obj_addr = NULL;
-	unsigned char *zram_buf = NULL;
-	unsigned char *outbuf = NULL;
+	ulong swap_info, bdev, bd_disk;
 
-	off = PAGEOFFSET(vaddr);
 	if (!symbol_exists("swap_info"))
-		return 0;
+		return FALSE;
 
 	swap_info = symbol_value("swap_info");
 
@@ -2738,16 +2729,53 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
 			sizeof(void *), "swap_info_struct_bdev", FAULT_ON_ERROR);
 	readmem(bdev + OFFSET(block_device_bd_disk), KVADDR, &bd_disk,
 			sizeof(void *), "block_device_bd_disk", FAULT_ON_ERROR);
-	readmem(bd_disk + OFFSET(gendisk_disk_name), KVADDR, name,
+	if (name)
+		readmem(bd_disk + OFFSET(gendisk_disk_name), KVADDR, name,
 			strlen("zram"), "gendisk_disk_name", FAULT_ON_ERROR);
+	if (private_data)
+		readmem(bd_disk + OFFSET(gendisk_private_data), KVADDR,
+			private_data, sizeof(void *), "gendisk_private_data",
+			FAULT_ON_ERROR);
+
+	return TRUE;
+}
+
+ulong readswap(ulonglong pte_val, char *buf, ulong len, ulonglong vaddr)
+{
+	char name[32] = {0};
 
-	if (strncmp(name, "zram", strlen("zram"))) {
+	if (!get_disk_name_private_data(pte_val, vaddr, name, NULL))
+		return 0;
+
+	if (!strncmp(name, "zram", 4)) {
+		return try_zram_decompress(pte_val,
+					   (unsigned char *)buf,
+					   len,
+					   vaddr);
+	} else {
 		if (CRASHDEBUG(2))
 			error(WARNING,
 			      "this page has been swapped to %s\n",
 			      name);
 		return 0;
 	}
+}
+
+ulong (*decompressor)(unsigned char *in_addr, ulong in_size, unsigned char *out_addr, ulong *out_size, void *other/* NOT USED */);
+/*
+ * If userspace address was swapped out to zram, this function is called to decompress the object.
+ * try_zram_decompress returns decompressed page data and data length
+ */
+ulong 
+try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong vaddr)
+{
+	char name[32] = {0};
+	ulonglong swp_offset;
+	unsigned char *obj_addr = NULL;
+	unsigned char *zram_buf = NULL;
+	unsigned char *outbuf = NULL;
+	ulong zram, zram_table_entry, sector, index, entry, flags, size,
+		outsize, off;
 
 	if (INVALID_MEMBER(zram_compressor)) {
 		zram_init();
@@ -2763,8 +2791,8 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
 	if (CRASHDEBUG(2))
 		error(WARNING, "this page has swapped to zram\n");
 
-	readmem(bd_disk + OFFSET(gendisk_private_data), KVADDR, &zram,
-		sizeof(void *), "gendisk_private_data", FAULT_ON_ERROR);
+	if (!get_disk_name_private_data(pte_val, vaddr, NULL, &zram))
+		return 0;
 
 	readmem(zram + OFFSET(zram_compressor), KVADDR, name,
 		sizeof(name), "zram compressor", FAULT_ON_ERROR);
@@ -2789,6 +2817,7 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
 
 	zram_buf = (unsigned char *)GETBUF(PAGESIZE());
 	/*lookup page from swap cache*/
+	off = PAGEOFFSET(vaddr);
 	obj_addr = lookup_swap_cache(pte_val, zram_buf);
 	if (obj_addr != NULL) {
 		memcpy(buf, obj_addr + off, len);
diff --git a/memory.c b/memory.c
index c951827..44213bb 100644
--- a/memory.c
+++ b/memory.c
@@ -2296,7 +2296,10 @@ readmem(ulonglong addr, int memtype, void *buffer, long size,
 					if (cnt > size)
 						cnt = size;
 
-					cnt = try_zram_decompress(paddr, (unsigned char *)bufptr, cnt, addr);
+					cnt = readswap(addr,
+						       bufptr,
+						       cnt,
+						       addr);
 					if (cnt) {
 						bufptr += cnt;
 						addr += cnt;
-- 
1.8.3.1




More information about the Crash-utility mailing list