* [PATCH] svm last branch recording MSR emulation
@ 2008-01-25 12:38 Markus Rechberger
[not found] ` <4799D852.9080606-5C7GfCeVMHo@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Markus Rechberger @ 2008-01-25 12:38 UTC (permalink / raw)
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
avi-atKUWr5tajBWk0Htik3J/w, muli-7z/5BgaJwgfQT0dZR+AlfA
[-- Attachment #1: Type: text/plain, Size: 266 bytes --]
Hi,
this patch adds support for the lbr MSR emulation, it also enables
support for Windows XP 64bit guests.
Signed-off-by: Joerg Roedel <Joerg.Roedel-5C7GfCeVMHo@public.gmane.org>
Signed-off-by: Markus Rechberger <Markus.Rechberger-5C7GfCeVMHo@public.gmane.org>
[-- Attachment #2: svm.diff --]
[-- Type: text/plain, Size: 1393 bytes --]
--- svm.c.orig 2008-01-23 10:04:14.000000000 +0100
+++ svm.c 2008-01-25 12:52:11.000000000 +0100
@@ -1099,6 +1100,21 @@
case MSR_IA32_SYSENTER_ESP:
*data = svm->vmcb->save.sysenter_esp;
break;
+ case MSR_IA32_DEBUGCTLMSR:
+ *data = svm->vmcb->save.dbgctl;
+ break;
+ case MSR_IA32_LASTBRANCHFROMIP:
+ *data = svm->vmcb->save.br_from;
+ break;
+ case MSR_IA32_LASTBRANCHTOIP:
+ *data = svm->vmcb->save.br_to;
+ break;
+ case MSR_IA32_LASTINTFROMIP:
+ *data = svm->vmcb->save.last_excp_from;
+ break;
+ case MSR_IA32_LASTINTTOIP:
+ *data = svm->vmcb->save.last_excp_to;
+ break;
default:
return kvm_get_msr_common(vcpu, ecx, data);
}
@@ -1171,6 +1187,19 @@
if (data != 0)
goto unhandled;
break;
+ case MSR_IA32_DEBUGCTLMSR:
+ svm->vmcb->save.dbgctl = data;
+ if (svm->vmcb->save.dbgctl && svm_has(SVM_FEATURE_LBRV)) {
+ void *msrpm_va;
+ svm->vmcb->control.lbr_ctl = 1;
+ msrpm_va = page_address(pfn_to_page(msrpm_base >> PAGE_SHIFT));
+ set_msr_interception(msrpm_va, MSR_IA32_DEBUGCTLMSR, 0, 0);
+ set_msr_interception(msrpm_va, MSR_IA32_LASTBRANCHFROMIP, 0, 0);
+ set_msr_interception(msrpm_va, MSR_IA32_LASTBRANCHTOIP, 0, 0);
+ set_msr_interception(msrpm_va, MSR_IA32_LASTINTFROMIP, 0, 0);
+ set_msr_interception(msrpm_va, MSR_IA32_LASTINTTOIP, 0, 0);
+ }
+ break;
default:
unhandled:
return kvm_set_msr_common(vcpu, ecx, data);
[-- Attachment #3: Type: text/plain, Size: 228 bytes --]
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
[-- Attachment #4: Type: text/plain, Size: 186 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH] svm: last branch recording MSR emulation
@ 2007-08-09 12:05 Jan Beulich
0 siblings, 0 replies; 3+ messages in thread
From: Jan Beulich @ 2007-08-09 12:05 UTC (permalink / raw)
To: xen-devel
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Index: 2007-08-08/xen/arch/x86/hvm/svm/svm.c
===================================================================
--- 2007-08-08.orig/xen/arch/x86/hvm/svm/svm.c 2007-08-07 15:00:27.000000000 +0200
+++ 2007-08-08/xen/arch/x86/hvm/svm/svm.c 2007-08-08 11:40:11.000000000 +0200
@@ -68,6 +68,9 @@ static void *hsa[NR_CPUS] __read_mostly;
/* vmcb used for extended host state */
static void *root_vmcb[NR_CPUS] __read_mostly;
+/* SVM feature flags */
+u32 svm_feature_flags;
+
/* hardware assisted paging bits */
extern int opt_hap_enabled;
@@ -991,20 +994,6 @@ static struct hvm_function_table svm_fun
.event_pending = svm_event_pending
};
-static void svm_npt_detect(void)
-{
- u32 eax, ebx, ecx, edx;
-
- /* Check CPUID for nested paging support. */
- cpuid(0x8000000A, &eax, &ebx, &ecx, &edx);
-
- if ( !(edx & 1) && opt_hap_enabled )
- {
- printk("SVM: Nested paging is not supported by this CPU.\n");
- opt_hap_enabled = 0;
- }
-}
-
int start_svm(struct cpuinfo_x86 *c)
{
u32 eax, ecx, edx;
@@ -1027,14 +1016,25 @@ int start_svm(struct cpuinfo_x86 *c)
return 0;
}
+ edx = cpuid_edx(0x8000000A);
+ if ( cpu == 0 )
+ svm_feature_flags = edx;
+ else
+ svm_feature_flags &= edx;
+
+ /* Check for nested paging support. */
+ if ( !cpu_has_npt && opt_hap_enabled )
+ {
+ printk("SVM: Nested paging is not supported by this CPU.\n");
+ opt_hap_enabled = 0;
+ }
+
if ( ((hsa[cpu] = alloc_host_save_area()) == NULL) ||
((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
return 0;
write_efer(read_efer() | EFER_SVME);
- svm_npt_detect();
-
/* Initialize the HSA for this core. */
phys_hsa = (u64) virt_to_maddr(hsa[cpu]);
phys_hsa_lo = (u32) phys_hsa;
@@ -2164,6 +2164,14 @@ static void svm_do_msr_access(
msr_content = 0;
break;
+ case MSR_IA32_DEBUGCTLMSR:
+ case MSR_IA32_LASTBRANCHFROMIP:
+ case MSR_IA32_LASTBRANCHTOIP:
+ case MSR_IA32_LASTINTFROMIP:
+ case MSR_IA32_LASTINTTOIP:
+ msr_content = 0;
+ break;
+
default:
if ( rdmsr_hypervisor_regs(ecx, &eax, &edx) ||
rdmsr_safe(ecx, eax, edx) == 0 )
@@ -2206,6 +2214,24 @@ static void svm_do_msr_access(
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
break;
+ case MSR_IA32_DEBUGCTLMSR:
+ if ( msr_content && cpu_has_lbrv )
+ {
+ vmcb->debugctlmsr = msr_content;
+ vmcb->lbr_control.fields.enable = 1;
+ svm_disable_intercept_for_msr(v->arch.hvm_svm.msrpm,
+ MSR_IA32_DEBUGCTLMSR);
+ svm_disable_intercept_for_msr(v->arch.hvm_svm.msrpm,
+ MSR_IA32_LASTBRANCHFROMIP);
+ svm_disable_intercept_for_msr(v->arch.hvm_svm.msrpm,
+ MSR_IA32_LASTBRANCHTOIP);
+ svm_disable_intercept_for_msr(v->arch.hvm_svm.msrpm,
+ MSR_IA32_LASTINTFROMIP);
+ svm_disable_intercept_for_msr(v->arch.hvm_svm.msrpm,
+ MSR_IA32_LASTINTTOIP);
+ }
+ break;
+
default:
switch ( long_mode_do_msr_write(regs) )
{
Index: 2007-08-08/xen/arch/x86/hvm/svm/vmcb.c
===================================================================
--- 2007-08-08.orig/xen/arch/x86/hvm/svm/vmcb.c 2007-08-06 15:08:40.000000000 +0200
+++ 2007-08-08/xen/arch/x86/hvm/svm/vmcb.c 2007-08-08 11:40:11.000000000 +0200
@@ -80,30 +80,6 @@ struct host_save_area *alloc_host_save_a
return hsa;
}
-static void disable_intercept_for_msr(char *msr_bitmap, u32 msr)
-{
- /*
- * See AMD64 Programmers Manual, Vol 2, Section 15.10 (MSR-Bitmap Address).
- */
- if ( msr <= 0x1fff )
- {
- __clear_bit(msr*2, msr_bitmap + 0x000);
- __clear_bit(msr*2+1, msr_bitmap + 0x000);
- }
- else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
- {
- msr &= 0x1fff;
- __clear_bit(msr*2, msr_bitmap + 0x800);
- __clear_bit(msr*2+1, msr_bitmap + 0x800);
- }
- else if ( (msr >= 0xc001000) && (msr <= 0xc0011fff) )
- {
- msr &= 0x1fff;
- __clear_bit(msr*2, msr_bitmap + 0x1000);
- __clear_bit(msr*2+1, msr_bitmap + 0x1000);
- }
-}
-
static int construct_vmcb(struct vcpu *v)
{
struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
@@ -138,16 +114,16 @@ static int construct_vmcb(struct vcpu *v
return -ENOMEM;
memset(arch_svm->msrpm, 0xff, MSRPM_SIZE);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_FS_BASE);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_GS_BASE);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_SHADOW_GS_BASE);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_CSTAR);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_LSTAR);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_STAR);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_SYSCALL_MASK);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_IA32_SYSENTER_CS);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_IA32_SYSENTER_ESP);
- disable_intercept_for_msr((char *)arch_svm->msrpm, MSR_IA32_SYSENTER_EIP);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_FS_BASE);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_GS_BASE);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_SHADOW_GS_BASE);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_CSTAR);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_LSTAR);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_STAR);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_SYSCALL_MASK);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_IA32_SYSENTER_CS);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_IA32_SYSENTER_ESP);
+ svm_disable_intercept_for_msr(arch_svm->msrpm, MSR_IA32_SYSENTER_EIP);
vmcb->msrpm_base_pa = (u64)virt_to_maddr(arch_svm->msrpm);
vmcb->iopm_base_pa = (u64)virt_to_maddr(hvm_io_bitmap);
Index: 2007-08-08/xen/include/asm-x86/hvm/svm/svm.h
===================================================================
--- 2007-08-08.orig/xen/include/asm-x86/hvm/svm/svm.h 2007-07-10 09:40:06.000000000 +0200
+++ 2007-08-08/xen/include/asm-x86/hvm/svm/svm.h 2007-08-08 11:43:48.000000000 +0200
@@ -47,4 +47,16 @@ extern void svm_dump_vmcb(const char *fr
#define SVM_REG_R14 (14)
#define SVM_REG_R15 (15)
+extern u32 svm_feature_flags;
+
+#define SVM_FEATURE_NPT 0
+#define SVM_FEATURE_LBRV 1
+#define SVM_FEATURE_SVML 2
+#define SVM_FEATURE_NRIPS 3
+
+#define cpu_has_npt test_bit(SVM_FEATURE_NPT, &svm_feature_flags)
+#define cpu_has_lbrv test_bit(SVM_FEATURE_LBRV, &svm_feature_flags)
+#define cpu_has_svml test_bit(SVM_FEATURE_SVML, &svm_feature_flags)
+#define cpu_has_nrips test_bit(SVM_FEATURE_NRIPS, &svm_feature_flags)
+
#endif /* __ASM_X86_HVM_SVM_H__ */
Index: 2007-08-08/xen/include/asm-x86/hvm/svm/vmcb.h
===================================================================
--- 2007-08-08.orig/xen/include/asm-x86/hvm/svm/vmcb.h 2007-08-06 15:08:41.000000000 +0200
+++ 2007-08-08/xen/include/asm-x86/hvm/svm/vmcb.h 2007-08-08 11:40:11.000000000 +0200
@@ -355,6 +355,15 @@ typedef union
} fields;
} __attribute__ ((packed)) ioio_info_t;
+typedef union
+{
+ u64 bytes;
+ struct
+ {
+ u64 enable:1;
+ } fields;
+} __attribute__ ((packed)) lbrctrl_t;
+
struct vmcb_struct {
u32 cr_intercepts; /* offset 0x00 */
u32 dr_intercepts; /* offset 0x04 */
@@ -383,7 +392,8 @@ struct vmcb_struct {
u64 res08[2];
eventinj_t eventinj; /* offset 0xA8 */
u64 h_cr3; /* offset 0xB0 */
- u64 res09[105]; /* offset 0xB8 pad to save area */
+ lbrctrl_t lbr_control; /* offset 0xB8 */
+ u64 res09[104]; /* offset 0xC0 pad to save area */
svm_segment_register_t es; /* offset 1024 */
svm_segment_register_t cs;
@@ -426,7 +436,12 @@ struct vmcb_struct {
u64 pdpe2;
u64 pdpe3;
u64 g_pat;
- u64 res16[50];
+ u64 debugctlmsr;
+ u64 lastbranchfromip;
+ u64 lastbranchtoip;
+ u64 lastintfromip;
+ u64 lastinttoip;
+ u64 res16[45];
u64 res17[128];
u64 res18[128];
} __attribute__ ((packed));
@@ -437,7 +452,7 @@ struct arch_svm_struct {
u64 vmcb_pa;
u64 asid_generation; /* ASID tracking, moved here to
prevent cacheline misses. */
- u32 *msrpm;
+ char *msrpm;
int launch_core;
bool_t vmcb_in_sync; /* VMCB sync'ed with VMSAVE? */
unsigned long cpu_shadow_cr0; /* Guest value for CR0 */
@@ -447,6 +462,30 @@ struct arch_svm_struct {
unsigned long cpu_cr3;
};
+static inline void svm_disable_intercept_for_msr(char *msr_bitmap, u32 msr)
+{
+ /*
+ * See AMD64 Programmers Manual, Vol 2, Section 15.10 (MSR-Bitmap Address).
+ */
+ if ( msr <= 0x1fff )
+ {
+ __clear_bit(msr*2, msr_bitmap + 0x000);
+ __clear_bit(msr*2+1, msr_bitmap + 0x000);
+ }
+ else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
+ {
+ msr &= 0x1fff;
+ __clear_bit(msr*2, msr_bitmap + 0x800);
+ __clear_bit(msr*2+1, msr_bitmap + 0x800);
+ }
+ else if ( (msr >= 0xc001000) && (msr <= 0xc0011fff) )
+ {
+ msr &= 0x1fff;
+ __clear_bit(msr*2, msr_bitmap + 0x1000);
+ __clear_bit(msr*2+1, msr_bitmap + 0x1000);
+ }
+}
+
struct vmcb_struct *alloc_vmcb(void);
struct host_save_area *alloc_host_save_area(void);
void free_vmcb(struct vmcb_struct *vmcb);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-01-27 7:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-25 12:38 [PATCH] svm last branch recording MSR emulation Markus Rechberger
[not found] ` <4799D852.9080606-5C7GfCeVMHo@public.gmane.org>
2008-01-27 7:29 ` Avi Kivity
-- strict thread matches above, loose matches on Subject: below --
2007-08-09 12:05 [PATCH] svm: " Jan Beulich
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.