From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A3B613976BD for ; Mon, 6 Apr 2026 21:33:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775511199; cv=none; b=mKZ2RbOCisLmswB/4NsTMtp0OcEFshwoluZukZ5WOYhOOBGy1Kta+PLlAe26Fgst0b13GkDPLEM0/b+y5fDKFWrdSQMTGKEZDOVr7sZ3ceFl6+1wjIY0L/FtiU9IGq8foAtDtRdXM5+yYLSJy0eM+pssl8/iHyvEwspL70qO3LI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775511199; c=relaxed/simple; bh=jtyulgU3jPnZB+wwVFVa/fuzQjdaB2omx+7UlCSxrnw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=sN7CucAsgppC+1KlQZ4EmYImn+rGfw0tj8ipg75qW+6EVNG8WfjxTkc6SXLiBFsLZvIa2BVnAo2+Tuu8s2rn+5SKgbIhI1zXslg1avcjd91J3UKv8SkHRxlIfNz6SxAnT4B9umZetxPt4Yv4U3xI9JvZgNVE63SoCWBILgHuUP8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=O9JczRbz; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="O9JczRbz" Received: from linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net (linux.microsoft.com [13.77.154.182]) by linux.microsoft.com (Postfix) with ESMTPSA id DD7A220B710C; Mon, 6 Apr 2026 14:33:17 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com DD7A220B710C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1775511197; bh=X4Z/u0BPYRMqLs52XcLcvuYfZRh4JiZHKYBfZ5dQ7wg=; h=From:To:Cc:Subject:Date:From; b=O9JczRbzGjrgnNesBV28xXrzqGwYfcUroOs+rggyWVdNAg4cxLpjWBN37n+qhE9o2 hNc+Oi0tCULO36I221+G1Jgp8j4w4alMZZiAXlmWwFWhkh/ERUD6Keazel2C+y8UKh c2xrJeRoOL7XLHLddE4YOccUS1Inen+lvPABPWpk= From: Kameron Carr To: catalin.marinas@arm.com, will@kernel.org Cc: suzuki.poulose@arm.com, steven.price@arm.com, ryan.roberts@arm.com, dev.jain@arm.com, yang@os.amperecomputing.com, shijie@os.amperecomputing.com, kevin.brodsky@arm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH] arm64: mm: support set_memory_encrypted/decrypted for vmalloc addresses Date: Mon, 6 Apr 2026 14:33:17 -0700 Message-ID: <20260406213317.216171-1-kameroncarr@linux.microsoft.com> X-Mailer: git-send-email 2.43.7 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Currently __set_memory_enc_dec() only handles linear map (lm) addresses and returns -EINVAL for anything else. This means callers using vmalloc'd buffers cannot mark memory as shared/protected with the RMM via set_memory_decrypted()/set_memory_encrypted(). Extend the implementation to handle vmalloc (non-linear-map) addresses by introducing __set_va_addr_enc_dec(). For vmalloc addresses, the page table entries are not contiguous in the physical address space, so the function walks the vm_area's pages array and issues per-page RSI calls to transition each page between shared and protected states. The original linear-map path is factored out into __set_lm_addr_enc_dec(), and __set_memory_enc_dec() now dispatches to the appropriate helper based on whether the address is a linear map address. Signed-off-by: Kameron Carr --- arch/arm64/mm/pageattr.c | 74 +++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index ce035e1b4eaf..45058f61b957 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -275,20 +275,12 @@ int set_direct_map_default_noflush(struct page *page) PAGE_SIZE, set_mask, clear_mask); } -static int __set_memory_enc_dec(unsigned long addr, - int numpages, - bool encrypt) +static int __set_lm_addr_enc_dec(unsigned long addr, int numpages, bool encrypt) { unsigned long set_prot = 0, clear_prot = 0; phys_addr_t start, end; int ret; - if (!is_realm_world()) - return 0; - - if (!__is_lm_address(addr)) - return -EINVAL; - start = __virt_to_phys(addr); end = start + numpages * PAGE_SIZE; @@ -321,6 +313,70 @@ static int __set_memory_enc_dec(unsigned long addr, __pgprot(PTE_PRESENT_INVALID)); } +static int __set_va_addr_enc_dec(unsigned long addr, int numpages, bool encrypt) +{ + unsigned long set_prot = 0, clear_prot = 0, start_idx; + struct vm_struct *area; + int i, ret; + + if (encrypt) + clear_prot = PROT_NS_SHARED; + else + set_prot = PROT_NS_SHARED; + + area = find_vm_area((void *)addr); + if (!area) + return -EINVAL; + + start_idx = ((unsigned long)kasan_reset_tag((void *)addr) - + (unsigned long)kasan_reset_tag(area->addr)) >> + PAGE_SHIFT; + + if (start_idx + numpages > area->nr_pages) + return -EINVAL; + + /* + * Break the mapping before we make any changes to avoid stale TLB + * entries or Synchronous External Aborts caused by RIPAS_EMPTY + */ + ret = change_memory_common(addr, numpages, + __pgprot(set_prot | PTE_PRESENT_INVALID), + __pgprot(clear_prot | PTE_PRESENT_VALID_KERNEL)); + + if (ret) + return ret; + + for (i = 0; i < numpages; i++) { + struct page *page = area->pages[start_idx + i]; + phys_addr_t phys = page_to_phys(page); + + if (encrypt) { + ret = rsi_set_memory_range_protected(phys, + phys + PAGE_SIZE); + } else { + ret = rsi_set_memory_range_shared(phys, + phys + PAGE_SIZE); + } + if (ret) + return ret; + } + + return change_memory_common(addr, numpages, + __pgprot(PTE_PRESENT_VALID_KERNEL), + __pgprot(PTE_PRESENT_INVALID)); +} + +static int __set_memory_enc_dec(unsigned long addr, int numpages, bool encrypt) +{ + if (!is_realm_world()) + return 0; + + if (!__is_lm_address(addr)) + return __set_va_addr_enc_dec(addr, numpages, encrypt); + + return __set_lm_addr_enc_dec(addr, numpages, encrypt); +} + static int realm_set_memory_encrypted(unsigned long addr, int numpages) { int ret = __set_memory_enc_dec(addr, numpages, true); base-commit: 25f6040ca43a78048466b949994b8d637fe2fe07 -- 2.45.4