Dheeraj Sangamkar wrote:
Thanks a million Dave,
I will try using the kprobes approach.
One thing I neglected to mention re: the usage of /dev/mem.
Another restriction it has always had (not just in Red Hat
kernels) is this:
static ssize_t read_mem(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
ssize_t read, sz;
char *ptr;
if (!valid_phys_addr_range(p, count))
return -EFAULT;
where valid_phys_addr_range() on an x86 restricts access
to lowmem, i.e. the first 896MB of physical memory:
static inline int valid_phys_addr_range(unsigned long addr, size_t count)
{
if (addr + count > __pa(high_memory))
return 0;
return 1;
}
So if you need to look at a piece of memory above that,
"crash /dev/mem" will fail. Normally that's not a problem,
if you're trying to access unity-mapped kernel virtual
memory, i.e., where static kernel data, slab data, etc.
exist. But if it's a user-space address, or a mapped vmalloc()
address, and the PTE's needed to translate that virtual
address exist in highmem, then the physical location
cannot be determined.
That's always been a weakness with the /dev/mem driver,
and again, I don't exactly know why. The /dev/crash
driver doesn't make the restriction, and AFAICT if the
valid_phys_addr_range() could be also be kprobe'd to return
a 1, then it would mimic /dev/crash. But it gets inlined
and it's certainly not nearly as simple as the devmem_is_allowed()
probe. It may be possible, but I don't know how...
Anyway, getting back to your original example:
crash> struct request_queue 0xf7b933f8
struct request_queue {
queue_head = {
<SNIP>
...
}
It's not clear to me whether 0xf7b933f8 is a vmalloc()
address (like from a module) or right on the edge of
being at the very top of unity-mapped memory. If it's
a mapped vmalloc() address, then the kprobes hack
won't work "out of the box". You may have first run
crash with /dev/crash, do a vtop on the vmalloc address
to find its physical address, and then *only* if the
physical address is in lowmem, will you be able to
then subsequently do the kprobes workaround, using
"wr -p" to specify the physical address instead of
the virtual address.
Or reboot your kernel with "mem=896m" to keep all
physical memory below 896MB.
Clear as mud?
Dave
Dave