All of lore.kernel.org
 help / color / mirror / Atom feed
* [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

* [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

* Re: [PATCH] svm last branch recording MSR emulation
       [not found] ` <4799D852.9080606-5C7GfCeVMHo@public.gmane.org>
@ 2008-01-27  7:29   ` Avi Kivity
  0 siblings, 0 replies; 3+ messages in thread
From: Avi Kivity @ 2008-01-27  7:29 UTC (permalink / raw)
  To: Markus Rechberger; +Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Markus Rechberger wrote:
> 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>
> @@ -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;
>   

blank line

> +			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:

What is the performance impact (for example, on 
user/test/x86/vmexit.flat when modified to set a bit in debugctl)?

Is it not better to enable LBR virtualization only when the guest 
enables LBR (but avoid it when other bits are enabled)?

Can we disable LBR virtualization when the guest disables LBR?

-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
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/

^ 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.