From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8184C433F5 for ; Mon, 1 Nov 2021 09:54:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 94A4F6056B for ; Mon, 1 Nov 2021 09:54:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233408AbhKAJ4s (ORCPT ); Mon, 1 Nov 2021 05:56:48 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:38476 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234234AbhKAJyp (ORCPT ); Mon, 1 Nov 2021 05:54:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1635760331; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=hTNjHa1TMEqRPhvFHuXK6XSXRxTvytm/OlBhth0P8ak=; b=Ou8QNeHiSvch1Cw6St+aqBm2KpUaPDC3dG6NVY8uYUMWoRCpz7falf+yCEfEh5ziWQ/IUe 8ewjPXaeWPUWuY0Lmngsjny9HKbf1CQqT1I9hVz1RP4BsCBChlybPfivNSo5OloCaKF4M7 hgLsTLO89YizVU0OeguYZ8nAjkMD8HY= Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-556-8d95Fy2QM7SCEdnwN2QHzg-1; Mon, 01 Nov 2021 05:52:10 -0400 X-MC-Unique: 8d95Fy2QM7SCEdnwN2QHzg-1 Received: by mail-ed1-f72.google.com with SMTP id r25-20020a05640216d900b003dca3501ab4so14979250edx.15 for ; Mon, 01 Nov 2021 02:52:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references:date :message-id:mime-version; bh=hTNjHa1TMEqRPhvFHuXK6XSXRxTvytm/OlBhth0P8ak=; b=T0IOY64uvC8Fh03YTMw/fKE5gIAJCSRw6BwfntM3SED9MsOu2dAuoTJOFK/e/BUE0T XATVTRVpkCytxD1KvbMteTM6c6xRO7gHwebOcoE1IlrzVQN91Orv5Xcak9rU7fd5s+qG 1QbiwBCbgSkgLe8EdnqtCxD+AVWA9V9adXjwiA16DoM5AqoKlEbx4sSXaiocgTd4IHCG O8cFovd/HLIOJxAzRl04MQNBFVBwrFjOyCb7P7H0G6zo2MZbLx5JZ1ECpRgSEo6d1eM1 v4376q5MDDz+h87uqdKbhCaM47rZh91mQl2eUNHrGFwLFMrUSaTmql36IkuuVTG6KQZX LoCA== X-Gm-Message-State: AOAM531q7Bl7z9gR92SFgpi7JT1xdn/a2ycUagK11/2Zv3f+NTk+MN/i qijRN61kGvT5kCEwzz4pCeFe6fHfjGlRPmdiDCFniLKrP2fQtJQAGSI14hNcD0+eAAKmmyEm89c Tzji5rruTFUG/9yWHLH7Egkm0 X-Received: by 2002:a05:6402:17c6:: with SMTP id s6mr23826590edy.11.1635760329730; Mon, 01 Nov 2021 02:52:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw+4wcfkcjbb+BJKXbX8UJhqQo0tsMPIRflgFbUhB0LTkA3bEecXam4YFslJKUNisDfYWgBOQ== X-Received: by 2002:a05:6402:17c6:: with SMTP id s6mr23826545edy.11.1635760329469; Mon, 01 Nov 2021 02:52:09 -0700 (PDT) Received: from vitty.brq.redhat.com (g-server-2.ign.cz. [91.219.240.2]) by smtp.gmail.com with ESMTPSA id j11sm6624691ejt.114.2021.11.01.02.52.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 02:52:08 -0700 (PDT) From: Vitaly Kuznetsov To: Sean Christopherson Cc: Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, Ajay Garg , Paolo Bonzini , "K. Y. Srinivasan" , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Arnd Bergmann Subject: Re: [PATCH v2 2/8] KVM: x86: Get the number of Hyper-V sparse banks from the VARHEAD field In-Reply-To: <20211030000800.3065132-3-seanjc@google.com> References: <20211030000800.3065132-1-seanjc@google.com> <20211030000800.3065132-3-seanjc@google.com> Date: Mon, 01 Nov 2021 10:52:07 +0100 Message-ID: <87a6iokxtk.fsf@vitty.brq.redhat.com> MIME-Version: 1.0 Content-Type: text/plain Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Sean Christopherson writes: > Get the number of sparse banks from the VARHEAD field, which the guest is > required to provide as "The size of a variable header, in QWORDS.", where > the variable header is: > > Variable Header Bytes = {Total Header Bytes - sizeof(Fixed Header)} > rounded up to nearest multiple of 8 > Variable HeaderSize = Variable Header Bytes / 8 > > In other words, the VARHEAD should match the number of sparse banks. > Keep the manual count as a sanity check, but otherwise rely on the field > so as to more closely align with the logic defined in the TLFS and to > allow for future cleanups. > > Signed-off-by: Sean Christopherson > --- > arch/x86/kvm/hyperv.c | 35 ++++++++++++++++++------------- > arch/x86/kvm/trace.h | 14 +++++++------ > include/asm-generic/hyperv-tlfs.h | 1 + > 3 files changed, 30 insertions(+), 20 deletions(-) > > diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c > index 814d1a1f2cb8..cf18aa1712bf 100644 > --- a/arch/x86/kvm/hyperv.c > +++ b/arch/x86/kvm/hyperv.c > @@ -1742,6 +1742,7 @@ struct kvm_hv_hcall { > u64 ingpa; > u64 outgpa; > u16 code; > + u16 var_cnt; > u16 rep_cnt; > u16 rep_idx; > bool fast; > @@ -1761,7 +1762,6 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool > unsigned long *vcpu_mask; > u64 valid_bank_mask; > u64 sparse_banks[64]; > - int sparse_banks_len; > bool all_cpus; > > if (!ex) { > @@ -1811,24 +1811,28 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool > all_cpus = flush_ex.hv_vp_set.format != > HV_GENERIC_SET_SPARSE_4K; > > - sparse_banks_len = bitmap_weight((unsigned long *)&valid_bank_mask, 64); > + if (hc->var_cnt != bitmap_weight((unsigned long *)&valid_bank_mask, 64)) > + return HV_STATUS_INVALID_HYPERCALL_INPUT; Let's hope Windows doesn't break this ruls when vp_set.format != HV_GENERIC_SET_SPARSE_4K > > - if (!sparse_banks_len && !all_cpus) > + if (!hc->var_cnt && !all_cpus) > goto ret_success; > > if (!all_cpus) { > if (hc->fast) { > - if (sparse_banks_len > HV_HYPERCALL_MAX_XMM_REGISTERS - 1) > + if (hc->var_cnt > HV_HYPERCALL_MAX_XMM_REGISTERS - 1) > return HV_STATUS_INVALID_HYPERCALL_INPUT; > - for (i = 0; i < sparse_banks_len; i += 2) { > + for (i = 0; i < hc->var_cnt; i += 2) { > sparse_banks[i] = sse128_lo(hc->xmm[i / 2 + 1]); > sparse_banks[i + 1] = sse128_hi(hc->xmm[i / 2 + 1]); > } > } else { > + if (hc->var_cnt > 64) > + return HV_STATUS_INVALID_HYPERCALL_INPUT; > + > gpa = hc->ingpa + offsetof(struct hv_tlb_flush_ex, > hv_vp_set.bank_contents); > if (unlikely(kvm_read_guest(kvm, gpa, sparse_banks, > - sparse_banks_len * > + hc->var_cnt * > sizeof(sparse_banks[0])))) > return HV_STATUS_INVALID_HYPERCALL_INPUT; > } > @@ -1884,7 +1888,6 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool > unsigned long *vcpu_mask; > unsigned long valid_bank_mask; > u64 sparse_banks[64]; > - int sparse_banks_len; > u32 vector; > bool all_cpus; > > @@ -1917,22 +1920,25 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc, bool > > vector = send_ipi_ex.vector; > valid_bank_mask = send_ipi_ex.vp_set.valid_bank_mask; > - sparse_banks_len = bitmap_weight(&valid_bank_mask, 64) * > - sizeof(sparse_banks[0]); > - > all_cpus = send_ipi_ex.vp_set.format == HV_GENERIC_SET_ALL; > > + if (hc->var_cnt != bitmap_weight(&valid_bank_mask, 64)) > + return HV_STATUS_INVALID_HYPERCALL_INPUT; > + > if (all_cpus) > goto check_and_send_ipi; > > - if (!sparse_banks_len) > + if (!hc->var_cnt) > goto ret_success; > > + if (hc->var_cnt > 64) > + return HV_STATUS_INVALID_HYPERCALL_INPUT; > + > if (kvm_read_guest(kvm, > hc->ingpa + offsetof(struct hv_send_ipi_ex, > vp_set.bank_contents), > sparse_banks, > - sparse_banks_len)) > + hc->var_cnt * sizeof(sparse_banks[0]))) > return HV_STATUS_INVALID_HYPERCALL_INPUT; > } > > @@ -2190,13 +2196,14 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) > } > > hc.code = hc.param & 0xffff; > + hc.var_cnt = (hc.param & HV_HYPERCALL_VARHEAD_MASK) >> HV_HYPERCALL_VARHEAD_OFFSET; > hc.fast = !!(hc.param & HV_HYPERCALL_FAST_BIT); > hc.rep_cnt = (hc.param >> HV_HYPERCALL_REP_COMP_OFFSET) & 0xfff; > hc.rep_idx = (hc.param >> HV_HYPERCALL_REP_START_OFFSET) & 0xfff; > hc.rep = !!(hc.rep_cnt || hc.rep_idx); > > - trace_kvm_hv_hypercall(hc.code, hc.fast, hc.rep_cnt, hc.rep_idx, > - hc.ingpa, hc.outgpa); > + trace_kvm_hv_hypercall(hc.code, hc.fast, hc.var_cnt, hc.rep_cnt, > + hc.rep_idx, hc.ingpa, hc.outgpa); > > if (unlikely(!hv_check_hypercall_access(hv_vcpu, hc.code))) { > ret = HV_STATUS_ACCESS_DENIED; > diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h > index 953b0fcb21ee..f6625cfb686c 100644 > --- a/arch/x86/kvm/trace.h > +++ b/arch/x86/kvm/trace.h > @@ -64,9 +64,9 @@ TRACE_EVENT(kvm_hypercall, > * Tracepoint for hypercall. > */ > TRACE_EVENT(kvm_hv_hypercall, > - TP_PROTO(__u16 code, bool fast, __u16 rep_cnt, __u16 rep_idx, > - __u64 ingpa, __u64 outgpa), > - TP_ARGS(code, fast, rep_cnt, rep_idx, ingpa, outgpa), > + TP_PROTO(__u16 code, bool fast, __u16 var_cnt, __u16 rep_cnt, > + __u16 rep_idx, __u64 ingpa, __u64 outgpa), > + TP_ARGS(code, fast, var_cnt, rep_cnt, rep_idx, ingpa, outgpa), > > TP_STRUCT__entry( > __field( __u16, rep_cnt ) > @@ -74,6 +74,7 @@ TRACE_EVENT(kvm_hv_hypercall, > __field( __u64, ingpa ) > __field( __u64, outgpa ) > __field( __u16, code ) > + __field( __u16, var_cnt ) > __field( bool, fast ) > ), > > @@ -83,13 +84,14 @@ TRACE_EVENT(kvm_hv_hypercall, > __entry->ingpa = ingpa; > __entry->outgpa = outgpa; > __entry->code = code; > + __entry->var_cnt = var_cnt; > __entry->fast = fast; > ), > > - TP_printk("code 0x%x %s cnt 0x%x idx 0x%x in 0x%llx out 0x%llx", > + TP_printk("code 0x%x %s var_cnt 0x%x cnt 0x%x idx 0x%x in 0x%llx out 0x%llx", Nit: 'cnt' is (and was) a bit ambiguous, I'd suggest to explicitly say 'rep_cnt' (and probably 'rep_idx') instead. > __entry->code, __entry->fast ? "fast" : "slow", > - __entry->rep_cnt, __entry->rep_idx, __entry->ingpa, > - __entry->outgpa) > + __entry->var_cnt, __entry->rep_cnt, __entry->rep_idx, > + __entry->ingpa, __entry->outgpa) > ); > > TRACE_EVENT(kvm_hv_hypercall_done, > diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h > index 56348a541c50..1ba8e6da4427 100644 > --- a/include/asm-generic/hyperv-tlfs.h > +++ b/include/asm-generic/hyperv-tlfs.h > @@ -182,6 +182,7 @@ enum HV_GENERIC_SET_FORMAT { > #define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0) > #define HV_HYPERCALL_FAST_BIT BIT(16) > #define HV_HYPERCALL_VARHEAD_OFFSET 17 > +#define HV_HYPERCALL_VARHEAD_MASK GENMASK_ULL(26, 17) > #define HV_HYPERCALL_REP_COMP_OFFSET 32 > #define HV_HYPERCALL_REP_COMP_1 BIT_ULL(32) > #define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32) Reviewed-by: Vitaly Kuznetsov -- Vitaly