All of lore.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-05-20 12:28 Ling, Xiaofeng
  0 siblings, 0 replies; 14+ messages in thread
From: Ling, Xiaofeng @ 2005-05-20 12:28 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 1032 bytes --]

Sorry, the last patch missed three files.(mm.h, shadow.h, domain.h)
This one is the correct one.

Xiaofeng Ling <> wrote:
> This patch adds paravirutulization driver support for vmx domain in
> hypervisor.  The VBD and VNIF frontend driver can then be used in
> unmodified kernel as a module to get better performance than device
> model. The backend driver needs no change and can work together with
> xeno-linux.   
> The event channel mechanism works as a pci device in guest linux, so
> a event channel device driver will as basic module in guest kernel. 
> 
> What's the patch done is:
> 1.copy_to/from_guest support, which is used to copy context from/to
> guest space to hypervisor space. 
> 2.copy_to/from_user will call copy_to/from_guest for a vmx domain.
> 3.A separate hypercall table for paravirutulization driver which mask
> some unused entries. 
> 4.add hypercalls for address translation.and share page mapping (event
>   channel and grant table)
> 5.clean some hypercalls path for vmx domain.

[-- Attachment #2: paravirtulization-driver-hypervisor-update.patch --]
[-- Type: application/octet-stream, Size: 33473 bytes --]

# This is a BitKeeper generated diff -Nru style patch.
# ChangeSet
#   2005/05/20 11:27:04+08:00 xiaofeng.ling@intel.com 
#   This patch adds paravirutulization driver support for vmx domain in hypervisor.
#   The VBD and VNIF frontend driver can then be used in unmodified kernel as a module to get 
#   better performance than device model.
#   The backend driver needs no change and can work together with xeno-linux.
#   The event channel mechanism works as a pci device in guest linux. 
#   
#   Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>
#
# xen/include/asm-x86/shadow.h
#   2005/05/20 15:17:46+08:00 xiaofeng.ling@intel.com +4 -0
#   return in vmx domain
# 
# xen/include/asm-x86/mm.h
#   2005/05/20 15:17:46+08:00 xiaofeng.ling@intel.com +22 -0
#   phystomachine call
# 
# xen/include/asm-x86/domain.h
#   2005/05/20 15:17:46+08:00 xiaofeng.ling@intel.com +4 -0
#   add callback irq member
# 
# BitKeeper/etc/logging_ok
#   2005/05/20 11:27:04+08:00 xiaofeng.ling@intel.com +1 -0
#   Logging to logging@openlogging.org accepted
# 
# xen/include/xen/config.h
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +8 -0
#   Add debug print for vmx driver
# 
# xen/include/public/xen.h
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +13 -1
#   add virtual device hypercall entry
# 
# xen/include/public/arch-x86_32.h
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +5 -0
#   add vmcall to do hypercall in vmx domain 
# 
# xen/include/asm-x86/x86_64/uaccess.h
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +5 -0
#   copy_to/from_guest for vmx domain.
# 
# xen/include/asm-x86/x86_32/uaccess.h
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +5 -0
#   copy_to/from_guest for vmx domain.
# 
# xen/include/asm-x86/vmx_vmcs.h
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +2 -0
#   debug for VMX VBD and VNIF
# 
# xen/common/multicall.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +34 -9
#   vmx domain hypercall path 
# 
# xen/common/grant_table.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +29 -6
#   setup grant table for vmx domain
# 
# xen/common/dom_mem_ops.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +12 -5
#   hypercall path for vmx domain
# 
# xen/arch/x86/x86_64/usercopy.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +15 -0
#   copy_to/from_guest stub for x86_64
# 
# xen/arch/x86/x86_32/usercopy.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +99 -0
#   copy_to/from_guest for vmx domain
# 
# xen/arch/x86/x86_32/entry.S
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +36 -0
#   add an hypercall table for vmx doamim, mask unused hypercalls
# 
# xen/arch/x86/vmx_io.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +53 -7
#   delieve event to vmx domain by irq
# 
# xen/arch/x86/vmx.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +83 -4
#   hypercall entry for vmx domain by vmcall
# 
# xen/arch/x86/shadow.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +25 -2
#   set map for vmx domain
# 
# xen/arch/x86/mm.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +27 -13
#   clear vmx hypercall path
# 
# xen/arch/x86/domain.c
#   2005/05/20 11:27:01+08:00 xiaofeng.ling@intel.com +1 -0
#   add call back irq member
# 
diff -Nru a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c	2005-05-20 15:19:36 +08:00
+++ b/xen/arch/x86/domain.c	2005-05-20 15:19:36 +08:00
@@ -265,6 +265,7 @@
     ed->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] =
         l1e_create_page(virt_to_page(gdt_table), PAGE_HYPERVISOR);
 
+    ed->arch.callback_irq = 0;
     ed->arch.guest_vtable  = __linear_l2_table;
     ed->arch.shadow_vtable = __shadow_linear_l2_table;
 
diff -Nru a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c	2005-05-20 15:19:36 +08:00
+++ b/xen/arch/x86/mm.c	2005-05-20 15:19:36 +08:00
@@ -1848,21 +1848,32 @@
 
     if ( unlikely(!array_access_ok(ureqs, count, sizeof(req))) )
     {
-        rc = -EFAULT;
-        goto out;
+       if(!VMX_DOMAIN(current)){
+           rc = -EFAULT;
+           goto out;
+       }
     }
 
     for ( i = 0; i < count; i++ )
     {
-        if ( hypercall_preempt_check() )
+        if(VMX_DOMAIN(current))
         {
-            rc = hypercall4_create_continuation(
-                __HYPERVISOR_mmu_update, ureqs, 
-                (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
-            break;
+
+             rc = copy_from_guest(&req, ureqs, sizeof(req));
         }
+        else
+        {
+            if ( hypercall_preempt_check() )
+            {
+                rc = hypercall4_create_continuation(
+                        __HYPERVISOR_mmu_update, ureqs, 
+                        (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
+                break;
+            }
+            rc = __copy_from_user(&req, ureqs, sizeof(req));
 
-        if ( unlikely(__copy_from_user(&req, ureqs, sizeof(req)) != 0) )
+        }
+        if ( unlikely(rc) != 0) 
         {
             MEM_LOG("Bad __copy_from_user");
             rc = -EFAULT;
@@ -2008,7 +2019,8 @@
                 break;
             }
 
-            if ( unlikely(shadow_mode_translate(FOREIGNDOM) && !IS_PRIV(d)) )
+            if ( unlikely(shadow_mode_translate(FOREIGNDOM) && !IS_PRIV(d) 
+                          && !shadow_mode_external(FOREIGNDOM)) )
             {
                 MEM_LOG("can't mutate the m2p of translated guests");
                 break;
@@ -2115,7 +2127,6 @@
     return rc;
 }
 
-
 int do_update_va_mapping(unsigned long va,
                          l1_pgentry_t  val, 
                          unsigned long flags)
@@ -2138,9 +2149,12 @@
     if ( unlikely(shadow_mode_enabled(d)) )
         check_pagetable(ed, "pre-va"); /* debug */
 
-    if ( unlikely(!mod_l1_entry(&linear_pg_table[l1_linear_offset(va)],
-                                val)) )
-        rc = -EINVAL;
+    if ( !shadow_mode_external(d) )
+    {
+        if ( unlikely(!mod_l1_entry(&linear_pg_table[l1_linear_offset(va)],
+                        val)) )
+            rc = -EINVAL;
+    }
 
     if ( likely(rc == 0) && unlikely(shadow_mode_enabled(d)) )
     {
diff -Nru a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c	2005-05-20 15:19:36 +08:00
+++ b/xen/arch/x86/shadow.c	2005-05-20 15:19:36 +08:00
@@ -2746,6 +2746,7 @@
     struct domain *d = ed->domain;
     l1_pgentry_t spte;
     int rc = 0;
+    unsigned long gpa, mfn;
 
     shadow_lock(d);
 
@@ -2756,9 +2757,31 @@
     // linear_pg_table[l1_linear_offset(va)] to be in sync)...
     //
     __shadow_sync_va(ed, va);
+    
+    if(!VMX_DOMAIN(ed))
+    {
+        l1pte_propagate_from_guest(d, val, &spte);
+    }
+    else
+    {
+        gpa = gva_to_gpa(va);
+        mfn = l1e_get_pfn(val);
+        if(gpa) 
+        {
+            if(l1e_get_value(val))
+            {
+                set_phystomachine(gpa >> PAGE_SHIFT, 
+                        mfn);
+            }
+            else
+                set_phystomachine(gpa >> PAGE_SHIFT, INVALID_MFN);
+        }
 
-    l1pte_propagate_from_guest(d, val, &spte);
-    shadow_set_l1e(va, spte, 0);
+        spte = val;
+
+    }
+
+    shadow_set_l1e(va, spte, VMX_DOMAIN(ed));
 
     /*
      * If we're in log-dirty mode then we need to note that we've updated
diff -Nru a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c	2005-05-20 15:19:36 +08:00
+++ b/xen/arch/x86/vmx.c	2005-05-20 15:19:36 +08:00
@@ -976,20 +976,49 @@
 char print_buf[BUF_SIZ];
 static int index;
 
-static void vmx_print_line(const char c, struct exec_domain *d) 
+asmlinkage unsigned long do_vmx_print_line(unsigned long ch) 
 {
 
+#if VMX_DEBUG
+    char c = (char)ch;
     if (index == MAX_LINE || c == '\n') {
         if (index == MAX_LINE) {
             print_buf[index++] = c;
         }
         print_buf[index] = '\0';
-        printk("(GUEST: %u) %s\n", d->domain->domain_id, (char *) &print_buf);
+        printk("(GUEST: %u) %s\n", current->domain->domain_id, (char *) &print_buf);
         index = 0;
     }
     else
         print_buf[index++] = c;
+#endif
+    return 0;
+}
+
+#if defined(__i386__)
+void vmx_do_hypercall(struct cpu_user_regs *pregs)
+{
+	unsigned long retcode;
+	__asm__ __volatile__(
+		"pushl %6\n\t"
+		"pushl %5\n\t"
+		"pushl %4\n\t"
+		"pushl %3\n\t"
+		"pushl %2\n\t"
+		"call *(vmx_hypercall_table)(,%0,4)\n\t"
+		"addl $20, %%esp\n\t"
+		:"=&a"(retcode)
+		:"0"(pregs->eax), "r"(pregs->ebx), "r"(pregs->ecx),
+		 "r"(pregs->edx), "r"(pregs->esi), "r"(pregs->edi)
+	);
+	pregs->eax = retcode;
+	return;
+}
+#else
+void vmx_do_hypercall(struct cpu_user_regs *pregs)
+{
 }
+#endif
 
 void save_vmx_cpu_user_regs(struct cpu_user_regs *ctxt)
 {
@@ -1230,8 +1259,7 @@
         __get_instruction_length(inst_len);
         __vmread(GUEST_EIP, &eip);
         __vmread(EXIT_QUALIFICATION, &exit_qualification);
-
-        vmx_print_line(regs.eax, ed); /* provides the current domain */
+         vmx_do_hypercall(&regs);
         __update_guest_eip(inst_len);
         break;
     case EXIT_REASON_CR_ACCESS:
@@ -1295,6 +1323,57 @@
 #endif
 
 }
+
+int do_update_va_mapping(unsigned long va,
+                         l1_pgentry_t  val, 
+                         unsigned long flags);
+/* 
+ * The va must be a page start address
+ */
+int map_sharepage_to_guest(unsigned long gva, unsigned long shared)
+{
+    l1_pgentry_t val, gpte; 
+
+    gpte = gva_to_gpte(gva);
+    val = l1e_create_phys((__pa(shared)), l1e_get_flags(gpte));
+    return do_update_va_mapping(gva, val, 0);
+}
+  
+asmlinkage unsigned long do_virtual_device_op(unsigned long op, 
+                                              unsigned long arg1, 
+                                              unsigned arg2)
+{
+	switch (op) 
+    {
+        case SET_SHAREINFO_MAP:
+		    return map_sharepage_to_guest(arg1, 
+                        (unsigned long)current->domain->shared_info);
+        case SET_CALLBACK_IRQ:
+            if(arg1)
+                current->arch.callback_irq = 0x20+arg1;
+            else
+                current->arch.callback_irq = 0;
+            return 0;
+        case ADDR_MACHTOPHYS: 
+        {
+            unsigned long phys = 
+                __mfn_to_gpfn(current->domain, arg1 >> PAGE_SHIFT);
+            phys = (phys << PAGE_SHIFT) | (arg1 & ~PAGE_MASK);
+            return phys;
+        }
+        case ADDR_PHYSTOMACH:
+        {
+            unsigned long machine = 
+                __gpfn_to_mfn(current->domain, arg1 >> PAGE_SHIFT);
+            machine = (machine << PAGE_SHIFT) | (arg1 & ~PAGE_MASK);
+            return machine;
+        }
+        default:
+	        printk("Not supported virtual device operation\n");
+    }
+    return 0L;
+}
+
 
 #endif /* CONFIG_VMX */
 
diff -Nru a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c	2005-05-20 15:19:36 +08:00
+++ b/xen/arch/x86/vmx_io.c	2005-05-20 15:19:36 +08:00
@@ -196,12 +196,14 @@
     mpci_p = &ed->arch.arch_vmx.vmx_platform.mpci;
     inst_decoder_regs = mpci_p->inst_decoder_regs;
 
-    /* clear the pending event */
-    ed->vcpu_info->evtchn_upcall_pending = 0;
     /* clear the pending bit for port 2 */
-    clear_bit(IOPACKET_PORT>>5, &ed->vcpu_info->evtchn_pending_sel);
     clear_bit(IOPACKET_PORT, &d->shared_info->evtchn_pending[0]);
 
+    if (!d->shared_info->evtchn_pending[IOPACKET_PORT>>5])
+        clear_bit(IOPACKET_PORT>>5, &ed->vcpu_info->evtchn_pending_sel);                                
+    if (!ed->vcpu_info->evtchn_pending_sel) 
+        ed->vcpu_info->evtchn_upcall_pending = 0;
+
     vio = (vcpu_iodata_t *) ed->arch.arch_vmx.vmx_platform.shared_page_va;
     if (vio == 0) {
         VMX_DBG_LOG(DBG_LEVEL_1, 
@@ -427,6 +429,25 @@
     return;
 }
 
+int vmx_event_to_irq(struct exec_domain *ed) 
+{
+    vcpu_iodata_t *vio;
+
+    vio = (vcpu_iodata_t *) ed->arch.arch_vmx.vmx_platform.shared_page_va;
+    if (vio == 0) {
+        VMX_DBG_LOG(DBG_LEVEL_VBD, 
+                "bad shared page: %lx\n", (unsigned long) vio);
+        domain_crash();
+    }
+    /*
+     * the event is only for guest, just set callback interrupt 
+     * bit  and return
+     */
+    return test_and_set_bit(ed->arch.callback_irq, &vio->vp_intr[0]);
+
+}
+
+/* for debug use*/
 void vmx_do_resume(struct exec_domain *d) 
 {
     vmx_stts();
@@ -440,12 +461,34 @@
     __vmwrite(HOST_ESP, (unsigned long)get_stack_bottom());
 
     if (event_pending(d)) {
-        if (test_bit(IOPACKET_PORT, &d->domain->shared_info->evtchn_pending[0])) 
+        if (test_bit(IOPACKET_PORT, &d->domain->shared_info->evtchn_pending[0]))
             vmx_io_assist(d);
+        if(event_pending(d) && !d->vcpu_info->callback_mask) {
+            VMX_DBG_LOG(DBG_LEVEL_VBD,
+               "<vbd>insert callback interrupt\n");
+
+            vmx_event_to_irq(d); 
+            d->vcpu_info->callback_mask = 
+                d->domain->shared_info->evtchn_pending[0];
+
+        }               
+        if (test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags)) {
+            /*
+             * clear the indicator, so that evtchn_set_pending can 
+             * unblock domain again 
+             */
+            d->vcpu_info->evtchn_upcall_pending = 0;
 
-        else if (test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags)) {
-            printk("got an event while blocked on I/O\n");
+            /*clear the bit, so that device-model can unblock domain again */
+            clear_bit(IOPACKET_PORT>>5, &d->vcpu_info->evtchn_pending_sel);
+
+            VMX_DBG_LOG(DBG_LEVEL_VBD,
+                "I/O not complete, do_block\n");
             do_block();
+
+            /* do_block shall not return at this time*/
+            printk("do_block return in vmx_do_resume!!!\n");
+
         }
                 
         /* Assumption: device model will not inject an interrupt
@@ -454,8 +497,11 @@
          * a response to ioreq_t is not ok.
          */
     }
-    if (!test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags))
+
+    if (!test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags)) 
         vmx_intr_assist(d);
+    else
+        do_block();
 }
 
 #endif /* CONFIG_VMX */
diff -Nru a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S	2005-05-20 15:19:36 +08:00
+++ b/xen/arch/x86/x86_32/entry.S	2005-05-20 15:19:36 +08:00
@@ -749,6 +749,42 @@
         .long do_boot_vcpu
         .long do_ni_hypercall       /* 25 */
         .long do_mmuext_op
+        .long do_ni_hypercall       
+        .long do_ni_hypercall       /* virutal device op for VMX */
         .rept NR_hypercalls-((.-hypercall_table)/4)
+        .long do_ni_hypercall
+        .endr
+
+ENTRY(vmx_hypercall_table)
+        .long do_ni_hypercall       /*  0 */
+        .long do_mmu_update
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_ni_hypercall       /*  5 */
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_ni_hypercall       /* 10 */
+        .long do_vmx_print_line
+        .long do_dom_mem_op
+        .long do_multicall
+        .long do_update_va_mapping
+        .long do_ni_hypercall       /* 15 */
+        .long do_event_channel_op
+        .long do_xen_version
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_grant_table_op     /* 20 */
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_ni_hypercall
+        .long do_ni_hypercall       /* 25 */
+        .long do_ni_hypercall
+        .long do_ni_hypercall       
+        .long do_virtual_device_op  /* 28 */
+        .rept NR_hypercalls-((.-vmx_hypercall_table)/4)
         .long do_ni_hypercall
         .endr
diff -Nru a/xen/arch/x86/x86_32/usercopy.c b/xen/arch/x86/x86_32/usercopy.c
--- a/xen/arch/x86/x86_32/usercopy.c	2005-05-20 15:19:36 +08:00
+++ b/xen/arch/x86/x86_32/usercopy.c	2005-05-20 15:19:36 +08:00
@@ -8,6 +8,8 @@
 #include <xen/config.h>
 #include <xen/mm.h>
 #include <asm/uaccess.h>
+#include <asm/domain_page.h>
+#include <asm/shadow.h>
 
 static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned long n)
 {
@@ -394,6 +396,98 @@
 	return n;
 }
 
+void* map_domain_vaddr(void * guest_vaddr, unsigned long len)
+{
+    l1_pgentry_t gpte;
+    unsigned long mfn;
+    unsigned long ma;
+    void * vstart;
+    
+    if (len > PAGE_SIZE) 
+    {
+        return NULL;
+    }
+ 
+    if (((unsigned long)guest_vaddr & PAGE_MASK) == 
+        (((unsigned long)guest_vaddr + len -1) & PAGE_MASK)) 
+    {
+        gpte = gva_to_gpte((unsigned long)guest_vaddr);
+        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+        ma = (mfn << PAGE_SHIFT) | 
+             ((unsigned long)guest_vaddr & (PAGE_SIZE - 1));
+        vstart = (void *)map_domain_mem(ma);
+    }
+    else 
+    {
+        return NULL;
+    }
+    return vstart;
+}
+
+unsigned long
+copy_from_guest(void *to, const void __user *from, unsigned long n)
+{
+    void *hfrom;    
+    unsigned long ncopy;
+    int nleft;
+    ncopy = (((unsigned long)from  + PAGE_SIZE) & PAGE_MASK) - 
+            (unsigned long)from;
+    ncopy = ncopy > n ? n : ncopy;  
+
+    for(nleft = n; nleft > 0; ncopy = nleft > PAGE_SIZE ? PAGE_SIZE : nleft) 
+    {
+        hfrom = map_domain_vaddr((void*)from, ncopy);
+        if(hfrom) 
+        {
+            memcpy(to, hfrom, ncopy);
+            unmap_domain_mem((void*)hfrom); 
+        }
+        else 
+        {
+            printk("error!, copy from guest map error, from:%p, ncopy:%ld\n", 
+                   from, ncopy);
+             return nleft;
+        }
+        nleft -= ncopy;
+        from += ncopy;
+        to += ncopy;
+    }
+    return nleft;
+}
+EXPORT_SYMBOL(copy_from_guest);
+
+unsigned long
+copy_to_guest(void __user *to, const void *from, unsigned long n)
+{
+    void *hto;  
+    unsigned long ncopy;
+    int nleft;
+
+    ncopy = (((unsigned long)to  + PAGE_SIZE) & PAGE_MASK) - (unsigned long)to;
+    ncopy = ncopy > n ? n : ncopy;  
+
+    for(nleft = n; nleft > 0; ncopy = nleft > PAGE_SIZE ? PAGE_SIZE : nleft) 
+    {
+        hto = map_domain_vaddr((void*)to, ncopy);
+        if(hto) 
+        {
+            memcpy(hto, from, ncopy);
+            unmap_domain_mem((void*)hto); 
+        }
+        else 
+        {
+            printk("error!, copy to guest map error, from:%p, ncopy:%ld\n", 
+                   from, ncopy);
+            return nleft;
+        }
+        nleft -= ncopy;
+        from += ncopy;
+        to += ncopy;
+    }
+    return nleft;
+}
+EXPORT_SYMBOL(copy_to_guest);
+
 /**
  * copy_to_user: - Copy a block of data into user space.
  * @to:   Destination address, in user space.
@@ -410,6 +504,8 @@
 unsigned long
 copy_to_user(void __user *to, const void *from, unsigned long n)
 {
+    if(VMX_DOMAIN(current))
+        return copy_to_guest(to, from, n);
 	if (access_ok(to, n))
 		n = __copy_to_user(to, from, n);
 	return n;
@@ -434,6 +530,9 @@
 unsigned long
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+
+    if(VMX_DOMAIN(current))
+        return copy_from_guest(to, from, n);
 	if (access_ok(from, n))
 		n = __copy_from_user(to, from, n);
 	else
diff -Nru a/xen/arch/x86/x86_64/usercopy.c b/xen/arch/x86/x86_64/usercopy.c
--- a/xen/arch/x86/x86_64/usercopy.c	2005-05-20 15:19:36 +08:00
+++ b/xen/arch/x86/x86_64/usercopy.c	2005-05-20 15:19:36 +08:00
@@ -132,6 +132,21 @@
 	return n;
 }
 
+unsigned long
+copy_from_guest(void *to, const void __user *from, unsigned long n)
+{
+  return n;
+}
+EXPORT_SYMBOL(copy_from_guest);
+
+unsigned long
+copy_to_guest(void __user *to, const void *from, unsigned long n)
+{
+    return n;
+}
+EXPORT_SYMBOL(copy_to_guest);
+
+
 /**
  * copy_to_user: - Copy a block of data into user space.
  * @to:   Destination address, in user space.
diff -Nru a/xen/common/dom_mem_ops.c b/xen/common/dom_mem_ops.c
--- a/xen/common/dom_mem_ops.c	2005-05-20 15:19:36 +08:00
+++ b/xen/common/dom_mem_ops.c	2005-05-20 15:19:36 +08:00
@@ -80,15 +80,21 @@
     struct pfn_info *page;
     unsigned long    i, j, mpfn;
 
-    if ( !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
+    if ( !VMX_DOMAIN(current) && 
+         unlikely(!array_access_ok(extent_list, nr_extents, 
+                                   sizeof(*extent_list))) )
         return start_extent;
 
     for ( i = start_extent; i < nr_extents; i++ )
     {
-        PREEMPT_CHECK(MEMOP_decrease_reservation);
-
-        if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) )
-            return i;
+        if( VMX_DOMAIN(current)) {
+            if(copy_from_guest(&mpfn, &extent_list[i], sizeof(mpfn)) != 0)
+                return i;
+        } else {
+            PREEMPT_CHECK(MEMOP_decrease_reservation);
+           if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) )
+                return i;
+        }
 
         for ( j = 0; j < (1 << extent_order); j++ )
         {
@@ -100,6 +106,7 @@
             }
             
             page = &frame_table[mpfn + j];
+
             if ( unlikely(!get_page(page, d)) )
             {
                 DPRINTK("Bad page free for domain %u\n", d->domain_id);
diff -Nru a/xen/common/grant_table.c b/xen/common/grant_table.c
--- a/xen/common/grant_table.c	2005-05-20 15:19:36 +08:00
+++ b/xen/common/grant_table.c	2005-05-20 15:19:36 +08:00
@@ -159,7 +159,10 @@
 
         /* rmb(); */ /* not on x86 */
 
-        frame = __gpfn_to_mfn_foreign(granting_d, sha->frame);
+        if(!shadow_mode_translate(granting_d))
+            frame = __gpfn_to_mfn_foreign(granting_d, sha->frame);
+        else
+            frame = sha->frame;
 
         if ( unlikely(!pfn_valid(frame)) ||
              unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
@@ -668,7 +671,8 @@
     {
         DPRINTK("Xen only supports up to %d grant-table frames per domain.\n",
                 NR_GRANT_FRAMES);
-        (void)put_user(GNTST_general_error, &uop->status);
+        op.status = GNTST_general_error;
+        (void)copy_to_user(uop, &op, sizeof(op));
         return 0;
     }
 
@@ -678,25 +682,44 @@
     }
     else if ( unlikely(!IS_PRIV(current->domain)) )
     {
-        (void)put_user(GNTST_permission_denied, &uop->status);
+        op.status = GNTST_permission_denied;
+        (void)copy_to_user(uop, &op, sizeof(op));
         return 0;
     }
 
     if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
     {
         DPRINTK("Bad domid %d.\n", op.dom);
-        (void)put_user(GNTST_bad_domain, &uop->status);
+        op.status = GNTST_bad_domain;
+        (void)copy_to_user(uop, &op, sizeof(op));
         return 0;
     }
 
     if ( op.nr_frames <= NR_GRANT_FRAMES )
     {
         ASSERT(d->grant_table != NULL);
-        (void)put_user(GNTST_okay, &uop->status);
-        for ( i = 0; i < op.nr_frames; i++ )
+        if(!VMX_DOMAIN(current))
+        {
+            (void)put_user(GNTST_okay, &uop->status);
+            for ( i = 0; i < op.nr_frames; i++ )
             (void)put_user(
                 (virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT) + i,
                 &uop->frame_list[i]);
+        }
+        else
+        {
+            op.status = GNTST_okay;
+            for ( i = 0; i < op.nr_frames; i++ )
+            {
+               if(map_sharepage_to_guest((unsigned long)op.frame_list + i * PAGE_SIZE, (unsigned long)d->grant_table->shared + i * PAGE_SIZE))
+               {
+     
+                   op.status = GNTST_general_error;
+                   break;
+               }
+            }
+            (void)copy_to_user(uop, &op, sizeof(op));
+        }
     }
 
     put_domain(d);
diff -Nru a/xen/common/multicall.c b/xen/common/multicall.c
--- a/xen/common/multicall.c	2005-05-20 15:19:36 +08:00
+++ b/xen/common/multicall.c	2005-05-20 15:19:36 +08:00
@@ -17,6 +17,7 @@
 {
     struct mc_state *mcs = &mc_state[smp_processor_id()];
     unsigned int     i;
+    int rc;
 
     if ( unlikely(__test_and_set_bit(_MCSF_in_multicall, &mcs->flags)) )
     {
@@ -24,7 +25,8 @@
         return -EINVAL;
     }
 
-    if ( unlikely(!array_access_ok(call_list, nr_calls, sizeof(*call_list))) )
+    if (likely(!VMX_DOMAIN(current)) && 
+        unlikely(!array_access_ok(call_list, nr_calls, sizeof(*call_list))) )
     {
         DPRINTK("Bad memory range %p for %u*%u bytes.\n",
                 call_list, nr_calls, (unsigned int)sizeof(*call_list));
@@ -33,23 +35,40 @@
 
     for ( i = 0; i < nr_calls; i++ )
     {
-        if ( unlikely(__copy_from_user(&mcs->call, &call_list[i], 
-                                       sizeof(*call_list))) )
+        if(VMX_DOMAIN(current)) 
         {
-            DPRINTK("Error copying from user range %p for %u bytes.\n",
-                    &call_list[i], (unsigned int)sizeof(*call_list));
+            rc = copy_from_guest(&mcs->call, &call_list[i], 
+                                       sizeof(*call_list)); 
+        }
+        else
+            rc = __copy_from_user(&mcs->call, &call_list[i], 
+                                       sizeof(*call_list));
+        if ( unlikely(rc) )
+        {
+            DPRINTK("Error copying from user range %p for %u bytes.%d, %d\n",
+                    &call_list[i], sizeof(*call_list), i, rc);
             goto fault;
         }
 
         do_multicall_call(&mcs->call);
 
-        if ( unlikely(__put_user(mcs->call.args[5], &call_list[i].args[5])) )
+        if(VMX_DOMAIN(current)) 
+        {
+            rc = copy_to_guest(&call_list[i].args[5], &mcs->call.args[5], 
+                               sizeof(mcs->call.args[5]));
+        }
+        else
+        {
+            rc  = __put_user(mcs->call.args[5], &call_list[i].args[5]);
+        }
+
+        if ( unlikely(rc) )
         {
             DPRINTK("Error writing result back to multicall block.\n");
             goto fault;
         }
 
-        if ( hypercall_preempt_check() )
+        if ( hypercall_preempt_check() && !VMX_DOMAIN(current))
         {
             /*
              * Copy the sub-call continuation if it was preempted.
@@ -57,9 +76,15 @@
              */
             if ( !test_bit(_MCSF_call_preempted, &mcs->flags) )
                 i++;
-            else
-                (void)__copy_to_user(&call_list[i], &mcs->call,
+            else 
+            {
+                if(VMX_DOMAIN(current))
+                    (void)copy_to_guest(&call_list[i], &mcs->call,
+                                     sizeof(*call_list));
+                 else
+                     (void)__copy_to_user(&call_list[i], &mcs->call,
                                      sizeof(*call_list));
+            }
 
             /* Only create a continuation if there is work left to be done. */
             if ( i < nr_calls )
diff -Nru a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/asm-x86/domain.h	2005-05-20 15:19:36 +08:00
@@ -117,6 +117,10 @@
 
     /* Current LDT details. */
     unsigned long shadow_ldt_mapcnt;
+ 
+    /* callback irq for virtual device in unmodified linux*/
+    unsigned int callback_irq;
+ 
 } __cacheline_aligned;
 
 #define IDLE0_ARCH_EXEC_DOMAIN                                      \
diff -Nru a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/asm-x86/mm.h	2005-05-20 15:19:36 +08:00
@@ -272,6 +272,23 @@
     
     return mfn; 
 }
+
+static inline unsigned long set_phystomachine(unsigned long pfn, 
+                                              unsigned long ma) 
+{
+    l1_pgentry_t pte;
+    if (__copy_from_user(&pte, (__phys_to_machine_mapping + pfn), 
+                        sizeof(pte))) {
+        return 0;
+    }
+
+    pte = l1e_create_pfn(ma, l1e_get_flags(pte));
+    if(__copy_to_user((__phys_to_machine_mapping + pfn), &pte, sizeof(pte)))
+        return 0;
+
+    return ma;
+}
+
 #define set_machinetophys(_mfn, _pfn) machine_to_phys_mapping[(_mfn)] = (_pfn)
 
 #ifdef MEMORY_GUARD
@@ -362,4 +379,9 @@
                             l1_pgentry_t _nl1e, 
                             struct domain *d,
                             struct exec_domain *ed);
+
+void page_info_mfn(char *s, unsigned long mfn);
+void page_info_pte(char *s, l1_pgentry_t pte);
+
+
 #endif /* __ASM_X86_MM_H__ */
diff -Nru a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/asm-x86/shadow.h	2005-05-20 15:19:36 +08:00
@@ -106,6 +106,7 @@
 
 extern void shadow_mode_init(void);
 extern int shadow_mode_control(struct domain *p, dom0_shadow_control_t *sc);
+extern int map_sharepage_to_guest(unsigned long va, unsigned long ma);
 extern int shadow_fault(unsigned long va, struct cpu_user_regs *regs);
 extern int shadow_mode_enable(struct domain *p, unsigned int mode);
 extern void shadow_invlpg(struct exec_domain *, unsigned long);
@@ -593,6 +594,9 @@
            __func__, page_to_pfn(page));
     printk("Before: mfn=%lx c=%08x t=%08x\n", page_to_pfn(page),
            page->count_info, page->u.inuse.type_info);
+
+    if(shadow_mode_external(d))
+        return;
 
     shadow_lock(d);
     shadow_remove_all_access(d, page_to_pfn(page));
diff -Nru a/xen/include/asm-x86/vmx_vmcs.h b/xen/include/asm-x86/vmx_vmcs.h
--- a/xen/include/asm-x86/vmx_vmcs.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/asm-x86/vmx_vmcs.h	2005-05-20 15:19:36 +08:00
@@ -185,6 +185,8 @@
 #define DBG_LEVEL_3     (1 << 3)
 #define DBG_LEVEL_IO    (1 << 4)
 #define DBG_LEVEL_VMMU  (1 << 5)
+#define DBG_LEVEL_VBD  (1 << 6)
+#define DBG_LEVEL_VNIF  (1 << 7)
 
 extern unsigned int opt_vmx_debug_level;
 #define VMX_DBG_LOG(level, _f, _a...)           \
diff -Nru a/xen/include/asm-x86/x86_32/uaccess.h b/xen/include/asm-x86/x86_32/uaccess.h
--- a/xen/include/asm-x86/x86_32/uaccess.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/asm-x86/x86_32/uaccess.h	2005-05-20 15:19:36 +08:00
@@ -332,6 +332,11 @@
 unsigned long copy_from_user(void *to,
                              const void __user *from, unsigned long n);
 
+unsigned long copy_to_guest(void __user *to, 
+                            const void *from, unsigned long n);
+unsigned long copy_from_guest(void *to,
+                              const void __user *from, unsigned long n);
+
 unsigned long clear_user(void __user *mem, unsigned long len);
 unsigned long __clear_user(void __user *mem, unsigned long len);
 
diff -Nru a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h
--- a/xen/include/asm-x86/x86_64/uaccess.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/asm-x86/x86_64/uaccess.h	2005-05-20 15:19:36 +08:00
@@ -224,6 +224,11 @@
 unsigned long copy_to_user(void __user *to, const void *from, unsigned len); 
 unsigned long copy_from_user(void *to, const void __user *from, unsigned len); 
 
+unsigned long copy_to_guest(void __user *to, 
+                            const void *from, unsigned long n);
+unsigned long copy_from_guest(void *to,
+                              const void __user *from, unsigned long n);
+
 static always_inline int __copy_from_user(void *dst, const void __user *src, unsigned size) 
 { 
     int ret = 0;
diff -Nru a/xen/include/public/arch-x86_32.h b/xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/public/arch-x86_32.h	2005-05-20 15:19:36 +08:00
@@ -57,7 +57,12 @@
 #define FLAT_USER_SS    FLAT_RING3_SS
 
 /* And the trap vector is... */
+#if defined (CONFIG_VMX_GUEST)
+/*for VMX paravirtualized driver*/
+#define TRAP_INSTR	".byte 0x0f,0x01,0xc1\n"
+#else
 #define TRAP_INSTR "int $0x82"
+#endif
 
 
 /*
diff -Nru a/xen/include/public/xen.h b/xen/include/public/xen.h
--- a/xen/include/public/xen.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/public/xen.h	2005-05-20 15:19:36 +08:00
@@ -58,6 +58,7 @@
 #define __HYPERVISOR_boot_vcpu            24
 #define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
 #define __HYPERVISOR_mmuext_op            26
+#define __HYPERVISOR_virtual_device_op    28	
 
 /*
  * MULTICALLS
@@ -244,6 +245,16 @@
 #define VMASST_TYPE_writable_pagetables  2
 #define MAX_VMASST_TYPE 2
 
+/*
+ * Commands to HYPERVISOR_virtual_device_op().
+ */
+
+#define SET_SHAREINFO_MAP   1
+#define ADDR_MACHTOPHYS     2
+#define ADDR_PHYSTOMACH     3
+#define SET_PHYSTOMACH     4
+#define SET_CALLBACK_IRQ    5
+
 #ifndef __ASSEMBLY__
 
 typedef u16 domid_t;
@@ -332,7 +343,8 @@
      */
     u8 evtchn_upcall_pending;           /* 0 */
     u8 evtchn_upcall_mask;              /* 1 */
-    u8 pad0, pad1;
+    u8 callback_mask;                   /* 2 */ 
+    u8 pad1;
     u32 evtchn_pending_sel;             /* 4 */
     arch_vcpu_info_t arch;              /* 8 */
 } PACKED vcpu_info_t;                   /* 8 + arch */
diff -Nru a/xen/include/xen/config.h b/xen/include/xen/config.h
--- a/xen/include/xen/config.h	2005-05-20 15:19:36 +08:00
+++ b/xen/include/xen/config.h	2005-05-20 15:19:36 +08:00
@@ -36,6 +36,14 @@
 #define DPRINTK(_f, _a...) ((void)0)
 #endif
 
+#ifdef VERBOSE
+#define VNIFPRINTK(_a...) \
+     if(VMX_DOMAIN(current))  \
+        printk(_a);
+#else
+#define VNIFPRINTK(_a...) 
+#endif
+
 #ifndef __ASSEMBLY__
 #include <xen/compiler.h>
 #endif

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-05-25  2:19 ` Ling, Xiaofeng
  2005-05-25  3:33   ` aq
  0 siblings, 1 reply; 14+ messages in thread
From: Ling, Xiaofeng @ 2005-05-25  2:19 UTC (permalink / raw)
  To: Ian Pratt; +Cc: xen-devel

Is there any comment for this patch?
Is it acceptable or not?

Xiaofeng Ling <> wrote:
> This patch adds paravirutulization driver support for vmx domain in
> hypervisor.  The VBD and VNIF frontend driver can then be used in
> unmodified kernel as a module to get better performance than device
> model. The backend driver needs no change and can work together with
> xeno-linux.   
> The event channel mechanism works as a pci device in guest linux, so
> a event channel device driver will as basic module in guest kernel. 
> 
> What's the patch done is:
> 1.copy_to/from_guest support, which is used to copy context from/to
> guest space to hypervisor space. 
> 2.copy_to/from_user will call copy_to/from_guest for a vmx domain.
> 3.A separate hypercall table for paravirutulization driver which mask
> some unused entries. 
> 4.add hypercalls for address translation.and share page mapping (event
>   channel and grant table)
> 5.clean some hypercalls path for vmx domain.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
  2005-05-25  2:19 ` Ling, Xiaofeng
@ 2005-05-25  3:33   ` aq
  0 siblings, 0 replies; 14+ messages in thread
From: aq @ 2005-05-25  3:33 UTC (permalink / raw)
  To: Ling, Xiaofeng; +Cc: Ian Pratt, xen-devel

On 5/25/05, Ling, Xiaofeng <xiaofeng.ling@intel.com> wrote:
> Is there any comment for this patch?
> Is it acceptable or not?

yes, i have the same question. sometimes patches sent to the list
receive no comment. that means they are in queu for review, and get
feedbacks later? or we should re-send the patches to the list (as in
LKML) ?

i think the policy of accepting patches should be made clear, and put
into the FAQ. that would be appreciated by contributors.

thank you,
aq

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-05-25  5:00 Ian Pratt
  0 siblings, 0 replies; 14+ messages in thread
From: Ian Pratt @ 2005-05-25  5:00 UTC (permalink / raw)
  To: Ling, Xiaofeng; +Cc: xen-devel

 

> Is there any comment for this patch?
> Is it acceptable or not?

I think it needs a more work. Using grant tables should help unify
things. I'm convinced that you're missing out on some unifying paradigm
that will cause many of the "if(VMX_DOMAIN(current))" clauses to
evaporate. 

I'll think a bit more about this and get back to you.

BTW: have you performance figures?

Best,
Ian

 
> Xiaofeng Ling <> wrote:
> > This patch adds paravirutulization driver support for vmx domain in 
> > hypervisor.  The VBD and VNIF frontend driver can then be used in 
> > unmodified kernel as a module to get better performance than device 
> > model. The backend driver needs no change and can work together with
> > xeno-linux.   
> > The event channel mechanism works as a pci device in guest 
> linux, so a 
> > event channel device driver will as basic module in guest kernel.
> > 
> > What's the patch done is:
> > 1.copy_to/from_guest support, which is used to copy context from/to 
> > guest space to hypervisor space.
> > 2.copy_to/from_user will call copy_to/from_guest for a vmx domain.
> > 3.A separate hypercall table for paravirutulization driver 
> which mask 
> > some unused entries.
> > 4.add hypercalls for address translation.and share page 
> mapping (event
> >   channel and grant table)
> > 5.clean some hypercalls path for vmx domain.
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-05-25  5:14 Ian Pratt
  0 siblings, 0 replies; 14+ messages in thread
From: Ian Pratt @ 2005-05-25  5:14 UTC (permalink / raw)
  To: aq, Ling, Xiaofeng; +Cc: xen-devel

 

> On 5/25/05, Ling, Xiaofeng <xiaofeng.ling@intel.com> wrote:
> > Is there any comment for this patch?
> > Is it acceptable or not?
> 
> yes, i have the same question. sometimes patches sent to the 
> list receive no comment. that means they are in queu for 
> review, and get feedbacks later? or we should re-send the 
> patches to the list (as in
> LKML) ?

It's safest to assume that this is a lossy communication channel: If
after a few days you haven't heard anything and the patch hasn't been
checked in, please send a follow up message. 

BTW: It's very helpful if the patch contains a good description of what
it does and the rational behind the design, either in the changelog or
in comments as appropriate. This save a lot of review time.

Further it would make our lives a lot easier if people at least checked
that patches build and work on both x86 and x86_64. Building with an
ia64 cross compiler would be good too, but I must admit that we don't
usually do this, though we'll probably have to once ia64 gets a larger
user community.

Thanks,
Ian
 
> i think the policy of accepting patches should be made clear, 
> and put into the FAQ. that would be appreciated by contributors.
> 
> thank you,
> aq
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-05-25  6:26 Ling, Xiaofeng
  2005-05-25  7:54 ` Keir Fraser
  0 siblings, 1 reply; 14+ messages in thread
From: Ling, Xiaofeng @ 2005-05-25  6:26 UTC (permalink / raw)
  To: Ian Pratt; +Cc: xen-devel



Ian Pratt <mailto:m+Ian.Pratt@cl.cam.ac.uk> wrote:
>> Is there any comment for this patch?
>> Is it acceptable or not?
> 
> I think it needs a more work. Using grant tables should help unify
The grant table support is already in for vbd. and without grant table
configuration can also work.

> things. I'm convinced that you're missing out on some unifying
> paradigm that will cause many of the "if(VMX_DOMAIN(current))"
> clauses to evaporate.   
Most of the VMX_DOMAIN is used for copy_to/from_user, __get_user/__put_user
things.
Because VMX domain has separate address space. these function can not be used directly.
I've add a condition in copy_to/from_user, but some place, it uses separated array_access_ok  and __copy_to/from_user. 
For  __get_user/__put_user, in some place, that can still be used, like linear page table, some place,
that must be replaced with copy_to/from_guest.
So do you have better idea to deal with these things?
Or we use shadow_mode_external() to separate the path?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
  2005-05-25  6:26 [PATCH]vbd/vnif paravirtulization driver hypervisorsupport] Ling, Xiaofeng
@ 2005-05-25  7:54 ` Keir Fraser
  2005-06-03  2:40   ` Xiaofeng Ling
  0 siblings, 1 reply; 14+ messages in thread
From: Keir Fraser @ 2005-05-25  7:54 UTC (permalink / raw)
  To: Ling, Xiaofeng; +Cc: Ian Pratt, xen-devel


On 25 May 2005, at 07:26, Ling, Xiaofeng wrote:

> Or we use shadow_mode_external() to separate the path?

That would make sense. Also push the test into the copy routines 
themselves.

entry.S is a big mess now. Consider pulling *all* the vmx stuff out 
into vmx.S.

  -- Keir

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-05-25  8:16 Ling, Xiaofeng
  0 siblings, 0 replies; 14+ messages in thread
From: Ling, Xiaofeng @ 2005-05-25  8:16 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Ian Pratt, xen-devel



Keir Fraser <mailto:Keir.Fraser@cl.cam.ac.uk> wrote:
> On 25 May 2005, at 07:26, Ling, Xiaofeng wrote:
> 
>> Or we use shadow_mode_external() to separate the path?
> 
> That would make sense. Also push the test into the copy routines
> themselves. 
As I mentioned, that can not work for all the case, some place that need
the orginal copy like linear page table, so I only put the test in copy_to/from_user,
and not __copy_to/from_user. and put/get_user

> entry.S is a big mess now. Consider pulling *all* the vmx stuff out
> into vmx.S. 
This patch only add a vmx_hypercall_table, if you don't like two tables
how about have a bitmap for the hypercall table to allow or prohibit the call
from vmx domain instead?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
  2005-05-25  7:54 ` Keir Fraser
@ 2005-06-03  2:40   ` Xiaofeng Ling
  2005-06-03  7:58     ` Keir Fraser
  0 siblings, 1 reply; 14+ messages in thread
From: Xiaofeng Ling @ 2005-06-03  2:40 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Ian Pratt, xen-devel

[-- Attachment #1: Type: text/plain, Size: 476 bytes --]

It's now all use shadow_mode_external, and use a permit bitmap for 
hypercall from vmx domain.
Do you think it's now acceptable?
It's against 1657.

Keir Fraser wrote:
> 
> On 25 May 2005, at 07:26, Ling, Xiaofeng wrote:
> 
>> Or we use shadow_mode_external() to separate the path?
> 
> 
> That would make sense. Also push the test into the copy routines 
> themselves.
> 
> entry.S is a big mess now. Consider pulling *all* the vmx stuff out into 
> vmx.S.
> 
>  -- Keir
> 


[-- Attachment #2: paravirtulization-driver-hypervisor-update5.patch --]
[-- Type: text/x-patch, Size: 30549 bytes --]

===== xen/arch/x86/domain.c 1.206 vs edited =====
--- 1.206/xen/arch/x86/domain.c	2005-06-03 05:05:30 +08:00
+++ edited/xen/arch/x86/domain.c	2005-06-03 10:24:26 +08:00
@@ -252,6 +252,7 @@
     v->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] =
         l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR);
 
+    v->arch.callback_irq = 0;
     v->arch.guest_vtable  = __linear_l2_table;
     v->arch.shadow_vtable = __shadow_linear_l2_table;
 
===== xen/arch/x86/mm.c 1.174 vs edited =====
--- 1.174/xen/arch/x86/mm.c	2005-06-03 05:05:30 +08:00
+++ edited/xen/arch/x86/mm.c	2005-06-03 10:13:09 +08:00
@@ -1975,23 +1975,35 @@
     perfc_addc(num_page_updates, count);
     perfc_incr_histo(bpt_updates, count, PT_UPDATES);
 
-    if ( unlikely(!array_access_ok(ureqs, count, sizeof(req))) )
+    if(likely(!shadow_mode_external(current->domain)) &&
+             unlikely(!array_access_ok(ureqs, count, sizeof(req))) )
     {
+
         rc = -EFAULT;
         goto out;
+
     }
 
     for ( i = 0; i < count; i++ )
     {
-        if ( hypercall_preempt_check() )
+        if(shadow_mode_external(current->domain))
         {
-            rc = hypercall4_create_continuation(
-                __HYPERVISOR_mmu_update, ureqs, 
-                (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
-            break;
+
+             rc = copy_from_guest(&req, ureqs, sizeof(req));
         }
+        else
+        {
+            if ( hypercall_preempt_check() )
+            {
+                rc = hypercall4_create_continuation(
+                        __HYPERVISOR_mmu_update, ureqs, 
+                        (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
+                break;
+            }
+            rc = __copy_from_user(&req, ureqs, sizeof(req));
 
-        if ( unlikely(__copy_from_user(&req, ureqs, sizeof(req)) != 0) )
+        }
+        if ( unlikely(rc) != 0) 
         {
             MEM_LOG("Bad __copy_from_user");
             rc = -EFAULT;
@@ -2140,7 +2152,8 @@
                 break;
             }
 
-            if ( unlikely(shadow_mode_translate(FOREIGNDOM) && !IS_PRIV(d)) )
+            if ( unlikely(shadow_mode_translate(FOREIGNDOM) && !IS_PRIV(d) 
+                          && !shadow_mode_external(FOREIGNDOM)) )
             {
                 MEM_LOG("can't mutate the m2p of translated guests");
                 break;
@@ -2247,7 +2260,6 @@
     return rc;
 }
 
-
 int do_update_va_mapping(unsigned long va,
                          unsigned long val32,
                          unsigned long flags)
@@ -2271,9 +2283,12 @@
     if ( unlikely(shadow_mode_enabled(d)) )
         check_pagetable(v, "pre-va"); /* debug */
 
-    if ( unlikely(!mod_l1_entry(&linear_pg_table[l1_linear_offset(va)],
-                                val)) )
-        rc = -EINVAL;
+    if ( !shadow_mode_external(d) )
+    {
+        if ( unlikely(!mod_l1_entry(&linear_pg_table[l1_linear_offset(va)],
+                        val)) )
+            rc = -EINVAL;
+    }
 
     if ( likely(rc == 0) && unlikely(shadow_mode_enabled(d)) )
     {
===== xen/arch/x86/shadow.c 1.118 vs edited =====
--- 1.118/xen/arch/x86/shadow.c	2005-06-03 05:05:30 +08:00
+++ edited/xen/arch/x86/shadow.c	2005-06-03 10:17:49 +08:00
@@ -2755,6 +2755,7 @@
     struct domain *d = v->domain;
     l1_pgentry_t spte;
     int rc = 0;
+    unsigned long gpa, mfn;
 
     shadow_lock(d);
 
@@ -2766,7 +2767,30 @@
     //
     __shadow_sync_va(v, va);
 
-    l1pte_propagate_from_guest(d, val, &spte);
+     
+    if(!shadow_mode_external(v->domain))
+    {
+        l1pte_propagate_from_guest(d, val, &spte);
+    }
+    else
+    {
+        gpa = gva_to_gpa(va);
+        mfn = l1e_get_pfn(val);
+        if(gpa) 
+        {
+            if(l1e_get_intpte(val))
+            {
+                set_phystomachine(gpa >> PAGE_SHIFT, 
+                        mfn);
+            }
+            else
+                set_phystomachine(gpa >> PAGE_SHIFT, INVALID_MFN);
+        }
+
+        spte = val;
+
+    }
+
     shadow_set_l1e(va, spte, 0);
 
     /*
===== xen/arch/x86/vmx.c 1.65 vs edited =====
--- 1.65/xen/arch/x86/vmx.c	2005-06-03 05:05:31 +08:00
+++ edited/xen/arch/x86/vmx.c	2005-06-03 10:27:42 +08:00
@@ -37,6 +37,7 @@
 #include <asm/vmx_vmcs.h>
 #include <asm/vmx_intercept.h>
 #include <asm/shadow.h>
+#include <asm/bitops.h>
 #include <public/io/ioreq.h>
 
 #ifdef CONFIG_VMX
@@ -1046,9 +1047,12 @@
 char print_buf[BUF_SIZ];
 static int index;
 
-static void vmx_print_line(const char c, struct vcpu *d) 
+asmlinkage unsigned long do_vmx_print_line(unsigned long ch) 
 {
 
+#if VMX_DEBUG
+    char c = (char)ch;
+    struct vcpu *d = current;
     if (index == MAX_LINE || c == '\n') {
         if (index == MAX_LINE) {
             print_buf[index++] = c;
@@ -1059,7 +1063,55 @@
     }
     else
         print_buf[index++] = c;
+    return 0;
+#endif
+    return -ENOSYS;
+}
+
+unsigned char vmx_hypercall_permit[NR_hypercalls/sizeof(unsigned char)] = 
+{
+    0x2,     /* do_mmu_update */
+    0x70,    /* do_dom_mem_op          12
+                do_multicall           13
+                do_update_va_mapping   14
+             */
+    0x13,    /* do_event_channel_op 16
+                do_xen_version      17
+                do_grant_table_op   20 
+             */
+    0x10     /* do_virtual_device_op 28*/
+};
+#if defined(__i386__)
+void vmx_do_hypercall(struct cpu_user_regs *pregs)
+{
+    unsigned long retcode;
+
+    /* Check whether this hypercall is permited from vmx domain*/
+    if(unlikely(!test_bit(pregs->eax, &vmx_hypercall_permit[0]))){
+        printk("not permit hypercall, %d\n", pregs->eax);
+        return;
+    }
+    __asm__ __volatile__(
+        "pushl %6\n\t"
+        "pushl %5\n\t"
+        "pushl %4\n\t"
+        "pushl %3\n\t"
+        "pushl %2\n\t"
+        "call *(hypercall_table)(,%0,4)\n\t"
+        "addl $20, %%esp\n\t"
+        :"=&a"(retcode)
+        :"0"(pregs->eax), "r"(pregs->ebx), "r"(pregs->ecx),
+         "r"(pregs->edx), "r"(pregs->esi), "r"(pregs->edi)
+    );
+    pregs->eax = retcode;
+    return;
+}
+#else
+void vmx_do_hypercall(struct cpu_user_regs *pregs)
+{
+    printk("not supported yet!\n");
 }
+#endif
 
 void save_vmx_cpu_user_regs(struct cpu_user_regs *ctxt)
 {
@@ -1300,7 +1352,7 @@
         __vmread(GUEST_EIP, &eip);
         __vmread(EXIT_QUALIFICATION, &exit_qualification);
 
-        vmx_print_line(regs.eax, v); /* provides the current domain */
+        vmx_do_hypercall(&regs);
         __update_guest_eip(inst_len);
         break;
     case EXIT_REASON_CR_ACCESS:
@@ -1364,6 +1416,56 @@
 #endif
 
 }
+
+int do_update_va_mapping(unsigned long va,
+                         l1_pgentry_t  val, 
+                         unsigned long flags);
+/* 
+ * The va must be a page start address
+ */
+int map_sharepage_to_guest(unsigned long gva, unsigned long shared)
+{
+    l1_pgentry_t val, gpte; 
+    gpte = gva_to_gpte(gva);
+    val = l1e_from_paddr((__pa(shared)), l1e_get_flags(gpte));
+    return do_update_va_mapping(gva, val, 0);
+}
+  
+asmlinkage unsigned long do_virtual_device_op(unsigned long op, 
+                                              unsigned long arg1, 
+                                              unsigned arg2)
+{
+    switch (op) 
+    {
+        case SET_SHAREINFO_MAP:
+            return map_sharepage_to_guest(arg1, 
+                        (unsigned long)current->domain->shared_info);
+        case SET_CALLBACK_IRQ:
+            if(arg1)
+                current->arch.callback_irq = 0x20+arg1;
+            else
+                current->arch.callback_irq = 0;
+            return 0;
+        case ADDR_MACHTOPHYS: 
+        {
+            unsigned long phys = 
+                __mfn_to_gpfn(current->domain, arg1 >> PAGE_SHIFT);
+            phys = (phys << PAGE_SHIFT) | (arg1 & ~PAGE_MASK);
+            return phys;
+        }
+        case ADDR_PHYSTOMACH:
+        {
+            unsigned long machine = 
+                __gpfn_to_mfn(current->domain, arg1 >> PAGE_SHIFT);
+            machine = (machine << PAGE_SHIFT) | (arg1 & ~PAGE_MASK);
+            return machine;
+        }
+        default:
+            printk("Not supported virtual device operation\n");
+    }
+    return 0L;
+}
+
 
 #endif /* CONFIG_VMX */
 
===== xen/arch/x86/vmx_intercept.c 1.12 vs edited =====
--- 1.12/xen/arch/x86/vmx_intercept.c	2005-06-03 05:05:31 +08:00
+++ edited/xen/arch/x86/vmx_intercept.c	2005-06-03 10:28:09 +08:00
@@ -28,6 +28,7 @@
 #include <xen/lib.h>
 #include <xen/sched.h>
 #include <asm/current.h>
+#include <xen/event.h>
 
 #ifdef CONFIG_VMX
 
@@ -196,6 +197,7 @@
     /* Set the pending intr bit, and send evtchn notification to myself. */
     if (test_and_set_bit(vpit->vector, vpit->intr_bitmap))
         vpit->pending_intr_nr++; /* already set, then count the pending intr */
+    evtchn_set_pending(vpit->v, IOPACKET_PORT);
 
     set_ac_timer(&vpit->pit_timer, NOW() + MILLISECS(vpit->period));
 }
@@ -247,6 +249,7 @@
         }
 
         vpit->intr_bitmap = intr;
+        vpit->v = d;
 
         /* set up the actimer */
         init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, 0);
===== xen/arch/x86/vmx_io.c 1.31 vs edited =====
--- 1.31/xen/arch/x86/vmx_io.c	2005-06-03 05:25:14 +08:00
+++ edited/xen/arch/x86/vmx_io.c	2005-06-03 10:33:20 +08:00
@@ -417,11 +417,53 @@
     return ((eflags & X86_EFLAGS_IF) == 0);
 }
 
+int vmx_event_to_irq(struct vcpu *v) 
+{
+    vcpu_iodata_t *vio;
+
+    if(unlikely(v->arch.callback_irq == 0)) {
+        printk("try to inject callback =0!!!\n");
+        printk("pending: %x, sel: %x, pending[0]:%x\n", 
+               v->vcpu_info->evtchn_upcall_pending,
+               v->vcpu_info->evtchn_pending_sel,
+               v->domain->shared_info->evtchn_pending[0]);  
+        return 0;
+    }
+    vio = (vcpu_iodata_t *) v->arch.arch_vmx.vmx_platform.shared_page_va;
+    if (vio == 0) {
+        VMX_DBG_LOG(DBG_LEVEL_VBD, 
+                "bad shared page: %lx\n", (unsigned long) vio);
+        domain_crash();
+    }
+    /*
+     * the event is only for guest, just set callback interrupt 
+     * bit  and return
+     */
+    return test_and_set_bit(v->arch.callback_irq, &vio->vp_intr[0]);
+
+}
+
+void vmx_check_guest_event(struct vcpu *v)
+{
+    if (!v->domain->shared_info->evtchn_pending[IOPACKET_PORT>>5])
+        clear_bit(IOPACKET_PORT>>5, &v->vcpu_info->evtchn_pending_sel);
+
+    /* Note: VMX domains may need upcalls as well */
+    if (!v->vcpu_info->evtchn_pending_sel) 
+        v->vcpu_info->evtchn_upcall_pending = 0;
+
+    if(event_pending(v) && !v->vcpu_info->callback_mask &&
+       !test_bit(IOPACKET_PORT, &v->domain->shared_info->evtchn_pending[0]) ) 
+        vmx_event_to_irq(v);
+}
+
 void vmx_intr_assist(struct vcpu *d) 
 {
     int highest_vector = find_highest_pending_irq(d);
     unsigned long intr_fields, eflags;
     struct vmx_virpit_t *vpit = &(d->arch.arch_vmx.vmx_platform.vmx_pit);
+
+    vmx_check_guest_event(d); /*inject para-device call back irq*/
 
     if (highest_vector == -1)
         return;
===== xen/arch/x86/x86_32/entry.S 1.112 vs edited =====
--- 1.112/xen/arch/x86/x86_32/entry.S	2005-06-03 05:05:31 +08:00
+++ edited/xen/arch/x86/x86_32/entry.S	2005-06-03 10:13:27 +08:00
@@ -735,7 +735,7 @@
         .long do_set_debugreg
         .long do_get_debugreg
         .long do_update_descriptor  /* 10 */
-        .long do_ni_hypercall
+        .long do_vmx_print_line
         .long do_dom_mem_op
         .long do_multicall
         .long do_update_va_mapping
@@ -751,6 +751,9 @@
         .long do_boot_vcpu
         .long do_ni_hypercall       /* 25 */
         .long do_mmuext_op
+        .long do_ni_hypercall       
+        .long do_virtual_device_op       /* virutal device op for VMX */
         .rept NR_hypercalls-((.-hypercall_table)/4)
         .long do_ni_hypercall
         .endr
+
===== xen/arch/x86/x86_32/usercopy.c 1.10 vs edited =====
--- 1.10/xen/arch/x86/x86_32/usercopy.c	2005-06-03 03:54:00 +08:00
+++ edited/xen/arch/x86/x86_32/usercopy.c	2005-06-03 10:13:28 +08:00
@@ -9,6 +9,8 @@
 #include <xen/config.h>
 #include <xen/lib.h>
 #include <asm/uaccess.h>
+#include <asm/domain_page.h>
+#include <asm/shadow.h>
 
 static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned long n)
 {
@@ -395,6 +397,98 @@
 	return n;
 }
 
+void* map_domain_vaddr(void * guest_vaddr, unsigned long len)
+{
+    l1_pgentry_t gpte;
+    unsigned long mfn;
+    unsigned long ma;
+    void * vstart;
+    
+    if (len > PAGE_SIZE) 
+    {
+        return NULL;
+    }
+ 
+    if (((unsigned long)guest_vaddr & PAGE_MASK) == 
+        (((unsigned long)guest_vaddr + len -1) & PAGE_MASK)) 
+    {
+        gpte = gva_to_gpte((unsigned long)guest_vaddr);
+        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+        ma = (mfn << PAGE_SHIFT) | 
+             ((unsigned long)guest_vaddr & (PAGE_SIZE - 1));
+        vstart = (void *)map_domain_mem(ma);
+    }
+    else 
+    {
+        return NULL;
+    }
+    return vstart;
+}
+
+unsigned long
+copy_from_guest(void *to, const void __user *from, unsigned long n)
+{
+    void *hfrom;    
+    unsigned long ncopy;
+    int nleft;
+    ncopy = (((unsigned long)from  + PAGE_SIZE) & PAGE_MASK) - 
+            (unsigned long)from;
+    ncopy = ncopy > n ? n : ncopy;  
+
+    for(nleft = n; nleft > 0; ncopy = nleft > PAGE_SIZE ? PAGE_SIZE : nleft) 
+    {
+        hfrom = map_domain_vaddr((void*)from, ncopy);
+        if(hfrom) 
+        {
+            memcpy(to, hfrom, ncopy);
+            unmap_domain_mem((void*)hfrom); 
+        }
+        else 
+        {
+            printk("error!, copy from guest map error, from:%p, ncopy:%ld\n", 
+                   from, ncopy);
+             return nleft;
+        }
+        nleft -= ncopy;
+        from += ncopy;
+        to += ncopy;
+    }
+    return nleft;
+}
+EXPORT_SYMBOL(copy_from_guest);
+
+unsigned long
+copy_to_guest(void __user *to, const void *from, unsigned long n)
+{
+    void *hto;  
+    unsigned long ncopy;
+    int nleft;
+
+    ncopy = (((unsigned long)to  + PAGE_SIZE) & PAGE_MASK) - (unsigned long)to;
+    ncopy = ncopy > n ? n : ncopy;  
+
+    for(nleft = n; nleft > 0; ncopy = nleft > PAGE_SIZE ? PAGE_SIZE : nleft) 
+    {
+        hto = map_domain_vaddr((void*)to, ncopy);
+        if(hto) 
+        {
+            memcpy(hto, from, ncopy);
+            unmap_domain_mem((void*)hto); 
+        }
+        else 
+        {
+            printk("error!, copy to guest map error, from:%p, ncopy:%ld\n", 
+                   from, ncopy);
+            return nleft;
+        }
+        nleft -= ncopy;
+        from += ncopy;
+        to += ncopy;
+    }
+    return nleft;
+}
+EXPORT_SYMBOL(copy_to_guest);
+
 /**
  * copy_to_user: - Copy a block of data into user space.
  * @to:   Destination address, in user space.
@@ -411,6 +505,8 @@
 unsigned long
 copy_to_user(void __user *to, const void *from, unsigned long n)
 {
+    if(shadow_mode_external(current->domain))
+        return copy_to_guest(to, from, n);
 	if (access_ok(to, n))
 		n = __copy_to_user(to, from, n);
 	return n;
@@ -435,6 +531,9 @@
 unsigned long
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+
+    if(shadow_mode_external(current->domain))
+        return copy_from_guest(to, from, n);
 	if (access_ok(from, n))
 		n = __copy_from_user(to, from, n);
 	else
===== xen/arch/x86/x86_64/usercopy.c 1.6 vs edited =====
--- 1.6/xen/arch/x86/x86_64/usercopy.c	2005-06-03 03:54:00 +08:00
+++ edited/xen/arch/x86/x86_64/usercopy.c	2005-06-03 10:13:30 +08:00
@@ -135,6 +135,21 @@
 	return n;
 }
 
+unsigned long
+copy_from_guest(void *to, const void __user *from, unsigned long n)
+{
+  return n;
+}
+EXPORT_SYMBOL(copy_from_guest);
+
+unsigned long
+copy_to_guest(void __user *to, const void *from, unsigned long n)
+{
+    return n;
+}
+EXPORT_SYMBOL(copy_to_guest);
+
+
 /**
  * copy_to_user: - Copy a block of data into user space.
  * @to:   Destination address, in user space.
===== xen/common/dom_mem_ops.c 1.58 vs edited =====
--- 1.58/xen/common/dom_mem_ops.c	2005-06-03 05:24:41 +08:00
+++ edited/xen/common/dom_mem_ops.c	2005-06-03 10:13:31 +08:00
@@ -82,15 +82,21 @@
     struct pfn_info *page;
     unsigned long    i, j, mpfn;
 
-    if ( !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
+    if ( !shadow_mode_external(current->domain) && 
+         unlikely(!array_access_ok(extent_list, nr_extents, 
+                                   sizeof(*extent_list))) )
         return start_extent;
 
     for ( i = start_extent; i < nr_extents; i++ )
     {
-        PREEMPT_CHECK(MEMOP_decrease_reservation);
-
-        if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) )
-            return i;
+        if( shadow_mode_external(current->domain)) {
+            if(copy_from_guest(&mpfn, &extent_list[i], sizeof(mpfn)) != 0)
+                return i;
+        } else {
+            PREEMPT_CHECK(MEMOP_decrease_reservation);
+           if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) )
+                return i;
+        }
 
         for ( j = 0; j < (1 << extent_order); j++ )
         {
@@ -102,6 +108,7 @@
             }
             
             page = &frame_table[mpfn + j];
+
             if ( unlikely(!get_page(page, d)) )
             {
                 DPRINTK("Bad page free for domain %u\n", d->domain_id);
===== xen/common/grant_table.c 1.46 vs edited =====
--- 1.46/xen/common/grant_table.c	2005-06-03 05:05:31 +08:00
+++ edited/xen/common/grant_table.c	2005-06-03 10:13:32 +08:00
@@ -160,7 +160,10 @@
 
         /* rmb(); */ /* not on x86 */
 
-        frame = __gpfn_to_mfn_foreign(granting_d, sha->frame);
+        if(!shadow_mode_translate(granting_d))
+            frame = __gpfn_to_mfn_foreign(granting_d, sha->frame);
+        else
+            frame = sha->frame;
 
         if ( unlikely(!pfn_valid(frame)) ||
              unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
@@ -669,7 +672,8 @@
     {
         DPRINTK("Xen only supports up to %d grant-table frames per domain.\n",
                 NR_GRANT_FRAMES);
-        (void)put_user(GNTST_general_error, &uop->status);
+        op.status = GNTST_general_error;
+        (void)copy_to_user(uop, &op, sizeof(op));
         return 0;
     }
 
@@ -679,25 +683,44 @@
     }
     else if ( unlikely(!IS_PRIV(current->domain)) )
     {
-        (void)put_user(GNTST_permission_denied, &uop->status);
+        op.status = GNTST_permission_denied;
+        (void)copy_to_user(uop, &op, sizeof(op));
         return 0;
     }
 
     if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
     {
         DPRINTK("Bad domid %d.\n", op.dom);
-        (void)put_user(GNTST_bad_domain, &uop->status);
+        op.status = GNTST_bad_domain;
+        (void)copy_to_user(uop, &op, sizeof(op));
         return 0;
     }
 
     if ( op.nr_frames <= NR_GRANT_FRAMES )
     {
         ASSERT(d->grant_table != NULL);
-        (void)put_user(GNTST_okay, &uop->status);
-        for ( i = 0; i < op.nr_frames; i++ )
+        if(!shadow_mode_external(current->domain))
+        {
+            (void)put_user(GNTST_okay, &uop->status);
+            for ( i = 0; i < op.nr_frames; i++ )
             (void)put_user(
                 (virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT) + i,
                 &uop->frame_list[i]);
+        }
+        else
+        {
+            op.status = GNTST_okay;
+            for ( i = 0; i < op.nr_frames; i++ )
+            {
+               if(map_sharepage_to_guest((unsigned long)op.frame_list + i * PAGE_SIZE, (unsigned long)d->grant_table->shared + i * PAGE_SIZE))
+               {
+     
+                   op.status = GNTST_general_error;
+                   break;
+               }
+            }
+            (void)copy_to_user(uop, &op, sizeof(op));
+        }
     }
 
     put_domain(d);
===== xen/common/multicall.c 1.12 vs edited =====
--- 1.12/xen/common/multicall.c	2005-06-03 05:24:41 +08:00
+++ edited/xen/common/multicall.c	2005-06-03 10:14:26 +08:00
@@ -12,6 +12,7 @@
 #include <xen/multicall.h>
 #include <asm/current.h>
 #include <asm/hardirq.h>
+#include <asm/shadow.h>
 
 struct mc_state mc_state[NR_CPUS];
 
@@ -19,6 +20,7 @@
 {
     struct mc_state *mcs = &mc_state[smp_processor_id()];
     unsigned int     i;
+    int rc;
 
     if ( unlikely(__test_and_set_bit(_MCSF_in_multicall, &mcs->flags)) )
     {
@@ -26,7 +28,8 @@
         return -EINVAL;
     }
 
-    if ( unlikely(!array_access_ok(call_list, nr_calls, sizeof(*call_list))) )
+    if (likely(!shadow_mode_external(current->domain)) && 
+        unlikely(!array_access_ok(call_list, nr_calls, sizeof(*call_list))) )
     {
         DPRINTK("Bad memory range %p for %u*%u bytes.\n",
                 call_list, nr_calls, (unsigned int)sizeof(*call_list));
@@ -35,23 +38,41 @@
 
     for ( i = 0; i < nr_calls; i++ )
     {
-        if ( unlikely(__copy_from_user(&mcs->call, &call_list[i], 
-                                       sizeof(*call_list))) )
+        if(shadow_mode_external(current->domain)) 
+        {
+            rc = copy_from_guest(&mcs->call, &call_list[i], 
+                    sizeof(*call_list)); 
+        }
+        else
+            rc = __copy_from_user(&mcs->call, &call_list[i], 
+                    sizeof(*call_list));
+        if ( unlikely(rc) )
         {
             DPRINTK("Error copying from user range %p for %u bytes.\n",
                     &call_list[i], (unsigned int)sizeof(*call_list));
+
             goto fault;
         }
 
         do_multicall_call(&mcs->call);
 
-        if ( unlikely(__put_user(mcs->call.result, &call_list[i].result)) )
+        if(shadow_mode_external(current->domain)) 
+        {
+            rc = copy_to_guest(&call_list[i].result, &mcs->call.result, 
+                    sizeof(mcs->call.result));
+        }
+        else
+        {
+            rc = __put_user(mcs->call.result, &call_list[i].result); 
+        }
+
+        if ( unlikely(rc) )
         {
             DPRINTK("Error writing result back to multicall block.\n");
             goto fault;
         }
 
-        if ( hypercall_preempt_check() )
+        if ( hypercall_preempt_check() && !shadow_mode_external(current->domain))
         {
             /*
              * Copy the sub-call continuation if it was preempted.
@@ -59,16 +80,22 @@
              */
             if ( !test_bit(_MCSF_call_preempted, &mcs->flags) )
                 i++;
-            else
-                (void)__copy_to_user(&call_list[i], &mcs->call,
-                                     sizeof(*call_list));
+            else 
+            {
+                if(shadow_mode_external(current->domain))
+                    (void)copy_to_guest(&call_list[i], &mcs->call,
+                                        sizeof(*call_list));
+                else
+                    (void)__copy_to_user(&call_list[i], &mcs->call,
+                                         sizeof(*call_list));
+            }
 
             /* Only create a continuation if there is work left to be done. */
             if ( i < nr_calls )
             {
                 mcs->flags = 0;
                 return hypercall2_create_continuation(
-                    __HYPERVISOR_multicall, &call_list[i], nr_calls-i);
+                        __HYPERVISOR_multicall, &call_list[i], nr_calls-i);
             }
         }
     }
===== xen/include/asm-x86/domain.h 1.29 vs edited =====
--- 1.29/xen/include/asm-x86/domain.h	2005-06-03 05:05:31 +08:00
+++ edited/xen/include/asm-x86/domain.h	2005-06-03 10:13:35 +08:00
@@ -117,6 +117,10 @@
 
     /* Current LDT details. */
     unsigned long shadow_ldt_mapcnt;
+ 
+    /* callback irq for virtual device in unmodified linux*/
+    unsigned int callback_irq;
+ 
 } __cacheline_aligned;
 
 #endif /* __ASM_DOMAIN_H__ */
===== xen/include/asm-x86/mm.h 1.76 vs edited =====
--- 1.76/xen/include/asm-x86/mm.h	2005-06-03 05:05:31 +08:00
+++ edited/xen/include/asm-x86/mm.h	2005-06-03 10:15:15 +08:00
@@ -272,6 +272,23 @@
     
     return mfn; 
 }
+
+static inline unsigned long set_phystomachine(unsigned long pfn, 
+                                              unsigned long ma) 
+{
+    l1_pgentry_t pte;
+    if (__copy_from_user(&pte, (__phys_to_machine_mapping + pfn), 
+                        sizeof(pte))) {
+        return 0;
+    }
+
+    pte = l1e_from_paddr(ma, l1e_get_flags(pte));
+    if(__copy_to_user((__phys_to_machine_mapping + pfn), &pte, sizeof(pte)))
+        return 0;
+
+    return ma;
+}
+
 #define set_machinetophys(_mfn, _pfn) machine_to_phys_mapping[(_mfn)] = (_pfn)
 
 #ifdef MEMORY_GUARD
@@ -349,4 +366,8 @@
                             l1_pgentry_t _nl1e, 
                             struct domain *d,
                             struct vcpu *v);
+
+
+void page_info_mfn(char *s, unsigned long mfn);
+void page_info_pte(char *s, l1_pgentry_t pte);
 #endif /* __ASM_X86_MM_H__ */
===== xen/include/asm-x86/shadow.h 1.103 vs edited =====
--- 1.103/xen/include/asm-x86/shadow.h	2005-06-03 05:25:15 +08:00
+++ edited/xen/include/asm-x86/shadow.h	2005-06-03 10:13:39 +08:00
@@ -111,6 +111,7 @@
 
 extern void shadow_mode_init(void);
 extern int shadow_mode_control(struct domain *p, dom0_shadow_control_t *sc);
+extern int map_sharepage_to_guest(unsigned long va, unsigned long ma);
 extern int shadow_fault(unsigned long va, struct cpu_user_regs *regs);
 extern int shadow_mode_enable(struct domain *p, unsigned int mode);
 extern void shadow_invlpg(struct vcpu *, unsigned long);
@@ -600,6 +601,9 @@
            __func__, page_to_pfn(page));
     printk("Before: mfn=%lx c=%08x t=%08x\n", page_to_pfn(page),
            page->count_info, page->u.inuse.type_info);
+
+    if(shadow_mode_external(d))
+        return;
 
     shadow_lock(d);
     shadow_remove_all_access(d, page_to_pfn(page));
===== xen/include/asm-x86/vmx_virpit.h 1.3 vs edited =====
--- 1.3/xen/include/asm-x86/vmx_virpit.h	2005-06-03 05:05:31 +08:00
+++ edited/xen/include/asm-x86/vmx_virpit.h	2005-06-03 10:30:23 +08:00
@@ -33,6 +33,7 @@
 
     unsigned int count;		/* the 16 bit channel count */
     unsigned int init_val;	/* the init value for the counter */
+    struct vcpu *v;
 
 } ;
 
===== xen/include/asm-x86/vmx_vmcs.h 1.13 vs edited =====
--- 1.13/xen/include/asm-x86/vmx_vmcs.h	2005-06-03 05:05:31 +08:00
+++ edited/xen/include/asm-x86/vmx_vmcs.h	2005-06-03 10:13:40 +08:00
@@ -184,6 +184,8 @@
 #define DBG_LEVEL_3     (1 << 3)
 #define DBG_LEVEL_IO    (1 << 4)
 #define DBG_LEVEL_VMMU  (1 << 5)
+#define DBG_LEVEL_VBD  (1 << 6)
+#define DBG_LEVEL_VNIF  (1 << 7)
 
 extern unsigned int opt_vmx_debug_level;
 #define VMX_DBG_LOG(level, _f, _a...)           \
===== xen/include/asm-x86/x86_32/uaccess.h 1.19 vs edited =====
--- 1.19/xen/include/asm-x86/x86_32/uaccess.h	2005-04-23 00:34:08 +08:00
+++ edited/xen/include/asm-x86/x86_32/uaccess.h	2005-06-03 10:13:40 +08:00
@@ -332,6 +332,11 @@
 unsigned long copy_from_user(void *to,
                              const void __user *from, unsigned long n);
 
+unsigned long copy_to_guest(void __user *to, 
+                            const void *from, unsigned long n);
+unsigned long copy_from_guest(void *to,
+                              const void __user *from, unsigned long n);
+
 unsigned long clear_user(void __user *mem, unsigned long len);
 unsigned long __clear_user(void __user *mem, unsigned long len);
 
===== xen/include/asm-x86/x86_64/uaccess.h 1.15 vs edited =====
--- 1.15/xen/include/asm-x86/x86_64/uaccess.h	2005-04-19 21:48:04 +08:00
+++ edited/xen/include/asm-x86/x86_64/uaccess.h	2005-06-03 10:13:41 +08:00
@@ -224,6 +224,11 @@
 unsigned long copy_to_user(void __user *to, const void *from, unsigned len); 
 unsigned long copy_from_user(void *to, const void __user *from, unsigned len); 
 
+unsigned long copy_to_guest(void __user *to, 
+                            const void *from, unsigned long n);
+unsigned long copy_from_guest(void *to,
+                              const void __user *from, unsigned long n);
+
 static always_inline int __copy_from_user(void *dst, const void __user *src, unsigned size) 
 { 
     int ret = 0;
===== xen/include/public/arch-x86_32.h 1.39 vs edited =====
--- 1.39/xen/include/public/arch-x86_32.h	2005-06-01 17:49:23 +08:00
+++ edited/xen/include/public/arch-x86_32.h	2005-06-03 10:13:43 +08:00
@@ -57,7 +57,12 @@
 #define FLAT_USER_SS    FLAT_RING3_SS
 
 /* And the trap vector is... */
+#if defined (CONFIG_VMX_GUEST)
+/*for VMX paravirtualized driver*/
+#define TRAP_INSTR	".byte 0x0f,0x01,0xc1\n"
+#else
 #define TRAP_INSTR "int $0x82"
+#endif
 
 
 /*
===== xen/include/public/xen.h 1.127 vs edited =====
--- 1.127/xen/include/public/xen.h	2005-06-01 17:49:23 +08:00
+++ edited/xen/include/public/xen.h	2005-06-03 10:13:44 +08:00
@@ -42,6 +42,7 @@
 #define __HYPERVISOR_set_debugreg          8
 #define __HYPERVISOR_get_debugreg          9
 #define __HYPERVISOR_update_descriptor    10
+#define __HYPERVISOR_debug_printk         11
 #define __HYPERVISOR_dom_mem_op           12
 #define __HYPERVISOR_multicall            13
 #define __HYPERVISOR_update_va_mapping    14
@@ -58,6 +59,7 @@
 #define __HYPERVISOR_boot_vcpu            24
 #define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
 #define __HYPERVISOR_mmuext_op            26
+#define __HYPERVISOR_virtual_device_op    28	
 
 /* 
  * VIRTUAL INTERRUPTS
@@ -234,6 +236,16 @@
 #define VMASST_TYPE_writable_pagetables  2
 #define MAX_VMASST_TYPE 2
 
+/*
+ * Commands to HYPERVISOR_virtual_device_op().
+ */
+
+#define SET_SHAREINFO_MAP   1
+#define ADDR_MACHTOPHYS     2
+#define ADDR_PHYSTOMACH     3
+#define SET_PHYSTOMACH     4
+#define SET_CALLBACK_IRQ    5
+
 #ifndef __ASSEMBLY__
 
 typedef u16 domid_t;
@@ -322,7 +334,8 @@
      */
     u8 evtchn_upcall_pending;           /* 0 */
     u8 evtchn_upcall_mask;              /* 1 */
-    u8 pad0, pad1;
+    u8 callback_mask;                   /* 2 */ 
+    u8 pad1;
     u32 evtchn_pending_sel;             /* 4 */
     arch_vcpu_info_t arch;              /* 8 */
 } PACKED vcpu_info_t;                   /* 8 + arch */
===== xen/include/xen/config.h 1.41 vs edited =====
--- 1.41/xen/include/xen/config.h	2005-05-10 01:50:08 +08:00
+++ edited/xen/include/xen/config.h	2005-06-03 10:13:45 +08:00
@@ -36,6 +36,14 @@
 #define DPRINTK(_f, _a...) ((void)0)
 #endif
 
+#ifdef VERBOSE
+#define VNIFPRINTK(_a...) \
+     if(shadow_mode_external(current->domain))  \
+        printk(_a);
+#else
+#define VNIFPRINTK(_a...) 
+#endif
+
 #ifndef __ASSEMBLY__
 #include <xen/compiler.h>
 #endif

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
  2005-06-03  2:40   ` Xiaofeng Ling
@ 2005-06-03  7:58     ` Keir Fraser
  0 siblings, 0 replies; 14+ messages in thread
From: Keir Fraser @ 2005-06-03  7:58 UTC (permalink / raw)
  To: Xiaofeng Ling; +Cc: Ian Pratt, xen-devel


On 3 Jun 2005, at 03:40, Xiaofeng Ling wrote:

> It's now all use shadow_mode_external, and use a permit bitmap for 
> hypercall from vmx domain.
> Do you think it's now acceptable?
> It's against 1657.

Still messy imo. When I said to split the path by shadow_mode_externel, 
I meant you should do it within the uaccess macros/functions; not in 
their callers.

But I'm not sure that is the best way either. Since VMX uses so few 
hypercalls, and you can easily define a new hypercall jump table in C, 
why not jump at alternative wrappers for those hypercalls that do the 
correct copy to/from guest, and then share the common guts of the 
hypercall with the paravirtualised version? I guess it depends how 
embedded in the core of each hypercall the VMX changes are...

  -- Keir

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-06-03  8:22 Ling, Xiaofeng
  2005-06-09  1:28 ` Xiaofeng Ling
  0 siblings, 1 reply; 14+ messages in thread
From: Ling, Xiaofeng @ 2005-06-03  8:22 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Ian Pratt, xen-devel



Keir Fraser <mailto:Keir.Fraser@cl.cam.ac.uk> wrote:
> On 3 Jun 2005, at 03:40, Xiaofeng Ling wrote:
> 
>> It's now all use shadow_mode_external, and use a permit bitmap for
>> hypercall from vmx domain. Do you think it's now acceptable?
>> It's against 1657.
> 
> Still messy imo. When I said to split the path by
> shadow_mode_externel, I meant you should do it within the uaccess
> macros/functions; not in their callers.  
I've already done that for copy_from/to_user, 
but for __copy_from/to_user
I can not do that, because not all the caller shall call copy_from/to_guest

> But I'm not sure that is the best way either. Since VMX uses so few
> hypercalls, and you can easily define a new hypercall jump table in
> C, why not jump at alternative wrappers for those hypercalls that do
> the correct copy to/from guest, and then share the common guts of the
> hypercall with the paravirtualised version? I guess it depends how
> embedded in the core of each hypercall the VMX changes are...     
for  copy_from/to_user, I've already changed in the callee.
For __copy_from/to_user, they are embedded deep.




>   -- Keir

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
  2005-06-03  8:22 Ling, Xiaofeng
@ 2005-06-09  1:28 ` Xiaofeng Ling
  0 siblings, 0 replies; 14+ messages in thread
From: Xiaofeng Ling @ 2005-06-09  1:28 UTC (permalink / raw)
  To: Ling, Xiaofeng; +Cc: Ian Pratt, xen-devel

[-- Attachment #1: Type: text/plain, Size: 1081 bytes --]

I'd like to split the patch into small ones, so that it can be clearer.
Attach is the patch of adding support copy_to/from_guest.

Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>

  arch/x86/x86_32/usercopy.c       |   99 
+++++++++++++++++++++++++++++++++++++++
  arch/x86/x86_64/usercopy.c       |   15 +++++
  include/asm-x86/x86_32/uaccess.h |    5 +
  include/asm-x86/x86_64/uaccess.h |    5 +
  4 files changed, 124 insertions(+)


Ling, Xiaofeng wrote:
> 
> Keir Fraser <mailto:Keir.Fraser@cl.cam.ac.uk> wrote:
> 
>>On 3 Jun 2005, at 03:40, Xiaofeng Ling wrote:
>>
>>
>>>It's now all use shadow_mode_external, and use a permit bitmap for
>>>hypercall from vmx domain. Do you think it's now acceptable?
>>>It's against 1657.
>>guest
>>Still messy imo. When I said to split the path by
>>shadow_mode_externel, I meant you should do it within the uaccess
>>macros/functions; not in their callers.  guest
> 
> I've already done that for copy_from/to_user, 
> but for __copy_from/to_user
> I can not do that, because not all the caller shall call copy_from/to_guest
> 
> 

[-- Attachment #2: guestcopy.patch --]
[-- Type: text/x-patch, Size: 5584 bytes --]

===== xen/arch/x86/x86_32/usercopy.c 1.10 vs edited =====
--- 1.10/xen/arch/x86/x86_32/usercopy.c	2005-06-03 03:54:00 +08:00
+++ edited/xen/arch/x86/x86_32/usercopy.c	2005-06-03 10:13:28 +08:00
@@ -9,6 +9,8 @@
 #include <xen/config.h>
 #include <xen/lib.h>
 #include <asm/uaccess.h>
+#include <asm/domain_page.h>
+#include <asm/shadow.h>
 
 static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned long n)
 {
@@ -395,6 +397,98 @@
 	return n;
 }
 
+void* map_domain_vaddr(void * guest_vaddr, unsigned long len)
+{
+    l1_pgentry_t gpte;
+    unsigned long mfn;
+    unsigned long ma;
+    void * vstart;
+    
+    if (len > PAGE_SIZE) 
+    {
+        return NULL;
+    }
+ 
+    if (((unsigned long)guest_vaddr & PAGE_MASK) == 
+        (((unsigned long)guest_vaddr + len -1) & PAGE_MASK)) 
+    {
+        gpte = gva_to_gpte((unsigned long)guest_vaddr);
+        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+        ma = (mfn << PAGE_SHIFT) | 
+             ((unsigned long)guest_vaddr & (PAGE_SIZE - 1));
+        vstart = (void *)map_domain_mem(ma);
+    }
+    else 
+    {
+        return NULL;
+    }
+    return vstart;
+}
+
+unsigned long
+copy_from_guest(void *to, const void __user *from, unsigned long n)
+{
+    void *hfrom;    
+    unsigned long ncopy;
+    int nleft;
+    ncopy = (((unsigned long)from  + PAGE_SIZE) & PAGE_MASK) - 
+            (unsigned long)from;
+    ncopy = ncopy > n ? n : ncopy;  
+
+    for(nleft = n; nleft > 0; ncopy = nleft > PAGE_SIZE ? PAGE_SIZE : nleft) 
+    {
+        hfrom = map_domain_vaddr((void*)from, ncopy);
+        if(hfrom) 
+        {
+            memcpy(to, hfrom, ncopy);
+            unmap_domain_mem((void*)hfrom); 
+        }
+        else 
+        {
+            printk("error!, copy from guest map error, from:%p, ncopy:%ld\n", 
+                   from, ncopy);
+             return nleft;
+        }
+        nleft -= ncopy;
+        from += ncopy;
+        to += ncopy;
+    }
+    return nleft;
+}
+EXPORT_SYMBOL(copy_from_guest);
+
+unsigned long
+copy_to_guest(void __user *to, const void *from, unsigned long n)
+{
+    void *hto;  
+    unsigned long ncopy;
+    int nleft;
+
+    ncopy = (((unsigned long)to  + PAGE_SIZE) & PAGE_MASK) - (unsigned long)to;
+    ncopy = ncopy > n ? n : ncopy;  
+
+    for(nleft = n; nleft > 0; ncopy = nleft > PAGE_SIZE ? PAGE_SIZE : nleft) 
+    {
+        hto = map_domain_vaddr((void*)to, ncopy);
+        if(hto) 
+        {
+            memcpy(hto, from, ncopy);
+            unmap_domain_mem((void*)hto); 
+        }
+        else 
+        {
+            printk("error!, copy to guest map error, from:%p, ncopy:%ld\n", 
+                   from, ncopy);
+            return nleft;
+        }
+        nleft -= ncopy;
+        from += ncopy;
+        to += ncopy;
+    }
+    return nleft;
+}
+EXPORT_SYMBOL(copy_to_guest);
+
 /**
  * copy_to_user: - Copy a block of data into user space.
  * @to:   Destination address, in user space.
@@ -411,6 +505,8 @@
 unsigned long
 copy_to_user(void __user *to, const void *from, unsigned long n)
 {
+    if(shadow_mode_external(current->domain))
+        return copy_to_guest(to, from, n);
 	if (access_ok(to, n))
 		n = __copy_to_user(to, from, n);
 	return n;
@@ -435,6 +531,9 @@
 unsigned long
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+
+    if(shadow_mode_external(current->domain))
+        return copy_from_guest(to, from, n);
 	if (access_ok(from, n))
 		n = __copy_from_user(to, from, n);
 	else
===== xen/arch/x86/x86_64/usercopy.c 1.6 vs edited =====
--- 1.6/xen/arch/x86/x86_64/usercopy.c	2005-06-03 03:54:00 +08:00
+++ edited/xen/arch/x86/x86_64/usercopy.c	2005-06-03 10:13:30 +08:00
@@ -135,6 +135,21 @@
 	return n;
 }
 
+unsigned long
+copy_from_guest(void *to, const void __user *from, unsigned long n)
+{
+  return n;
+}
+EXPORT_SYMBOL(copy_from_guest);
+
+unsigned long
+copy_to_guest(void __user *to, const void *from, unsigned long n)
+{
+    return n;
+}
+EXPORT_SYMBOL(copy_to_guest);
+
+
 /**
  * copy_to_user: - Copy a block of data into user space.
  * @to:   Destination address, in user space.
===== xen/include/asm-x86/x86_32/uaccess.h 1.19 vs edited =====
--- 1.19/xen/include/asm-x86/x86_32/uaccess.h	2005-04-23 00:34:08 +08:00
+++ edited/xen/include/asm-x86/x86_32/uaccess.h	2005-06-03 10:13:40 +08:00
@@ -332,6 +332,11 @@
 unsigned long copy_from_user(void *to,
                              const void __user *from, unsigned long n);
 
+unsigned long copy_to_guest(void __user *to, 
+                            const void *from, unsigned long n);
+unsigned long copy_from_guest(void *to,
+                              const void __user *from, unsigned long n);
+
 unsigned long clear_user(void __user *mem, unsigned long len);
 unsigned long __clear_user(void __user *mem, unsigned long len);
 
===== xen/include/asm-x86/x86_64/uaccess.h 1.15 vs edited =====
--- 1.15/xen/include/asm-x86/x86_64/uaccess.h	2005-04-19 21:48:04 +08:00
+++ edited/xen/include/asm-x86/x86_64/uaccess.h	2005-06-03 10:13:41 +08:00
@@ -224,6 +224,11 @@
 unsigned long copy_to_user(void __user *to, const void *from, unsigned len); 
 unsigned long copy_from_user(void *to, const void __user *from, unsigned len); 
 
+unsigned long copy_to_guest(void __user *to, 
+                            const void *from, unsigned long n);
+unsigned long copy_from_guest(void *to,
+                              const void __user *from, unsigned long n);
+
 static always_inline int __copy_from_user(void *dst, const void __user *src, unsigned size) 
 { 
     int ret = 0;


[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-06-10 15:42 Ling, Xiaofeng
  0 siblings, 0 replies; 14+ messages in thread
From: Ling, Xiaofeng @ 2005-06-10 15:42 UTC (permalink / raw)
  To: Keir Fraser, Ian Pratt, xen-devel

Is this patch acceptable? 
If yes, I'll continue to work out the other splitted patch.

Xiaofeng Ling <mailto:xiaofeng.ling@intel.com> wrote:
> I'd like to split the patch into small ones, so that it can be
> clearer. Attach is the patch of adding support copy_to/from_guest.
> 
> Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>
> 
>   arch/x86/x86_32/usercopy.c       |   99
> +++++++++++++++++++++++++++++++++++++++
>   arch/x86/x86_64/usercopy.c       |   15 +++++
>   include/asm-x86/x86_32/uaccess.h |    5 +
>   include/asm-x86/x86_64/uaccess.h |    5 +
>   4 files changed, 124 insertions(+)
> 
> 
> Ling, Xiaofeng wrote:
>> 
>> Keir Fraser <mailto:Keir.Fraser@cl.cam.ac.uk> wrote:
>> 
>>> On 3 Jun 2005, at 03:40, Xiaofeng Ling wrote:
>>> 
>>> 
>>>> It's now all use shadow_mode_external, and use a permit bitmap for
>>>> hypercall from vmx domain. Do you think it's now acceptable?
>>>> It's against 1657.
>>> guest
>>> Still messy imo. When I said to split the path by
>>> shadow_mode_externel, I meant you should do it within the uaccess
>>> macros/functions; not in their callers.  guest
>> 
>> I've already done that for copy_from/to_user, but for
>> __copy_from/to_user I can not do that, because not all the caller
>> shall call copy_from/to_guest

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
@ 2005-06-10 16:25 Ian Pratt
  0 siblings, 0 replies; 14+ messages in thread
From: Ian Pratt @ 2005-06-10 16:25 UTC (permalink / raw)
  To: Ling, Xiaofeng, Keir Fraser, xen-devel

> Is this patch acceptable? 
> If yes, I'll continue to work out the other splitted patch.

I want a chance to think a bit more about the paravirtualized VT
drivers, and about paravirtualized drivers working in shadow_translate
mode in general.

Having to map the domain mem for the hypercall arguments in copy_*_user
is going to be painful anyhow -- we might want to register a page that
is permanently mapped into the hypervisor's address space and translate
in the vt-specific entry code.

Ian
 
> Xiaofeng Ling <mailto:xiaofeng.ling@intel.com> wrote:
> > I'd like to split the patch into small ones, so that it can be 
> > clearer. Attach is the patch of adding support copy_to/from_guest.
> > 
> > Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>
> > 
> >   arch/x86/x86_32/usercopy.c       |   99
> > +++++++++++++++++++++++++++++++++++++++
> >   arch/x86/x86_64/usercopy.c       |   15 +++++
> >   include/asm-x86/x86_32/uaccess.h |    5 +
> >   include/asm-x86/x86_64/uaccess.h |    5 +
> >   4 files changed, 124 insertions(+)
> > 
> > 
> > Ling, Xiaofeng wrote:
> >> 
> >> Keir Fraser <mailto:Keir.Fraser@cl.cam.ac.uk> wrote:
> >> 
> >>> On 3 Jun 2005, at 03:40, Xiaofeng Ling wrote:
> >>> 
> >>> 
> >>>> It's now all use shadow_mode_external, and use a permit 
> bitmap for 
> >>>> hypercall from vmx domain. Do you think it's now acceptable?
> >>>> It's against 1657.
> >>> guest
> >>> Still messy imo. When I said to split the path by 
> >>> shadow_mode_externel, I meant you should do it within the uaccess 
> >>> macros/functions; not in their callers.  guest
> >> 
> >> I've already done that for copy_from/to_user, but for 
> >> __copy_from/to_user I can not do that, because not all the caller 
> >> shall call copy_from/to_guest
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2005-06-10 16:25 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-25  6:26 [PATCH]vbd/vnif paravirtulization driver hypervisorsupport] Ling, Xiaofeng
2005-05-25  7:54 ` Keir Fraser
2005-06-03  2:40   ` Xiaofeng Ling
2005-06-03  7:58     ` Keir Fraser
  -- strict thread matches above, loose matches on Subject: below --
2005-06-10 16:25 Ian Pratt
2005-06-10 15:42 Ling, Xiaofeng
2005-06-03  8:22 Ling, Xiaofeng
2005-06-09  1:28 ` Xiaofeng Ling
2005-05-25  8:16 Ling, Xiaofeng
2005-05-25  5:14 Ian Pratt
2005-05-25  5:00 Ian Pratt
     [not found] <AcVdBMqGMA2IEEsTSdm26uwqvN7GUwDyn0Kw>
2005-05-25  2:19 ` Ling, Xiaofeng
2005-05-25  3:33   ` aq
2005-05-20 12:28 Ling, Xiaofeng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.