[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] Announcing OpenBSD/amd64 Xen port
Keir Fraser wrote: I've attached 3 patches needed for OpenBSD/amd64 to work. The two first address a bug in loadelfsymtab() which load the ELF symbol table at a bad address on x86_64. More explanations can be found in one of my older posts. The third is a first try to fix the issue I have with linear pagetables. It does fix my issue, and doesn't break my Linux dom0, but besides this fact, I have no guarantee. Any feedback or advice would be appreciated.On 8 Jun 2006, at 10:48, Mathieu Ropert wrote:- events/clock issue: there seems to be a race condition leading to clock not ticking, hence putting system to sleep till a keyboard/network/disk interrupt is received.The ticker doesn't tick when you block. Your idle loop needs to disable interrupts, set a one-shot timer, then block. See safe_halt() in our Linux source tree (arch/i386/kernel/time-xen.c) -- the function expects to be called with interrupts disabled and caller should also have already checked for any other threads being runnable.-- Keir Mathieu diff -r -bu a/tools/libxc/xc_load_elf.c b/tools/libxc/xc_load_elf.c --- a/tools/libxc/xc_load_elf.c 2006-06-09 12:32:22.000000000 +0200 +++ b/tools/libxc/xc_load_elf.c 2006-06-09 12:37:04.000000000 +0200 @@ -283,8 +283,9 @@ return 0; maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1); - symva = maxva; - maxva += sizeof(int); + if (maxva - dsi->v_kernend < sizeof(int)) + maxva += ELFROUND; + symva = maxva - sizeof(int); dsi->symtab_addr = maxva; dsi->symtab_len = 0; maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr); diff -r -bu a/xen/common/elf.c b/xen/common/elf.c --- a/xen/common/elf.c 2006-06-09 12:32:24.000000000 +0200 +++ b/xen/common/elf.c 2006-06-09 12:36:57.000000000 +0200 @@ -185,8 +185,9 @@ return; maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1); - symva = maxva; - maxva += sizeof(int); + if (maxva - dsi->v_kernend < sizeof(int)) + maxva += ELFROUND; + symva = maxva - sizeof(int); dsi->symtab_addr = maxva; dsi->symtab_len = 0; maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr); diff -r -bu a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c 2006-06-09 12:32:24.000000000 +0200 +++ b/xen/arch/x86/mm.c 2006-06-09 12:41:04.000000000 +0200 @@ -493,7 +493,7 @@ */ static int get_linear_pagetable( - root_pgentry_t re, unsigned long re_pfn, struct domain *d) + pgentry_t re, unsigned long re_pfn, struct domain *d, int level) { unsigned long x, y; struct page_info *page; @@ -501,13 +501,13 @@ ASSERT( !shadow_mode_refcounts(d) ); - if ( (root_get_flags(re) & _PAGE_RW) ) + if ( (pgentry_get_flags(re, level) & _PAGE_RW) ) { MEM_LOG("Attempt to create linear p.t. with write perms"); return 0; } - if ( (pfn = root_get_pfn(re)) != re_pfn ) + if ( (pfn = pgentry_get_pfn(re, level)) != re_pfn ) { /* Make sure the mapped frame belongs to the correct domain. */ if ( unlikely(!get_page_from_pagenr(pfn, d)) ) @@ -522,8 +522,7 @@ do { x = y; if ( unlikely((x & PGT_count_mask) == PGT_count_mask) || - unlikely((x & (PGT_type_mask|PGT_validated)) != - (PGT_root_page_table|PGT_validated)) ) + unlikely(!(x & PGT_validated) || !is_ptp(x))) { put_page(page); return 0; @@ -611,9 +610,12 @@ vaddr <<= PGT_va_shift; rc = get_page_and_type_from_pagenr( l2e_get_pfn(l2e), PGT_l1_page_table | vaddr, d); -#if CONFIG_PAGING_LEVELS == 2 - if ( unlikely(!rc) ) - rc = get_linear_pagetable(l2e, pfn, d); +#if CONFIG_PAGING_LEVELS >= 2 + if ( unlikely(!rc) ) { + pgentry_t re; + re.l2.l2 = l2e.l2; + rc = get_linear_pagetable(re, pfn, d, 2); + } #endif return rc; } @@ -643,6 +645,13 @@ rc = get_page_and_type_from_pagenr( l3e_get_pfn(l3e), PGT_l2_page_table | vaddr, d); + + if ( unlikely(!rc) ) { + pgentry_t re; + re.l3.l3 = l3e.l3; + rc = get_linear_pagetable(re, pfn, d, 3); + } + return rc; } #endif /* 3 level */ @@ -672,8 +681,11 @@ l4e_get_pfn(l4e), PGT_l3_page_table | vaddr, d); - if ( unlikely(!rc) ) - rc = get_linear_pagetable(l4e, pfn, d); + if ( unlikely(!rc) ) { + pgentry_t re; + re.l4.l4 = l4e.l4; + rc = get_linear_pagetable(re, pfn, d, 4); + } return rc; } diff -r -bu a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h --- a/xen/include/asm-x86/page.h 2006-06-09 12:32:24.000000000 +0200 +++ b/xen/include/asm-x86/page.h 2006-06-09 12:44:03.000000000 +0200 @@ -179,6 +179,69 @@ #define pagetable_from_page(pg) pagetable_from_pfn(page_to_mfn(pg)) #define pagetable_from_paddr(p) pagetable_from_pfn((p)>>PAGE_SHIFT) #define pagetable_null() pagetable_from_pfn(0) + +/* Guest linear PT handling */ +typedef union { + l1_pgentry_t l1; +#if CONFIG_PAGING_LEVELS >= 2 + l2_pgentry_t l2; +#if CONFIG_PAGING_LEVELS >= 3 + l3_pgentry_t l3; +#if CONFIG_PAGING_LEVELS == 4 + l4_pgentry_t l4; +#endif /* LEVELS == 4 */ +#endif /* LEVELS >= 3 */ +#endif /* LEVELS >= 2 */ +} pgentry_t; + +static inline intpte_t pgentry_get_flags(pgentry_t p, int level) +{ + switch (level) + { + case 1: + return l1e_get_flags(p.l1); +#if CONFIG_PAGING_LEVELS >= 2 + case 2: + return l2e_get_flags(p.l2); +#if CONFIG_PAGING_LEVELS >= 3 + case 3: + return l3e_get_flags(p.l3); +#if CONFIG_PAGING_LEVELS == 4 + case 4: + return l4e_get_flags(p.l4); +#endif /* LEVELS == 4 */ +#endif /* LEVELS >= 3 */ +#endif /* LEVELS >= 2 */ + default: + /* should not happen */ + return 0; + } +} + +static inline intpte_t pgentry_get_pfn(pgentry_t p, int level) +{ + switch (level) + { + case 1: + return l1e_get_pfn(p.l1); +#if CONFIG_PAGING_LEVELS >= 2 + case 2: + return l2e_get_pfn(p.l2); +#if CONFIG_PAGING_LEVELS >= 3 + case 3: + return l3e_get_pfn(p.l3); +#if CONFIG_PAGING_LEVELS == 4 + case 4: + return l4e_get_pfn(p.l4); +#endif /* LEVELS == 4 */ +#endif /* LEVELS >= 3 */ +#endif /* LEVELS >= 2 */ + default: + /* should not happen */ + return 0; + } +} + #endif #define clear_page(_p) memset((void *)(_p), 0, PAGE_SIZE) diff -r -bu a/xen/include/asm-x86/x86_32/page-2level.h b/xen/include/asm-x86/x86_32/page-2level.h --- a/xen/include/asm-x86/x86_32/page-2level.h 2006-06-09 12:32:24.000000000 +0200 +++ b/xen/include/asm-x86/x86_32/page-2level.h 2006-06-09 12:37:10.000000000 +0200 @@ -28,6 +28,11 @@ #endif /* !__ASSEMBLY__ */ +/* Check if page type is page table (any level) */ +#define is_ptp(x) \ + ((x & PGT_type_mask) == PGT_l1_page_table \ + || (x & PGT_type_mask) == PGT_l2_page_table) + /* root table */ #define root_get_pfn l2e_get_pfn #define root_get_flags l2e_get_flags diff -r -bu a/xen/include/asm-x86/x86_32/page-3level.h b/xen/include/asm-x86/x86_32/page-3level.h --- a/xen/include/asm-x86/x86_32/page-3level.h 2006-06-09 12:32:24.000000000 +0200 +++ b/xen/include/asm-x86/x86_32/page-3level.h 2006-06-09 12:37:10.000000000 +0200 @@ -38,6 +38,12 @@ #endif /* !__ASSEMBLY__ */ +/* Check if page type is page table (any level) */ +#define is_ptp(x) \ + ((x & PGT_type_mask) == PGT_l1_page_table \ + || (x & PGT_type_mask) == PGT_l2_page_table \ + || (x & PGT_type_mask) == PGT_l3_page_table) + /* root table */ #define root_get_pfn l3e_get_pfn #define root_get_flags l3e_get_flags diff -r -bu a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h --- a/xen/include/asm-x86/x86_64/page.h 2006-06-09 12:32:24.000000000 +0200 +++ b/xen/include/asm-x86/x86_64/page.h 2006-06-09 12:37:10.000000000 +0200 @@ -41,6 +41,13 @@ #endif /* !__ASSEMBLY__ */ +/* Check if page type is page table (any level) */ +#define is_ptp(x) \ + ((x & PGT_type_mask) == PGT_l1_page_table \ + || (x & PGT_type_mask) == PGT_l2_page_table \ + || (x & PGT_type_mask) == PGT_l3_page_table \ + || (x & PGT_type_mask) == PGT_l4_page_table) + /* Given a virtual address, get an entry offset into a linear page table. */ #define l1_linear_offset(_a) (((_a) & VADDR_MASK) >> L1_PAGETABLE_SHIFT) #define l2_linear_offset(_a) (((_a) & VADDR_MASK) >> L2_PAGETABLE_SHIFT) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |