117 lines
3.8 KiB
Diff
117 lines
3.8 KiB
Diff
|
# HG changeset patch
|
||
|
# User Travis Betak <travis.betak@amd.com>
|
||
|
# Date 1168370530 21600
|
||
|
# Node ID e822926dd62492282e51c5847a8d85a3d22dda1d
|
||
|
# Parent d401cb96d8a0da5febe737b86f453a88f1f45bb7
|
||
|
[HVM][SVM] Updated the SVM V_TPR register on MMIO writes to the VLAPIC TPR
|
||
|
|
||
|
The SVM architecture includes a virtual TPR register. This patch
|
||
|
updates this register on MMIO writes to the HVM Virtual APIC.
|
||
|
|
||
|
VT does not have this register as far as I know so a stub is added in
|
||
|
the VT code.
|
||
|
|
||
|
Signed-off-by: Travis Betak <travis.betak@amd.com>
|
||
|
|
||
|
Index: xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c
|
||
|
===================================================================
|
||
|
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/svm/svm.c
|
||
|
+++ xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c
|
||
|
@@ -503,6 +503,13 @@ void svm_update_guest_cr3(struct vcpu *v
|
||
|
v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
|
||
|
}
|
||
|
|
||
|
+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;
|
||
|
+}
|
||
|
+
|
||
|
unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
|
||
|
{
|
||
|
switch ( num )
|
||
|
@@ -894,6 +901,8 @@ int start_svm(void)
|
||
|
hvm_funcs.update_host_cr3 = svm_update_host_cr3;
|
||
|
hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
|
||
|
|
||
|
+ hvm_funcs.update_vtpr = svm_update_vtpr;
|
||
|
+
|
||
|
hvm_funcs.stts = svm_stts;
|
||
|
hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
|
||
|
|
||
|
@@ -1956,6 +1965,7 @@ static int mov_to_cr(int gpreg, int cr,
|
||
|
|
||
|
case 8:
|
||
|
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
|
||
|
+ vmcb->vintr.fields.tpr = value & 0x0F;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
Index: xen-3.0.4-testing/xen/arch/x86/hvm/vlapic.c
|
||
|
===================================================================
|
||
|
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/vlapic.c
|
||
|
+++ xen-3.0.4-testing/xen/arch/x86/hvm/vlapic.c
|
||
|
@@ -631,6 +631,7 @@ 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:
|
||
|
Index: xen-3.0.4-testing/xen/arch/x86/hvm/vmx/vmx.c
|
||
|
===================================================================
|
||
|
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
|
||
|
+++ xen-3.0.4-testing/xen/arch/x86/hvm/vmx/vmx.c
|
||
|
@@ -738,6 +738,11 @@ 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 */
|
||
|
+}
|
||
|
+
|
||
|
/* Setup HVM interfaces */
|
||
|
static void vmx_setup_hvm_funcs(void)
|
||
|
{
|
||
|
@@ -763,6 +768,8 @@ static void vmx_setup_hvm_funcs(void)
|
||
|
hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
|
||
|
hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
|
||
|
|
||
|
+ hvm_funcs.update_vtpr = vmx_update_vtpr;
|
||
|
+
|
||
|
hvm_funcs.stts = vmx_stts;
|
||
|
hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
|
||
|
|
||
|
Index: xen-3.0.4-testing/xen/include/asm-x86/hvm/hvm.h
|
||
|
===================================================================
|
||
|
--- xen-3.0.4-testing.orig/xen/include/asm-x86/hvm/hvm.h
|
||
|
+++ xen-3.0.4-testing/xen/include/asm-x86/hvm/hvm.h
|
||
|
@@ -108,6 +108,11 @@ struct hvm_function_table {
|
||
|
void (*update_guest_cr3)(struct vcpu *v);
|
||
|
|
||
|
/*
|
||
|
+ * 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
|
||
|
@@ -193,6 +198,12 @@ 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);
|
||
|
|
||
|
void hvm_hypercall_page_initialise(struct domain *d,
|