x86/VPMU: merge vpmu_rdmsr and vpmu_wrmsr

The two routines share most of their logic.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Dietmar Hahn <dietmar.hahn@ts.fujitsu.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
Boris Ostrovsky authored and Jan Beulich committed 2015-07-09 16:51:51 +02:00
1 parent 0d67f25687
commit 45bbd16974
2 files changed
+44 -51

No files matched your search

+32 -49
View File
@@ -100,63 +100,46 @@ void vpmu_lvtpc_update(uint32_t val)
apic_write(APIC_LVTPC, vpmu->hw_lapic_lvtpc);
}
int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, uint64_t supported)
int vpmu_do_msr(unsigned int msr, uint64_t *msr_content,
uint64_t supported, bool_t is_write)
{
struct vcpu *curr = current;
struct vpmu_struct *vpmu;
const struct arch_vpmu_ops *ops;
int ret = 0;
if ( vpmu_mode == XENPMU_MODE_OFF )
return 0;
if ( likely(vpmu_mode == XENPMU_MODE_OFF) )
goto nop;
vpmu = vcpu_vpmu(curr);
if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->do_wrmsr )
{
int ret = vpmu->arch_vpmu_ops->do_wrmsr(msr, msr_content, supported);
ops = vpmu->arch_vpmu_ops;
if ( !ops )
goto nop;
/*
* We may have received a PMU interrupt during WRMSR handling
* and since do_wrmsr may load VPMU context we should save
* (and unload) it again.
*/
if ( !is_hvm_vcpu(curr) && vpmu->xenpmu_data &&
vpmu_is_set(vpmu, VPMU_CACHED) )
{
vpmu_set(vpmu, VPMU_CONTEXT_SAVE);
vpmu->arch_vpmu_ops->arch_vpmu_save(curr, 0);
vpmu_reset(vpmu, VPMU_CONTEXT_SAVE | VPMU_CONTEXT_LOADED);
}
return ret;
}
return 0;
}
int vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content)
{
struct vcpu *curr = current;
struct vpmu_struct *vpmu;
if ( vpmu_mode == XENPMU_MODE_OFF )
{
*msr_content = 0;
return 0;
}
vpmu = vcpu_vpmu(curr);
if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->do_rdmsr )
{
int ret = vpmu->arch_vpmu_ops->do_rdmsr(msr, msr_content);
if ( !is_hvm_vcpu(curr) && vpmu->xenpmu_data &&
vpmu_is_set(vpmu, VPMU_CACHED) )
{
vpmu_set(vpmu, VPMU_CONTEXT_SAVE);
vpmu->arch_vpmu_ops->arch_vpmu_save(curr, 0);
vpmu_reset(vpmu, VPMU_CONTEXT_SAVE | VPMU_CONTEXT_LOADED);
}
return ret;
}
if ( is_write && ops->do_wrmsr )
ret = ops->do_wrmsr(msr, *msr_content, supported);
else if ( !is_write && ops->do_rdmsr )
ret = ops->do_rdmsr(msr, msr_content);
else
goto nop;
/*
* We may have received a PMU interrupt while handling MSR access
* and since do_wr/rdmsr may load VPMU context we should save
* (and unload) it again.
*/
if ( !is_hvm_vcpu(curr) && vpmu->xenpmu_data &&
vpmu_is_set(vpmu, VPMU_CACHED) )
{
vpmu_set(vpmu, VPMU_CONTEXT_SAVE);
ops->arch_vpmu_save(curr, 0);
vpmu_reset(vpmu, VPMU_CONTEXT_SAVE | VPMU_CONTEXT_LOADED);
}
return ret;
nop:
if ( !is_write )
*msr_content = 0;
return 0;
+12 -2
View File
@@ -101,8 +101,8 @@ static inline bool_t vpmu_are_all_set(const struct vpmu_struct *vpmu,
}
void vpmu_lvtpc_update(uint32_t val);
int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, uint64_t supported);
int vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content);
int vpmu_do_msr(unsigned int msr, uint64_t *msr_content,
uint64_t supported, bool_t is_write);
void vpmu_do_interrupt(struct cpu_user_regs *regs);
void vpmu_do_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx);
@@ -112,6 +112,16 @@ void vpmu_save(struct vcpu *v);
int vpmu_load(struct vcpu *v, bool_t from_guest);
void vpmu_dump(struct vcpu *v);
static inline int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content,
uint64_t supported)
{
return vpmu_do_msr(msr, &msr_content, supported, 1);
}
static inline int vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content)
{
return vpmu_do_msr(msr, msr_content, 0, 0);
}
extern int acquire_pmu_ownership(int pmu_ownership);
extern void release_pmu_ownership(int pmu_ownership);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.