* [PATCH v5 0/2] Fix issues with vmalloc flush flag
@ 2019-05-27 21:10 Rick Edgecombe
2019-05-27 21:10 ` [PATCH v5 1/2] vmalloc: Fix calculation of direct map addr range Rick Edgecombe
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Rick Edgecombe @ 2019-05-27 21:10 UTC (permalink / raw)
To: linux-kernel, peterz, sparclinux, linux-mm, netdev, luto
Cc: dave.hansen, namit, Rick Edgecombe
These two patches address issues with the recently added
VM_FLUSH_RESET_PERMS vmalloc flag.
Patch 1 addresses an issue that could cause a crash after other
architectures besides x86 rely on this path.
Patch 2 addresses an issue where in a rare case strange arguments
could be provided to flush_tlb_kernel_range().
v4->v5:
- Update commit messages with info that the first issue will actually
not cause problems today
- Avoid re-use of variable (PeterZ)
v3->v4:
- Drop patch that switched vm_unmap_alias() calls to regular flush (Andy)
- Add patch to address correctness previously fixed in dropped patch
v2->v3:
- Split into two patches (Andy)
v1->v2:
- Update commit message with more detail
- Fix flush end range on !CONFIG_ARCH_HAS_SET_DIRECT_MAP case
Rick Edgecombe (2):
vmalloc: Fix calculation of direct map addr range
vmalloc: Avoid rare case of flushing tlb with weird arguments
mm/vmalloc.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v5 1/2] vmalloc: Fix calculation of direct map addr range
2019-05-27 21:10 [PATCH v5 0/2] Fix issues with vmalloc flush flag Rick Edgecombe
@ 2019-05-27 21:10 ` Rick Edgecombe
2019-06-03 12:59 ` [tip:x86/urgent] mm/vmalloc: " tip-bot for Rick Edgecombe
2019-05-27 21:10 ` [PATCH v5 2/2] vmalloc: Avoid rare case of flushing tlb with weird arguments Rick Edgecombe
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Rick Edgecombe @ 2019-05-27 21:10 UTC (permalink / raw)
To: linux-kernel, peterz, sparclinux, linux-mm, netdev, luto
Cc: dave.hansen, namit, Rick Edgecombe, Meelis Roos, David S. Miller,
Borislav Petkov, Ingo Molnar
The calculation of the direct map address range to flush was wrong.
This could cause the RO direct map alias to not get flushed. Today
this shouldn't be a problem because this flush is only needed on x86
right now and the spurious fault handler will fix cached RO->RW
translations. In the future though, it could cause the permissions
to remain RO in the TLB for the direct map alias, and then the page
would return from the page allocator to some other component as RO
and cause a crash.
So fix fix the address range calculation so the flush will include the
direct map range.
Fixes: 868b104d7379 ("mm/vmalloc: Add flag for freeing of special permsissions")
Cc: Meelis Roos <mroos@linux.ee>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Nadav Amit <namit@vmware.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
mm/vmalloc.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 233af6936c93..3ede9c064477 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2123,7 +2123,6 @@ static inline void set_area_direct_map(const struct vm_struct *area,
/* Handle removing and resetting vm mappings related to the vm_struct. */
static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
{
- unsigned long addr = (unsigned long)area->addr;
unsigned long start = ULONG_MAX, end = 0;
int flush_reset = area->flags & VM_FLUSH_RESET_PERMS;
int i;
@@ -2135,8 +2134,8 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
* execute permissions, without leaving a RW+X window.
*/
if (flush_reset && !IS_ENABLED(CONFIG_ARCH_HAS_SET_DIRECT_MAP)) {
- set_memory_nx(addr, area->nr_pages);
- set_memory_rw(addr, area->nr_pages);
+ set_memory_nx((unsigned long)area->addr, area->nr_pages);
+ set_memory_rw((unsigned long)area->addr, area->nr_pages);
}
remove_vm_area(area->addr);
@@ -2160,9 +2159,11 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
* the vm_unmap_aliases() flush includes the direct map.
*/
for (i = 0; i < area->nr_pages; i++) {
- if (page_address(area->pages[i])) {
+ unsigned long addr =
+ (unsigned long)page_address(area->pages[i]);
+ if (addr) {
start = min(addr, start);
- end = max(addr, end);
+ end = max(addr + PAGE_SIZE, end);
}
}
--
2.20.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v5 2/2] vmalloc: Avoid rare case of flushing tlb with weird arguments
2019-05-27 21:10 [PATCH v5 0/2] Fix issues with vmalloc flush flag Rick Edgecombe
2019-05-27 21:10 ` [PATCH v5 1/2] vmalloc: Fix calculation of direct map addr range Rick Edgecombe
@ 2019-05-27 21:10 ` Rick Edgecombe
2019-06-03 12:59 ` [tip:x86/urgent] mm/vmalloc: Avoid rare case of flushing TLB " tip-bot for Rick Edgecombe
2019-05-28 8:01 ` [PATCH v5 0/2] Fix issues with vmalloc flush flag Peter Zijlstra
2019-05-29 0:23 ` David Miller
3 siblings, 1 reply; 8+ messages in thread
From: Rick Edgecombe @ 2019-05-27 21:10 UTC (permalink / raw)
To: linux-kernel, peterz, sparclinux, linux-mm, netdev, luto
Cc: dave.hansen, namit, Rick Edgecombe, Meelis Roos, David S. Miller,
Borislav Petkov, Ingo Molnar
In a rare case, flush_tlb_kernel_range() could be called with a start
higher than the end.
In vm_remove_mappings(), in case page_address() returns 0 for all pages
(for example they were all in highmem), _vm_unmap_aliases() will be
called with start = ULONG_MAX, end = 0 and flush = 1.
If at the same time, the vmalloc purge operation is triggered by something
else while the current operation is between remove_vm_area() and
_vm_unmap_aliases(), then the vm mapping just removed will be already
purged. In this case the call of vm_unmap_aliases() may not find any other
mappings to flush and so end up flushing start = ULONG_MAX, end = 0. So
only set flush = true if we find something in the direct mapping that we
need to flush, and this way this can't happen.
Fixes: 868b104d7379 ("mm/vmalloc: Add flag for freeing of special permsissions")
Cc: Meelis Roos <mroos@linux.ee>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Nadav Amit <namit@vmware.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
mm/vmalloc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 3ede9c064477..7f15a3ebcd74 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2125,6 +2125,7 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
{
unsigned long start = ULONG_MAX, end = 0;
int flush_reset = area->flags & VM_FLUSH_RESET_PERMS;
+ int flush_dmap = 0;
int i;
/*
@@ -2164,6 +2165,7 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
if (addr) {
start = min(addr, start);
end = max(addr + PAGE_SIZE, end);
+ flush_dmap = 1;
}
}
@@ -2173,7 +2175,7 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
* reset the direct map permissions to the default.
*/
set_area_direct_map(area, set_direct_map_invalid_noflush);
- _vm_unmap_aliases(start, end, 1);
+ _vm_unmap_aliases(start, end, flush_dmap);
set_area_direct_map(area, set_direct_map_default_noflush);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v5 0/2] Fix issues with vmalloc flush flag
2019-05-27 21:10 [PATCH v5 0/2] Fix issues with vmalloc flush flag Rick Edgecombe
2019-05-27 21:10 ` [PATCH v5 1/2] vmalloc: Fix calculation of direct map addr range Rick Edgecombe
2019-05-27 21:10 ` [PATCH v5 2/2] vmalloc: Avoid rare case of flushing tlb with weird arguments Rick Edgecombe
@ 2019-05-28 8:01 ` Peter Zijlstra
2019-05-29 0:23 ` David Miller
3 siblings, 0 replies; 8+ messages in thread
From: Peter Zijlstra @ 2019-05-28 8:01 UTC (permalink / raw)
To: Rick Edgecombe
Cc: linux-kernel, sparclinux, linux-mm, netdev, luto, dave.hansen, namit
On Mon, May 27, 2019 at 02:10:56PM -0700, Rick Edgecombe wrote:
> These two patches address issues with the recently added
> VM_FLUSH_RESET_PERMS vmalloc flag.
>
> Patch 1 addresses an issue that could cause a crash after other
> architectures besides x86 rely on this path.
>
> Patch 2 addresses an issue where in a rare case strange arguments
> could be provided to flush_tlb_kernel_range().
Thanks!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v5 0/2] Fix issues with vmalloc flush flag
2019-05-27 21:10 [PATCH v5 0/2] Fix issues with vmalloc flush flag Rick Edgecombe
` (2 preceding siblings ...)
2019-05-28 8:01 ` [PATCH v5 0/2] Fix issues with vmalloc flush flag Peter Zijlstra
@ 2019-05-29 0:23 ` David Miller
2019-05-29 5:11 ` Edgecombe, Rick P
3 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2019-05-29 0:23 UTC (permalink / raw)
To: rick.p.edgecombe
Cc: linux-kernel, peterz, sparclinux, linux-mm, netdev, luto,
dave.hansen, namit
From: Rick Edgecombe <rick.p.edgecombe@intel.com>
Date: Mon, 27 May 2019 14:10:56 -0700
> These two patches address issues with the recently added
> VM_FLUSH_RESET_PERMS vmalloc flag.
>
> Patch 1 addresses an issue that could cause a crash after other
> architectures besides x86 rely on this path.
>
> Patch 2 addresses an issue where in a rare case strange arguments
> could be provided to flush_tlb_kernel_range().
It just occurred to me another situation that would cause trouble on
sparc64, and that's if someone the address range of the main kernel
image ended up being passed to flush_tlb_kernel_range().
That would flush the locked kernel mapping and crash the kernel
instantly in a completely non-recoverable way.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v5 0/2] Fix issues with vmalloc flush flag
2019-05-29 0:23 ` David Miller
@ 2019-05-29 5:11 ` Edgecombe, Rick P
0 siblings, 0 replies; 8+ messages in thread
From: Edgecombe, Rick P @ 2019-05-29 5:11 UTC (permalink / raw)
To: davem
Cc: linux-kernel, peterz, linux-mm, namit, luto, netdev, Hansen,
Dave, sparclinux
On Tue, 2019-05-28 at 17:23 -0700, David Miller wrote:
> From: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Date: Mon, 27 May 2019 14:10:56 -0700
>
> > These two patches address issues with the recently added
> > VM_FLUSH_RESET_PERMS vmalloc flag.
> >
> > Patch 1 addresses an issue that could cause a crash after other
> > architectures besides x86 rely on this path.
> >
> > Patch 2 addresses an issue where in a rare case strange arguments
> > could be provided to flush_tlb_kernel_range().
>
> It just occurred to me another situation that would cause trouble on
> sparc64, and that's if someone the address range of the main kernel
> image ended up being passed to flush_tlb_kernel_range().
>
> That would flush the locked kernel mapping and crash the kernel
> instantly in a completely non-recoverable way.
Hmm, I haven't received the logs from Meelis that will show the real
ranges being passed into flush_tlb_kernel_range() on sparc, but it
should be flushing a range spanning from the modules to the direct map.
It looks like the kernel is at the very bottom of the address space, so
not included. Or do you mean the pages that hold the kernel text on the
direct map?
But regardless of this new code, DEBUG_PAGEALLOC hangs with the first
vmalloc free/unmap. That should be just flushing a single allocation in
the vmalloc range.
If it is somehow catching a locked entry though... Are there any sparc
flush mechanisms that could be used in vmalloc that won't touch locked
entries? Peter Z was pointing out that flush_tlb_all() might be more
approriate for vmalloc anyway.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [tip:x86/urgent] mm/vmalloc: Fix calculation of direct map addr range
2019-05-27 21:10 ` [PATCH v5 1/2] vmalloc: Fix calculation of direct map addr range Rick Edgecombe
@ 2019-06-03 12:59 ` tip-bot for Rick Edgecombe
0 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Rick Edgecombe @ 2019-06-03 12:59 UTC (permalink / raw)
To: linux-tip-commits
Cc: tglx, namit, hpa, rick.p.edgecombe, dave.hansen, torvalds, akpm,
linux-kernel, bp, peterz, luto, mingo, davem, mroos
Commit-ID: 8e41f8726dcf423621e2b6938d015b9796f6f676
Gitweb: https://git.kernel.org/tip/8e41f8726dcf423621e2b6938d015b9796f6f676
Author: Rick Edgecombe <rick.p.edgecombe@intel.com>
AuthorDate: Mon, 27 May 2019 14:10:57 -0700
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 3 Jun 2019 11:47:25 +0200
mm/vmalloc: Fix calculation of direct map addr range
The calculation of the direct map address range to flush was wrong.
This could cause the RO direct map alias to not get flushed. Today
this shouldn't be a problem because this flush is only needed on x86
right now and the spurious fault handler will fix cached RO->RW
translations. In the future though, it could cause the permissions
to remain RO in the TLB for the direct map alias, and then the page
would return from the page allocator to some other component as RO
and cause a crash.
So fix fix the address range calculation so the flush will include the
direct map range.
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Meelis Roos <mroos@linux.ee>
Cc: Nadav Amit <namit@vmware.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Fixes: 868b104d7379 ("mm/vmalloc: Add flag for freeing of special permsissions")
Link: https://lkml.kernel.org/r/20190527211058.2729-2-rick.p.edgecombe@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
mm/vmalloc.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 7350a124524b..93b2dca2aadb 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2123,7 +2123,6 @@ static inline void set_area_direct_map(const struct vm_struct *area,
/* Handle removing and resetting vm mappings related to the vm_struct. */
static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
{
- unsigned long addr = (unsigned long)area->addr;
unsigned long start = ULONG_MAX, end = 0;
int flush_reset = area->flags & VM_FLUSH_RESET_PERMS;
int i;
@@ -2135,8 +2134,8 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
* execute permissions, without leaving a RW+X window.
*/
if (flush_reset && !IS_ENABLED(CONFIG_ARCH_HAS_SET_DIRECT_MAP)) {
- set_memory_nx(addr, area->nr_pages);
- set_memory_rw(addr, area->nr_pages);
+ set_memory_nx((unsigned long)area->addr, area->nr_pages);
+ set_memory_rw((unsigned long)area->addr, area->nr_pages);
}
remove_vm_area(area->addr);
@@ -2160,9 +2159,10 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
* the vm_unmap_aliases() flush includes the direct map.
*/
for (i = 0; i < area->nr_pages; i++) {
- if (page_address(area->pages[i])) {
+ unsigned long addr = (unsigned long)page_address(area->pages[i]);
+ if (addr) {
start = min(addr, start);
- end = max(addr, end);
+ end = max(addr + PAGE_SIZE, end);
}
}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [tip:x86/urgent] mm/vmalloc: Avoid rare case of flushing TLB with weird arguments
2019-05-27 21:10 ` [PATCH v5 2/2] vmalloc: Avoid rare case of flushing tlb with weird arguments Rick Edgecombe
@ 2019-06-03 12:59 ` tip-bot for Rick Edgecombe
0 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Rick Edgecombe @ 2019-06-03 12:59 UTC (permalink / raw)
To: linux-tip-commits
Cc: mingo, linux-kernel, mroos, dave.hansen, luto, bp,
rick.p.edgecombe, akpm, torvalds, hpa, davem, peterz, namit,
tglx
Commit-ID: 31e67340cc65edfd9dac5ef26f81de8414ce5906
Gitweb: https://git.kernel.org/tip/31e67340cc65edfd9dac5ef26f81de8414ce5906
Author: Rick Edgecombe <rick.p.edgecombe@intel.com>
AuthorDate: Mon, 27 May 2019 14:10:58 -0700
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 3 Jun 2019 11:47:25 +0200
mm/vmalloc: Avoid rare case of flushing TLB with weird arguments
In a rare case, flush_tlb_kernel_range() could be called with a start
higher than the end.
In vm_remove_mappings(), in case page_address() returns 0 for all pages
(for example they were all in highmem), _vm_unmap_aliases() will be
called with start = ULONG_MAX, end = 0 and flush = 1.
If at the same time, the vmalloc purge operation is triggered by something
else while the current operation is between remove_vm_area() and
_vm_unmap_aliases(), then the vm mapping just removed will be already
purged. In this case the call of vm_unmap_aliases() may not find any other
mappings to flush and so end up flushing start = ULONG_MAX, end = 0. So
only set flush = true if we find something in the direct mapping that we
need to flush, and this way this can't happen.
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Meelis Roos <mroos@linux.ee>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Fixes: 868b104d7379 ("mm/vmalloc: Add flag for freeing of special permsissions")
Link: https://lkml.kernel.org/r/20190527211058.2729-3-rick.p.edgecombe@intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
mm/vmalloc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 93b2dca2aadb..4c9e150e5ad3 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2125,6 +2125,7 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
{
unsigned long start = ULONG_MAX, end = 0;
int flush_reset = area->flags & VM_FLUSH_RESET_PERMS;
+ int flush_dmap = 0;
int i;
/*
@@ -2163,6 +2164,7 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
if (addr) {
start = min(addr, start);
end = max(addr + PAGE_SIZE, end);
+ flush_dmap = 1;
}
}
@@ -2172,7 +2174,7 @@ static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
* reset the direct map permissions to the default.
*/
set_area_direct_map(area, set_direct_map_invalid_noflush);
- _vm_unmap_aliases(start, end, 1);
+ _vm_unmap_aliases(start, end, flush_dmap);
set_area_direct_map(area, set_direct_map_default_noflush);
}
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2019-06-03 13:00 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-27 21:10 [PATCH v5 0/2] Fix issues with vmalloc flush flag Rick Edgecombe
2019-05-27 21:10 ` [PATCH v5 1/2] vmalloc: Fix calculation of direct map addr range Rick Edgecombe
2019-06-03 12:59 ` [tip:x86/urgent] mm/vmalloc: " tip-bot for Rick Edgecombe
2019-05-27 21:10 ` [PATCH v5 2/2] vmalloc: Avoid rare case of flushing tlb with weird arguments Rick Edgecombe
2019-06-03 12:59 ` [tip:x86/urgent] mm/vmalloc: Avoid rare case of flushing TLB " tip-bot for Rick Edgecombe
2019-05-28 8:01 ` [PATCH v5 0/2] Fix issues with vmalloc flush flag Peter Zijlstra
2019-05-29 0:23 ` David Miller
2019-05-29 5:11 ` Edgecombe, Rick P
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).