ASI has a separate PGD for the physmap, which needs to be kept in sync
with the unrestricted physmap with respect to permissions.
Since only the direct map is currently populated in that address space,
just ignore everything else. Handling of holes in that map is left
behaving the same as the unrestricted pagetables.
Co-developed-by: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: Brendan Jackman <jackmanb@google.com>
---
arch/x86/mm/pat/set_memory.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index d2d54b8c4dbb04cf276d074ddee3ffde2f48e381..53c3ac0ba55d6b6992db6f6761ffdfbd52bf3688 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -3,6 +3,7 @@
* Copyright 2002 Andi Kleen, SuSE Labs.
* Thanks to Ben LaHaise for precious feedback.
*/
+#include <linux/asi.h>
#include <linux/highmem.h>
#include <linux/memblock.h>
#include <linux/sched.h>
@@ -1780,6 +1781,11 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
cpa->numpages = ret;
return 0;
}
+static inline bool is_direct_map(unsigned long vaddr)
+{
+ return within(vaddr, PAGE_OFFSET,
+ PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT));
+}
static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
int primary)
@@ -1808,8 +1814,7 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
* one virtual address page and its pfn. TBD: numpages can be set based
* on the initial value and the level returned by lookup_address().
*/
- if (within(vaddr, PAGE_OFFSET,
- PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
+ if (is_direct_map(vaddr)) {
cpa->numpages = 1;
cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
return 0;
@@ -1981,6 +1986,27 @@ static int cpa_process_alias(struct cpa_data *cpa)
return 0;
}
+/*
+ * Having updated the unrestricted PGD, reflect this change in the ASI
+ * restricted address space too.
+ */
+static inline int mirror_asi_direct_map(struct cpa_data *cpa, int primary)
+{
+ struct cpa_data asi_cpa = *cpa;
+
+ if (!asi_enabled_static())
+ return 0;
+
+ /* Only need to do this for the real unrestricted direct map. */
+ if ((cpa->pgd && cpa->pgd != init_mm.pgd) || !is_direct_map(*cpa->vaddr))
+ return 0;
+ VM_WARN_ON_ONCE(!is_direct_map(*cpa->vaddr + (cpa->numpages * PAGE_SIZE)));
+
+ asi_cpa.pgd = asi_nonsensitive_pgd;
+ asi_cpa.curpage = 0;
+ return __change_page_attr(cpa, primary);
+}
+
static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
{
unsigned long numpages = cpa->numpages;
@@ -2007,6 +2033,8 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
if (!debug_pagealloc_enabled())
spin_lock(&cpa_lock);
ret = __change_page_attr(cpa, primary);
+ if (!ret)
+ ret = mirror_asi_direct_map(cpa, primary);
if (!debug_pagealloc_enabled())
spin_unlock(&cpa_lock);
if (ret)
--
2.50.1
On 9/24/25 07:59, Brendan Jackman wrote:
> ASI has a separate PGD for the physmap, which needs to be kept in sync
> with the unrestricted physmap with respect to permissions.
So that leads to another thing... What about vmalloc()? Why doesn't it
need to be in the ASI pgd?
> +static inline bool is_direct_map(unsigned long vaddr)
> +{
> + return within(vaddr, PAGE_OFFSET,
> + PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT));
> +}
>
> static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
> int primary)
> @@ -1808,8 +1814,7 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
> * one virtual address page and its pfn. TBD: numpages can be set based
> * on the initial value and the level returned by lookup_address().
> */
> - if (within(vaddr, PAGE_OFFSET,
> - PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
> + if (is_direct_map(vaddr)) {
> cpa->numpages = 1;
> cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
> return 0;
> @@ -1981,6 +1986,27 @@ static int cpa_process_alias(struct cpa_data *cpa)
> return 0;
> }
>
> +/*
> + * Having updated the unrestricted PGD, reflect this change in the ASI
> + * restricted address space too.
> + */
> +static inline int mirror_asi_direct_map(struct cpa_data *cpa, int primary)
> +{
> + struct cpa_data asi_cpa = *cpa;
> +
> + if (!asi_enabled_static())
> + return 0;
> +
> + /* Only need to do this for the real unrestricted direct map. */
> + if ((cpa->pgd && cpa->pgd != init_mm.pgd) || !is_direct_map(*cpa->vaddr))
> + return 0;
> + VM_WARN_ON_ONCE(!is_direct_map(*cpa->vaddr + (cpa->numpages * PAGE_SIZE)));
> +
> + asi_cpa.pgd = asi_nonsensitive_pgd;
> + asi_cpa.curpage = 0;
Please document what functionality this curpage=0 has. It's not clear.
> + return __change_page_attr(cpa, primary);
> +}
But let's say someone is doing something silly like:
set_memory_np(addr, size);
set_memory_p(addr, size);
Won't that end up in here and make the "unrestricted PGD" have
_PAGE_PRESENT==1 entries?
Also, could we try and make the nomenclature consistent? We've got
"unrestricted direct map" and "asi_nonsensitive_pgd" being used (at
least). Could the terminology be made more consistent?
One subtle thing here is that it's OK to allocate memory here when
mirroring changes into 'asi_nonsensitive_pgd'. It's just not OK when
flipping sensitivity. That seems worth a comment.
> static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
> {
> unsigned long numpages = cpa->numpages;
> @@ -2007,6 +2033,8 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
> if (!debug_pagealloc_enabled())
> spin_lock(&cpa_lock);
> ret = __change_page_attr(cpa, primary);
> + if (!ret)
> + ret = mirror_asi_direct_map(cpa, primary);
> if (!debug_pagealloc_enabled())
> spin_unlock(&cpa_lock);
> if (ret)
>
Is cpa->pgd ever have any values other than NULL or init_mm->pgd? I
didn't see anything in a quick grep.
On Wed Oct 1, 2025 at 8:50 PM UTC, Dave Hansen wrote:
> On 9/24/25 07:59, Brendan Jackman wrote:
>> ASI has a separate PGD for the physmap, which needs to be kept in sync
>> with the unrestricted physmap with respect to permissions.
>
> So that leads to another thing... What about vmalloc()? Why doesn't it
> need to be in the ASI pgd?
Oh yeah it does. For the "actually entering the restricted addres space"
patchset, I'll include logic that just shares that region between the
unrestricted and restricted address space, something like this:
https://github.com/torvalds/linux/commit/04fd7a0b0098af48f2f8d9c0343b1edd12987681#diff-ecb3536ec179c07d4b4b387e58e62a9a6e553069cfed22a73448eb2ce5b82aa6R637-R669
Later, we'll want to be able to protect subsets of the vmalloc area
(i.e. unmap them from the restricted address space) too, but that's
something we can think about later I think. Unless I'm mistaken it's
much simpler than for the direct map. Junaid had a minumal solution for
that in his 2022 RFC [0]:
[0] https://lore.kernel.org/all/20220223052223.1202152-12-junaids@google.com/
>> +static inline bool is_direct_map(unsigned long vaddr)
>> +{
>> + return within(vaddr, PAGE_OFFSET,
>> + PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT));
>> +}
>>
>> static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
>> int primary)
>> @@ -1808,8 +1814,7 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
>> * one virtual address page and its pfn. TBD: numpages can be set based
>> * on the initial value and the level returned by lookup_address().
>> */
>> - if (within(vaddr, PAGE_OFFSET,
>> - PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
>> + if (is_direct_map(vaddr)) {
>> cpa->numpages = 1;
>> cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
>> return 0;
>> @@ -1981,6 +1986,27 @@ static int cpa_process_alias(struct cpa_data *cpa)
>> return 0;
>> }
>>
>> +/*
>> + * Having updated the unrestricted PGD, reflect this change in the ASI
>> + * restricted address space too.
>> + */
>> +static inline int mirror_asi_direct_map(struct cpa_data *cpa, int primary)
>> +{
>> + struct cpa_data asi_cpa = *cpa;
>> +
>> + if (!asi_enabled_static())
>> + return 0;
>> +
>> + /* Only need to do this for the real unrestricted direct map. */
>> + if ((cpa->pgd && cpa->pgd != init_mm.pgd) || !is_direct_map(*cpa->vaddr))
>> + return 0;
>> + VM_WARN_ON_ONCE(!is_direct_map(*cpa->vaddr + (cpa->numpages * PAGE_SIZE)));
>> +
>> + asi_cpa.pgd = asi_nonsensitive_pgd;
>> + asi_cpa.curpage = 0;
>
> Please document what functionality this curpage=0 has. It's not clear.
Ack, I'll add some commentary.
>> + return __change_page_attr(cpa, primary);
>> +}
>
> But let's say someone is doing something silly like:
>
> set_memory_np(addr, size);
> set_memory_p(addr, size);
>
> Won't that end up in here and make the "unrestricted PGD" have
> _PAGE_PRESENT==1 entries?
Er, yes, that's a bug, thanks for pointing this out. I guess this is
actually broken under debug_pagealloc or something? I should check that.
This code should only mirror the bits that are irrelevant to ASI.
> Also, could we try and make the nomenclature consistent? We've got
> "unrestricted direct map" and "asi_nonsensitive_pgd" being used (at
> least). Could the terminology be made more consistent?
Hm. It is actually consistent: "unrestricted" is a property of the
address space / execution context. "nonsensitive" is a property of the
memory. Nonsensitive memory is mapped into the unrestricted address
space. asi_nonsensitive_pgd isn't an address space we enter it's just a
holding area (like if we never actually pointed CR3 at init_mm.pgd but
just useed it as a source to clone from).
However.. just because it's consistent doesn't mean it's not confusing.
Do you think we should just squash these two words and call the whole
thing "nonsensitive"? I don't know if "nonsensitive address space" makes
much sense... Is it possible I can fix this by just adding more
comments?
> One subtle thing here is that it's OK to allocate memory here when
> mirroring changes into 'asi_nonsensitive_pgd'. It's just not OK when
> flipping sensitivity. That seems worth a comment.
Ack, will add that.
>> static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
>> {
>> unsigned long numpages = cpa->numpages;
>> @@ -2007,6 +2033,8 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
>> if (!debug_pagealloc_enabled())
>> spin_lock(&cpa_lock);
>> ret = __change_page_attr(cpa, primary);
>> + if (!ret)
>> + ret = mirror_asi_direct_map(cpa, primary);
>> if (!debug_pagealloc_enabled())
>> spin_unlock(&cpa_lock);
>> if (ret)
>>
>
> Is cpa->pgd ever have any values other than NULL or init_mm->pgd? I
> didn't see anything in a quick grep.
It can also be efi_mm.pgd via sev_es_efi_map_ghcbs_cas().
On 10/2/25 07:31, Brendan Jackman wrote:
> On Wed Oct 1, 2025 at 8:50 PM UTC, Dave Hansen wrote:
...
>> But let's say someone is doing something silly like:
>>
>> set_memory_np(addr, size);
>> set_memory_p(addr, size);
>>
>> Won't that end up in here and make the "unrestricted PGD" have
>> _PAGE_PRESENT==1 entries?
>
> Er, yes, that's a bug, thanks for pointing this out. I guess this is
> actually broken under debug_pagealloc or something? I should check that.
>
> This code should only mirror the bits that are irrelevant to ASI.
It's actually anything that has _PAGE_PRESENT in cpa->mask_set. There
are a number of those. Some of them are irrelevant like the execmem
code, but there are quite a few more that look troublesome outside of
debugging environments.
>> Also, could we try and make the nomenclature consistent? We've got
>> "unrestricted direct map" and "asi_nonsensitive_pgd" being used (at
>> least). Could the terminology be made more consistent?
>
> Hm. It is actually consistent: "unrestricted" is a property of the
> address space / execution context. "nonsensitive" is a property of the
> memory. Nonsensitive memory is mapped into the unrestricted address
> space. asi_nonsensitive_pgd isn't an address space we enter it's just a
> holding area (like if we never actually pointed CR3 at init_mm.pgd but
> just useed it as a source to clone from).
>
> However.. just because it's consistent doesn't mean it's not confusing.
> Do you think we should just squash these two words and call the whole
> thing "nonsensitive"? I don't know if "nonsensitive address space" makes
> much sense... Is it possible I can fix this by just adding more
> comments?
It makes sense to me that a "nonsensitive address space" would not map
any sensitive data and that a "asi_nonsensitive_pgd" is the root of that
address space.
>>> static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
>>> {
>>> unsigned long numpages = cpa->numpages;
>>> @@ -2007,6 +2033,8 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
>>> if (!debug_pagealloc_enabled())
>>> spin_lock(&cpa_lock);
>>> ret = __change_page_attr(cpa, primary);
>>> + if (!ret)
>>> + ret = mirror_asi_direct_map(cpa, primary);
>>> if (!debug_pagealloc_enabled())
>>> spin_unlock(&cpa_lock);
>>> if (ret)
>>>
>>
>> Is cpa->pgd ever have any values other than NULL or init_mm->pgd? I
>> didn't see anything in a quick grep.
>
> It can also be efi_mm.pgd via sev_es_efi_map_ghcbs_cas().
It would be _nice_ if the ASI exclusion wasn't so magic.
Like, instead of hooking in to __change_page_attr_set_clr() and
filtering on init_mm if we had the callers declare explicitly whether
their changes get reflected into the ASI nonsensitive PGD.
Maybe that looks like a new flag: CPA_DIRECT_MAP or something. Once you
pass that flag in, the cpa code knows that you're working on init_mm.pgd
and mirror_asi_direct_map() can look for *that* instead of init_mm.
On Thu Oct 2, 2025 at 4:40 PM UTC, Dave Hansen wrote:
> On 10/2/25 07:31, Brendan Jackman wrote:
> It's actually anything that has _PAGE_PRESENT in cpa->mask_set. There
> are a number of those. Some of them are irrelevant like the execmem
> code, but there are quite a few more that look troublesome outside of
> debugging environments.
>
>>> Also, could we try and make the nomenclature consistent? We've got
>>> "unrestricted direct map" and "asi_nonsensitive_pgd" being used (at
>>> least). Could the terminology be made more consistent?
>>
>> Hm. It is actually consistent: "unrestricted" is a property of the
>> address space / execution context. "nonsensitive" is a property of the
>> memory. Nonsensitive memory is mapped into the unrestricted address
>> space. asi_nonsensitive_pgd isn't an address space we enter it's just a
>> holding area (like if we never actually pointed CR3 at init_mm.pgd but
>> just useed it as a source to clone from).
>>
>> However.. just because it's consistent doesn't mean it's not confusing.
>> Do you think we should just squash these two words and call the whole
>> thing "nonsensitive"? I don't know if "nonsensitive address space" makes
>> much sense... Is it possible I can fix this by just adding more
>> comments?
>
> It makes sense to me that a "nonsensitive address space" would not map
> any sensitive data and that a "asi_nonsensitive_pgd" is the root of that
> address space.
OK, then it probably just sounds wrong to me because I'm steeped in the
current jargon. For v2 I'll try just dropping "[un]restricted".
>>>> static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
>>>> {
>>>> unsigned long numpages = cpa->numpages;
>>>> @@ -2007,6 +2033,8 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int primary)
>>>> if (!debug_pagealloc_enabled())
>>>> spin_lock(&cpa_lock);
>>>> ret = __change_page_attr(cpa, primary);
>>>> + if (!ret)
>>>> + ret = mirror_asi_direct_map(cpa, primary);
>>>> if (!debug_pagealloc_enabled())
>>>> spin_unlock(&cpa_lock);
>>>> if (ret)
>>>>
>>>
>>> Is cpa->pgd ever have any values other than NULL or init_mm->pgd? I
>>> didn't see anything in a quick grep.
>>
>> It can also be efi_mm.pgd via sev_es_efi_map_ghcbs_cas().
>
> It would be _nice_ if the ASI exclusion wasn't so magic.
>
> Like, instead of hooking in to __change_page_attr_set_clr() and
> filtering on init_mm if we had the callers declare explicitly whether
> their changes get reflected into the ASI nonsensitive PGD.
>
> Maybe that looks like a new flag: CPA_DIRECT_MAP or something. Once you
> pass that flag in, the cpa code knows that you're working on init_mm.pgd
> and mirror_asi_direct_map() can look for *that* instead of init_mm.
Sounds good to me. If "The Direct Map" is a gonna be a special thing
then having it be a flag instead of a certain magic pgd_t * makes sense
to me. I'll try this out.
On Thu, Oct 02, 2025 at 05:08:59PM +0000, Brendan Jackman wrote:
> OK, then it probably just sounds wrong to me because I'm steeped in the
> current jargon. For v2 I'll try just dropping "[un]restricted".
So AFAIU, we have two address spaces - the full one - which has *everything*
mapped in and the limited one, with things removed from it. Right?
So calling the unrestricted "the full address space" makes sense to me. I.e.,
it has *everything* in it.
And then there's the subset of the full address space which has holes in it.
Looking at Merriam Webster, it suggests those antonyms to "complete":
partial, incomplete, reduced, abbreviated, diminished.
Yahaa, they all make sense.
"partial address space" sounds good to me. "Reduced" even better. So having
the full and the reduced address space would make the nomenclature very easy,
IMO.
Thoughts?
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On Tue Jan 20, 2026 at 4:37 PM UTC, Borislav Petkov wrote: > On Thu, Oct 02, 2025 at 05:08:59PM +0000, Brendan Jackman wrote: >> OK, then it probably just sounds wrong to me because I'm steeped in the >> current jargon. For v2 I'll try just dropping "[un]restricted". > > So AFAIU, we have two address spaces - the full one - which has *everything* > mapped in and the limited one, with things removed from it. Right? > > So calling the unrestricted "the full address space" makes sense to me. I.e., > it has *everything* in it. > > And then there's the subset of the full address space which has holes in it. > Looking at Merriam Webster, it suggests those antonyms to "complete": > > partial, incomplete, reduced, abbreviated, diminished. > > Yahaa, they all make sense. > > "partial address space" sounds good to me. "Reduced" even better. So having > the full and the reduced address space would make the nomenclature very easy, > IMO. > > Thoughts? Full/partial sounds like good naming for the address spaces, but that doesn't help with the issue that we have two related concepts that we need jargon for: 1. Address spaces (current patch's terminology: restricted/unrestricted) 2. The property of some memory being mapped or unmapped in the "restricted"/"partial"/"sensitive" address space (current patch's terminology: sensitive/nonsensitive). IIUC Dave's complaint wasn't that the word choices don't work for their respective concepts. His issue was that we have separte jargon for 1 and 2 even though they are closely entangled concepts. Since I'm now convinced that "sensitive/nonsensitive" makes sense for both, I think we should stick to that.
On Wed, Jan 21, 2026 at 09:45:22AM +0000, Brendan Jackman wrote:
> 2. The property of some memory being mapped or unmapped in the
> "restricted"/"partial"/"sensitive" address space (current patch's
> terminology: sensitive/nonsensitive).
Why do we care about the sensitivity of memory? To the kernel it doesn't
matter whether memory is sensitive or not. You simply map it in the sensitive
page table or in the nonsensitive or in both.
Having a sensitive and nonsensitive pagetable should be enough. And that'll
make the whole concept a lot simpler.
I'd say.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On Wed Jan 21, 2026 at 11:27 AM UTC, Borislav Petkov wrote: > On Wed, Jan 21, 2026 at 09:45:22AM +0000, Brendan Jackman wrote: >> 2. The property of some memory being mapped or unmapped in the >> "restricted"/"partial"/"sensitive" address space (current patch's >> terminology: sensitive/nonsensitive). > > Why do we care about the sensitivity of memory? To the kernel it doesn't > matter whether memory is sensitive or not. You simply map it in the sensitive > page table or in the nonsensitive or in both. > > Having a sensitive and nonsensitive pagetable should be enough. And that'll > make the whole concept a lot simpler. Well, something has to manage those pagetables and that thing needs a term to describe the stuff it's acting on. I.e. we need an adjective better than "to-be-mapped-into-the-full-pagtable". Anyway, I think this will be an easier debate to have once we're looking at actual code etc - I'm still debugging my page allocator changes to support the guest_memfd thing and that code doesn't need to care about "sensitivity" at all, there's just one address space and data is "mapped" or "unmapped". So I propose we defer this conversation until after that...
On Wed, Jan 21, 2026 at 11:49:13AM +0000, Brendan Jackman wrote:
> Well, something has to manage those pagetables and that thing needs a
> term to describe the stuff it's acting on. I.e. we need an adjective
> better than "to-be-mapped-into-the-full-pagtable".
>
> Anyway, I think this will be an easier debate to have once we're looking
> at actual code etc - I'm still debugging my page allocator changes to
> support the guest_memfd thing and that code doesn't need to care about
> "sensitivity" at all, there's just one address space and data is
> "mapped" or "unmapped". So I propose we defer this conversation until
> after that...
Ok, sounds good.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
Hi Brendan,
kernel test robot noticed the following build warnings:
[auto build test WARNING on bf2602a3cb2381fb1a04bf1c39a290518d2538d1]
url: https://github.com/intel-lab-lkp/linux/commits/Brendan-Jackman/x86-mm-asi-Add-CONFIG_MITIGATION_ADDRESS_SPACE_ISOLATION/20250924-230633
base: bf2602a3cb2381fb1a04bf1c39a290518d2538d1
patch link: https://lore.kernel.org/r/20250924-b4-asi-page-alloc-v1-5-2d861768041f%40google.com
patch subject: [PATCH 05/21] x86/mm/pat: mirror direct map changes to ASI
config: x86_64-buildonly-randconfig-002-20250925 (https://download.01.org/0day-ci/archive/20250925/202509252153.JhjsdZ6c-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250925/202509252153.JhjsdZ6c-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509252153.JhjsdZ6c-lkp@intel.com/
All warnings (new ones prefixed by >>):
arch/x86/mm/pat/set_memory.c: In function 'mirror_asi_direct_map':
>> arch/x86/mm/pat/set_memory.c:1995:25: warning: variable 'asi_cpa' set but not used [-Wunused-but-set-variable]
1995 | struct cpa_data asi_cpa = *cpa;
| ^~~~~~~
vim +/asi_cpa +1995 arch/x86/mm/pat/set_memory.c
1988
1989 /*
1990 * Having updated the unrestricted PGD, reflect this change in the ASI
1991 * restricted address space too.
1992 */
1993 static inline int mirror_asi_direct_map(struct cpa_data *cpa, int primary)
1994 {
> 1995 struct cpa_data asi_cpa = *cpa;
1996
1997 if (!asi_enabled_static())
1998 return 0;
1999
2000 /* Only need to do this for the real unrestricted direct map. */
2001 if ((cpa->pgd && cpa->pgd != init_mm.pgd) || !is_direct_map(*cpa->vaddr))
2002 return 0;
2003 VM_WARN_ON_ONCE(!is_direct_map(*cpa->vaddr + (cpa->numpages * PAGE_SIZE)));
2004
2005 asi_cpa.pgd = asi_nonsensitive_pgd;
2006 asi_cpa.curpage = 0;
2007 return __change_page_attr(cpa, primary);
2008 }
2009
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.