Device model cleanup.
PATCH 1/10 Device model cleanup.
Device model cleanup.
- Single config file for xen and device models (Shell script doesn't source xmdefconfig anymore)
- No more device-model shell script by default. You can have one if needed (qemu-dm.debug)
- All logic in the script device-model is moved to python
- $DISPLAY is passed from xm to xend
- Don't fork vncviewer on dryruns
- Add support for killing device models on domain destroy
- info vmxiopage command added to the monitor
- Refactor shared io page into global and per vcpu state
- Remove the hard coding of IOPACKET_PORT
- move the virtual_platform_def up to domain struct from vcpu
- xm create -n:
(vm
(name ExampleVMXDomain)
(memory 128)
(ssidref -1)
(image
(vmx
(kernel /usr/lib/xen/boot/vmxloader)
(root '/dev/hda1 ro')
(vcpus 1)
)
)
(memmap )
(device_model /tmp/foo)
(hda /var/images/min-el3-i386.img)
(hdb )
(hdc )
(hdd )
(cdrom )
(boot c)
(fda )
(fdb )
(localtime 0)
(serial )
(macaddr )
(stdvga 0)
(isa 0)
(nographic 0)
(vnc 0)
(sdl 0)
(display localhost:10.0))
xen/include/asm-x86/domain.h +1 -1
@@ -63,7 +63,7 @@struct list_head free_shadow_frames;pagetable_t phys_table;/* guest 1:1 pagetable */ - +struct virtual_platform_def vmx_platform; } __cacheline_aligned;struct arch_vcpu
tools/ioemu/target-i386-dm/helper2.c +17 -8
@@ -45,14 +45,16 @@#include <limits.h> #include <fcntl.h> +#include <sys/ioctl.h> #include "xc.h" #include <io/ioreq.h> #include "cpu.h" #include "exec-all.h" - -void *shared_page; +#include "vl.h" + +shared_iopage_t *shared_page =NULL ;CPUX86State *cpu_86_init (void ) {
@@ -116,19 +118,27 @@//the evtchn port for polling the notification, should be inputed as bochs's parameter u16 ioreq_port =0 ; -void *shared_page =NULL ; -//some functions to handle the io req packet +void +sp_info () +{ +ioreq_t *req; + + req = &(shared_page->vcpu_iodata[0 ].vp_ioreq); +term_printf ("event port: %d\n" , shared_page->sp_global.eport); +term_printf ("req state: %x, pvalid: %x, addr: %llx, data: %llx, count: %llx, size: %llx\n" , req->state, req->pdata_valid, req->addr, req->u.data, req->count, req->size); +}//get the ioreq packets from share mem ioreq_t *__cpu_get_ioreq (void ) {ioreq_t *req; - req = &((vcpu_iodata_t *) shared_page)->vp_ioreq; + + req = &(shared_page->vcpu_iodata[0 ].vp_ioreq);if (req->state ==STATE_IOREQ_READY ) { req->state =STATE_IOREQ_INPROCESS ; }else { -fprintf (logfile,"False I/O requrest ... in-service already: %x, pvalid: %x,port: %llx, data: %llx, count: %llx, size: %llx\n" , req->state, req->pdata_valid, req->addr, req->u.data, req->count, req->size); +fprintf (logfile,"False I/O request ... in-service already: %x, pvalid: %x,port: %llx, data: %llx, count: %llx, size: %llx\n" , req->state, req->pdata_valid, req->addr, req->u.data, req->count, req->size); req =NULL ; }
@@ -310,8 +320,7 @@// Send a message on the event channel. Add the vector to the shared mem // page. - - intr = &(((vcpu_iodata_t *) shared_page)->vp_intr[0 ]); + intr = &(shared_page->vcpu_iodata[0 ].vp_intr[0 ]);atomic_set_bit (vector, intr);if (loglevel &CPU_LOG_INT )fprintf (logfile,"injecting vector: %x\n" , vector);
tools/python/xen/xm/create.py +71 -9
102 lines not on this page · raw message
xen/include/asm-x86/vmx_platform.h +1 -1
@@ -77,7 +77,7 @@struct cpu_user_regs *inst_decoder_regs; }; -struct virutal_platform_def { +struct virtual_platform_def {unsigned long *real_mode_data;/* E820, etc. */ unsigned long shared_page_va;struct vmx_virpit_t vmx_pit;
tools/ioemu/monitor.c +2 -0
@@ -353,6 +353,8 @@ "", "show i8259 (PIC) state", }, {"pci" ,"" , pci_info, "", "show PCI info", }, + { "vmxiopage", "", sp_info, + "", "show VMX device model shared page info", }, { NULL, NULL, }, };
tools/examples/xmexample.vmx +4 -10
@@ -87,18 +87,12 @@ #============================================================================ + # New stuff +device_model = '/usr/bin/qemu-dm' + +# Advanced users only. Don't touch if you don't know what you're doing memmap = '/etc/xen/mem-map.sxp' -device_model = '/usr/bin/device-model' -device_config = '/etc/xen/xmexample.vmx' - -#============================================================================ -# -# config item for qemu device model -# Note: no space between = -#----------------------------------------------------------------------------- -# Qemu binary path -qemubin='/usr/bin/qemu-dm' #----------------------------------------------------------------------------- # Disk image for
xen/include/asm-x86/vmx.h +12 -0
@@ -25,6 +25,8 @@#include <asm/processor.h> #include <asm/vmx_vmcs.h> #include <asm/i387.h> + +#include <public/io/ioreq.h> extern void vmx_asm_vmexit_handler (struct cpu_user_regs );extern void vmx_asm_do_resume (void );
@@ -337,4 +339,14 @@ return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG); } +static inline vcpu_iodata_t *get_vio (struct domain *d,unsigned long cpu) +{ +return &((shared_iopage_t *) d->arch.vmx_platform.shared_page_va)->vcpu_iodata[cpu]; +} + +static inline int iopacket_port (struct domain *d) +{ +return ((shared_iopage_t *) d->arch.vmx_platform.shared_page_va)->sp_global.eport; +} +#endif /* __ASM_X86_VMX_H__ */
tools/libxc/xc_vmx_build.c +15 -0
@@ -8,6 +8,7 @@#include "xc_elf.h" #include <stdlib.h> #include <zlib.h> +#include <xen/io/ioreq.h> #include "linux_boot_params.h" #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
@@ -173,6 +174,9 @@unsigned long vpt_start;unsigned long vpt_end;unsigned long v_end; + +unsigned long shared_page_frame =0 ; +shared_iopage_t *sp;memset (&dsi,0 ,sizeof (struct domain_setup_info ));
@@ -382,6 +386,8 @@ boot_paramsp->e820_map[i].addr = mem_mapp->map[i].addr; boot_paramsp->e820_map[i].size = mem_mapp->map[i].size; boot_paramsp->e820_map[i].type = mem_mapp->map[i].type; +if (mem_mapp->map[i].type ==E820_SHARED ) + shared_page_frame = (mem_mapp->map[i].addr >>PAGE_SHIFT ); }munmap (boot_paramsp,PAGE_SIZE );
@@ -406,6 +412,15 @@for ( i =0 ; i <MAX_VIRT_CPUS ; i++ ) shared_info->vcpu_data[i].evtchn_upcall_mask =1 ;munmap (shared_info,PAGE_SIZE ); + +/* Populate the event channel port in the shared page */ +if ((sp = (shared_iopage_t *)xc_map_foreign_range ( + xc_handle, dom,PAGE_SIZE ,PROT_READ |PROT_WRITE , + page_array[shared_page_frame])) ==0 ) + goto error_out; +memset (sp,0 ,PAGE_SIZE ); + sp->sp_global.eport = control_evtchn; +munmap (sp,PAGE_SIZE );/* * Pin down l2tab addr as page dir page - causes hypervisor to provide
xen/arch/x86/vmx.c +3 -3
@@ -388,7 +388,7 @@return ; } - vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; + vio =get_vio (d->domain, d->vcpu_id);if (vio ==0 ) {printk ("bad shared page: %lx" , (unsigned long ) vio);domain_crash_synchronous ();
@@ -458,7 +458,7 @@set_bit (ARCH_VMX_IO_WAIT , &d->arch.arch_vmx.flags); p->state =STATE_IOREQ_READY ; -evtchn_send (IOPACKET_PORT ); +evtchn_send (iopacket_port (d->domain));vmx_wait_io (); }
@@ -1260,7 +1260,7 @@ (unsigned long )regs.eax, (unsigned long )regs.ebx, (unsigned long )regs.ecx, (unsigned long )regs.edx, (unsigned long)regs.esi, (unsigned long)regs.edi); - v->arch.arch_vmx.vmx_platform.mpci.inst_decoder_regs = ®s; + v->domain->arch.vmx_platform.mpci.inst_decoder_regs = ®s;if (!(error =vmx_do_page_fault (va, ®s))) {/*
xen/include/asm-x86/vmx_intercept.h +0 -1
@@ -8,7 +8,6 @@#include <xen/time.h> #include <xen/errno.h> #include <public/io/ioreq.h> -#define MAX_IO_HANDLER 6
xen/arch/x86/vmx_vmcs.c +4 -2
@@ -151,8 +151,10 @@/* Initialise shared page */ mpfn =phys_to_machine_mapping (gpfn); p =map_domain_page (mpfn); -memset (p,0 ,PAGE_SIZE ); - d->arch.arch_vmx.vmx_platform.shared_page_va = (unsigned long )p; + d->domain->arch.vmx_platform.shared_page_va = (unsigned long )p; + +clear_bit (iopacket_port (d->domain), + &d->domain->shared_info->evtchn_mask[0 ]);return 0 ; }
xen/include/asm-x86/vmx_vmcs.h +0 -1
@@ -68,7 +68,6 @@unsigned long cpu_cr3;unsigned long cpu_state;struct msr_state msr_content; -struct virutal_platform_def vmx_platform; };#define vmx_schedule_tail (next) \
tools/ioemu/target-i386-dm/Makefile +1 -1
@@ -390,7 +390,7 @@ ifneq ($(PROGS),) install -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)" endif - install -m 755 device-model "$(DESTDIR)$(bindir)" + install -m 755 qemu-dm.debug "$(DESTDIR)$(bindir)" install -m 755 qemu-ifup "$(DESTDIR)$(configdir)" gunzip -c qemu-vgaram-bin.gz >qemu-vgaram-bin install -m 755 qemu-vgaram-bin "$(DESTDIR)$(configdir)"
xen/arch/x86/vmx_io.c +20 -17
@@ -317,10 +317,11 @@struct mi_per_cpu_info *mpci_p;struct cpu_user_regs *inst_decoder_regs; - mpci_p = &v->arch.arch_vmx.vmx_platform.mpci; + mpci_p = &v->domain->arch.vmx_platform.mpci; inst_decoder_regs = mpci_p->inst_decoder_regs; - vio = (vcpu_iodata_t *) v->arch.arch_vmx.vmx_platform.shared_page_va; + vio =get_vio (v->domain, v->vcpu_id); +if (vio ==0 ) {VMX_DBG_LOG (DBG_LEVEL_1 ,"bad shared page: %lx" , (unsigned long ) vio);
@@ -356,10 +357,10 @@ }int size =-1 , index =-1 ; - size =operand_size (v->arch.arch_vmx.vmx_platform.mpci.mmio_target); - index =operand_index (v->arch.arch_vmx.vmx_platform.mpci.mmio_target); - -if (v->arch.arch_vmx.vmx_platform.mpci.mmio_target &WZEROEXTEND ) { + size =operand_size (v->domain->arch.vmx_platform.mpci.mmio_target); + index =operand_index (v->domain->arch.vmx_platform.mpci.mmio_target); + +if (v->domain->arch.vmx_platform.mpci.mmio_target &WZEROEXTEND ) { p->u.data = p->u.data &0xffff ; }set_reg_value (size, index,0 , regs, p->u.data);
@@ -404,18 +405,18 @@int vmx_clear_pending_io_event (struct vcpu *v) {struct domain *d = v->domain; +int port =iopacket_port (d);/* evtchn_pending is shared by other event channels in 0-31 range */ -if (!d->shared_info->evtchn_pending[IOPACKET_PORT >>5 ]) -clear_bit (IOPACKET_PORT >>5 , &v->vcpu_info->evtchn_pending_sel); +if (!d->shared_info->evtchn_pending[port>>5 ]) +clear_bit (port>>5 , &v->vcpu_info->evtchn_pending_sel);/* Note: VMX domains may need upcalls as well */ if (!v->vcpu_info->evtchn_pending_sel)clear_bit (0 , &v->vcpu_info->evtchn_upcall_pending); -/* clear the pending bit for IOPACKET_PORT */ -return test_and_clear_bit (IOPACKET_PORT , - &d->shared_info->evtchn_pending[0 ]); +/* clear the pending bit for port */ +return test_and_clear_bit (port, &d->shared_info->evtchn_pending[0 ]); }/* Because we've cleared the pending events first, we need to guarantee that
@@ -437,17 +438,17 @@void vmx_wait_io () {extern void do_block (); +int port =iopacket_port (current->domain);do { -if (!test_bit (IOPACKET_PORT , - ¤t->domain->shared_info->evtchn_pending[0 ])) +if (!test_bit (port, ¤t->domain->shared_info->evtchn_pending[0 ]))do_block ();vmx_check_events (current);if (!test_bit (ARCH_VMX_IO_WAIT , ¤t->arch.arch_vmx.flags))break ;/* Events other than IOPACKET_PORT might have woken us up. In that case, safely go back to sleep. */ -clear_bit (IOPACKET_PORT >>5 , ¤t->vcpu_info->evtchn_pending_sel); +clear_bit (port>>5 , ¤t->vcpu_info->evtchn_pending_sel);clear_bit (0 , ¤t->vcpu_info->evtchn_upcall_pending); }while (1 ); }
@@ -522,7 +523,8 @@ {vcpu_iodata_t *vio; - vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; + vio =get_vio (d->domain, d->vcpu_id); +if (vio ==0 ) {VMX_DBG_LOG (DBG_LEVEL_1 ,"bad shared page: %lx" , (unsigned long ) vio);
@@ -536,7 +538,8 @@ {vcpu_iodata_t *vio; - vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; + vio =get_vio (d->domain, d->vcpu_id); +if (vio ==0 ) {VMX_DBG_LOG (DBG_LEVEL_1 ,"bad shared page: %lx" , (unsigned long ) vio);
@@ -555,7 +558,7 @@ {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); +struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit);if (highest_vector ==-1 )return ;
tools/python/xen/xend/image.py +61 -33
140 lines not on this page · raw message
xen/arch/x86/vmx_platform.c +5 -4
@@ -565,10 +565,11 @@struct cpu_user_regs *inst_decoder_regs;extern long evtchn_send (int lport); - mpci_p = ¤t->arch.arch_vmx.vmx_platform.mpci; + mpci_p = ¤t->domain->arch.vmx_platform.mpci; inst_decoder_regs = mpci_p->inst_decoder_regs; - vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; + vio =get_vio (d->domain, d->vcpu_id); +if (vio ==NULL ) {printk ("bad shared page\n" );domain_crash_synchronous ();
@@ -612,7 +613,7 @@ p->port_mm, p->size, p->addr, value, p->count);#endif -evtchn_send (IOPACKET_PORT ); +evtchn_send (iopacket_port (d->domain));vmx_wait_io (); }
@@ -626,7 +627,7 @@unsigned char inst[MAX_INST_LEN ];int vm86, ret; - mpci_p = ¤t->arch.arch_vmx.vmx_platform.mpci; + mpci_p = ¤t->domain->arch.vmx_platform.mpci; inst_decoder_regs = mpci_p->inst_decoder_regs;__vmread (GUEST_RIP , &eip);
xen/arch/x86/vmx_intercept.c +5 -5
@@ -35,7 +35,7 @@int vmx_io_intercept (ioreq_t *p) {struct vcpu *d = current; -struct vmx_handler_t *handler = &(d->arch.arch_vmx.vmx_platform.vmx_handler); +struct vmx_handler_t *handler = &(d->domain->arch.vmx_platform.vmx_handler);int i;unsigned long addr, offset;for (i =0 ; i < handler->num_slot; i++) {
@@ -51,7 +51,7 @@int register_io_handler (unsigned long addr,unsigned long offset,intercept_action_t action) {struct vcpu *d = current; -struct vmx_handler_t *handler = &(d->arch.arch_vmx.vmx_platform.vmx_handler); +struct vmx_handler_t *handler = &(d->domain->arch.vmx_platform.vmx_handler);int num = handler->num_slot;if (num >=MAX_IO_HANDLER ) {
@@ -163,7 +163,7 @@int intercept_pit_io (ioreq_t *p) {struct vcpu *d = current; -struct vmx_virpit_t *vpit = &(d->arch.arch_vmx.vmx_platform.vmx_pit); +struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit); if (p->size != 1 || p->pdata_valid ||
@@ -206,10 +206,10 @@*/ void vmx_hooks_assist (struct vcpu *d) { -vcpu_iodata_t *vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; +vcpu_iodata_t * vio =get_vio (d->domain, d->vcpu_id);ioreq_t *p = &vio->vp_ioreq;unsigned long *intr = &(vio->vp_intr[0 ]); -struct vmx_virpit_t *vpit = &(d->arch.arch_vmx.vmx_platform.vmx_pit); +struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit);int rw_mode;/* load init count*/
tools/ioemu/exec.c +1 -1
@@ -127,7 +127,7 @@void cpu_set_log (int log_flags) { loglevel = log_flags; -if (loglevel && !logfile) { +if (!logfile) { logfile =fopen (logfilename,"w" );if (!logfile) {perror (logfilename);
tools/ioemu/vl.h +1 -0
@@ -624,6 +624,7 @@uint32_t pic_intack_read (CPUState *env);void pic_info (void );void irq_info (void ); +void sp_info (void );int pic_irq2vec (int irq);/* i8254.c */
tools/ioemu/vl.c +8 -2
@@ -116,7 +116,7 @@int64_t ticks_per_sec;int boot_device ='c' ;int ram_size; -int domid; +int domid =-1 ;static char network_script[1024 ];int pit_min_timer_count =0 ;int nb_nics;
@@ -2402,6 +2402,9 @@ macaddr[4 ] =0x34 ; macaddr[5 ] =0x56 ; +/* init debug */ +cpu_set_log (0 ); + optind =1 ;for (;;) {if (optind >= argc)
@@ -2808,10 +2811,13 @@exit (-1 ); } - shared_page =xc_map_foreign_range (xc_handle, domid,PAGE_SIZE ,PROT_READ |PROT_WRITE , page_array[nr_pages -1 ]); + + +fprintf (logfile,"shared page at pfn:%lx, mfn: %lx\n" , (nr_pages-1 ), + (page_array[nr_pages -1 ]));/* we always create the cdrom drive, even if no disk is there */ bdrv_init ();
tools/ioemu/hw/i8254.c +2 -2
@@ -217,7 +217,7 @@void pit_reset_vmx_vectors () { -extern void *shared_page; +extern shared_iopage_t *shared_page;ioreq_t *req;int irq, i;PITChannelState *s;
@@ -239,7 +239,7 @@ s = &pit_state.channels[vmx_channel];fprintf (logfile,"VMX_PIT:guest init pit channel %d!\n" , vmx_channel); - req = &((vcpu_iodata_t *) shared_page)->vp_ioreq; + req = &shared_page->vcpu_iodata[0 ].vp_ioreq; req->state =STATE_IORESP_HOOK ;/*
xen/arch/x86/domain.c +2 -3
@@ -345,7 +345,7 @@ v->arch.schedule_tail = arch_vmx_do_launch;#if defined (__i386) - v->arch.arch_vmx.vmx_platform.real_mode_data = + v->domain->arch.vmx_platform.real_mode_data = (unsigned long *) regs->esi;#endif
@@ -356,7 +356,6 @@*/ memset (&v->domain->shared_info->evtchn_mask[0 ],0xff ,sizeof (v->domain->shared_info->evtchn_mask)); -clear_bit (IOPACKET_PORT , &v->domain->shared_info->evtchn_mask[0 ]);/* Put the domain in shadow mode even though we're going to be using * the shared 1:1 page table initially. It shouldn't hurt */
@@ -906,7 +905,7 @@ v->arch.arch_vmx.vmcs =0 ;free_monitor_pagetable (v); - rem_ac_timer(&v->arch.arch_vmx.vmx_platform.vmx_pit.pit_timer); + rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer); }#else #define vmx_relinquish_resources (_v) ((void)0)
xen/include/public/io/ioreq.h +14 -2
@@ -29,8 +29,6 @@#define STATE_IORESP_READY 3#define STATE_IORESP_HOOK 4 -#define IOPACKET_PORT 2 -/* VMExit dispatcher should cooperate with instruction decoder to prepare this structure and notify service OS and DM by sending virq */
@@ -53,9 +51,23 @@#define BITS_PER_BYTE 8#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(unsigned long))) +/* We only track the master PIC state here */ +typedef struct { +uint16_t irr;/* interrupt request register */ +uint16_t imr;/* interrupt mask register */ +uint16_t isr;/* interrupt service register */ + +int eport;/* Event channel port */ +}global_iodata_t ; +typedef struct {ioreq_t vp_ioreq;unsigned long vp_intr[INTR_LEN ]; }vcpu_iodata_t ; +typedef struct { +global_iodata_t sp_global; +vcpu_iodata_t vcpu_iodata[1 ]; +}shared_iopage_t ; +#endif /* _IOREQ_H_ */
tools/ioemu/target-i386-dm/qemu-dm.debug new file +5 -0
@@ -0,0 +1,5 @@ +#!/bin/sh + +echo $* > /tmp/args +echo $DISPLAY >> /tmp/args +exec /usr/bin/qemu-dm $*
tools/ioemu/target-i386-dm/device-model deleted +0 -91
91 lines not on this page · raw message