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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8939DC71135 for ; Thu, 12 Jun 2025 00:50:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Reply-To:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To: From:Subject:Message-ID:References:Mime-Version:In-Reply-To:Date: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=IkktWH+V9h3bcYXFzddTxBsHDsmGjlRn4knyOKrNzLg=; b=ne1XQK/mgUHf3Fm7pxSXFbGBJD 1EVzN5Hh0wKGjYiEbWU/THveTibTfcyz+25YaHcW5Er8EIc3dt//wvWW3EdxGAgxKXS2Y+U+vmUF/ Zy2GC6xE2+WrkEwICE/4+TEFmYFuW13uzfIwbPJ7oxYfNZErPXzQed03AGGMn0bDwJDgjOpGhKg9b Y+95OGvlFvmJ7DZmbTMmolpU5cLSrUEKh7+aXOFd7BGhRfF76vMbq4C/J+EkH+O7xksaEbACDsbZn DO/VIEhZQuKs0ehX9nzQaVMn3XinWP6xE+gIXfbd2PIDrFtAj8psI7ixBdHX4tIIU/8icliekRFhz nlj2U1hA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1uPW98-0000000Bpqb-28T5; Thu, 12 Jun 2025 00:50:22 +0000 Received: from mail-pf1-x449.google.com ([2607:f8b0:4864:20::449]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uPUED-0000000BXEs-2sUR for linux-arm-kernel@lists.infradead.org; Wed, 11 Jun 2025 22:47:30 +0000 Received: by mail-pf1-x449.google.com with SMTP id d2e1a72fcca58-7395d07a3dcso234988b3a.3 for ; Wed, 11 Jun 2025 15:47:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749682048; x=1750286848; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=IkktWH+V9h3bcYXFzddTxBsHDsmGjlRn4knyOKrNzLg=; b=QqLMzAMu97XwXNFxh9j2leahtaIp1nYXRCMT4M7P56qPCChQl8ehPa4GcUJLGK4XtH sy86MKw9Nfuf7fUAoSIEC+O7RaipsZ0WGgnGao5IyD+NZj+T7UurbCU8dQvUKP/JXHMQ 654mZL0JlKgtAcKoeyJF3Ozvl7itog40C4wfpRRB85unfKfidbCzRd/pmudzm26ncxxi lxMai9IApdvoAxE8k9mEynLKBnVInXOELke9SBk54hOv7AitTloF0TmWDctHaKUNXJ7J ZuzfWgNsg4I4nPC9EQkqJk9kXYO9W5x5JGLYnxTmWFCsw7prOppy2GTWnCdFu4XPqABj zxkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749682048; x=1750286848; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=IkktWH+V9h3bcYXFzddTxBsHDsmGjlRn4knyOKrNzLg=; b=rU5B8wJ621yjFxScVyur2pldWJl/lRubVThe2oZwHnNKbW69soujJbaLEG8XJ03wQY s7xOBiSmDKJZVhV4iqdHfD85kVY8VXidrzflPio8q6B5eD0BwtSM05/T6WaHbOdHF+Zf ehvlTH+lYlOFbGUaJ9bJwWcGdLn5bFXxs0QAYNRpYCGK9PaOEeXs8vcHpnIc7NYJn5RB 5wCZeqz8ATgJ1xa4QfwjZAJQDsTn3KGzaTZkP0bnEHIe9kw9UTiR0kAtS6DHYOcjF6eA Ba+kxdvzdR+ho0Y3Ip7uG3XwpQzfbmxjDEvCKf3OKQY968Q6D7PbRRCuZ8aBv7V3G8g0 wZQg== X-Gm-Message-State: AOJu0YzRptJiIyPZwznzcwHDYiUBDkdjfis2po7bk5LjbKS8JVctPoTK zeOcUCq+hj0LRXmjax+0gsot1kdaSI+tOLoFaClOUlrKg99pO5eHKag698PAwzbOn2DeIslDniI DlpWsTQ== X-Google-Smtp-Source: AGHT+IFju6WrqvBHypqRYrHHoWezRKFOOmxRqymOxF1hxx8+vosFxM+8IRo96ENVv8Z0pfdBM/f4N8kJm6A= X-Received: from pflc8.prod.google.com ([2002:a05:6a00:ac8:b0:746:1e60:660e]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:3925:b0:736:d297:164 with SMTP id d2e1a72fcca58-7487e0b1b93mr961505b3a.1.1749682048530; Wed, 11 Jun 2025 15:47:28 -0700 (PDT) Date: Wed, 11 Jun 2025 15:45:22 -0700 In-Reply-To: <20250611224604.313496-2-seanjc@google.com> Mime-Version: 1.0 References: <20250611224604.313496-2-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc1.591.g9c95f17f64-goog Message-ID: <20250611224604.313496-21-seanjc@google.com> Subject: [PATCH v3 19/62] KVM: VMX: Suppress PI notifications whenever the vCPU is put From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Sean Christopherson , Paolo Bonzini , Joerg Roedel , David Woodhouse , Lu Baolu Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Sairaj Kodilkar , Vasant Hegde , Maxim Levitsky , Joao Martins , Francesco Lavra , David Matlack Content-Type: text/plain; charset="UTF-8" X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250611_154729_730561_E858E455 X-CRM114-Status: GOOD ( 25.82 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Sean Christopherson Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Suppress posted interrupt notifications (set PID.SN=1) whenever the vCPU is put, i.e. unloaded, not just when the vCPU is preempted, as KVM doesn't do anything in response to a notification IRQ that arrives in the host, nor does KVM rely on the Outstanding Notification (PID.ON) flag when the vCPU is unloaded. And, the cost of scanning the PIR to manually set PID.ON when loading the vCPU is quite small, especially relative to the cost of loading (and unloading) a vCPU. On the flip side, leaving SN clear means a notification for the vCPU will result in a spurious IRQ for the pCPU, even if vCPU task is scheduled out, running in userspace, etc. Even worse, if the pCPU is running a different vCPU, the spurious IRQ could trigger posted interrupt processing for the wrong vCPU, which is technically a violation of the architecture, as setting bits in PIR aren't supposed to be propagated to the vIRR until a notification IRQ is received. The saving grace of the current behavior is that hardware sends notification interrupts if and only if PID.ON=0, i.e. only the first posted interrupt for a vCPU will trigger a spurious IRQ (for each window where the vCPU is unloaded). Ideally, KVM would suppress notifications before enabling IRQs in the VM-Exit, but KVM relies on PID.ON as an indicator that there is a posted interrupt pending in PIR, e.g. in vmx_sync_pir_to_irr(), and sadly there is no way to ask hardware to set PID.ON, but not generate an interrupt. That could be solved by using pi_has_pending_interrupt() instead of checking only PID.ON, but it's not at all clear that would be a performance win, as KVM would end up scanning the entire PIR whenever an interrupt isn't pending. And long term, the spurious IRQ window, i.e. where a vCPU is loaded with IRQs enabled, can effectively be made smaller for hot paths by moving performance critical VM-Exit handlers into the fastpath, i.e. by never enabling IRQs for hot path VM-Exits. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/posted_intr.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c index 110fb19848ab..d4826a6b674f 100644 --- a/arch/x86/kvm/vmx/posted_intr.c +++ b/arch/x86/kvm/vmx/posted_intr.c @@ -73,13 +73,10 @@ void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) /* * If the vCPU wasn't on the wakeup list and wasn't migrated, then the * full update can be skipped as neither the vector nor the destination - * needs to be changed. + * needs to be changed. Clear SN even if there is no assigned device, + * again for simplicity. */ if (pi_desc->nv != POSTED_INTR_WAKEUP_VECTOR && vcpu->cpu == cpu) { - /* - * Clear SN if it was set due to being preempted. Again, do - * this even if there is no assigned device for simplicity. - */ if (pi_test_and_clear_sn(pi_desc)) goto after_clear_sn; return; @@ -225,17 +222,23 @@ void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu) if (!vmx_needs_pi_wakeup(vcpu)) return; - if (kvm_vcpu_is_blocking(vcpu) && + /* + * If the vCPU is blocking with IRQs enabled and ISN'T being preempted, + * enable the wakeup handler so that notification IRQ wakes the vCPU as + * expected. There is no need to enable the wakeup handler if the vCPU + * is preempted between setting its wait state and manually scheduling + * out, as the task is still runnable, i.e. doesn't need a wake event + * from KVM to be scheduled in. + * + * If the wakeup handler isn't being enabled, Suppress Notifications as + * the cost of propagating PIR.IRR to PID.ON is negligible compared to + * the cost of a spurious IRQ, and vCPU put/load is a slow path. + */ + if (!vcpu->preempted && kvm_vcpu_is_blocking(vcpu) && ((is_td_vcpu(vcpu) && tdx_interrupt_allowed(vcpu)) || (!is_td_vcpu(vcpu) && !vmx_interrupt_blocked(vcpu)))) pi_enable_wakeup_handler(vcpu); - - /* - * Set SN when the vCPU is preempted. Note, the vCPU can both be seen - * as blocking and preempted, e.g. if it's preempted between setting - * its wait state and manually scheduling out. - */ - if (vcpu->preempted) + else pi_set_sn(pi_desc); } -- 2.50.0.rc1.591.g9c95f17f64-goog