When I tested it, it also applies for reading.

    sudo dd if=/dev/mem bs=1 count=1 skip=$ADDR

This was a 32-bit Ubuntu 12.04 Live CD on a 64-bit desktop machine. ADDR
is any address higher than or equal to 0xf7bfe000 (see below).

Using strace and writing a minimalistic C program, I could verify that
open() and _llseek() works, but that read() fails with -EFAULT.

>From the static read_mem function in drivers/char/mem.c at
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/char/mem.c;h=e5eedfa24c91010bd8358db7b7076e4f0af6ad1b;hb=HEAD#l96
there are three places where -EFAULT could be returned. But when using read(fd, 
buffer, 0), only the below is supposed to give issues:

103         if (!valid_phys_addr_range(p, count))
104                 return -EFAULT;

Since ARCH_HAS_VALID_PHYS_ADDR_RANGE is not set for x86, valid_phys_addr_range 
is:
 49 static inline int valid_phys_addr_range(unsigned long addr, size_t count)
 50 {
 51         return addr + count <= __pa(high_memory);
 52 }

A simple module that includes linux/mm.h can read the values from memory:
high_memory is a void pointer to 0xf7bfe000
__pa(high_memory) is an unsigned long that contains 0x37bfe000
Obviously, the ASL address that we are trying to read is highjer than that and 
thus the read fails with -EFAULT.

http://lxr.free-electrons.com/source/arch/x86/include/asm/page.h#L36
 36 #define __pa(x)         __phys_addr((unsigned long)(x))

http://lxr.free-electrons.com/source/arch/x86/mm/physaddr.c#L11
basically x - PAGE_OFFSET

Since the CONFIG_X86_64 is not set, the file that is included by page_types.h:
http://lxr.free-electrons.com/source/arch/x86/include/asm/page_32_types.h#L16
#define __PAGE_OFFSET           _AC(CONFIG_PAGE_OFFSET, UL)

.config (or /boot/config-...) contains CONFIG_PAGE_OFFSET=0xC0000000
which is exactly the difference above.

So far the analysis. I don't know if there is a solution available for
/dev/mem.

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1037094

Title:
  "writing `/dev/mem': Bad address" Error writing to ACPI area with 32
  bit kernel

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1037094/+subscriptions

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to