gzFile initrd_gfd, unsigned long initrd_len,
unsigned long nr_pages,
unsigned long *pvsi, unsigned long *pvke,
- dom0_builddomain_t *builddomain,
+ full_execution_context_t *ctxt,
const char *cmdline,
unsigned long shared_info_frame,
- unsigned int control_evtchn)
+ unsigned int control_evtchn,
+ int io_priv)
{
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
if ( setup_guestos(xc_handle, domid, image, image_size,
initrd_gfd, initrd_size, nr_pages,
&vstartinfo_start, &vkern_entry,
- &launch_op.u.builddomain, cmdline,
+ ctxt, cmdline,
op.u.getdomaininfo.shared_info_frame,
- control_evtchn) < 0 )
+ control_evtchn, io_priv) < 0 )
{
ERROR("Error constructing guest OS");
goto error_out;
unsigned long tot_pages,
unsigned long *virt_startinfo_addr,
unsigned long *virt_load_addr,
- dom0_builddomain_t *builddomain,
+ full_execution_context_t *ctxt,
const char *cmdline,
unsigned long shared_info_frame,
- unsigned int control_evtchn)
+ unsigned int control_evtchn,
+ int io_priv)
{
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
if ( setup_guestos(xc_handle, domid, kernel_gfd, tot_pages,
&virt_startinfo_addr,
- &load_addr, &launch_op.u.builddomain, cmdline,
+ &load_addr, &st_ctxt, cmdline,
op.u.getdomaininfo.shared_info_frame,
- control_evtchn) < 0 )
+ control_evtchn, io_priv) < 0 )
{
ERROR("Error constructing guest OS");
goto error_out;
}
break;
+ case IOCTL_PRIVCMD_MMAP:
+ {
+#define PRIVCMD_MMAP_SZ 32
+ privcmd_mmap_t mmapcmd;
+ privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ], *p;
+ int i, rc;
+
+ if ( copy_from_user(&mmapcmd, (void *)data, sizeof(mmapcmd)) )
+ return -EFAULT;
+
+ p = mmapcmd.entry;
+
+ for (i=0; i<mmapcmd.num; i+=PRIVCMD_MMAP_SZ, p+=PRIVCMD_MMAP_SZ)
+ {
+ int j, n = ((mmapcmd.num-i)>PRIVCMD_MMAP_SZ)?
+ PRIVCMD_MMAP_SZ:(mmapcmd.num-i);
+ if ( copy_from_user(&msg, p, n*sizeof(privcmd_mmap_entry_t)) )
+ return -EFAULT;
+
+ for (j=0;j<n;j++)
+ {
+ struct vm_area_struct *vma =
+ find_vma( current->mm, msg[j].va );
+
+ if (!vma)
+ return -EINVAL;
+
+ if (msg[j].va > PAGE_OFFSET)
+ return -EINVAL;
+
+ if (msg[j].va + (msg[j].npages<<PAGE_SHIFT) > vma->vm_end)
+ return -EINVAL;
+
+ if (rc = direct_remap_area_pages(vma->vm_mm,
+ msg[j].va&PAGE_MASK,
+ msg[j].mfn<<PAGE_SHIFT,
+ msg[j].npages<<PAGE_SHIFT,
+ vma->vm_page_prot,
+ mmapcmd.dom))
+ return rc;
+ }
+ }
+ ret = 0;
+ }
+ break;
+
+ case IOCTL_PRIVCMD_INITDOMAIN_EVTCHN:
+ {
+ extern int initdom_ctrlif_domcontroller_port;
+ ret = initdom_ctrlif_domcontroller_port;
+ }
+ break;
++
+ default:
+ ret = -EINVAL;
+ break;
}
-
return ret;
}
v += 2;
}
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
do {
+#if 0 /* thanks to new ioctl mmaping interface this is no longer a bug */
if (!pte_none(*pte)) {
printk("direct_remap_area_pte: page already exists\n");
BUG();
}
+#endif
v->ptr = virt_to_machine(pte);
v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot) | _PAGE_IO;
- v++;
+ if ( ++v == MAX_DIRECTMAP_MMU_QUEUE )
+ {
+ if ( HYPERVISOR_mmu_update(u, MAX_DIRECTMAP_MMU_QUEUE) < 0 )
+ return -EFAULT;
+ goto reset_buffer;
+ }
address += PAGE_SIZE;
machine_addr += PAGE_SIZE;
pte++;
} while (address && (address < end));
- if ( ((v-u) != 0) && (HYPERVISOR_mmu_update(u, v-u) < 0) )
- return -EFAULT;
+ if ( ((v-u) > 2) && (HYPERVISOR_mmu_update(u, v-u) < 0) )
+ {
+ printk(KERN_WARNING "Failed to ioremap %08lx->%08lx (%08lx)\n",
+ end-size, end, machine_addr-size);
+ return -EINVAL;
+ }
- vfree(u);
return 0;
}
pte_t * pte = pte_alloc(mm, pmd, address);
if (!pte)
return -ENOMEM;
- if ( rc = direct_remap_area_pte(pte, address, end - address,
- address + machine_addr, prot, domid) )
- return rc;
-
+
+ error = direct_remap_area_pte(pte, address, end - address,
+ address + machine_addr, prot, domid);
+ if ( error )
+ break;
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address && (address < end));
unsigned long arg[5];
} privcmd_hypercall_t;
- #define IOCTL_PRIVCMD_HYPERCALL \
+typedef struct privcmd_mmap_entry {
+ unsigned long va;
+ unsigned long mfn;
+ unsigned long npages;
+} privcmd_mmap_entry_t;
+
+typedef struct privcmd_mmap {
+ int num;
+ domid_t dom; /* target domain */
+ privcmd_mmap_entry_t *entry;
+} privcmd_mmap_t;
+
+typedef struct privcmd_blkmsg
+{
+ unsigned long op;
+ void *buf;
+ int buf_size;
+} privcmd_blkmsg_t;
+
+ /*
+ * @cmd: IOCTL_PRIVCMD_HYPERCALL
+ * @arg: &privcmd_hypercall_t
+ * Return: Value returned from execution of the specified hypercall.
+ */
+ #define IOCTL_PRIVCMD_HYPERCALL \
_IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
- #define IOCTL_PRIVCMD_BLKMSG \
- _IOC(_IOC_NONE, 'P', 1, sizeof(privcmd_blkmsg_t))
+
+ /*
+ * @cmd: IOCTL_PRIVCMD_INITDOMAIN_EVTCHN
+ * @arg: n/a
+ * Return: Port associated with domain-controller end of control event channel
+ * for the initial domain.
+ */
+ #define IOCTL_PRIVCMD_INITDOMAIN_EVTCHN \
+ _IOC(_IOC_NONE, 'P', 1, 0)
+#define IOCTL_PRIVCMD_MMAP \
+ _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
#endif /* __PROC_CMD_H__ */