lkml.org 
[lkml]   [2024]   [Feb]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH 11/73] KVM: x86: Implement gpc refresh for guest usage
    Date
    From: Hou Wenlong <houwenlong.hwl@antgroup.com>

    PVM uses pfncache to share the PVCS structure between the guest and
    host. The flag of pfncache of PVCS is initialized as
    KVM_GUEST_AND_HOST_USE_PFN because the PVCS is used inside the
    vcpu_run() callback, even in the switcher, where the vcpu is in guest
    mode. However, there is no real usage for GUEST_USE_PFN, so the request
    in mmu_notifier only kicks the vcpu out of guest mode and no refresh is
    done before the next vcpu_run(). Therefore, a new request type is
    introduced to request the refresh, and a new callback is used to service
    the request.

    Suggested-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
    Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com>
    Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
    ---
    arch/x86/include/asm/kvm-x86-ops.h | 1 +
    arch/x86/include/asm/kvm_host.h | 3 +++
    arch/x86/kvm/mmu/mmu.c | 1 +
    arch/x86/kvm/x86.c | 3 +++
    include/linux/kvm_host.h | 10 ++++++++++
    virt/kvm/pfncache.c | 2 +-
    6 files changed, 19 insertions(+), 1 deletion(-)

    diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
    index 32e5473b499d..0d9b21988943 100644
    --- a/arch/x86/include/asm/kvm-x86-ops.h
    +++ b/arch/x86/include/asm/kvm-x86-ops.h
    @@ -94,6 +94,7 @@ KVM_X86_OP_OPTIONAL_RET0(set_identity_map_addr)
    KVM_X86_OP_OPTIONAL_RET0(get_mt_mask)
    KVM_X86_OP(load_mmu_pgd)
    KVM_X86_OP_OPTIONAL_RET0(disallowed_va)
    +KVM_X86_OP_OPTIONAL(vcpu_gpc_refresh);
    KVM_X86_OP(has_wbinvd_exit)
    KVM_X86_OP(get_l2_tsc_offset)
    KVM_X86_OP(get_l2_tsc_multiplier)
    diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
    index d17d85106d6f..9223d34cb8e3 100644
    --- a/arch/x86/include/asm/kvm_host.h
    +++ b/arch/x86/include/asm/kvm_host.h
    @@ -1683,6 +1683,8 @@ struct kvm_x86_ops {

    bool (*disallowed_va)(struct kvm_vcpu *vcpu, u64 la);

    + void (*vcpu_gpc_refresh)(struct kvm_vcpu *vcpu);
    +
    bool (*has_wbinvd_exit)(void);

    u64 (*get_l2_tsc_offset)(struct kvm_vcpu *vcpu);
    @@ -1839,6 +1841,7 @@ static inline int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
    }

    #define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE
    +#define __KVM_HAVE_GUEST_USE_PFN_USAGE

    #define kvm_arch_pmi_in_guest(vcpu) \
    ((vcpu) && (vcpu)->arch.handling_intr_from_guest)
    diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
    index 80406666d7da..7bd88f7ace51 100644
    --- a/arch/x86/kvm/mmu/mmu.c
    +++ b/arch/x86/kvm/mmu/mmu.c
    @@ -6741,6 +6741,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
    struct kvm_memory_slot *slot)
    {
    kvm_mmu_zap_all_fast(kvm);
    + kvm_make_all_cpus_request(kvm, KVM_REQ_GPC_REFRESH);
    }

    void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen)
    diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
    index be8fdae942d1..89bf368085a9 100644
    --- a/arch/x86/kvm/x86.c
    +++ b/arch/x86/kvm/x86.c
    @@ -10786,6 +10786,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)

    if (kvm_check_request(KVM_REQ_UPDATE_CPU_DIRTY_LOGGING, vcpu))
    static_call(kvm_x86_update_cpu_dirty_logging)(vcpu);
    +
    + if (kvm_check_request(KVM_REQ_GPC_REFRESH, vcpu))
    + static_call_cond(kvm_x86_vcpu_gpc_refresh)(vcpu);
    }

    if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win ||
    diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
    index 4944136efaa2..b7c490e74704 100644
    --- a/include/linux/kvm_host.h
    +++ b/include/linux/kvm_host.h
    @@ -167,6 +167,7 @@ static inline bool is_error_page(struct page *page)
    #define KVM_REQ_VM_DEAD (1 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
    #define KVM_REQ_UNBLOCK 2
    #define KVM_REQ_DIRTY_RING_SOFT_FULL 3
    +#define KVM_REQ_GPC_REFRESH (5 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
    #define KVM_REQUEST_ARCH_BASE 8

    /*
    @@ -1367,6 +1368,15 @@ int kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, unsigned long len);
    */
    void kvm_gpc_deactivate(struct gfn_to_pfn_cache *gpc);

    +static inline unsigned int kvm_gpc_refresh_request(void)
    +{
    +#ifdef __KVM_HAVE_GUEST_USE_PFN_USAGE
    + return KVM_REQ_GPC_REFRESH;
    +#else
    + return KVM_REQ_OUTSIDE_GUEST_MODE;
    +#endif
    +}
    +
    void kvm_sigset_activate(struct kvm_vcpu *vcpu);
    void kvm_sigset_deactivate(struct kvm_vcpu *vcpu);

    diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
    index 2d6aba677830..f7b7a2f75ec7 100644
    --- a/virt/kvm/pfncache.c
    +++ b/virt/kvm/pfncache.c
    @@ -59,7 +59,7 @@ void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, unsigned long start,
    * KVM needs to ensure the vCPU is fully out of guest context
    * before allowing the invalidation to continue.
    */
    - unsigned int req = KVM_REQ_OUTSIDE_GUEST_MODE;
    + unsigned int req = kvm_gpc_refresh_request();
    bool called;

    /*
    --
    2.19.1.6.gb485710b

    \
     
     \ /
      Last update: 2024-05-27 15:22    [W:4.037 / U:0.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site