- __asm__ __volatile__ (
- "movq %5,%%r10; movq %6,%%r8;" TRAP_INSTR
- : "=a" (ret)
- : "a" ((unsigned long)hypercall.op),
- "D" ((unsigned long)hypercall.arg[0]),
- "S" ((unsigned long)hypercall.arg[1]),
- "d" ((unsigned long)hypercall.arg[2]),
- "g" ((unsigned long)hypercall.arg[3]),
- "g" ((unsigned long)hypercall.arg[4])
- : "r11","rcx","r8","r10","memory");
-#endif
- }
- break;
-
- case IOCTL_PRIVCMD_INITDOMAIN_EVTCHN:
- {
- extern int initdom_ctrlif_domcontroller_port;
- ret = initdom_ctrlif_domcontroller_port;
- }
- break;
-
-#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
- 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)) < 0 )
- return rc;
- }
- }
- ret = 0;
- }
- break;
-
- case IOCTL_PRIVCMD_MMAPBATCH:
- {
- mmu_update_t u;
- privcmd_mmapbatch_t m;
- struct vm_area_struct *vma = NULL;
- unsigned long *p, addr;
- unsigned long mfn;
- int i;
-
- if ( copy_from_user(&m, (void *)data, sizeof(m)) )
- { ret = -EFAULT; goto batch_err; }
-
- vma = find_vma( current->mm, m.addr );
-
- if ( !vma )
- { ret = -EINVAL; goto batch_err; }
-
- if ( m.addr > PAGE_OFFSET )
- { ret = -EFAULT; goto batch_err; }
-
- if ( (m.addr + (m.num<<PAGE_SHIFT)) > vma->vm_end )
- { ret = -EFAULT; goto batch_err; }
-
- p = m.arr;
- addr = m.addr;
- for ( i = 0; i < m.num; i++, addr += PAGE_SIZE, p++ )
- {
- if ( get_user(mfn, p) )
- return -EFAULT;
-
- u.val = (mfn << PAGE_SHIFT) | pgprot_val(vma->vm_page_prot);
-
- __direct_remap_area_pages(vma->vm_mm,
- addr,
- PAGE_SIZE,
- &u);
-
- if ( unlikely(HYPERVISOR_mmu_update(&u, 1, NULL, m.dom) < 0) )
- put_user(0xF0000000 | mfn, p);
- }
-
- ret = 0;
- break;
-
- batch_err:
- printk("batch_err ret=%d vma=%p addr=%lx num=%d arr=%p %lx-%lx\n",
- ret, vma, m.addr, m.num, m.arr,
- vma ? vma->vm_start : 0, vma ? vma->vm_end : 0);
- break;
- }
- break;
+ if (hypercall.op < (PAGE_SIZE >> 5)) {
+ long ign1, ign2, ign3;
+ __asm__ __volatile__ (
+ "movq %8,%%r10; movq %9,%%r8;"
+ "shll $5,%%eax ;"
+ "addq $hypercall_page,%%rax ;"
+ "call *%%rax"
+ : "=a" (ret), "=D" (ign1),
+ "=S" (ign2), "=d" (ign3)
+ : "0" ((unsigned int)hypercall.op),
+ "1" (hypercall.arg[0]),
+ "2" (hypercall.arg[1]),
+ "3" (hypercall.arg[2]),
+ "g" (hypercall.arg[3]),
+ "g" (hypercall.arg[4])
+ : "r8", "r10", "memory" );
+ }
+#elif defined (__ia64__)
+ __asm__ __volatile__ (
+ ";; mov r14=%2; mov r15=%3; "
+ "mov r16=%4; mov r17=%5; mov r18=%6;"
+ "mov r2=%1; break 0x1000;; mov %0=r8 ;;"
+ : "=r" (ret)
+ : "r" (hypercall.op),
+ "r" (hypercall.arg[0]),
+ "r" (hypercall.arg[1]),
+ "r" (hypercall.arg[2]),
+ "r" (hypercall.arg[3]),
+ "r" (hypercall.arg[4])
+ : "r14","r15","r16","r17","r18","r2","r8","memory");