# HG changeset patch
# User sos22@xxxxxxxxxxxxxxxxxxxx
# Node ID 415614d3a1eecab543bc71e4188ae8015d59f3e6
# Parent 857e7b864bb0a87cc6fc286bc1abb958df7d8db1
[hvm/qemu] Flip the device model over to using the new Xen event channels
support.
Signed-off-by: Steven Smith <ssmith@xxxxxxxxxxxxx>
---
tools/ioemu/target-i386-dm/helper2.c | 19 ++++---
tools/libxc/xc_hvm_build.c | 15 -----
xen/arch/x86/hvm/hvm.c | 24 +++++++++
xen/arch/x86/hvm/intercept.c | 2
xen/arch/x86/hvm/io.c | 89 ++++-------------------------------
xen/arch/x86/hvm/platform.c | 52 ++++++++++++--------
xen/arch/x86/hvm/svm/svm.c | 3 -
xen/arch/x86/hvm/svm/vmcb.c | 34 +++++--------
xen/arch/x86/hvm/svm/x86_32/exits.S | 3 +
xen/arch/x86/hvm/svm/x86_64/exits.S | 2
xen/arch/x86/hvm/vlapic.c | 2
xen/arch/x86/hvm/vmx/io.c | 18 ++++---
xen/arch/x86/hvm/vmx/vmcs.c | 12 ----
xen/arch/x86/hvm/vmx/vmx.c | 4 +
xen/arch/x86/hvm/vmx/x86_32/exits.S | 3 +
xen/arch/x86/hvm/vmx/x86_64/exits.S | 2
xen/include/asm-x86/hvm/hvm.h | 5 +
xen/include/asm-x86/hvm/io.h | 3 -
xen/include/asm-x86/hvm/support.h | 7 --
xen/include/asm-x86/hvm/vcpu.h | 2
xen/include/public/hvm/ioreq.h | 1
xen/include/xen/event.h | 1
22 files changed, 132 insertions(+), 171 deletions(-)
diff -r 857e7b864bb0 -r 415614d3a1ee tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c Tue Aug 08 11:17:52 2006 +0100
+++ b/tools/ioemu/target-i386-dm/helper2.c Tue Aug 08 11:19:29 2006 +0100
@@ -82,6 +82,10 @@ int xce_handle = -1;
/* which vcpu we are serving */
int send_vcpu = 0;
+//the evtchn port for polling the notification,
+#define NR_CPUS 32
+evtchn_port_t ioreq_local_port[NR_CPUS];
+
CPUX86State *cpu_x86_init(void)
{
CPUX86State *env;
@@ -113,7 +117,7 @@ CPUX86State *cpu_x86_init(void)
fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
return NULL;
}
- shared_page->vcpu_iodata[i].dm_eport = rc;
+ ioreq_local_port[i] = rc;
}
}
@@ -184,8 +188,7 @@ void sp_info()
for (i = 0; i < vcpus; i++) {
req = &(shared_page->vcpu_iodata[i].vp_ioreq);
- term_printf("vcpu %d: event port %d\n", i,
- shared_page->vcpu_iodata[i].vp_eport);
+ term_printf("vcpu %d: event port %d\n", i, ioreq_local_port[i]);
term_printf(" req state: %x, pvalid: %x, addr: %"PRIx64", "
"data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
req->state, req->pdata_valid, req->addr,
@@ -204,6 +207,7 @@ static ioreq_t *__cpu_get_ioreq(int vcpu
if (req->state == STATE_IOREQ_READY) {
req->state = STATE_IOREQ_INPROCESS;
+ rmb();
return req;
}
@@ -226,7 +230,7 @@ static ioreq_t *cpu_get_ioreq(void)
port = xc_evtchn_pending(xce_handle);
if (port != -1) {
for ( i = 0; i < vcpus; i++ )
- if ( shared_page->vcpu_iodata[i].dm_eport == port )
+ if ( ioreq_local_port[i] == port )
break;
if ( i == vcpus ) {
@@ -447,8 +451,10 @@ void cpu_handle_ioreq(void *opaque)
}
/* No state change if state = STATE_IORESP_HOOK */
- if (req->state == STATE_IOREQ_INPROCESS)
+ if (req->state == STATE_IOREQ_INPROCESS) {
+ mb();
req->state = STATE_IORESP_READY;
+ }
env->send_event = 1;
}
}
@@ -479,8 +485,7 @@ int main_loop(void)
if (env->send_event) {
env->send_event = 0;
- xc_evtchn_notify(xce_handle,
- shared_page->vcpu_iodata[send_vcpu].dm_eport);
+ xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
}
}
destroy_hvm_domain();
diff -r 857e7b864bb0 -r 415614d3a1ee tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Tue Aug 08 11:17:52 2006 +0100
+++ b/tools/libxc/xc_hvm_build.c Tue Aug 08 11:19:29 2006 +0100
@@ -294,26 +294,13 @@ static int setup_guest(int xc_handle,
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
munmap(shared_info, PAGE_SIZE);
- /* Populate the event channel port in the shared page */
+ /* Paranoia */
shared_page_frame = page_array[(v_end >> PAGE_SHIFT) - 1];
if ( (sp = (shared_iopage_t *) xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
shared_page_frame)) == 0 )
goto error_out;
memset(sp, 0, PAGE_SIZE);
-
- /* FIXME: how about if we overflow the page here? */
- for ( i = 0; i < vcpus; i++ ) {
- unsigned int vp_eport;
-
- vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
- if ( vp_eport < 0 ) {
- PERROR("Couldn't get unbound port from VMX guest.\n");
- goto error_out;
- }
- sp->vcpu_iodata[i].vp_eport = vp_eport;
- }
-
munmap(sp, PAGE_SIZE);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, (v_end >>
PAGE_SHIFT) - 2);
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/hvm.c Tue Aug 08 11:19:29 2006 +0100
@@ -29,6 +29,7 @@
#include <xen/domain_page.h>
#include <xen/hypercall.h>
#include <xen/guest_access.h>
+#include <xen/event.h>
#include <asm/current.h>
#include <asm/io.h>
#include <asm/shadow.h>
@@ -160,6 +161,29 @@ void hvm_map_io_shared_page(struct vcpu
d->arch.hvm_domain.shared_page_va = (unsigned long)p;
}
+void hvm_create_event_channels(struct vcpu *v)
+{
+ vcpu_iodata_t *p;
+ struct vcpu *o;
+
+ if ( v->vcpu_id == 0 ) {
+ /* Ugly: create event channels for every vcpu when vcpu 0
+ starts, so that they're available for ioemu to bind to. */
+ for_each_vcpu(v->domain, o) {
+ p = get_vio(v->domain, o->vcpu_id);
+ o->arch.hvm_vcpu.xen_port = p->vp_eport =
+ alloc_unbound_xen_event_channel(o, 0);
+ DPRINTK("Allocated port %d for hvm.\n", o->arch.hvm_vcpu.xen_port);
+ }
+ }
+}
+
+void hvm_release_assist_channel(struct vcpu *v)
+{
+ free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);
+}
+
+
void hvm_setup_platform(struct domain* d)
{
struct hvm_domain *platform;
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/intercept.c Tue Aug 08 11:19:29 2006 +0100
@@ -211,7 +211,7 @@ void hlt_timer_fn(void *data)
{
struct vcpu *v = data;
- evtchn_set_pending(v, iopacket_port(v));
+ hvm_prod_vcpu(v);
}
static __inline__ void missed_ticks(struct periodic_time *pt)
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/io.c Tue Aug 08 11:19:29 2006 +0100
@@ -687,84 +687,17 @@ void hvm_io_assist(struct vcpu *v)
p = &vio->vp_ioreq;
- /* clear IO wait HVM flag */
- if ( test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) ) {
- if ( p->state == STATE_IORESP_READY ) {
- p->state = STATE_INVALID;
- clear_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
-
- if ( p->type == IOREQ_TYPE_PIO )
- hvm_pio_assist(regs, p, io_opp);
- else
- hvm_mmio_assist(regs, p, io_opp);
-
- /* Copy register changes back into current guest state. */
- hvm_load_cpu_guest_regs(v, regs);
- memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
- }
- /* else an interrupt send event raced us */
- }
-}
-
-/*
- * On exit from hvm_wait_io, we're guaranteed not to be waiting on
- * I/O response from the device model.
- */
-void hvm_wait_io(void)
-{
- struct vcpu *v = current;
- struct domain *d = v->domain;
- int port = iopacket_port(v);
-
- for ( ; ; )
- {
- /* Clear master flag, selector flag, event flag each in turn. */
- v->vcpu_info->evtchn_upcall_pending = 0;
- clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
- smp_mb__after_clear_bit();
- if ( test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]) )
- hvm_io_assist(v);
-
- /* Need to wait for I/O responses? */
- if ( !test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
- break;
-
- do_sched_op_compat(SCHEDOP_block, 0);
- }
-
- /*
- * Re-set the selector and master flags in case any other notifications
- * are pending.
- */
- if ( d->shared_info->evtchn_pending[port/BITS_PER_LONG] )
- set_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
- if ( v->vcpu_info->evtchn_pending_sel )
- v->vcpu_info->evtchn_upcall_pending = 1;
-}
-
-void hvm_safe_block(void)
-{
- struct vcpu *v = current;
- struct domain *d = v->domain;
- int port = iopacket_port(v);
-
- for ( ; ; )
- {
- /* Clear master flag & selector flag so we will wake from block. */
- v->vcpu_info->evtchn_upcall_pending = 0;
- clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
- smp_mb__after_clear_bit();
-
- /* Event pending already? */
- if ( test_bit(port, &d->shared_info->evtchn_pending[0]) )
- break;
-
- do_sched_op_compat(SCHEDOP_block, 0);
- }
-
- /* Reflect pending event in selector and master flags. */
- set_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
- v->vcpu_info->evtchn_upcall_pending = 1;
+ if ( p->state == STATE_IORESP_READY ) {
+ p->state = STATE_INVALID;
+ if ( p->type == IOREQ_TYPE_PIO )
+ hvm_pio_assist(regs, p, io_opp);
+ else
+ hvm_mmio_assist(regs, p, io_opp);
+
+ /* Copy register changes back into current guest state. */
+ hvm_load_cpu_guest_regs(v, regs);
+ memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
+ }
}
/*
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/platform.c Tue Aug 08 11:19:29 2006 +0100
@@ -669,6 +669,30 @@ int inst_copy_from_guest(unsigned char *
return inst_len;
}
+static void hvm_send_assist_req(struct vcpu *v)
+{
+ ioreq_t *p;
+
+ p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+ if ( unlikely(p->state != STATE_INVALID) ) {
+ /* This indicates a bug in the device model. Crash the
+ domain. */
+ printf("Device model set bad IO state %d.\n", p->state);
+ domain_crash(v->domain);
+ return;
+ }
+ wmb();
+ p->state = STATE_IOREQ_READY;
+ notify_via_xen_event_channel(v->arch.hvm_vcpu.xen_port);
+}
+
+
+/* Wake up a vcpu whihc is waiting for interrupts to come in */
+void hvm_prod_vcpu(struct vcpu *v)
+{
+ vcpu_unblock(v);
+}
+
void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
unsigned long count, int size, long value, int dir, int
pvalid)
{
@@ -682,13 +706,10 @@ void send_pio_req(struct cpu_user_regs *
domain_crash_synchronous();
}
- if (test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags)) {
- printf("HVM I/O has not yet completed\n");
- domain_crash_synchronous();
- }
- set_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
-
p = &vio->vp_ioreq;
+ if ( p->state != STATE_INVALID )
+ printf("WARNING: send pio with something already pending (%d)?\n",
+ p->state);
p->dir = dir;
p->pdata_valid = pvalid;
@@ -714,10 +735,7 @@ void send_pio_req(struct cpu_user_regs *
return;
}
- p->state = STATE_IOREQ_READY;
-
- evtchn_send(iopacket_port(v));
- hvm_wait_io();
+ hvm_send_assist_req(v);
}
void send_mmio_req(
@@ -739,12 +757,9 @@ void send_mmio_req(
p = &vio->vp_ioreq;
- if (test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags)) {
- printf("HVM I/O has not yet completed\n");
- domain_crash_synchronous();
- }
-
- set_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags);
+ if ( p->state != STATE_INVALID )
+ printf("WARNING: send mmio with something already pending (%d)?\n",
+ p->state);
p->dir = dir;
p->pdata_valid = pvalid;
@@ -770,10 +785,7 @@ void send_mmio_req(
return;
}
- p->state = STATE_IOREQ_READY;
-
- evtchn_send(iopacket_port(v));
- hvm_wait_io();
+ hvm_send_assist_req(v);
}
static void mmio_operands(int type, unsigned long gpa, struct instruction
*inst,
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Tue Aug 08 11:19:29 2006 +0100
@@ -25,6 +25,7 @@
#include <xen/sched.h>
#include <xen/irq.h>
#include <xen/softirq.h>
+#include <xen/hypercall.h>
#include <asm/current.h>
#include <asm/io.h>
#include <asm/shadow.h>
@@ -2121,7 +2122,7 @@ static inline void svm_vmexit_do_hlt(str
next_wakeup = next_pit;
if ( next_wakeup != - 1 )
set_timer(¤t->arch.hvm_svm.hlt_timer, next_wakeup);
- hvm_safe_block();
+ do_sched_op_compat(SCHEDOP_block, 0);
}
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/svm/vmcb.c Tue Aug 08 11:19:29 2006 +0100
@@ -370,18 +370,6 @@ void svm_do_launch(struct vcpu *v)
if (v->vcpu_id == 0)
hvm_setup_platform(v->domain);
- if ( evtchn_bind_vcpu(iopacket_port(v), v->vcpu_id) < 0 )
- {
- printk("HVM domain bind port %d to vcpu %d failed!\n",
- iopacket_port(v), v->vcpu_id);
- domain_crash_synchronous();
- }
-
- HVM_DBG_LOG(DBG_LEVEL_1, "eport: %x", iopacket_port(v));
-
- clear_bit(iopacket_port(v),
- &v->domain->shared_info->evtchn_mask[0]);
-
if (hvm_apic_support(v->domain))
vlapic_init(v);
init_timer(&v->arch.hvm_svm.hlt_timer,
@@ -439,10 +427,12 @@ void set_hsa_to_guest( struct arch_svm_s
/*
* Resume the guest.
*/
+/* XXX svm_do_resume and vmx_do_resume are remarkably similar; could
+ they be unified? */
void svm_do_resume(struct vcpu *v)
{
- struct domain *d = v->domain;
- struct periodic_time *pt = &d->arch.hvm_domain.pl_time.periodic_tm;
+ struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm;
+ ioreq_t *p;
svm_stts(v);
@@ -455,12 +445,16 @@ void svm_do_resume(struct vcpu *v)
pickup_deactive_ticks(pt);
}
- if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
- test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
- hvm_wait_io();
-
- /* We can't resume the guest if we're waiting on I/O */
- ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
+ p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+ wait_on_xen_event_channel(v->arch.hvm.xen_port,
+ p->state != STATE_IOREQ_READY &&
+ p->state != STATE_IOREQ_INPROCESS);
+ if ( p->state == STATE_IORESP_READY )
+ hvm_io_assist(v);
+ if ( p->state != STATE_INVALID ) {
+ printf("Weird HVM iorequest state %d.\n", p->state);
+ domain_crash(v->domain);
+ }
}
void svm_launch_fail(unsigned long eflags)
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/svm/x86_32/exits.S
--- a/xen/arch/x86/hvm/svm/x86_32/exits.S Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/svm/x86_32/exits.S Tue Aug 08 11:19:29 2006 +0100
@@ -132,6 +132,9 @@ ENTRY(svm_asm_do_resume)
ENTRY(svm_asm_do_resume)
svm_test_all_events:
GET_CURRENT(%ebx)
+ pushl %ebx
+ call svm_do_resume
+ addl $4, %esp
/*test_all_events:*/
xorl %ecx,%ecx
notl %ecx
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/svm/x86_64/exits.S
--- a/xen/arch/x86/hvm/svm/x86_64/exits.S Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/svm/x86_64/exits.S Tue Aug 08 11:19:29 2006 +0100
@@ -147,6 +147,8 @@ ENTRY(svm_asm_do_resume)
ENTRY(svm_asm_do_resume)
svm_test_all_events:
GET_CURRENT(%rbx)
+ movq %rbx, %rdi
+ call svm_do_resume
/*test_all_events:*/
cli # tests must not race interrupts
/*test_softirqs:*/
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Tue Aug 08 11:19:29 2006 +0100
@@ -232,7 +232,7 @@ static int vlapic_accept_irq(struct vcpu
"level trig mode for vector %d\n", vector);
set_bit(vector, vlapic->regs + APIC_TMR);
}
- evtchn_set_pending(v, iopacket_port(v));
+ hvm_prod_vcpu(v);
result = 1;
break;
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/io.c Tue Aug 08 11:19:29 2006 +0100
@@ -221,7 +221,7 @@ asmlinkage void vmx_intr_assist(void)
void vmx_do_resume(struct vcpu *v)
{
- struct domain *d = v->domain;
+ ioreq_t *p;
struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm;
vmx_stts();
@@ -235,12 +235,16 @@ void vmx_do_resume(struct vcpu *v)
pickup_deactive_ticks(pt);
}
- if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
- test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
- hvm_wait_io();
-
- /* We can't resume the guest if we're waiting on I/O */
- ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
+ p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+ wait_on_xen_event_channel(v->arch.hvm.xen_port,
+ p->state != STATE_IOREQ_READY &&
+ p->state != STATE_IOREQ_INPROCESS);
+ if ( p->state == STATE_IORESP_READY )
+ hvm_io_assist(v);
+ if ( p->state != STATE_INVALID ) {
+ printf("Weird HVM iorequest state %d.\n", p->state);
+ domain_crash(v->domain);
+ }
}
/*
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Aug 08 11:19:29 2006 +0100
@@ -245,18 +245,6 @@ static void vmx_do_launch(struct vcpu *v
if (v->vcpu_id == 0)
hvm_setup_platform(v->domain);
- if ( evtchn_bind_vcpu(iopacket_port(v), v->vcpu_id) < 0 )
- {
- printk("VMX domain bind port %d to vcpu %d failed!\n",
- iopacket_port(v), v->vcpu_id);
- domain_crash_synchronous();
- }
-
- HVM_DBG_LOG(DBG_LEVEL_1, "eport: %x", iopacket_port(v));
-
- clear_bit(iopacket_port(v),
- &v->domain->shared_info->evtchn_mask[0]);
-
__asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : );
error |= __vmwrite(GUEST_CR0, cr0);
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Aug 08 11:19:29 2006 +0100
@@ -25,6 +25,7 @@
#include <xen/irq.h>
#include <xen/softirq.h>
#include <xen/domain_page.h>
+#include <xen/hypercall.h>
#include <asm/current.h>
#include <asm/io.h>
#include <asm/shadow.h>
@@ -141,6 +142,7 @@ static void vmx_relinquish_guest_resourc
free_domheap_page(VLAPIC(v)->regs_page);
xfree(VLAPIC(v));
}
+ hvm_release_assist_channel(v);
}
kill_timer(&d->arch.hvm_domain.pl_time.periodic_tm.timer);
@@ -2014,7 +2016,7 @@ void vmx_vmexit_do_hlt(void)
next_wakeup = next_pit;
if ( next_wakeup != - 1 )
set_timer(¤t->arch.hvm_vmx.hlt_timer, next_wakeup);
- hvm_safe_block();
+ do_sched_op_compat(SCHEDOP_block, 0);
}
static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/vmx/x86_32/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_32/exits.S Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S Tue Aug 08 11:19:29 2006 +0100
@@ -94,6 +94,9 @@ vmx_process_softirqs:
ALIGN
ENTRY(vmx_asm_do_vmentry)
GET_CURRENT(%ebx)
+ pushl %ebx
+ call vmx_do_resume
+ addl $4, %esp
cli # tests must not race interrupts
movl VCPU_processor(%ebx),%eax
diff -r 857e7b864bb0 -r 415614d3a1ee xen/arch/x86/hvm/vmx/x86_64/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_64/exits.S Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S Tue Aug 08 11:19:29 2006 +0100
@@ -105,6 +105,8 @@ vmx_process_softirqs:
ALIGN
ENTRY(vmx_asm_do_vmentry)
GET_CURRENT(%rbx)
+ movq %rbx, %rdi
+ call vmx_do_resume
cli # tests must not race interrupts
movl VCPU_processor(%rbx),%eax
diff -r 857e7b864bb0 -r 415614d3a1ee xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/include/asm-x86/hvm/hvm.h Tue Aug 08 11:19:29 2006 +0100
@@ -77,6 +77,7 @@ hvm_disable(void)
hvm_funcs.disable();
}
+void hvm_create_event_channels(struct vcpu *v);
void hvm_map_io_shared_page(struct vcpu *v);
static inline int
@@ -85,8 +86,10 @@ hvm_initialize_guest_resources(struct vc
int ret = 1;
if ( hvm_funcs.initialize_guest_resources )
ret = hvm_funcs.initialize_guest_resources(v);
- if ( ret == 1 )
+ if ( ret == 1 ) {
hvm_map_io_shared_page(v);
+ hvm_create_event_channels(v);
+ }
return ret;
}
diff -r 857e7b864bb0 -r 415614d3a1ee xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/include/asm-x86/hvm/io.h Tue Aug 08 11:19:29 2006 +0100
@@ -150,13 +150,12 @@ static inline int irq_masked(unsigned lo
#endif
extern void handle_mmio(unsigned long, unsigned long);
-extern void hvm_wait_io(void);
-extern void hvm_safe_block(void);
extern void hvm_io_assist(struct vcpu *v);
extern void pic_irq_request(void *data, int level);
extern void hvm_pic_assist(struct vcpu *v);
extern int cpu_get_interrupt(struct vcpu *v, int *type);
extern int cpu_has_pending_irq(struct vcpu *v);
+extern void hvm_release_assist_channel(struct vcpu *v);
// XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO
frame.
#define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT)))
diff -r 857e7b864bb0 -r 415614d3a1ee xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/include/asm-x86/hvm/support.h Tue Aug 08 11:19:29 2006 +0100
@@ -42,11 +42,6 @@ static inline vcpu_iodata_t *get_vio(str
static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu)
{
return &get_sp(d)->vcpu_iodata[cpu];
-}
-
-static inline int iopacket_port(struct vcpu *v)
-{
- return get_vio(v->domain, v->vcpu_id)->vp_eport;
}
/* XXX these are really VMX specific */
@@ -150,4 +145,6 @@ extern void hlt_timer_fn(void *data);
void hvm_do_hypercall(struct cpu_user_regs *pregs);
+void hvm_prod_vcpu(struct vcpu *v);
+
#endif /* __ASM_X86_HVM_SUPPORT_H__ */
diff -r 857e7b864bb0 -r 415614d3a1ee xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/include/asm-x86/hvm/vcpu.h Tue Aug 08 11:19:29 2006 +0100
@@ -38,6 +38,8 @@ struct hvm_vcpu {
/* For AP startup */
unsigned long init_sipi_sipi_state;
+ int xen_port;
+
/* Flags */
int flag_dr_dirty;
diff -r 857e7b864bb0 -r 415614d3a1ee xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/include/public/hvm/ioreq.h Tue Aug 08 11:19:29 2006 +0100
@@ -69,7 +69,6 @@ struct vcpu_iodata {
struct ioreq vp_ioreq;
/* Event channel port */
unsigned int vp_eport; /* VMX vcpu uses this to notify DM */
- unsigned int dm_eport; /* DM uses this to notify VMX vcpu */
};
typedef struct vcpu_iodata vcpu_iodata_t;
diff -r 857e7b864bb0 -r 415614d3a1ee xen/include/xen/event.h
--- a/xen/include/xen/event.h Tue Aug 08 11:17:52 2006 +0100
+++ b/xen/include/xen/event.h Tue Aug 08 11:19:29 2006 +0100
@@ -12,6 +12,7 @@
#include <xen/config.h>
#include <xen/sched.h>
#include <xen/smp.h>
+#include <xen/softirq.h>
#include <asm/bitops.h>
#include <asm/event.h>
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|