From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.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 1CE6D2E7BB4 for ; Fri, 20 Feb 2026 17:23:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771608198; cv=none; b=KnqcAF/kGJdMrxus7gK86CQdPZrRrxV4k9VH8sQg1/eM6HiQ9gbXs5NxP8y0aU0TkBwOT+hAwO0VqKkc4a7x7KYANutUShEWg1MJZ43Z05rU3RTyji+QzX8efwvlO2be6kJCPyAtlY0UR1Izwku7uHFk4iIwSNUS9SSNQzBM7Qk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771608198; c=relaxed/simple; bh=N4vvYLmbSC+lWZdiZowMt5Dnv4enGTpeHrDlBx83/vM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Vg3KrtzS7fAOsZWiBqUs0skjwWqCd/MsGm3ZYQZpYZSsMDVAIP8qfiiG4OqE8cQfsqXkt78myBKFemgP/WU9NsdQC0lpKAMIvespYTBNIYXBE7T1AojNrY8QiwUKflFDCY9H5xBEaSLB8e+OE9S6qQ0DgNStkv2TCSM9esaF7rE= 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=ls2Dc+GA; arc=none smtp.client-ip=209.85.214.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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ls2Dc+GA" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2a7d7b87977so25244945ad.0 for ; Fri, 20 Feb 2026 09:23:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1771608195; x=1772212995; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=TscEQ0P2KNXXlEwZM4rO49aZdtxwBEkde4PwCpeJoWQ=; b=ls2Dc+GA0WOvgUWcg1B8CuA3i5sHapFXXY67LFbyjQ+W5JTwW35mzkRYnQ03xFeqTf hJyCpL5eDELBkR0yhOmr20dLkQDSMVjIGpufaLFQLFB8tXTWk3QBdljESbeLRIpVowGk K24Q+9ALBGE1PRyzmxCZUxN+EP5x4Rt8cJHLRBio68FzwNqIjWZguTu0dFXgsjPG1Jex I//f6AsOiKz2P+ksarhGunemwL0bkwnyLIHhWJDNhP8xEkptMiRXmxICWD0JILuy4Uf+ gxZZhd38l/sVKM/De1hcpJTtaUCnE17y+C6La55mFrvom3JRZLS7dXmdrknSIEtgQyuJ 3MBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771608195; x=1772212995; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=TscEQ0P2KNXXlEwZM4rO49aZdtxwBEkde4PwCpeJoWQ=; b=JPtwxBgYSfeADT9KUTIWs6VEE3rX5GO5BUU/mBojvPe/nbqDNQbV2ddktk3ZY11iQV TOX7esVnfV8+89URGuIXuZ8qjlQVKmIgXhPJjeypsg9bYE1pb56GYLEdA6hcvyKwoh8a 2bwXW2EvINMiBsOqYpOq4oFewlfILoMQpIwnilJpRvfMZ5ZCWYpxcVFIzXUpOc6QnKTI c8nD96AklINyTtf5sawvqYfVG91cdoTqmVzLAam+KnwrV+KrCKFQ4fa1ZL6N17PqX+S+ JKFQmESQa4R6+WfXfuIYMg97zsCQyzPRNQ7vl5+H21oi2MYRRxahZQyuHacfNu8kAhm0 4M3w== X-Forwarded-Encrypted: i=1; AJvYcCW4c7vbGuTc5Xtsz/4gyAWonbr9RpUOsvQ6TzpJzGhKONoL/IYjVxLFNyY887wPu4Xp3XcvSxcIIVvCo4Q=@vger.kernel.org X-Gm-Message-State: AOJu0Yy/ZXttTLRsSXPAiOdsQVyDMiiZMjiZ5XRI0LIoqEBoYNMd1gmV dDCWLn8zju+clfMlNIbc11uw+dM4l6ZVHh6kn3k+C7KI5NCS9yCNspaTvKrG4Kr7pcih4z+GRXk uTashFA== X-Received: from plsb22.prod.google.com ([2002:a17:902:b616:b0:2a0:f0e5:b144]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:e852:b0:2a9:cb10:42b with SMTP id d9443c01a7336-2ad7452f39amr2369645ad.44.1771608195306; Fri, 20 Feb 2026 09:23:15 -0800 (PST) Date: Fri, 20 Feb 2026 09:23:13 -0800 In-Reply-To: <00a7a31b-573b-4d92-91f8-7d7e2f88ea48@tum.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <00a7a31b-573b-4d92-91f8-7d7e2f88ea48@tum.de> Message-ID: Subject: Re: [PATCH] x86/hyper-v: Validate entire GVA range for non-canonical addresses during PV TLB flush From: Sean Christopherson To: Manuel Andreas Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Vitaly Kuznetsov , Paolo Bonzini Content-Type: text/plain; charset="us-ascii" +Vitaly and Paolo Please use scripts/get_maintainer.pl, otherwise your emails might not reach the right eyeballs. On Thu, Feb 19, 2026, Manuel Andreas wrote: > In KVM guests with Hyper-V hypercalls enabled, the hypercalls > HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST and HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX > allow a guest to request invalidation of portions of a virtual TLB. > For this, the hypercall parameter includes a list of GVAs that are supposed > to be invalidated. > > Currently, only the base GVA is checked to be canonical. In reality, > this check needs to be performed for the entire range of GVAs. > This still enables guests running on Intel hardware to trigger a > WARN_ONCE in the host (see prior commit below). > > This patch simply moves the check for non-canonical addresses to be > performed for every single GVA of the supplied range. This should also > be more in line with the Hyper-V specification, since, although > unlikely, a range starting with an invalid GVA may still contain > GVAs that are valid. > > Fixes: fa787ac07b3c ("KVM: x86/hyper-v: Skip non-canonical addresses during PV TLB flush") > Signed-off-by: Manuel Andreas > --- > arch/x86/kvm/hyperv.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c > index de92292eb1f5..f4f6accf1a33 100644 > --- a/arch/x86/kvm/hyperv.c > +++ b/arch/x86/kvm/hyperv.c > @@ -1981,16 +1981,17 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) > if (entries[i] == KVM_HV_TLB_FLUSHALL_ENTRY) > goto out_flush_all; > > - if (is_noncanonical_invlpg_address(entries[i], vcpu)) > - continue; > - > /* > * Lower 12 bits of 'address' encode the number of additional > * pages to flush. > */ > gva = entries[i] & PAGE_MASK; > - for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) > + for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) { > + if (is_noncanonical_invlpg_address(gva + j * PAGE_SIZE, vcpu)) > + continue; > + > kvm_x86_call(flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE); > + } Vitaly, can we treat the entire request as garbage and throw it away if any part isn't valid? Or do you think we should go with the more conservative approach as above? diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index de92292eb1f5..f568f3d4f6e5 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1967,8 +1967,8 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) struct kvm_vcpu_hv_tlb_flush_fifo *tlb_flush_fifo; struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); u64 entries[KVM_HV_TLB_FLUSH_FIFO_SIZE]; + gva_t gva, extra_pages; int i, j, count; - gva_t gva; if (!tdp_enabled || !hv_vcpu) return -EINVAL; @@ -1978,18 +1978,22 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) count = kfifo_out(&tlb_flush_fifo->entries, entries, KVM_HV_TLB_FLUSH_FIFO_SIZE); for (i = 0; i < count; i++) { + if (entries[i] == KVM_HV_TLB_FLUSHALL_ENTRY) goto out_flush_all; - if (is_noncanonical_invlpg_address(entries[i], vcpu)) - continue; - /* * Lower 12 bits of 'address' encode the number of additional * pages to flush. */ gva = entries[i] & PAGE_MASK; - for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) + extra_pages = (entries[i] & ~PAGE_MASK); + + if (is_noncanonical_invlpg_address(gva, vcpu) || + is_noncanonical_invlpg_address(gva + extra_pages * PAGE_SIZE)) + continue; + + for (j = 0; j < extra_pages + 1; j++) kvm_x86_call(flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE); ++vcpu->stat.tlb_flush;