# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1197633931 0
# Node ID 7f8a28149131ee9cb9894b1b00a1d669d7e402f5
# Parent 17820aa1b2c04091702a3ee86440042e1029c1f5
SVM: Treat the vlapic's tpr as the master copy and sync the vtpr to it
before every vm entry. This fixes HVM save/restore/migrate, as the
vtpr value was only being synced on guest TPR writes before.
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
xen-unstable changeset: 16618:966a6d3b74087474df337e00b31cbecf495b442a
xen-unstable date: Fri Dec 14 11:50:24 2007 +0000
---
xen/arch/x86/hvm/svm/intr.c | 3 ++-
xen/arch/x86/hvm/svm/svm.c | 26 ++++++++++++--------------
xen/arch/x86/hvm/vlapic.c | 1 -
xen/arch/x86/hvm/vmx/vmx.c | 6 ------
xen/include/asm-x86/hvm/hvm.h | 11 -----------
5 files changed, 14 insertions(+), 33 deletions(-)
diff -r 17820aa1b2c0 -r 7f8a28149131 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Fri Dec 14 11:58:37 2007 +0000
+++ b/xen/arch/x86/hvm/svm/intr.c Fri Dec 14 12:05:31 2007 +0000
@@ -83,7 +83,8 @@ static void update_cr8_intercept(
return;
/* Highest-priority pending interrupt is masked by the TPR? */
- if ( (vmcb->vintr.fields.tpr & 0xf) >= (max_irr >> 4) )
+ if ( ((vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0) >> 4) >=
+ (max_irr >> 4) )
vmcb->cr_intercepts |= CR_INTERCEPT_CR8_WRITE;
}
diff -r 17820aa1b2c0 -r 7f8a28149131 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Dec 14 11:58:37 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Fri Dec 14 12:05:31 2007 +0000
@@ -676,13 +676,6 @@ static void svm_flush_guest_tlbs(void)
svm_asid_inc_generation();
}
-static void svm_update_vtpr(struct vcpu *v, unsigned long value)
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
- vmcb->vintr.fields.tpr = value & 0x0f;
-}
-
static unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
{
switch ( num )
@@ -948,6 +941,10 @@ static void svm_do_resume(struct vcpu *v
/* Migrating to another ASID domain. Request a new ASID. */
svm_asid_init_vcpu(v);
}
+
+ /* Reflect the vlapic's TPR in the hardware vtpr */
+ v->arch.hvm_svm.vmcb->vintr.fields.tpr =
+ (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4;
hvm_do_resume(v);
reset_stack_and_jump(svm_asm_do_resume);
@@ -1015,7 +1012,6 @@ static struct hvm_function_table svm_fun
.update_host_cr3 = svm_update_host_cr3,
.update_guest_cr3 = svm_update_guest_cr3,
.flush_guest_tlbs = svm_flush_guest_tlbs,
- .update_vtpr = svm_update_vtpr,
.stts = svm_stts,
.set_tsc_offset = svm_set_tsc_offset,
.inject_exception = svm_hvm_inject_exception,
@@ -2424,13 +2420,11 @@ asmlinkage void svm_vmexit_handler(struc
/*
* Before doing anything else, we need to sync up the VLAPIC's TPR with
- * SVM's vTPR if CR8 writes are currently disabled. It's OK if the
- * guest doesn't touch the CR8 (e.g. 32-bit Windows) because we update
- * the vTPR on MMIO writes to the TPR
+ * SVM's vTPR. It's OK if the guest doesn't touch CR8 (e.g. 32-bit Windows)
+ * because we update the vTPR on MMIO writes to the TPR.
*/
- if ( !(vmcb->cr_intercepts & CR_INTERCEPT_CR8_WRITE) )
- vlapic_set_reg(vcpu_vlapic(v), APIC_TASKPRI,
- (vmcb->vintr.fields.tpr & 0x0F) << 4);
+ vlapic_set_reg(vcpu_vlapic(v), APIC_TASKPRI,
+ (vmcb->vintr.fields.tpr & 0x0F) << 4);
exit_reason = vmcb->exitcode;
@@ -2637,6 +2631,10 @@ asmlinkage void svm_vmexit_handler(struc
domain_crash(v->domain);
break;
}
+
+ /* The exit may have updated the TPR: reflect this in the hardware vtpr */
+ vmcb->vintr.fields.tpr =
+ (vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xFF) >> 4;
}
asmlinkage void svm_trace_vmentry(void)
diff -r 17820aa1b2c0 -r 7f8a28149131 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Fri Dec 14 11:58:37 2007 +0000
+++ b/xen/arch/x86/hvm/vlapic.c Fri Dec 14 12:05:31 2007 +0000
@@ -576,7 +576,6 @@ static void vlapic_write(struct vcpu *v,
{
case APIC_TASKPRI:
vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
- hvm_update_vtpr(v, (val >> 4) & 0x0f);
break;
case APIC_EOI:
diff -r 17820aa1b2c0 -r 7f8a28149131 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Dec 14 11:58:37 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Dec 14 12:05:31 2007 +0000
@@ -1174,11 +1174,6 @@ static void vmx_inject_exception(
v->arch.hvm_vmx.cpu_cr2 = cr2;
}
-static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
-{
- /* VMX doesn't have a V_TPR field */
-}
-
static int vmx_event_injection_faulted(struct vcpu *v)
{
unsigned int idtv_info_field;
@@ -1230,7 +1225,6 @@ static struct hvm_function_table vmx_fun
.update_host_cr3 = vmx_update_host_cr3,
.update_guest_cr3 = vmx_update_guest_cr3,
.flush_guest_tlbs = vmx_flush_guest_tlbs,
- .update_vtpr = vmx_update_vtpr,
.stts = vmx_stts,
.set_tsc_offset = vmx_set_tsc_offset,
.inject_exception = vmx_inject_exception,
diff -r 17820aa1b2c0 -r 7f8a28149131 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Fri Dec 14 11:58:37 2007 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h Fri Dec 14 12:05:31 2007 +0000
@@ -129,11 +129,6 @@ struct hvm_function_table {
void (*flush_guest_tlbs)(void);
/*
- * Reflect the virtual APIC's value in the guest's V_TPR register
- */
- void (*update_vtpr)(struct vcpu *v, unsigned long value);
-
- /*
* Update specifics of the guest state:
* 1) TS bit in guest cr0
* 2) TSC offset in guest
@@ -228,12 +223,6 @@ hvm_update_host_cr3(struct vcpu *v)
hvm_update_host_cr3(struct vcpu *v)
{
hvm_funcs.update_host_cr3(v);
-}
-
-static inline void
-hvm_update_vtpr(struct vcpu *v, unsigned long value)
-{
- hvm_funcs.update_vtpr(v, value);
}
void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|