direct-io.hg

changeset 7514:cc23d4236b20

This patch provide local APIC support for vmx guest.

A configure option is also added to disable it, which is off by default.

Signed-off-by: Jiang Yunhong <yunhong.jiang@intel.com>
Signed-off-by: Li Xin <xin.b.li@intel.com>
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Oct 28 09:48:46 2005 +0100 (2005-10-28)
parents f23b897930d1
children f5de9429118c
files tools/libxc/xc_vmx_build.c tools/libxc/xenguest.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/image.py tools/python/xen/xm/create.py xen/arch/x86/apic.c xen/arch/x86/dm/i8259.c xen/arch/x86/vmx.c xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vlapic.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/vmx_intercept.h xen/include/asm-x86/vmx_platform.h xen/include/asm-x86/vmx_vlapic.h xen/include/asm-x86/vmx_vmcs.h xen/include/public/io/ioreq.h xen/include/public/io/vmx_vpic.h
line diff
     1.1 --- a/tools/libxc/xc_vmx_build.c	Thu Oct 27 18:22:45 2005 +0100
     1.2 +++ b/tools/libxc/xc_vmx_build.c	Fri Oct 28 09:48:46 2005 +0100
     1.3 @@ -279,6 +279,7 @@ static int setup_guest(int xc_handle,
     1.4                         vcpu_guest_context_t *ctxt,
     1.5                         unsigned long shared_info_frame,
     1.6                         unsigned int control_evtchn,
     1.7 +                       unsigned int lapic,
     1.8                         unsigned int vcpus,
     1.9                         unsigned int store_evtchn,
    1.10                         unsigned long *store_mfn)
    1.11 @@ -554,7 +555,7 @@ static int setup_guest(int xc_handle,
    1.12      ctxt->user_regs.eax = 0;
    1.13      ctxt->user_regs.esp = 0;
    1.14      ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */
    1.15 -    ctxt->user_regs.ecx = 0;
    1.16 +    ctxt->user_regs.ecx = lapic;
    1.17      ctxt->user_regs.esi = 0;
    1.18      ctxt->user_regs.edi = 0;
    1.19      ctxt->user_regs.ebp = 0;
    1.20 @@ -597,6 +598,7 @@ int xc_vmx_build(int xc_handle,
    1.21                   int memsize,
    1.22                   const char *image_name,
    1.23                   unsigned int control_evtchn,
    1.24 +                 unsigned int lapic,
    1.25                   unsigned int vcpus,
    1.26                   unsigned int store_evtchn,
    1.27                   unsigned long *store_mfn)
    1.28 @@ -651,9 +653,9 @@ int xc_vmx_build(int xc_handle,
    1.29          goto error_out;
    1.30      }
    1.31  
    1.32 -    if ( setup_guest(xc_handle, domid, memsize, image, image_size,
    1.33 -                     nr_pages, ctxt, op.u.getdomaininfo.shared_info_frame,
    1.34 -                     control_evtchn, vcpus, store_evtchn, store_mfn) < 0)
    1.35 +    if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
    1.36 +                     ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
    1.37 +                     lapic, vcpus, store_evtchn, store_mfn) < 0)
    1.38      {
    1.39          ERROR("Error constructing guest OS");
    1.40          goto error_out;
     2.1 --- a/tools/libxc/xenguest.h	Thu Oct 27 18:22:45 2005 +0100
     2.2 +++ b/tools/libxc/xenguest.h	Fri Oct 28 09:48:46 2005 +0100
     2.3 @@ -56,6 +56,7 @@ int xc_vmx_build(int xc_handle,
     2.4                   int memsize,
     2.5                   const char *image_name,
     2.6                   unsigned int control_evtchn,
     2.7 +                 unsigned int lapic,
     2.8                   unsigned int vcpus,
     2.9                   unsigned int store_evtchn,
    2.10                   unsigned long *store_mfn);
     3.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Thu Oct 27 18:22:45 2005 +0100
     3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Fri Oct 28 09:48:46 2005 +0100
     3.3 @@ -438,19 +438,20 @@ static PyObject *pyxc_vmx_build(PyObject
     3.4      char *image;
     3.5      int control_evtchn, store_evtchn;
     3.6      int vcpus = 1;
     3.7 +    int lapic = 0;
     3.8      int memsize;
     3.9      unsigned long store_mfn = 0;
    3.10  
    3.11      static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
    3.12 -                                "memsize", "image", "vcpus", NULL };
    3.13 +                                "memsize", "image", "lapic", "vcpus", NULL };
    3.14  
    3.15 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisi", kwd_list,
    3.16 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
    3.17                                        &dom, &control_evtchn, &store_evtchn,
    3.18 -                                      &memsize, &image, &vcpus) )
    3.19 +                                      &memsize, &image, &lapic, &vcpus) )
    3.20          return NULL;
    3.21  
    3.22      if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn,
    3.23 -                      vcpus, store_evtchn, &store_mfn) != 0 )
    3.24 +                      lapic, vcpus, store_evtchn, &store_mfn) != 0 )
    3.25          return PyErr_SetFromErrno(xc_error);
    3.26  
    3.27      return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
     4.1 --- a/tools/python/xen/xend/image.py	Thu Oct 27 18:22:45 2005 +0100
     4.2 +++ b/tools/python/xen/xend/image.py	Fri Oct 28 09:48:46 2005 +0100
     4.3 @@ -203,6 +203,10 @@ class VmxImageHandler(ImageHandler):
     4.4  
     4.5          self.dmargs += self.configVNC(imageConfig)
     4.6  
     4.7 +        self.lapic = 0
     4.8 +        lapic = sxp.child_value(imageConfig, 'lapic')
     4.9 +        if not lapic is None:
    4.10 +            self.lapic = int(lapic)
    4.11  
    4.12      def buildDomain(self):
    4.13          # Create an event channel
    4.14 @@ -217,6 +221,7 @@ class VmxImageHandler(ImageHandler):
    4.15          log.debug("control_evtchn = %d", self.device_channel)
    4.16          log.debug("store_evtchn   = %d", store_evtchn)
    4.17          log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
    4.18 +        log.debug("lapic          = %d", self.lapic)
    4.19          log.debug("vcpus          = %d", self.vm.getVCpuCount())
    4.20  
    4.21          return xc.vmx_build(dom            = self.vm.getDomid(),
    4.22 @@ -224,6 +229,7 @@ class VmxImageHandler(ImageHandler):
    4.23                              control_evtchn = self.device_channel,
    4.24                              store_evtchn   = store_evtchn,
    4.25                              memsize        = self.vm.getMemoryTarget() / 1024,
    4.26 +                            lapic          = self.lapic,
    4.27                              vcpus          = self.vm.getVCpuCount())
    4.28  
    4.29  
     5.1 --- a/tools/python/xen/xm/create.py	Thu Oct 27 18:22:45 2005 +0100
     5.2 +++ b/tools/python/xen/xm/create.py	Fri Oct 28 09:48:46 2005 +0100
     5.3 @@ -158,6 +158,10 @@ gopts.var('cpu', val='CPU',
     5.4            fn=set_int, default=None,
     5.5            use="CPU to run the domain on.")
     5.6  
     5.7 +gopts.var('lapic', val='LAPIC',
     5.8 +          fn=set_int, default=0,
     5.9 +          use="Disable or enable local APIC of VMX domain.")
    5.10 +
    5.11  gopts.var('vcpus', val='VCPUS',
    5.12            fn=set_int, default=1,
    5.13            use="# of Virtual CPUS in domain.")
    5.14 @@ -316,10 +320,6 @@ gopts.var('nfs_root', val="PATH",
    5.15            fn=set_value, default=None,
    5.16            use="Set the path of the root NFS directory.")
    5.17  
    5.18 -gopts.var('memmap', val='FILE',
    5.19 -          fn=set_value, default='',
    5.20 -          use="Path to memap SXP file.")
    5.21 -
    5.22  gopts.var('device_model', val='FILE',
    5.23            fn=set_value, default='',
    5.24            use="Path to device model program.")
    5.25 @@ -542,9 +542,9 @@ def configure_vfr(opts, config, vals):
    5.26  def configure_vmx(opts, config_image, vals):
    5.27      """Create the config for VMX devices.
    5.28      """
    5.29 -    args = [ 'memmap', 'device_model', 'vcpus', 'cdrom',
    5.30 -             'boot', 'fda', 'fdb', 'localtime', 'serial', 'macaddr', 'stdvga', 
    5.31 -             'isa', 'nographic', 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000']
    5.32 +    args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
    5.33 +             'localtime', 'serial', 'macaddr', 'stdvga', 'isa', 'nographic',
    5.34 +             'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic']
    5.35      for a in args:
    5.36          if (vals.__dict__[a]):
    5.37              config_image.append([a, vals.__dict__[a]])
     6.1 --- a/xen/arch/x86/apic.c	Thu Oct 27 18:22:45 2005 +0100
     6.2 +++ b/xen/arch/x86/apic.c	Fri Oct 28 09:48:46 2005 +0100
     6.3 @@ -815,6 +815,10 @@ int __init calibrate_APIC_clock(void)
     6.4      return result;
     6.5  }
     6.6  
     6.7 +unsigned int get_apic_bus_scale(void)
     6.8 +{
     6.9 +    return bus_scale;
    6.10 +}
    6.11  
    6.12  static unsigned int calibration_result;
    6.13  
     7.1 --- a/xen/arch/x86/dm/i8259.c	Thu Oct 27 18:22:45 2005 +0100
     7.2 +++ b/xen/arch/x86/dm/i8259.c	Fri Oct 28 09:48:46 2005 +0100
     7.3 @@ -32,8 +32,8 @@
     7.4  #include <public/io/ioreq.h>
     7.5  #include <asm/vmx.h>
     7.6  #include <public/io/vmx_vpic.h>
     7.7 -#include <public/io/vmx_vlapic.h>
     7.8  #include <asm/current.h>
     7.9 +#include <asm/vmx_vlapic.h>
    7.10  
    7.11  /* set irq level. If an edge is detected, then the IRR is set to 1 */
    7.12  static inline void pic_set_irq1(PicState *s, int irq, int level)
    7.13 @@ -135,7 +135,6 @@ void do_pic_irqs (struct vmx_virpic *s, 
    7.14  {
    7.15      s->pics[1].irr |= (uint8_t)(irqs >> 8);
    7.16      s->pics[0].irr |= (uint8_t) irqs;
    7.17 -    /* TODO for alt_irq_func */
    7.18      pic_update_irq(s);
    7.19  }
    7.20  
    7.21 @@ -505,14 +504,22 @@ int cpu_get_pic_interrupt(struct vcpu *v
    7.22  {
    7.23      int intno;
    7.24      struct vmx_virpic *s = &v->domain->arch.vmx_platform.vmx_pic;
    7.25 -    
    7.26 +    struct vmx_platform *plat = &v->domain->arch.vmx_platform;
    7.27 +
    7.28 +    if ( !vlapic_accept_pic_intr(v) )
    7.29 +        return -1;
    7.30 +
    7.31 +    if ( !plat->interrupt_request )
    7.32 +        return -1;
    7.33 +
    7.34      /* read the irq from the PIC */
    7.35      intno = pic_read_irq(s);
    7.36      *type = VLAPIC_DELIV_MODE_EXT;
    7.37 +    plat->interrupt_request = 0;
    7.38      return intno;
    7.39  }
    7.40  
    7.41 -int is_pit_irq(struct vcpu *v, int irq)
    7.42 +int is_pit_irq(struct vcpu *v, int irq, int type)
    7.43  {
    7.44      int  pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base;
    7.45  
     8.1 --- a/xen/arch/x86/vmx.c	Thu Oct 27 18:22:45 2005 +0100
     8.2 +++ b/xen/arch/x86/vmx.c	Fri Oct 28 09:48:46 2005 +0100
     8.3 @@ -65,6 +65,11 @@ void vmx_final_setup_guest(struct vcpu *
     8.4  
     8.5      if ( v == v->domain->vcpu[0] )
     8.6      {
     8.7 +        v->domain->arch.vmx_platform.lapic_enable =
     8.8 +            v->arch.guest_context.user_regs.ecx;
     8.9 +        v->arch.guest_context.user_regs.ecx = 0;
    8.10 +        VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "lapic enable is %d.\n",
    8.11 +                    v->domain->arch.vmx_platform.lapic_enable);
    8.12          /*
    8.13           * Required to do this once per domain
    8.14           * XXX todo: add a seperate function to do these.
    8.15 @@ -96,6 +101,10 @@ void vmx_relinquish_resources(struct vcp
    8.16      destroy_vmcs(&v->arch.arch_vmx);
    8.17      free_monitor_pagetable(v);
    8.18      rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer);
    8.19 +    if ( vmx_apic_support(v->domain) ) {
    8.20 +        rem_ac_timer( &(VLAPIC(v)->vlapic_timer) );
    8.21 +        xfree( VLAPIC(v) );
    8.22 +    }
    8.23  }
    8.24  
    8.25  #ifdef __x86_64__
    8.26 @@ -442,7 +451,9 @@ static int vmx_do_page_fault(unsigned lo
    8.27  
    8.28      /* Use 1:1 page table to identify MMIO address space */
    8.29      if ( mmio_space(gpa) ){
    8.30 -        if (gpa >= 0xFEE00000) { /* workaround for local APIC */
    8.31 +        struct vcpu *v = current;
    8.32 +        /* No support for APIC */
    8.33 +        if (!vmx_apic_support(v->domain) && gpa >= 0xFEC00000) { 
    8.34              u32 inst_len;
    8.35              __vmread(VM_EXIT_INSTRUCTION_LEN, &(inst_len));
    8.36              __update_guest_eip(inst_len);
    8.37 @@ -487,6 +498,7 @@ static void vmx_vmexit_do_cpuid(unsigned
    8.38  {
    8.39      unsigned int eax, ebx, ecx, edx;
    8.40      unsigned long eip;
    8.41 +    struct vcpu *v = current;
    8.42  
    8.43      __vmread(GUEST_RIP, &eip);
    8.44  
    8.45 @@ -500,6 +512,9 @@ static void vmx_vmexit_do_cpuid(unsigned
    8.46      cpuid(input, &eax, &ebx, &ecx, &edx);
    8.47  
    8.48      if (input == 1) {
    8.49 +        if ( vmx_apic_support(v->domain) &&
    8.50 +                !vlapic_global_enabled((VLAPIC(v))) )
    8.51 +            clear_bit(X86_FEATURE_APIC, &edx);
    8.52  #ifdef __i386__
    8.53          clear_bit(X86_FEATURE_PSE, &edx);
    8.54          clear_bit(X86_FEATURE_PAE, &edx);
    8.55 @@ -1441,6 +1456,7 @@ static int vmx_cr_access(unsigned long e
    8.56  static inline void vmx_do_msr_read(struct cpu_user_regs *regs)
    8.57  {
    8.58      u64 msr_content = 0;
    8.59 +    struct vcpu *v = current;
    8.60  
    8.61      VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read: ecx=%lx, eax=%lx, edx=%lx",
    8.62                  (unsigned long)regs->ecx, (unsigned long)regs->eax,
    8.63 @@ -1455,6 +1471,9 @@ static inline void vmx_do_msr_read(struc
    8.64      case MSR_IA32_SYSENTER_EIP:
    8.65          __vmread(GUEST_SYSENTER_EIP, &msr_content);
    8.66          break;
    8.67 +    case MSR_IA32_APICBASE:
    8.68 +        msr_content = VLAPIC(v) ? VLAPIC(v)->apic_base_msr : 0;
    8.69 +        break;
    8.70      default:
    8.71          if(long_mode_do_msr_read(regs))
    8.72              return;
    8.73 @@ -1474,6 +1493,7 @@ static inline void vmx_do_msr_read(struc
    8.74  static inline void vmx_do_msr_write(struct cpu_user_regs *regs)
    8.75  {
    8.76      u64 msr_content;
    8.77 +    struct vcpu *v = current;
    8.78  
    8.79      VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_write: ecx=%lx, eax=%lx, edx=%lx",
    8.80                  (unsigned long)regs->ecx, (unsigned long)regs->eax,
    8.81 @@ -1491,6 +1511,9 @@ static inline void vmx_do_msr_write(stru
    8.82      case MSR_IA32_SYSENTER_EIP:
    8.83          __vmwrite(GUEST_SYSENTER_EIP, msr_content);
    8.84          break;
    8.85 +    case MSR_IA32_APICBASE:
    8.86 +        vlapic_msr_set(VLAPIC(v), msr_content);
    8.87 +        break;
    8.88      default:
    8.89          long_mode_do_msr_write(regs);
    8.90          break;
     9.1 --- a/xen/arch/x86/vmx_intercept.c	Thu Oct 27 18:22:45 2005 +0100
     9.2 +++ b/xen/arch/x86/vmx_intercept.c	Fri Oct 28 09:48:46 2005 +0100
     9.3 @@ -23,6 +23,7 @@
     9.4  #include <asm/vmx_platform.h>
     9.5  #include <asm/vmx_virpit.h>
     9.6  #include <asm/vmx_intercept.h>
     9.7 +#include <asm/vmx_vlapic.h>
     9.8  #include <public/io/ioreq.h>
     9.9  #include <xen/lib.h>
    9.10  #include <xen/sched.h>
    9.11 @@ -32,6 +33,123 @@
    9.12  
    9.13  #ifdef CONFIG_VMX
    9.14  
    9.15 +struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR] =
    9.16 +{
    9.17 +    {
    9.18 +        .check_handler = vlapic_range,
    9.19 +        .read_handler  = vlapic_read,
    9.20 +        .write_handler = vlapic_write
    9.21 +    }
    9.22 +};
    9.23 +
    9.24 +static inline void vmx_mmio_access(struct vcpu *v,
    9.25 +                                   ioreq_t *p,
    9.26 +                                   vmx_mmio_read_t read_handler,
    9.27 +                                   vmx_mmio_write_t write_handler)
    9.28 +{
    9.29 +    ioreq_t *req;
    9.30 +    vcpu_iodata_t *vio = get_vio(v->domain, v->vcpu_id);
    9.31 +    unsigned int tmp1, tmp2;
    9.32 +    unsigned long data;
    9.33 +
    9.34 +    if (vio == NULL) {
    9.35 +        printk("vlapic_access: bad shared page\n");
    9.36 +        domain_crash_synchronous();
    9.37 +    }
    9.38 +
    9.39 +    req = &vio->vp_ioreq;
    9.40 +
    9.41 +    switch (req->type) {
    9.42 +    case IOREQ_TYPE_COPY:
    9.43 +    {
    9.44 +        int sign = (req->df) ? -1 : 1, i;
    9.45 +
    9.46 +        if (!req->pdata_valid) {
    9.47 +            if (req->dir == IOREQ_READ){
    9.48 +                req->u.data = read_handler(v, req->addr, req->size);
    9.49 +            } else {                 /* req->dir != IOREQ_READ */
    9.50 +                write_handler(v, req->addr, req->size, req->u.data);
    9.51 +            }
    9.52 +        } else {                     /* !req->pdata_valid */
    9.53 +            if (req->dir == IOREQ_READ) {
    9.54 +                for (i = 0; i < req->count; i++) {
    9.55 +                    data = read_handler(v,
    9.56 +                      req->addr + (sign * i * req->size),
    9.57 +                      req->size);
    9.58 +                    vmx_copy(&data,
    9.59 +                      (unsigned long)p->u.pdata + (sign * i * req->size),
    9.60 +                      p->size,
    9.61 +                      VMX_COPY_OUT);
    9.62 +                }
    9.63 +            } else {                  /* !req->dir == IOREQ_READ */
    9.64 +                for (i = 0; i < req->count; i++) {
    9.65 +                    vmx_copy(&data,
    9.66 +                      (unsigned long)p->u.pdata + (sign * i * req->size),
    9.67 +                      p->size,
    9.68 +                      VMX_COPY_IN);
    9.69 +                    write_handler(v,
    9.70 +                      req->addr + (sign * i * req->size),
    9.71 +                      req->size, data);
    9.72 +                }
    9.73 +            }
    9.74 +        }
    9.75 +        break;
    9.76 +    }
    9.77 +
    9.78 +    case IOREQ_TYPE_AND:
    9.79 +        tmp1 = read_handler(v, req->addr, req->size);
    9.80 +        if (req->dir == IOREQ_WRITE) {
    9.81 +            tmp2 = tmp1 & (unsigned long) req->u.data;
    9.82 +            write_handler(v, req->addr, req->size, tmp2);
    9.83 +        }
    9.84 +        req->u.data = tmp1;
    9.85 +        break;
    9.86 +
    9.87 +    case IOREQ_TYPE_OR:
    9.88 +        tmp1 = read_handler(v, req->addr, req->size);
    9.89 +        if (req->dir == IOREQ_WRITE) {
    9.90 +            tmp2 = tmp1 | (unsigned long) req->u.data;
    9.91 +            write_handler(v, req->addr, req->size, tmp2);
    9.92 +        }
    9.93 +        req->u.data = tmp1;
    9.94 +        break;
    9.95 +
    9.96 +    case IOREQ_TYPE_XOR:
    9.97 +        tmp1 = read_handler(v, req->addr, req->size);
    9.98 +        if (req->dir == IOREQ_WRITE) {
    9.99 +            tmp2 = tmp1 ^ (unsigned long) req->u.data;
   9.100 +            write_handler(v, req->addr, req->size, tmp2);
   9.101 +        }
   9.102 +        req->u.data = tmp1;
   9.103 +        break;
   9.104 +
   9.105 +    default:
   9.106 +        printk("error ioreq type for local APIC %x\n", req->type);
   9.107 +        domain_crash_synchronous();
   9.108 +        break;
   9.109 +    }
   9.110 +}
   9.111 +
   9.112 +int vmx_mmio_intercept(ioreq_t *p)
   9.113 +{
   9.114 +    struct vcpu *v = current;
   9.115 +    int i;
   9.116 +    struct vmx_mmio_handler *handler = vmx_mmio_handers;
   9.117 +
   9.118 +    /* XXX currently only APIC use intercept */
   9.119 +    if ( !vmx_apic_support(v->domain) )
   9.120 +        return 0;
   9.121 +
   9.122 +    for ( i = 0; i < VMX_MMIO_HANDLER_NR; i++ ) {
   9.123 +        if ( handler[i].check_handler(v, p->addr) ) {
   9.124 +            vmx_mmio_access(v, p,
   9.125 +              handler[i].read_handler, handler[i].write_handler);
   9.126 +            return 1;
   9.127 +        }
   9.128 +    }
   9.129 +    return 0;
   9.130 +}
   9.131 +
   9.132  /*
   9.133   * Check if the request is handled inside xen
   9.134   * return value: 0 --not handled; 1 --handled
    10.1 --- a/xen/arch/x86/vmx_io.c	Thu Oct 27 18:22:45 2005 +0100
    10.2 +++ b/xen/arch/x86/vmx_io.c	Fri Oct 28 09:48:46 2005 +0100
    10.3 @@ -36,9 +36,9 @@
    10.4  #include <asm/apic.h>
    10.5  #include <asm/shadow.h>
    10.6  
    10.7 +#include <asm/vmx_vlapic.h>
    10.8  #include <public/io/ioreq.h>
    10.9  #include <public/io/vmx_vpic.h>
   10.10 -#include <public/io/vmx_vlapic.h>
   10.11  
   10.12  #ifdef CONFIG_VMX
   10.13  #if defined (__i386__)
   10.14 @@ -732,48 +732,6 @@ void vmx_wait_io()
   10.15      } while(1);
   10.16  }
   10.17  
   10.18 -#if defined(__i386__) || defined(__x86_64__)
   10.19 -static inline int __fls(u32 word)
   10.20 -{
   10.21 -    int bit;
   10.22 -
   10.23 -    __asm__("bsrl %1,%0"
   10.24 -            :"=r" (bit)
   10.25 -            :"rm" (word));
   10.26 -    return word ? bit : -1;
   10.27 -}
   10.28 -#else
   10.29 -#define __fls(x)  generic_fls(x)
   10.30 -static __inline__ int generic_fls(u32 x)
   10.31 -{
   10.32 -    int r = 31;
   10.33 -
   10.34 -    if (!x)
   10.35 -        return -1;
   10.36 -    if (!(x & 0xffff0000u)) {
   10.37 -        x <<= 16;
   10.38 -        r -= 16;
   10.39 -    }
   10.40 -    if (!(x & 0xff000000u)) {
   10.41 -        x <<= 8;
   10.42 -        r -= 8;
   10.43 -    }
   10.44 -    if (!(x & 0xf0000000u)) {
   10.45 -        x <<= 4;
   10.46 -        r -= 4;
   10.47 -    }
   10.48 -    if (!(x & 0xc0000000u)) {
   10.49 -        x <<= 2;
   10.50 -        r -= 2;
   10.51 -    }
   10.52 -    if (!(x & 0x80000000u)) {
   10.53 -        x <<= 1;
   10.54 -        r -= 1;
   10.55 -    }
   10.56 -    return r;
   10.57 -}
   10.58 -#endif
   10.59 -
   10.60  /* Simple minded Local APIC priority implementation. Fix later */
   10.61  static __inline__ int find_highest_irq(u32 *pintr)
   10.62  {
   10.63 @@ -801,31 +759,31 @@ interrupt_post_injection(struct vcpu * v
   10.64      struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
   10.65      u64    drift;
   10.66  
   10.67 +    if ( is_pit_irq(v, vector, type) ) {
   10.68 +        if ( !vpit->first_injected ) {
   10.69 +            vpit->first_injected = 1;
   10.70 +            vpit->pending_intr_nr = 0;
   10.71 +        } else {
   10.72 +            vpit->pending_intr_nr--;
   10.73 +        }
   10.74 +        vpit->inject_point = NOW();
   10.75 +        drift = vpit->period_cycles * vpit->pending_intr_nr;
   10.76 +        drift = v->arch.arch_vmx.tsc_offset - drift;
   10.77 +        __vmwrite(TSC_OFFSET, drift);
   10.78 +
   10.79 +#if defined (__i386__)
   10.80 +        __vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
   10.81 +#endif
   10.82 +
   10.83 +    }
   10.84 +
   10.85      switch(type)
   10.86      {
   10.87      case VLAPIC_DELIV_MODE_EXT:
   10.88 -        if ( is_pit_irq(v, vector) ) {
   10.89 -            if ( !vpit->first_injected ) {
   10.90 -                vpit->first_injected = 1;
   10.91 -                vpit->pending_intr_nr = 0;
   10.92 -            }
   10.93 -            else {
   10.94 -                vpit->pending_intr_nr--;
   10.95 -            }
   10.96 -            vpit->inject_point = NOW();
   10.97 -            drift = vpit->period_cycles * vpit->pending_intr_nr;
   10.98 -            drift = v->arch.arch_vmx.tsc_offset - drift;
   10.99 -            __vmwrite(TSC_OFFSET, drift);
  10.100 -
  10.101 -#if defined (__i386__)
  10.102 -            __vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
  10.103 -#endif
  10.104 - 
  10.105 -        }
  10.106          break;
  10.107  
  10.108      default:
  10.109 -        printk("Not support interrupt type\n");
  10.110 +        vlapic_post_injection(v, vector, type);
  10.111          break;
  10.112      }
  10.113  }
  10.114 @@ -885,6 +843,24 @@ void vmx_pic_assist(struct vcpu *v)
  10.115  
  10.116  }
  10.117  
  10.118 +int cpu_get_interrupt(struct vcpu *v, int *type)
  10.119 +{
  10.120 +    int intno;
  10.121 +    struct vmx_virpic *s = &v->domain->arch.vmx_platform.vmx_pic;
  10.122 +
  10.123 +    if ( (intno = cpu_get_apic_interrupt(v, type)) != -1 ) {
  10.124 +        /* set irq request if a PIC irq is still pending */
  10.125 +        /* XXX: improve that */
  10.126 +        pic_update_irq(s);
  10.127 +        return intno;
  10.128 +    }
  10.129 +    /* read the irq from the PIC */
  10.130 +    if ( (intno = cpu_get_pic_interrupt(v, type)) != -1 )
  10.131 +        return intno;
  10.132 +
  10.133 +    return -1;
  10.134 +}
  10.135 +
  10.136  asmlinkage void vmx_intr_assist(void)
  10.137  {
  10.138      int intr_type = 0;
  10.139 @@ -902,11 +878,6 @@ asmlinkage void vmx_intr_assist(void)
  10.140          pic_set_irq(pic, 0, 1);
  10.141      }
  10.142  
  10.143 -    if ( !plat->interrupt_request ) {
  10.144 -        disable_irq_window(cpu_exec_control);
  10.145 -        return;
  10.146 -    }
  10.147 -
  10.148      __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields);
  10.149  
  10.150      if (intr_fields & INTR_INFO_VALID_MASK) {
  10.151 @@ -928,16 +899,21 @@ asmlinkage void vmx_intr_assist(void)
  10.152          enable_irq_window(cpu_exec_control);
  10.153          return;
  10.154      }
  10.155 -    plat->interrupt_request = 0;
  10.156 -    highest_vector = cpu_get_pic_interrupt(v, &intr_type); 
  10.157 +
  10.158 +    highest_vector = cpu_get_interrupt(v, &intr_type); 
  10.159 +
  10.160 +    if (highest_vector == -1) {
  10.161 +        disable_irq_window(cpu_exec_control);
  10.162 +        return;
  10.163 +    }
  10.164  
  10.165      switch (intr_type) {
  10.166      case VLAPIC_DELIV_MODE_EXT:
  10.167 +    case VLAPIC_DELIV_MODE_FIXED:
  10.168 +    case VLAPIC_DELIV_MODE_LPRI:
  10.169          vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE);
  10.170          TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
  10.171          break;
  10.172 -    case VLAPIC_DELIV_MODE_FIXED:
  10.173 -    case VLAPIC_DELIV_MODE_LPRI:
  10.174      case VLAPIC_DELIV_MODE_SMI:
  10.175      case VLAPIC_DELIV_MODE_NMI:
  10.176      case VLAPIC_DELIV_MODE_INIT:
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xen/arch/x86/vmx_vlapic.c	Fri Oct 28 09:48:46 2005 +0100
    11.3 @@ -0,0 +1,997 @@
    11.4 +/*
    11.5 + * vmx_vlapic.c: virtualize LAPIC for VMX vcpus.
    11.6 + * Copyright (c) 2004, Intel Corporation.
    11.7 + *
    11.8 + * This program is free software; you can redistribute it and/or modify it
    11.9 + * under the terms and conditions of the GNU General Public License,
   11.10 + * version 2, as published by the Free Software Foundation.
   11.11 + *
   11.12 + * This program is distributed in the hope it will be useful, but WITHOUT
   11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   11.15 + * more details.
   11.16 + *
   11.17 + * You should have received a copy of the GNU General Public License along with
   11.18 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   11.19 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   11.20 + *
   11.21 + */
   11.22 +
   11.23 +#include <xen/config.h>
   11.24 +#include <xen/types.h>
   11.25 +#include <xen/mm.h>
   11.26 +#include <xen/xmalloc.h>
   11.27 +#include <asm/shadow.h>
   11.28 +#include <asm/page.h>
   11.29 +#include <xen/event.h>
   11.30 +#include <xen/trace.h>
   11.31 +#include <asm/vmx.h>
   11.32 +#include <asm/vmx_platform.h>
   11.33 +#include <asm/vmx_vlapic.h>
   11.34 +
   11.35 +#include <xen/lib.h>
   11.36 +#include <xen/sched.h>
   11.37 +#include <asm/current.h>
   11.38 +#include <public/io/ioreq.h>
   11.39 +
   11.40 +#ifdef CONFIG_VMX
   11.41 +
   11.42 +/* XXX remove this definition after GFW enabled */
   11.43 +#define VLAPIC_NO_BIOS
   11.44 +
   11.45 +extern unsigned int get_apic_bus_scale(void);
   11.46 +
   11.47 +static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] =
   11.48 +{
   11.49 +    0x310ff, 0x117ff, 0x117ff, 0x1f7ff, 0x1f7ff, 0x117ff
   11.50 +};
   11.51 +
   11.52 +int vlapic_find_highest_irr(struct vlapic *vlapic)
   11.53 +{
   11.54 +    int result;
   11.55 +
   11.56 +    result = find_highest_bit((uint32_t *)&vlapic->irr[0], INTR_LEN_32);
   11.57 +
   11.58 +    if (result != -1 && result < 16) {
   11.59 +        printk("VLAPIC: irr on reserved bits %d\n ", result);
   11.60 +        domain_crash_synchronous();
   11.61 +    }
   11.62 +
   11.63 +    return result;
   11.64 +}
   11.65 +
   11.66 +inline int vmx_apic_support(struct domain *d)
   11.67 +{
   11.68 +    return d->arch.vmx_platform.lapic_enable;
   11.69 +}
   11.70 +
   11.71 +int vlapic_find_highest_isr(struct vlapic *vlapic)
   11.72 +{
   11.73 +    int result;
   11.74 +
   11.75 +    result = find_highest_bit((uint32_t *)&vlapic->isr[0], INTR_LEN_32);
   11.76 +
   11.77 +    if (result != -1 && result < 16) {
   11.78 +        int i = 0;
   11.79 +        printk("VLAPIC: isr on reserved bits %d, isr is\n ", result);
   11.80 +        for (i = 0; i < INTR_LEN_32; i += 2)
   11.81 +            printk("%d: 0x%08x%08x\n", i, vlapic->isr[i], vlapic->isr[i+1]);
   11.82 +        return -1;
   11.83 +    }
   11.84 +
   11.85 +    return result;
   11.86 +}
   11.87 +
   11.88 +uint32_t vlapic_update_ppr(struct vlapic *vlapic)
   11.89 +{
   11.90 +    uint32_t tpr, isrv, ppr;
   11.91 +    int isr;
   11.92 +
   11.93 +    tpr = (vlapic->task_priority >> 4) & 0xf;      /* we want 7:4 */
   11.94 +
   11.95 +    isr = vlapic_find_highest_isr(vlapic);
   11.96 +    if (isr != -1)
   11.97 +        isrv = (isr >> 4) & 0xf;   /* ditto */
   11.98 +    else
   11.99 +        isrv = 0;
  11.100 +
  11.101 +    if (tpr >= isrv)
  11.102 +        ppr = vlapic->task_priority & 0xff;
  11.103 +    else
  11.104 +        ppr = isrv << 4;  /* low 4 bits of PPR have to be cleared */
  11.105 +
  11.106 +    vlapic->processor_priority = ppr;
  11.107 +
  11.108 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT,
  11.109 +                "vlapic_update_ppr: vlapic %p ppr %x isr %x isrv %x",
  11.110 +                vlapic, ppr, isr, isrv);
  11.111 +
  11.112 +    return ppr;
  11.113 +}
  11.114 +
  11.115 +/* This only for fixed delivery mode */
  11.116 +int vlapic_match_dest(struct vlapic *target, struct vlapic *source,
  11.117 +                      int short_hand, int dest, int dest_mode,
  11.118 +                      int delivery_mode)
  11.119 +{
  11.120 +    int result = 0;
  11.121 +
  11.122 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_match_dest: "
  11.123 +                "target %p source %p dest %x dest_mode %x short_hand %x "
  11.124 +                "delivery_mode %x",
  11.125 +                target, source, dest, dest_mode, short_hand, delivery_mode);
  11.126 +
  11.127 +    switch (short_hand) {
  11.128 +    case VLAPIC_NO_SHORTHAND:
  11.129 +        if (!dest_mode) {   /* Physical */
  11.130 +            result = (target->id == dest);
  11.131 +        } else {            /* Logical */
  11.132 +            if (((target->dest_format >> 28) & 0xf) == 0xf) {   /* Flat mode */
  11.133 +                result = (target->logical_dest >> 24) & dest;
  11.134 +            } else {
  11.135 +                if ((delivery_mode == VLAPIC_DELIV_MODE_LPRI) &&
  11.136 +                   (dest == 0xff)) {
  11.137 +                    /* What shall we do now? */
  11.138 +                    printk("Broadcast IPI with lowest priority "
  11.139 +                           "delivery mode\n");
  11.140 +                    domain_crash_synchronous();
  11.141 +                }
  11.142 +                result = (target->logical_dest == (dest & 0xf)) ?
  11.143 +                  ((target->logical_dest >> 4) & (dest >> 4)) : 0;
  11.144 +            }
  11.145 +        }
  11.146 +        break;
  11.147 +
  11.148 +    case VLAPIC_SHORTHAND_SELF:
  11.149 +        if (target == source)
  11.150 +            result = 1;
  11.151 +        break;
  11.152 +
  11.153 +    case VLAPIC_SHORTHAND_INCLUDE_SELF:
  11.154 +        result = 1;
  11.155 +        break;
  11.156 +
  11.157 +    case VLAPIC_SHORTHAND_EXCLUDE_SELF:
  11.158 +        if (target != source)
  11.159 +            result = 1;
  11.160 +        break;
  11.161 +
  11.162 +    default:
  11.163 +        break;
  11.164 +    }
  11.165 +
  11.166 +    return result;
  11.167 +}
  11.168 +
  11.169 +/*
  11.170 + * Add a pending IRQ into lapic.
  11.171 + * Return 1 if successfully added and 0 if discarded.
  11.172 + */
  11.173 +int vlapic_accept_irq(struct vlapic *vlapic, int delivery_mode,
  11.174 +                      int vector, int level, int trig_mode)
  11.175 +{
  11.176 +    int	result = 1;
  11.177 +
  11.178 +    switch (delivery_mode) {
  11.179 +    case VLAPIC_DELIV_MODE_FIXED:
  11.180 +    case VLAPIC_DELIV_MODE_LPRI:
  11.181 +        /* FIXME add logic for vcpu on reset */
  11.182 +        if (!vlapic->vcpu || !vlapic_enabled(vlapic))
  11.183 +            return 0;
  11.184 +
  11.185 +        if (test_and_set_bit(vector, &vlapic->irr[0])) {
  11.186 +            printk("<vlapic_accept_irq>"
  11.187 +                    "level trig mode repeatedly for vector %d\n", vector);
  11.188 +            result = 0;
  11.189 +        } else {
  11.190 +            if (level) {
  11.191 +                printk("<vlapic_accept_irq> level trig mode for vector %d\n", vector);
  11.192 +                set_bit(vector, &vlapic->tmr[0]);
  11.193 +            }
  11.194 +        }
  11.195 +        evtchn_set_pending(vlapic->vcpu, iopacket_port(vlapic->domain));
  11.196 +        break;
  11.197 +
  11.198 +    case VLAPIC_DELIV_MODE_RESERVED:
  11.199 +        printk("Ignore deliver mode 3 in vlapic_accept_irq\n");
  11.200 +        break;
  11.201 +
  11.202 +    case VLAPIC_DELIV_MODE_SMI:
  11.203 +    case VLAPIC_DELIV_MODE_NMI:
  11.204 +        /* Fixme */
  11.205 +        printk("TODO: for guest SMI/NMI\n");
  11.206 +        break;
  11.207 +
  11.208 +    case VLAPIC_DELIV_MODE_INIT:
  11.209 +        if (!level && trig_mode == 1) {        //Deassert
  11.210 +            printk("This vmx_vlapic is for P4, no work for De-assert init\n");
  11.211 +        } else {
  11.212 +            /* FIXME How to check the situation after vcpu reset? */
  11.213 +            vlapic->init_sipi_sipi_state = VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI;
  11.214 +            if (vlapic->vcpu) {
  11.215 +                vcpu_pause(vlapic->vcpu);
  11.216 +            }
  11.217 +        }
  11.218 +        break;
  11.219 +
  11.220 +    case VLAPIC_DELIV_MODE_STARTUP:
  11.221 +        if (vlapic->init_sipi_sipi_state != VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI)
  11.222 +            break;
  11.223 +        vlapic->init_sipi_sipi_state = VLAPIC_INIT_SIPI_SIPI_STATE_NORM;
  11.224 +        if (!vlapic->vcpu) {
  11.225 +            /* XXX Call vmx_bringup_ap here */
  11.226 +             result = 0;
  11.227 +        }else{
  11.228 +            //vmx_vcpu_reset(vlapic->vcpu);
  11.229 +        }
  11.230 +        break;
  11.231 +
  11.232 +    default:
  11.233 +        printk("TODO: not support interrup type %x\n", delivery_mode);
  11.234 +        domain_crash_synchronous();
  11.235 +        break;
  11.236 +    }
  11.237 +
  11.238 +    return result;
  11.239 +}
  11.240 +/*
  11.241 +    This function is used by both ioapic and local APIC
  11.242 +    The bitmap is for vcpu_id
  11.243 + */
  11.244 +struct vlapic* apic_round_robin(struct domain *d,
  11.245 +                                uint8_t dest_mode,
  11.246 +                                uint8_t vector,
  11.247 +                                uint32_t bitmap)
  11.248 +{
  11.249 +    int next, old;
  11.250 +    struct vlapic* target = NULL;
  11.251 +
  11.252 +    if (dest_mode == 0) { //Physical mode
  11.253 +        printk("<apic_round_robin> lowest priority for physical mode\n");
  11.254 +        return NULL;
  11.255 +    }
  11.256 +
  11.257 +    if (!bitmap) {
  11.258 +        printk("<apic_round_robin> no bit on bitmap\n");
  11.259 +        return NULL;
  11.260 +    }
  11.261 +
  11.262 +    spin_lock(&d->arch.vmx_platform.round_robin_lock);
  11.263 +
  11.264 +    old = next = d->arch.vmx_platform.round_info[vector];
  11.265 +
  11.266 +    next++;
  11.267 +    if (next == MAX_VIRT_CPUS || !d->vcpu[next])
  11.268 +        next = 0;
  11.269 +
  11.270 +    do {
  11.271 +        /* the vcpu array is arranged according to vcpu_id */
  11.272 +        if (test_bit(next, &bitmap)) {
  11.273 +            target = d->vcpu[next]->arch.arch_vmx.vlapic;
  11.274 +            if (!vlapic_enabled(target)) {
  11.275 +                printk("warning: targe round robin local apic disabled\n");
  11.276 +                /* XXX should we domain crash?? Or should we return NULL */
  11.277 +            }
  11.278 +            break;
  11.279 +        }
  11.280 +
  11.281 +        next ++;
  11.282 +        if (next == MAX_VIRT_CPUS || !d->vcpu[next])
  11.283 +            next = 0;
  11.284 +    }while(next != old);
  11.285 +
  11.286 +    d->arch.vmx_platform.round_info[vector] = next;
  11.287 +    spin_unlock(&d->arch.vmx_platform.round_robin_lock);
  11.288 +    return target;
  11.289 +}
  11.290 +
  11.291 +void
  11.292 +vlapic_EOI_set(struct vlapic *vlapic)
  11.293 +{
  11.294 +    int vector = vlapic_find_highest_isr(vlapic);
  11.295 +
  11.296 +    /* Not every write EOI will has correpsoning ISR,
  11.297 +       one example is when Kernel check timer on setup_IO_APIC */
  11.298 +    if (vector == -1) {
  11.299 +        return ;
  11.300 +    }
  11.301 +
  11.302 +    vlapic_clear_isr(vlapic, vector);
  11.303 +    vlapic_update_ppr(vlapic);
  11.304 +}
  11.305 +
  11.306 +int vlapic_check_vector(struct vlapic *vlapic,
  11.307 +                        unsigned char dm, int vector)
  11.308 +{
  11.309 +    if ((dm == VLAPIC_DELIV_MODE_FIXED) && (vector < 16)) {
  11.310 +        vlapic->err_status |= 0x40;
  11.311 +        vlapic_accept_irq(vlapic, VLAPIC_DELIV_MODE_FIXED,
  11.312 +          vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0);
  11.313 +        printk("<vlapic_check_vector>: check fail\n");
  11.314 +        return 0;
  11.315 +    }
  11.316 +    return 1;
  11.317 +}
  11.318 +
  11.319 +
  11.320 +void vlapic_ipi(struct vlapic *vlapic)
  11.321 +{
  11.322 +    unsigned int dest = (vlapic->icr_high >> 24) & 0xff;
  11.323 +    unsigned int short_hand = (vlapic->icr_low >> 18) & 3;
  11.324 +    unsigned int trig_mode = (vlapic->icr_low >> 15) & 1;
  11.325 +    unsigned int level = (vlapic->icr_low >> 14) & 1;
  11.326 +    unsigned int dest_mode = (vlapic->icr_low >> 11) & 1;
  11.327 +    unsigned int delivery_mode = (vlapic->icr_low >> 8) & 7;
  11.328 +    unsigned int vector = (vlapic->icr_low & 0xff);
  11.329 +
  11.330 +    struct vlapic *target;
  11.331 +    struct vcpu *v = NULL;
  11.332 +    int result = 0;
  11.333 +    uint32_t lpr_map;
  11.334 +
  11.335 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_ipi: "
  11.336 +                "icr_high %x icr_low %x "
  11.337 +                "short_hand %x dest %x trig_mode %x level %x "
  11.338 +                "dest_mode %x delivery_mode %x vector %x",
  11.339 +                vlapic->icr_high, vlapic->icr_low,
  11.340 +                short_hand, dest, trig_mode, level, dest_mode,
  11.341 +                delivery_mode, vector);
  11.342 +
  11.343 +    for_each_vcpu ( vlapic->domain, v ) {
  11.344 +        target = VLAPIC(v);
  11.345 +        if (vlapic_match_dest(target, vlapic, short_hand,
  11.346 +                              dest, dest_mode, delivery_mode)) {
  11.347 +            if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) {
  11.348 +                set_bit(v->vcpu_id, &lpr_map);
  11.349 +            }else
  11.350 +                result = vlapic_accept_irq(target, delivery_mode,
  11.351 +                  vector, level, trig_mode);
  11.352 +        }
  11.353 +    }
  11.354 +
  11.355 +    if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) {
  11.356 +        extern struct vlapic*
  11.357 +          apic_round_robin(struct domain *d,
  11.358 +            uint8_t dest_mode, uint8_t vector, uint32_t bitmap);
  11.359 +
  11.360 +        v = vlapic->vcpu;
  11.361 +        target = apic_round_robin(v->domain, dest_mode, vector, lpr_map);
  11.362 +
  11.363 +        if (target)
  11.364 +            vlapic_accept_irq(target, delivery_mode,
  11.365 +              vector, level, trig_mode);
  11.366 +    }
  11.367 +}
  11.368 +
  11.369 +void vlapic_begin_timer(struct vlapic *vlapic)
  11.370 +{
  11.371 +    s_time_t cur = NOW(), offset;
  11.372 +
  11.373 +    offset = vlapic->timer_current *
  11.374 +      (262144 / get_apic_bus_scale()) * vlapic->timer_divide_counter;
  11.375 +    vlapic->vlapic_timer.expires = cur + offset;
  11.376 +
  11.377 +    set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires );
  11.378 +
  11.379 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_begin_timer: "
  11.380 +                "bus_scale %x now %08x%08x expire %08x%08x "
  11.381 +                "offset %08x%08x current %x",
  11.382 +                get_apic_bus_scale(), (uint32_t)(cur >> 32), (uint32_t)cur,
  11.383 +                (uint32_t)(vlapic->vlapic_timer.expires >> 32),
  11.384 +                (uint32_t) vlapic->vlapic_timer.expires,
  11.385 +                (uint32_t)(offset >> 32), (uint32_t)offset,
  11.386 +                vlapic->timer_current);
  11.387 +}
  11.388 +
  11.389 +void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset,
  11.390 +                         unsigned int len, unsigned int *result)
  11.391 +{
  11.392 +    if (len != 4) {
  11.393 +        VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
  11.394 +                    "local apic read with len=%d (should be 4)", len);
  11.395 +    }
  11.396 +
  11.397 +    *result = 0;
  11.398 +
  11.399 +    switch (offset) {
  11.400 +    case APIC_ID:
  11.401 +        *result = (vlapic->id) << 24;
  11.402 +        break;
  11.403 +
  11.404 +    case APIC_LVR:
  11.405 +        *result = vlapic->version;
  11.406 +        break;
  11.407 +
  11.408 +    case APIC_TASKPRI:
  11.409 +        *result = vlapic->task_priority;
  11.410 +        break;
  11.411 +
  11.412 +    case APIC_ARBPRI:
  11.413 +        printk("Access local APIC ARBPRI register which is for P6\n");
  11.414 +        break;
  11.415 +
  11.416 +    case APIC_PROCPRI:
  11.417 +        *result = vlapic->processor_priority;
  11.418 +        break;
  11.419 +
  11.420 +    case APIC_EOI:      /* EOI is write only */
  11.421 +        break;
  11.422 +
  11.423 +    case APIC_LDR:
  11.424 +        *result = vlapic->logical_dest;
  11.425 +        break;
  11.426 +
  11.427 +    case APIC_DFR:
  11.428 +        *result = vlapic->dest_format;
  11.429 +        break;
  11.430 +
  11.431 +    case APIC_SPIV:
  11.432 +        *result = vlapic->spurious_vec;
  11.433 +        break;
  11.434 +
  11.435 +    case APIC_ISR:
  11.436 +    case 0x110:
  11.437 +    case 0x120:
  11.438 +    case 0x130:
  11.439 +    case 0x140:
  11.440 +    case 0x150:
  11.441 +    case 0x160:
  11.442 +    case 0x170:
  11.443 +        *result = vlapic->isr[(offset - APIC_ISR) >> 4];
  11.444 +        break;
  11.445 +
  11.446 +    case APIC_TMR:
  11.447 +    case 0x190:
  11.448 +    case 0x1a0:
  11.449 +    case 0x1b0:
  11.450 +    case 0x1c0:
  11.451 +    case 0x1d0:
  11.452 +    case 0x1e0:
  11.453 +    case 0x1f0:
  11.454 +        *result = vlapic->tmr[(offset - APIC_TMR) >> 4];
  11.455 +        break;
  11.456 +
  11.457 +    case APIC_IRR:
  11.458 +    case 0x210:
  11.459 +    case 0x220:
  11.460 +    case 0x230:
  11.461 +    case 0x240:
  11.462 +    case 0x250:
  11.463 +    case 0x260:
  11.464 +    case 0x270:
  11.465 +        *result = vlapic->irr[(offset - APIC_IRR) >> 4];
  11.466 +        break;
  11.467 +
  11.468 +    case APIC_ESR:
  11.469 +        if (vlapic->err_write_count)
  11.470 +            *result = vlapic->err_status;
  11.471 +        break;
  11.472 +
  11.473 +    case APIC_ICR:
  11.474 +        *result = vlapic->icr_low;
  11.475 +        break;
  11.476 +
  11.477 +    case APIC_ICR2:
  11.478 +        *result = vlapic->icr_high;
  11.479 +        break;
  11.480 +
  11.481 +    case APIC_LVTT:     /* LVT Timer Reg */
  11.482 +    case APIC_LVTTHMR:     /* LVT Thermal Monitor */
  11.483 +    case APIC_LVTPC:     /* LVT Performance Counter */
  11.484 +    case APIC_LVT0:     /* LVT LINT0 Reg */
  11.485 +    case APIC_LVT1:     /* LVT Lint1 Reg */
  11.486 +    case APIC_LVTERR:     /* LVT Error Reg */
  11.487 +        *result = vlapic->lvt[(offset - APIC_LVTT) >> 4];
  11.488 +        break;
  11.489 +
  11.490 +    case APIC_TMICT:
  11.491 +        *result = vlapic->timer_initial;
  11.492 +        break;
  11.493 +
  11.494 +    case APIC_TMCCT:         //Timer CCR
  11.495 +        {
  11.496 +            uint32_t counter;
  11.497 +            s_time_t passed, cur = NOW();
  11.498 +
  11.499 +            if (cur <= vlapic->timer_current_update) {
  11.500 +                passed = ~0x0LL - vlapic->timer_current_update + cur;
  11.501 +                VMX_DBG_LOG(DBG_LEVEL_VLAPIC,"time elapsed");
  11.502 +            }else
  11.503 +                passed = cur - vlapic->timer_current_update;
  11.504 +
  11.505 +            counter = (passed * get_apic_bus_scale()) / (262144* vlapic->timer_divide_counter);
  11.506 +            if (vlapic->timer_current > counter)
  11.507 +                *result = vlapic->timer_current - counter;
  11.508 +            else {
  11.509 +                if (!vlapic_lvt_timer_period(vlapic))
  11.510 +                    *result = 0;
  11.511 +                //FIXME should we add interrupt here?
  11.512 +                else
  11.513 +                    //*result = counter % vlapic->timer_initial;
  11.514 +                    *result = vlapic->timer_initial - (counter - vlapic->timer_current);
  11.515 +            }
  11.516 +            vlapic->timer_current = *result;
  11.517 +            vlapic->timer_current_update = NOW();
  11.518 +
  11.519 +            VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
  11.520 +                        "initial %x timer current %x "
  11.521 +                        "update %08x%08x cur %08x%08x offset %d",
  11.522 +                        vlapic->timer_initial, vlapic->timer_current,
  11.523 +                        (uint32_t)(vlapic->timer_current_update >> 32),
  11.524 +                        (uint32_t)vlapic->timer_current_update ,
  11.525 +                        (uint32_t)(cur >> 32), (uint32_t)cur, counter);
  11.526 +        }
  11.527 +        break;
  11.528 +
  11.529 +    case APIC_TDCR:
  11.530 +        *result = vlapic->timer_divconf;
  11.531 +        break;
  11.532 +
  11.533 +    default:
  11.534 +        printk("Read local APIC address %x not implemented\n",offset);
  11.535 +        *result = 0;
  11.536 +        break;
  11.537 +    }
  11.538 +}
  11.539 +
  11.540 +unsigned long vlapic_read(struct vcpu *v, unsigned long address,
  11.541 +            unsigned long len)
  11.542 +{
  11.543 +    unsigned int alignment;
  11.544 +    unsigned int tmp;
  11.545 +    unsigned long result;
  11.546 +    struct vlapic *vlapic = VLAPIC(v);
  11.547 +    unsigned int offset = address - vlapic->base_address;
  11.548 +
  11.549 +    if ( len != 4) {
  11.550 +        /* some bugs on kernel cause read this with byte*/
  11.551 +        printk("Local APIC read with len = %lx, should be 4 instead\n", len);
  11.552 +    }
  11.553 +
  11.554 +    alignment = offset & 0x3;
  11.555 +
  11.556 +    vlapic_read_aligned(vlapic, offset & ~0x3, 4, &tmp);
  11.557 +    switch (len) {
  11.558 +    case 1:
  11.559 +        result = *((unsigned char *)&tmp + alignment);
  11.560 +        break;
  11.561 +
  11.562 +    case 2:
  11.563 +        result = *(unsigned short *)((unsigned char *)&tmp + alignment);
  11.564 +        break;
  11.565 +
  11.566 +    case 4:
  11.567 +        result = *(unsigned int *)((unsigned char *)&tmp + alignment);
  11.568 +        break;
  11.569 +
  11.570 +    default:
  11.571 +        printk("Local APIC read with len = %lx, should be 4 instead\n", len);
  11.572 +        domain_crash_synchronous();
  11.573 +        break;
  11.574 +    }
  11.575 +
  11.576 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
  11.577 +                "vlapic_read offset %x with length %lx and the result is %lx",
  11.578 +                offset, len, result);
  11.579 +    return result;
  11.580 +}
  11.581 +
  11.582 +unsigned long vlapic_write(struct vcpu *v, unsigned long address,
  11.583 +                  unsigned long len, unsigned long val)
  11.584 +{
  11.585 +    struct vlapic *vlapic = VLAPIC(v);
  11.586 +    unsigned int offset = address - vlapic->base_address;
  11.587 +
  11.588 +    if (offset != 0xb0)
  11.589 +        VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
  11.590 +          "vlapic_write offset %x with length %lx source %lx",
  11.591 +          offset, len, val);
  11.592 +
  11.593 +    /*
  11.594 +     * According to IA 32 Manual, all resgiters should be accessed with
  11.595 +     * 32 bits alignment.
  11.596 +     */
  11.597 +    if (len != 4) {
  11.598 +        unsigned int tmp;
  11.599 +        unsigned char alignment;
  11.600 +
  11.601 +        /* Some kernel do will access with byte/word alignment*/
  11.602 +        printk("Notice: Local APIC write with len = %lx\n",len);
  11.603 +        alignment = offset & 0x3;
  11.604 +        tmp = vlapic_read(v, offset & (~0x3), 4);
  11.605 +        switch (len) {
  11.606 +        case 1:
  11.607 +            /* XXX the saddr is a tmp variable from caller, so should be ok
  11.608 +               But we should still change the following ref to val to 
  11.609 +               local variable later */
  11.610 +            val  = (tmp & ~(0xff << alignment)) |
  11.611 +                        ((val & 0xff) << alignment);
  11.612 +            break;
  11.613 +
  11.614 +        case 2:
  11.615 +            if (alignment != 0x0 && alignment != 0x2) {
  11.616 +                printk("alignment error for vlapic with len == 2\n");
  11.617 +                    domain_crash_synchronous();
  11.618 +            }
  11.619 +
  11.620 +            val = (tmp & ~(0xffff << alignment)) |
  11.621 +                        ((val & 0xffff)  << alignment);
  11.622 +            break;
  11.623 +
  11.624 +        case 3:
  11.625 +            /* will it happen? */
  11.626 +            printk("vlapic_write with len = 3 !!!\n");
  11.627 +            domain_crash_synchronous();
  11.628 +            break;
  11.629 +
  11.630 +        default:
  11.631 +            printk("Local APIC write with len = %lx, should be 4 instead\n", len);
  11.632 +            domain_crash_synchronous();
  11.633 +            break;
  11.634 +        }
  11.635 +    }
  11.636 +
  11.637 +    offset &= 0xff0;
  11.638 +
  11.639 +    switch (offset) {
  11.640 +    case APIC_ID:   /* Local APIC ID */
  11.641 +        vlapic->id = ((val) >> 24) & VAPIC_ID_MASK;
  11.642 +        break;
  11.643 +
  11.644 +    case APIC_TASKPRI:
  11.645 +        vlapic->task_priority = val & 0xff;
  11.646 +        vlapic_update_ppr(vlapic);
  11.647 +        break;
  11.648 +
  11.649 +    case APIC_EOI:
  11.650 +        vlapic_EOI_set(vlapic);
  11.651 +        break;
  11.652 +
  11.653 +    case APIC_LDR:
  11.654 +        vlapic->logical_dest = val & VAPIC_LDR_MASK;
  11.655 +        break;
  11.656 +
  11.657 +    case APIC_DFR:
  11.658 +        vlapic->dest_format = val ;
  11.659 +        break;
  11.660 +
  11.661 +    case APIC_SPIV:
  11.662 +        vlapic->spurious_vec = val & 0x1ff;
  11.663 +        if (!(vlapic->spurious_vec & 0x100)) {
  11.664 +            int i = 0;
  11.665 +            for (i=0; i < VLAPIC_LVT_NUM; i++) 
  11.666 +                vlapic->lvt[i] |= 0x10000;
  11.667 +            vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK;
  11.668 +        }
  11.669 +        else
  11.670 +            vlapic->status &= ~VLAPIC_SOFTWARE_DISABLE_MASK;
  11.671 +        break;
  11.672 +
  11.673 +    case APIC_ESR:
  11.674 +        vlapic->err_write_count = !vlapic->err_write_count;
  11.675 +        if (!vlapic->err_write_count)
  11.676 +            vlapic->err_status = 0;
  11.677 +        break;
  11.678 +
  11.679 +    case APIC_ICR:
  11.680 +        /* No delay here, so we always clear the pending bit*/
  11.681 +        vlapic->icr_low = val & ~(1 << 12);
  11.682 +        vlapic_ipi(vlapic);
  11.683 +        break;
  11.684 +
  11.685 +    case APIC_ICR2:
  11.686 +        vlapic->icr_high = val & 0xff000000;
  11.687 +        break;
  11.688 +
  11.689 +    case APIC_LVTT: // LVT Timer Reg
  11.690 +    case APIC_LVTTHMR: // LVT Thermal Monitor
  11.691 +    case APIC_LVTPC: // LVT Performance Counter
  11.692 +    case APIC_LVT0: // LVT LINT0 Reg
  11.693 +    case APIC_LVT1: // LVT Lint1 Reg
  11.694 +    case APIC_LVTERR: // LVT Error Reg
  11.695 +        {
  11.696 +            int vt = (offset - APIC_LVTT) >> 4;
  11.697 +
  11.698 +            vlapic->lvt[vt] = val & vlapic_lvt_mask[vt];
  11.699 +            if (vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK)
  11.700 +                vlapic->lvt[vt] |= VLAPIC_LVT_BIT_MASK;
  11.701 +
  11.702 +            /* On hardware, when write vector less than 0x20 will error */
  11.703 +            vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic->lvt[vt]),
  11.704 +              vlapic_lvt_vector(vlapic, vt));
  11.705 +
  11.706 +            if (!vlapic->vcpu_id && (offset == APIC_LVT0)) {
  11.707 +                if ((vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_DELIMOD)
  11.708 +                            == 0x700) {
  11.709 +                    if (!(vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_MASK)) {
  11.710 +                        set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
  11.711 +                    }else
  11.712 +                        clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
  11.713 +                }
  11.714 +                else
  11.715 +                    clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
  11.716 +            }
  11.717 +
  11.718 +        }
  11.719 +        break;
  11.720 +
  11.721 +    case APIC_TMICT:
  11.722 +        if (vlapic_timer_active(vlapic))
  11.723 +            rem_ac_timer(&(vlapic->vlapic_timer));
  11.724 +
  11.725 +        vlapic->timer_initial = val;
  11.726 +        vlapic->timer_current = val;
  11.727 +        vlapic->timer_current_update = NOW();
  11.728 +
  11.729 +        VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
  11.730 +          "timer_init %x timer_current %x timer_current_update %08x%08x",
  11.731 +          vlapic->timer_initial, vlapic->timer_current, (uint32_t)(vlapic->timer_current_update>>32), (uint32_t)vlapic->timer_current_update);
  11.732 +        vlapic_begin_timer(vlapic);
  11.733 +        break;
  11.734 +
  11.735 +    case APIC_TDCR:
  11.736 +        {
  11.737 +            //FIXME clean this code
  11.738 +            unsigned char tmp1,tmp2;
  11.739 +            tmp1 = (val & 0xf);
  11.740 +            tmp2 = ((tmp1 & 0x3 )|((tmp1 & 0x8) >>1)) + 1;
  11.741 +            vlapic->timer_divide_counter = 0x1<<tmp2;
  11.742 +
  11.743 +            VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
  11.744 +                        "timer divider is 0x%x",
  11.745 +                        vlapic->timer_divide_counter);
  11.746 +        }
  11.747 +        break;
  11.748 +
  11.749 +    default:
  11.750 +        printk("Local APIC Write to read-only register\n");
  11.751 +        break;
  11.752 +    }
  11.753 +    return 1;
  11.754 +}
  11.755 +
  11.756 +int vlapic_range(struct vcpu *v, unsigned long addr)
  11.757 +{
  11.758 +    struct vlapic *vlapic = VLAPIC(v);
  11.759 +
  11.760 +    if (vlapic_global_enabled(vlapic) &&
  11.761 +        (addr >= vlapic->base_address) &&
  11.762 +        (addr <= (vlapic->base_address + VLOCAL_APIC_MEM_LENGTH)))
  11.763 +        return 1;
  11.764 +
  11.765 +    return 0;
  11.766 +}
  11.767 +
  11.768 +void vlapic_msr_set(struct vlapic *vlapic, uint64_t value)
  11.769 +{
  11.770 +    /* When apic disabled */
  11.771 +    if (!vlapic)
  11.772 +        return;
  11.773 +
  11.774 +    if (vlapic->vcpu_id)
  11.775 +        value &= ~MSR_IA32_APICBASE_BSP;
  11.776 +
  11.777 +    vlapic->apic_base_msr = value;
  11.778 +    vlapic->base_address = vlapic_get_base_address(vlapic);
  11.779 +
  11.780 +    if (!(value & 0x800))
  11.781 +        set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status );
  11.782 +
  11.783 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
  11.784 +                "apic base msr = 0x%08x%08x,\nbase address = 0x%lx",
  11.785 +                (uint32_t)(vlapic->apic_base_msr >> 32),
  11.786 +                (uint32_t)vlapic->apic_base_msr,
  11.787 +                vlapic->base_address);
  11.788 +}
  11.789 +
  11.790 +static inline int vlapic_get_init_id(struct vcpu *v)
  11.791 +{
  11.792 +    return v->vcpu_id;
  11.793 +}
  11.794 +
  11.795 +void vlapic_timer_fn(void *data)
  11.796 +{
  11.797 +    struct vlapic *vlapic;
  11.798 +
  11.799 +    vlapic = data;
  11.800 +    if (!vlapic_enabled(vlapic)) return;
  11.801 +
  11.802 +    vlapic->timer_current_update = NOW();
  11.803 +
  11.804 +    if (vlapic_lvt_timer_enabled(vlapic)) {
  11.805 +        if (!vlapic_irr_status(vlapic,
  11.806 +              vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER))) {
  11.807 +            test_and_set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER),
  11.808 +              &vlapic->irr[0]);
  11.809 +        }
  11.810 +        else
  11.811 +            vlapic->intr_pending_count[vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)]++;
  11.812 +    }
  11.813 +
  11.814 +    vlapic->timer_current_update = NOW();
  11.815 +    if (vlapic_lvt_timer_period(vlapic)) {
  11.816 +        s_time_t offset;
  11.817 +
  11.818 +        vlapic->timer_current = vlapic->timer_initial;
  11.819 +        offset = vlapic->timer_current * (262144/get_apic_bus_scale()) * vlapic->timer_divide_counter;
  11.820 +        vlapic->vlapic_timer.expires = NOW() + offset;
  11.821 +        set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires);
  11.822 +    }else {
  11.823 +        vlapic->timer_current = 0;
  11.824 +    }
  11.825 +
  11.826 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
  11.827 +      "vlapic_timer_fn: now: %08x%08x expire %08x%08x init %x current %x",
  11.828 +      (uint32_t)(NOW() >> 32),(uint32_t)NOW(),
  11.829 +      (uint32_t)(vlapic->vlapic_timer.expires >> 32),
  11.830 +      (uint32_t)vlapic->vlapic_timer.expires,
  11.831 +      vlapic->timer_initial,vlapic->timer_current);
  11.832 +}
  11.833 +
  11.834 +#if 0
  11.835 +static int
  11.836 +vlapic_check_direct_intr(struct vcpu *v, int * mode)
  11.837 +{
  11.838 +    struct vlapic *vlapic = VLAPIC(v);
  11.839 +    int type;
  11.840 +
  11.841 +    type = __fls(vlapic->direct_intr.deliver_mode);
  11.842 +    if (type == -1)
  11.843 +        return -1;
  11.844 +
  11.845 +    *mode = type;
  11.846 +    return 0;
  11.847 +}
  11.848 +#endif
  11.849 +
  11.850 +int
  11.851 +vlapic_accept_pic_intr(struct vcpu *v)
  11.852 +{
  11.853 +    struct vlapic *vlapic = VLAPIC(v);
  11.854 +
  11.855 +    return vlapic ? test_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status) : 1;
  11.856 +}
  11.857 +
  11.858 +int cpu_get_apic_interrupt(struct vcpu* v, int *mode)
  11.859 +{
  11.860 +    struct vlapic *vlapic = VLAPIC(v);
  11.861 +
  11.862 +    if (vlapic && vlapic_enabled(vlapic)) {
  11.863 +        int highest_irr = vlapic_find_highest_irr(vlapic);
  11.864 +
  11.865 +        if (highest_irr != -1 && highest_irr >= vlapic->processor_priority) {
  11.866 +            if (highest_irr < 0x10) {
  11.867 +                vlapic->err_status |= 0x20;
  11.868 +                /* XXX What will happen if this vector illegal stil */
  11.869 +                VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
  11.870 +                  "vmx_intr_assist: illegal vector number %x err_status %x",
  11.871 +                  highest_irr,  vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR));
  11.872 +
  11.873 +                set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), &vlapic->irr[0]);
  11.874 +                highest_irr = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR);
  11.875 +            }
  11.876 +
  11.877 +            *mode = VLAPIC_DELIV_MODE_FIXED;
  11.878 +            return highest_irr;
  11.879 +        }
  11.880 +    }
  11.881 +    return -1;
  11.882 +}
  11.883 +
  11.884 +void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode) {
  11.885 +    struct vlapic  *vlapic = VLAPIC(v);
  11.886 +
  11.887 +    if (!vlapic)
  11.888 +        return;
  11.889 +
  11.890 +    switch (deliver_mode) {
  11.891 +    case VLAPIC_DELIV_MODE_FIXED:
  11.892 +    case VLAPIC_DELIV_MODE_LPRI:
  11.893 +        vlapic_set_isr(vlapic, vector);
  11.894 +        vlapic_clear_irr(vlapic, vector);
  11.895 +        vlapic_update_ppr(vlapic);
  11.896 +
  11.897 +        if (vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)) {
  11.898 +            vlapic->intr_pending_count[vector]--;
  11.899 +            if (vlapic->intr_pending_count[vector] > 0)
  11.900 +                test_and_set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER),
  11.901 +                  &vlapic->irr[0]);
  11.902 +        }
  11.903 +
  11.904 +        break;
  11.905 +        /*XXX deal with these later */
  11.906 +
  11.907 +    case VLAPIC_DELIV_MODE_RESERVED:
  11.908 +        printk("Ignore deliver mode 3 in vlapic_post_injection\n");
  11.909 +        break;
  11.910 +
  11.911 +    case VLAPIC_DELIV_MODE_SMI:
  11.912 +    case VLAPIC_DELIV_MODE_NMI:
  11.913 +    case VLAPIC_DELIV_MODE_INIT:
  11.914 +    case VLAPIC_DELIV_MODE_STARTUP:
  11.915 +        vlapic->direct_intr.deliver_mode &= ~(1 << deliver_mode);
  11.916 +        break;
  11.917 +
  11.918 +    default:
  11.919 +        printk("<vlapic_post_injection> error deliver mode\n");
  11.920 +        break;
  11.921 +    }
  11.922 +}
  11.923 +
  11.924 +static int vlapic_reset(struct vlapic *vlapic)
  11.925 +{
  11.926 +    struct vcpu *v = vlapic->vcpu;
  11.927 +    int apic_id = v->vcpu_id, i;
  11.928 +
  11.929 +    if (!v || !vlapic)
  11.930 +        return 0;
  11.931 +
  11.932 +    memset(vlapic, 0,sizeof(struct vlapic));
  11.933 +
  11.934 +    v->arch.arch_vmx.vlapic = vlapic;
  11.935 +
  11.936 +    vlapic->domain = v->domain;
  11.937 +
  11.938 +    vlapic->id = apic_id;
  11.939 +
  11.940 +    vlapic->version = VLAPIC_VERSION;
  11.941 +
  11.942 +    vlapic->apic_base_msr = VLAPIC_BASE_MSR_INIT_VALUE;
  11.943 +
  11.944 +    if (apic_id == 0)
  11.945 +        vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP;
  11.946 +    vlapic->base_address = vlapic_get_base_address(vlapic);
  11.947 +
  11.948 +    for (i = 0; i < VLAPIC_LVT_NUM; i++)
  11.949 +        vlapic->lvt[i] = VLAPIC_LVT_BIT_MASK;
  11.950 +
  11.951 +    vlapic->dest_format = 0xffffffffU;
  11.952 +
  11.953 +    vlapic->spurious_vec = 0xff;
  11.954 +
  11.955 +
  11.956 +    init_ac_timer(&vlapic->vlapic_timer,
  11.957 +      vlapic_timer_fn, vlapic, v->processor);
  11.958 +
  11.959 +#ifdef VLAPIC_NO_BIOS
  11.960 +    /*
  11.961 +     * XXX According to mp sepcific, BIOS will enable LVT0/1,
  11.962 +     * remove it after BIOS enabled
  11.963 +     */
  11.964 +    if (!v->vcpu_id) {
  11.965 +        vlapic->lvt[VLAPIC_LVT_LINT0] = 0x700;
  11.966 +        vlapic->lvt[VLAPIC_LVT_LINT1] = 0x500;
  11.967 +        set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
  11.968 +    }
  11.969 +#endif
  11.970 +
  11.971 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_reset: "
  11.972 +      "vcpu=%p id=%d vlapic_apic_base_msr=%08x%08x "
  11.973 +      "vlapic_base_address=%0lx",
  11.974 +      v, vlapic->id, (uint32_t)(vlapic->apic_base_msr >> 32),
  11.975 +      (uint32_t)vlapic->apic_base_msr, vlapic->base_address);
  11.976 +
  11.977 +    return 1;
  11.978 +}
  11.979 +
  11.980 +int vlapic_init(struct vcpu *v)
  11.981 +{
  11.982 +    struct vlapic *vlapic = NULL;
  11.983 +
  11.984 +    VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_init %d", v->vcpu_id);
  11.985 +
  11.986 +    vlapic = xmalloc_bytes(sizeof(struct vlapic));
  11.987 +
  11.988 +    if (!vlapic) {
  11.989 +        printk("malloc vlapic error for vcpu %x\n", v->vcpu_id);
  11.990 +        return -ENOMEM;
  11.991 +    }
  11.992 +
  11.993 +    vlapic->vcpu = v;
  11.994 +
  11.995 +    vlapic_reset(vlapic);
  11.996 +
  11.997 +    return 0;
  11.998 +}
  11.999 +
 11.1000 +#endif  /* CONFIG_VMX */
    12.1 --- a/xen/arch/x86/vmx_vmcs.c	Thu Oct 27 18:22:45 2005 +0100
    12.2 +++ b/xen/arch/x86/vmx_vmcs.c	Fri Oct 28 09:48:46 2005 +0100
    12.3 @@ -252,6 +252,10 @@ static void vmx_setup_platform(struct do
    12.4      pic_init(&platform->vmx_pic,  pic_irq_request, 
    12.5               &platform->interrupt_request);
    12.6      register_pic_io_hook();
    12.7 +
    12.8 +    if ( vmx_apic_support(d) ) {
    12.9 +        spin_lock_init(&d->arch.vmx_platform.round_robin_lock);
   12.10 +    }
   12.11  }
   12.12  
   12.13  static void vmx_set_host_env(struct vcpu *v)
   12.14 @@ -313,6 +317,9 @@ static void vmx_do_launch(struct vcpu *v
   12.15  
   12.16      vmx_stts();
   12.17  
   12.18 +    if(vmx_apic_support(v->domain))
   12.19 +        vlapic_init(v);
   12.20 +
   12.21      vmx_set_host_env(v);
   12.22  
   12.23      error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
    13.1 --- a/xen/include/asm-x86/vmx_intercept.h	Thu Oct 27 18:22:45 2005 +0100
    13.2 +++ b/xen/include/asm-x86/vmx_intercept.h	Fri Oct 28 09:48:46 2005 +0100
    13.3 @@ -14,6 +14,16 @@
    13.4  #define VMX_MMIO                    1
    13.5  
    13.6  typedef int (*intercept_action_t)(ioreq_t *);
    13.7 +typedef unsigned long (*vmx_mmio_read_t)(struct vcpu *v,
    13.8 +                                         unsigned long addr,
    13.9 +                                         unsigned long length);
   13.10 +
   13.11 +typedef unsigned long (*vmx_mmio_write_t)(struct vcpu *v,
   13.12 +                                         unsigned long addr,
   13.13 +                                         unsigned long length,
   13.14 +                                         unsigned long val);
   13.15 +
   13.16 +typedef int (*vmx_mmio_check_t)(struct vcpu *v, unsigned long addr);
   13.17  
   13.18  struct io_handler {
   13.19      int                 type;
   13.20 @@ -27,6 +37,16 @@ struct vmx_io_handler {
   13.21      struct  io_handler hdl_list[MAX_IO_HANDLER];
   13.22  };
   13.23  
   13.24 +struct vmx_mmio_handler {
   13.25 +    vmx_mmio_check_t check_handler;
   13.26 +    vmx_mmio_read_t read_handler;
   13.27 +    vmx_mmio_write_t write_handler;
   13.28 +};
   13.29 +
   13.30 +#define VMX_MMIO_HANDLER_NR 1
   13.31 +
   13.32 +extern struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR];
   13.33 +
   13.34  /* global io interception point in HV */
   13.35  extern int vmx_io_intercept(ioreq_t *p, int type);
   13.36  extern int register_io_handler(unsigned long addr, unsigned long size,
   13.37 @@ -37,10 +57,7 @@ static inline int vmx_portio_intercept(i
   13.38      return vmx_io_intercept(p, VMX_PORTIO);
   13.39  }
   13.40  
   13.41 -static inline int vmx_mmio_intercept(ioreq_t *p)
   13.42 -{
   13.43 -    return vmx_io_intercept(p, VMX_MMIO);
   13.44 -}
   13.45 +int vmx_mmio_intercept(ioreq_t *p);
   13.46  
   13.47  static inline int register_portio_handler(unsigned long addr,
   13.48                                            unsigned long size,
   13.49 @@ -49,11 +66,4 @@ static inline int register_portio_handle
   13.50      return register_io_handler(addr, size, action, VMX_PORTIO);
   13.51  }
   13.52  
   13.53 -static inline int register_mmio_handler(unsigned long addr,
   13.54 -                                        unsigned long size,
   13.55 -                                        intercept_action_t action)
   13.56 -{
   13.57 -    return register_io_handler(addr, size, action, VMX_MMIO);
   13.58 -}
   13.59 -
   13.60  #endif /* _VMX_INTERCEPT_H */
    14.1 --- a/xen/include/asm-x86/vmx_platform.h	Thu Oct 27 18:22:45 2005 +0100
    14.2 +++ b/xen/include/asm-x86/vmx_platform.h	Fri Oct 28 09:48:46 2005 +0100
    14.3 @@ -80,10 +80,13 @@ struct instruction {
    14.4  struct vmx_platform {
    14.5      unsigned long          shared_page_va;
    14.6      unsigned int           nr_vcpu;
    14.7 +    unsigned int           lapic_enable;
    14.8  
    14.9      struct vmx_virpit      vmx_pit;
   14.10      struct vmx_io_handler  vmx_io_handler;
   14.11      struct vmx_virpic      vmx_pic;
   14.12 +    unsigned char          round_info[256];
   14.13 +    spinlock_t             round_robin_lock;
   14.14      int                    interrupt_request;
   14.15  };
   14.16  
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/xen/include/asm-x86/vmx_vlapic.h	Fri Oct 28 09:48:46 2005 +0100
    15.3 @@ -0,0 +1,245 @@
    15.4 +/*
    15.5 + * vmx_vlapic.h: virtualize LAPIC definitions.
    15.6 + * Copyright (c) 2004, Intel Corporation.
    15.7 + *
    15.8 + * This program is free software; you can redistribute it and/or modify it
    15.9 + * under the terms and conditions of the GNU General Public License,
   15.10 + * version 2, as published by the Free Software Foundation.
   15.11 + *
   15.12 + * This program is distributed in the hope it will be useful, but WITHOUT
   15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   15.15 + * more details.
   15.16 + *
   15.17 + * You should have received a copy of the GNU General Public License along with
   15.18 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   15.19 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   15.20 + *
   15.21 + */
   15.22 +
   15.23 +#ifndef VMX_VLAPIC_H
   15.24 +#define VMX_VLAPIC_H
   15.25 +
   15.26 +#include <asm/msr.h>
   15.27 +#include <public/io/ioreq.h>
   15.28 +
   15.29 +#if defined(__i386__) || defined(__x86_64__)
   15.30 +static inline int __fls(uint32_t word)
   15.31 +{
   15.32 +    int bit;
   15.33 +
   15.34 +    __asm__("bsrl %1,%0"
   15.35 +      :"=r" (bit)
   15.36 +      :"rm" (word));
   15.37 +    return word ? bit : -1;
   15.38 +}
   15.39 +#else
   15.40 +#define __fls(x)    generic_fls(x)
   15.41 +static __inline__ int generic_fls(uint32_t x)
   15.42 +{
   15.43 +    int r = 31;
   15.44 +
   15.45 +    if (!x)
   15.46 +        return -1;
   15.47 +    if (!(x & 0xffff0000u)) {
   15.48 +        x <<= 16;
   15.49 +        r -= 16;
   15.50 +    }
   15.51 +    if (!(x & 0xff000000u)) {
   15.52 +        x <<= 8;
   15.53 +        r -= 8;
   15.54 +    }
   15.55 +    if (!(x & 0xf0000000u)) {
   15.56 +        x <<= 4;
   15.57 +        r -= 4;
   15.58 +    }
   15.59 +    if (!(x & 0xc0000000u)) {
   15.60 +        x <<= 2;
   15.61 +        r -= 2;
   15.62 +    }
   15.63 +    if (!(x & 0x80000000u)) {
   15.64 +        x <<= 1;
   15.65 +        r -= 1;
   15.66 +    }
   15.67 +    return r;
   15.68 +}
   15.69 +#endif
   15.70 +
   15.71 +static __inline__ int find_highest_bit(uint32_t *data, int length)
   15.72 +{
   15.73 +    while(length && !data[--length]);
   15.74 +    return __fls(data[length]) +  32 * length;
   15.75 +}
   15.76 +
   15.77 +#define VLAPIC(v)                       (v->arch.arch_vmx.vlapic)
   15.78 +
   15.79 +#define VAPIC_ID_MASK                   0xff
   15.80 +#define VAPIC_LDR_MASK                  (VAPIC_ID_MASK << 24)
   15.81 +#define VLAPIC_VERSION                  0x00050014
   15.82 +
   15.83 +#define VLAPIC_BASE_MSR_MASK            0x00000000fffff900ULL
   15.84 +#define VLAPIC_BASE_MSR_INIT_BASE_ADDR  0xfee00000U
   15.85 +#define VLAPIC_BASE_MSR_BASE_ADDR_MASK  0xfffff000U
   15.86 +#define VLAPIC_BASE_MSR_INIT_VALUE      (VLAPIC_BASE_MSR_INIT_BASE_ADDR | \
   15.87 +                                         MSR_IA32_APICBASE_ENABLE)
   15.88 +#define VLOCAL_APIC_MEM_LENGTH          (1 << 12)
   15.89 +
   15.90 +#define VLAPIC_LVT_TIMER                0
   15.91 +#define VLAPIC_LVT_THERMAL              1
   15.92 +#define VLAPIC_LVT_PERFORM              2
   15.93 +#define VLAPIC_LVT_LINT0                3
   15.94 +#define VLAPIC_LVT_LINT1                4
   15.95 +#define VLAPIC_LVT_ERROR                5
   15.96 +#define VLAPIC_LVT_NUM                  6
   15.97 +
   15.98 +#define VLAPIC_LVT_BIT_MASK             (1 << 16)
   15.99 +#define VLAPIC_LVT_BIT_VECTOR           0xff
  15.100 +#define VLAPIC_LVT_BIT_DELIMOD          (0x7 << 8)
  15.101 +#define VLAPIC_LVT_BIT_DELISTATUS       (1 << 12)
  15.102 +#define VLAPIC_LVT_BIT_POLARITY         (1 << 13)
  15.103 +#define VLAPIC_LVT_BIT_IRR              (1 << 14)
  15.104 +#define VLAPIC_LVT_BIT_TRIG             (1 << 15)
  15.105 +#define VLAPIC_LVT_TIMERMODE            (1 << 17)
  15.106 +
  15.107 +#define VLAPIC_DELIV_MODE_FIXED          0x0
  15.108 +#define VLAPIC_DELIV_MODE_LPRI           0x1
  15.109 +#define VLAPIC_DELIV_MODE_SMI            0x2
  15.110 +#define VLAPIC_DELIV_MODE_RESERVED       0x3
  15.111 +#define VLAPIC_DELIV_MODE_NMI            0x4
  15.112 +#define VLAPIC_DELIV_MODE_INIT           0x5
  15.113 +#define VLAPIC_DELIV_MODE_STARTUP        0x6
  15.114 +#define VLAPIC_DELIV_MODE_EXT            0x7
  15.115 +
  15.116 +
  15.117 +
  15.118 +#define VLAPIC_NO_SHORTHAND             0x0
  15.119 +#define VLAPIC_SHORTHAND_SELF           0x1
  15.120 +#define VLAPIC_SHORTHAND_INCLUDE_SELF   0x2
  15.121 +#define VLAPIC_SHORTHAND_EXCLUDE_SELF   0x3
  15.122 +
  15.123 +#define vlapic_lvt_timer_enabled(vlapic)    \
  15.124 +  (!(vlapic->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_MASK))
  15.125 +
  15.126 +#define vlapic_lvt_vector(vlapic, type)   \
  15.127 +  (vlapic->lvt[type] & VLAPIC_LVT_BIT_VECTOR)
  15.128 +
  15.129 +#define vlapic_lvt_dm(value)        ((value >> 8) && 7)
  15.130 +#define vlapic_lvt_timer_period(vlapic) \
  15.131 +  (vlapic->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_TIMERMODE)
  15.132 +
  15.133 +#define vlapic_isr_status(vlapic,vector)    \
  15.134 +  test_bit(vector, &vlapic->isr[0])
  15.135 +
  15.136 +#define vlapic_irr_status(vlapic,vector)    \
  15.137 +  test_bit(vector, &vlapic->irr[0])
  15.138 +
  15.139 +#define vlapic_set_isr(vlapic,vector) \
  15.140 +  test_and_set_bit(vector, &vlapic->isr[0])
  15.141 +
  15.142 +#define vlapic_set_irr(vlapic,vector)      \
  15.143 +  test_and_set_bit(vector, &vlapic->irr[0])
  15.144 +
  15.145 +#define vlapic_clear_irr(vlapic,vector)      \
  15.146 +  clear_bit(vector, &vlapic->irr[0])
  15.147 +#define vlapic_clear_isr(vlapic,vector)     \
  15.148 +  clear_bit(vector, &vlapic->isr[0])
  15.149 +
  15.150 +#define vlapic_enabled(vlapic)               \
  15.151 +  (!(vlapic->status &                           \
  15.152 +     (VLAPIC_GLOB_DISABLE_MASK | VLAPIC_SOFTWARE_DISABLE_MASK)))
  15.153 +
  15.154 +#define vlapic_global_enabled(vlapic)               \
  15.155 +  !(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status))
  15.156 +
  15.157 +typedef struct direct_intr_info {
  15.158 +    int deliver_mode;
  15.159 +    int source[6];
  15.160 +} direct_intr_info_t;
  15.161 +
  15.162 +#define VLAPIC_INIT_SIPI_SIPI_STATE_NORM          0
  15.163 +#define VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI     1
  15.164 +
  15.165 +struct vlapic
  15.166 +{
  15.167 +    //FIXME check what would be 64 bit on EM64T
  15.168 +    uint32_t           version;
  15.169 +#define _VLAPIC_GLOB_DISABLE            0x0
  15.170 +#define VLAPIC_GLOB_DISABLE_MASK        0x1
  15.171 +#define VLAPIC_SOFTWARE_DISABLE_MASK    0x2
  15.172 +#define _VLAPIC_BSP_ACCEPT_PIC          0x3
  15.173 +    uint32_t           status;
  15.174 +    uint32_t           id;
  15.175 +    uint32_t           vcpu_id;
  15.176 +    unsigned long      base_address;
  15.177 +    uint32_t           isr[8];
  15.178 +    uint32_t           irr[INTR_LEN_32];
  15.179 +    uint32_t           tmr[INTR_LEN_32];
  15.180 +    uint32_t           task_priority;
  15.181 +    uint32_t           processor_priority;
  15.182 +    uint32_t           logical_dest;
  15.183 +    uint32_t           dest_format;
  15.184 +    uint32_t           spurious_vec;
  15.185 +    uint32_t           lvt[6];
  15.186 +    uint32_t           timer_initial;
  15.187 +    uint32_t           timer_current;
  15.188 +    uint32_t           timer_divconf;
  15.189 +    uint32_t           timer_divide_counter;
  15.190 +    struct ac_timer    vlapic_timer;
  15.191 +    int                intr_pending_count[MAX_VECTOR];
  15.192 +    s_time_t           timer_current_update;
  15.193 +    uint32_t           icr_high;
  15.194 +    uint32_t           icr_low;
  15.195 +    direct_intr_info_t direct_intr;
  15.196 +    uint32_t           err_status;
  15.197 +    unsigned long      init_ticks;
  15.198 +    uint32_t           err_write_count;
  15.199 +    uint64_t           apic_base_msr;
  15.200 +    uint32_t           init_sipi_sipi_state;
  15.201 +    struct vcpu        *vcpu;
  15.202 +    struct domain      *domain;
  15.203 +};
  15.204 +
  15.205 +static inline int  vlapic_timer_active(struct vlapic *vlapic)
  15.206 +{
  15.207 +    return  active_ac_timer(&(vlapic->vlapic_timer));
  15.208 +}
  15.209 +
  15.210 +int vlapic_find_highest_irr(struct vlapic *vlapic);
  15.211 +
  15.212 +int vlapic_find_highest_isr(struct vlapic *vlapic);
  15.213 +
  15.214 +static uint32_t inline vlapic_get_base_address(struct vlapic *vlapic)
  15.215 +{
  15.216 +    return (vlapic->apic_base_msr & VLAPIC_BASE_MSR_BASE_ADDR_MASK);
  15.217 +}
  15.218 +
  15.219 +void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode);
  15.220 +
  15.221 +int cpu_get_apic_interrupt(struct vcpu* v, int *mode);
  15.222 +
  15.223 +extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
  15.224 +
  15.225 +int vlapic_update(struct vcpu *v);
  15.226 +
  15.227 +extern int vlapic_init(struct vcpu *vc);
  15.228 +
  15.229 +extern void vlapic_msr_set(struct vlapic *vlapic, uint64_t value);
  15.230 +
  15.231 +int vlapic_range(struct vcpu *v, unsigned long addr);
  15.232 +
  15.233 +unsigned long vlapic_write(struct vcpu *v, unsigned long address,
  15.234 +                           unsigned long len, unsigned long val);
  15.235 +
  15.236 +unsigned long vlapic_read(struct vcpu *v, unsigned long address,
  15.237 +                          unsigned long len);
  15.238 +
  15.239 +int vlapic_accept_pic_intr(struct vcpu *v);
  15.240 +
  15.241 +struct vlapic* apic_round_robin(struct domain *d,
  15.242 +                                uint8_t dest_mode,
  15.243 +                                uint8_t vector,
  15.244 +                                uint32_t bitmap);
  15.245 +
  15.246 +int vmx_apic_support(struct domain *d);
  15.247 +
  15.248 +#endif /* VMX_VLAPIC_H */
    16.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Thu Oct 27 18:22:45 2005 +0100
    16.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Fri Oct 28 09:48:46 2005 +0100
    16.3 @@ -22,6 +22,7 @@
    16.4  #include <asm/config.h>
    16.5  #include <asm/vmx_cpu.h>
    16.6  #include <asm/vmx_platform.h>
    16.7 +#include <asm/vmx_vlapic.h>
    16.8  #include <public/vmx_assist.h>
    16.9  
   16.10  extern int start_vmx(void);
   16.11 @@ -96,6 +97,7 @@ struct arch_vmx_struct {
   16.12      struct msr_state        msr_content;
   16.13      struct mmio_op          mmio_op;  /* MMIO */
   16.14      void                    *io_bitmap_a, *io_bitmap_b;
   16.15 +    struct vlapic           *vlapic;
   16.16      u64                     tsc_offset;
   16.17  };
   16.18  
   16.19 @@ -272,18 +274,21 @@ enum vmcs_field {
   16.20  
   16.21  #define VMX_DEBUG 1
   16.22  #if VMX_DEBUG
   16.23 -#define DBG_LEVEL_0     (1 << 0)
   16.24 -#define DBG_LEVEL_1     (1 << 1)
   16.25 -#define DBG_LEVEL_2     (1 << 2)
   16.26 -#define DBG_LEVEL_3     (1 << 3)
   16.27 -#define DBG_LEVEL_IO    (1 << 4)
   16.28 -#define DBG_LEVEL_VMMU  (1 << 5)
   16.29 +#define DBG_LEVEL_0                 (1 << 0)
   16.30 +#define DBG_LEVEL_1                 (1 << 1)
   16.31 +#define DBG_LEVEL_2                 (1 << 2)
   16.32 +#define DBG_LEVEL_3                 (1 << 3)
   16.33 +#define DBG_LEVEL_IO                (1 << 4)
   16.34 +#define DBG_LEVEL_VMMU              (1 << 5)
   16.35 +#define DBG_LEVEL_VLAPIC            (1 << 6)
   16.36 +#define DBG_LEVEL_VLAPIC_TIMER      (1 << 7)
   16.37 +#define DBG_LEVEL_VLAPIC_INTERRUPT  (1 << 7)
   16.38  
   16.39  extern unsigned int opt_vmx_debug_level;
   16.40  #define VMX_DBG_LOG(level, _f, _a...)           \
   16.41      if ((level) & opt_vmx_debug_level)          \
   16.42          printk("[VMX:%d.%d] " _f "\n",          \
   16.43 -                current->domain->domain_id, current->vcpu_id, ## _a)
   16.44 +               current->domain->domain_id, current->vcpu_id, ## _a)
   16.45  #else
   16.46  #define VMX_DBG_LOG(level, _f, _a...)
   16.47  #endif
    17.1 --- a/xen/include/public/io/ioreq.h	Thu Oct 27 18:22:45 2005 +0100
    17.2 +++ b/xen/include/public/io/ioreq.h	Fri Oct 28 09:48:46 2005 +0100
    17.3 @@ -29,11 +29,11 @@
    17.4  #define STATE_IORESP_READY      3
    17.5  #define STATE_IORESP_HOOK       4
    17.6  
    17.7 -#define IOREQ_TYPE_PIO  0 /* pio */
    17.8 -#define IOREQ_TYPE_COPY  1 /* mmio ops */
    17.9 -#define IOREQ_TYPE_AND  2
   17.10 -#define IOREQ_TYPE_OR  3
   17.11 -#define IOREQ_TYPE_XOR  4
   17.12 +#define IOREQ_TYPE_PIO          0 /* pio */
   17.13 +#define IOREQ_TYPE_COPY         1 /* mmio ops */
   17.14 +#define IOREQ_TYPE_AND          2
   17.15 +#define IOREQ_TYPE_OR           3
   17.16 +#define IOREQ_TYPE_XOR          4
   17.17  
   17.18  /*
   17.19   * VMExit dispatcher should cooperate with instruction decoder to
   17.20 @@ -55,9 +55,10 @@ typedef struct {
   17.21      uint8_t type;    /* I/O type                     */
   17.22  } ioreq_t;
   17.23  
   17.24 -#define MAX_VECTOR    256
   17.25 +#define MAX_VECTOR      256
   17.26  #define BITS_PER_BYTE   8
   17.27  #define INTR_LEN        (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t)))
   17.28 +#define INTR_LEN_32     (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint32_t)))
   17.29  
   17.30  typedef struct {
   17.31      uint16_t  pic_elcr;
    18.1 --- a/xen/include/public/io/vmx_vpic.h	Thu Oct 27 18:22:45 2005 +0100
    18.2 +++ b/xen/include/public/io/vmx_vpic.h	Fri Oct 28 09:48:46 2005 +0100
    18.3 @@ -76,7 +76,7 @@ void pic_update_irq(struct vmx_virpic *s
    18.4  uint32_t pic_intack_read(struct vmx_virpic *s);
    18.5  void register_pic_io_hook (void);
    18.6  int cpu_get_pic_interrupt(struct vcpu *v, int *type);
    18.7 -int is_pit_irq(struct vcpu *v, int irq);
    18.8 +int is_pit_irq(struct vcpu *v, int irq, int type);
    18.9  void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs);
   18.10  void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs);
   18.11