# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID e256d8ccd6aca34340d71bbe47033e4dc7abd67f
# Parent 899836e04387bec0fc9f7c080e03ca9c4b9b11fd
[HVM] Fix oprofile for HVM guests.
Signed-off-by: Tom Woller <thomas.woller@xxxxxxx>
Signed-off-by: Mats Petersson <mats.petersson@xxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/svm/x86_32/exits.S | 2 +
xen/arch/x86/hvm/svm/x86_64/exits.S | 2 +
xen/arch/x86/oprofile/op_model_athlon.c | 28 +++++++++++++++++-------
xen/arch/x86/oprofile/op_model_p4.c | 10 ++------
xen/arch/x86/oprofile/op_model_ppro.c | 10 ++------
xen/arch/x86/oprofile/xenoprof.c | 37 +++++++++++++++++++++-----------
6 files changed, 55 insertions(+), 34 deletions(-)
diff -r 899836e04387 -r e256d8ccd6ac xen/arch/x86/hvm/svm/x86_32/exits.S
--- a/xen/arch/x86/hvm/svm/x86_32/exits.S Fri Oct 20 10:11:45 2006 +0100
+++ b/xen/arch/x86/hvm/svm/x86_32/exits.S Fri Oct 20 10:34:24 2006 +0100
@@ -126,6 +126,8 @@ ENTRY(svm_asm_do_launch)
HVM_SAVE_ALL_NOSEGREGS
STGI
+.globl svm_stgi_label;
+svm_stgi_label:
movl %esp,%eax
push %eax
call svm_vmexit_handler
diff -r 899836e04387 -r e256d8ccd6ac xen/arch/x86/hvm/svm/x86_64/exits.S
--- a/xen/arch/x86/hvm/svm/x86_64/exits.S Fri Oct 20 10:11:45 2006 +0100
+++ b/xen/arch/x86/hvm/svm/x86_64/exits.S Fri Oct 20 10:34:24 2006 +0100
@@ -144,6 +144,8 @@ ENTRY(svm_asm_do_launch)
VMLOAD
STGI
+.globl svm_stgi_label;
+svm_stgi_label:
movq %rsp,%rdi
call svm_vmexit_handler
jmp svm_asm_do_resume
diff -r 899836e04387 -r e256d8ccd6ac xen/arch/x86/oprofile/op_model_athlon.c
--- a/xen/arch/x86/oprofile/op_model_athlon.c Fri Oct 20 10:11:45 2006 +0100
+++ b/xen/arch/x86/oprofile/op_model_athlon.c Fri Oct 20 10:34:24 2006 +0100
@@ -18,6 +18,7 @@
#include <xen/sched.h>
#include <asm/regs.h>
#include <asm/current.h>
+#include <asm/hvm/support.h>
#include "op_x86_model.h"
#include "op_counter.h"
@@ -44,7 +45,11 @@ static unsigned long reset_value[NUM_COU
extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
int mode, int event);
-
+extern int xenoprofile_get_mode(struct vcpu *v,
+ struct cpu_user_regs * const regs);
+
+extern char svm_stgi_label[];
+
static void athlon_fill_in_addresses(struct op_msrs * const msrs)
{
msrs->counters[0].addr = MSR_K7_PERFCTR0;
@@ -97,10 +102,9 @@ static void athlon_setup_ctrs(struct op_
}
}
-
static int athlon_check_ctrs(unsigned int const cpu,
- struct op_msrs const * const msrs,
- struct cpu_user_regs * const regs)
+ struct op_msrs const * const msrs,
+ struct cpu_user_regs * const regs)
{
unsigned int low, high;
@@ -108,11 +112,19 @@ static int athlon_check_ctrs(unsigned in
int ovf = 0;
unsigned long eip = regs->eip;
int mode = 0;
+ struct vcpu *v = current;
+ struct cpu_user_regs tmp_regs;
- if (guest_kernel_mode(current, regs))
- mode = 1;
- else if (ring_0(regs))
- mode = 2;
+ if (!guest_mode(regs) &&
+ (regs->eip == (unsigned long)svm_stgi_label)) {
+ /* SVM guest was running when NMI occurred */
+ hvm_store_cpu_guest_regs(v, &tmp_regs, NULL);
+ eip = tmp_regs.eip;
+ mode = xenoprofile_get_mode(v, &tmp_regs);
+ } else {
+ eip = regs->eip;
+ mode = xenoprofile_get_mode(v, regs);
+ }
for (i = 0 ; i < NUM_COUNTERS; ++i) {
CTR_READ(low, high, msrs, i);
diff -r 899836e04387 -r e256d8ccd6ac xen/arch/x86/oprofile/op_model_p4.c
--- a/xen/arch/x86/oprofile/op_model_p4.c Fri Oct 20 10:11:45 2006 +0100
+++ b/xen/arch/x86/oprofile/op_model_p4.c Fri Oct 20 10:34:24 2006 +0100
@@ -620,9 +620,10 @@ static void p4_setup_ctrs(struct op_msrs
}
}
-
extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
int mode, int event);
+extern int xenoprofile_get_mode(struct vcpu *v,
+ struct cpu_user_regs * const regs);
static int p4_check_ctrs(unsigned int const cpu,
struct op_msrs const * const msrs,
@@ -632,12 +633,7 @@ static int p4_check_ctrs(unsigned int co
int i;
int ovf = 0;
unsigned long eip = regs->eip;
- int mode = 0;
-
- if (guest_kernel_mode(current, regs))
- mode = 1;
- else if (ring_0(regs))
- mode = 2;
+ int mode = xenoprofile_get_mode(current, regs);
stag = get_stagger();
diff -r 899836e04387 -r e256d8ccd6ac xen/arch/x86/oprofile/op_model_ppro.c
--- a/xen/arch/x86/oprofile/op_model_ppro.c Fri Oct 20 10:11:45 2006 +0100
+++ b/xen/arch/x86/oprofile/op_model_ppro.c Fri Oct 20 10:34:24 2006 +0100
@@ -88,9 +88,10 @@ static void ppro_setup_ctrs(struct op_ms
}
}
-
extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
int mode, int event);
+extern int xenoprofile_get_mode(struct vcpu *v,
+ struct cpu_user_regs * const regs);
static int ppro_check_ctrs(unsigned int const cpu,
struct op_msrs const * const msrs,
@@ -100,13 +101,8 @@ static int ppro_check_ctrs(unsigned int
int i;
int ovf = 0;
unsigned long eip = regs->eip;
- int mode = 0;
+ int mode = xenoprofile_get_mode(current, regs);
- if ( guest_kernel_mode(current, regs) )
- mode = 1;
- else if ( ring_0(regs) )
- mode = 2;
-
for (i = 0 ; i < NUM_COUNTERS; ++i) {
CTR_READ(low, high, msrs, i);
if (CTR_OVERFLOWED(low)) {
diff -r 899836e04387 -r e256d8ccd6ac xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c Fri Oct 20 10:11:45 2006 +0100
+++ b/xen/arch/x86/oprofile/xenoprof.c Fri Oct 20 10:34:24 2006 +0100
@@ -7,6 +7,7 @@
#include <xen/guest_access.h>
#include <xen/sched.h>
#include <public/xenoprof.h>
+#include <asm/hvm/support.h>
#include "op_counter.h"
@@ -98,7 +99,7 @@ static void xenoprof_reset_buf(struct do
}
}
-char *alloc_xenoprof_buf(struct domain *d, int npages)
+static char *alloc_xenoprof_buf(struct domain *d, int npages)
{
char *rawbuf;
int i, order;
@@ -121,7 +122,8 @@ char *alloc_xenoprof_buf(struct domain *
return rawbuf;
}
-int alloc_xenoprof_struct(struct domain *d, int max_samples, int is_passive)
+static int alloc_xenoprof_struct(
+ struct domain *d, int max_samples, int is_passive)
{
struct vcpu *v;
int nvcpu, npages, bufsize, max_bufsize;
@@ -207,7 +209,7 @@ void free_xenoprof_pages(struct domain *
d->xenoprof = NULL;
}
-int active_index(struct domain *d)
+static int active_index(struct domain *d)
{
int i;
@@ -218,7 +220,7 @@ int active_index(struct domain *d)
return -1;
}
-int set_active(struct domain *d)
+static int set_active(struct domain *d)
{
int ind;
struct xenoprof *x;
@@ -239,7 +241,7 @@ int set_active(struct domain *d)
return 0;
}
-int reset_active(struct domain *d)
+static int reset_active(struct domain *d)
{
int ind;
struct xenoprof *x;
@@ -265,7 +267,7 @@ int reset_active(struct domain *d)
return 0;
}
-void reset_passive(struct domain *d)
+static void reset_passive(struct domain *d)
{
struct xenoprof *x;
@@ -281,7 +283,7 @@ void reset_passive(struct domain *d)
return;
}
-void reset_active_list(void)
+static void reset_active_list(void)
{
int i;
@@ -297,7 +299,7 @@ void reset_active_list(void)
activated = 0;
}
-void reset_passive_list(void)
+static void reset_passive_list(void)
{
int i;
@@ -311,7 +313,7 @@ void reset_passive_list(void)
pdomains = 0;
}
-int add_active_list (domid_t domid)
+static int add_active_list(domid_t domid)
{
struct domain *d;
@@ -329,7 +331,7 @@ int add_active_list (domid_t domid)
return 0;
}
-int add_passive_list(XEN_GUEST_HANDLE(void) arg)
+static int add_passive_list(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_passive passive;
struct domain *d;
@@ -436,7 +438,7 @@ void xenoprof_log_event(
}
}
-int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
+static int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_init xenoprof_init;
int ret;
@@ -458,7 +460,7 @@ int xenoprof_op_init(XEN_GUEST_HANDLE(vo
return 0;
}
-int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg)
+static int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_get_buffer xenoprof_get_buffer;
struct domain *d = current->domain;
@@ -694,6 +696,17 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
return ret;
}
+int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs)
+{
+ if ( !guest_mode(regs) )
+ return 2;
+
+ if ( hvm_guest(v) )
+ return ((regs->cs & 3) != 3);
+
+ return guest_kernel_mode(v, regs);
+}
+
/*
* Local variables:
* mode: C
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|