Mailing List Archive

Re: kmap_atomic issue with SLES11SP1 32bit XEN driver code
On Wed, Dec 07, 2011 at 03:47:57PM -0600, dbrace wrote:
> 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);

Just to be clear, it's these memcpy's that get the BUG, correct?

-- steve


>
> 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
Re: kmap_atomic issue with SLES11SP1 32bit XEN driver code [ In reply to ]
Yes

On 12/07/2011 03:52 PM, scameron@beardog.cce.hp.com wrote:
> On Wed, Dec 07, 2011 at 03:47:57PM -0600, dbrace wrote:
>> 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);
> Just to be clear, it's these memcpy's that get the BUG, correct?
>
> -- steve
>
>
>> 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

--
Don Brace
SPSN Linux Development
Hewlett-Packard Company

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel