From mboxrd@z Thu Jan 1 00:00:00 1970 From: dbrace Subject: Re: kmap_atomic issue with SLES11SP1 32bit XEN driver code Date: Wed, 14 Dec 2011 18:47:54 -0600 Message-ID: <4EE943BA.6010202@hp.com> References: <4EDFDF0D.2020104@hp.com> <4EE628D80200007800066F9E@nat28.tlf.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <4EE628D80200007800066F9E@nat28.tlf.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Jan Beulich Cc: xen-devel@lists.xensource.com, "scameron@beardog.cce.hp.com" List-Id: xen-devel@lists.xenproject.org >>... without knowing where you got physical_address from it's impossible >>to tell whether your problem is that under Xen physical and machine >>(sometimes called "bus") addresses being distinct (end hence you're ??possibly lacking a translation between the two). Is there a way to tell from the address is this is happening? On 12/12/2011 09:16 AM, Jan Beulich wrote: >>>> On 07.12.11 at 22:47, 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 > Pretty outdated. > >> 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().) > For a valid high memory page this is surely not being returned by > kmap_atomic(), so we have to assume that what you started with is > the address of a low memory one. > >> 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? > No, but ... > >> 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? > PageHighMem(). > >> 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); > ... without knowing where you got physical_address from it's impossible > to tell whether your problem is that under Xen physical and machine > (sometimes called "bus") addresses being distinct (end hence you're > possibly lacking a translation between the two). > > Jan > >> 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 > > -- Don Brace SPSN Linux Development Hewlett-Packard Company