Hello everyone,
I try to calculate the world switch general-register load/store overhead in ARMv8 KVM recently. I find something weird that the pmccntr_el0 sometimes equals 0.
Here is my code to calculate the save_host_regs macro cycle count:
.macro save_host_regs
// set PMCCFILTR_EL0 to no count EL0 clock cycle
ldr x3, =(PMCCFILTR_EL1_EL2_EL3) // PMCCFILTR_EL1_EL2_EL2 = 0x48000000
msr pmccfiltr_el0, x3
// set PMCR_EL0 to 64-bit overflow and count every 1 cycle
ldr x3, =(PMCR_64V_1) // PMCR_64V_1 = 0x41
orr x3, x3, #RESET_PMCCNTR // RESET_PMCCNTR = 1<<2
msr pmcr_el0, x3
// enable PMCCNTR_EL0
ldr x3, =(ENABLE_PMCCNTR) // ENABLE_PMCCNTR = 1<<31
msr pmcntenset_el0, x3
save_common_regs
push x3, x4
mrs x3, tpidr_el2
mrs x4, pmccntr_el0
str x4, [x3, #DEBUG_CYCLE_COUNTER] // store pmccntr_el0 to vcpu->debug_cycle_counter
pop x3, x4
.endm
Here is save_common_regs macro:
.macro save_common_regs
// x2: base address for cpu context
// x3: tmp register
add x3, x2, #CPU_XREG_OFFSET(19)
stp x19, x20, [x3]
stp x21, x22, [x3, #16]
stp x23, x24, [x3, #32]
stp x25, x26, [x3, #48]
stp x27, x28, [x3, #64]
stp x29, lr, [x3, #80]
mrs x19, sp_el0
mrs x20, elr_el2 // EL1 PC
mrs x21, spsr_el2 // EL1 pstate
stp x19, x20, [x3, #96]
str x21, [x3, #112]
mrs x22, sp_el1
mrs x23, elr_el1
mrs x24, spsr_el1
str x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
str x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
str x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
.endm
I read vcpu->debug_cycle_counter after kvm_call_hyp(__kvm_vcpu_run, vcpu) in arch/arm/kvm/arm.c and the value is 0 sometimes.
Is there any wrong that I set the PMU system register, or any other mistake?
Thank you!
Best regard,
Henrry
I try to calculate the world switch general-register load/store overhead in ARMv8 KVM recently. I find something weird that the pmccntr_el0 sometimes equals 0.
Here is my code to calculate the save_host_regs macro cycle count:
.macro save_host_regs
// set PMCCFILTR_EL0 to no count EL0 clock cycle
ldr x3, =(PMCCFILTR_EL1_EL2_EL3) // PMCCFILTR_EL1_EL2_EL2 = 0x48000000
msr pmccfiltr_el0, x3
// set PMCR_EL0 to 64-bit overflow and count every 1 cycle
ldr x3, =(PMCR_64V_1) // PMCR_64V_1 = 0x41
orr x3, x3, #RESET_PMCCNTR // RESET_PMCCNTR = 1<<2
msr pmcr_el0, x3
// enable PMCCNTR_EL0
ldr x3, =(ENABLE_PMCCNTR) // ENABLE_PMCCNTR = 1<<31
msr pmcntenset_el0, x3
save_common_regs
push x3, x4
mrs x3, tpidr_el2
mrs x4, pmccntr_el0
str x4, [x3, #DEBUG_CYCLE_COUNTER] // store pmccntr_el0 to vcpu->debug_cycle_counter
pop x3, x4
.endm
Here is save_common_regs macro:
.macro save_common_regs
// x2: base address for cpu context
// x3: tmp register
add x3, x2, #CPU_XREG_OFFSET(19)
stp x19, x20, [x3]
stp x21, x22, [x3, #16]
stp x23, x24, [x3, #32]
stp x25, x26, [x3, #48]
stp x27, x28, [x3, #64]
stp x29, lr, [x3, #80]
mrs x19, sp_el0
mrs x20, elr_el2 // EL1 PC
mrs x21, spsr_el2 // EL1 pstate
stp x19, x20, [x3, #96]
str x21, [x3, #112]
mrs x22, sp_el1
mrs x23, elr_el1
mrs x24, spsr_el1
str x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
str x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
str x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
.endm
I read vcpu->debug_cycle_counter after kvm_call_hyp(__kvm_vcpu_run, vcpu) in arch/arm/kvm/arm.c and the value is 0 sometimes.
Is there any wrong that I set the PMU system register, or any other mistake?
Thank you!
Best regard,
Henrry
_______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm