From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD0DF2F616B for ; Sat, 22 Aug 2026 19:02:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.53 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787425362; cv=none; b=fYM5HYX9JLGal8houWCqPUlKvlrMjSKJ0Zhg2+mbHbidOggzbkzAoPbKnWJAW0mKKZ67bmOa5nrp973nqVKpT0idWr05+NMzRv3yzssv5QyAIzoYcHhT1qUxSFsQdmVX59eAbzXf+xKARMRtsXIOcvIyLs8LDh2r1YFc2LMAmrM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787425362; c=relaxed/simple; bh=TEVVR+NJeSOM6jhm2KmEJQjEK4pU5ls7LvfbQaqcKFU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=OerLhDYbEAzxye9xTg7GgnTm/riTDU9gWpY40pwbZPQMCWsb/A1fMvIndJhgzTCLeqGHlzEvfi9pddUzEIQn88Sj3y1q7F6h6aPKSakThsAwZ0x1Sl3yxbIjvUnkK5iM/tYlzDIaDDB3U838+U6FZPJqZokFdb1K3aPQmTMO/gg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=oV32R1YM; arc=none smtp.client-ip=209.85.216.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oV32R1YM" Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-38ecc48b3deso185653a91.0 for ; Sat, 22 Aug 2026 12:02:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787425360; x=1788030160; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=D0DJujrfDn5dw25P3BnoPNA4Oq1OjRXcOtGPqI8/msc=; b=oV32R1YM56A+DDWB8TLmVIdWhQckn87wnLJS7I2tU8giStxFRs9xig9UyLvsuqITXJ KH8jBUmUMlOsp4TzXPaeFCktbJ4lY53K+amdUsyNb5TOn0q5Vkk3KyOPDLYA00FiaT+7 2NrjsadlbRsyy8FRKocgKW163hQcR1ZRQuq0hnJxHh38NS0fPgvoLuDWS5lpm3ldO8Eb pxmxOwNXAUUY6RGZFlBAyouDrT48fiCLoe+NQJ6VWcoiiKJat90wwfjfrr6ZplZ+wI73 9Cvz7a83ykcQWGPPaiwhQNDZQRjCqIcdLV5gfmN4SP5pS+3srBkXAtw49dz1px8XHgu1 imxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787425360; x=1788030160; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=D0DJujrfDn5dw25P3BnoPNA4Oq1OjRXcOtGPqI8/msc=; b=iHiTe435LiHDhVGKX35U8njjT1u54L23oYtgX6Xjx4xFfLQieYURofZ11RALjDE2gl dXHRoO6hYXY8zziLSvw1TzurLRR0v5sj3H7LZPR3xdVrO7ofDZUCjY4EhKODZC/VhNX/ x/Qfl9aYqNbZKOGgUZ8tD9BW66IREyBRGr5NzWRFFczLzrWd1A76EGrSVS/z+MGssUAJ OBwy0I4LpflALwp7jRn1Nwy4H8rfHY7o5gKh4xhY2t+sOtp0LZ9dtJmTmyFXeJu3c/l1 J0ypKtoxPnmcQ0j7SkOaJGsfjgpWkqMGjB8aAVmpgJSerLscGYOrUuNiX5MetRykBMJn ZLMQ== X-Forwarded-Encrypted: i=1; AHgh+RriaU6hUpoerDOTuL3zvEIKgFqTqRbaSLHAlHUMrglDMkR+lxyeRrvaJLHByNoQ6c4IFqIa0ZwgnrKzcHg=@vger.kernel.org X-Gm-Message-State: AFuF++kqq1dhsooGF+ab655gXt+dT2cVLaL18GZcpcFCT7BnNVuuEgVW N5F+GLJzFnczf+ryQupIcIOKZqI7gFOEjudBuKDJodn8hCfMZR9lwnXHLPJWton6q/w= X-Gm-Gg: AR+sD11QO/UfsfYxnsevdM3hif8rA3t0F9SBWKPJ64JjPBg6NqL5mYGxtIHJAI2EJwA aeI+kyo0LiebYL0lGBl86r3FcCM70ma4khO1JnXpQcPN/KtBUH8iolM24tVB734AXyEGZFmCI9S kfnmwmSPyOVLezhv9nfrwrkOCgYmSyol+vRQQdtPkDivxjDJlfyLc1P3VAemciYwG3tKbdSY4Ct gvq6K/D7OLhmmVnBDh+mvk9ivzZc3zH2pNySd8tAfz3hdcs3qU9Dpg5mNLDaqgHOm1ZdCFqS3l4 yItMO7+nI8yXxs3uMxnGZmotOqo6zZppGm4bWFEKBjhp8gi1LkXflJTLd5HYyajR4Te4s69i29V D1QvV8mVBNRt3WBCXmaCWlg6DOLV0yR31Xc2dcIgHk4o0o5IgN9Fr3m3RPfHyD8u4thYpsDyAm1 yvmuY65gp+wiZMfhX0mZ3ZYiLG5/sdWhLxX3IqCfJsxecVdTlgB5FgjwV4TLVVivZ2OYYIQmzb9 R4QkYyUze+0utYGGW0eqqHqPyhV+TrU1t+X69EgROoL9TrHPljuvfSCw1RCalmxVQ== X-Received: by 2002:a17:90b:4f45:b0:38e:91a8:fb85 with SMTP id 98e67ed59e1d1-395c35e7049mr11712009a91.3.1787425359802; Sat, 22 Aug 2026 12:02:39 -0700 (PDT) Received: from localhost.localdomain (45.78.65.84.16clouds.com. [45.78.65.84]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-141860c6989sm9412297c88.2.2026.08.22.12.02.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Aug 2026 12:02:39 -0700 (PDT) From: Chengfeng Ye To: Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Yan Zhao Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Chengfeng Ye , stable@vger.kernel.org Subject: [PATCH] KVM: x86/mmu: Protect noncoherent DMA zaps with SRCU Date: Sun, 23 Aug 2026 03:02:24 +0800 Message-ID: <20260822190224.3788887-1-nicoyip.dev@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Protect the noncoherent DMA zap with KVM's SRCU so that memslots and their architecture-specific metadata remain alive if the rmap walk drops mmu_lock to reschedule. The VFIO noncoherent-DMA path invokes kvm_arch_register_noncoherent_dma() without holding slots_lock or an SRCU read lock. kvm_zap_gfn_range() can then enter __walk_slot_rmaps(), which retains pointers to a memslot and its rmap while cond_resched_rwlock_write() temporarily drops mmu_lock. The race looks like this: CPU 0: VFIO coherency update CPU 1: memslot delete ---------------------------- --------------------- kvm_vfio_set_attr() kvm_arch_register_noncoherent_dma() kvm_zap_gfn_range() __walk_slot_rmaps() iterator.rmap = slot->arch.rmap cond_resched_rwlock_write() drop mmu_lock KVM_SET_USER_MEMORY_REGION(DELETE) kvm_arch_flush_shadow_memslot() zap SPTEs under mmu_lock kvm_swap_active_memslots() synchronize_srcu_expedited() kvm_free_memslot() vfree(slot->arch.rmap[i]) kfree(slot) reacquire mmu_lock slot_rmap_walk_next() read freed iterator.rmap The delete path is allowed to free the old memslot because the zap path holds no SRCU read lock. synchronize_srcu_expedited() therefore does not wait for the rmap walk before kvm_free_memslot() releases the old slot and its rmap array. When the zap resumes, slot_rmap_walk_next() reads from freed memory. KASAN reported: BUG: KASAN: vmalloc-out-of-bounds in slot_rmap_walk_next+0x82/0x1c0 Read of size 8 at addr ffffc900005c1008 Call Trace: slot_rmap_walk_next+0x82/0x1c0 __kvm_rmap_zap_gfn_range+0x17a/0x280 kvm_zap_gfn_range+0x2a6/0x6a0 kvm_vfio_set_attr+0x576/0x770 kvm_device_ioctl+0x1ff/0x3b0 __x64_sys_ioctl+0x134/0x1c0 Hold SRCU across the zap so that memslot deletion waits for the walk to finish before freeing the old slot, without changing zap behavior. Fixes: 362ff6dca541 ("KVM: x86/mmu: Zap KVM TDP when noncoherent DMA assignment starts/stops") Cc: stable@vger.kernel.org Signed-off-by: Chengfeng Ye --- arch/x86/kvm/x86.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 69469bbdc84a..2114553f3159 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -14092,8 +14092,12 @@ static void kvm_noncoherent_dma_assignment_start_or_stop(struct kvm *kvm) * * If KVM always honors guest PAT, however, there is nothing to do. */ - if (kvm_check_has_quirk(kvm, KVM_X86_QUIRK_IGNORE_GUEST_PAT)) + if (kvm_check_has_quirk(kvm, KVM_X86_QUIRK_IGNORE_GUEST_PAT)) { + int idx = srcu_read_lock(&kvm->srcu); + kvm_zap_gfn_range(kvm, gpa_to_gfn(0), gpa_to_gfn(~0ULL)); + srcu_read_unlock(&kvm->srcu, idx); + } } void kvm_arch_register_noncoherent_dma(struct kvm *kvm) -- 2.43.0