[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [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)
)

Signed-off-by: Edwin Zhai <edwin.zhai@xxxxxxxxx>
Signed-off-by: Arun Sharma <arun.sharma@xxxxxxxxx>

diff -r 23833ae55425 -r febfcd0a1a0a xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Tue Jun 28 16:38:30 2005
+++ b/xen/include/asm-x86/domain.h      Thu Jun 30 03:20:48 2005
@@ -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
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c      Tue Jun 28 16:38:30 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c      Thu Jun 30 03:20:48 2005
@@ -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);
diff -r 23833ae55425 -r febfcd0a1a0a tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Tue Jun 28 16:38:30 2005
+++ b/tools/python/xen/xm/create.py     Thu Jun 30 03:20:48 2005
@@ -254,9 +254,69 @@
           fn=set_value, default='',
           use="Path to device model program.")
 
-gopts.var('device_config', val='FILE',
-          fn=set_value, default='',
-          use="Path to device model configuration.")
+gopts.var('hda', val='FILE',
+          fn=set_value, default='',
+          use="Path to hda")
+
+gopts.var('hdb', val='FILE',
+          fn=set_value, default='',
+          use="Path to hdb")
+
+gopts.var('hdc', val='FILE',
+          fn=set_value, default='',
+          use="Path to hdc")
+
+gopts.var('hdd', val='FILE',
+          fn=set_value, default='',
+          use="Path to hdd")
+
+gopts.var('fda', val='FILE',
+          fn=set_value, default='',
+          use="Path to fda")
+
+gopts.var('fdb', val='FILE',
+          fn=set_value, default='',
+          use="Path to fdb")
+
+gopts.var('serial', val='FILE',
+          fn=set_value, default='',
+          use="Path to serial or pty or vc")
+
+gopts.var('localtime', val='no|yes',
+          fn=set_bool, default=0,
+          use="Is RTC set to localtime?")
+
+gopts.var('stdvga', val='no|yes',
+          fn=set_bool, default=0,
+          use="Use std vga or cirrhus logic graphics")
+
+gopts.var('isa', val='no|yes',
+          fn=set_bool, default=0,
+          use="Simulate an ISA only system?")
+
+gopts.var('cdrom', val='FILE',
+          fn=set_value, default='',
+          use="Path to cdrom")
+
+gopts.var('macaddr', val='MACADDR',
+          fn=set_value, default='',
+          use="Macaddress of the first network interface")
+
+gopts.var('boot', val="a|b|c|d",
+          fn=set_value, default='c',
+          use="Default boot device")
+
+gopts.var('nographic', val='no|yes',
+          fn=set_bool, default=0,
+          use="Should device models use graphics?")
+
+gopts.var('sdl', val='',
+          fn=set_value, default=None,
+          use="""Should the device model use SDL?""")
+
+gopts.var('display', val='DISPLAY',
+          fn=set_value, default='localhost:0',
+          use="X11 display to use")
 
 def strip(pre, s):
     """Strip prefix 'pre' if present.
@@ -382,12 +442,11 @@
 def configure_vmx(opts, config_devs, vals):
     """Create the config for VMX devices.
     """
-    memmap = vals.memmap
-    device_model = vals.device_model
-    device_config = vals.device_config
-    config_devs.append(['memmap', memmap])
-    config_devs.append(['device_model', device_model])
-    config_devs.append(['device_config', device_config])
+    args = [ 'memmap', 'device_model', 'hda', 'hdb', 'hdc', 'hdd', 'cdrom',
+            'boot', 'fda', 'fdb', 'localtime', 'serial', 'macaddr', 'stdvga', 
+             'isa', 'nographic', 'vnc', 'sdl', 'display']       
+    for a in args:
+       config_devs.append([a, vals.__dict__[a]])
 
 def run_bootloader(opts, config, vals):
     if not os.access(vals.bootloader, os.X_OK):
@@ -614,10 +673,13 @@
         if '=' in arg:
             (var, val) = arg.strip().split('=', 1)
             gopts.setvar(var.strip(), val.strip())
+    opts.vals.display = os.getenv("DISPLAY")
     if opts.vals.config:
         config = opts.vals.config
     else:
         opts.load_defconfig()
+        if opts.vals.dryrun:
+           opts.vals.vnc = 0
         preprocess(opts, opts.vals)
         if not opts.getopt('name') and opts.getopt('defconfig'):
             opts.setopt('name', os.path.basename(opts.getopt('defconfig')))
diff -r 23833ae55425 -r febfcd0a1a0a xen/include/asm-x86/vmx_platform.h
--- a/xen/include/asm-x86/vmx_platform.h        Tue Jun 28 16:38:30 2005
+++ b/xen/include/asm-x86/vmx_platform.h        Thu Jun 30 03:20:48 2005
@@ -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;
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/monitor.c
--- a/tools/ioemu/monitor.c     Tue Jun 28 16:38:30 2005
+++ b/tools/ioemu/monitor.c     Thu Jun 30 03:20:48 2005
@@ -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, },
 };
 
diff -r 23833ae55425 -r febfcd0a1a0a tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx      Tue Jun 28 16:38:30 2005
+++ b/tools/examples/xmexample.vmx      Thu Jun 30 03:20:48 2005
@@ -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 
diff -r 23833ae55425 -r febfcd0a1a0a xen/include/asm-x86/vmx.h
--- a/xen/include/asm-x86/vmx.h Tue Jun 28 16:38:30 2005
+++ b/xen/include/asm-x86/vmx.h Thu Jun 30 03:20:48 2005
@@ -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__ */
diff -r 23833ae55425 -r febfcd0a1a0a tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c        Tue Jun 28 16:38:30 2005
+++ b/tools/libxc/xc_vmx_build.c        Thu Jun 30 03:20:48 2005
@@ -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
diff -r 23833ae55425 -r febfcd0a1a0a xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        Tue Jun 28 16:38:30 2005
+++ b/xen/arch/x86/vmx.c        Thu Jun 30 03:20:48 2005
@@ -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 = &regs;
+            v->domain->arch.vmx_platform.mpci.inst_decoder_regs = &regs;
 
             if (!(error = vmx_do_page_fault(va, &regs))) {
                 /*
diff -r 23833ae55425 -r febfcd0a1a0a xen/include/asm-x86/vmx_intercept.h
--- a/xen/include/asm-x86/vmx_intercept.h       Tue Jun 28 16:38:30 2005
+++ b/xen/include/asm-x86/vmx_intercept.h       Thu Jun 30 03:20:48 2005
@@ -8,7 +8,6 @@
 #include <xen/time.h>
 #include <xen/errno.h>
 #include <public/io/ioreq.h>
-
 
 #define MAX_IO_HANDLER 6
 
diff -r 23833ae55425 -r febfcd0a1a0a xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c   Tue Jun 28 16:38:30 2005
+++ b/xen/arch/x86/vmx_vmcs.c   Thu Jun 30 03:20:48 2005
@@ -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;
 }
diff -r 23833ae55425 -r febfcd0a1a0a xen/include/asm-x86/vmx_vmcs.h
--- a/xen/include/asm-x86/vmx_vmcs.h    Tue Jun 28 16:38:30 2005
+++ b/xen/include/asm-x86/vmx_vmcs.h    Thu Jun 30 03:20:48 2005
@@ -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)         \
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile       Tue Jun 28 16:38:30 2005
+++ b/tools/ioemu/target-i386-dm/Makefile       Thu Jun 30 03:20:48 2005
@@ -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)"
diff -r 23833ae55425 -r febfcd0a1a0a xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c     Tue Jun 28 16:38:30 2005
+++ b/xen/arch/x86/vmx_io.c     Thu Jun 30 03:20:48 2005
@@ -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, 
-            &current->domain->shared_info->evtchn_pending[0]))
+        if(!test_bit(port, &current->domain->shared_info->evtchn_pending[0]))
             do_block();
         vmx_check_events(current);
         if (!test_bit(ARCH_VMX_IO_WAIT, &current->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, &current->vcpu_info->evtchn_pending_sel);
+        clear_bit(port>>5, &current->vcpu_info->evtchn_pending_sel);
         clear_bit(0, &current->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;
diff -r 23833ae55425 -r febfcd0a1a0a tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Jun 28 16:38:30 2005
+++ b/tools/python/xen/xend/image.py    Thu Jun 30 03:20:48 2005
@@ -231,7 +231,7 @@
     
     ostype = "vmx"
     memmap = None
-    memmap_value = None
+    memmap_value = []
     device_channel = None
 
     def createImage(self):
@@ -242,9 +242,12 @@
         self.createDomain()
 
     def buildDomain(self):
+        # Create an event channel
+        self.device_channel = channel.eventChannel(0, self.vm.getDomain())
+        log.info("VMX device model port: %d", self.device_channel.port2)
         return xc.vmx_build(dom            = self.vm.getDomain(),
                             image          = self.kernel,
-                            control_evtchn = 0,
+                            control_evtchn = self.device_channel.port2,
                             memsize        = self.vm.memory,
                             memmap         = self.memmap_value,
                             cmdline        = self.cmdline,
@@ -254,51 +257,74 @@
     def parseMemmap(self):
         self.memmap = sxp.child_value(self.vm.config, "memmap")
         if self.memmap is None:
-            raise VmError("missing memmap")
+            return
         memmap = sxp.parse(open(self.memmap))[0]
         from xen.util.memmap import memmap_parse
         self.memmap_value = memmap_parse(memmap)
         
-    def createDeviceModel_old(self):
-        device_model = sxp.child_value(self.vm.config, 'device_model')
-        if not device_model:
-            raise VmError("vmx: missing device model")
-        device_config = sxp.child_value(self.vm.config, 'device_config')
-        if not device_config:
-            raise VmError("vmx: missing device config")
-        # Create an event channel.
-        self.device_channel = channel.eventChannel(0, self.vm.getDomain())
-        # Execute device model.
-        #todo: Error handling
-        os.system(device_model
-                  + " -f %s" % device_config
-                  + " -d %d" % self.vm.getDomain()
-                  + " -p %d" % self.device_channel['port1']
-                  + " -m %s" % self.vm.memory)
-
+    # Return a list of cmd line args to the device models based on the
+    # xm config file
+    def parseDeviceModelArgs(self):
+       dmargs = [ 'hda', 'hdb', 'hdc', 'hdd', 'cdrom', 'boot', 'fda', 'fdb',
+                   'localtime', 'serial', 'macaddr', 'stdvga', 'isa' ] 
+       ret = []
+       for a in dmargs:
+                   v = sxp.child_value(self.vm.config, a)
+
+            # python doesn't allow '-' in variable names
+            if a == 'stdvga': a = 'std-vga'
+
+            # Handle booleans gracefully
+            if a in ['localtime', 'std-vga', 'isa']:
+                v = int(v)
+
+           log.debug("args: %s, val: %s" % (a,v))
+           if v: 
+               ret.append("-%s" % a)
+               ret.append("%s" % v)
+
+       # Handle graphics library related options
+       vnc = int(sxp.child_value(self.vm.config, 'vnc'))
+       sdl = int(sxp.child_value(self.vm.config, 'sdl'))
+       nographic = int(sxp.child_value(self.vm.config, 'nographic'))
+       if nographic:
+           ret.append('-nographic')
+           return ret
+       
+       if vnc and sdl:
+           ret = ret + ['-vnc-and-sdl', '-k', 'en-us']
+       elif vnc:
+           ret = ret + ['-vnc', '-k', 'en-us']
+       if vnc:
+           vncport = int(self.vm.getDomain()) + 5900
+           ret = ret + ['-vncport', '%d' % vncport]
+       return ret
+                 
     def createDeviceModel(self):
         device_model = sxp.child_value(self.vm.config, 'device_model')
         if not device_model:
             raise VmError("vmx: missing device model")
-        device_config = sxp.child_value(self.vm.config, 'device_config')
-        if not device_config:
-            raise VmError("vmx: missing device config")
-        # Create an event channel
-        self.device_channel = channel.eventChannel(0, self.vm.getDomain())
         # Execute device model.
         #todo: Error handling
         # XXX RN: note that the order of args matter!
-        os.system(device_model
-                  + " -f %s" % device_config
-                  + self.vncParams()
-                  + " -d %d" % self.vm.getDomain()
-                  + " -p %d" % (int(self.device_channel.port1)-1)
-                  + " -m %s" % self.vm.memory)
+        args = [device_model]
+        vnc = self.vncParams()
+        if len(vnc):
+            args = args + vnc
+        args = args + ([ "-d",  "%d" % self.vm.getDomain(),
+                  "-p", "%d" % self.device_channel.port1,
+                  "-m", "%s" % self.vm.memory ])
+       args = args + self.parseDeviceModelArgs()
+        env = dict(os.environ)
+        env['DISPLAY'] = sxp.child_value(self.vm.config, 'display')
+        log.info("spawning device models: %s %s", device_model, args)
+        self.pid = os.spawnve(os.P_NOWAIT, device_model, args, env)
+        log.info("device model pid: %d", self.pid)
 
     def vncParams(self):
         # see if a vncviewer was specified
         # XXX RN: bit of a hack. should unify this, maybe stick in config space
-        vncconnect=""
+        vncconnect=[]
         image = self.config
         args = sxp.child_value(image, "args")
         if args:
@@ -306,12 +332,14 @@
             for arg in arg_list:
                 al = string.split(arg, '=')
                 if al[0] == "VNC_VIEWER":
-                    vncconnect=" -v %s" % al[1]
+                    vncconnect=["-vncconnect", "%s" % al[1]]
                     break
         return vncconnect
 
     def destroy(self):
         channel.eventChannelClose(self.device_channel)
+        os.system("kill -KILL"
+                + " %d" % self.pid)
 
     def getDomainMemory(self, mem_mb):
         return (mem_mb * 1024) + self.getPageTableSize(mem_mb)
diff -r 23833ae55425 -r febfcd0a1a0a xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c       Tue Jun 28 16:38:30 2005
+++ b/xen/arch/x86/vmx_platform.c       Thu Jun 30 03:20:48 2005
@@ -565,10 +565,11 @@
     struct cpu_user_regs *inst_decoder_regs;
     extern long evtchn_send(int lport);
 
-    mpci_p = &current->arch.arch_vmx.vmx_platform.mpci;
+    mpci_p = &current->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 = &current->arch.arch_vmx.vmx_platform.mpci;
+    mpci_p = &current->domain->arch.vmx_platform.mpci;
     inst_decoder_regs = mpci_p->inst_decoder_regs;
 
     __vmread(GUEST_RIP, &eip);
diff -r 23833ae55425 -r febfcd0a1a0a xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c      Tue Jun 28 16:38:30 2005
+++ b/xen/arch/x86/vmx_intercept.c      Thu Jun 30 03:20:48 2005
@@ -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*/
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/exec.c
--- a/tools/ioemu/exec.c        Tue Jun 28 16:38:30 2005
+++ b/tools/ioemu/exec.c        Thu Jun 30 03:20:48 2005
@@ -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);
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue Jun 28 16:38:30 2005
+++ b/tools/ioemu/vl.h  Thu Jun 30 03:20:48 2005
@@ -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 */
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Jun 28 16:38:30 2005
+++ b/tools/ioemu/vl.c  Thu Jun 30 03:20:48 2005
@@ -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();
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/hw/i8254.c
--- a/tools/ioemu/hw/i8254.c    Tue Jun 28 16:38:30 2005
+++ b/tools/ioemu/hw/i8254.c    Thu Jun 30 03:20:48 2005
@@ -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;
     /*
diff -r 23833ae55425 -r febfcd0a1a0a xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Tue Jun 28 16:38:30 2005
+++ b/xen/arch/x86/domain.c     Thu Jun 30 03:20:48 2005
@@ -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)
diff -r 23833ae55425 -r febfcd0a1a0a xen/include/public/io/ioreq.h
--- a/xen/include/public/io/ioreq.h     Tue Jun 28 16:38:30 2005
+++ b/xen/include/public/io/ioreq.h     Thu Jun 30 03:20:48 2005
@@ -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_ */
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/target-i386-dm/qemu-dm.debug
--- /dev/null   Tue Jun 28 16:38:30 2005
+++ b/tools/ioemu/target-i386-dm/qemu-dm.debug  Thu Jun 30 03:20:48 2005
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+echo $* > /tmp/args
+echo $DISPLAY >> /tmp/args
+exec /usr/bin/qemu-dm $*
diff -r 23833ae55425 -r febfcd0a1a0a tools/ioemu/target-i386-dm/device-model
--- a/tools/ioemu/target-i386-dm/device-model   Tue Jun 28 16:38:30 2005
+++ /dev/null   Thu Jun 30 03:20:48 2005
@@ -1,91 +0,0 @@
-#!/bin/sh
-
-. /etc/rc.d/init.d/functions
-
-qemubin=/usr/bin/qemu-dm
-
-ulimit -c unlimited
-
-# Use this for debugging:
-#gdb --args /usr/sbin/qemu-dm -hda /var/images/qemu-linux.img -nographic \
-#      -serial pty -l 'ioport,int' $*
-
-# XXX this is a bit skanky. we assume an order of arguments here.
-# namely to have configfile and vncconnect argument as the first 
-# two arguments.
-
-while getopts ":f:v:d:" opt;
-do
-    case $opt in
-      f) QEMUCONFIGFILE=$OPTARG;;
-      v) VNCCONNECT=$OPTARG;;
-      d) DOMAIN=$OPTARG;;
-      \?) echo;;
-    esac
-done
-if [ "x$QEMUCONFIGFILE" != "x" ]; then shift; shift; fi
-if [ "x$VNCCONNECT" != "x" ]; then shift; shift; fi
-
-
-echo $QEMUCONFIGFILE
-if [ ! -z $QEMUCONFIGFILE ];then
-    . $QEMUCONFIGFILE
-else
-    echo "no config file specified!" > /dev/tty
-    echo "no config file specified!" >> /tmp/qemustart.log
-    exit
-fi
- 
-PARMETER=""
-
-if [ ! -z $hda ];then
-PARMETER="$PARMETER -hda $hda"
-fi
-
-if [ ! -z $hdb ];then
-PARMETER="$PARMETER -hdb $hdb"
-fi
-
-if [ ! -z $hdc ];then
-PARMETER="$PARMETER -hdc $hdc"
-fi
-
-if [ ! -z $hdd ];then
-PARMETER="$PARMETER -hdd $hdd"
-fi
-
-if [ ! -z $cdrom ];then
-PARMETER="$PARMETER -cdrom $cdrom"
-fi
-
-if [ ! -z $boot ];then
-PARMETER="$PARMETER -boot $boot"
-fi
-
-if [ ! -z $nographic ] && [ $nographic -eq 1 ];then
-PARMETER="$PARMETER -nographic"
-fi
-
-vnc=${vnc:=1}
-sdl=${sdl:=0}
-if qemu-dm 2>&1 |grep vnc > /dev/null;then
-       if [ $vnc -eq 1 ] && [ $sdl -eq 1 ];then
-               PARMETER="$PARMETER -vnc-and-sdl -k en-us"
-       elif [ $vnc -eq 1 ];then
-               PARMETER="$PARMETER -vnc -k en-us"
-       fi
-    VNCPORT=`expr 5900 + $DOMAIN`
-    PARMETER="$PARMETER -vncport $VNCPORT"
-    if [ "x$VNCCONNECT" != "x" ]; then
-        PARMETER="$PARMETER -vncconnect $VNCCONNECT"
-    fi
-fi
-
-#optional cmdline for qemu        
-#       -nographic \
-#       -serial pty \
-
-
-PARMETER="$PARMETER -l int $*";
-echo "$qemubin $PARMETER" >>/tmp/qemustart.log
-$qemubin $PARMETER &

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.