* 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 [PATCH]vbd/vnif paravirtulization driver hypervisorsupport] 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 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
* 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-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 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 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 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(®s);
__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-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 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
[parent not found: <AcVdBMqGMA2IEEsTSdm26uwqvN7GUwDyn0Kw>]
* 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-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(®s);
__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
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-06-03 8:22 [PATCH]vbd/vnif paravirtulization driver hypervisorsupport] Ling, Xiaofeng
2005-06-09 1:28 ` Xiaofeng Ling
-- strict thread matches above, loose matches on Subject: below --
2005-06-10 16:25 Ian Pratt
2005-06-10 15:42 Ling, Xiaofeng
2005-05-25 8:16 Ling, Xiaofeng
2005-05-25 6:26 Ling, Xiaofeng
2005-05-25 7:54 ` Keir Fraser
2005-06-03 2:40 ` Xiaofeng Ling
2005-06-03 7:58 ` Keir Fraser
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.