diff -r e6f751ed8e38 xen/arch/x86/hvm/Makefile --- a/xen/arch/x86/hvm/Makefile Tue Mar 09 10:00:37 2010 +0000 +++ b/xen/arch/x86/hvm/Makefile Tue May 11 14:46:48 2010 +0200 @@ -21,3 +21,4 @@ obj-y += vmsi.o obj-y += vmsi.o obj-y += vpic.o obj-y += vpt.o +obj-y += vpmu.o \ No newline at end of file diff -r e6f751ed8e38 xen/arch/x86/hvm/vmx/Makefile --- a/xen/arch/x86/hvm/vmx/Makefile Tue Mar 09 10:00:37 2010 +0000 +++ b/xen/arch/x86/hvm/vmx/Makefile Tue May 11 14:46:48 2010 +0200 @@ -3,5 +3,4 @@ obj-y += realmode.o obj-y += realmode.o obj-y += vmcs.o obj-y += vmx.o -obj-y += vpmu.o obj-y += vpmu_core2.o diff -r e6f751ed8e38 xen/arch/x86/hvm/vmx/vpmu_core2.c --- a/xen/arch/x86/hvm/vmx/vpmu_core2.c Tue Mar 09 10:00:37 2010 +0000 +++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c Tue May 11 14:46:48 2010 +0200 @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include u32 core2_counters_msr[] = { diff -r e6f751ed8e38 xen/arch/x86/oprofile/op_model_ppro.c --- a/xen/arch/x86/oprofile/op_model_ppro.c Tue Mar 09 10:00:37 2010 +0000 +++ b/xen/arch/x86/oprofile/op_model_ppro.c Tue May 11 14:46:48 2010 +0200 @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include "op_x86_model.h" diff -r e6f751ed8e38 xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Tue Mar 09 10:00:37 2010 +0000 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Tue May 11 14:46:48 2010 +0200 @@ -21,7 +21,7 @@ #include #include -#include +#include extern void start_vmx(void); extern void vmcs_dump_vcpu(struct vcpu *v); diff -r e6f751ed8e38 xen/arch/x86/hvm/vpmu.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/hvm/vpmu.c Tue May 11 14:46:48 2010 +0200 @@ -0,0 +1,119 @@ +/* + * vpmu.c: PMU virtualization for HVM domain. + * + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Author: Haitao Shan + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int __read_mostly opt_vpmu_enabled; +boolean_param("vpmu", opt_vpmu_enabled); + +int vpmu_do_wrmsr(struct cpu_user_regs *regs) +{ + struct vpmu_struct *vpmu = vcpu_vpmu(current); + + if ( vpmu->arch_vpmu_ops ) + return vpmu->arch_vpmu_ops->do_wrmsr(regs); + return 0; +} + +int vpmu_do_rdmsr(struct cpu_user_regs *regs) +{ + struct vpmu_struct *vpmu = vcpu_vpmu(current); + + if ( vpmu->arch_vpmu_ops ) + return vpmu->arch_vpmu_ops->do_rdmsr(regs); + return 0; +} + +int vpmu_do_interrupt(struct cpu_user_regs *regs) +{ + struct vpmu_struct *vpmu = vcpu_vpmu(current); + + if ( vpmu->arch_vpmu_ops ) + return vpmu->arch_vpmu_ops->do_interrupt(regs); + return 0; +} + +void vpmu_save(struct vcpu *v) +{ + struct vpmu_struct *vpmu = vcpu_vpmu(v); + + if ( vpmu->arch_vpmu_ops ) + vpmu->arch_vpmu_ops->arch_vpmu_save(v); +} + +void vpmu_load(struct vcpu *v) +{ + struct vpmu_struct *vpmu = vcpu_vpmu(v); + + if ( vpmu->arch_vpmu_ops ) + vpmu->arch_vpmu_ops->arch_vpmu_load(v); +} + +extern struct arch_vpmu_ops core2_vpmu_ops; +void vpmu_initialise(struct vcpu *v) +{ + struct vpmu_struct *vpmu = vcpu_vpmu(v); + + if ( !opt_vpmu_enabled ) + return; + + if ( vpmu->flags & VPMU_CONTEXT_ALLOCATED ) + vpmu_destroy(v); + + if ( current_cpu_data.x86 == 6 ) + { + switch ( current_cpu_data.x86_model ) + { + case 15: + case 23: + case 26: + case 29: + vpmu->arch_vpmu_ops = &core2_vpmu_ops; + break; + } + } + + if ( vpmu->arch_vpmu_ops != NULL ) + { + vpmu->flags = 0; + vpmu->context = NULL; + vpmu->arch_vpmu_ops->arch_vpmu_initialise(v); + } +} + +void vpmu_destroy(struct vcpu *v) +{ + struct vpmu_struct *vpmu = vcpu_vpmu(v); + + if ( vpmu->arch_vpmu_ops ) + vpmu->arch_vpmu_ops->arch_vpmu_destroy(v); +} + diff -r e6f751ed8e38 xen/include/asm-x86/hvm/vpmu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/hvm/vpmu.h Tue May 11 14:46:48 2010 +0200 @@ -0,0 +1,81 @@ +/* + * vpmu.h: PMU virtualization for HVM domain. + * + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Author: Haitao Shan + */ + +#ifndef __ASM_X86_HVM_VPMU_H_ +#define __ASM_X86_HVM_VPMU_H_ + +#define msraddr_to_bitpos(x) (((x)&0xffff) + ((x)>>31)*0x2000) +#define vcpu_vpmu(vcpu) (&(vcpu)->arch.hvm_vcpu.u.vmx.vpmu) +#define vpmu_vcpu(vpmu) (container_of((vpmu), struct vcpu, \ + arch.hvm_vcpu.u.vmx.vpmu)) +#define vpmu_domain(vpmu) (vpmu_vcpu(vpmu)->domain) + +#define MSR_TYPE_COUNTER 0 +#define MSR_TYPE_CTRL 1 +#define MSR_TYPE_GLOBAL 2 +#define MSR_TYPE_ARCH_COUNTER 3 +#define MSR_TYPE_ARCH_CTRL 4 + +struct pmumsr { + unsigned int num; + u32 *msr; +}; + +struct msr_load_store_entry { + u32 msr_index; + u32 msr_reserved; + u64 msr_data; +}; + +/* Arch specific operations shared by all vpmus */ +struct arch_vpmu_ops { + int (*do_wrmsr)(struct cpu_user_regs *regs); + int (*do_rdmsr)(struct cpu_user_regs *regs); + int (*do_interrupt)(struct cpu_user_regs *regs); + void (*arch_vpmu_initialise)(struct vcpu *v); + void (*arch_vpmu_destroy)(struct vcpu *v); + void (*arch_vpmu_save)(struct vcpu *v); + void (*arch_vpmu_load)(struct vcpu *v); +}; + +struct vpmu_struct { + u32 flags; + void *context; + struct arch_vpmu_ops *arch_vpmu_ops; +}; + +#define VPMU_CONTEXT_ALLOCATED 0x1 +#define VPMU_CONTEXT_LOADED 0x2 +#define VPMU_RUNNING 0x4 +#define PASSIVE_DOMAIN_ALLOCATED 0x8 +int vpmu_do_wrmsr(struct cpu_user_regs *regs); +int vpmu_do_rdmsr(struct cpu_user_regs *regs); +int vpmu_do_interrupt(struct cpu_user_regs *regs); +void vpmu_initialise(struct vcpu *v); +void vpmu_destroy(struct vcpu *v); +void vpmu_save(struct vcpu *v); +void vpmu_load(struct vcpu *v); + +extern int acquire_pmu_ownership(int pmu_ownership); +extern void release_pmu_ownership(int pmu_ownership); + +#endif /* __ASM_X86_HVM_VPMU_H_*/ + diff -r e6f751ed8e38 xen/include/asm-x86/hvm/vmx/vpmu.h --- a/xen/include/asm-x86/hvm/vmx/vpmu.h Tue Mar 09 10:00:37 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * vpmu.h: PMU virtualization for HVM domain. - * - * Copyright (c) 2007, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Author: Haitao Shan - */ - -#ifndef __ASM_X86_HVM_VPMU_H_ -#define __ASM_X86_HVM_VPMU_H_ - -#define msraddr_to_bitpos(x) (((x)&0xffff) + ((x)>>31)*0x2000) -#define vcpu_vpmu(vcpu) (&(vcpu)->arch.hvm_vcpu.u.vmx.vpmu) -#define vpmu_vcpu(vpmu) (container_of((vpmu), struct vcpu, \ - arch.hvm_vcpu.u.vmx.vpmu)) -#define vpmu_domain(vpmu) (vpmu_vcpu(vpmu)->domain) - -#define MSR_TYPE_COUNTER 0 -#define MSR_TYPE_CTRL 1 -#define MSR_TYPE_GLOBAL 2 -#define MSR_TYPE_ARCH_COUNTER 3 -#define MSR_TYPE_ARCH_CTRL 4 - -struct pmumsr { - unsigned int num; - u32 *msr; -}; - -struct msr_load_store_entry { - u32 msr_index; - u32 msr_reserved; - u64 msr_data; -}; - -/* Arch specific operations shared by all vpmus */ -struct arch_vpmu_ops { - int (*do_wrmsr)(struct cpu_user_regs *regs); - int (*do_rdmsr)(struct cpu_user_regs *regs); - int (*do_interrupt)(struct cpu_user_regs *regs); - void (*arch_vpmu_initialise)(struct vcpu *v); - void (*arch_vpmu_destroy)(struct vcpu *v); - void (*arch_vpmu_save)(struct vcpu *v); - void (*arch_vpmu_load)(struct vcpu *v); -}; - -struct vpmu_struct { - u32 flags; - void *context; - struct arch_vpmu_ops *arch_vpmu_ops; -}; - -#define VPMU_CONTEXT_ALLOCATED 0x1 -#define VPMU_CONTEXT_LOADED 0x2 -#define VPMU_RUNNING 0x4 -#define PASSIVE_DOMAIN_ALLOCATED 0x8 -int vpmu_do_wrmsr(struct cpu_user_regs *regs); -int vpmu_do_rdmsr(struct cpu_user_regs *regs); -int vpmu_do_interrupt(struct cpu_user_regs *regs); -void vpmu_initialise(struct vcpu *v); -void vpmu_destroy(struct vcpu *v); -void vpmu_save(struct vcpu *v); -void vpmu_load(struct vcpu *v); - -extern int acquire_pmu_ownership(int pmu_ownership); -extern void release_pmu_ownership(int pmu_ownership); - -#endif /* __ASM_X86_HVM_VPMU_H_*/ -