Blame SOURCES/v1.0.7_update.patch

9e423b
9e423b
ptdump could fail with the following error message:
9e423b
9e423b
    ptdump: invalid size request: 0 type: "read page for write"
9e423b
9e423b
This is because there is lack of consideration in function
9e423b
write_buffer_wrapped() that there is possibility that current write
9e423b
position in the corresponding ring buffer could be just on
9e423b
page-aligned offset. Then, read size for the 3rd write operation
9e423b
becomes 0 bytes and then readmem() accepting the 0 bytes in the 4th
9e423b
argument results in the error with the above error message.
9e423b
9e423b
More concretely, function write_buffer_wrapped() retrieves and writes
9e423b
data on the corresponding ring buffer in 3 write operations as the
9e423b
following picture:
9e423b
9e423b
           current write position
9e423b
      (2)           (3)  | (1)
9e423b
     <-----------> <---> v <----------->
9e423b
    +-------------+---------+----------+
9e423b
    |             |         |          |
9e423b
    |             |    P    |          |
9e423b
    |             |         |          |
9e423b
    +-------------+---------+----------+
9e423b
9e423b
The largest square is the corresponding ring buffer containing the
9e423b
trace data collected by Intel PT. The downward arrow illustrates the
9e423b
current write position, i.e. the offset of the write operation() at
9e423b
the timing when system panic occurs and crash dump is collected. The
9e423b
small square containing the letter 'P' is the page where the current
9e423b
write position belongs to. ptdump retrieves and writes the data in
9e423b
this ring buffer in the order of (1), (2) and (3), i.e. from old to
9e423b
new data.
9e423b
9e423b
Then, note that when the current write position is on the page-aligned
9e423b
offset, there is no square containing 'P' as:
9e423b
9e423b
          current write position
9e423b
      (2)          | (1)
9e423b
     <------------>v<----------->
9e423b
    +-------------++------------+
9e423b
    |             ||            |
9e423b
    |             ||            |
9e423b
    |             ||            |
9e423b
    +-------------++------------+
9e423b
9e423b
and then the write size for the write operation (3) becomes 0 bytes,
9e423b
meaning that the write operation (3) is unnecessary in this case.
9e423b
9e423b
9e423b
9e423b
--- ptdump-1.0.3/ptdump.c.orig
9e423b
+++ ptdump-1.0.3/ptdump.c
9e423b
@@ -72,7 +72,7 @@ get_member(ulong addr, char *name, char
9e423b
 	size = MEMBER_SIZE(name, member);
9e423b
 
9e423b
 
9e423b
-	if (!readmem(addr + offset, KVADDR, buf, size, name, FAULT_ON_ERROR))
9e423b
+	if (!readmem(addr + offset, KVADDR, buf, size, name, RETURN_ON_ERROR))
9e423b
 		return FALSE;
9e423b
 
9e423b
 	return TRUE;
9e423b
@@ -162,7 +162,7 @@ int init_pt_info(int cpu)
9e423b
 		ulong page;
9e423b
 
9e423b
 		if (!readmem(pgaddr, KVADDR, &page, sizeof(ulong),
9e423b
-			     "struct page", FAULT_ON_ERROR))
9e423b
+			     "struct page", RETURN_ON_ERROR))
9e423b
 			continue;
9e423b
 
9e423b
 		pt_info_ptr->buffer_ptr[i] = page;
9e423b
@@ -194,7 +194,7 @@ int init_pt_info(int cpu)
9e423b
 	/* Read topa entry */
9e423b
 	if (!readmem((topa_base) + topa_idx*(sizeof(struct topa_entry)),
9e423b
 		     KVADDR, &topa, sizeof(topa),
9e423b
-		     "struct topa_entry", FAULT_ON_ERROR)) {
9e423b
+		     "struct topa_entry", RETURN_ON_ERROR)) {
9e423b
 		fprintf(fp, "Cannot read topa table\n");
9e423b
 		goto out_error;
9e423b
 	}
9e423b
@@ -230,7 +230,8 @@ int init_pt_info(int cpu)
9e423b
 out_error:
9e423b
 	if (pt_info_ptr->buffer_ptr != NULL)
9e423b
 		free(pt_info_ptr->buffer_ptr);
9e423b
-		return FALSE;
9e423b
+
9e423b
+	return FALSE;
9e423b
 }
9e423b
 
9e423b
 static inline int is_zero_page(ulong page, int offset)
9e423b
@@ -247,8 +248,11 @@ static inline int is_zero_page(ulong pag
9e423b
 
9e423b
 	memset(buf, 0, PAGESIZE());
9e423b
 	dbgprintf(fp, "zero page chk: 0x%016lx, %lu\n", read_addr, read_size);
9e423b
-	readmem(read_addr, KVADDR, buf, read_size, "zero page check",
9e423b
-	        FAULT_ON_ERROR);
9e423b
+	if (!readmem(read_addr, KVADDR, buf, read_size, "zero page check",
9e423b
+		     RETURN_ON_ERROR)) {
9e423b
+		free(buf);
9e423b
+		return FALSE;
9e423b
+	}
9e423b
 
9e423b
 	for (i = 0; i < PAGESIZE() - offset; i++) {
9e423b
 		if (buf[i]) {
9e423b
@@ -312,8 +316,11 @@ int write_buffer_wrapped(int cpu, FILE *
9e423b
 		page = pt_info_ptr->buffer_ptr[idx];
9e423b
 		len = PAGESIZE() - offset;
9e423b
 
9e423b
-		readmem(page + offset, KVADDR, buf, len, "read page for write",
9e423b
-			FAULT_ON_ERROR);
9e423b
+		if (!readmem(page + offset, KVADDR, buf, len, "read page for write",
9e423b
+			     RETURN_ON_ERROR)) {
9e423b
+			free(buf);
9e423b
+			return FALSE;
9e423b
+		}
9e423b
 
9e423b
 		dbgprintf(fp, "[%d] R/W1 buff: p=0x%lx, i=%d, o=%lu, l=%d\n",
9e423b
 			cpu, page + offset, idx, offset, len);
9e423b
@@ -332,8 +339,11 @@ int write_buffer_wrapped(int cpu, FILE *
9e423b
 		page = pt_info_ptr->buffer_ptr[idx];
9e423b
 		len = PAGESIZE() - offset;
9e423b
 
9e423b
-		readmem(page + offset, KVADDR, buf, len, "read page for write",
9e423b
-			FAULT_ON_ERROR);
9e423b
+		if (!readmem(page + offset, KVADDR, buf, len, "read page for write",
9e423b
+			     RETURN_ON_ERROR)) {
9e423b
+			free(buf);
9e423b
+			return FALSE;
9e423b
+		}
9e423b
 
9e423b
 		dbgprintf(fp, "[%d] R/W2 buff: p=0x%lx, i=%d, o=%lu, l=%d\n",
9e423b
 			cpu, page + offset, idx, offset, len);
9e423b
@@ -351,8 +361,14 @@ int write_buffer_wrapped(int cpu, FILE *
9e423b
 	offset = pt_info_ptr->output_off & mask;
9e423b
 	len = offset;
9e423b
 
9e423b
-	readmem(page, KVADDR, buf, len, "read page for write",
9e423b
-		FAULT_ON_ERROR);
9e423b
+	if (!len)
9e423b
+		goto done;
9e423b
+
9e423b
+	if (!readmem(page, KVADDR, buf, len, "read page for write",
9e423b
+		     RETURN_ON_ERROR)) {
9e423b
+		free(buf);
9e423b
+		return FALSE;
9e423b
+	}
9e423b
 
9e423b
 	dbgprintf(fp, "[%d] R/W3 buff: p=0x%lx, i=%d, o=%lu, l=%d\n", cpu,
9e423b
 		page, idx, offset, len);
9e423b
@@ -364,6 +380,7 @@ int write_buffer_wrapped(int cpu, FILE *
9e423b
 		return FALSE;
9e423b
 	}
9e423b
 
9e423b
+done:
9e423b
 	free(buf);
9e423b
 	return TRUE;
9e423b
 }
9e423b
@@ -388,8 +405,11 @@ int write_buffer_nowrapped(int cpu, FILE
9e423b
 		page = pt_info_ptr->buffer_ptr[idx];
9e423b
 		len = PAGESIZE();
9e423b
 
9e423b
-		readmem(page, KVADDR, buf, len, "read page for write",
9e423b
-			FAULT_ON_ERROR);
9e423b
+		if (!readmem(page, KVADDR, buf, len, "read page for write",
9e423b
+			     RETURN_ON_ERROR)) {
9e423b
+			free(buf);
9e423b
+			return FALSE;
9e423b
+		}
9e423b
 
9e423b
 		dbgprintf(fp, "[%d] R/W1 buff: p=0x%lx, i=%d, o=%lu, l=%d\n",
9e423b
 			cpu, page, idx, (ulong)0, len);
9e423b
@@ -406,8 +426,14 @@ int write_buffer_nowrapped(int cpu, FILE
9e423b
 	page = pt_info_ptr->buffer_ptr[idx];
9e423b
 	len = pt_info_ptr->output_off & mask;
9e423b
 
9e423b
-	readmem(page, KVADDR, buf, len, "read page for write",
9e423b
-		FAULT_ON_ERROR);
9e423b
+	if (!len)
9e423b
+		goto done;
9e423b
+
9e423b
+	if (!readmem(page, KVADDR, buf, len, "read page for write",
9e423b
+		     RETURN_ON_ERROR)) {
9e423b
+		free(buf);
9e423b
+		return FALSE;
9e423b
+	}
9e423b
 
9e423b
 	dbgprintf(fp, "[%d] R/W2 buff: p=0x%lx, i=%d, o=%lu, l=%d\n", cpu,
9e423b
 		page, idx, (ulong)0, len);
9e423b
@@ -419,6 +445,7 @@ int write_buffer_nowrapped(int cpu, FILE
9e423b
 		return FALSE;
9e423b
 	}
9e423b
 
9e423b
+done:
9e423b
 	free(buf);
9e423b
 	return TRUE;
9e423b
 }
9e423b
@@ -491,6 +518,9 @@ cmd_ptdump(void)
9e423b
 	if (argcnt != 2)
9e423b
 		cmd_usage(pc->curcmd, SYNOPSIS);
9e423b
 
9e423b
+	if (ACTIVE())
9e423b
+		error(FATAL, "not supported on a live system\n");
9e423b
+
9e423b
 	outdir = args[1];
9e423b
 	if ((ret = mkdir(outdir, mode))) {
9e423b
 		fprintf(fp, "Cannot create directory %s: %d\n", outdir, ret);
9e423b
@@ -502,12 +532,12 @@ cmd_ptdump(void)
9e423b
 		return;
9e423b
 	}
9e423b
 
9e423b
-	/* 
9e423b
-	 * Set the gdb scope to ensure that the appropriate ring_buffer 
9e423b
-	 * structure is selected. 
9e423b
+	/*
9e423b
+	 * Set the gdb scope to ensure that the appropriate ring_buffer
9e423b
+	 * structure is selected.
9e423b
 	 */
9e423b
 	if (kernel_symbol_exists("perf_mmap_to_page"))
9e423b
-		gdb_set_crash_scope(symbol_value("perf_mmap_to_page"), 
9e423b
+		gdb_set_crash_scope(symbol_value("perf_mmap_to_page"),
9e423b
 			"perf_mmap_to_page");
9e423b
 
9e423b
 	online_cpus = get_cpus_online();