Received: by 2002:ab2:620c:0:b0:1ef:ffd0:ce49 with SMTP id o12csp1216119lqt; Tue, 19 Mar 2024 17:16:10 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVeoDjLBF7hMLRxVt20XeMnANyuqhpEx+pBskp7mmSyeDg+7lBoMGYjzydUMCeDQZKHqxZoJspSMMfx6xQAk7vLA8iOb27YT1K1Qg68GQ== X-Google-Smtp-Source: AGHT+IEs2+/fPwo3bMXminYVMpEHfSnyOXMt+5vv7wXP63XnxLVjkO/4N6mf45eDKGBq3a/73DS8 X-Received: by 2002:a05:6a00:23d5:b0:6e6:8b59:1bad with SMTP id g21-20020a056a0023d500b006e68b591badmr669085pfc.25.1710893770174; Tue, 19 Mar 2024 17:16:10 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1710893770; cv=pass; d=google.com; s=arc-20160816; b=dRfMl1mZ9rJkBHkF6ik2e/S7eVWKPyt9vmU4Ida70lEE8YOlDOW3nnoYUZbbyQ4F9m t9Da845jehPQXRz29iHqKWjWWg9gGCc9d25u9EBh98tJ9PHDxivCMdp0WtP4ZiQo6SN9 e+cdp8XFXOaMHfK8PIt2w8W/Kkdl2zVwuE6zhwbrUUvjocSxugxl4t2m0Aa21ZHd87Ps 75jZYdvB2ndu2M11PdAJiYFsTPixcD/FxP7kQh2kqEe31D+FpcKwViwbt6G1ixs64WhZ 2JyOcL0j2ld0oFhZ3BJMJXSS9xjKFUqwpG92Nzvg17Tft6P99bqeUEO7TULHzd0CHvhQ tL0w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :reply-to:dkim-signature; bh=i9kVuQFqGWveMSm1GQ8GItZlMlvWOz6Hx+yWjI9J9D0=; fh=1aaOf/Z1Jt4tpqr0j1iNdUoKLFX8J8y1L3Q3C6izV4k=; b=AA0PknXjujgCFcY8IdjmKeEx+z6gv1QT7AbgC5ZG7hie8tXv7ew4PgBvcv38PT0+jo DoAoX/x9FdsFFeSFTAiWoM+FqGivLtBerwp2OjlODmlT8cP47rEWabtvSeh8E/u5hP9B EcEWZ0HSiK4hppeskDaaIXIVAXm0f5Xhj5ZvKzbVqugED0Xs0nVG0xRNR5toXA/dqEmJ tL//zBh3Xr1u6N9pD0ETaEgkWC/EIy4Yk7cqV5GuXyBKL3Wg4UzX89I1foc/bLz85oO6 KHv9izdW6l2bhATgwZAWSeLV9rhZoTkDmu/qmYUqClHzoXXkS0tavdobLuReCjL4x+XG jn1g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=dft+e1h4; arc=pass (i=1 spf=pass spfdomain=flex--seanjc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-108256-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-108256-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id h14-20020aa786ce000000b006e68d125d7fsi11662033pfo.110.2024.03.19.17.16.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Mar 2024 17:16:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-108256-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=dft+e1h4; arc=pass (i=1 spf=pass spfdomain=flex--seanjc.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-108256-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-108256-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 82DDD284136 for ; Wed, 20 Mar 2024 00:16:09 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 59B963C2C; Wed, 20 Mar 2024 00:15:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dft+e1h4" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (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 B3C4B812 for ; Wed, 20 Mar 2024 00:15:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710893749; cv=none; b=FGsGa6HgCZBA+LrXd/HjBXMxniFOdbb4b1QmtZtNL689qm63sfl4cuYjrr+RKHkhrO3l8Wtv04buJCIpu4eyqpECUyImpuKiRT/RwSAk3tRuhoPuxRywp79aSatdRFWQB5LKp2LDPB/kUaa8qjZ5jft5w4HX2z1f81oayf70X9M= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710893749; c=relaxed/simple; bh=YyvaQnQJdiY8Q7R4CiMT+UezwhRShOi5cPHWawz2f9s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=liQClu3iyTuzo7sgUT/iTU89HwOaQln5S1cpgEeQUKCEZZ0ot1uADdAqkHuv28AhQghhNmPfN1cEPHi/DnmTUIOtWRPrWXyiSheD3TqG066QLFbDCRU3c31GTkLlwQZYdvXI51NrmZI4KV4ydBHP5nBqmPmOdmm4ShynJfrmem0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dft+e1h4; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60a2b53b99eso133896307b3.3 for ; Tue, 19 Mar 2024 17:15:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1710893746; x=1711498546; darn=vger.kernel.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=i9kVuQFqGWveMSm1GQ8GItZlMlvWOz6Hx+yWjI9J9D0=; b=dft+e1h4Nh8crW2PYZK9Wc/PQ3LW8gKEhxHBn0x64lcmPtwmgTIW21PgdkJ5S42sS/ Pmlcadj0i4zwmPC1fx5sFT3boRtHkaV3jogEkosH/84RWf1nGwB9Sr6xtk3vHuO2dmLO WNyCeHEgy/5Be4Tl9LzRkX1AuVXcnAGwhsw2ezspFv0MFKQavvxySNpZzQlAmF6KbhQu JF46oCgdu5DbrC3IbFadILDqW6xUnfXjqw6zcBY40NCxmm8ey6DUaQkgvLXPIYnesBEL UUfbP8gv/yVvEyBij/bRHX3ejd96LVCEv79BVUyBaTKGlaP4EL8eAHlEtuk9DHgIlTGu DzEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710893746; x=1711498546; 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=i9kVuQFqGWveMSm1GQ8GItZlMlvWOz6Hx+yWjI9J9D0=; b=Q6IV4GpWMXp+NtHQz/y160zDyMv/HphZdbIKRDM/QgStMmv4gwKxbjotnzosObdkED Sy4zbnuBOiPsL1xBTQJxdkEfTHmyq9o+yDIJ0oBDCLTvzYRRXRIAUvk02hv/k1gMpOB3 zpzSlmboRrQaJw6Orx+hArIiq/jeX/DQI8Cxnk8cqrq02/bPF4j3D22HvVdRO6vItFRu hzHxGXFFBXgvPFXmTL6FsXjz4lnRdSD4J0rmvrwXKRs/08CbORDgFbol5bsoOLj0oLlT zy5ZRayF45a31qRIiNmFUy/jNqb6PGyQgjGZEcphh79DknUR57IyFE5Aov8yDPQCy7kM wspg== X-Forwarded-Encrypted: i=1; AJvYcCVS3QNVShqpKBPtrilvfbvZj9vbPN/XNL/K+mdwNDqAynAZ2Wm5fGY/xhFqIG0ifdYNNA/wq4oCaQttpgf+Z4zF0MkeSDSaWZs53iH6 X-Gm-Message-State: AOJu0Yx6XBSwQRpzFricB7nSyBhRWrHLEIAAPbfL8Yg0Va2HKYc7EA7H znA9JwGHdY5lcqpfogCwQcCkFIs23gf+yWa0yf5g0r+HtFeygyfImOwuY0FDVaBtC13RGjonOso FFw== X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a05:6902:1507:b0:dcd:ad52:6932 with SMTP id q7-20020a056902150700b00dcdad526932mr4330305ybu.5.1710893746735; Tue, 19 Mar 2024 17:15:46 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 19 Mar 2024 17:15:40 -0700 In-Reply-To: <20240320001542.3203871-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240320001542.3203871-1-seanjc@google.com> X-Mailer: git-send-email 2.44.0.291.gc1ea87d7ee-goog Message-ID: <20240320001542.3203871-2-seanjc@google.com> Subject: [PATCH 1/3] KVM: Add helpers to consolidate gfn_to_pfn_cache's page split check From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Sean Christopherson , syzbot+106a4f72b0474e1d1b33@syzkaller.appspotmail.com, David Woodhouse , Paul Durrant Content-Type: text/plain; charset="UTF-8" Add a helper to check that the incoming length for a gfn_to_pfn_cache is valid with respect to the cache's GPA and/or HVA. To avoid activating a cache with a bogus GPA, a future fix will fork the page split check in the inner refresh path into activate() and the public rerfresh() APIs, at which point KVM will check the length in three separate places. Deliberately keep the "page offset" logic open coded, as the only other path that consumes the offset, __kvm_gpc_refresh(), already needs to differentiate between GPA-based and HVA-based caches, and it's not obvious that using a helper is a net positive in overall code readability. Note, for GPA-based caches, this has a subtle side effect of using the GPA instead of the resolved HVA in the check() path, but that should be a nop as the HVA offset is derived from the GPA, i.e. the two offsets are identical, barring a KVM bug. Signed-off-by: Sean Christopherson --- virt/kvm/pfncache.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c index 4e07112a24c2..8f2121b5f2a0 100644 --- a/virt/kvm/pfncache.c +++ b/virt/kvm/pfncache.c @@ -57,6 +57,19 @@ void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, unsigned long start, spin_unlock(&kvm->gpc_lock); } +static bool kvm_gpc_is_valid_len(gpa_t gpa, unsigned long uhva, + unsigned long len) +{ + unsigned long offset = kvm_is_error_gpa(gpa) ? offset_in_page(uhva) : + offset_in_page(gpa); + + /* + * The cached access must fit within a single page. The 'len' argument + * to activate() and refresh() exists only to enforce that. + */ + return offset + len <= PAGE_SIZE; +} + bool kvm_gpc_check(struct gfn_to_pfn_cache *gpc, unsigned long len) { struct kvm_memslots *slots = kvm_memslots(gpc->kvm); @@ -74,7 +87,7 @@ bool kvm_gpc_check(struct gfn_to_pfn_cache *gpc, unsigned long len) if (kvm_is_error_hva(gpc->uhva)) return false; - if (offset_in_page(gpc->uhva) + len > PAGE_SIZE) + if (!kvm_gpc_is_valid_len(gpc->gpa, gpc->uhva, len)) return false; if (!gpc->valid) @@ -247,13 +260,7 @@ static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned l if (WARN_ON_ONCE(kvm_is_error_gpa(gpa) == kvm_is_error_hva(uhva))) return -EINVAL; - /* - * The cached acces must fit within a single page. The 'len' argument - * exists only to enforce that. - */ - page_offset = kvm_is_error_gpa(gpa) ? offset_in_page(uhva) : - offset_in_page(gpa); - if (page_offset + len > PAGE_SIZE) + if (!kvm_gpc_is_valid_len(gpa, uhva, len)) return -EINVAL; lockdep_assert_held(&gpc->refresh_lock); @@ -270,6 +277,8 @@ static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned l old_uhva = PAGE_ALIGN_DOWN(gpc->uhva); if (kvm_is_error_gpa(gpa)) { + page_offset = offset_in_page(uhva); + gpc->gpa = INVALID_GPA; gpc->memslot = NULL; gpc->uhva = PAGE_ALIGN_DOWN(uhva); @@ -279,6 +288,8 @@ static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned l } else { struct kvm_memslots *slots = kvm_memslots(gpc->kvm); + page_offset = offset_in_page(gpa); + if (gpc->gpa != gpa || gpc->generation != slots->generation || kvm_is_error_hva(gpc->uhva)) { gfn_t gfn = gpa_to_gfn(gpa); -- 2.44.0.291.gc1ea87d7ee-goog