Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp720032pxb; Fri, 14 Jan 2022 14:58:37 -0800 (PST) X-Google-Smtp-Source: ABdhPJzP6Y3nsPQqo86Ks/nwnWlcSs5MxtSX+NflVhdLuwHTLM+YjGlDFvLJYbfN3Iokf58PjCCM X-Received: by 2002:a05:6402:408:: with SMTP id q8mr10697795edv.254.1642201116870; Fri, 14 Jan 2022 14:58:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642201116; cv=none; d=google.com; s=arc-20160816; b=MQdLQ0WYs7w3jRGnM2Zpk1iQkKYJIdlvg/xnSjlrzeAiw2D/SDqOJ0g790SA1amChK +liGuwXrs71jAm4sX6H10oa2iECaHwfiZIoMUZ8NLHvKB7q/qwgnB6+CcKgJEWz3WhPP 8bND7YRGOGLXwUkKGHXESXIwiNdvjysJmCGHGj5kY4d9n3EAbaSdskl6TG1WO7yuwx19 LOswEm5TtEZ2YugD9ZArjnLOT+f47O1C0Xzg68rd+3ZTY9eOP0OweP6lPlj5ofPvSNOK hcJEKY+kqS0iPyVun3mojHlR1oBfJgwDCzMoF80DGyFP3nx39z/eGyno1/aOzs89sqj0 DtLg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=tlKPtWrMnNhQ2zUBMOVAbMivXCD/K2BWvR3jQNPgLzU=; b=bUdik4KrK3J3G9uuiD//XKfe3A86F1bpXezVu8/qLJkI+1imCwuiXA7I3VEHeaBpHd NeSrH1AmkijLINlqe2GTze5r1v4fyVoPAgzuNgi9WyobDvZV8S25YsF22ugWO6c9G0d+ +kXjLMXBhOyjV8ERt2rDfCllLYF/W8HxjPSla1KhtlHOerEV3UirSHVSR9tTN1eh0lQW Sgg99zZyk8FB6ShopBe8xxoUl6vAs0nvzZ+DAQD2GXWVkb9JbV4NA0PjoH1LU6W4P+0v W5K6SrqSqKWAq1MZt1qayfyl/J4KjenNhS+y14jc9xfu/Ih6cjuqd/3pTfW692PE4pKX tKng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=XX3A9YU5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ho19si4017148ejc.270.2022.01.14.14.58.13; Fri, 14 Jan 2022 14:58:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=XX3A9YU5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232005AbiANReT (ORCPT + 99 others); Fri, 14 Jan 2022 12:34:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234268AbiANReS (ORCPT ); Fri, 14 Jan 2022 12:34:18 -0500 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8549CC06161C for ; Fri, 14 Jan 2022 09:34:18 -0800 (PST) Received: by mail-pj1-x102c.google.com with SMTP id hv15so14005576pjb.5 for ; Fri, 14 Jan 2022 09:34:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=tlKPtWrMnNhQ2zUBMOVAbMivXCD/K2BWvR3jQNPgLzU=; b=XX3A9YU5P9pPfPub0Or+FHT3A4oAky7zr4urlHgkYLnqB8z7/2b/EqK5iiG4E0wOeq N8Gx2uQyyhrP09NCe/+hw0TLcUD++Kg4nWrW+cQTtwy5GQZHnIykaefKz2QN4YnF3knv eb473RVPUHUxe7QZUu/8Wy2g4lEYhCJ6z1y7fza6hsRUk/wBlDEBYocvGe6w9Iz4K1Oz VFfDevOC91HFlntLAk4esr1Krz0O6G3MMuzjAvVK8cZJ8O12aoVYTc3J/DhFB7iMyUuH 5VzZJ9pY6RXLejBX1fkmWlWGaoT9owo0Sq1xp2NtTmd4sbA0N3e37MZ954j0He81pN90 V6+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=tlKPtWrMnNhQ2zUBMOVAbMivXCD/K2BWvR3jQNPgLzU=; b=xw6fcTI2U7cS3dg7NdUOxvoutGKiNrHoJFERvCh/AM/tIrC5WIRc9TNx0cGkODq3pL lb0SxRj0y2sxmqkHnEP9E52geEVf0bOAszgo1eLA10ndrSWkfAwiQNhT+fv8qJGWXyGJ xYqYfc6rs8mFSacdtvrE4sicX32ApI/NP7uJDGnFDc7yve00go3icOJjtnG4XBT9ZPMW fxzOxJJJfeb37o8ZMk5VHSHtZG2DB9W2/oHfFLCH49/crpi4u70tqoe2qxF4YaDnbDa2 zXmDjhiRazTyl/vV4IIIp9p+P4YuVD1cKaLW1g1dnT86hL7gygPN/vz7QD14mlJT/uOI bwRw== X-Gm-Message-State: AOAM532ZMpFgOKH7uvCNCmn6IbwLxAuY2wS5tb2Uir4faH75h77m/0OB 8ECgy1IVC3pZzVrpUy5wLC6tfQ== X-Received: by 2002:a17:90a:e018:: with SMTP id u24mr11720844pjy.95.1642181657872; Fri, 14 Jan 2022 09:34:17 -0800 (PST) Received: from google.com (157.214.185.35.bc.googleusercontent.com. [35.185.214.157]) by smtp.gmail.com with ESMTPSA id o3sm5560840pjr.2.2022.01.14.09.34.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 09:34:17 -0800 (PST) Date: Fri, 14 Jan 2022 17:34:13 +0000 From: Sean Christopherson To: Zeng Guang Cc: Paolo Bonzini , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , "kvm@vger.kernel.org" , Dave Hansen , "Luck, Tony" , Kan Liang , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Kim Phillips , Jarkko Sakkinen , Jethro Beekman , "Huang, Kai" , "x86@kernel.org" , "linux-kernel@vger.kernel.org" , "Hu, Robert" , "Gao, Chao" Subject: Re: [PATCH v5 5/8] KVM: x86: Support interrupt dispatch in x2APIC mode with APIC-write VM exit Message-ID: References: <20211231142849.611-1-guang.zeng@intel.com> <20211231142849.611-6-guang.zeng@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jan 14, 2022, Zeng Guang wrote: > kvm_lapic_reg_read() is limited to read up to 4 bytes. It needs extension to > support 64bit read. Ah, right. > And another concern is here getting reg value only specific from vICR(no > other regs need take care), going through whole path on kvm_lapic_reg_read() > could be time-consuming unnecessarily. Is it proper that calling > kvm_lapic_get_reg64() to retrieve vICR value directly? Hmm, no, I don't think that's proper. Retrieving a 64-bit value really is unique to vICR. Yes, the code does WARN on that, but if future architectural extensions even generate APIC-write exits on other registers, then using kvm_lapic_get_reg64() would be wrong and this code would need to be updated again. What about tweaking my prep patch from before to the below? That would yield: if (apic_x2apic_mode(apic)) { if (WARN_ON_ONCE(offset != APIC_ICR)) return 1; kvm_lapic_msr_read(apic, offset, &val); kvm_lapic_msr_write(apic, offset, val); } else { kvm_lapic_reg_read(apic, offset, 4, &val); kvm_lapic_reg_write(apic, offset, val); } I like that the above has "msr" in the low level x2apic helpers, and it maximizes code reuse. Compile tested only... From: Sean Christopherson Date: Fri, 14 Jan 2022 09:29:34 -0800 Subject: [PATCH] KVM: x86: Add helpers to handle 64-bit APIC MSR read/writes Add helpers to handle 64-bit APIC read/writes via MSRs to deduplicate the x2APIC and Hyper-V code needed to service reads/writes to ICR. Future support for IPI virtualization will add yet another path where KVM must handle 64-bit APIC MSR reads/write (to ICR). Opportunistically fix the comment in the write path; ICR2 holds the destination (if there's no shorthand), not the vector. No functional change intended. Signed-off-by: Sean Christopherson --- arch/x86/kvm/lapic.c | 59 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index f206fc35deff..cc4531eb448f 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2787,6 +2787,30 @@ int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) return 0; } +static int kvm_lapic_msr_read(struct kvm_lapic *apic, u32 reg, u64 *data) +{ + u32 low, high = 0; + + if (kvm_lapic_reg_read(apic, reg, 4, &low)) + return 1; + + if (reg == APIC_ICR && + WARN_ON_ONCE(kvm_lapic_reg_read(apic, APIC_ICR2, 4, &high))) + return 1; + + *data = (((u64)high) << 32) | low; + + return 0; +} + +static int kvm_lapic_msr_write(struct kvm_lapic *apic, u32 reg, u64 data) +{ + /* For 64-bit ICR writes, set ICR2 (dest) before ICR (command). */ + if (reg == APIC_ICR) + kvm_lapic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); + return kvm_lapic_reg_write(apic, reg, (u32)data); +} + int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) { struct kvm_lapic *apic = vcpu->arch.apic; @@ -2798,16 +2822,13 @@ int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) if (reg == APIC_ICR2) return 1; - /* if this is ICR write vector before command */ - if (reg == APIC_ICR) - kvm_lapic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); - return kvm_lapic_reg_write(apic, reg, (u32)data); + return kvm_lapic_msr_write(apic, reg, data); } int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data) { struct kvm_lapic *apic = vcpu->arch.apic; - u32 reg = (msr - APIC_BASE_MSR) << 4, low, high = 0; + u32 reg = (msr - APIC_BASE_MSR) << 4; if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic)) return 1; @@ -2815,45 +2836,23 @@ int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data) if (reg == APIC_DFR || reg == APIC_ICR2) return 1; - if (kvm_lapic_reg_read(apic, reg, 4, &low)) - return 1; - if (reg == APIC_ICR) - kvm_lapic_reg_read(apic, APIC_ICR2, 4, &high); - - *data = (((u64)high) << 32) | low; - - return 0; + return kvm_lapic_msr_read(apic, reg, data); } int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 reg, u64 data) { - struct kvm_lapic *apic = vcpu->arch.apic; - if (!lapic_in_kernel(vcpu)) return 1; - /* if this is ICR write vector before command */ - if (reg == APIC_ICR) - kvm_lapic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); - return kvm_lapic_reg_write(apic, reg, (u32)data); + return kvm_lapic_msr_write(vcpu->arch.apic, reg, data); } int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data) { - struct kvm_lapic *apic = vcpu->arch.apic; - u32 low, high = 0; - if (!lapic_in_kernel(vcpu)) return 1; - if (kvm_lapic_reg_read(apic, reg, 4, &low)) - return 1; - if (reg == APIC_ICR) - kvm_lapic_reg_read(apic, APIC_ICR2, 4, &high); - - *data = (((u64)high) << 32) | low; - - return 0; + return kvm_lapic_msr_read(vcpu->arch.apic, reg, data); } int kvm_lapic_set_pv_eoi(struct kvm_vcpu *vcpu, u64 data, unsigned long len) --