WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [IA64] Self IO EMUlator (sioemu) - Hyperv

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] Self IO EMUlator (sioemu) - Hypervisor part
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 21 Feb 2008 07:10:40 -0800
Delivery-date: Fri, 22 Feb 2008 07:29:53 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1203433882 25200
# Node ID 430a036ab26115335698230c815051b3ee327363
# Parent  c750c7177d63c1c6aa44917bff4b996ea745ea96
[IA64] Self IO EMUlator (sioemu) - Hypervisor part

Implements Self IO-EMUlator.  It's an hybrid domain: looks
like PV from an external point of view but runs with VTI enabled.

All MMIO/IO writes/reads are reflected to the firmware, which converts the
access to PV drivers requests.

Signed-off-by: Tristan Gingold <tgingold@xxxxxxx>
---
 xen/arch/ia64/vmx/Makefile            |    1 
 xen/arch/ia64/vmx/mmio.c              |   42 +++++-
 xen/arch/ia64/vmx/sioemu.c            |  219 ++++++++++++++++++++++++++++++++++
 xen/arch/ia64/vmx/vmx_fault.c         |  184 +++++++++++++++-------------
 xen/arch/ia64/vmx/vmx_hypercall.c     |   10 +
 xen/arch/ia64/vmx/vmx_init.c          |   36 ++++-
 xen/arch/ia64/xen/dom0_ops.c          |    6 
 xen/arch/ia64/xen/hypercall.c         |    8 +
 xen/arch/ia64/xen/xensetup.c          |    9 -
 xen/arch/ia64/xen/xentime.c           |    7 +
 xen/include/asm-ia64/dom_fw.h         |    3 
 xen/include/asm-ia64/domain.h         |    5 
 xen/include/asm-ia64/sioemu.h         |   30 ++++
 xen/include/asm-ia64/time.h           |    2 
 xen/include/asm-ia64/vmmu.h           |    1 
 xen/include/asm-ia64/vmx_vpd.h        |    3 
 xen/include/public/arch-ia64/sioemu.h |   42 ++++++
 xen/include/public/domctl.h           |    2 
 18 files changed, 503 insertions(+), 107 deletions(-)

diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/vmx/Makefile
--- a/xen/arch/ia64/vmx/Makefile        Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/vmx/Makefile        Tue Feb 19 08:11:22 2008 -0700
@@ -21,3 +21,4 @@ obj-y += vacpi.o
 obj-y += vacpi.o
 obj-y += vmx_vcpu_save.o
 obj-y += save.o
+obj-y += sioemu.o
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c  Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/vmx/mmio.c  Tue Feb 19 08:11:22 2008 -0700
@@ -39,6 +39,8 @@
 #include <asm/hvm/vacpi.h>
 #include <asm/hvm/support.h>
 #include <public/hvm/save.h>
+#include <public/arch-ia64/sioemu.h>
+#include <asm/sioemu.h>
 
 #define HVM_BUFFERED_IO_RANGE_NR 1
 
@@ -388,6 +390,8 @@ static void mmio_access(VCPU *vcpu, u64 
     return;
 }
 
+enum inst_type_en { SL_INTEGER, SL_FLOATING, SL_FLOATING_FP8 };
+
 /*
    dir 1: read 0:write
  */
@@ -396,11 +400,12 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
     REGS *regs;
     IA64_BUNDLE bundle;
     int slot, dir=0;
-    enum { SL_INTEGER, SL_FLOATING, SL_FLOATING_FP8 } inst_type;
+    enum inst_type_en inst_type;
     size_t size;
     u64 data, data1, temp, update_reg;
     s32 imm;
     INST64 inst;
+    unsigned long update_word;
 
     regs = vcpu_regs(vcpu);
     if (IA64_RETRY == __vmx_get_domain_bundle(regs->cr_iip, &bundle)) {
@@ -523,24 +528,53 @@ void emulate_io_inst(VCPU *vcpu, u64 pad
              inst.inst, regs->cr_iip);
     }
 
+    update_word = size | (dir << 7) | (ma << 8) | (inst_type << 12);
+    if (dir == IOREQ_READ) {
+        if (inst_type == SL_INTEGER)
+            update_word |= (inst.M1.r1 << 16);
+        else if (inst_type == SL_FLOATING_FP8)
+            update_word |= (inst.M12.f1 << 16) | (inst.M12.f2 << 24);
+    }
+
+    if (vcpu->domain->arch.is_sioemu) {
+        unsigned long iot = __gpfn_is_io(vcpu->domain, padr >> PAGE_SHIFT);
+
+        if (iot != GPFN_PIB && iot != GPFN_IOSAPIC) {
+            sioemu_io_emulate(padr, data, data1, update_word);
+            return;
+        }
+    }
+
     if (size == 4) {
         mmio_access(vcpu, padr + 8, &data1, 1 << 3, ma, dir);
         size = 3;
     }
     mmio_access(vcpu, padr, &data, 1 << size, ma, dir);
 
+    emulate_io_update(vcpu, update_word, data, data1);
+}
+
+void
+emulate_io_update(VCPU *vcpu, u64 word, u64 data, u64 data1)
+{
+    int dir = (word >> 7) & 1;
+
     if (dir == IOREQ_READ) {
+        int r1 = (word >> 16) & 0xff;
+        int r2 = (word >> 24) & 0xff;
+        enum inst_type_en inst_type = (word >> 12) & 0x0f;
+
         if (inst_type == SL_INTEGER) {
-            vcpu_set_gr(vcpu, inst.M1.r1, data, 0);
+            vcpu_set_gr(vcpu, r1, data, 0);
         } else if (inst_type == SL_FLOATING_FP8) {
             struct ia64_fpreg v;
 
             v.u.bits[0] = data;
             v.u.bits[1] = 0x1003E;
-            vcpu_set_fpreg(vcpu, inst.M12.f1, &v);
+            vcpu_set_fpreg(vcpu, r1, &v);
             v.u.bits[0] = data1;
             v.u.bits[1] = 0x1003E;
-            vcpu_set_fpreg(vcpu, inst.M12.f2, &v);
+            vcpu_set_fpreg(vcpu, r2, &v);
         } else {
             panic_domain(NULL, "Don't support ldfd now !");
         }
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/vmx/sioemu.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/ia64/vmx/sioemu.c        Tue Feb 19 08:11:22 2008 -0700
@@ -0,0 +1,219 @@
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
+/*
+ * sioemu.c: Self IO emulation - hypercall and return.
+ * Copyright (c) 2008, Tristan Gingold <tgingold@xxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <asm/vcpu.h>
+#include <asm/vmx_vcpu.h>
+#include <asm/sioemu.h>
+#include <public/arch-ia64/sioemu.h>
+#include <asm/dom_fw.h>
+#include <asm/debugger.h>
+
+static REGS *
+sioemu_deliver (void)
+{
+    VCPU *vcpu = current;
+    REGS *regs = vcpu_regs(vcpu);
+    unsigned long psr = vmx_vcpu_get_psr(vcpu);
+
+    if (vcpu->vcpu_info->evtchn_upcall_mask)
+        panic_domain (NULL, "sioemu_deliver: aleady in stub mode\n");
+
+    /* All cleared, but keep BN.  */
+    vmx_vcpu_set_psr(vcpu, IA64_PSR_MC | (psr & IA64_PSR_BN));
+
+    /* Save registers. */
+    vcpu->arch.arch_vmx.stub_saved[0] = regs->r16;
+    vcpu->arch.arch_vmx.stub_saved[1] = regs->r17;
+    vcpu->arch.arch_vmx.stub_saved[2] = regs->r18;
+    vcpu->arch.arch_vmx.stub_saved[3] = regs->r19;
+    vcpu->arch.arch_vmx.stub_saved[4] = regs->r20;
+    vcpu->arch.arch_vmx.stub_saved[5] = regs->r21;
+    vcpu->arch.arch_vmx.stub_saved[6] = regs->r22;
+    vcpu->arch.arch_vmx.stub_saved[7] = regs->r23;
+    vcpu->arch.arch_vmx.stub_saved[8] = regs->r24;
+    vcpu->arch.arch_vmx.stub_saved[9] = regs->r25;
+    vcpu->arch.arch_vmx.stub_saved[10] = regs->r26;
+    vcpu->arch.arch_vmx.stub_saved[11] = regs->r27;
+    vcpu->arch.arch_vmx.stub_saved[12] = regs->r28;
+    vcpu->arch.arch_vmx.stub_saved[13] = regs->r29;
+    vcpu->arch.arch_vmx.stub_saved[14] = regs->r30;
+    vcpu->arch.arch_vmx.stub_saved[15] = regs->r31;
+    vcpu->arch.arch_vmx.stub_nats =
+        (regs->eml_unat >> IA64_PT_REGS_R16_SLOT) & 0xffff;
+
+    /* Context. */
+    regs->r28 = regs->cr_iip;
+    regs->r29 = psr;
+    regs->r30 = regs->cr_ifs;
+
+    regs->cr_ifs = 0;  // pre-cover
+
+    regs->cr_iip = vcpu->arch.event_callback_ip;
+    regs->eml_unat &= ~(0xffffUL << IA64_PT_REGS_R16_SLOT);
+
+    /* Parameters.  */
+    regs->r16 = 0;
+    regs->r17 = vcpu->arch.arch_vmx.stub_buffer;
+
+    /* Mask events.  */
+    vcpu->vcpu_info->evtchn_upcall_mask = 1;
+
+    debugger_event(XEN_IA64_DEBUG_ON_EVENT);
+
+    return regs;
+}
+
+void
+sioemu_callback_return (void)
+{
+    VCPU *vcpu = current;
+    REGS *regs = vcpu_regs(vcpu);
+    u64 cmd = regs->r16;
+    u64 arg1 = regs->r19;
+    u64 arg2 = regs->r20;
+    u64 arg3 = regs->r21;
+
+    if ((cmd & ~0x1UL) != 0)
+        panic_domain (NULL,
+                      "sioemu_callback_return: bad operation (%lx)\n", cmd);
+
+    /* First restore registers.  */
+    regs->cr_iip = regs->r28;
+    regs->cr_ifs = regs->r30;
+    vmx_vcpu_set_psr (vcpu, regs->r29);
+
+    regs->eml_unat &= ~(0xffffUL << IA64_PT_REGS_R16_SLOT);
+    regs->eml_unat |= vcpu->arch.arch_vmx.stub_nats << IA64_PT_REGS_R16_SLOT;
+
+    regs->r16 = vcpu->arch.arch_vmx.stub_saved[0];
+    regs->r17 = vcpu->arch.arch_vmx.stub_saved[1];
+    regs->r18 = vcpu->arch.arch_vmx.stub_saved[2];
+    regs->r19 = vcpu->arch.arch_vmx.stub_saved[3];
+    regs->r20 = vcpu->arch.arch_vmx.stub_saved[4];
+    regs->r21 = vcpu->arch.arch_vmx.stub_saved[5];
+    regs->r22 = vcpu->arch.arch_vmx.stub_saved[6];
+    regs->r23 = vcpu->arch.arch_vmx.stub_saved[7];
+    regs->r24 = vcpu->arch.arch_vmx.stub_saved[8];
+    regs->r25 = vcpu->arch.arch_vmx.stub_saved[9];
+    regs->r26 = vcpu->arch.arch_vmx.stub_saved[10];
+    regs->r27 = vcpu->arch.arch_vmx.stub_saved[11];
+    regs->r28 = vcpu->arch.arch_vmx.stub_saved[12];
+    regs->r29 = vcpu->arch.arch_vmx.stub_saved[13];
+    regs->r30 = vcpu->arch.arch_vmx.stub_saved[14];
+    regs->r31 = vcpu->arch.arch_vmx.stub_saved[15];
+
+    /* Unmask events.  */
+    vcpu->vcpu_info->evtchn_upcall_mask = 0;
+
+    /* Then apply commands.  */
+    if (cmd & 1) {
+        emulate_io_update (vcpu, arg1, arg2, arg3);
+    }
+}
+
+void
+sioemu_deliver_event (void)
+{
+    REGS *regs;
+
+    regs = sioemu_deliver ();
+
+    regs->r16 = 0;
+}
+
+void
+sioemu_io_emulate (unsigned long padr, unsigned long data,
+                  unsigned long data1, unsigned long word)
+{
+    REGS *regs;
+
+    regs = sioemu_deliver ();
+    regs->r16 = 1;
+    regs->r19 = padr;
+    regs->r20 = data;
+    regs->r21 = data1;
+    regs->r22 = word;
+}
+
+static int
+sioemu_add_io_physmap (struct domain *d, unsigned long start,
+                      unsigned long size, unsigned long type)
+{
+    unsigned long i;
+    int res;
+
+    /* Check type.  */
+    if (type == 0 || (type & GPFN_IO_MASK) != type)
+        return -EINVAL;
+    if ((start & (PAGE_SIZE -1)) || (size & (PAGE_SIZE - 1)))
+        return -EINVAL;
+
+    /* Check area is currently unassigned.  */
+    for (i = start; i < start + size; i += PAGE_SIZE) {
+        unsigned long mpa = ____lookup_domain_mpa(d, i);
+        if (mpa != GPFN_INV_MASK && mpa != INVALID_MFN)
+            return -EBUSY;
+    }
+
+    /* Set.  */
+    for (i = start; i < start + size; i += PAGE_SIZE) {
+        res = __assign_domain_page(d, i, type, ASSIGN_writable);
+        if (res != 0)
+            return res;
+    }
+
+    return 0;
+}
+
+void
+sioemu_hypercall (struct pt_regs *regs)
+{
+    //printk ("sioemu_hypercall: r2=%lx r8=%lx r9=%lx\n",
+    //        regs->r2, regs->r8, regs->r9);
+
+    if (current->vcpu_info->evtchn_upcall_mask == 0)
+        panic_domain (NULL, "sioemu_hypercall: not in stub mode\n");
+
+    switch (regs->r2 & FW_HYPERCALL_NUM_MASK_LOW)
+    {
+    case SIOEMU_HYPERCALL_SET_CALLBACK:
+        current->arch.event_callback_ip = regs->r8;
+        current->arch.arch_vmx.stub_buffer = regs->r9;
+        break;
+    case SIOEMU_HYPERCALL_START_FW:
+        regs->cr_iip = regs->r8;
+        vmx_vcpu_set_psr (current, regs->r9);
+        current->vcpu_info->evtchn_upcall_mask = 0;
+        break;
+    case SIOEMU_HYPERCALL_ADD_IO_PHYSMAP:
+        regs->r8 = sioemu_add_io_physmap (current->domain,
+                                          regs->r8, regs->r9, regs->r10);
+        break;
+    case SIOEMU_HYPERCALL_GET_TIME:
+    {
+        uint64_t sec, nsec;
+        get_wallclock (&sec, &nsec);
+        regs->r8 = (sec << 30) + nsec;
+        break;
+    }
+    default:
+        panic_domain (NULL, "bad sioemu hypercall %lx\n", regs->r2);
+        break;
+    }
+}
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/vmx/vmx_fault.c
--- a/xen/arch/ia64/vmx/vmx_fault.c     Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/vmx/vmx_fault.c     Tue Feb 19 08:11:22 2008 -0700
@@ -42,7 +42,6 @@
 #include <asm/privop.h>
 #include <asm/ia64_int.h>
 #include <asm/debugger.h>
-//#include <asm/hpsim_ssc.h>
 #include <asm/dom_fw.h>
 #include <asm/vmx_vcpu.h>
 #include <asm/kregs.h>
@@ -53,6 +52,9 @@
 #include <xen/mm.h>
 #include <asm/vmx_pal.h>
 #include <asm/shadow.h>
+#include <asm/sioemu.h>
+#include <public/arch-ia64/sioemu.h>
+
 /* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */
 #define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
 
@@ -178,34 +180,44 @@ vmx_ia64_handle_break (unsigned long ifa
             show_registers(regs);
         debugger_trap_fatal(0 /* don't care */, regs);
         regs_increment_iip(regs);
-    } else
+        return IA64_NO_FAULT;
+    }
 #endif
-    {
-        if (!vmx_user_mode(regs)) {
-            show_registers(regs);
-            gdprintk(XENLOG_DEBUG, "%s:%d imm %lx\n", __func__, __LINE__, iim);
-            ia64_fault(11 /* break fault */, isr, ifa, iim,
-                       0 /* cr.itir */, 0, 0, 0, (unsigned long)regs);
-        }
-
-        if (ia64_psr(regs)->cpl == 0) {
-            /* Allow hypercalls only when cpl = 0.  */
-
-            /* normal hypercalls are handled by vmx_break_fault */
-            BUG_ON(iim == d->arch.breakimm);
-
-            if (iim == DOMN_PAL_REQUEST) {
-                pal_emul(v);
-                vcpu_increment_iip(v);
-                return IA64_NO_FAULT;
-            } else if (iim == DOMN_SAL_REQUEST) {
-                sal_emul(v);
-                vcpu_increment_iip(v);
-                return IA64_NO_FAULT;
-            }
-        }
-        vmx_reflect_interruption(ifa, isr, iim, 11, regs);
-    }
+    if (!vmx_user_mode(regs)) {
+        show_registers(regs);
+        gdprintk(XENLOG_DEBUG, "%s:%d imm %lx\n", __func__, __LINE__, iim);
+        ia64_fault(11 /* break fault */, isr, ifa, iim,
+                   0 /* cr.itir */, 0, 0, 0, (unsigned long)regs);
+    }
+
+    if (ia64_psr(regs)->cpl == 0) {
+        /* Allow hypercalls only when cpl = 0.  */
+
+        /* Only common hypercalls are handled by vmx_break_fault. */
+        if (iim == d->arch.breakimm) {
+            ia64_hypercall(regs);
+            vcpu_increment_iip(v);
+            return IA64_NO_FAULT;
+        }
+
+        /* normal hypercalls are handled by vmx_break_fault */
+        BUG_ON(iim == d->arch.breakimm);
+        
+        if (iim == DOMN_PAL_REQUEST) {
+            pal_emul(v);
+            vcpu_increment_iip(v);
+            return IA64_NO_FAULT;
+        } else if (iim == DOMN_SAL_REQUEST) {
+            sal_emul(v);
+            vcpu_increment_iip(v);
+            return IA64_NO_FAULT;
+        } else if (d->arch.is_sioemu
+                   && iim == SIOEMU_HYPERPRIVOP_CALLBACK_RETURN) {
+            sioemu_callback_return ();
+            return IA64_NO_FAULT;
+        }
+    }
+    vmx_reflect_interruption(ifa, isr, iim, 11, regs);
     return IA64_NO_FAULT;
 }
 
@@ -214,10 +226,11 @@ void save_banked_regs_to_vpd(VCPU *v, RE
 {
     unsigned long i=0UL, * src,* dst, *sunat, *dunat;
     IA64_PSR vpsr;
-    src=&regs->r16;
-    sunat=&regs->eml_unat;
+
+    src = &regs->r16;
+    sunat = &regs->eml_unat;
     vpsr.val = VCPU(v, vpsr);
-    if(vpsr.bn){
+    if (vpsr.bn) {
         dst = &VCPU(v, vgr[0]);
         dunat =&VCPU(v, vnat);
         __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;; \
@@ -225,7 +238,7 @@ void save_banked_regs_to_vpd(VCPU *v, RE
                             st8 [%3] = %2;;"
        
::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory");
 
-    }else{
+    } else {
         dst = &VCPU(v, vbgr[0]);
 //        dunat =&VCPU(v, vbnat);
 //        __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;;
@@ -234,7 +247,7 @@ void save_banked_regs_to_vpd(VCPU *v, RE
 //       
::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory");
 
     }
-    for(i=0; i<16; i++)
+    for (i = 0; i < 16; i++)
         *dst++ = *src++;
 }
 
@@ -247,58 +260,61 @@ void leave_hypervisor_tail(void)
     struct domain *d = current->domain;
     struct vcpu *v = current;
 
+    /* FIXME: can this happen ?  */
+    if (is_idle_domain(current->domain))
+        return;
+
+    // A softirq may generate an interrupt.  So call softirq early.
+    local_irq_enable();
+    do_softirq();
+    local_irq_disable();
+
     // FIXME: Will this work properly if doing an RFI???
-    if (!is_idle_domain(d) ) { // always comes from guest
-//        struct pt_regs *user_regs = vcpu_regs(current);
-        local_irq_enable();
-        do_softirq();
-        local_irq_disable();
-
-        if (v->vcpu_id == 0) {
-            unsigned long callback_irq =
-                d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
-
-            if ( v->arch.arch_vmx.pal_init_pending ) {
-                /*inject INIT interruption to guest pal*/
-                v->arch.arch_vmx.pal_init_pending = 0;
-                deliver_pal_init(v);
-                return;
-            }
-
-            /*
-             * val[63:56] == 1: val[55:0] is a delivery PCI INTx line:
-             *                  Domain = val[47:32], Bus  = val[31:16],
-             *                  DevFn  = val[15: 8], IntX = val[ 1: 0]
-             * val[63:56] == 0: val[55:0] is a delivery as GSI
-             */
-            if (callback_irq != 0 && local_events_need_delivery()) {
-                /* change level for para-device callback irq */
-                /* use level irq to send discrete event */
-                if ((uint8_t)(callback_irq >> 56) == 1) {
-                    /* case of using PCI INTx line as callback irq */
-                    int pdev = (callback_irq >> 11) & 0x1f;
-                    int pintx = callback_irq & 3;
-                    viosapic_set_pci_irq(d, pdev, pintx, 1);
-                    viosapic_set_pci_irq(d, pdev, pintx, 0);
-                } else {
-                    /* case of using GSI as callback irq */
-                    viosapic_set_irq(d, callback_irq, 1);
-                    viosapic_set_irq(d, callback_irq, 0);
-                }
-            }
-        }
-
-        rmb();
-        if (xchg(&v->arch.irq_new_pending, 0)) {
-            v->arch.irq_new_condition = 0;
-            vmx_check_pending_irq(v);
-            return;
-        }
-
-        if (v->arch.irq_new_condition) {
-            v->arch.irq_new_condition = 0;
-            vhpi_detection(v);
-        }
+    if (d->arch.is_sioemu) {
+        if (local_events_need_delivery()) {
+            sioemu_deliver_event();
+        }
+    } else if (v->vcpu_id == 0) {
+        unsigned long callback_irq =
+            d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+        
+        if (v->arch.arch_vmx.pal_init_pending) {
+            /* inject INIT interruption to guest pal */
+            v->arch.arch_vmx.pal_init_pending = 0;
+            deliver_pal_init(v);
+            return;
+        }
+
+        /*
+         * val[63:56] == 1: val[55:0] is a delivery PCI INTx line:
+         *                  Domain = val[47:32], Bus  = val[31:16],
+         *                  DevFn  = val[15: 8], IntX = val[ 1: 0]
+         * val[63:56] == 0: val[55:0] is a delivery as GSI
+         */
+        if (callback_irq != 0 && local_events_need_delivery()) {
+            /* change level for para-device callback irq */
+            /* use level irq to send discrete event */
+            if ((uint8_t)(callback_irq >> 56) == 1) {
+                /* case of using PCI INTx line as callback irq */
+                int pdev = (callback_irq >> 11) & 0x1f;
+                int pintx = callback_irq & 3;
+                viosapic_set_pci_irq(d, pdev, pintx, 1);
+                viosapic_set_pci_irq(d, pdev, pintx, 0);
+            } else {
+                /* case of using GSI as callback irq */
+                viosapic_set_irq(d, callback_irq, 1);
+                viosapic_set_irq(d, callback_irq, 0);
+            }
+        }
+    }
+
+    rmb();
+    if (xchg(&v->arch.irq_new_pending, 0)) {
+        v->arch.irq_new_condition = 0;
+        vmx_check_pending_irq(v);
+    } else if (v->arch.irq_new_condition) {
+        v->arch.irq_new_condition = 0;
+        vhpi_detection(v);
     }
 }
 
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Tue Feb 19 08:11:22 2008 -0700
@@ -50,12 +50,15 @@ static int hvmop_set_isa_irq_level(
     if ( op.isa_irq > 15 )
         return -EINVAL;
 
+    if ( op.domid == DOMID_SELF )
+        op.domid = current->domain->domain_id;
+
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
 
     rc = -EPERM;
-    if ( !IS_PRIV_FOR(current->domain, d) )
+    if ( !IS_PRIV_FOR(current->domain, d) && d != current->domain )
         goto out;
 
     rc = -EINVAL;
@@ -83,12 +86,15 @@ static int hvmop_set_pci_intx_level(
     if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) )
         return -EINVAL;
 
+    if ( op.domid == DOMID_SELF )
+        op.domid = current->domain->domain_id;
+
     d = rcu_lock_domain_by_id(op.domid);
     if ( d == NULL )
         return -ESRCH;
 
     rc = -EPERM;
-    if ( !IS_PRIV_FOR(current->domain, d) )
+    if ( !IS_PRIV_FOR(current->domain, d) && d != current->domain )
         goto out;
 
     rc = -EINVAL;
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c      Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/vmx/vmx_init.c      Tue Feb 19 08:11:22 2008 -0700
@@ -494,9 +494,11 @@ vmx_final_setup_guest(struct vcpu *v)
        if (rc)
                return rc;
 
-       rc = vmx_create_event_channels(v);
-       if (rc)
-               return rc;
+       if (!v->domain->arch.is_sioemu) {
+               rc = vmx_create_event_channels(v);
+               if (rc)
+                       return rc;
+       }
 
        /* v->arch.schedule_tail = arch_vmx_do_launch; */
        vmx_create_vp(v);
@@ -523,6 +525,9 @@ vmx_relinquish_guest_resources(struct do
 vmx_relinquish_guest_resources(struct domain *d)
 {
        struct vcpu *v;
+
+       if (d->arch.is_sioemu)
+               return;
 
        for_each_vcpu(d, v)
                vmx_release_assist_channel(v);
@@ -579,12 +584,13 @@ int vmx_setup_platform(struct domain *d)
 {
        ASSERT(d != dom0); /* only for non-privileged vti domain */
 
-       vmx_build_io_physmap_table(d);
-
-       vmx_init_ioreq_page(d, &d->arch.vmx_platform.ioreq);
-       vmx_init_ioreq_page(d, &d->arch.vmx_platform.buf_ioreq);
-       vmx_init_ioreq_page(d, &d->arch.vmx_platform.buf_pioreq);
-
+       if (!d->arch.is_sioemu) {
+               vmx_build_io_physmap_table(d);
+
+               vmx_init_ioreq_page(d, &d->arch.vmx_platform.ioreq);
+               vmx_init_ioreq_page(d, &d->arch.vmx_platform.buf_ioreq);
+               vmx_init_ioreq_page(d, &d->arch.vmx_platform.buf_pioreq);
+       }
        /* TEMP */
        d->arch.vmx_platform.pib_base = 0xfee00000UL;
 
@@ -599,7 +605,14 @@ int vmx_setup_platform(struct domain *d)
        /* Initialize iosapic model within hypervisor */
        viosapic_init(d);
 
-       vacpi_init(d);
+       if (!d->arch.is_sioemu)
+               vacpi_init(d);
+
+       if (d->arch.is_sioemu) {
+               int i;
+               for (i = 1; i < MAX_VIRT_CPUS; i++)
+                       d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
+       }
 
        return 0;
 }
@@ -609,6 +622,9 @@ void vmx_do_resume(struct vcpu *v)
        ioreq_t *p;
 
        vmx_load_state(v);
+
+       if (v->domain->arch.is_sioemu)
+               return;
 
        /* stolen from hvm_do_resume() in arch/x86/hvm/hvm.c */
        /* NB. Optimised for common case (p->state == STATE_IOREQ_NONE). */
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/xen/dom0_ops.c      Tue Feb 19 08:11:22 2008 -0700
@@ -114,12 +114,16 @@ long arch_do_domctl(xen_domctl_t *op, XE
                 ret = -EFAULT;
         }
         else {
-            if (is_hvm_domain(d) || (ds->flags & XEN_DOMAINSETUP_hvm_guest)) {
+            if (is_hvm_domain(d)
+                || (ds->flags & (XEN_DOMAINSETUP_hvm_guest
+                                 | XEN_DOMAINSETUP_sioemu_guest))) {
                 if (!vmx_enabled) {
                     printk("No VMX hardware feature for vmx domain.\n");
                     ret = -EINVAL;
                 } else {
                     d->is_hvm = 1;
+                    if (ds->flags & XEN_DOMAINSETUP_sioemu_guest)
+                        d->arch.is_sioemu = 1;
                     xen_ia64_set_convmem_end(d, ds->maxmem);
                     ret = vmx_setup_platform(d);
                 }
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/xen/hypercall.c     Tue Feb 19 08:11:22 2008 -0700
@@ -33,6 +33,8 @@
 #include <xen/event.h>
 #include <xen/perfc.h>
 #include <public/arch-ia64/debug_op.h>
+#include <asm/sioemu.h>
+#include <public/arch-ia64/sioemu.h>
 
 static IA64FAULT
 xen_hypercall (struct pt_regs *regs)
@@ -222,7 +224,8 @@ ia64_hypercall(struct pt_regs *regs)
                regs->r10 = fpswa_ret.err1;
                regs->r11 = fpswa_ret.err2;
                break;
-       case __HYPERVISOR_opt_feature: {
+       case __HYPERVISOR_opt_feature:
+       {
                XEN_GUEST_HANDLE(void) arg;
                struct xen_ia64_opt_feature optf;
                set_xen_guest_handle(arg, (void*)(vcpu_get_gr(v, 32)));
@@ -232,6 +235,9 @@ ia64_hypercall(struct pt_regs *regs)
                        regs->r8 = -EFAULT;
                break;
        }
+       case FW_HYPERCALL_SIOEMU:
+               sioemu_hypercall(regs);
+               break;
        default:
                printk("unknown ia64 fw hypercall %lx\n", regs->r2);
                regs->r8 = do_ni_hypercall();
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/xen/xensetup.c      Tue Feb 19 08:11:22 2008 -0700
@@ -693,6 +693,9 @@ void arch_get_xen_caps(xen_capabilities_
     {
         snprintf(s, sizeof(s), "hvm-%d.%d-ia64 ", major, minor);
         safe_strcat(*info, s);
-    }
-}
-
+
+        snprintf(s, sizeof(s), "hvm-%d.%d-ia64-sioemu ", major, minor);
+        safe_strcat(*info, s);
+    }
+}
+
diff -r c750c7177d63 -r 430a036ab261 xen/arch/ia64/xen/xentime.c
--- a/xen/arch/ia64/xen/xentime.c       Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/arch/ia64/xen/xentime.c       Tue Feb 19 08:11:22 2008 -0700
@@ -252,3 +252,10 @@ struct tm wallclock_time(void)
     do_div(seconds, NSEC_PER_SEC);
     return gmtime(seconds);
 }
+
+void get_wallclock(uint64_t *sec, uint64_t *nsec)
+{
+    uint64_t nano = NOW() + wc_nsec;
+    *sec = wc_sec + nano / NSEC_PER_SEC;
+    *nsec = nano % NSEC_PER_SEC;
+}
diff -r c750c7177d63 -r 430a036ab261 xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h     Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/include/asm-ia64/dom_fw.h     Tue Feb 19 08:11:22 2008 -0700
@@ -168,6 +168,9 @@
 /* Set the shared_info base virtual address.  */
 #define FW_HYPERCALL_SET_SHARED_INFO_VA                        0x600UL
 
+/* Hvmstub hypercalls.  See details in hvm_stub.h  */
+#define FW_HYPERCALL_SIOEMU                            0x800UL
+
 /* Hypercalls index bellow _FIRST_ARCH are reserved by Xen, while those above
    are for the architecture.
    Note: this limit was defined by Xen/ia64 (and not by Xen).
diff -r c750c7177d63 -r 430a036ab261 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/include/asm-ia64/domain.h     Tue Feb 19 08:11:22 2008 -0700
@@ -133,12 +133,13 @@ struct arch_domain {
     /* Flags.  */
     union {
         unsigned long flags;
+        struct {
+            unsigned int is_sioemu : 1;
 #ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
-        struct {
             unsigned int has_pervcpu_vhpt : 1;
             unsigned int vhpt_size_log2 : 6;
+#endif
         };
-#endif
     };
 
     /* maximum metaphysical address of conventional memory */
diff -r c750c7177d63 -r 430a036ab261 xen/include/asm-ia64/sioemu.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-ia64/sioemu.h     Tue Feb 19 08:11:22 2008 -0700
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * sioemu.h
+ * 
+ * Copyright (c) 2008 Tristan Gingold <tgingold@xxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ASM_SIOEMU_H_
+#define __ASM_SIOEMU_H_
+extern void sioemu_hypercall (struct pt_regs *regs);
+extern void sioemu_deliver_event (void);
+extern void sioemu_callback_return (void);
+extern void sioemu_io_emulate (unsigned long padr, unsigned long data,
+                              unsigned long data1, unsigned long word);
+
+#endif /* __ASM_SIOEMU_H_ */
diff -r c750c7177d63 -r 430a036ab261 xen/include/asm-ia64/time.h
--- a/xen/include/asm-ia64/time.h       Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/include/asm-ia64/time.h       Tue Feb 19 08:11:22 2008 -0700
@@ -7,4 +7,6 @@ struct tm;
 struct tm;
 struct tm wallclock_time(void);
 
+void get_wallclock(uint64_t *sec, uint64_t *nsec);
+
 #endif /* _ASM_TIME_H_ */
diff -r c750c7177d63 -r 430a036ab261 xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h       Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/include/asm-ia64/vmmu.h       Tue Feb 19 08:11:22 2008 -0700
@@ -197,6 +197,7 @@ extern thash_data_t * vhpt_lookup(u64 va
 extern thash_data_t * vhpt_lookup(u64 va);
 extern unsigned long fetch_code(struct vcpu *vcpu, u64 gip, IA64_BUNDLE 
*pbundle);
 extern void emulate_io_inst(struct vcpu *vcpu, u64 padr, u64 ma);
+extern void emulate_io_update(struct vcpu *vcpu, u64 word, u64 d, u64 d1);
 extern int vhpt_enabled(struct vcpu *vcpu, uint64_t vadr, vhpt_ref_t ref);
 extern void thash_vhpt_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa,
                               int type);
diff -r c750c7177d63 -r 430a036ab261 xen/include/asm-ia64/vmx_vpd.h
--- a/xen/include/asm-ia64/vmx_vpd.h    Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/include/asm-ia64/vmx_vpd.h    Tue Feb 19 08:11:22 2008 -0700
@@ -74,6 +74,9 @@ struct arch_vmx_struct {
     unsigned long  ivt_current;
     struct ivt_debug ivt_debug[IVT_DEBUG_MAX];
 #endif
+    unsigned long stub_saved[16];
+    unsigned long stub_buffer;
+    unsigned int  stub_nats;
 };
 
 #define VMX_DOMAIN(v)   v->arch.arch_vmx.flags
diff -r c750c7177d63 -r 430a036ab261 xen/include/public/arch-ia64/sioemu.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/public/arch-ia64/sioemu.h     Tue Feb 19 08:11:22 2008 -0700
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * sioemu.h
+ *
+ * Copyright (c) 2008 Tristan Gingold <tgingold@xxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __XEN_PUBLIC_IA64_SIOEMU_H__
+#define __XEN_PUBLIC_IA64_SIOEMU_H__
+
+/* Defines the callback entry point.  r8=ip, r9=data.
+   Must be called per-vcpu.  */
+#define SIOEMU_HYPERCALL_SET_CALLBACK 0x01
+
+/* Finish sioemu fw initialization and start firmware.  r8=ip.  */
+#define SIOEMU_HYPERCALL_START_FW 0x02
+
+/* Add IO pages in physmap.  */
+#define SIOEMU_HYPERCALL_ADD_IO_PHYSMAP 0x03
+
+/* Get wallclock time.  */
+#define SIOEMU_HYPERCALL_GET_TIME 0x04
+
+/* Return from callback.  r16=0.
+   Unmask vcpu events.  */
+#define SIOEMU_HYPERPRIVOP_CALLBACK_RETURN 0x01
+
+#endif /* __XEN_PUBLIC_IA64_SIOEMU_H__ */
diff -r c750c7177d63 -r 430a036ab261 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h       Tue Feb 19 07:51:25 2008 -0700
+++ b/xen/include/public/domctl.h       Tue Feb 19 08:11:22 2008 -0700
@@ -376,6 +376,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_hyper
 #define XEN_DOMAINSETUP_hvm_guest  (1UL<<_XEN_DOMAINSETUP_hvm_guest)
 #define _XEN_DOMAINSETUP_query 1 /* Get parameters (for save)  */
 #define XEN_DOMAINSETUP_query  (1UL<<_XEN_DOMAINSETUP_query)
+#define _XEN_DOMAINSETUP_sioemu_guest 2
+#define XEN_DOMAINSETUP_sioemu_guest  (1UL<<_XEN_DOMAINSETUP_sioemu_guest)
 typedef struct xen_domctl_arch_setup {
     uint64_aligned_t flags;  /* XEN_DOMAINSETUP_* */
 #ifdef __ia64__

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [IA64] Self IO EMUlator (sioemu) - Hypervisor part, Xen patchbot-unstable <=