diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-03-21 10:42:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:15:16 -0400 |
commit | f022bfd58253099102218db5249220a7f4787114 (patch) | |
tree | 21409f8c6c1fefb370b86c2b6d86d94802147d61 /arch | |
parent | 86cf02f8eaea1b09e102e0f432fc137dc5cf4407 (diff) |
x86: PAT fix
Adrian Bunk noticed the following Coverity report:
> Commit e7f260a276f2c9184fe753732d834b1f6fbe9f17
> (x86: PAT use reserve free memtype in mmap of /dev/mem)
> added the following gem to arch/x86/mm/pat.c:
>
> <-- snip -->
>
> ...
> int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
> unsigned long size, pgprot_t *vma_prot)
> {
> u64 offset = ((u64) pfn) << PAGE_SHIFT;
> unsigned long flags = _PAGE_CACHE_UC_MINUS;
> unsigned long ret_flags;
> ...
> ... (nothing that touches ret_flags)
> ...
> if (flags != _PAGE_CACHE_UC_MINUS) {
> retval = reserve_memtype(offset, offset + size, flags, NULL);
> } else {
> retval = reserve_memtype(offset, offset + size, -1, &ret_flags);
> }
>
> if (retval < 0)
> return 0;
>
> flags = ret_flags;
>
> if (pfn <= max_pfn_mapped &&
> ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) {
> free_memtype(offset, offset + size);
> printk(KERN_INFO
> "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
> current->comm, current->pid,
> cattr_name(flags),
> offset, offset + size);
> return 0;
> }
>
> *vma_prot = __pgprot((pgprot_val(*vma_prot) & ~_PAGE_CACHE_MASK) |
> flags);
> return 1;
> }
>
> <-- snip -->
>
> If (flags != _PAGE_CACHE_UC_MINUS) we pass garbage from the stack to
> ioremap_change_attr() and/or __pgprot().
>
> Spotted by the Coverity checker.
the fix simplifies the code as we get rid of the 'ret_flags'
complication.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/mm/pat.c | 5 |
1 files changed, 1 insertions, 4 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index b17cdf64e41e..277446cd30b6 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -510,7 +510,6 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | |||
510 | { | 510 | { |
511 | u64 offset = ((u64) pfn) << PAGE_SHIFT; | 511 | u64 offset = ((u64) pfn) << PAGE_SHIFT; |
512 | unsigned long flags = _PAGE_CACHE_UC_MINUS; | 512 | unsigned long flags = _PAGE_CACHE_UC_MINUS; |
513 | unsigned long ret_flags; | ||
514 | int retval; | 513 | int retval; |
515 | 514 | ||
516 | if (!range_is_allowed(pfn, size)) | 515 | if (!range_is_allowed(pfn, size)) |
@@ -549,14 +548,12 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | |||
549 | if (flags != _PAGE_CACHE_UC_MINUS) { | 548 | if (flags != _PAGE_CACHE_UC_MINUS) { |
550 | retval = reserve_memtype(offset, offset + size, flags, NULL); | 549 | retval = reserve_memtype(offset, offset + size, flags, NULL); |
551 | } else { | 550 | } else { |
552 | retval = reserve_memtype(offset, offset + size, -1, &ret_flags); | 551 | retval = reserve_memtype(offset, offset + size, -1, &flags); |
553 | } | 552 | } |
554 | 553 | ||
555 | if (retval < 0) | 554 | if (retval < 0) |
556 | return 0; | 555 | return 0; |
557 | 556 | ||
558 | flags = ret_flags; | ||
559 | |||
560 | if (pfn <= max_pfn_mapped && | 557 | if (pfn <= max_pfn_mapped && |
561 | ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) { | 558 | ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) { |
562 | free_memtype(offset, offset + size); | 559 | free_memtype(offset, offset + size); |