Akio Takebe
2006-Aug-25 03:22 UTC
[Xen-devel] [Patch][RFC] fix xc_ptrace_core for gdbserver-xen on x86_64.
Hi, x86_64 people I make a patch to fix xc_ptrace_core for gdbserver-xen on x86_64. But I''m not familiar with x86_64. Please review it. Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com> diff -r b688d4a68a3e tools/libxc/xc_ptrace_core.c --- a/tools/libxc/xc_ptrace_core.c Tue Aug 22 14:59:16 2006 +0100 +++ b/tools/libxc/xc_ptrace_core.c Fri Aug 25 12:22:19 2006 +0900 @@ -9,9 +9,8 @@ /* XXX application state */ -static long nr_pages = 0; +static unsigned long nr_pages = 0; static unsigned long *p2m_array = NULL; -static unsigned long *m2p_array = NULL; static unsigned long pages_offset; static unsigned long cr3[MAX_VIRT_CPUS]; @@ -20,11 +19,18 @@ static unsigned long static unsigned long map_mtop_offset(unsigned long ma) { - return pages_offset + (m2p_array[ma >> PAGE_SHIFT] << PAGE_SHIFT); - return 0; -} - - + + unsigned long page_num; + for(page_num=0; page_num <nr_pages; page_num++){ + if((ma >> PAGE_SHIFT) == p2m_array[page_num]) + break; + } + + return pages_offset + (page_num << PAGE_SHIFT); +} + + +#if defined(__i386__) void * map_domain_va_core(unsigned long domfd, int cpu, void * guest_va, vcpu_guest_context_t *ctxt) @@ -93,6 +99,122 @@ map_domain_va_core(unsigned long domfd, } return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK)); } + +#elif defined(__x86_64__) +void * +map_domain_va_core(unsigned long domfd, int cpu, void * guest_va, + vcpu_guest_context_t *ctxt) +{ + unsigned long pgd, pud, pmd, page; + unsigned long va = (unsigned long)guest_va; + void *v; + + static unsigned long cr3_phys[MAX_VIRT_CPUS]; + static unsigned long *cr3_virt[MAX_VIRT_CPUS]; + static unsigned long pgd_phys[MAX_VIRT_CPUS]; + static unsigned long *pgd_virt[MAX_VIRT_CPUS]; + static unsigned long pud_phys[MAX_VIRT_CPUS]; + static unsigned long *pud_virt[MAX_VIRT_CPUS]; + static unsigned long pmd_phys[MAX_VIRT_CPUS]; + static unsigned long *pmd_virt[MAX_VIRT_CPUS]; + static unsigned long page_phys[MAX_VIRT_CPUS]; + static unsigned long *page_virt[MAX_VIRT_CPUS]; + + if (cr3[cpu] != cr3_phys[cpu]) + { + cr3_phys[cpu] = cr3[cpu]; + if (cr3_virt[cpu]) + munmap(cr3_virt[cpu], PAGE_SIZE); + v = mmap( + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, + map_mtop_offset(xen_cr3_to_pfn(cr3_phys[cpu]))); + if (v == MAP_FAILED) + { + perror("mmap failed"); + return NULL; + } + cr3_virt[cpu] = v; + } + + /* 4 level */ + if ((pgd = cr3_virt[cpu][l4_table_offset(va)]) == 0) /* logical address */ + return NULL; + if (ctxt[cpu].flags & VGCF_HVM_GUEST) + pgd = p2m_array[pgd >> PAGE_SHIFT] << PAGE_SHIFT; + if (pgd != pgd_phys[cpu]) + { + pgd_phys[cpu] = pgd; + if (pgd_virt[cpu]) + munmap(pgd_virt[cpu], PAGE_SIZE); + v = mmap( + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, + map_mtop_offset(pgd_phys[cpu])); + if (v == MAP_FAILED) + return NULL; + pgd_virt[cpu] = v; + } + + /* 3 level */ + if ((pud = pgd_virt[cpu][l3_table_offset(va)]) == 0) /* logical address */ + return NULL; + if (ctxt[cpu].flags & VGCF_HVM_GUEST) + pud = p2m_array[pud >> PAGE_SHIFT] << PAGE_SHIFT; + if (pud != pud_phys[cpu]) + { + pud_phys[cpu] = pud; + if (pud_virt[cpu]) + munmap(pud_virt[cpu], PAGE_SIZE); + v = mmap( + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, + map_mtop_offset(pud_phys[cpu])); + if (v == MAP_FAILED) + return NULL; + pud_virt[cpu] = v; + } + + + /* 2 level */ + if ((pmd = pud_virt[cpu][l2_table_offset(va)]) == 0) /* logical address */ + return NULL; + if (ctxt[cpu].flags & VGCF_HVM_GUEST) + pmd = p2m_array[pmd >> PAGE_SHIFT] << PAGE_SHIFT; + if (pmd != pmd_phys[cpu]) + { + pmd_phys[cpu] = pmd; + if (pmd_virt[cpu]) + munmap(pmd_virt[cpu], PAGE_SIZE); + v = mmap( + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, + map_mtop_offset(pmd_phys[cpu])); + if (v == MAP_FAILED) + return NULL; + pmd_virt[cpu] = v; + } + + + if ((page = pmd_virt[cpu][l1_table_offset(va)]) == 0) /* logical address */ + return NULL; + if (ctxt[cpu].flags & VGCF_HVM_GUEST) + page = p2m_array[page >> PAGE_SHIFT] << PAGE_SHIFT; + if (page != page_phys[cpu]) + { + page_phys[cpu] = page; + if (page_virt[cpu]) + munmap(page_virt[cpu], PAGE_SIZE); + v = mmap( + NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, + map_mtop_offset(page_phys[cpu])); + if (v == MAP_FAILED) + { + IPRINTF("cr3 %lx pmd %lx page %lx pti %lx\n", cr3[cpu], pmd, page, l1_table_offset(va)); + page_phys[cpu] = 0; + return NULL; + } + page_virt[cpu] = v; + } + return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK)); +} +#endif int xc_waitdomain_core( @@ -140,15 +262,6 @@ xc_waitdomain_core( sizeof(unsigned long)*nr_pages) return -1; - if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL) - { - IPRINTF("Could not allocate m2p array\n"); - return -1; - } - bzero(m2p_array, sizeof(unsigned long)* 1 << 20); - - for (i = 0; i < nr_pages; i++) - m2p_array[p2m_array[i]] = i; } return 0; } Best Regards, Akio Takebe _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Horms
2006-Aug-25 08:00 UTC
[Xen-devel] Re: [Patch][RFC] fix xc_ptrace_core for gdbserver-xen on?x86_64.
On Fri, 25 Aug 2006 12:22:21 +0900, Akio Takebe wrote:> [-- text/plain, encoding 7bit, charset: iso-2022-jp, 199 lines --] > [-- Description: Mail message body --] > > Hi, x86_64 people > > I make a patch to fix xc_ptrace_core for gdbserver-xen on x86_64. > But I''m not familiar with x86_64. > Please review it.Hi Takebe-san, It seems generaly consistent with the i386 code, and looks generaly fine, though I am not an expert on x86_64 either. There seem to be three distinct portions of your patch. 1. Make nr_pages an unsigned long instead of a long This seems like it should be a separate patch as its really a trivial (but probably important) bugfix. Right? 2. Fill in map_domain_va_core() for x86_64 3. Get rid of m2p_array. I''m not sure what the relationship between 2 and 3 is. Is m2p_array no longer needed because of the changes in 2? Or is it a separate cleanup? -- Horms H: http://www.vergenet.net/~horms/ W: http://www.valinux.co.jp/en/ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Akio Takebe
2006-Aug-25 09:03 UTC
[Xen-devel] Re: [Patch][RFC] fix xc_ptrace_core for gdbserver-xen on?x86_64.
Hi, Horms> >It seems generaly consistent with the i386 code, and looks generaly >fine, though I am not an expert on x86_64 either. > >There seem to be three distinct portions of your patch. > >1. Make nr_pages an unsigned long instead of a long > > This seems like it should be a separate patch as its really > a trivial (but probably important) bugfix. Right? >Yes, This is trivial bugfix.>2. Fill in map_domain_va_core() for x86_64 > >3. Get rid of m2p_array. > > I''m not sure what the relationship between 2 and 3 is. > Is m2p_array no longer needed because of the changes in 2? > Or is it a separate cleanup?Yes, separate cleanup. m2p_array for x86_64 is very big. So I fix the code with the following way. @@ -20,11 +19,18 @@ static unsigned long static unsigned long map_mtop_offset(unsigned long ma) { - return pages_offset + (m2p_array[ma >> PAGE_SHIFT] << PAGE_SHIFT); - return 0; -} - - + + unsigned long page_num; + for(page_num=0; page_num <nr_pages; page_num++){ + if((ma >> PAGE_SHIFT) == p2m_array[page_num]) + break; + } + + return pages_offset + (page_num << PAGE_SHIFT); +} + + The way get page number of ma by searching the p2m_array without m2p_array. Best Regards, Akio Takebe _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel