Bug 492803

Summary: Please disable CONFIG_STRICT_DEVMEM
Product: [Fedora] Fedora Reporter: Lubomir Rintel <lkundrak>
Component: kernelAssignee: Kernel Maintainer List <kernel-maint>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: rawhideCC: anderson, jlayton, kernel-maint, quintela
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2009-04-24 14:28:31 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Lubomir Rintel 2009-03-29 19:41:56 UTC
Description of problem:

Crash tool does not work against live kernel when CONFIG_STRICT_DEVMEM is enabled, since it uselessly limits /dev/mem to 1M.

Version-Release number of selected component (if applicable):

2.6.29-16.fc11.i586

Steps to Reproduce:

# crash -d7 /usr/lib/debug/lib/modules/2.6.29-16.fc11.i586/vmlinux 
...
<readmem: c0abb600, KVADDR, "xtime", 8, (FOE), 84305d8>
/dev/mem: Operation not permitted
crash: read(/dev/mem, abb600, 0): 8 (ffffffff)
crash: read error: kernel virtual address: c0abb600  type: "xtime"

dmesg:
Program crash tried to access /dev/mem between abb000->abb008.

Comment 1 Chuck Ebbert 2009-03-31 04:36:02 UTC
A boot parameter has been added: strict-devmem=0 will disable it now.

Comment 2 Lubomir Rintel 2009-03-31 14:26:33 UTC
Chuck: perfect, thanks!
By the way -- anyone knows why doesn't crash use /proc/kcore?

Comment 3 Dave Anderson 2009-03-31 14:44:38 UTC
Just curious -- why was the crash driver module dropped?

* Thu Mar 12 2009 Dave Jones <davej@redhat.com>
- Drop no longer needed 'crash' driver.

The strict-devmem parameter is a nice solution, although even with it in place,
/dev/mem will still not allow x86 32-bit memory accesses above highmem.  So
module memory access, user memory access, PTEs, etc., anything that's not
GFP_KERNEL will not be accessible.

> By the way -- anyone knows why doesn't crash use /proc/kcore? 

Couple reasons, one being that /proc/kcore doesn't exist in RHEL.

But even if it did, it's a kernel virtual memory accessor, whereas crash
translates all memory accesses to physical addresses prior to reading them
from whatever the memory-access handler is, i.e., live memory or the plethora
of dumpfile formats it supports.

Comment 4 Dave Jones 2009-04-01 14:55:17 UTC
I was under the mistaken impression that crash would work on /dev/mem
I was unaware of the 32bit limitations. How much work would it be to make /dev/mem use kmaps ?
(Essentially folding bits of /dev/crash into /dev/mem).

I'm not opposed to adding back the crash driver, but I'd like some sort of plan where we can get it upstream, so we don't have to carry it forever.

Comment 5 Dave Anderson 2009-04-01 15:38:11 UTC
(In reply to comment #4)
> I was under the mistaken impression that crash would work on /dev/mem
> I was unaware of the 32bit limitations. How much work would it be to make
> /dev/mem use kmaps ?
> (Essentially folding bits of /dev/crash into /dev/mem).

Crash on x86 with /dev/mem will at least come up to its prompt, and as long
as only lowmem addresses are required, most crash commands will work OK.
But if the system has more than 896MB, then in all probability the highmem
memory will have been used for kernel modules, PTE contents, and user-space.
That being the case, kernel module debugging will be unavailable, and
less importantly, user-space access won't be available.  There are other
things that won't work, but I can't remember them off-hand.

Anyway, there's a couple gotcha's upstream.

The first thing /dev/mem's read_mem() function does is:

  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;

which has the high_memory restriction:

  #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
  static inline int valid_phys_addr_range(unsigned long addr, size_t count)  
  {
          if (addr + count > __pa(high_memory))
                  return 0;

          return 1;
  }

And that restriction would also be affected by systems with more than
4GB of physical memory -- note that the "p" assignment is an unsigned
long, so it would clip off the upper 32 bits from "loff_t *ppos".

And then the unsigned long "p" is used in a few other places further on in read_mem(), so dealing with that could get ugly...

Secondly, the physical page mapping/copying is done like so:

                ptr = xlate_dev_mem_ptr(p);
                if (!ptr)
                        return -EFAULT;

                if (copy_to_user(buf, ptr, sz)) {
                        unxlate_dev_mem_ptr(p, ptr);
                        return -EFAULT;
                }

                unxlate_dev_mem_ptr(p, ptr);

where xlate_dev_mem_ptr() for x86 only works for lowmem physical addrs:

  #define xlate_dev_mem_ptr(p)    __va(p)

and unxlate_dev_mem_ptr() also has to deal with non-RAM addresses:

  void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
  {
          if (page_is_ram(phys >> PAGE_SHIFT))
                  return;

          iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
          return;
  }

> I'm not opposed to adding back the crash driver, but I'd like some sort of
> plan where we can get it upstream, so we don't have to carry it forever.  

So to be honest, for the remainder of the x86 life-form, it's probably
easier to carry forward the crash driver for x86.

Bernhard Walle tried to get a patch similar in nature to the "strict-devmem"
concept upstream a few months ago, but got nowhere.

Comment 6 Dave Jones 2009-04-24 14:28:31 UTC
re-added the crash driver.