fix xc_ptrace_core for gdbserver-xen on x86_64.
RFC PATCH 1/1 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.
tools/libxc/xc_ptrace_core.c +13 -7
@@ -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 longstatic 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
tools/libxc/xc_ptrace_core.c +129 -16
170 lines not on this page · raw message
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
Re: [Patch][RFC] fix xc_ptrace_core for gdbserver-xen on?x86_64.
Quoted 8 lines · Akio Takebe
[-- text/plain, encoding 7bit, charset: iso-2022-jp, 199 lines --] [-- Description: Mail message body --]
Hi,
x86_64peopleI make a patch to fix
xc_ptrace_corefor gdbserver-xen onx86_64. But I'm not familiar withx86_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?
Signature · 3 lines
Horms H: http://www.vergenet.net/~horms/ W: http://www.valinux.co.jp/en/
Re: [Patch][RFC] fix xc_ptrace_core for gdbserver-xen on?x86_64.
Hi, Horms
Quoted 11 lines
It seems generaly consistent with the i386 code, and looks generaly fine, though I am not an expert on
x86_64either.There seem to be three distinct portions of your patch.
1. Make
nr_pagesan unsigned long instead of a longThis seems like it should be a separate patch as its really a trivial (but probably important) bugfix. Right?
Yes, This is trivial bugfix.
Quoted 7 lines
2. Fill in
map_domain_va_core()forx86_643. Get rid of
m2p_array.I'm not sure what the relationship between 2 and 3 is. Is
m2p_arrayno 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