From: Simon Kagstrom <simon.kagstrom@bth.se>
To: xen-devel list <xen-devel@lists.xensource.com>
Subject: [PATCH] reenabling ptrace for paravirtualized guests
Date: Thu, 11 May 2006 17:02:59 +0200 [thread overview]
Message-ID: <87zmho4na4.wl%simon.kagstrom@bth.se> (raw)
Debugging with the gdbserver has been broken for paravirtualized
guests for a while since parts of xc_ptrace.c assumes HVM guests. The
following patch fixes this along with single-stepping in attached
domains. The patch tries to separate HVM-specific address
handling. Changes:
- Functions va_to_ma32 and va_to_ma64 have been added. These translate
virtual to machine addresses through a given page directory/table
and optionally through page_array for HVM guests. These have
replaced page_array-references.
- paging_enabled now contains a check for HVM guests, and always
returns 1 for PV guests.
- Reversed logic in PTRACE_SINGLESTEP to allow stepping in attached
domains and disallow stepping in corefiles.
NOTE: I only have access to "regular" 32-bit hardware, so I've only
been able to test map_domain_va32 for PV guests. It would be nice if
other people could test it on HVM, PAE and 64-bit guests.
// Simon
Signed-off-by: Simon Kagstrom <simon.kagstrom@bth.se>
===File /tmp/xc_ptrace.patch================================
diff -r fc9ec6fd3400 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c Mon May 08 14:56:18 2006 +0100
+++ b/tools/libxc/xc_ptrace.c Thu May 11 16:49:59 2006 +0200
@@ -100,8 +100,15 @@ static inline int
static inline int
paging_enabled(vcpu_guest_context_t *v)
{
- unsigned long cr0 = v->ctrlreg[0];
- return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
+ /* This check can be removed when Xen places the correct values in
+ * cr0 for paravirtualized guests.
+ */
+ if ( (v->flags & VGCF_HVM_GUEST) == 1 ) {
+ unsigned long cr0 = v->ctrlreg[0];
+
+ return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
+ }
+ return 1;
}
/*
@@ -157,6 +164,43 @@ static long nr_pages
static long nr_pages = 0;
static unsigned long *page_array = NULL;
+
+static unsigned long
+va_to_ma32(int cpu,
+ uint32_t *table,
+ unsigned long idx)
+{
+ unsigned long out;
+
+ /* Paravirtualized domains store machine addresses in tables while
+ * HVM domains keep pseudo-physical addresses. HVM domains
+ * therefore need one extra translation.
+ */
+ if ( (out = table[idx]) == 0)
+ return 0;
+ if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
+ out = page_array[idx] << PAGE_SHIFT;
+ return out;
+}
+
+static unsigned long
+va_to_ma64(int cpu,
+ uint64_t *table,
+ unsigned long idx)
+{
+ unsigned long out;
+
+ /* Paravirtualized domains store machine addresses in tables while
+ * HVM domains keep pseudo-physical addresses. HVM domains
+ * therefore need one extra translation.
+ */
+ if ( (out = table[idx]) == 0)
+ return 0;
+ if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
+ out = page_array[idx] << PAGE_SHIFT;
+ return out;
+}
+
static void *
map_domain_va_32(
int xc_handle,
@@ -188,10 +232,8 @@ map_domain_va_32(
if ( cr3_virt[cpu] == NULL )
return NULL;
}
- if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
- return NULL;
- if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
- pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
+ if ( (pde = va_to_ma32(cpu, cr3_virt[cpu], vtopdi(va))) == 0 )
+ return NULL;
if ( pde != pde_phys[cpu] )
{
pde_phys[cpu] = pde;
@@ -203,10 +245,9 @@ map_domain_va_32(
if ( pde_virt[cpu] == NULL )
return NULL;
}
- if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
- return NULL;
- if (ctxt[cpu].flags & VGCF_HVM_GUEST)
- page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
+ if ( (page = va_to_ma32(cpu, pde_virt[cpu], vtopti(va))) == 0 )
+ return NULL;
+
if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
{
page_phys[cpu] = page;
@@ -243,25 +284,25 @@ map_domain_va_pae(
if ( l3 == NULL )
return NULL;
- l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
- l2p = page_array[l2p];
- l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p);
+ if ( ( l2p = va_to_ma64(cpu, l3, l3_table_offset_pae(va)) ) == 0 )
+ return NULL;
+ l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p >> PAGE_SHIFT);
munmap(l3, PAGE_SIZE);
if ( l2 == NULL )
return NULL;
- l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
- l1p = page_array[l1p];
- l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
+ if ( ( l1p = va_to_ma64(cpu, l2, l2_table_offset_pae(va)) ) == 0 )
+ return NULL;
+ l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p >> PAGE_SHIFT);
munmap(l2, PAGE_SIZE);
if ( l1 == NULL )
return NULL;
- p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
- p = page_array[p];
+ if ( ( p = va_to_ma64(cpu, l1, l1_table_offset_pae(va)) ) == 0 )
+ return NULL;
if ( v != NULL )
munmap(v, PAGE_SIZE);
- v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+ v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p >> PAGE_SHIFT);
munmap(l1, PAGE_SIZE);
if ( v == NULL )
return NULL;
@@ -289,38 +330,41 @@ map_domain_va_64(
if ( l4 == NULL )
return NULL;
- l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT;
- l3p = page_array[l3p];
- l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l3p);
+ if ( ( l3p = va_to_ma64(cpu, l4, l4_table_offset(va)) ) == 0 )
+ return NULL;
+ l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l3p >> PAGE_SHIFT);
munmap(l4, PAGE_SIZE);
if ( l3 == NULL )
return NULL;
- l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT;
- l2p = page_array[l2p];
- l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p);
+ if ( ( l2p = va_to_ma64(cpu, l3, l3_table_offset(va)) ) == 0 )
+ return NULL;
+ l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p >> PAGE_SHIFT);
munmap(l3, PAGE_SIZE);
if ( l2 == NULL )
return NULL;
l1 = NULL;
- l1e = l2[l2_table_offset(va)];
+ if ( ( l1e = va_to_ma64(cpu, l2, l2_table_offset(va)) ) == 0 )
+ return NULL;
l1p = l1e >> PAGE_SHIFT;
if (l1e & 0x80) { /* 2M pages */
p = (l1p + l1_table_offset(va));
+ if ( (ctxt[cpu].flags & VGCF_HVM_GUEST))
+ p = page_array[p] << PAGE_SHIFT;
} else { /* 4K pages */
- l1p = page_array[l1p];
- l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
+ if ( ( l1p = va_to_ma64(cpu, l1e, l1_table_offset(va)) ) == 0 )
+ return NULL;
+ l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p >> PAGE_SHIFT);
munmap(l2, PAGE_SIZE);
if ( l1 == NULL )
return NULL;
- p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
- }
- p = page_array[p];
+ p = va_to_ma64(cpu, l1, l1_table_offset(va));
+ }
if ( v != NULL )
munmap(v, PAGE_SIZE);
- v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+ v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p >> PAGE_SHIFT);
if (l1)
munmap(l1, PAGE_SIZE);
if ( v == NULL )
@@ -381,7 +425,7 @@ map_domain_va(
if ( v != NULL )
munmap(v, PAGE_SIZE);
- page = page_array[va >> PAGE_SHIFT] << PAGE_SHIFT;
+ page = va_to_ma32(cpu, (uint32_t*)page_array, va);
v = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE,
perm, page >> PAGE_SHIFT);
@@ -526,7 +570,7 @@ xc_ptrace(
break;
case PTRACE_SINGLESTEP:
- if (!current_isfile)
+ if (current_isfile)
goto out_unspported; /* XXX not yet supported */
/* XXX we can still have problems if the user switches threads
* during single-stepping - but that just seems retarded
============================================================
next reply other threads:[~2006-05-11 15:02 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-11 15:02 Simon Kagstrom [this message]
2006-05-11 21:29 ` [PATCH] reenabling ptrace for paravirtualized guests Hollis Blanchard
2006-05-12 7:07 ` Simon Kagstrom
2006-05-12 7:19 ` Keir Fraser
2006-05-12 9:21 ` Simon Kagstrom
2006-05-14 19:11 ` Keir Fraser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87zmho4na4.wl%simon.kagstrom@bth.se \
--to=simon.kagstrom@bth.se \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.