|
@@ -34,28 +34,28 @@ static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static bool in_range(unsigned long start, unsigned long size,
|
|
|
+ unsigned long range_start, unsigned long range_end)
|
|
|
+{
|
|
|
+ return start >= range_start && start < range_end &&
|
|
|
+ size <= range_end - start;
|
|
|
+}
|
|
|
+
|
|
|
static int change_memory_common(unsigned long addr, int numpages,
|
|
|
pgprot_t set_mask, pgprot_t clear_mask)
|
|
|
{
|
|
|
- unsigned long start = addr;
|
|
|
- unsigned long size = PAGE_SIZE*numpages;
|
|
|
- unsigned long end = start + size;
|
|
|
+ unsigned long start = addr & PAGE_MASK;
|
|
|
+ unsigned long end = PAGE_ALIGN(addr) + numpages * PAGE_SIZE;
|
|
|
+ unsigned long size = end - start;
|
|
|
int ret;
|
|
|
struct page_change_data data;
|
|
|
|
|
|
- if (!IS_ALIGNED(addr, PAGE_SIZE)) {
|
|
|
- start &= PAGE_MASK;
|
|
|
- end = start + size;
|
|
|
- WARN_ON_ONCE(1);
|
|
|
- }
|
|
|
+ WARN_ON_ONCE(start != addr);
|
|
|
|
|
|
- if (!numpages)
|
|
|
+ if (!size)
|
|
|
return 0;
|
|
|
|
|
|
- if (start < MODULES_VADDR || start >= MODULES_END)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- if (end < MODULES_VADDR || start >= MODULES_END)
|
|
|
+ if (!in_range(start, size, MODULES_VADDR, MODULES_END))
|
|
|
return -EINVAL;
|
|
|
|
|
|
data.set_mask = set_mask;
|