xen/xu-12012-hvm-smp-timer.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 */