ia64/xen-unstable

view xen/arch/ia64/vmx/vmx_support.c @ 9563:9bee4875a848

Rename sched_op->sched_op_compat and sched_op_new->sched_op
after Christian's interface cleanup.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Apr 01 11:08:50 2006 +0100 (2006-04-01)
parents cb14f4db7a1e
children 6e979aa0e6d2
line source
2 /* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
3 /*
4 * vmx_support.c: vmx specific support interface.
5 * Copyright (c) 2005, Intel Corporation.
6 * Kun Tian (Kevin Tian) (Kevin.tian@intel.com)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place - Suite 330, Boston, MA 02111-1307 USA.
20 *
21 */
22 #include <xen/config.h>
23 #include <xen/sched.h>
24 #include <xen/hypercall.h>
25 #include <public/sched.h>
26 #include <public/hvm/ioreq.h>
27 #include <asm/vmx.h>
28 #include <asm/vmx_vcpu.h>
30 /*
31 * I/O emulation should be atomic from domain point of view. However,
32 * when emulation code is waiting for I/O completion by blocking,
33 * other events like DM interrupt, VBD, etc. may come and unblock
34 * current exection flow. So we have to prepare for re-block if unblocked
35 * by non I/O completion event.
36 */
37 void vmx_wait_io(void)
38 {
39 struct vcpu *v = current;
40 struct domain *d = v->domain;
41 int port = iopacket_port(v);
43 do {
44 if (!test_bit(port,
45 &d->shared_info->evtchn_pending[0]))
46 do_sched_op_compat(SCHEDOP_block, 0);
48 /* Unblocked when some event is coming. Clear pending indication
49 * immediately if deciding to go for io assist
50 */
51 if (test_and_clear_bit(port,
52 &d->shared_info->evtchn_pending[0])) {
53 clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
54 clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
55 vmx_io_assist(v);
56 }
59 if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
60 /*
61 * Latest event is not I/O completion, so clear corresponding
62 * selector and pending indication, to allow real event coming
63 */
64 clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
66 /* Here atually one window is leaved before selector is cleared.
67 * However this window only delay the indication to coming event,
68 * nothing losed. Next loop will check I/O channel to fix this
69 * window.
70 */
71 clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
72 }
73 else
74 break;
75 } while (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags));
76 }
78 /*
79 * Only place to call vmx_io_assist is mmio/legacy_io emulation.
80 * Since I/O emulation is synchronous, it shouldn't be called in
81 * other places. This is not like x86, since IA-64 implements a
82 * per-vp stack without continuation.
83 */
84 void vmx_io_assist(struct vcpu *v)
85 {
86 vcpu_iodata_t *vio;
87 ioreq_t *p;
89 /*
90 * This shared page contains I/O request between emulation code
91 * and device model.
92 */
93 vio = get_vio(v->domain, v->vcpu_id);
94 if (!vio)
95 panic("Corruption: bad shared page: %lx\n", (unsigned long)vio);
97 p = &vio->vp_ioreq;
99 if (p->state == STATE_IORESP_HOOK)
100 panic("Not supported: No hook available for DM request\n");
102 if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
103 if (p->state != STATE_IORESP_READY) {
104 /* Can't block here, for the same reason as other places to
105 * use vmx_wait_io. Simple return is safe since vmx_wait_io will
106 * try to block again
107 */
108 return;
109 } else
110 p->state = STATE_INVALID;
112 clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
113 } else
114 return; /* Spurous event? */
115 }
117 /*
118 * VMX domainN has two types of interrupt source: lsapic model within
119 * HV, and device model within domain 0 (service OS). There're another
120 * pending array in share page, manipulated by device model directly.
121 * To conform to VT-i spec, we have to sync pending bits in shared page
122 * into VPD. This has to be done before checking pending interrupt at
123 * resume to guest. For domain 0, all the interrupt sources come from
124 * HV, which then doesn't require this assist.
125 */
126 void vmx_intr_assist(struct vcpu *v)
127 {
128 vcpu_iodata_t *vio;
129 struct domain *d = v->domain;
130 extern void vmx_vcpu_pend_batch_interrupt(VCPU *vcpu,
131 unsigned long *pend_irr);
132 int port = iopacket_port(v);
134 /* I/O emulation is atomic, so it's impossible to see execution flow
135 * out of vmx_wait_io, when guest is still waiting for response.
136 */
137 if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
138 panic("!!!Bad resume to guest before I/O emulation is done.\n");
140 /* Clear indicator specific to interrupt delivered from DM */
141 if (test_and_clear_bit(port,
142 &d->shared_info->evtchn_pending[0])) {
143 if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG])
144 clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
146 if (!v->vcpu_info->evtchn_pending_sel)
147 clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
148 }
150 /* Even without event pending, we still need to sync pending bits
151 * between DM and vlsapic. The reason is that interrupt delivery
152 * shares same event channel as I/O emulation, with corresponding
153 * indicator possibly cleared when vmx_wait_io().
154 */
155 vio = get_vio(v->domain, v->vcpu_id);
156 if (!vio)
157 panic("Corruption: bad shared page: %lx\n", (unsigned long)vio);
159 #ifdef V_IOSAPIC_READY
160 /* Confirm virtual interrupt line signals, and set pending bits in vpd */
161 vmx_virq_line_assist(v);
162 #endif
163 return;
164 }