[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Initial check-in to support PV balloon driver within HVM guests.
# HG changeset patch # User Steven Hand <steven@xxxxxxxxxxxxx> # Date 1175713150 -3600 # Node ID 2bbd28891160a1d03e45ebc571d8d61ae16ef876 # Parent b3c75956303b90a5feb293b05272dc399c68a8da Initial check-in to support PV balloon driver within HVM guests. Still todo: - fix mapcache invalidation (should happen in Xen) - support 32-on-64 mode correctly Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx> --- linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 43 ++++++++++++++-- linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c | 1 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c | 4 + linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c | 5 + unmodified_drivers/linux-2.6/Makefile | 1 unmodified_drivers/linux-2.6/balloon/Kbuild | 9 +++ unmodified_drivers/linux-2.6/balloon/Makefile | 3 + unmodified_drivers/linux-2.6/mkbuildtree | 4 + unmodified_drivers/linux-2.6/platform-pci/xen_support.c | 9 --- xen/arch/x86/hvm/hvm.c | 25 ++++++--- xen/arch/x86/hvm/irq.c | 6 -- xen/arch/x86/hvm/svm/svm.c | 11 +++- xen/arch/x86/hvm/vmx/vmx.c | 12 +++- xen/common/memory.c | 7 -- xen/include/asm-x86/hvm/hvm.h | 14 ++++- xen/include/asm-x86/hvm/support.h | 2 16 files changed, 117 insertions(+), 39 deletions(-) diff -r b3c75956303b -r 2bbd28891160 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Apr 04 19:17:39 2007 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Apr 04 19:59:10 2007 +0100 @@ -48,13 +48,20 @@ #include <asm/hypervisor.h> #include <xen/balloon.h> #include <xen/interface/memory.h> +#include <asm/maddr.h> +#include <asm/page.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm/uaccess.h> #include <asm/tlb.h> +#include <linux/highmem.h> #include <linux/list.h> #include <xen/xenbus.h> #include "common.h" + +#ifndef CONFIG_XEN +#define scrub_pages(_p,_n) +#endif #ifdef CONFIG_PROC_FS static struct proc_dir_entry *balloon_pde; @@ -217,6 +224,7 @@ static int increase_reservation(unsigned set_phys_to_machine(pfn, frame_list[i]); +#ifdef CONFIG_XEN /* Link back into the page tables if not highmem. */ if (pfn < max_low_pfn) { int ret; @@ -226,6 +234,7 @@ static int increase_reservation(unsigned 0); BUG_ON(ret); } +#endif /* Relinquish the page back to the allocator. */ ClearPageReserved(page); @@ -241,6 +250,8 @@ static int increase_reservation(unsigned return 0; } + +extern void xen_invalidate_foreign_mappings(void); static int decrease_reservation(unsigned long nr_pages) { @@ -275,7 +286,7 @@ static int decrease_reservation(unsigned (unsigned long)v, __pte_ma(0), 0); BUG_ON(ret); } -#ifdef CONFIG_XEN_SCRUB_PAGES +#ifdef CONFIG_XEN else { v = kmap(page); scrub_pages(v, 1); @@ -284,19 +295,24 @@ static int decrease_reservation(unsigned #endif } +#ifdef CONFIG_XEN /* Ensure that ballooned highmem pages don't have kmaps. */ kmap_flush_unused(); flush_tlb_all(); +#endif balloon_lock(flags); /* No more mappings: invalidate P2M and add to balloon. */ for (i = 0; i < nr_pages; i++) { pfn = mfn_to_pfn(frame_list[i]); +#ifdef CONFIG_XEN set_phys_to_machine(pfn, INVALID_P2M_ENTRY); +#endif balloon_append(pfn_to_page(pfn)); } + xen_invalidate_foreign_mappings(); set_xen_guest_handle(reservation.extent_start, frame_list); reservation.nr_extents = nr_pages; ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); @@ -446,7 +462,7 @@ static struct notifier_block xenstore_no static int __init balloon_init(void) { -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) && defined(CONFIG_XEN) unsigned long pfn; struct page *page; #endif @@ -456,8 +472,12 @@ static int __init balloon_init(void) IPRINTK("Initialising balloon driver.\n"); +#ifdef CONFIG_XEN bs.current_pages = min(xen_start_info->nr_pages, max_pfn); totalram_pages = bs.current_pages; +#else + bs.current_pages = totalram_pages; +#endif bs.target_pages = bs.current_pages; bs.balloon_low = 0; bs.balloon_high = 0; @@ -479,7 +499,7 @@ static int __init balloon_init(void) #endif balloon_sysfs_init(); -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) && defined(CONFIG_XEN) /* Initialise the balloon with excess memory space. */ for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { page = pfn_to_page(pfn); @@ -498,6 +518,14 @@ static int __init balloon_init(void) subsys_initcall(balloon_init); +static void balloon_exit(void) +{ + /* XXX - release balloon here */ + return; +} + +module_exit(balloon_exit); + void balloon_update_driver_allowance(long delta) { unsigned long flags; @@ -507,6 +535,7 @@ void balloon_update_driver_allowance(lon balloon_unlock(flags); } +#ifdef CONFIG_XEN static int dealloc_pte_fn( pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) { @@ -524,6 +553,7 @@ static int dealloc_pte_fn( BUG_ON(ret != 1); return 0; } +#endif struct page **alloc_empty_pages_and_pagevec(int nr_pages) { @@ -559,8 +589,13 @@ struct page **alloc_empty_pages_and_page if (ret == 1) ret = 0; /* success */ } else { +#ifdef CONFIG_XEN ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE, dealloc_pte_fn, NULL); +#else + /* cannot handle non-auto translate mode */ + ret = 1; +#endif } if (ret != 0) { @@ -576,7 +611,9 @@ struct page **alloc_empty_pages_and_page out: schedule_work(&balloon_worker); +#ifdef CONFIG_XEN flush_tlb_all(); +#endif return pagevec; err: diff -r b3c75956303b -r 2bbd28891160 linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c Wed Apr 04 19:17:39 2007 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c Wed Apr 04 19:59:10 2007 +0100 @@ -29,6 +29,7 @@ */ #include <linux/capability.h> +#include <linux/errno.h> #include <linux/stat.h> #include <linux/sysdev.h> #include "common.h" diff -r b3c75956303b -r 2bbd28891160 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Wed Apr 04 19:17:39 2007 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Wed Apr 04 19:59:10 2007 +0100 @@ -407,11 +407,13 @@ static unsigned int __max_nr_grant_frame static unsigned int __max_nr_grant_frames(void) { struct gnttab_query_size query; - int rc; + int rc = -1; query.dom = DOMID_SELF; +#ifdef CONFIG_XEN rc = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &query, 1); +#endif if ((rc < 0) || (query.status != GNTST_okay)) return 4; /* Legacy max supported number of frames */ diff -r b3c75956303b -r 2bbd28891160 linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c Wed Apr 04 19:17:39 2007 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c Wed Apr 04 19:59:10 2007 +0100 @@ -1,4 +1,5 @@ +#include <linux/module.h> #include <linux/proc_fs.h> #include <xen/xen_proc.h> @@ -12,7 +13,11 @@ struct proc_dir_entry *create_xen_proc_e return create_proc_entry(name, mode, xen_base); } +EXPORT_SYMBOL_GPL(create_xen_proc_entry); + void remove_xen_proc_entry(const char *name) { remove_proc_entry(name, xen_base); } + +EXPORT_SYMBOL_GPL(remove_xen_proc_entry); diff -r b3c75956303b -r 2bbd28891160 unmodified_drivers/linux-2.6/Makefile --- a/unmodified_drivers/linux-2.6/Makefile Wed Apr 04 19:17:39 2007 +0100 +++ b/unmodified_drivers/linux-2.6/Makefile Wed Apr 04 19:59:10 2007 +0100 @@ -2,6 +2,7 @@ include $(M)/overrides.mk obj-m += platform-pci/ obj-m += xenbus/ +obj-m += balloon/ obj-m += blkfront/ obj-m += netfront/ obj-m += util/ diff -r b3c75956303b -r 2bbd28891160 unmodified_drivers/linux-2.6/balloon/Kbuild --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/balloon/Kbuild Wed Apr 04 19:59:10 2007 +0100 @@ -0,0 +1,9 @@ +include $(M)/overrides.mk + +obj-m = xen-balloon.o + +EXTRA_CFLAGS += -I$(M)/platform-pci + +xen-balloon-objs = +xen-balloon-objs += balloon.o +xen-balloon-objs += sysfs.o diff -r b3c75956303b -r 2bbd28891160 unmodified_drivers/linux-2.6/balloon/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/balloon/Makefile Wed Apr 04 19:59:10 2007 +0100 @@ -0,0 +1,3 @@ +ifneq ($(KERNELRELEASE),) +include $(src)/Kbuild +endif diff -r b3c75956303b -r 2bbd28891160 unmodified_drivers/linux-2.6/mkbuildtree --- a/unmodified_drivers/linux-2.6/mkbuildtree Wed Apr 04 19:17:39 2007 +0100 +++ b/unmodified_drivers/linux-2.6/mkbuildtree Wed Apr 04 19:59:10 2007 +0100 @@ -15,6 +15,9 @@ XL=$C/../../linux-2.6-xen-sparse for d in $(find ${XL}/drivers/xen/ -maxdepth 1 -type d | sed -e 1d); do if ! echo $d | egrep -q back; then + lndir $d $(basename $d) > /dev/null 2>&1 + fi + if ! echo $d | egrep -q ball; then lndir $d $(basename $d) > /dev/null 2>&1 fi done @@ -47,6 +50,7 @@ i[34567]86) ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypercall.h include/asm ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm + ln -sf ${XL}/include/asm-i386/mach-xen/asm/page.h include/asm ;; "ia64") ln -sf ${XL}/include/asm-ia64/hypervisor.h include/asm diff -r b3c75956303b -r 2bbd28891160 unmodified_drivers/linux-2.6/platform-pci/xen_support.c --- a/unmodified_drivers/linux-2.6/platform-pci/xen_support.c Wed Apr 04 19:17:39 2007 +0100 +++ b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c Wed Apr 04 19:59:10 2007 +0100 @@ -59,12 +59,3 @@ void xen_machphys_update(unsigned long m } EXPORT_SYMBOL(xen_machphys_update); -void balloon_update_driver_allowance(long delta) -{ -} -EXPORT_SYMBOL(balloon_update_driver_allowance); - -void balloon_release_driver_page(struct page *page) -{ -} -EXPORT_SYMBOL(balloon_release_driver_page); diff -r b3c75956303b -r 2bbd28891160 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Wed Apr 04 19:17:39 2007 +0100 +++ b/xen/arch/x86/hvm/hvm.c Wed Apr 04 19:59:10 2007 +0100 @@ -521,12 +521,12 @@ static hvm_hypercall_t *hvm_hypercall_ta HYPERCALL(hvm_op) }; -void hvm_do_hypercall(struct cpu_user_regs *pregs) +int hvm_do_hypercall(struct cpu_user_regs *pregs) { if ( unlikely(ring_3(pregs)) ) { pregs->eax = -EPERM; - return; + return 0; } if ( (pregs->eax >= NR_hypercalls) || !hvm_hypercall_table[pregs->eax] ) @@ -535,11 +535,21 @@ void hvm_do_hypercall(struct cpu_user_re current->domain->domain_id, current->vcpu_id, pregs->eax); pregs->eax = -ENOSYS; - return; - } + return 0; + } + + /* Install a canary value in regs->eip so can check for continuation */ + pregs->eip |= 0xF; pregs->eax = hvm_hypercall_table[pregs->eax]( pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi); + + /* XXX: pot fake IO instr here to inform the emulator to flush mapcache */ + + if( (pregs->eip & 0xF) == 0 ) /* preempted */ + return 1; + + return 0; } #else /* defined(__x86_64__) */ @@ -599,12 +609,12 @@ static hvm_hypercall_t *hvm_hypercall32_ HYPERCALL(event_channel_op) }; -void hvm_do_hypercall(struct cpu_user_regs *pregs) +int hvm_do_hypercall(struct cpu_user_regs *pregs) { if ( unlikely(ring_3(pregs)) ) { pregs->rax = -EPERM; - return; + return 0; } pregs->rax = (uint32_t)pregs->eax; /* mask in case compat32 caller */ @@ -614,7 +624,7 @@ void hvm_do_hypercall(struct cpu_user_re current->domain->domain_id, current->vcpu_id, pregs->rax); pregs->rax = -ENOSYS; - return; + return 0; } if ( current->arch.paging.mode->guest_levels == 4 ) @@ -633,6 +643,7 @@ void hvm_do_hypercall(struct cpu_user_re (uint32_t)pregs->esi, (uint32_t)pregs->edi); } + return 0; /* XXX SMH: fix for preempt here */ } #endif /* defined(__x86_64__) */ diff -r b3c75956303b -r 2bbd28891160 xen/arch/x86/hvm/irq.c --- a/xen/arch/x86/hvm/irq.c Wed Apr 04 19:17:39 2007 +0100 +++ b/xen/arch/x86/hvm/irq.c Wed Apr 04 19:59:10 2007 +0100 @@ -347,11 +347,7 @@ int hvm_local_events_need_delivery(struc pending = (vcpu_info(v, evtchn_upcall_pending) || cpu_has_pending_irq(v)); if ( unlikely(pending) ) - { - struct cpu_user_regs regs; - hvm_store_cpu_guest_regs(v, ®s, NULL); - pending = !irq_masked(regs.eflags); - } + pending = hvm_interrupts_enabled(v); return pending; } diff -r b3c75956303b -r 2bbd28891160 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed Apr 04 19:17:39 2007 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Wed Apr 04 19:59:10 2007 +0100 @@ -498,6 +498,12 @@ static int svm_realmode(struct vcpu *v) return (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE); } +static int svm_interrupts_enabled(struct vcpu *v) +{ + unsigned long eflags = v->arch.hvm_svm.vmcb->rflags; + return !irq_masked(eflags); +} + static int svm_guest_x86_mode(struct vcpu *v) { struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; @@ -800,6 +806,7 @@ static struct hvm_function_table svm_fun .paging_enabled = svm_paging_enabled, .long_mode_enabled = svm_long_mode_enabled, .pae_enabled = svm_pae_enabled, + .interrupts_enabled = svm_interrupts_enabled, .guest_x86_mode = svm_guest_x86_mode, .get_guest_ctrl_reg = svm_get_ctrl_reg, .get_segment_base = svm_get_segment_base, @@ -2268,8 +2275,8 @@ asmlinkage void svm_vmexit_handler(struc inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL); ASSERT(inst_len > 0); HVMTRACE_1D(VMMCALL, v, regs->eax); - __update_guest_eip(vmcb, inst_len); - hvm_do_hypercall(regs); + if(hvm_do_hypercall(regs) == 0) /* not preempted */ + __update_guest_eip(vmcb, inst_len); break; case VMEXIT_CR0_READ: diff -r b3c75956303b -r 2bbd28891160 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Wed Apr 04 19:17:39 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Apr 04 19:59:10 2007 +0100 @@ -957,6 +957,13 @@ static int vmx_pae_enabled(struct vcpu * return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE)); } +static int vmx_interrupts_enabled(struct vcpu *v) +{ + unsigned long eflags = __vmread(GUEST_RFLAGS); + return !irq_masked(eflags); +} + + static void vmx_update_host_cr3(struct vcpu *v) { ASSERT( (v == current) || !vcpu_runnable(v) ); @@ -1030,6 +1037,7 @@ static struct hvm_function_table vmx_fun .paging_enabled = vmx_paging_enabled, .long_mode_enabled = vmx_long_mode_enabled, .pae_enabled = vmx_pae_enabled, + .interrupts_enabled = vmx_interrupts_enabled, .guest_x86_mode = vmx_guest_x86_mode, .get_guest_ctrl_reg = vmx_get_ctrl_reg, .get_segment_base = vmx_get_segment_base, @@ -2620,8 +2628,8 @@ asmlinkage void vmx_vmexit_handler(struc { HVMTRACE_1D(VMMCALL, v, regs->eax); inst_len = __get_instruction_length(); /* Safe: VMCALL */ - __update_guest_eip(inst_len); - hvm_do_hypercall(regs); + if(hvm_do_hypercall(regs) == 0) /* not preempted */ + __update_guest_eip(inst_len); break; } case EXIT_REASON_CR_ACCESS: diff -r b3c75956303b -r 2bbd28891160 xen/common/memory.c --- a/xen/common/memory.c Wed Apr 04 19:17:39 2007 +0100 +++ b/xen/common/memory.c Wed Apr 04 19:59:10 2007 +0100 @@ -176,12 +176,7 @@ int guest_remove_page(struct domain *d, if ( unlikely((page->count_info & PGC_count_mask) != 1) ) { shadow_drop_references(d, page); - /* We'll make this a guest-visible error in future, so take heed! */ - if ( (page->count_info & PGC_count_mask) != 1 ) - gdprintk(XENLOG_INFO, "Dom%d freeing in-use page %lx " - "(pseudophys %lx): count=%lx type=%lx\n", - d->domain_id, mfn, get_gpfn_from_mfn(mfn), - (unsigned long)page->count_info, page->u.inuse.type_info); + /* NB: still may have foreign references to the page at this stage */ } guest_physmap_remove_page(d, gmfn, mfn); diff -r b3c75956303b -r 2bbd28891160 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Wed Apr 04 19:17:39 2007 +0100 +++ b/xen/include/asm-x86/hvm/hvm.h Wed Apr 04 19:59:10 2007 +0100 @@ -93,13 +93,15 @@ struct hvm_function_table { * 1) determine whether paging is enabled, * 2) determine whether long mode is enabled, * 3) determine whether PAE paging is enabled, - * 4) determine the mode the guest is running in, - * 5) return the current guest control-register value - * 6) return the current guest segment descriptor base + * 4) determine whether interrupts are enabled or not, + * 5) determine the mode the guest is running in, + * 6) return the current guest control-register value + * 7) return the current guest segment descriptor base */ int (*paging_enabled)(struct vcpu *v); int (*long_mode_enabled)(struct vcpu *v); int (*pae_enabled)(struct vcpu *v); + int (*interrupts_enabled)(struct vcpu *v); int (*guest_x86_mode)(struct vcpu *v); unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num); unsigned long (*get_segment_base)(struct vcpu *v, enum x86_segment seg); @@ -190,6 +192,12 @@ hvm_pae_enabled(struct vcpu *v) } static inline int +hvm_interrupts_enabled(struct vcpu *v) +{ + return hvm_funcs.interrupts_enabled(v); +} + +static inline int hvm_guest_x86_mode(struct vcpu *v) { return hvm_funcs.guest_x86_mode(v); diff -r b3c75956303b -r 2bbd28891160 xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Wed Apr 04 19:17:39 2007 +0100 +++ b/xen/include/asm-x86/hvm/support.h Wed Apr 04 19:59:10 2007 +0100 @@ -228,7 +228,7 @@ void hvm_print_line(struct vcpu *v, cons void hvm_print_line(struct vcpu *v, const char c); void hlt_timer_fn(void *data); -void hvm_do_hypercall(struct cpu_user_regs *pregs); +int hvm_do_hypercall(struct cpu_user_regs *pregs); void hvm_hlt(unsigned long rflags); void hvm_triple_fault(void); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |