int i;
LIST_HEAD(pagelist);
struct list_head *l, *l2;
+ int paged_out = 0;
if (!is_initial_xendomain())
return -EPERM;
(m.addr != vma->vm_start) ||
((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) ||
!privcmd_enforce_singleshot_mapping(vma)) {
- up_write(&mm->mmap_sem);
- goto mmapbatch_out;
+ if (!(vma &&
+ (m.addr >= vma->vm_start) &&
+ ((m.addr + (nr_pages << PAGE_SHIFT)) <= vma->vm_end) &&
+ (nr_pages == 1) &&
+ !privcmd_enforce_singleshot_mapping(vma))) {
+ up_write(&mm->mmap_sem);
+ goto mmapbatch_out;
+ }
}
p = m.arr;
ret = 0;
list_for_each(l, &pagelist) {
int nr = i + min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
+ int rc;
+
mfn = (unsigned long *)(l + 1);
while (i<nr) {
- if(direct_remap_pfn_range(vma, addr & PAGE_MASK,
- *mfn, PAGE_SIZE,
- vma->vm_page_prot, m.dom) < 0) {
- *mfn |= 0xf0000000U;
+ rc = direct_remap_pfn_range(vma, addr & PAGE_MASK,
+ *mfn, PAGE_SIZE,
+ vma->vm_page_prot, m.dom);
+ if(rc < 0) {
+ if (rc == -ENOENT)
+ {
+ *mfn |= 0x80000000U;
+ paged_out = 1;
+ }
+ else
+ *mfn |= 0xf0000000U;
ret++;
}
mfn++; i++; addr += PAGE_SIZE;
if (ret > 0) {
p = m.arr;
i = 0;
- ret = 0;
+ if (paged_out)
+ ret = -ENOENT;
+ else
+ ret = 0;
list_for_each(l, &pagelist) {
int nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
mfn = (unsigned long *)(l + 1);