On Wed, 9 Jan 2013 17:32:32 +0800
Tang Chen [off-list ref] wrote:
+static void __meminit
+remove_pagetable(unsigned long start, unsigned long end, bool direct)
+{
+ unsigned long next;
+ pgd_t *pgd;
+ pud_t *pud;
+ bool pgd_changed = false;
+
+ for (; start < end; start = next) {
+ pgd = pgd_offset_k(start);
+ if (!pgd_present(*pgd))
+ continue;
+
+ next = pgd_addr_end(start, end);
+
+ pud = (pud_t *)map_low_page((pud_t *)pgd_page_vaddr(*pgd));
+ remove_pud_table(pud, start, next, direct);
+ if (free_pud_table(pud, pgd))
+ pgd_changed = true;
+ unmap_low_page(pud);
+ }
+
+ if (pgd_changed)
+ sync_global_pgds(start, end - 1);
+
+ flush_tlb_all();
+}
This generates a compiler warning saying that `next' may be used
uninitialised.
The warning is correct. If we take that `continue' on the first pass
through the loop, the "start = next" will copy uninitialised data into
`start'.
Is this the correct fix?
--- a/arch/x86/mm/init_64.c~memory-hotplug-common-apis-to-support-page-tables-hot-remove-fix-fix-fix-fix-fix-fix-fix
+++ a/arch/x86/mm/init_64.c
@@ -993,12 +993,12 @@ remove_pagetable(unsigned long start, un
bool pgd_changed = false;
for (; start < end; start = next) {
+ next = pgd_addr_end(start, end);
+
pgd = pgd_offset_k(start);
if (!pgd_present(*pgd))
continue;
- next = pgd_addr_end(start, end);
-
pud = (pud_t *)pgd_page_vaddr(*pgd);
remove_pud_table(pud, start, next, direct);
if (free_pud_table(pud, pgd))_