Guanglin Xu
2013-Jul-27 12:03 UTC
IOCTL_PRIVCMD_MMAPBATCH can''t mmap more than 160 pages?
Hi,
I want to map the whole guest memory by xc_map_foreign_range() in
libxc, but I failed when the mmaping number of pages exceeded 160
pages (640KB).
Can anyone help, 1.figure out the reason; 2.try the same
xc_map_foreign_range() codes if you can use IOCTL_PRIVCMD_MMAPBATCH2
and share you result ? Thank you.
My configurations:
Host: Ubuntu 12.04 64bit
Xen 4.1.2
Linux Kernel: 3.5.0-23, support IOCTL_PRIVCMD_MMAPBATCH only, rather
than IOCTL_PRIVCMD_MMAPBATCH2.
Guest: Windows XP SP2 32bit
Source code:
#define MEM_PAGE_MAX_MAP (40 * XC_PAGE_SIZE)
for (i=0; i < region_num; i++) {
unsigned long pfn_offset = i * MEM_PAGE_MAX_MAP / XC_PAGE_SIZE;
int map_size
(last_region_size==0||i<region_num-1)?MEM_PAGE_MAX_MAP:last_region_size;
printf("foreign_range "
"pfn_offset = %ld, map_size = %ld \n"
, pfn_offset, map_size);
void *memory = xc_map_foreign_range(xchandle, domainid, map_size,
PROT_READ, pfn_offset);
if (MAP_FAILED == memory || NULL == memory) {
dbprint("xc_map_foreign_range failed on pfn_offset=%d\n",
pfn_offset);
return;
}
}
Output:
foreign_range pfn_offset = 0, map_size = 163840
foreign_range pfn_offset = 40, map_size = 163840
foreign_range pfn_offset = 80, map_size = 163840
foreign_range pfn_offset = 120, map_size = 163840
foreign_range pfn_offset = 160, map_size = 16384
xc_map_foreign_range failed on pfn_offset=160
I have debuged libxc, too. And I find that when I have mmaped 160
pages, subsequent invoking of ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH,
&ioctlx) will set pfn[n] = 140737344202616, never conform to arr[n]
any more.
libxc code:
xc_linux_osdep.c:277
memcpy(pfn, arr, num * sizeof(*arr));
ioctlx.num = num;
ioctlx.dom = dom;
ioctlx.addr = (unsigned long)addr;
ioctlx.arr = pfn;
rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx);
rc = rc < 0 ? -errno : 0;
for ( i = 0; i < num; ++i )
{
switch ( pfn[i] ^ arr[i] )
{
case 0:
err[i] = rc != -ENOENT ? rc : 0;
continue;
default:
err[i] = -EINVAL;
continue;
}
Also, I have tried to look into kernel/drivers/xen/privcmd.c, but the
data flow in the ioctl interface seems complex to me. So I haven''t
figured out the reason even nnow.
Guanglin Xu
2013-Jul-29 19:36 UTC
Re: IOCTL_PRIVCMD_MMAPBATCH can''t mmap more than 160 pages?
I''ve tried IOCTL_PRIVCMD_MMAPBATCH_V2 by installing kernel 3.8, but failed again. rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx); While the ioctl() always returns 0 whatever number of pages have been mmaped, the ioctlx.err[] array items would be assigned EINVAL if more than 160 pages have been mmaped. Can any one help? 2013/7/27 Guanglin Xu <mzguanglin@gmail.com>:> Hi, > > I want to map the whole guest memory by xc_map_foreign_range() in > libxc, but I failed when the mmaping number of pages exceeded 160 > pages (640KB). > > Can anyone help, 1.figure out the reason; 2.try the same > xc_map_foreign_range() codes if you can use IOCTL_PRIVCMD_MMAPBATCH2 > and share you result ? Thank you. > > My configurations: > Host: Ubuntu 12.04 64bit > Xen 4.1.2 > Linux Kernel: 3.5.0-23, support IOCTL_PRIVCMD_MMAPBATCH only, rather > than IOCTL_PRIVCMD_MMAPBATCH2. > Guest: Windows XP SP2 32bit > > Source code: > #define MEM_PAGE_MAX_MAP (40 * XC_PAGE_SIZE) > for (i=0; i < region_num; i++) { > > unsigned long pfn_offset = i * MEM_PAGE_MAX_MAP / XC_PAGE_SIZE; > int map_size > (last_region_size==0||i<region_num-1)?MEM_PAGE_MAX_MAP:last_region_size; > > printf("foreign_range " > "pfn_offset = %ld, map_size = %ld \n" > , pfn_offset, map_size); > > void *memory = xc_map_foreign_range(xchandle, domainid, map_size, > PROT_READ, pfn_offset); > if (MAP_FAILED == memory || NULL == memory) { > dbprint("xc_map_foreign_range failed on pfn_offset=%d\n", > pfn_offset); > return; > } > } > > Output: > foreign_range pfn_offset = 0, map_size = 163840 > foreign_range pfn_offset = 40, map_size = 163840 > foreign_range pfn_offset = 80, map_size = 163840 > foreign_range pfn_offset = 120, map_size = 163840 > foreign_range pfn_offset = 160, map_size = 16384 > xc_map_foreign_range failed on pfn_offset=160 > > > I have debuged libxc, too. And I find that when I have mmaped 160 > pages, subsequent invoking of ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, > &ioctlx) will set pfn[n] = 140737344202616, never conform to arr[n] > any more. > > libxc code: > xc_linux_osdep.c:277 > memcpy(pfn, arr, num * sizeof(*arr)); > > ioctlx.num = num; > ioctlx.dom = dom; > ioctlx.addr = (unsigned long)addr; > ioctlx.arr = pfn; > > rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx); > > rc = rc < 0 ? -errno : 0; > > for ( i = 0; i < num; ++i ) > { > switch ( pfn[i] ^ arr[i] ) > { > case 0: > err[i] = rc != -ENOENT ? rc : 0; > continue; > default: > err[i] = -EINVAL; > continue; > } > > Also, I have tried to look into kernel/drivers/xen/privcmd.c, but the > data flow in the ioctl interface seems complex to me. So I haven''t > figured out the reason even nnow.