141 lines
5.8 KiB
Diff
141 lines
5.8 KiB
Diff
# HG changeset patch
|
|
# User kaf24@localhost.localdomain
|
|
# Date Fri Oct 27 18:00:03 2006 +0100
|
|
# 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@intel.com>
|
|
|
|
Index: xen-3.0.3-testing/xen/arch/x86/hvm/hvm.c
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/hvm.c
|
|
+++ xen-3.0.3-testing/xen/arch/x86/hvm/hvm.c
|
|
@@ -226,7 +226,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;
|
|
Index: xen-3.0.3-testing/xen/arch/x86/hvm/intercept.c
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/intercept.c
|
|
+++ xen-3.0.3-testing/xen/arch/x86/hvm/intercept.c
|
|
@@ -339,6 +339,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 */
|
|
Index: xen-3.0.3-testing/xen/arch/x86/hvm/io.c
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/io.c
|
|
+++ xen-3.0.3-testing/xen/arch/x86/hvm/io.c
|
|
@@ -680,7 +680,7 @@ void hvm_interrupt_post(struct vcpu *v,
|
|
struct periodic_time *pt =
|
|
&(v->domain->arch.hvm_domain.pl_time.periodic_tm);
|
|
|
|
- if ( is_pit_irq(v, vector, type) ) {
|
|
+ if ( is_pit_irq(v, vector, type) && (v->vcpu_id == pt->bind_vcpu) ) {
|
|
if ( !pt->first_injected ) {
|
|
pt->pending_intr_nr = 0;
|
|
pt->last_plt_gtime = hvm_get_guest_time(v);
|
|
Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/svm.c
|
|
+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c
|
|
@@ -763,7 +763,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));
|
|
}
|
|
Index: xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmcs.c
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c
|
|
+++ xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmcs.c
|
|
@@ -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);
|
|
}
|
|
|
|
/*
|
|
Index: xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmx.c
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
|
|
+++ xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmx.c
|
|
@@ -456,7 +456,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));
|
|
}
|
|
@@ -1927,6 +1928,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:
|
|
Index: xen-3.0.3-testing/xen/include/asm-x86/hvm/vpit.h
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/include/asm-x86/hvm/vpit.h
|
|
+++ xen-3.0.3-testing/xen/include/asm-x86/hvm/vpit.h
|
|
@@ -58,6 +58,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 */
|