[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Self IO EMUlator (sioemu) - Hypervisor part
# 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=®s->r16; - sunat=®s->eml_unat; + + src = ®s->r16; + sunat = ®s->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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |