kernel: Linux 360 2.6.32.12-0.7-xen #1 SMP 2010-05-20 11:14:20 +0200
i686 i686 i386 GNU/Linux
I am having issues with some code that uses kmap_atomic(). I am getting:
BUG: unable to handle kernel paging request at 23a1a000 (which is the
address returned from kmap_atomic().)
The same code works when running on non-XEN 32bit kernels so I am
wondering why this does not work under
XEN kernels. Is there a different approach that I need to take for 32bit
XEN kernels?
I really only need to do this code segment if the memory address is a
high memory address. Is there a MACRO or function
that can help me determine this?
Here is a code snippet:
void *linux_vaddr = NULL; /* kmapped temporary
virtual address */
int linux_page_offset = 0; /* offset in page */
int count = 0; /* bytes left to
transfer */
int left = byte_count; /* number of bytes left
to transfer */
int memcpysize = 0; /* current size to
transfer */
struct page *linux_page = NULL; /* calculated page */
int kmap_flags = 0;
linux_page = __pfn_to_page(physical_address >> PAGE_SHIFT);
linux_page_offset = (physical_address &
0x0000000000000FFFULL);
memcpysize = min((PAGE_SIZE - linux_page_offset), left);
kmap_flags = KM_USER0;
linux_vaddr = kmap_atomic(linux_page, kmap_flags) +
linux_page_offset;
printk("%s: called kmap_atomic, "
"calling memcpy linux_vaddr = 0x%x virt_address
= 0x%x count = 0x%x\n",
__func__, linux_vaddr, virt_address, count);
/*
* Either need to copy to a kmapped destination
* or a kmapped source.
*/
if (type == 0) // Write to s/g element, dest virtual
addr was known.
memcpy((void *)virt_address+count, (void
*)linux_vaddr, memcpysize);
else // Source virt. address was known.
memcpy((void *)linux_vaddr, (void
*)virt_address+count, memcpysize);
printk("OS_Linux32_Xfer_SG_Page: calling kunmap_atomic, "
"calling memcpy linux_vaddr = 0x%lx\n",
linux_vaddr);
kunmap_atomic(linux_vaddr, kmap_flags);
--
Don Brace
SPSN Linux Development
Hewlett-Packard Company
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
i686 i686 i386 GNU/Linux
I am having issues with some code that uses kmap_atomic(). I am getting:
BUG: unable to handle kernel paging request at 23a1a000 (which is the
address returned from kmap_atomic().)
The same code works when running on non-XEN 32bit kernels so I am
wondering why this does not work under
XEN kernels. Is there a different approach that I need to take for 32bit
XEN kernels?
I really only need to do this code segment if the memory address is a
high memory address. Is there a MACRO or function
that can help me determine this?
Here is a code snippet:
void *linux_vaddr = NULL; /* kmapped temporary
virtual address */
int linux_page_offset = 0; /* offset in page */
int count = 0; /* bytes left to
transfer */
int left = byte_count; /* number of bytes left
to transfer */
int memcpysize = 0; /* current size to
transfer */
struct page *linux_page = NULL; /* calculated page */
int kmap_flags = 0;
linux_page = __pfn_to_page(physical_address >> PAGE_SHIFT);
linux_page_offset = (physical_address &
0x0000000000000FFFULL);
memcpysize = min((PAGE_SIZE - linux_page_offset), left);
kmap_flags = KM_USER0;
linux_vaddr = kmap_atomic(linux_page, kmap_flags) +
linux_page_offset;
printk("%s: called kmap_atomic, "
"calling memcpy linux_vaddr = 0x%x virt_address
= 0x%x count = 0x%x\n",
__func__, linux_vaddr, virt_address, count);
/*
* Either need to copy to a kmapped destination
* or a kmapped source.
*/
if (type == 0) // Write to s/g element, dest virtual
addr was known.
memcpy((void *)virt_address+count, (void
*)linux_vaddr, memcpysize);
else // Source virt. address was known.
memcpy((void *)linux_vaddr, (void
*)virt_address+count, memcpysize);
printk("OS_Linux32_Xfer_SG_Page: calling kunmap_atomic, "
"calling memcpy linux_vaddr = 0x%lx\n",
linux_vaddr);
kunmap_atomic(linux_vaddr, kmap_flags);
--
Don Brace
SPSN Linux Development
Hewlett-Packard Company
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel