In generic code kvm_setup_async_pf() checks the async_pf size by: if (vcpu->async_pf.queued >= ASYNC_PF_PER_VCPU) While in x86, we define the array as: gfn_t gfns[roundup_pow_of_two(ASYNC_PF_PER_VCPU)]; And each time we compare the index like this: i < roundup_pow_of_two(ASYNC_PF_PER_VCPU) The behavior is correct now, while not consistent with generic code. As for now ASYNC_PF_PER_VCPU is defined as 64, which is already a power of 2. This patch introduces ASYNC_PF_PER_VCPU_ORDER and rewrite the definition as: #define ASYNC_PF_PER_VCPU_ORDER 6 #define ASYNC_PF_PER_VCPU (1 << ASYNC_PF_PER_VCPU_ORDER) By doing so, we can remove the roundup_pow_of_two()/order_base_2() helpers when access async_pf on x86. And this make code consistent between generic and x86. Signed-off-by: Wei Yang <richardw.yang@xxxxxxxxxxxxxxx> --- v2: Radim suggest to change platform code instead of generic code. --- arch/x86/include/asm/kvm_host.h | 5 +++-- arch/x86/kvm/x86.c | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index fbda5a917c5b..570ddc74a4e5 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -134,7 +134,8 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level) #define KVM_NR_FIXED_MTRR_REGION 88 #define KVM_NR_VAR_MTRR 8 -#define ASYNC_PF_PER_VCPU 64 +#define ASYNC_PF_PER_VCPU_ORDER 6 +#define ASYNC_PF_PER_VCPU (1 << ASYNC_PF_PER_VCPU_ORDER) enum kvm_reg { VCPU_REGS_RAX = 0, @@ -726,7 +727,7 @@ struct kvm_vcpu_arch { struct { bool halted; - gfn_t gfns[roundup_pow_of_two(ASYNC_PF_PER_VCPU)]; + gfn_t gfns[ASYNC_PF_PER_VCPU]; struct gfn_to_hva_cache data; u64 msr_val; u32 id; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d02937760c3b..ff5296cbc9da 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -218,7 +218,7 @@ static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt); static inline void kvm_async_pf_hash_reset(struct kvm_vcpu *vcpu) { int i; - for (i = 0; i < roundup_pow_of_two(ASYNC_PF_PER_VCPU); i++) + for (i = 0; i < ASYNC_PF_PER_VCPU; i++) vcpu->arch.apf.gfns[i] = ~0; } @@ -9488,12 +9488,12 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) static inline u32 kvm_async_pf_hash_fn(gfn_t gfn) { - return hash_32(gfn & 0xffffffff, order_base_2(ASYNC_PF_PER_VCPU)); + return hash_32(gfn & 0xffffffff, ASYNC_PF_PER_VCPU_ORDER); } static inline u32 kvm_async_pf_next_probe(u32 key) { - return (key + 1) & (roundup_pow_of_two(ASYNC_PF_PER_VCPU) - 1); + return (key + 1) & (ASYNC_PF_PER_VCPU - 1); } static void kvm_add_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) @@ -9511,7 +9511,7 @@ static u32 kvm_async_pf_gfn_slot(struct kvm_vcpu *vcpu, gfn_t gfn) int i; u32 key = kvm_async_pf_hash_fn(gfn); - for (i = 0; i < roundup_pow_of_two(ASYNC_PF_PER_VCPU) && + for (i = 0; i < ASYNC_PF_PER_VCPU && (vcpu->arch.apf.gfns[key] != gfn && vcpu->arch.apf.gfns[key] != ~0); i++) key = kvm_async_pf_next_probe(key); -- 2.19.1