WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH]vbd/vnif paravirtulization driver hypervisorsuppo

To: Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH]vbd/vnif paravirtulization driver hypervisorsupport]
From: Xiaofeng Ling <xiaofeng.ling@xxxxxxxxx>
Date: Fri, 03 Jun 2005 10:40:48 +0800
Cc: Ian Pratt <m+Ian.Pratt@xxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Fri, 03 Jun 2005 02:40:30 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <c14dd1d083dac56284a12cd40fed9c3e@xxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <3ACA40606221794F80A5670F0AF15F840836E8CF@pdsmsx403> <c14dd1d083dac56284a12cd40fed9c3e@xxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040510
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


===== 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
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>