# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1197633024 0
# Node ID 966a6d3b74087474df337e00b31cbecf495b442a
# Parent cb0ce96c02defc429ca09e1a33f972f2ee09a61b
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/arch/x86/hvm/hvm.c | 19 +++++++++++++++++++
xen/arch/x86/hvm/svm/svm.c | 20 ++++++++------------
xen/arch/x86/hvm/vlapic.c | 1 -
xen/arch/x86/hvm/vmx/vmx.c | 13 -------------
xen/include/asm-x86/hvm/hvm.h | 19 ++-----------------
5 files changed, 29 insertions(+), 43 deletions(-)
diff -r cb0ce96c02de -r 966a6d3b7408 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/arch/x86/hvm/hvm.c Fri Dec 14 11:50:24 2007 +0000
@@ -1403,6 +1403,25 @@ void hvm_cpuid(unsigned int input, unsig
#endif
break;
}
+}
+
+enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
+{
+ enum hvm_intblk r;
+ ASSERT(v == current);
+
+ r = hvm_funcs.interrupt_blocked(v, intack);
+ if ( r != hvm_intblk_none )
+ return r;
+
+ if ( intack.source == hvm_intsrc_lapic )
+ {
+ uint32_t tpr = vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xF0;
+ if ( (tpr >> 4) >= (intack.vector >> 4) )
+ return hvm_intblk_tpr;
+ }
+
+ return r;
}
static long hvm_grant_table_op(
diff -r cb0ce96c02de -r 966a6d3b7408 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Fri Dec 14 11:50:24 2007 +0000
@@ -443,10 +443,6 @@ static enum hvm_intblk svm_interrupt_blo
if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
return hvm_intblk_rflags_ie;
- if ( (intack.source == hvm_intsrc_lapic) &&
- ((vmcb->vintr.fields.tpr & 0xf) >= (intack.vector >> 4)) )
- return hvm_intblk_tpr;
-
return hvm_intblk_none;
}
@@ -520,13 +516,6 @@ static void svm_flush_guest_tlbs(void)
* next VMRUN. (If ASIDs are disabled, the whole TLB is flushed on
* VMRUN anyway). */
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 void svm_sync_vmcb(struct vcpu *v)
@@ -787,6 +776,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);
@@ -885,7 +878,6 @@ static struct hvm_function_table svm_fun
.update_guest_cr = svm_update_guest_cr,
.update_guest_efer = svm_update_guest_efer,
.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_inject_exception,
@@ -2212,6 +2204,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 cb0ce96c02de -r 966a6d3b7408 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/arch/x86/hvm/vlapic.c Fri Dec 14 11:50:24 2007 +0000
@@ -580,7 +580,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 cb0ce96c02de -r 966a6d3b7408 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Dec 14 11:50:24 2007 +0000
@@ -1011,13 +1011,6 @@ static enum hvm_intblk vmx_interrupt_blo
if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
return hvm_intblk_rflags_ie;
- if ( intack.source == hvm_intsrc_lapic )
- {
- uint32_t tpr = vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xF0;
- if ( (tpr >> 4) >= (intack.vector >> 4) )
- return hvm_intblk_tpr;
- }
-
return hvm_intblk_none;
}
@@ -1118,11 +1111,6 @@ static void vmx_inject_exception(
__restore_debug_registers(curr);
write_debugreg(6, read_debugreg(6) | 0x4000);
}
-}
-
-static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
-{
- /* VMX doesn't have a V_TPR field */
}
static int vmx_event_pending(struct vcpu *v)
@@ -1148,7 +1136,6 @@ static struct hvm_function_table vmx_fun
.update_guest_cr = vmx_update_guest_cr,
.update_guest_efer = vmx_update_guest_efer,
.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 cb0ce96c02de -r 966a6d3b7408 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Fri Dec 14 11:39:02 2007 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h Fri Dec 14 11:50:24 2007 +0000
@@ -106,11 +106,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
@@ -161,12 +156,8 @@ u64 hvm_get_guest_tsc(struct vcpu *v);
#define hvm_long_mode_enabled(v) (v,0)
#endif
-static inline enum hvm_intblk
-hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
-{
- ASSERT(v == current);
- return hvm_funcs.interrupt_blocked(v, intack);
-}
+enum hvm_intblk
+hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack);
static inline int
hvm_guest_x86_mode(struct vcpu *v)
@@ -182,12 +173,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);
}
static inline void hvm_update_guest_cr(struct vcpu *v, unsigned int cr)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|