vbd/vnif paravirtulization driver hypervisor support]
PATCH 1/1 vbd/vnif paravirtulization driver hypervisor support]
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.
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.
# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2005/05/20 11:27:04+08:00 [email protected] # 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 <[email protected]>
#
# BitKeeper/etc/logging_ok
# 2005/05/20 11:27:04+08:00 [email protected] +1 -0
# Logging to [email protected] accepted
#
# xen/include/xen/config.h # 2005/05/20 11:27:01+08:00 [email protected] +8 -0 # Add debug print for vmx driver # # xen/include/public/xen.h # 2005/05/20 11:27:01+08:00 [email protected] +13 -1 # add virtual device hypercall entry # # xen/include/public/arch-x86_32.h # 2005/05/20 11:27:01+08:00 [email protected] +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 [email protected] +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 [email protected] +5 -0 # copy_to/from_guest for vmx domain. # # xen/include/asm-x86/vmx_vmcs.h # 2005/05/20 11:27:01+08:00 [email protected] +2 -0 # debug for VMX VBD and VNIF # # xen/common/multicall.c # 2005/05/20 11:27:01+08:00 [email protected] +34 -9 # vmx domain hypercall path # # xen/common/grant_table.c # 2005/05/20 11:27:01+08:00 [email protected] +29 -6 # setup grant table for vmx domain # # xen/common/dom_mem_ops.c # 2005/05/20 11:27:01+08:00 [email protected] +12 -5 # hypercall path for vmx domain # # xen/arch/x86/x86_64/usercopy.c # 2005/05/20 11:27:01+08:00 [email protected] +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 [email protected] +99 -0 # copy_to/from_guest for vmx domain # # xen/arch/x86/x86_32/entry.S # 2005/05/20 11:27:01+08:00 [email protected] +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 [email protected] +53 -7 # delieve event to vmx domain by irq # # xen/arch/x86/vmx.c # 2005/05/20 11:27:01+08:00 [email protected] +83 -4 # hypercall entry for vmx domain by vmcall # # xen/arch/x86/shadow.c # 2005/05/20 11:27:01+08:00 [email protected] +25 -2 # set map for vmx domain # # xen/arch/x86/mm.c # 2005/05/20 11:27:01+08:00 [email protected] +27 -13 # clear vmx hypercall path # # xen/arch/x86/domain.c # 2005/05/20 11:27:01+08:00 [email protected] +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 11:40:12 +08:00 +++ b/xen/arch/x86/domain.c 2005-05-20 11:40:12 +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;xen/arch/x86/mm.c +27 -13
@@ -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)) ) {
xen/arch/x86/shadow.c +25 -2
@@ -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
xen/arch/x86/vmx.c +83 -4
117 lines not on this page · raw message
xen/arch/x86/vmx_io.c +53 -7
91 lines not on this page · raw message
xen/arch/x86/x86_32/entry.S +36 -0
@@ -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
xen/arch/x86/x86_32/usercopy.c +99 -0
123 lines not on this page · raw message
xen/arch/x86/x86_64/usercopy.c +15 -0
@@ -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.
xen/common/dom_mem_ops.c +12 -5
@@ -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);
xen/common/grant_table.c +29 -6
@@ -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);
xen/common/multicall.c +34 -9
79 lines not on this page · raw message
xen/include/asm-x86/vmx_vmcs.h +2 -0
@@ -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...) \
xen/include/asm-x86/x86_32/uaccess.h +5 -0
@@ -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 +5 -0
@@ -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 +5 -0
@@ -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 +13 -1
@@ -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 */
xen/include/xen/config.h +8 -0
@@ -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
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel