From f5278847a9e750a21224dfc1b3346c650fab4d64 Mon Sep 17 00:00:00 2001 From: "kaf24@freefall.cl.cam.ac.uk" Date: Tue, 16 Nov 2004 11:54:32 +0000 Subject: [PATCH 1/4] bitkeeper revision 1.1159.174.1 (4199ea78WRqMUotnBDHybojMaiF37w) Add more required sanity checks to writable p.t. code in Xen. --- xen/arch/x86/memory.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 39345ed7a3..fafbb40491 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -1577,7 +1577,7 @@ void ptwr_flush(const int which) { unsigned long sstat, spte, pte, *ptep, l1va; l1_pgentry_t *sl1e = NULL, *pl1e, ol1e, nl1e; - l2_pgentry_t *pl2e, nl2e; + l2_pgentry_t *pl2e; int i, cpu = smp_processor_id(); struct domain *d = current; @@ -1691,8 +1691,7 @@ void ptwr_flush(const int which) if ( (which == PTWR_PT_ACTIVE) && likely(!d->mm.shadow_mode) ) { pl2e = &linear_l2_table[ptwr_info[cpu].ptinfo[which].l2_idx]; - nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT); - update_l2e(pl2e, *pl2e, nl2e); + *pl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT); } /* @@ -1711,9 +1710,9 @@ void ptwr_flush(const int which) /* Write page fault handler: check if guest is trying to modify a PTE. */ int ptwr_do_page_fault(unsigned long addr) { - unsigned long pte, pfn; + unsigned long pte, pfn, l2e; struct pfn_info *page; - l2_pgentry_t *pl2e, nl2e; + l2_pgentry_t *pl2e; int which, cpu = smp_processor_id(); u32 l2_idx; @@ -1739,14 +1738,34 @@ int ptwr_do_page_fault(unsigned long addr) if ( unlikely(l2_idx >= PGT_va_unknown) ) domain_crash(); /* Urk! This L1 is mapped in multiple L2 slots! */ l2_idx >>= PGT_va_shift; - + + if ( l2_idx == (addr >> L2_PAGETABLE_SHIFT) ) + { + MEM_LOG("PTWR failure! Pagetable maps itself at %08lx\n", addr); + domain_crash(); + } + /* * Is the L1 p.t. mapped into the current address space? If so we call it * an ACTIVE p.t., otherwise it is INACTIVE. */ pl2e = &linear_l2_table[l2_idx]; - which = (l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn) ? - PTWR_PT_INACTIVE : PTWR_PT_ACTIVE; + l2e = l2_pgentry_val(*pl2e); + which = PTWR_PT_INACTIVE; + if ( (l2e >> PAGE_SHIFT) == pfn ) + { + /* + * If the PRESENT bit is clear, we may be conflicting with the current + * ACTIVE p.t. (it may be the same p.t. mapped at another virt addr). + */ + if ( unlikely(!(l2e & _PAGE_PRESENT)) && + ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va ) + ptwr_flush(PTWR_PT_ACTIVE); + + /* Now do a final check of the PRESENT bit to set ACTIVE. */ + if ( likely(l2e & _PAGE_PRESENT) ) + which = PTWR_PT_ACTIVE; + } PTWR_PRINTK("[%c] page_fault on l1 pt at va %08lx, pt for %08x, " "pfn %08lx\n", PTWR_PRINT_WHICH, @@ -1765,8 +1784,7 @@ int ptwr_do_page_fault(unsigned long addr) /* For safety, disconnect the L1 p.t. page from current space. */ if ( (which == PTWR_PT_ACTIVE) && likely(!current->mm.shadow_mode) ) { - nl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT); - update_l2e(pl2e, *pl2e, nl2e); + *pl2e = mk_l2_pgentry(l2e & ~_PAGE_PRESENT); flush_tlb(); /* XXX Multi-CPU guests? */ } From 7777720dbf54f01df426c258a6f18402535fe651 Mon Sep 17 00:00:00 2001 From: "kaf24@freefall.cl.cam.ac.uk" Date: Tue, 16 Nov 2004 11:55:31 +0000 Subject: [PATCH 2/4] bitkeeper revision 1.1159.174.2 (4199eab3BFgYlgf6yBL0RuSb19gzGA) Fix CONFIG_4KSTACKS kernel config option, and add it do default config. --- linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig | 2 +- linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig | 2 +- linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig index 44797f293e..1532ab3dfb 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig +++ b/linux-2.6.9-xen-sparse/arch/xen/configs/xen0_defconfig @@ -158,7 +158,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_FRAME_POINTER is not set -# CONFIG_4KSTACKS is not set +CONFIG_4KSTACKS=y CONFIG_X86_BIOS_REBOOT=y CONFIG_X86_STD_RESOURCES=y CONFIG_PC=y diff --git a/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig b/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig index 1d1ec8135a..24c57a3f50 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig +++ b/linux-2.6.9-xen-sparse/arch/xen/configs/xenU_defconfig @@ -119,7 +119,7 @@ CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_FRAME_POINTER is not set -# CONFIG_4KSTACKS is not set +CONFIG_4KSTACKS=y CONFIG_X86_BIOS_REBOOT=y CONFIG_X86_STD_RESOURCES=y CONFIG_PC=y diff --git a/linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c index 0041caa9bf..9648518ae8 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c @@ -467,6 +467,8 @@ void __init init_IRQ(void) { int i; + irq_ctx_init(0); + spin_lock_init(&irq_mapping_update_lock); /* No VIRQ -> IRQ mappings. */ From 9f9af87611c442c4a587a02f8dbe4b4eee631204 Mon Sep 17 00:00:00 2001 From: "kaf24@freefall.cl.cam.ac.uk" Date: Tue, 16 Nov 2004 11:56:15 +0000 Subject: [PATCH 3/4] bitkeeper revision 1.1159.174.3 (4199eadf9ra8mQPwvvr9Ke8eQfkfIg) Fix CONFIG_DEBUG_PAGEALLOC. More generally, this fixes __change_page_attr at the same time (incompatible with writable pagetables). --- linux-2.6.9-xen-sparse/arch/xen/i386/mm/pageattr.c | 5 +++-- .../include/asm-xen/asm-i386/pgtable-2level.h | 9 +++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pageattr.c b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pageattr.c index 19f9d9c525..74f3b150df 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pageattr.c +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/pageattr.c @@ -119,7 +119,7 @@ __change_page_attr(struct page *page, pgprot_t prot) if ((pte_val(*kpte) & _PAGE_PSE) == 0) { pte_t old = *kpte; pte_t standard = mk_pte(page, PAGE_KERNEL); - set_pte_atomic(kpte, mk_pte(page, prot)); + set_pte_batched(kpte, mk_pte(page, prot)); if (pte_same(old,standard)) get_page(kpte_page); } else { @@ -130,7 +130,7 @@ __change_page_attr(struct page *page, pgprot_t prot) set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL)); } } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { - set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL)); + set_pte_batched(kpte, mk_pte(page, PAGE_KERNEL)); __put_page(kpte_page); } @@ -171,6 +171,7 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot) if (err) break; } + flush_page_update_queue(); spin_unlock_irqrestore(&cpa_lock, flags); return err; } diff --git a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h index aa23bd9d55..7000c5dbe8 100644 --- a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h +++ b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h @@ -23,13 +23,10 @@ static inline int pgd_present(pgd_t pgd) { return 1; } * within a page table are directly modified. Thus, the following * hook is made available. */ -#ifdef CONFIG_XEN_WRITABLE_PAGETABLES +#define set_pte_batched(pteptr, pteval) \ +queue_l1_entry_update(pteptr, (pteval).pte_low) #define set_pte(pteptr, pteval) (*(pteptr) = pteval) -#define set_pte_atomic(pteptr, pteval) (*(pteptr) = pteval) -#else -#define set_pte(pteptr, pteval) xen_l1_entry_update(pteptr, (pteval).pte_low) -#define set_pte_atomic(pteptr, pteval) xen_l1_entry_update(pteptr, (pteval).pte_low) -#endif +#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) /* * (pmds are folded into pgds so this doesn't get actually called, * but the define is needed for a generic inline function.) From 9a152b3fe0246f47765c4897cbfc22d7581cb0e4 Mon Sep 17 00:00:00 2001 From: "kaf24@freefall.cl.cam.ac.uk" Date: Tue, 16 Nov 2004 11:56:44 +0000 Subject: [PATCH 4/4] bitkeeper revision 1.1159.174.4 (4199eafc-o43U-MPvkSymdEahhBVLg) Fix panic() so that it flushes console messages and then kills the VM cleanly (instead of spinning). --- linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c index e10a0aaf97..c9574a4311 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c @@ -1319,6 +1319,11 @@ void __init setup_arch(char **cmdline_p) unsigned long max_low_pfn; + /* Force a quick death if the kernel panics. */ + extern int panic_timeout; + if ( panic_timeout == 0 ) + panic_timeout = 1; + HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);