# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 65c3b9382caac676b392189f8775de50736f51c2
# Parent b180310a0d2ce3b76ca435269c7c99da62f8beec
This patch is to remove the pit_timer when the vmx domain is
inactive to save HV external IRQ caused by ac_time and some cleanup for
ioapic in HV.
Thx,eddie
Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>
diff -r b180310a0d2c -r 65c3b9382caa tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Sat Nov 5 10:23:02 2005
+++ b/tools/ioemu/hw/pc.c Sat Nov 5 10:26:29 2005
@@ -547,9 +547,6 @@
pci_pcnet_init(pci_bus, &nd_table[i]);
}
pci_piix3_ide_init(pci_bus, bs_table);
-#ifdef APIC_SUPPORT
- IOAPICInit();
-#endif
} else {
nb_nics1 = nb_nics;
if (nb_nics1 > NE2000_NB_MAX)
diff -r b180310a0d2c -r 65c3b9382caa tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile Sat Nov 5 10:23:02 2005
+++ b/tools/ioemu/target-i386-dm/Makefile Sat Nov 5 10:26:29 2005
@@ -187,7 +187,7 @@
#########################################################
-DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-DAPIC_SUPPORT
+DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
LIBS+=-lm -L../../libxc -lxenctrl
ifndef CONFIG_USER_ONLY
LIBS+=-lz
@@ -245,7 +245,6 @@
# must use static linking to avoid leaving stuff in virtual address space
VL_OBJS=vl.o exec.o monitor.o osdep.o block.o readline.o pci.o console.o
VL_OBJS+=block-cow.o block-qcow.o block-vmdk.o block-cloop.o aes.o
-VL_OBJS+=ioapic.o
#VL_OBJS+= block-cloop.o
SOUND_HW = sb16.o
diff -r b180310a0d2c -r 65c3b9382caa tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c Sat Nov 5 10:23:02 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c Sat Nov 5 10:26:29 2005
@@ -456,17 +456,10 @@
#endif
main_loop_wait(0);
-#ifdef APIC_SUPPORT
- ioapic_update_EOI();
-#endif
tun_receive_handler(&rfds);
if ( FD_ISSET(evtchn_fd, &rfds) ) {
cpu_handle_ioreq(env);
}
-#ifdef APIC_SUPPORT
- if (ioapic_has_intr())
- do_ioapic();
-#endif
if (env->send_event) {
struct ioctl_evtchn_notify notify;
notify.port = ioreq_local_port;
diff -r b180310a0d2c -r 65c3b9382caa xen/arch/x86/dm/i8259.c
--- a/xen/arch/x86/dm/i8259.c Sat Nov 5 10:23:02 2005
+++ b/xen/arch/x86/dm/i8259.c Sat Nov 5 10:26:29 2005
@@ -525,3 +525,16 @@
return (irq == pit_vec);
}
+
+int is_irq_enabled(struct vcpu *v, int irq)
+{
+ struct vmx_virpic *vpic=&v->domain->arch.vmx_platform.vmx_pic;
+
+ if ( irq & 8 ) {
+ return !( (1 << (irq&7)) & vpic->pics[1].imr);
+ }
+ else {
+ return !( (1 << irq) & vpic->pics[0].imr);
+ }
+}
+
diff -r b180310a0d2c -r 65c3b9382caa xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Sat Nov 5 10:23:02 2005
+++ b/xen/arch/x86/vmx.c Sat Nov 5 10:26:29 2005
@@ -43,6 +43,8 @@
#endif
#include <public/sched.h>
#include <public/io/ioreq.h>
+#include <public/io/vmx_vpic.h>
+#include <public/io/vmx_vlapic.h>
int hvm_enabled;
@@ -85,6 +87,8 @@
void vmx_relinquish_resources(struct vcpu *v)
{
+ struct vmx_virpit *vpit;
+
if ( !VMX_DOMAIN(v) )
return;
@@ -96,7 +100,12 @@
destroy_vmcs(&v->arch.arch_vmx);
free_monitor_pagetable(v);
- rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer);
+ vpit = &v->domain->arch.vmx_platform.vmx_pit;
+ if ( vpit->ticking && active_ac_timer(&(vpit->pit_timer)) )
+ rem_ac_timer(&vpit->pit_timer);
+ if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) ) {
+ rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
+ }
if ( vmx_apic_support(v->domain) ) {
rem_ac_timer( &(VLAPIC(v)->vlapic_timer) );
xfree( VLAPIC(v) );
@@ -1521,12 +1530,24 @@
(unsigned long)regs->edx);
}
-volatile unsigned long do_hlt_count;
/*
* Need to use this exit to reschedule
*/
void vmx_vmexit_do_hlt(void)
{
+ struct vcpu *v=current;
+ struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
+ s_time_t next_pit=-1,next_wakeup;
+
+ 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 ) {
+ next_wakeup = next_pit;
+ }
+ if ( next_wakeup != - 1 )
+ set_ac_timer(¤t->arch.arch_vmx.hlt_timer, next_wakeup);
do_block();
}
diff -r b180310a0d2c -r 65c3b9382caa xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c Sat Nov 5 10:23:02 2005
+++ b/xen/arch/x86/vmx_intercept.c Sat Nov 5 10:26:29 2005
@@ -317,27 +317,51 @@
return 0;
}
-/* hooks function for the PIT initialization response iopacket */
-static void pit_timer_fn(void *data)
-{
- struct vmx_virpit *vpit = data;
- s_time_t next;
+/* hooks function for the HLT instruction emulation wakeup */
+void hlt_timer_fn(void *data)
+{
+ struct vcpu *v = data;
+
+ evtchn_set_pending(v, iopacket_port(v->domain));
+}
+
+static __inline__ void missed_ticks(struct vmx_virpit*vpit)
+{
int missed_ticks;
missed_ticks = (NOW() - vpit->scheduled)/(s_time_t) vpit->period;
-
- /* Set the pending intr bit, and send evtchn notification to myself. */
- vpit->pending_intr_nr++; /* already set, then count the pending intr */
- evtchn_set_pending(vpit->v, iopacket_port(vpit->v->domain));
-
- /* pick up missed timer tick */
if ( missed_ticks > 0 ) {
vpit->pending_intr_nr += missed_ticks;
vpit->scheduled += missed_ticks * vpit->period;
}
- next = vpit->scheduled + vpit->period;
- set_ac_timer(&vpit->pit_timer, next);
- vpit->scheduled = next;
+}
+
+/* hooks function for the PIT when the guest is active */
+static void pit_timer_fn(void *data)
+{
+ struct vcpu *v = data;
+ struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
+
+ /* pick up missed timer tick */
+ missed_ticks(vpit);
+
+ vpit->pending_intr_nr++;
+ if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) {
+ vpit->scheduled += vpit->period;
+ set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+ }
+}
+
+void pickup_deactive_ticks(struct vmx_virpit *vpit)
+{
+
+ if ( !active_ac_timer(&(vpit->pit_timer)) ) {
+ /* pick up missed timer tick */
+ missed_ticks(vpit);
+
+ vpit->scheduled += vpit->period;
+ set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+ }
}
/* Only some PIT operations such as load init counter need a hypervisor hook.
@@ -359,8 +383,10 @@
reinit = 1;
}
- else
- init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, v->processor);
+ else {
+ init_ac_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
+ vpit->ticking = 1;
+ }
/* init count for this channel */
vpit->init_val = (p->u.data & 0xFFFF) ;
@@ -397,8 +423,6 @@
break;
}
- vpit->v = v;
-
vpit->scheduled = NOW() + vpit->period;
set_ac_timer(&vpit->pit_timer, vpit->scheduled);
diff -r b180310a0d2c -r 65c3b9382caa xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c Sat Nov 5 10:23:02 2005
+++ b/xen/arch/x86/vmx_io.c Sat Nov 5 10:26:29 2005
@@ -931,6 +931,7 @@
void vmx_do_resume(struct vcpu *v)
{
+ struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
vmx_stts();
if (event_pending(v)) {
@@ -939,6 +940,9 @@
if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
vmx_wait_io();
}
+ /* pick up the elapsed PIT ticks and re-enable pit_timer */
+ if ( vpit->ticking )
+ pickup_deactive_ticks(vpit);
/* We can't resume the guest if we're waiting on I/O */
ASSERT(!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags));
diff -r b180310a0d2c -r 65c3b9382caa xen/arch/x86/vmx_vlapic.c
--- a/xen/arch/x86/vmx_vlapic.c Sat Nov 5 10:23:02 2005
+++ b/xen/arch/x86/vmx_vlapic.c Sat Nov 5 10:26:29 2005
@@ -60,9 +60,18 @@
return result;
}
-inline int vmx_apic_support(struct domain *d)
+int vmx_apic_support(struct domain *d)
{
return d->arch.vmx_platform.lapic_enable;
+}
+
+s_time_t get_apictime_scheduled(struct vcpu *v)
+{
+ struct vlapic *vlapic = VLAPIC(v);
+
+ if ( !vmx_apic_support(v->domain) || !vlapic_lvt_timer_enabled(vlapic) )
+ return -1;
+ return vlapic->vlapic_timer.expires;
}
int vlapic_find_highest_isr(struct vlapic *vlapic)
diff -r b180310a0d2c -r 65c3b9382caa xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c Sat Nov 5 10:23:02 2005
+++ b/xen/arch/x86/vmx_vmcs.c Sat Nov 5 10:26:29 2005
@@ -321,6 +321,7 @@
vlapic_init(v);
vmx_set_host_env(v);
+ init_ac_timer(&v->arch.arch_vmx.hlt_timer, hlt_timer_fn, v, v->processor);
error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
error |= __vmwrite(GUEST_LDTR_BASE, 0);
diff -r b180310a0d2c -r 65c3b9382caa xen/include/asm-x86/vmx.h
--- a/xen/include/asm-x86/vmx.h Sat Nov 5 10:23:02 2005
+++ b/xen/include/asm-x86/vmx.h Sat Nov 5 10:26:29 2005
@@ -530,5 +530,6 @@
enum { VMX_COPY_IN = 0, VMX_COPY_OUT };
int vmx_copy(void *buf, unsigned long laddr, int size, int dir);
+void pickup_deactive_ticks(struct vmx_virpit *vpit);
#endif /* __ASM_X86_VMX_H__ */
diff -r b180310a0d2c -r 65c3b9382caa xen/include/asm-x86/vmx_virpit.h
--- a/xen/include/asm-x86/vmx_virpit.h Sat Nov 5 10:23:02 2005
+++ b/xen/include/asm-x86/vmx_virpit.h Sat Nov 5 10:26:29 2005
@@ -8,6 +8,7 @@
#include <xen/errno.h>
#include <xen/ac_timer.h>
#include <asm/vmx_vmcs.h>
+#include <public/io/vmx_vpic.h>
#define PIT_FREQ 1193181
@@ -18,14 +19,15 @@
struct vmx_virpit {
/* for simulation of counter 0 in mode 2*/
- u32 period; /* pit frequency in ns */
u64 period_cycles; /* pit frequency in cpu cycles */
+ u64 inject_point; /* the time inject virt intr */
s_time_t scheduled; /* scheduled timer interrupt */
+ struct ac_timer pit_timer; /* periodic timer for mode 2*/
unsigned int channel; /* the pit channel, counter 0~2 */
unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
- u64 inject_point; /* the time inject virt intr */
- struct ac_timer pit_timer; /* periodic timer for mode 2*/
+ u32 period; /* pit frequency in ns */
int first_injected; /* flag to prevent shadow window */
+ int ticking; /* indicating it is ticking */
/* virtual PIT state for handle related I/O */
int read_state;
@@ -34,10 +36,20 @@
unsigned int count; /* the 16 bit channel count */
unsigned int init_val; /* the init value for the counter */
- struct vcpu *v;
};
/* to hook the ioreq packet to get the PIT initializaiton info */
extern void vmx_hooks_assist(struct vcpu *v);
+static __inline__ s_time_t get_pit_scheduled(
+ struct vcpu *v,
+ struct vmx_virpit *vpit)
+{
+ if ( is_irq_enabled(v, 0) ) {
+ return vpit->scheduled;
+ }
+ else
+ return -1;
+}
+
#endif /* _VMX_VIRPIT_H_ */
diff -r b180310a0d2c -r 65c3b9382caa xen/include/asm-x86/vmx_vlapic.h
--- a/xen/include/asm-x86/vmx_vlapic.h Sat Nov 5 10:23:02 2005
+++ b/xen/include/asm-x86/vmx_vlapic.h Sat Nov 5 10:26:29 2005
@@ -239,7 +239,8 @@
uint8_t dest_mode,
uint8_t vector,
uint32_t bitmap);
-
+s_time_t get_apictime_scheduled(struct vcpu *v);
int vmx_apic_support(struct domain *d);
#endif /* VMX_VLAPIC_H */
+
diff -r b180310a0d2c -r 65c3b9382caa xen/include/asm-x86/vmx_vmcs.h
--- a/xen/include/asm-x86/vmx_vmcs.h Sat Nov 5 10:23:02 2005
+++ b/xen/include/asm-x86/vmx_vmcs.h Sat Nov 5 10:26:29 2005
@@ -99,6 +99,7 @@
void *io_bitmap_a, *io_bitmap_b;
struct vlapic *vlapic;
u64 tsc_offset;
+ struct ac_timer hlt_timer; /* hlt ins emulation wakeup timer */
};
#define vmx_schedule_tail(next) \
@@ -116,6 +117,7 @@
int modify_vmcs(struct arch_vmx_struct *arch_vmx,
struct cpu_user_regs *regs);
void destroy_vmcs(struct arch_vmx_struct *arch_vmx);
+void hlt_timer_fn(void *data);
#define VMCS_USE_HOST_ENV 1
#define VMCS_USE_SEPARATE_ENV 0
diff -r b180310a0d2c -r 65c3b9382caa xen/include/public/io/vmx_vlapic.h
--- a/xen/include/public/io/vmx_vlapic.h Sat Nov 5 10:23:02 2005
+++ b/xen/include/public/io/vmx_vlapic.h Sat Nov 5 10:26:29 2005
@@ -28,14 +28,6 @@
#define VLAPIC_INT_COUNT (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE *
sizeof(uint64_t)))
#define VLAPIC_INT_COUNT_32 (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE *
sizeof(uint32_t)))
-struct vapic_bus_message{
- uint8_t deliv_mode:4; /* deliver mode, including fixed, LPRI, etc */
- uint8_t level:1; /* level or edge */
- uint8_t trig_mod:1; /* assert or disassert */
- uint8_t reserved:2;
- uint8_t vector;
-};
-
typedef struct {
/* interrupt for PIC and ext type IOAPIC interrupt */
uint64_t vl_ext_intr[VLAPIC_INT_COUNT];
@@ -51,7 +43,6 @@
uint32_t vl_arb_id;
uint32_t vl_state;
uint32_t apic_msg_count;
- struct vapic_bus_message vl_apic_msg[24];
} vlapic_info;
#endif /* _VMX_VLAPIC_H_ */
diff -r b180310a0d2c -r 65c3b9382caa xen/include/public/io/vmx_vpic.h
--- a/xen/include/public/io/vmx_vpic.h Sat Nov 5 10:23:02 2005
+++ b/xen/include/public/io/vmx_vpic.h Sat Nov 5 10:26:29 2005
@@ -77,6 +77,7 @@
void register_pic_io_hook (void);
int cpu_get_pic_interrupt(struct vcpu *v, int *type);
int is_pit_irq(struct vcpu *v, int irq, int type);
+int is_irq_enabled(struct vcpu *v, int irq);
void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs);
void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|