Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp4320019ybg; Tue, 29 Oct 2019 05:30:48 -0700 (PDT) X-Google-Smtp-Source: APXvYqyeiR0uFO4dXIfcc1iEH+OJFthsaq9F+5smXyiBEW66nff61JRvYb+53RGljns4rKlFFV54 X-Received: by 2002:a05:6402:1816:: with SMTP id g22mr25463009edy.76.1572352248090; Tue, 29 Oct 2019 05:30:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572352248; cv=none; d=google.com; s=arc-20160816; b=VWoAe12O7hvMvBc8c1SJFOUVjW/BvFVp1OIPHm1CBZD34ve0oR5+Xm1BSizxqkTqKu MQ4la3RrIJXCrW4eAt0l+tdazYKj8lzUJrFi0tCpOlRbTu+iaUGMPB6gpVFK58a+7+jC kFo3Y7HF2nkTtkmtVYOYdjfyEewsRAJMjsYzRApp5QlVOe4V4zYv9cYLpwRxytsEM6ol RdHRoVd7VHNe7MfhwqtoFy9xdBJx1VrSn2q2gC3oSqWhI8RXzLkmEIicEtx5rXs+7Gzu H6Csg+nH4cja5EeTZTELjJCNVBxW4IlupPocs4Q2vIZro9Op6zcEao5qhfDIQb29vDUo Iq1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=XJ+h27DusqP+PN56iOnJmoznEFSgiQyGIkkYk8yRZ1o=; b=jGEJC7OII0YqOyxhqOoYFOgYC0copxaOIsXPFfOzEZpizgyD5zrmLErl4lYFHHCbtn soMiNvSeBFaxjUGC+ScrB13ulWtKzMOf6w5C1RHtKMw7zmbo74Z6iffrb9eNTObmLZ2x sALEyfvgZw/45ji5a/zJ0MnEqpEKMnuZTXUQvwvHKhaXcInTAWvkvzYo3eLVov+Zh4Yc WutFI9/4sljZc3JAbsHXxn5cU7Ghpno5o1BrBM9pOCUU7DCI1Qx4EUjpBK91k1w1KUVK Ss+KUbgxCPM2Bk0W67+z7n6VV8U0GSF1qURFF9/0BZs4X/R8d29/BJDakrUgW3k/kJ4A LZiA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p4si1291430ejo.21.2019.10.29.05.30.23; Tue, 29 Oct 2019 05:30:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732382AbfJ2M2V (ORCPT + 99 others); Tue, 29 Oct 2019 08:28:21 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:5209 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729317AbfJ2M2V (ORCPT ); Tue, 29 Oct 2019 08:28:21 -0400 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 41C96AAB6D429E4EEA23; Tue, 29 Oct 2019 20:28:06 +0800 (CST) Received: from [127.0.0.1] (10.173.222.27) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.439.0; Tue, 29 Oct 2019 20:27:58 +0800 Subject: Re: [PATCH 3/3] KVM: arm/arm64: vgic: Don't rely on the wrong pending table To: Marc Zyngier CC: , , , , , , , References: <20191029071919.177-1-yuzenghui@huawei.com> <20191029071919.177-4-yuzenghui@huawei.com> <86mudjykfa.wl-maz@kernel.org> From: Zenghui Yu Message-ID: Date: Tue, 29 Oct 2019 20:27:56 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.2.0 MIME-Version: 1.0 In-Reply-To: <86mudjykfa.wl-maz@kernel.org> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.173.222.27] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Marc, On 2019/10/29 17:23, Marc Zyngier wrote: > On Tue, 29 Oct 2019 07:19:19 +0000, > Zenghui Yu wrote: >> >> It's possible that two LPIs locate in the same "byte_offset" but target >> two different vcpus, where their pending status are indicated by two >> different pending tables. In such a scenario, using last_byte_offset >> optimization will lead KVM relying on the wrong pending table entry. >> Let us use last_ptr instead, which can be treated as a byte index into >> a pending table and also, can be vcpu specific. >> >> Signed-off-by: Zenghui Yu >> --- >> >> If this patch has done the right thing, we can even add the: >> >> Fixes: 280771252c1b ("KVM: arm64: vgic-v3: KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES") >> >> But to be honest, I'm not clear about what has this patch actually fixed. >> Pending tables should contain all zeros before we flush vgic_irq's pending >> status into guest's RAM (thinking that guest should never write anything >> into it). So the pending table entry we've read from the guest memory >> seems always be zero. And we will always do the right thing even if we >> rely on the wrong pending table entry. >> >> I think I must have some misunderstanding here... Please fix me. > > I think you're spot on, and it is the code needs fixing, not you! The > problem is that we only read a byte once, irrespective of the vcpu the > interrupts is routed to. If we switch to another vcpu for the same > byte offset, we must reload it. > > This can be done by either checking the vcpu, or by tracking the guest > address that we read from (just like you do here). okay, the remaining question is that in vgic_v3_save_pending_tables(): stored = val & (1U << bit_nr); if (stored == irq->pending_latch) continue; if (irq->pending_latch) val |= 1 << bit_nr; else val &= ~(1 << bit_nr); Do we really have a scenario where irq->pending_latch==false and stored==true (corresponds to the above "else") and then we clear pending status of this LPI in guest memory? I can not think out one now. > > A small comment below: > >> virt/kvm/arm/vgic/vgic-v3.c | 6 +++--- >> 1 file changed, 3 insertions(+), 3 deletions(-) >> >> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c >> index 5ef93e5041e1..7cd2e2f81513 100644 >> --- a/virt/kvm/arm/vgic/vgic-v3.c >> +++ b/virt/kvm/arm/vgic/vgic-v3.c >> @@ -363,8 +363,8 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq) >> int vgic_v3_save_pending_tables(struct kvm *kvm) >> { >> struct vgic_dist *dist = &kvm->arch.vgic; >> - int last_byte_offset = -1; >> struct vgic_irq *irq; >> + gpa_t last_ptr = -1; > > This should be written as > > gpa_t last_ptr = ~(gpa_t)0; Thanks for pointing it out. > >> int ret; >> u8 val; >> >> @@ -384,11 +384,11 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) >> bit_nr = irq->intid % BITS_PER_BYTE; >> ptr = pendbase + byte_offset; >> >> - if (byte_offset != last_byte_offset) { >> + if (ptr != last_ptr) { >> ret = kvm_read_guest_lock(kvm, ptr, &val, 1); >> if (ret) >> return ret; >> - last_byte_offset = byte_offset; >> + last_ptr = ptr; >> } >> >> stored = val & (1U << bit_nr); > > Otherwise, this looks good to me (no need to respin for the above > nit). Thanks, Zenghui