Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 80550
b: refs/heads/master
c: 0879750
h: refs/heads/master
v: v3
  • Loading branch information
Thomas Gleixner authored and Ingo Molnar committed Jan 30, 2008
1 parent 6939d5e commit 410b93d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 86f03989d99cfa2e1216cdd7aa996852236909cf
refs/heads/master: 0879750f5d75dee0546316b7b0e83fb6cd258ad7
56 changes: 30 additions & 26 deletions trunk/arch/x86/mm/pageattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,49 +305,53 @@ __change_page_attr(unsigned long address, unsigned long pfn,
* Modules and drivers should use the set_memory_* APIs instead.
*/

#define HIGH_MAP_START __START_KERNEL_map
#define HIGH_MAP_END (__START_KERNEL_map + KERNEL_TEXT_SIZE)

static int
change_page_attr_addr(unsigned long address, pgprot_t mask_set,
pgprot_t mask_clr)
pgprot_t mask_clr)
{
int err = 0, kernel_map = 0;
unsigned long pfn;
unsigned long phys_addr = __pa(address);
unsigned long pfn = phys_addr >> PAGE_SHIFT;
int err;

#ifdef CONFIG_X86_64
if (address >= __START_KERNEL_map &&
address < __START_KERNEL_map + KERNEL_TEXT_SIZE) {

address = (unsigned long)__va(__pa((void *)address));
kernel_map = 1;
}
/*
* If we are inside the high mapped kernel range, then we
* fixup the low mapping first. __va() returns the virtual
* address in the linear mapping:
*/
if (within(address, HIGH_MAP_START, HIGH_MAP_END))
address = (unsigned long) __va(phys_addr);
#endif

pfn = __pa(address) >> PAGE_SHIFT;

if (!kernel_map || 1) {
err = __change_page_attr(address, pfn, mask_set, mask_clr);
if (err)
return err;
}
err = __change_page_attr(address, pfn, mask_set, mask_clr);
if (err)
return err;

#ifdef CONFIG_X86_64
/*
* Handle kernel mapping too which aliases part of
* lowmem:
* If the physical address is inside the kernel map, we need
* to touch the high mapped kernel as well:
*/
if (__pa(address) < KERNEL_TEXT_SIZE) {
unsigned long addr2;

addr2 = __pa(address) + __START_KERNEL_map - phys_base;
if (within(phys_addr, 0, KERNEL_TEXT_SIZE)) {
/*
* Calc the high mapping address. See __phys_addr()
* for the non obvious details.
*/
address = phys_addr + HIGH_MAP_START - phys_base;
/* Make sure the kernel mappings stay executable */
pgprot_val(mask_clr) |= _PAGE_NX;

/*
* Our high aliases are imprecise, so do not propagate
* failures back to users:
* Our high aliases are imprecise, because we check
* everything between 0 and KERNEL_TEXT_SIZE, so do
* not propagate lookup failures back to users:
*/
__change_page_attr(addr2, pfn, mask_set, mask_clr);
__change_page_attr(address, pfn, mask_set, mask_clr);
}
#endif

return err;
}

Expand Down

0 comments on commit 410b93d

Please sign in to comment.