Mailing List Archive

Fix HVM event handling some more.
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# Node ID 3cb8e672b11578f1f3c9bc3bfd1f6972fff21f5b
# Parent 79d6a1061ad2689ac1e7d84942253581265f5c78
Fix HVM event handling some more.

Signed-off-by: Keir Fraser <keir@xensource.com>

diff -r 79d6a1061ad2 -r 3cb8e672b115 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Mon Feb 13 13:54:27 2006
+++ b/xen/arch/x86/hvm/io.c Mon Feb 13 14:58:50 2006
@@ -704,7 +704,6 @@
{
/* Clear master flag, selector flag, event flag each in turn. */
v->vcpu_info->evtchn_upcall_pending = 0;
- smp_mb__before_clear_bit();
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]) )
@@ -725,6 +724,31 @@
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(d);
+
+ 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(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;
}

/*
diff -r 79d6a1061ad2 -r 3cb8e672b115 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Mon Feb 13 13:54:27 2006
+++ b/xen/arch/x86/hvm/svm/svm.c Mon Feb 13 14:58:50 2006
@@ -25,7 +25,6 @@
#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>
@@ -1812,16 +1811,14 @@
inst_len = __get_instruction_length(vmcb, INSTR_HLT, NULL);
__update_guest_eip(vmcb, inst_len);

- if ( !v->vcpu_id ) {
+ if ( !v->vcpu_id )
next_pit = get_pit_scheduled(v, vpit);
- }
next_wakeup = get_apictime_scheduled(v);
- if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 ) {
+ if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
next_wakeup = next_pit;
- }
if ( next_wakeup != - 1 )
set_timer(&current->arch.hvm_svm.hlt_timer, next_wakeup);
- do_sched_op(SCHEDOP_block, 0);
+ hvm_safe_block();
}


@@ -2434,7 +2431,6 @@
#else
svm_store_cpu_user_regs(&regs, v);
domain_pause_for_debugger();
- do_sched_op(SCHEDOP_yield, 0);
#endif
}
break;
diff -r 79d6a1061ad2 -r 3cb8e672b115 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Mon Feb 13 13:54:27 2006
+++ b/xen/arch/x86/hvm/svm/vmcb.c Mon Feb 13 14:58:50 2006
@@ -487,16 +487,16 @@
*/
void svm_do_resume(struct vcpu *v)
{
- struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
-
- if ( event_pending(v) ||
+ struct domain *d = v->domain;
+ struct hvm_virpit *vpit = &d->arch.hvm_domain.vpit;
+
+ if ( test_bit(iopacket_port(d), &d->shared_info->evtchn_pending[0]) ||
test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
hvm_wait_io();

/* pick up the elapsed PIT ticks and re-enable pit_timer */
- if ( vpit->first_injected ) {
+ if ( vpit->first_injected )
pickup_deactive_ticks(vpit);
- }
svm_set_tsc_shift(v, vpit);

/* We can't resume the guest if we're waiting on I/O */
diff -r 79d6a1061ad2 -r 3cb8e672b115 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Mon Feb 13 13:54:27 2006
+++ b/xen/arch/x86/hvm/vmx/io.c Mon Feb 13 14:58:50 2006
@@ -173,11 +173,12 @@

void vmx_do_resume(struct vcpu *v)
{
- struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+ struct domain *d = v->domain;
+ struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;

vmx_stts();

- if ( event_pending(v) ||
+ if ( test_bit(iopacket_port(d), &d->shared_info->evtchn_pending[0]) ||
test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
hvm_wait_io();

diff -r 79d6a1061ad2 -r 3cb8e672b115 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Mon Feb 13 13:54:27 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Feb 13 14:58:50 2006
@@ -25,7 +25,6 @@
#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>
@@ -1643,16 +1642,14 @@
struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
s_time_t next_pit=-1,next_wakeup;

- if ( !v->vcpu_id ) {
+ if ( !v->vcpu_id )
next_pit = get_pit_scheduled(v,vpit);
- }
next_wakeup = get_apictime_scheduled(v);
- if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 ) {
+ if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
next_wakeup = next_pit;
- }
if ( next_wakeup != - 1 )
set_timer(&current->arch.hvm_vmx.hlt_timer, next_wakeup);
- do_sched_op(SCHEDOP_block, 0);
+ hvm_safe_block();
}

static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
@@ -1849,7 +1846,6 @@
__vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS, PENDING_DEBUG_EXC_BS);

domain_pause_for_debugger();
- do_sched_op(SCHEDOP_yield, 0);

break;
}
diff -r 79d6a1061ad2 -r 3cb8e672b115 xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h Mon Feb 13 13:54:27 2006
+++ b/xen/include/asm-x86/hvm/io.h Mon Feb 13 14:58:50 2006
@@ -148,6 +148,7 @@

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(int *interrupt_request, int level);
extern void hvm_pic_assist(struct vcpu *v);

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