Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp4936261pxb; Wed, 19 Jan 2022 07:50:51 -0800 (PST) X-Google-Smtp-Source: ABdhPJxAy7R2n2zjK5jUItxifANIUYfs4iwhFshCEvFjg9qH1bGvmathbx3mfADnl15Bz7kZORjA X-Received: by 2002:a17:903:1c2:b0:14a:586c:134f with SMTP id e2-20020a17090301c200b0014a586c134fmr34524917plh.14.1642607451016; Wed, 19 Jan 2022 07:50:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642607451; cv=none; d=google.com; s=arc-20160816; b=Myg+587GItBfjtxZzYKroWZnGfyJEuNBnYh82/rrM0Qb/7CdRnWGffBzjNdZzQyIMq uJRXp8vgwI6BEVfkva+4cElTD+kxfRlfGzoQJQja8L7v/+HFJUdJeclWyY3haADAT2RU dD4ydWgHfD0BJxBl1vehBx0tqfyHKSEDImiD1o2uMM1lJEYXKLYj/quIS6SP2ZeyG+UH SFwQrFgdiv0bIOpZ1WoamePCUXfEXW402WcZyRfQXgVvr+Sip3RD+HgOQjJybusx3bUQ WzdkIqkpmsROHu+56D1PGE+XcrJYC/yEISJxtqayIQYsbHhNdiYX3NdU+gKLleFgY7sP cQqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id:dkim-signature; bh=Yvh3H32CuLULmQP9rM4UXA+g/CxmwZsZEAXYm94HfD8=; b=GGRtas8s1fdyloCkVMTmPstrs3fQHYsKk7glzOCzbknDTCOO3vDk093XVFUz7DbDB9 d0zM0sR1AJ4C2ObXmWuSoER92aPxJ0YvNRCYrl1paZQinDaUMtF4M7fpcFWnFHFIA/iS AnqOFUxQyc0i+dT1su3PaXgcrucdnlnk+BXuwAPFbNFEIyPVOGA3ENYJAz7kUxU/bxJn Vza/4ykNxGFd9OORWbmIGJPORhObx0F8NLClFOQoNZtiAeKMg0kyZ6yGEAKAftLCeQ4B Nu6qmdquUjFJ+tm5wzQIF5uqd1yZ7N32RVqyXoVFd02SRDtSmEY+ydHd3mbpL2CFX/8C XpTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=NsQv5Shz; 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=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q132si202172pgq.489.2022.01.19.07.50.38; Wed, 19 Jan 2022 07:50:50 -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=@intel.com header.s=Intel header.b=NsQv5Shz; 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=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351979AbiARD1U (ORCPT + 99 others); Mon, 17 Jan 2022 22:27:20 -0500 Received: from mga07.intel.com ([134.134.136.100]:37606 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242760AbiARDHJ (ORCPT ); Mon, 17 Jan 2022 22:07:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642475229; x=1674011229; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=6EDCrTWoJGrxyaF+nH0zOpujS9YGdyY2LOuNgo9Dpi8=; b=NsQv5ShzwWjqk9dVpNID1Vs0LdP4YE2A1z22BRl4z3onfoF5wB/yoBY9 ezP1gUmWzMGccM9htxD6esQNKhIInr3ADUSmER+h4JGu5mFGj+4hKwTIo M3vi3aKlfEo0XyOdSzUcCD0p8fri36LbyiRJx0NJZJX1S2dYDdANN+2V+ WgxsrFtUMZe8pGpOcpDckovMYy5V7cGNa9FHwSIo0bNXvFAfq4KYvUEsL AJlEdII5pd7Mx8jxwZnz5+jvijFXyVII4vmYiRVzQQpRgXmKe0oeK8hwb huKBo4Dgp3BL4sP+0DBKl/sW+YbHuj9e8J4u9xyem8BLpwtZajkgNlaqq g==; X-IronPort-AV: E=McAfee;i="6200,9189,10230"; a="308066567" X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="308066567" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 19:07:08 -0800 X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="531569632" Received: from zengguan-mobl.ccr.corp.intel.com (HELO [10.238.0.96]) ([10.238.0.96]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 19:07:03 -0800 Message-ID: Date: Tue, 18 Jan 2022 11:06:55 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Thunderbird/91.4.1 Subject: Re: [PATCH v5 5/8] KVM: x86: Support interrupt dispatch in x2APIC mode with APIC-write VM exit Content-Language: en-US To: Yuan Yao Cc: "Christopherson,, Sean" , 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" References: <20211231142849.611-1-guang.zeng@intel.com> <20211231142849.611-6-guang.zeng@intel.com> <8ab5f976-1f3e-e2a5-87f6-e6cf376ead2f@intel.com> <20220118004405.po36x3lxi26mkwsz@yy-desk-7060> From: Zeng Guang In-Reply-To: <20220118004405.po36x3lxi26mkwsz@yy-desk-7060> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 1/18/2022 8:44 AM, Yuan Yao wrote: > On Sat, Jan 15, 2022 at 10:08:10AM +0800, Zeng Guang wrote: >> On 1/15/2022 1:34 AM, Sean Christopherson wrote: >>> 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. >> Split on x2apic and WARN on (offset != APIC_ICR) already limit register read >> to vICR only. Actually >> we just need consider to deal with 64bit data specific to vICR in APIC-write >> exits. From this point of >> view, previous design can be compatible on handling other registers even if >> future architectural >> extensions changes. :) >>> 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); >> I think it's problematic to use kvm_lapic_msr_read() in this case. It >> premises the high 32bit value >> already valid at APIC_ICR2, while in handling "nodecode" x2APIC writes we >> need get continuous 64bit >> data from offset 300H first and prepare emulation of APIC_ICR2 write. At >> this time, APIC_ICR2 is not >> ready yet. > How about combine them, then you can handle the ICR write vmexit for > IPI virtualization and Sean's patch can still work with code reusing, > like below: > > if (apic_x2apic_mode(apic)) { > if (WARN_ON_ONCE(offset != APIC_ICR)) > kvm_lapic_msr_read(apic, offset, &val); > else > kvm_lapic_get_reg64(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); > } Alternatively we can merge as this if Sean think it ok to call kvm_lapic_get_reg64() retrieving 64bit data from vICR directly. >>> 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) >>> --