Received: by 2002:ab2:69cc:0:b0:1f4:be93:e15a with SMTP id n12csp1082683lqp; Sun, 14 Apr 2024 13:31:22 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVqVHUvl8Td85/2eJg+Tnv3+WiwtoW8DzyNRq97z364e3vKwqSdnT0TXYd1Ie0FsUh5x9cGigqBO7xULGw0E4p3QnDfVdqVRLY0mNlXYw== X-Google-Smtp-Source: AGHT+IHNtWscSL0GMnPiUkm9o+706aPoyXFycw7KGreb8ZKQRPULGc4y8FDK9GPWERBYCZro+RI4 X-Received: by 2002:aca:100e:0:b0:3c5:f87b:684 with SMTP id 14-20020aca100e000000b003c5f87b0684mr9264098oiq.15.1713126682180; Sun, 14 Apr 2024 13:31:22 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1713126682; cv=pass; d=google.com; s=arc-20160816; b=gn/BQHLTnIvC5nhKD66BkAjFydWwCNcUpT80vTA9g5ytwR8qEF1Y4V8OmjkTJSenZ0 8OjOGOFAefRhwK0OICD/9iNAS3cMpve3zuSJKOcJonMPdfZP28VLEwG9XsLLyAwSx+vo SaO4oDbHqMgbrWgjkUYjx3+Y27iP1B1KRM0kcX3NIZlhQeU4AcPcFjKzUJ2IBcTfaKcX 4EzqEjkKF1fVye3zNOxgDF4D84Xx8ddDomjDmR237OM0/a8siqvGXEFRTuhO2/XEE9cK s84BuoNeH9zF/2gUH+GNRWumUVb3vZ8lqSFJvbb1zI0i2uBFINKUlVVv6+/324evkIdn x25Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:precedence:robot-unsubscribe:robot-id :message-id:mime-version:list-unsubscribe:list-subscribe:list-id :precedence:references:in-reply-to:cc:subject:to:reply-to:sender :from:dkim-signature:dkim-signature:date; bh=eLrfnERQ94x41+EaIQSuqj1gV6EWrsba9MRHny86r2E=; fh=ArUdKlFqBl0xOVDLSGVnlEtCmC2s6YLqSVksjl6nkg0=; b=eDSnKVS0dCW3YPOcnMzo2Dq2oRK4Bl0ziTdUfXhjXOSrV+ykdMRjf1Z/3eCC/FP3wY /gUJVQmMpUFk6VU+yFU20Fdt5SS3lWMPoIY7qFFEFEUmavNjdeT0ExGlness286j370+ mPuajDfiPV/jFAEA7DZPKsFYqQhW2CZiHUV8BznSy3i27N9hbu6/Hqf46MJQf2O8HHlB TAraHKSs8XF14rpxdqSwMHWouNmDW/JJfLjRd9L5I9+TfKD26ZXGdExq6SvDz5aPHXH3 02HIE7pfso8pM6y2Qp3tvyYBFm75o/QHJogmt0qJbaqxlQMt+6JzXvp+9DtiZUbgIfJN cY+A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=LBvUta7C; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; arc=pass (i=1 spf=pass spfdomain=linutronix.de dkim=pass dkdomain=linutronix.de dmarc=pass fromdomain=linutronix.de); spf=pass (google.com: domain of linux-kernel+bounces-144368-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-144368-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id y12-20020a05622a164c00b004365cbc30c5si8668381qtj.39.2024.04.14.13.31.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 14 Apr 2024 13:31:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-144368-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=LBvUta7C; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; arc=pass (i=1 spf=pass spfdomain=linutronix.de dkim=pass dkdomain=linutronix.de dmarc=pass fromdomain=linutronix.de); spf=pass (google.com: domain of linux-kernel+bounces-144368-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-144368-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de 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 ny.mirrors.kernel.org (Postfix) with ESMTPS id CBF481C20D5B for ; Sun, 14 Apr 2024 20:31:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 345F8136E31; Sun, 14 Apr 2024 20:31:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="LBvUta7C"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="DN9FqJNR" Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73B38179BD; Sun, 14 Apr 2024 20:31:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713126666; cv=none; b=IHaQs9Vr6gdEiUiHUNsifucoaLy3sVoZ+Hi8DNgoGgOA+ofqIf+RuAxMA7YxWXfWEudOwAdGAlPy96eSIb+FwHh8Y1qGUT1cew5qk4TYJc5hPGJkhdkshv/xSi5G9FfH3h3mQfP3gV6a70HVNm97VlS2aWcx+jnTjGmQ+kww4ws= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713126666; c=relaxed/simple; bh=o6IXzeU3JlDncJq0wgKgzRbREI3IG9CC/YN6ms32ZpM=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=QHjk7VIUGMeFKQkiXas0CDbgu8lDRm4bCz5LTkJMuNZo02uzv3YUeBG6VOhHmAdqk0JuQpDnyGzipdZAlnIwJ+arKKH4fg8yCL8E7urgdug3h9xD+/UurodYLCKrAb4tKCDNfPWwR19y2l4JdxCe3NRO8onGISpCKVV4BPnoO0M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=LBvUta7C; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=DN9FqJNR; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Date: Sun, 14 Apr 2024 20:30:59 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1713126660; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eLrfnERQ94x41+EaIQSuqj1gV6EWrsba9MRHny86r2E=; b=LBvUta7C8839nn7Pm0QXF/VOW4O8K6dOq9deAj8TIJ5w0hMB8t7j9xiktzuq4uEnEWeUDE vyiSVxqcZvrWG2FojqVqkOyze9BN2deFNDwR+fR8b/u/PcazusM+stim4GBogJZiIgEu9x zoWjUOFRBsEP5eSO/2ihiVeYKJAjg/LA/qD0008emsk/N3no7xyw/Q8jKwP2KuPVx8QJAl 3k0/pXNYzU+ly0kOWlWqfDQMBDe2xveF87N9BTx+hmwMmfbFYxX5t+76LiSN6IqrJLNLDF glzUaxOczblYRlq2gDNsR6SMKCtyyZfsDmDlhM4UQLFt3vqquBJzb3mrkmaL3g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1713126660; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eLrfnERQ94x41+EaIQSuqj1gV6EWrsba9MRHny86r2E=; b=DN9FqJNRysQWo+g6iN5SO5+aYL2+oPG6W1wlS5APN1yTXBo4VWzqZ9oogBBsvFasGk1x+6 +kZVQ2d7V23Nl3AA== From: "tip-bot2 for Juergen Gross" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/mm] x86/pat: Fix W^X violation false-positives when running as Xen PV guest Cc: Jason Andryuk , Juergen Gross , Ingo Molnar , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20240412151258.9171-5-jgross@suse.com> References: <20240412151258.9171-5-jgross@suse.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <171312665911.10875.634353281532361733.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit The following commit has been merged into the x86/mm branch of tip: Commit-ID: 5bc8b0f5dac04cd4ebe47f8090a5942f2f2647ef Gitweb: https://git.kernel.org/tip/5bc8b0f5dac04cd4ebe47f8090a5942f2f2647ef Author: Juergen Gross AuthorDate: Fri, 12 Apr 2024 17:12:58 +02:00 Committer: Ingo Molnar CommitterDate: Sun, 14 Apr 2024 22:16:30 +02:00 x86/pat: Fix W^X violation false-positives when running as Xen PV guest When running as Xen PV guest in some cases W^X violation WARN()s have been observed. Those WARN()s are produced by verify_rwx(), which looks into the PTE to verify that writable kernel pages have the NX bit set in order to avoid code modifications of the kernel by rogue code. As the NX bits of all levels of translation entries are or-ed and the RW bits of all levels are and-ed, looking just into the PTE isn't enough for the decision that a writable page is executable, too. When running as a Xen PV guest, the direct map PMDs and kernel high map PMDs share the same set of PTEs. Xen kernel initialization will set the NX bit in the direct map PMD entries, and not the shared PTEs. Fixes: 652c5bf380ad ("x86/mm: Refuse W^X violations") Reported-by: Jason Andryuk Signed-off-by: Juergen Gross Signed-off-by: Ingo Molnar Link: https://lore.kernel.org/r/20240412151258.9171-5-jgross@suse.com --- arch/x86/mm/pat/set_memory.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 4ebccaf..19fdfbb 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -619,7 +619,8 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long start, * Validate strict W^X semantics. */ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long start, - unsigned long pfn, unsigned long npg) + unsigned long pfn, unsigned long npg, + bool nx, bool rw) { unsigned long end; @@ -641,6 +642,10 @@ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long star if ((pgprot_val(new) & (_PAGE_RW | _PAGE_NX)) != _PAGE_RW) return new; + /* Non-leaf translation entries can disable writing or execution. */ + if (!rw || nx) + return new; + end = start + npg * PAGE_SIZE - 1; WARN_ONCE(1, "CPA detected W^X violation: %016llx -> %016llx range: 0x%016lx - 0x%016lx PFN %lx\n", (unsigned long long)pgprot_val(old), @@ -742,7 +747,7 @@ pte_t *lookup_address(unsigned long address, unsigned int *level) EXPORT_SYMBOL_GPL(lookup_address); static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address, - unsigned int *level) + unsigned int *level, bool *nx, bool *rw) { pgd_t *pgd; @@ -751,7 +756,7 @@ static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address, else pgd = cpa->pgd + pgd_index(address); - return lookup_address_in_pgd(pgd, address, level); + return lookup_address_in_pgd_attr(pgd, address, level, nx, rw); } /* @@ -879,12 +884,13 @@ static int __should_split_large_page(pte_t *kpte, unsigned long address, pgprot_t old_prot, new_prot, req_prot, chk_prot; pte_t new_pte, *tmp; enum pg_level level; + bool nx, rw; /* * Check for races, another CPU might have split this page * up already: */ - tmp = _lookup_address_cpa(cpa, address, &level); + tmp = _lookup_address_cpa(cpa, address, &level, &nx, &rw); if (tmp != kpte) return 1; @@ -995,7 +1001,8 @@ static int __should_split_large_page(pte_t *kpte, unsigned long address, new_prot = static_protections(req_prot, lpaddr, old_pfn, numpages, psize, CPA_DETECT); - new_prot = verify_rwx(old_prot, new_prot, lpaddr, old_pfn, numpages); + new_prot = verify_rwx(old_prot, new_prot, lpaddr, old_pfn, numpages, + nx, rw); /* * If there is a conflict, split the large page. @@ -1076,6 +1083,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address, pte_t *pbase = (pte_t *)page_address(base); unsigned int i, level; pgprot_t ref_prot; + bool nx, rw; pte_t *tmp; spin_lock(&pgd_lock); @@ -1083,7 +1091,7 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address, * Check for races, another CPU might have split this page * up for us already: */ - tmp = _lookup_address_cpa(cpa, address, &level); + tmp = _lookup_address_cpa(cpa, address, &level, &nx, &rw); if (tmp != kpte) { spin_unlock(&pgd_lock); return 1; @@ -1624,10 +1632,11 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) int do_split, err; unsigned int level; pte_t *kpte, old_pte; + bool nx, rw; address = __cpa_addr(cpa, cpa->curpage); repeat: - kpte = _lookup_address_cpa(cpa, address, &level); + kpte = _lookup_address_cpa(cpa, address, &level, &nx, &rw); if (!kpte) return __cpa_process_fault(cpa, address, primary); @@ -1649,7 +1658,8 @@ repeat: new_prot = static_protections(new_prot, address, pfn, 1, 0, CPA_PROTECT); - new_prot = verify_rwx(old_prot, new_prot, address, pfn, 1); + new_prot = verify_rwx(old_prot, new_prot, address, pfn, 1, + nx, rw); new_prot = pgprot_clear_protnone_bits(new_prot);