# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Node ID a1939d76c0e8e27bdac5233df7bd78c004ea8deb
# Parent 66fe61db9e69e03e12d0c4086683bebfb4a67780
[HVM] Fix SMP timer issues:
* Sync AP TSCs with BP at startup
* Only halt BP TSC when descheduled
* Correctly handle IPIs on timer vector
Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx>
---
xen/arch/x86/hvm/hvm.c | 5 ++++-
xen/arch/x86/hvm/intercept.c | 1 +
xen/arch/x86/hvm/io.c | 3 ++-
xen/arch/x86/hvm/svm/svm.c | 3 ++-
xen/arch/x86/hvm/vmx/vmcs.c | 13 ++++++++-----
xen/arch/x86/hvm/vmx/vmx.c | 10 +++++++++-
xen/include/asm-x86/hvm/vpt.h | 1 +
7 files changed, 27 insertions(+), 9 deletions(-)
diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Oct 27 17:50:40 2006 +0100
+++ b/xen/arch/x86/hvm/hvm.c Fri Oct 27 18:00:03 2006 +0100
@@ -228,7 +228,7 @@ void hvm_do_resume(struct vcpu *v)
hvm_stts(v);
/* pick up the elapsed PIT ticks and re-enable pit_timer */
- if ( pt->enabled && pt->first_injected ) {
+ if ( pt->enabled && v->vcpu_id == pt->bind_vcpu && pt->first_injected ) {
if ( v->arch.hvm_vcpu.guest_time ) {
hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time);
v->arch.hvm_vcpu.guest_time = 0;
@@ -286,6 +286,9 @@ void hvm_setup_platform(struct domain* d
pit_init(v, cpu_khz);
rtc_init(v, RTC_PORT(0), RTC_IRQ);
pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS);
+
+ /* init guest tsc to start from 0 */
+ hvm_set_guest_time(v, 0);
}
void pic_irq_request(void *data, int level)
diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c Fri Oct 27 17:50:40 2006 +0100
+++ b/xen/arch/x86/hvm/intercept.c Fri Oct 27 18:00:03 2006 +0100
@@ -325,6 +325,7 @@ struct periodic_time * create_periodic_t
stop_timer (&pt->timer);
pt->enabled = 0;
}
+ pt->bind_vcpu = 0; /* timer interrupt delivered to BSP by default */
pt->pending_intr_nr = 0;
pt->first_injected = 0;
if (period < 900000) { /* < 0.9 ms */
diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Fri Oct 27 17:50:40 2006 +0100
+++ b/xen/arch/x86/hvm/io.c Fri Oct 27 18:00:03 2006 +0100
@@ -683,7 +683,8 @@ void hvm_interrupt_post(struct vcpu *v,
struct periodic_time *pt =
&(v->domain->arch.hvm_domain.pl_time.periodic_tm);
- if ( pt->enabled && is_periodic_irq(v, vector, type) ) {
+ if ( pt->enabled && v->vcpu_id == pt->bind_vcpu
+ && is_periodic_irq(v, vector, type) ) {
if ( !pt->first_injected ) {
pt->pending_intr_nr = 0;
pt->last_plt_gtime = hvm_get_guest_time(v);
diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Oct 27 17:50:40 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Fri Oct 27 18:00:03 2006 +0100
@@ -761,7 +761,8 @@ static void svm_freeze_time(struct vcpu
{
struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;
- if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) {
+ if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu
+ && !v->arch.hvm_vcpu.guest_time ) {
v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
stop_timer(&(pt->timer));
}
diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Oct 27 17:50:40 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri Oct 27 18:00:03 2006 +0100
@@ -314,14 +314,20 @@ static void vmx_set_host_env(struct vcpu
error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
}
+/* Update CR3, CR0, CR4, GDT, LDT, TR */
static void vmx_do_launch(struct vcpu *v)
{
-/* Update CR3, CR0, CR4, GDT, LDT, TR */
unsigned int error = 0;
unsigned long cr0, cr4;
- if (v->vcpu_id == 0)
+ if ( v->vcpu_id == 0 )
hvm_setup_platform(v->domain);
+ else {
+ /* Sync AP's TSC with BSP's */
+ v->arch.hvm_vcpu.cache_tsc_offset =
+ v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
+ hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
+ }
__asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : );
@@ -360,9 +366,6 @@ static void vmx_do_launch(struct vcpu *v
__vmwrite(HOST_CR3, v->arch.cr3);
v->arch.schedule_tail = arch_vmx_do_resume;
-
- /* init guest tsc to start from 0 */
- hvm_set_guest_time(v, 0);
}
/*
diff -r 66fe61db9e69 -r a1939d76c0e8 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Oct 27 17:50:40 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Oct 27 18:00:03 2006 +0100
@@ -458,7 +458,8 @@ static void vmx_freeze_time(struct vcpu
{
struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;
- if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) {
+ if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu
+ && !v->arch.hvm_vcpu.guest_time ) {
v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
stop_timer(&(pt->timer));
}
@@ -1972,6 +1973,13 @@ static inline void vmx_do_msr_write(stru
switch (regs->ecx) {
case MSR_IA32_TIME_STAMP_COUNTER:
+ {
+ struct periodic_time *pt =
+ &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
+ if ( pt->enabled && pt->first_injected
+ && v->vcpu_id == pt->bind_vcpu )
+ pt->first_injected = 0;
+ }
hvm_set_guest_time(v, msr_content);
break;
case MSR_IA32_SYSENTER_CS:
diff -r 66fe61db9e69 -r a1939d76c0e8 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h Fri Oct 27 17:50:40 2006 +0100
+++ b/xen/include/asm-x86/hvm/vpt.h Fri Oct 27 18:00:03 2006 +0100
@@ -91,6 +91,7 @@ struct periodic_time {
char one_shot; /* one shot time */
char irq;
char first_injected; /* flag to prevent shadow window */
+ u32 bind_vcpu; /* vcpu timer interrupt delivers to */
u32 pending_intr_nr; /* the couner for pending timer interrupts */
u32 period; /* frequency in ns */
u64 period_cycles; /* frequency in cpu cycles */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|