Blame SOURCES/v1.0.7_update.patch

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