Re-indent libxc to avoid hard tabs. Also, fix the PAE

domain builder to correctly write PTEs that map pages
above 4GB.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-09-19 11:06:05 +00:00
1 parent d847ecf971
commit e701d05c8a
13 files changed
+1149 -996

No files matched your search

+92 -82
View File
@@ -11,10 +11,10 @@
static int
copy_from_domain_page(int xc_handle,
u32 domid,
unsigned long *page_array,
unsigned long src_pfn,
void *dst_page)
u32 domid,
unsigned long *page_array,
unsigned long src_pfn,
void *dst_page)
{
void *vaddr = xc_map_foreign_range(
xc_handle, domid, PAGE_SIZE, PROT_READ, page_array[src_pfn]);
@@ -27,90 +27,100 @@ copy_from_domain_page(int xc_handle,
int
xc_domain_dumpcore(int xc_handle,
u32 domid,
const char *corename)
u32 domid,
const char *corename)
{
unsigned long nr_pages;
unsigned long *page_array;
xc_dominfo_t info;
int i, j, vcpu_map_size, dump_fd;
char *dump_mem, *dump_mem_start = NULL;
struct xc_core_header header;
vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
unsigned long nr_pages;
unsigned long *page_array;
xc_dominfo_t info;
int i, j, vcpu_map_size, dump_fd;
char *dump_mem, *dump_mem_start = NULL;
struct xc_core_header header;
vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) {
PERROR("Could not open corefile %s: %s", corename, strerror(errno));
goto error_out;
}
if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL) {
PERROR("Could not allocate dump_mem");
goto error_out;
}
if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) {
PERROR("Could not get info for domain");
goto error_out;
}
vcpu_map_size = sizeof(info.vcpu_to_cpu) / sizeof(info.vcpu_to_cpu[0]);
if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) {
PERROR("Could not open corefile %s: %s", corename, strerror(errno));
goto error_out;
}
if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL) {
PERROR("Could not allocate dump_mem");
goto error_out;
}
if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) {
PERROR("Could not get info for domain");
goto error_out;
}
vcpu_map_size = sizeof(info.vcpu_to_cpu) / sizeof(info.vcpu_to_cpu[0]);
for (i = 0, j = 0; i < vcpu_map_size; i++) {
if (info.vcpu_to_cpu[i] == -1) {
continue;
}
if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[j])) {
PERROR("Could not get all vcpu contexts for domain");
goto error_out;
}
j++;
}
nr_pages = info.nr_pages;
for (i = 0, j = 0; i < vcpu_map_size; i++) {
if (info.vcpu_to_cpu[i] == -1) {
continue;
}
if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[j])) {
PERROR("Could not get all vcpu contexts for domain");
goto error_out;
}
j++;
}
nr_pages = info.nr_pages;
header.xch_magic = 0xF00FEBED;
header.xch_nr_vcpus = info.vcpus;
header.xch_nr_pages = nr_pages;
header.xch_ctxt_offset = sizeof(struct xc_core_header);
header.xch_index_offset = sizeof(struct xc_core_header) +
sizeof(vcpu_guest_context_t)*info.vcpus;
header.xch_pages_offset = round_pgup(sizeof(struct xc_core_header) +
(sizeof(vcpu_guest_context_t) * info.vcpus) +
(nr_pages * sizeof(unsigned long)));
header.xch_magic = 0xF00FEBED;
header.xch_nr_vcpus = info.vcpus;
header.xch_nr_pages = nr_pages;
header.xch_ctxt_offset = sizeof(struct xc_core_header);
header.xch_index_offset = sizeof(struct xc_core_header) +
sizeof(vcpu_guest_context_t)*info.vcpus;
header.xch_pages_offset = round_pgup(sizeof(struct xc_core_header) +
(sizeof(vcpu_guest_context_t) * info.vcpus) +
(nr_pages * sizeof(unsigned long)));
write(dump_fd, &header, sizeof(struct xc_core_header));
write(dump_fd, &ctxt, sizeof(ctxt[0]) * info.vcpus);
write(dump_fd, &header, sizeof(struct xc_core_header));
write(dump_fd, &ctxt, sizeof(ctxt[0]) * info.vcpus);
if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
printf("Could not allocate memory\n");
goto error_out;
}
if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
printf("Could not get the page frame list\n");
goto error_out;
}
write(dump_fd, page_array, nr_pages * sizeof(unsigned long));
lseek(dump_fd, header.xch_pages_offset, SEEK_SET);
for (dump_mem = dump_mem_start, i = 0; i < nr_pages; i++) {
copy_from_domain_page(xc_handle, domid, page_array, i, dump_mem);
dump_mem += PAGE_SIZE;
if (((i + 1) % DUMP_INCREMENT == 0) || (i + 1) == nr_pages) {
if (write(dump_fd, dump_mem_start, dump_mem - dump_mem_start) <
dump_mem - dump_mem_start) {
PERROR("Partial write, file system full?");
goto error_out;
}
dump_mem = dump_mem_start;
}
}
if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
printf("Could not allocate memory\n");
goto error_out;
}
if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
printf("Could not get the page frame list\n");
goto error_out;
}
write(dump_fd, page_array, nr_pages * sizeof(unsigned long));
lseek(dump_fd, header.xch_pages_offset, SEEK_SET);
for (dump_mem = dump_mem_start, i = 0; i < nr_pages; i++) {
copy_from_domain_page(xc_handle, domid, page_array, i, dump_mem);
dump_mem += PAGE_SIZE;
if (((i + 1) % DUMP_INCREMENT == 0) || (i + 1) == nr_pages) {
if (write(dump_fd, dump_mem_start, dump_mem - dump_mem_start) <
dump_mem - dump_mem_start) {
PERROR("Partial write, file system full?");
goto error_out;
}
dump_mem = dump_mem_start;
}
}
close(dump_fd);
free(dump_mem_start);
return 0;
close(dump_fd);
free(dump_mem_start);
return 0;
error_out:
if (dump_fd != -1)
close(dump_fd);
free(dump_mem_start);
return -1;
if (dump_fd != -1)
close(dump_fd);
free(dump_mem_start);
return -1;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+12 -2
View File
@@ -265,7 +265,7 @@ int xc_domain_memory_increase_reservation(int xc_handle,
unsigned long nr_extents,
unsigned int extent_order,
unsigned int address_bits,
unsigned long *extent_start)
unsigned long *extent_start)
{
int err;
struct xen_memory_reservation reservation = {
@@ -296,7 +296,7 @@ int xc_domain_memory_decrease_reservation(int xc_handle,
u32 domid,
unsigned long nr_extents,
unsigned int extent_order,
unsigned long *extent_start)
unsigned long *extent_start)
{
int err;
struct xen_memory_reservation reservation = {
@@ -328,3 +328,13 @@ int xc_domain_memory_decrease_reservation(int xc_handle,
return err;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+11 -2
View File
@@ -9,8 +9,8 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
}
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
unsigned int store_evtchn, unsigned long *store_mfn,
unsigned int console_evtchn, unsigned long *console_mfn)
unsigned int store_evtchn, unsigned long *store_mfn,
unsigned int console_evtchn, unsigned long *console_mfn)
{
PERROR("xc_linux_restore not implemented\n");
return -1;
@@ -44,3 +44,12 @@ xc_plan9_build(int xc_handle,
return -1;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+166 -168
View File
@@ -13,7 +13,6 @@
#define ELFSIZE 64
#endif
#include "xc_elf.h"
#include "xc_aout9.h"
#include <stdlib.h>
@@ -33,6 +32,13 @@
#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#endif
#ifdef __ia64__
#define already_built(ctxt) (0)
#define get_tot_pages xc_get_max_pages
#else
#define already_built(ctxt) ((ctxt)->ctrlreg[3] != 0)
#define get_tot_pages xc_get_tot_pages
#endif
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
#define round_pgdown(_p) ((_p)&PAGE_MASK)
@@ -47,7 +53,7 @@ static int probeimageformat(char *image,
{
if ( probe_elf(image, image_size, load_funcs) &&
probe_bin(image, image_size, load_funcs) &&
probe_aout9(image, image_size, load_funcs) )
probe_aout9(image, image_size, load_funcs) )
{
ERROR( "Unrecognized image format" );
return -EINVAL;
@@ -56,27 +62,27 @@ static int probeimageformat(char *image,
return 0;
}
#define alloc_pt(ltab, vltab) \
ltab = (unsigned long long)(page_array[ppt_alloc++]) << PAGE_SHIFT; \
if (vltab != NULL) { \
munmap(vltab, PAGE_SIZE); \
} \
if ((vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, \
PROT_READ|PROT_WRITE, \
ltab >> PAGE_SHIFT)) == NULL) { \
goto error_out; \
} \
memset(vltab, 0, PAGE_SIZE);
#define alloc_pt(ltab, vltab) \
do { \
ltab = (u64)page_array[ppt_alloc++] << PAGE_SHIFT; \
if ( vltab != NULL ) \
munmap(vltab, PAGE_SIZE); \
if ( (vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, \
PROT_READ|PROT_WRITE, \
ltab >> PAGE_SHIFT)) == NULL ) \
goto error_out; \
memset(vltab, 0, PAGE_SIZE); \
} while ( 0 )
#if defined(__i386__)
static int setup_pg_tables(int xc_handle, u32 dom,
vcpu_guest_context_t *ctxt,
unsigned long dsi_v_start,
unsigned long v_end,
unsigned long *page_array,
unsigned long vpt_start,
unsigned long vpt_end)
vcpu_guest_context_t *ctxt,
unsigned long dsi_v_start,
unsigned long v_end,
unsigned long *page_array,
unsigned long vpt_start,
unsigned long vpt_end)
{
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
@@ -90,11 +96,11 @@ static int setup_pg_tables(int xc_handle, u32 dom,
vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
ctxt->ctrlreg[3] = l2tab;
for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++ )
for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
{
if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
{
alloc_pt(l1tab, vl1tab);
alloc_pt(l1tab, vl1tab);
vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
*vl2e++ = l1tab | L2_PROT;
}
@@ -111,79 +117,67 @@ static int setup_pg_tables(int xc_handle, u32 dom,
error_out:
if (vl1tab)
munmap(vl1tab, PAGE_SIZE);
munmap(vl1tab, PAGE_SIZE);
if (vl2tab)
munmap(vl2tab, PAGE_SIZE);
munmap(vl2tab, PAGE_SIZE);
return -1;
}
static int setup_pg_tables_pae(int xc_handle, u32 dom,
vcpu_guest_context_t *ctxt,
unsigned long dsi_v_start,
unsigned long v_end,
unsigned long *page_array,
unsigned long vpt_start,
unsigned long vpt_end)
vcpu_guest_context_t *ctxt,
unsigned long dsi_v_start,
unsigned long v_end,
unsigned long *page_array,
unsigned long vpt_start,
unsigned long vpt_end)
{
l1_pgentry_64_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_64_t *vl2tab=NULL, *vl2e=NULL;
l3_pgentry_64_t *vl3tab=NULL, *vl3e=NULL;
unsigned long long l1tab = 0;
unsigned long long l2tab = 0;
unsigned long long l3tab = 0;
unsigned long ppt_alloc;
unsigned long count;
l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL;
l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL;
l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL;
u64 l1tab, l2tab, l3tab;
unsigned long ppt_alloc, count, nmfn;
/* First allocate page for page dir. */
ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
if ( page_array[ppt_alloc] > 0xfffff )
{
unsigned long nmfn;
nmfn = xc_make_page_below_4G( xc_handle, dom, page_array[ppt_alloc] );
if ( nmfn == 0 )
{
fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
goto error_out;
}
page_array[ppt_alloc] = nmfn;
nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]);
if ( nmfn == 0 )
{
fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
goto error_out;
}
page_array[ppt_alloc] = nmfn;
}
alloc_pt(l3tab, vl3tab);
vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
ctxt->ctrlreg[3] = l3tab;
if(l3tab>0xfffff000ULL)
{
fprintf(stderr,"L3TAB = %llx above 4GB!\n",l3tab);
goto error_out;
}
for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
{
if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
{
if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
{
alloc_pt(l2tab, vl2tab);
vl2e = &vl2tab[l2_table_offset_pae(
dsi_v_start + (count << PAGE_SHIFT))];
*vl3e++ = l2tab | L3_PROT;
}
alloc_pt(l1tab, vl1tab);
if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
{
alloc_pt(l2tab, vl2tab);
vl2e = &vl2tab[l2_table_offset_pae(dsi_v_start + (count<<PAGE_SHIFT))];
*vl3e = l2tab | L3_PROT;
vl3e++;
}
vl1e = &vl1tab[l1_table_offset_pae(dsi_v_start + (count<<PAGE_SHIFT))];
*vl2e = l1tab | L2_PROT;
vl2e++;
vl1e = &vl1tab[l1_table_offset_pae(
dsi_v_start + (count << PAGE_SHIFT))];
*vl2e++ = l1tab | L2_PROT;
}
*vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
*vl1e = ((u64)page_array[count] << PAGE_SHIFT) | L1_PROT;
if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
(count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) )
{
*vl1e &= ~_PAGE_RW;
}
vl1e++;
(count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) )
*vl1e &= ~_PAGE_RW;
vl1e++;
}
munmap(vl1tab, PAGE_SIZE);
@@ -193,11 +187,11 @@ static int setup_pg_tables_pae(int xc_handle, u32 dom,
error_out:
if (vl1tab)
munmap(vl1tab, PAGE_SIZE);
munmap(vl1tab, PAGE_SIZE);
if (vl2tab)
munmap(vl2tab, PAGE_SIZE);
munmap(vl2tab, PAGE_SIZE);
if (vl3tab)
munmap(vl3tab, PAGE_SIZE);
munmap(vl3tab, PAGE_SIZE);
return -1;
}
@@ -206,12 +200,12 @@ static int setup_pg_tables_pae(int xc_handle, u32 dom,
#if defined(__x86_64__)
static int setup_pg_tables_64(int xc_handle, u32 dom,
vcpu_guest_context_t *ctxt,
unsigned long dsi_v_start,
unsigned long v_end,
unsigned long *page_array,
unsigned long vpt_start,
unsigned long vpt_end)
vcpu_guest_context_t *ctxt,
unsigned long dsi_v_start,
unsigned long v_end,
unsigned long *page_array,
unsigned long vpt_start,
unsigned long vpt_end)
{
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
@@ -236,20 +230,20 @@ static int setup_pg_tables_64(int xc_handle, u32 dom,
{
alloc_pt(l1tab, vl1tab);
if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
{
alloc_pt(l2tab, vl2tab);
if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) )
{
alloc_pt(l2tab, vl2tab);
if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) )
{
alloc_pt(l3tab, vl3tab);
vl3e = &vl3tab[l3_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
*vl4e = l3tab | L4_PROT;
vl4e++;
}
vl2e = &vl2tab[l2_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
*vl3e = l2tab | L3_PROT;
vl3e++;
alloc_pt(l3tab, vl3tab);
vl3e = &vl3tab[l3_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
*vl4e = l3tab | L4_PROT;
vl4e++;
}
vl2e = &vl2tab[l2_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
*vl3e = l2tab | L3_PROT;
vl3e++;
}
vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
*vl2e = l1tab | L2_PROT;
vl2e++;
@@ -257,11 +251,11 @@ static int setup_pg_tables_64(int xc_handle, u32 dom,
*vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
(count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) )
(count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) )
{
*vl1e &= ~_PAGE_RW;
*vl1e &= ~_PAGE_RW;
}
vl1e++;
vl1e++;
}
munmap(vl1tab, PAGE_SIZE);
@@ -272,13 +266,13 @@ static int setup_pg_tables_64(int xc_handle, u32 dom,
error_out:
if (vl1tab)
munmap(vl1tab, PAGE_SIZE);
munmap(vl1tab, PAGE_SIZE);
if (vl2tab)
munmap(vl2tab, PAGE_SIZE);
munmap(vl2tab, PAGE_SIZE);
if (vl3tab)
munmap(vl3tab, PAGE_SIZE);
munmap(vl3tab, PAGE_SIZE);
if (vl4tab)
munmap(vl4tab, PAGE_SIZE);
munmap(vl4tab, PAGE_SIZE);
return -1;
}
#endif
@@ -286,18 +280,18 @@ static int setup_pg_tables_64(int xc_handle, u32 dom,
#ifdef __ia64__
#include <asm/fpu.h> /* for FPSR_DEFAULT */
static int setup_guest(int xc_handle,
u32 dom,
char *image, unsigned long image_size,
gzFile initrd_gfd, unsigned long initrd_len,
unsigned long nr_pages,
unsigned long *pvsi, unsigned long *pvke,
unsigned long *pvss, vcpu_guest_context_t *ctxt,
const char *cmdline,
unsigned long shared_info_frame,
unsigned long flags,
unsigned int vcpus,
unsigned int store_evtchn, unsigned long *store_mfn,
unsigned int console_evtchn, unsigned long *console_mfn)
u32 dom,
char *image, unsigned long image_size,
gzFile initrd_gfd, unsigned long initrd_len,
unsigned long nr_pages,
unsigned long *pvsi, unsigned long *pvke,
unsigned long *pvss, vcpu_guest_context_t *ctxt,
const char *cmdline,
unsigned long shared_info_frame,
unsigned long flags,
unsigned int vcpus,
unsigned int store_evtchn, unsigned long *store_mfn,
unsigned int console_evtchn, unsigned long *console_mfn)
{
unsigned long *page_array = NULL;
struct load_funcs load_funcs;
@@ -339,19 +333,20 @@ static int setup_guest(int xc_handle,
*pvke = dsi.v_kernentry;
/* Now need to retrieve machine pfn for system pages:
* start_info/store/console
* start_info/store/console
*/
pgnr = 3;
if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, nr_pages - 3, pgnr) != pgnr)
if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array,
nr_pages - 3, pgnr) != pgnr )
{
PERROR("Could not get page frame for xenstore");
goto error_out;
PERROR("Could not get page frame for xenstore");
goto error_out;
}
*store_mfn = page_array[1];
*console_mfn = page_array[2];
printf("store_mfn: 0x%lx, console_mfn: 0x%lx\n",
(u64)store_mfn, (u64)console_mfn);
(u64)store_mfn, (u64)console_mfn);
start_info = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]);
@@ -382,8 +377,8 @@ static int setup_guest(int xc_handle,
unsigned long shared_info_frame,
unsigned long flags,
unsigned int vcpus,
unsigned int store_evtchn, unsigned long *store_mfn,
unsigned int console_evtchn, unsigned long *console_mfn)
unsigned int store_evtchn, unsigned long *store_mfn,
unsigned int console_evtchn, unsigned long *console_mfn)
{
unsigned long *page_array = NULL;
unsigned long count, i;
@@ -458,26 +453,26 @@ static int setup_guest(int xc_handle,
if ( (v_end - vstack_end) < (512UL << 10) )
v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */
#if defined(__i386__)
if (dsi.pae_kernel) {
/* FIXME: assumes one L2 pgtable @ 0xc0000000 */
if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT_PAE)-1)) >>
L2_PAGETABLE_SHIFT_PAE) + 2) <= nr_pt_pages )
break;
} else {
if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >>
L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
break;
}
if (dsi.pae_kernel) {
/* FIXME: assumes one L2 pgtable @ 0xc0000000 */
if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT_PAE)-1)) >>
L2_PAGETABLE_SHIFT_PAE) + 2) <= nr_pt_pages )
break;
} else {
if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >>
L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
break;
}
#endif
#if defined(__x86_64__)
#define NR(_l,_h,_s) \
(((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
((_l) & ~((1UL<<(_s))-1))) >> (_s))
if ( (1 + /* # L4 */
NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */
NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
<= nr_pt_pages )
if ( (1 + /* # L4 */
NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */
NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
<= nr_pt_pages )
break;
#endif
}
@@ -541,7 +536,7 @@ static int setup_guest(int xc_handle,
goto error_out;
}
xc_copy_to_domain_page(xc_handle, dom,
page_array[i>>PAGE_SHIFT], page);
page_array[i>>PAGE_SHIFT], page);
}
}
@@ -551,22 +546,22 @@ static int setup_guest(int xc_handle,
/* setup page tables */
#if defined(__i386__)
if (dsi.pae_kernel)
rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
dsi.v_start, v_end,
page_array, vpt_start, vpt_end);
rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
dsi.v_start, v_end,
page_array, vpt_start, vpt_end);
else {
rc = setup_pg_tables(xc_handle, dom, ctxt,
dsi.v_start, v_end,
page_array, vpt_start, vpt_end);
rc = setup_pg_tables(xc_handle, dom, ctxt,
dsi.v_start, v_end,
page_array, vpt_start, vpt_end);
}
#endif
#if defined(__x86_64__)
rc = setup_pg_tables_64(xc_handle, dom, ctxt,
dsi.v_start, v_end,
page_array, vpt_start, vpt_end);
dsi.v_start, v_end,
page_array, vpt_start, vpt_end);
#endif
if (0 != rc)
goto error_out;
goto error_out;
/* Write the phys->machine and machine->phys table entries. */
physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
@@ -576,11 +571,13 @@ static int setup_guest(int xc_handle,
for ( count = 0; count < nr_pages; count++ )
{
if ( xc_add_mmu_update(xc_handle, mmu,
((unsigned long long)page_array[count] << PAGE_SHIFT) |
MMU_MACHPHYS_UPDATE, count) )
if ( xc_add_mmu_update(
xc_handle, mmu,
((u64)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
count) )
{
fprintf(stderr,"m2p update failure p=%lx m=%lx\n",count,page_array[count] );
fprintf(stderr,"m2p update failure p=%lx m=%lx\n",
count, page_array[count]);
munmap(physmap, PAGE_SIZE);
goto error_out;
}
@@ -601,13 +598,13 @@ static int setup_guest(int xc_handle,
* correct protection for the page
*/
if (dsi.pae_kernel) {
if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
goto error_out;
if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
goto error_out;
} else {
if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
goto error_out;
if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
goto error_out;
}
#endif
@@ -616,8 +613,8 @@ static int setup_guest(int xc_handle,
* Pin down l4tab addr as page dir page - causes hypervisor to provide
* correct protection for the page
*/
if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
goto error_out;
#endif
@@ -703,12 +700,7 @@ int xc_linux_build(int xc_handle,
unsigned long image_size, initrd_size=0;
unsigned long vstartinfo_start, vkern_entry, vstack_start;
#ifdef __ia64__
/* Current xen/ia64 allocates domU pages on demand */
if ( (nr_pages = xc_get_max_pages(xc_handle, domid)) < 0 )
#else
if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 )
#endif
if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 )
{
PERROR("Could not find total pages for domain");
goto error_out;
@@ -755,12 +747,7 @@ int xc_linux_build(int xc_handle,
goto error_out;
}
if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
#ifdef __ia64__
0 )
#else
(ctxt->ctrlreg[3] != 0) )
#endif
if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) || already_built(ctxt) )
{
ERROR("Domain is already constructed");
goto error_out;
@@ -773,7 +760,7 @@ int xc_linux_build(int xc_handle,
op.u.getdomaininfo.shared_info_frame,
flags, vcpus,
store_evtchn, store_mfn,
console_evtchn, console_mfn) < 0 )
console_evtchn, console_mfn) < 0 )
{
ERROR("Error constructing guest OS");
goto error_out;
@@ -789,12 +776,13 @@ int xc_linux_build(int xc_handle,
/* based on new_thread in xen/arch/ia64/domain.c */
ctxt->flags = 0;
ctxt->shared.flags = flags;
ctxt->shared.start_info_pfn = nr_pages - 3; // metaphysical
ctxt->shared.start_info_pfn = nr_pages - 3; /* metaphysical */
ctxt->regs.cr_ipsr = 0; /* all necessary bits filled by hypervisor */
ctxt->regs.cr_iip = vkern_entry;
ctxt->regs.cr_ifs = 1UL << 63;
ctxt->regs.ar_fpsr = FPSR_DEFAULT;
/* ctxt->regs.r28 = dom_fw_setup(); currently done by hypervisor, should move here */
/* currently done by hypervisor, should move here */
/* ctxt->regs.r28 = dom_fw_setup(); */
ctxt->vcpu.privregs = 0;
ctxt->sys_pgnr = nr_pages - 3;
i = 0; /* silence unused variable warning */
@@ -875,3 +863,13 @@ int xc_linux_build(int xc_handle,
return -1;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+267 -217
View File
@@ -18,7 +18,6 @@
#define MAX_MBIT_RATE 500
/*
** Default values for important tuning parameters. Can override by passing
** non-zero replacement values to xc_linux_save().
@@ -29,13 +28,10 @@
#define DEF_MAX_ITERS 29 /* limit us to 30 times round loop */
#define DEF_MAX_FACTOR 3 /* never send more than 3x nr_pfns */
/* Flags to control behaviour of xc_linux_save */
#define XCFLAGS_LIVE 1
#define XCFLAGS_DEBUG 2
#define DEBUG 0
#if 1
@@ -115,8 +111,8 @@ static inline int count_bits ( int nr, volatile void *addr)
int i, count = 0;
unsigned long *p = (unsigned long *)addr;
/* We know that the array is padded to unsigned long. */
for(i=0;i<nr/(sizeof(unsigned long)*8);i++,p++)
count += hweight32( *p );
for( i = 0; i < (nr / (sizeof(unsigned long)*8)); i++, p++ )
count += hweight32(*p);
return count;
}
@@ -201,42 +197,50 @@ ratewrite(int io_fd, void *buf, int n)
struct timespec delay;
long long delta;
if (START_MBIT_RATE == 0)
return write(io_fd, buf, n);
if ( START_MBIT_RATE == 0 )
return write(io_fd, buf, n);
budget -= n;
if (budget < 0) {
if (MBIT_RATE != ombit_rate) {
BURST_TIME_US = RATE_TO_BTU / MBIT_RATE;
ombit_rate = MBIT_RATE;
DPRINTF("rate limit: %d mbit/s burst budget %d slot time %d\n",
MBIT_RATE, BURST_BUDGET, BURST_TIME_US);
}
if (last_put.tv_sec == 0) {
budget += BURST_BUDGET;
gettimeofday(&last_put, NULL);
} else {
while (budget < 0) {
gettimeofday(&now, NULL);
delta = tv_delta(&now, &last_put);
while (delta > BURST_TIME_US) {
budget += BURST_BUDGET;
last_put.tv_usec += BURST_TIME_US;
if (last_put.tv_usec > 1000000) {
last_put.tv_usec -= 1000000;
last_put.tv_sec++;
}
delta -= BURST_TIME_US;
}
if (budget > 0)
break;
delay.tv_sec = 0;
delay.tv_nsec = 1000 * (BURST_TIME_US - delta);
while (delay.tv_nsec > 0)
if (nanosleep(&delay, &delay) == 0)
break;
}
}
if ( budget < 0 )
{
if ( MBIT_RATE != ombit_rate )
{
BURST_TIME_US = RATE_TO_BTU / MBIT_RATE;
ombit_rate = MBIT_RATE;
DPRINTF("rate limit: %d mbit/s burst budget %d slot time %d\n",
MBIT_RATE, BURST_BUDGET, BURST_TIME_US);
}
if ( last_put.tv_sec == 0 )
{
budget += BURST_BUDGET;
gettimeofday(&last_put, NULL);
}
else
{
while ( budget < 0 )
{
gettimeofday(&now, NULL);
delta = tv_delta(&now, &last_put);
while ( delta > BURST_TIME_US )
{
budget += BURST_BUDGET;
last_put.tv_usec += BURST_TIME_US;
if ( last_put.tv_usec > 1000000 )
{
last_put.tv_usec -= 1000000;
last_put.tv_sec++;
}
delta -= BURST_TIME_US;
}
if ( budget > 0 )
break;
delay.tv_sec = 0;
delay.tv_nsec = 1000 * (BURST_TIME_US - delta);
while ( delay.tv_nsec > 0 )
if ( nanosleep(&delay, &delay) == 0 )
break;
}
}
}
return write(io_fd, buf, n);
}
@@ -271,20 +275,21 @@ static int print_stats( int xc_handle, u32 domid,
if ( print )
fprintf(stderr,
"delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, "
"dirtied %dMb/s %" PRId32 " pages\n",
wall_delta,
(int)((d0_cpu_delta*100)/wall_delta),
(int)((d1_cpu_delta*100)/wall_delta),
(int)((pages_sent*PAGE_SIZE)/(wall_delta*(1000/8))),
(int)((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8))),
stats->dirty_count);
"delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, "
"dirtied %dMb/s %" PRId32 " pages\n",
wall_delta,
(int)((d0_cpu_delta*100)/wall_delta),
(int)((d1_cpu_delta*100)/wall_delta),
(int)((pages_sent*PAGE_SIZE)/(wall_delta*(1000/8))),
(int)((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8))),
stats->dirty_count);
if (((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8))) > mbit_rate) {
mbit_rate = (int)((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8)))
+ 50;
if (mbit_rate > MAX_MBIT_RATE)
mbit_rate = MAX_MBIT_RATE;
if ( ((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8))) > mbit_rate )
{
mbit_rate = (int)((stats->dirty_count*PAGE_SIZE)/(wall_delta*(1000/8)))
+ 50;
if (mbit_rate > MAX_MBIT_RATE)
mbit_rate = MAX_MBIT_RATE;
}
d0_cpu_last = d0_cpu_now;
@@ -303,7 +308,7 @@ static int analysis_phase( int xc_handle, u32 domid,
start = llgettimeofday();
for (j = 0; j < runs; j++)
for ( j = 0; j < runs; j++ )
{
int i;
@@ -320,10 +325,10 @@ static int analysis_phase( int xc_handle, u32 domid,
NULL, 0, &stats);
fprintf(stderr, "now= %lld faults= %" PRId32 " dirty= %" PRId32
" dirty_net= %" PRId32 " dirty_block= %" PRId32"\n",
((now-start)+500)/1000,
stats.fault_count, stats.dirty_count,
stats.dirty_net_count, stats.dirty_block_count);
" dirty_net= %" PRId32 " dirty_block= %" PRId32"\n",
((now-start)+500)/1000,
stats.fault_count, stats.dirty_count,
stats.dirty_net_count, stats.dirty_block_count);
}
}
@@ -331,7 +336,7 @@ static int analysis_phase( int xc_handle, u32 domid,
}
static int suspend_and_state(int xc_handle, int io_fd, int dom,
static int suspend_and_state(int xc_handle, int io_fd, int dom,
xc_dominfo_t *info,
vcpu_guest_context_t *ctxt)
{
@@ -340,51 +345,53 @@ static int suspend_and_state(int xc_handle, int io_fd, int dom,
printf("suspend\n");
fflush(stdout);
if (fgets(ans, sizeof(ans), stdin) == NULL) {
if ( fgets(ans, sizeof(ans), stdin) == NULL )
{
ERR("failed reading suspend reply");
return -1;
}
if (strncmp(ans, "done\n", 5)) {
if ( strncmp(ans, "done\n", 5) )
{
ERR("suspend reply incorrect: %s", ans);
return -1;
}
retry:
retry:
if ( xc_domain_getinfo(xc_handle, dom, 1, info) != 1)
{
ERR("Could not get domain info");
return -1;
ERR("Could not get domain info");
return -1;
}
if ( xc_domain_get_vcpu_context(xc_handle, dom, 0 /* XXX */,
ctxt) )
ctxt) )
{
ERR("Could not get vcpu context");
}
if ( info->shutdown && info->shutdown_reason == SHUTDOWN_suspend )
{
return 0; // success
return 0; // success
}
if ( info->paused )
{
// try unpausing domain, wait, and retest
xc_domain_unpause( xc_handle, dom );
// try unpausing domain, wait, and retest
xc_domain_unpause( xc_handle, dom );
ERR("Domain was paused. Wait and re-test.");
usleep(10000); // 10ms
ERR("Domain was paused. Wait and re-test.");
usleep(10000); // 10ms
goto retry;
goto retry;
}
if( ++i < 100 )
{
ERR("Retry suspend domain.");
usleep(10000); // 10ms
goto retry;
ERR("Retry suspend domain.");
usleep(10000); // 10ms
goto retry;
}
ERR("Unable to suspend domain.");
@@ -454,26 +461,26 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
/* If no explicit control parameters given, use defaults */
if(!max_iters)
if( !max_iters )
max_iters = DEF_MAX_ITERS;
if(!max_factor)
if( !max_factor )
max_factor = DEF_MAX_FACTOR;
DPRINTF("xc_linux_save start DOM%u live=%s\n", dom, live?"true":"false");
if (mlock(&ctxt, sizeof(ctxt))) {
if ( mlock(&ctxt, sizeof(ctxt)) )
{
ERR("Unable to mlock ctxt");
return 1;
}
if ( xc_domain_getinfo(xc_handle, dom, 1, &info) != 1)
if ( xc_domain_getinfo(xc_handle, dom, 1, &info) != 1 )
{
ERR("Could not get domain info");
goto out;
}
if ( xc_domain_get_vcpu_context( xc_handle, dom, /* FIXME */ 0,
&ctxt) )
if ( xc_domain_get_vcpu_context(xc_handle, dom, /* FIXME */ 0, &ctxt) )
{
ERR("Could not get vcpu context");
goto out;
@@ -481,7 +488,8 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
shared_info_frame = info.shared_info_frame;
/* A cheesy test to see whether the domain contains valid state. */
if ( ctxt.ctrlreg[3] == 0 ){
if ( ctxt.ctrlreg[3] == 0 )
{
ERR("Domain is not in a valid Linux guest OS state");
goto out;
}
@@ -496,18 +504,17 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
}
/* Map the shared info frame */
live_shinfo = xc_map_foreign_range(xc_handle, dom,
PAGE_SIZE, PROT_READ,
shared_info_frame);
if (!live_shinfo){
live_shinfo = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ, shared_info_frame);
if ( !live_shinfo )
{
ERR("Couldn't map live_shinfo");
goto out;
}
live_pfn_to_mfn_frame_list_list = xc_map_foreign_range(xc_handle, dom,
PAGE_SIZE, PROT_READ,
live_shinfo->arch.pfn_to_mfn_frame_list_list);
live_pfn_to_mfn_frame_list_list = xc_map_foreign_range(
xc_handle, dom,
PAGE_SIZE, PROT_READ, live_shinfo->arch.pfn_to_mfn_frame_list_list);
if (!live_pfn_to_mfn_frame_list_list){
ERR("Couldn't map pfn_to_mfn_frame_list_list");
@@ -515,12 +522,13 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
}
live_pfn_to_mfn_frame_list =
xc_map_foreign_batch(xc_handle, dom,
PROT_READ,
live_pfn_to_mfn_frame_list_list,
(nr_pfns+(1024*1024)-1)/(1024*1024) );
xc_map_foreign_batch(xc_handle, dom,
PROT_READ,
live_pfn_to_mfn_frame_list_list,
(nr_pfns+(1024*1024)-1)/(1024*1024) );
if (!live_pfn_to_mfn_frame_list){
if ( !live_pfn_to_mfn_frame_list)
{
ERR("Couldn't map pfn_to_mfn_frame_list");
goto out;
}
@@ -535,7 +543,8 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
PROT_READ,
live_pfn_to_mfn_frame_list,
(nr_pfns+1023)/1024 );
if( !live_pfn_to_mfn_table ){
if ( !live_pfn_to_mfn_table )
{
ERR("Couldn't map pfn_to_mfn table");
goto out;
}
@@ -544,15 +553,17 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
mfn_to_pfn_table_start_mfn = xc_get_m2p_start_mfn( xc_handle );
live_mfn_to_pfn_table =
xc_map_foreign_range(xc_handle, DOMID_XEN,
PAGE_SIZE*1024, PROT_READ,
mfn_to_pfn_table_start_mfn );
xc_map_foreign_range(xc_handle, DOMID_XEN,
PAGE_SIZE*1024, PROT_READ,
mfn_to_pfn_table_start_mfn );
/* Canonicalise the pfn-to-mfn table frame-number list. */
memcpy( pfn_to_mfn_frame_list, live_pfn_to_mfn_frame_list, PAGE_SIZE );
for ( i = 0; i < nr_pfns; i += 1024 ){
if ( !translate_mfn_to_pfn(&pfn_to_mfn_frame_list[i/1024]) ){
for ( i = 0; i < nr_pfns; i += 1024 )
{
if ( !translate_mfn_to_pfn(&pfn_to_mfn_frame_list[i/1024]) )
{
ERR("Frame# in pfn-to-mfn frame list is not in pseudophys");
goto out;
}
@@ -561,40 +572,44 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
/* Domain is still running at this point */
if( live )
if ( live )
{
if ( xc_shadow_control( xc_handle, dom,
DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY,
NULL, 0, NULL ) < 0 ) {
NULL, 0, NULL ) < 0 )
{
ERR("Couldn't enable shadow mode");
goto out;
}
last_iter = 0;
} else{
/* This is a non-live suspend. Issue the call back to get the
domain suspended */
}
else
{
/* This is a non-live suspend. Issue the call back to get the
domain suspended */
last_iter = 1;
if ( suspend_and_state( xc_handle, io_fd, dom, &info, &ctxt) )
{
ERR("Domain appears not to have suspended");
goto out;
}
if ( suspend_and_state( xc_handle, io_fd, dom, &info, &ctxt) )
{
ERR("Domain appears not to have suspended");
goto out;
}
}
sent_last_iter = 1<<20; /* 4GB of pages */
/* calculate the power of 2 order of nr_pfns, e.g.
15->4 16->4 17->5 */
for( i=nr_pfns-1, order_nr=0; i ; i>>=1, order_nr++ );
for ( i = nr_pfns-1, order_nr = 0; i ; i >>= 1, order_nr++ )
continue;
/* Setup to_send bitmap */
{
/* size these for a maximal 4GB domain, to make interaction
with balloon driver easier. It's only user space memory,
ater all... (3x 128KB) */
/* size these for a maximal 4GB domain, to make interaction
with balloon driver easier. It's only user space memory,
ater all... (3x 128KB) */
int sz = ( 1<<20 ) / 8;
@@ -602,21 +617,24 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
to_fix = calloc( 1, sz );
to_skip = malloc( sz );
if (!to_send || !to_fix || !to_skip){
if ( !to_send || !to_fix || !to_skip )
{
ERR("Couldn't allocate to_send array");
goto out;
}
memset( to_send, 0xff, sz );
memset(to_send, 0xff, sz);
if ( mlock( to_send, sz ) ){
if ( mlock(to_send, sz) )
{
ERR("Unable to mlock to_send");
return 1;
}
/* (to fix is local only) */
if ( mlock( to_skip, sz ) ){
if ( mlock(to_skip, sz) )
{
ERR("Unable to mlock to_skip");
return 1;
}
@@ -629,12 +647,14 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
pfn_type = calloc(BATCH_SIZE, sizeof(unsigned long));
pfn_batch = calloc(BATCH_SIZE, sizeof(unsigned long));
if ( (pfn_type == NULL) || (pfn_batch == NULL) ){
if ( (pfn_type == NULL) || (pfn_batch == NULL) )
{
errno = ENOMEM;
goto out;
}
if ( mlock( pfn_type, BATCH_SIZE * sizeof(unsigned long) ) ){
if ( mlock(pfn_type, BATCH_SIZE * sizeof(unsigned long)) )
{
ERR("Unable to mlock");
goto out;
}
@@ -645,31 +665,34 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
*/
#if DEBUG
{
int err=0;
for ( i = 0; i < nr_pfns; i++ )
{
mfn = live_pfn_to_mfn_table[i];
if( (live_mfn_to_pfn_table[mfn] != i) && (mfn != 0xffffffffUL) )
{
fprintf(stderr, "i=0x%x mfn=%lx live_mfn_to_pfn_table=%lx\n",
i,mfn,live_mfn_to_pfn_table[mfn]);
err++;
}
}
fprintf(stderr, "Had %d unexplained entries in p2m table\n",err);
int err=0;
for ( i = 0; i < nr_pfns; i++ )
{
mfn = live_pfn_to_mfn_table[i];
if( (live_mfn_to_pfn_table[mfn] != i) && (mfn != 0xffffffffUL) )
{
fprintf(stderr, "i=0x%x mfn=%lx live_mfn_to_pfn_table=%lx\n",
i,mfn,live_mfn_to_pfn_table[mfn]);
err++;
}
}
fprintf(stderr, "Had %d unexplained entries in p2m table\n",err);
}
#endif
/* Start writing out the saved-domain record. */
if (write(io_fd, &nr_pfns, sizeof(unsigned long)) !=
sizeof(unsigned long)) {
ERR("write: nr_pfns");
goto out;
if ( write(io_fd, &nr_pfns, sizeof(unsigned long)) !=
sizeof(unsigned long) )
{
ERR("write: nr_pfns");
goto out;
}
if (write(io_fd, pfn_to_mfn_frame_list, PAGE_SIZE) != PAGE_SIZE) {
if ( write(io_fd, pfn_to_mfn_frame_list, PAGE_SIZE) != PAGE_SIZE )
{
ERR("write: pfn_to_mfn_frame_list");
goto out;
}
@@ -678,7 +701,8 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
/* Now write out each data page, canonicalising page tables as we go... */
while(1){
for ( ; ; )
{
unsigned int prev_pc, sent_this_iter, N, batch;
iter++;
@@ -689,10 +713,12 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
DPRINTF("Saving memory pages: iter %d 0%%", iter);
while( N < nr_pfns ){
while ( N < nr_pfns )
{
unsigned int this_pc = (N * 100) / nr_pfns;
if ( (this_pc - prev_pc) >= 5 ){
if ( (this_pc - prev_pc) >= 5 )
{
DPRINTF("\b\b\b\b%3d%%", this_pc);
prev_pc = this_pc;
}
@@ -701,10 +727,10 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
but this is fast enough for the moment. */
if ( !last_iter &&
xc_shadow_control(xc_handle, dom,
xc_shadow_control(xc_handle, dom,
DOM0_SHADOW_CONTROL_OP_PEEK,
to_skip, nr_pfns, NULL) != nr_pfns )
{
{
ERR("Error peeking shadow bitmap");
goto out;
}
@@ -748,7 +774,7 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
pfn_type[batch] = live_pfn_to_mfn_table[n];
if( ! is_mapped(pfn_type[batch]) )
{
{
/* not currently in pusedo-physical map -- set bit
in to_fix that we must send this page in last_iter
unless its sent sooner anyhow */
@@ -756,7 +782,7 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
set_bit( n, to_fix );
if( iter>1 )
DPRINTF("netbuf race: iter %d, pfn %x. mfn %lx\n",
iter,n,pfn_type[batch]);
iter,n,pfn_type[batch]);
continue;
}
@@ -790,8 +816,10 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
goto out;
}
for ( j = 0; j < batch; j++ ){
if ( (pfn_type[j] & LTAB_MASK) == XTAB ){
for ( j = 0; j < batch; j++ )
{
if ( (pfn_type[j] & LTAB_MASK) == XTAB )
{
DPRINTF("type fail: page %i mfn %08lx\n",j,pfn_type[j]);
continue;
}
@@ -809,21 +837,25 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
pfn_type[j] = (pfn_type[j] & LTAB_MASK) | pfn_batch[j];
}
if (write(io_fd, &batch, sizeof(int)) != sizeof(int)) {
if ( write(io_fd, &batch, sizeof(int)) != sizeof(int) )
{
ERR("Error when writing to state file (2)");
goto out;
}
if (write(io_fd, pfn_type, sizeof(unsigned long)*j) !=
sizeof(unsigned long)*j) {
if ( write(io_fd, pfn_type, sizeof(unsigned long)*j) !=
(sizeof(unsigned long) * j) )
{
ERR("Error when writing to state file (3)");
goto out;
}
/* entering this loop, pfn_type is now in pfns (Not mfns) */
for( j = 0; j < batch; j++ ){
for ( j = 0; j < batch; j++ )
{
/* write out pages in batch */
if( (pfn_type[j] & LTAB_MASK) == XTAB){
if ( (pfn_type[j] & LTAB_MASK) == XTAB )
{
DPRINTF("SKIP BOGUS page %i mfn %08lx\n",j,pfn_type[j]);
continue;
}
@@ -836,7 +868,8 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
k < (((pfn_type[j] & LTABTYPE_MASK) == L2TAB) ?
(HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT) :
1024);
k++ ){
k++ )
{
unsigned long pfn;
if ( !(page[k] & _PAGE_PRESENT) )
@@ -849,13 +882,13 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
{
/* I don't think this should ever happen */
fprintf(stderr, "FNI %d : [%08lx,%d] pte=%08lx, "
"mfn=%08lx, pfn=%08lx [mfn]=%08lx\n",
j, pfn_type[j], k,
page[k], mfn, live_mfn_to_pfn_table[mfn],
(live_mfn_to_pfn_table[mfn]<nr_pfns)?
live_pfn_to_mfn_table[
live_mfn_to_pfn_table[mfn]] :
0xdeadbeef);
"mfn=%08lx, pfn=%08lx [mfn]=%08lx\n",
j, pfn_type[j], k,
page[k], mfn, live_mfn_to_pfn_table[mfn],
(live_mfn_to_pfn_table[mfn]<nr_pfns)?
live_pfn_to_mfn_table[
live_mfn_to_pfn_table[mfn]] :
0xdeadbeef);
pfn = 0; /* be suspicious */
}
@@ -865,12 +898,12 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
#if 0
fprintf(stderr,
"L%d i=%d pfn=%d mfn=%d k=%d pte=%08lx "
"xpfn=%d\n",
pfn_type[j]>>28,
j,i,mfn,k,page[k],page[k]>>PAGE_SHIFT);
"L%d i=%d pfn=%d mfn=%d k=%d pte=%08lx "
"xpfn=%d\n",
pfn_type[j]>>28,
j,i,mfn,k,page[k],page[k]>>PAGE_SHIFT);
#endif
} /* end of page table rewrite for loop */
if (ratewrite(io_fd, page, PAGE_SIZE) != PAGE_SIZE) {
@@ -880,8 +913,9 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
} /* end of it's a PT page */ else { /* normal page */
if (ratewrite(io_fd, region_base + (PAGE_SIZE*j),
PAGE_SIZE) != PAGE_SIZE) {
if ( ratewrite(io_fd, region_base + (PAGE_SIZE*j),
PAGE_SIZE) != PAGE_SIZE )
{
ERR("Error when writing to state file (5)");
goto out;
}
@@ -899,13 +933,13 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
total_sent += sent_this_iter;
DPRINTF("\r %d: sent %d, skipped %d, ",
iter, sent_this_iter, skip_this_iter );
iter, sent_this_iter, skip_this_iter );
if ( last_iter ) {
print_stats( xc_handle, dom, sent_this_iter, &stats, 1);
DPRINTF("Total pages sent= %d (%.2fx)\n",
total_sent, ((float)total_sent)/nr_pfns );
total_sent, ((float)total_sent)/nr_pfns );
DPRINTF("(of which %d were fixups)\n", needed_to_fix );
}
@@ -930,7 +964,7 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
{
if (
( ( sent_this_iter > sent_last_iter ) &&
(mbit_rate == MAX_MBIT_RATE ) ) ||
(mbit_rate == MAX_MBIT_RATE ) ) ||
(iter >= max_iters) ||
(sent_this_iter+skip_this_iter < 50) ||
(total_sent > nr_pfns*max_factor) )
@@ -938,15 +972,15 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
DPRINTF("Start last iteration\n");
last_iter = 1;
if ( suspend_and_state( xc_handle, io_fd, dom, &info, &ctxt) )
{
ERR("Domain appears not to have suspended");
goto out;
}
if ( suspend_and_state( xc_handle, io_fd, dom, &info, &ctxt) )
{
ERR("Domain appears not to have suspended");
goto out;
}
DPRINTF("SUSPEND shinfo %08lx eip %08u esi %08u\n",
info.shared_info_frame,
ctxt.user_regs.eip, ctxt.user_regs.esi);
DPRINTF("SUSPEND shinfo %08lx eip %08u esi %08u\n",
info.shared_info_frame,
ctxt.user_regs.eip, ctxt.user_regs.esi);
}
if ( xc_shadow_control( xc_handle, dom,
@@ -972,86 +1006,92 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
rc = 0;
/* Zero terminate */
if (write(io_fd, &rc, sizeof(int)) != sizeof(int)) {
if ( write(io_fd, &rc, sizeof(int)) != sizeof(int) )
{
ERR("Error when writing to state file (6)");
goto out;
}
/* Send through a list of all the PFNs that were not in map at the close */
{
unsigned int i,j;
unsigned int pfntab[1024];
unsigned int i,j;
unsigned int pfntab[1024];
for ( i = 0, j = 0; i < nr_pfns; i++ )
{
if ( ! is_mapped(live_pfn_to_mfn_table[i]) )
j++;
}
for ( i = 0, j = 0; i < nr_pfns; i++ )
if ( !is_mapped(live_pfn_to_mfn_table[i]) )
j++;
if (write(io_fd, &j, sizeof(unsigned int)) != sizeof(unsigned int)) {
ERR("Error when writing to state file (6a)");
goto out;
}
if ( write(io_fd, &j, sizeof(unsigned int)) != sizeof(unsigned int) )
{
ERR("Error when writing to state file (6a)");
goto out;
}
for ( i = 0, j = 0; i < nr_pfns; )
{
if ( ! is_mapped(live_pfn_to_mfn_table[i]) )
{
pfntab[j++] = i;
}
i++;
if ( j == 1024 || i == nr_pfns )
{
if (write(io_fd, &pfntab, sizeof(unsigned long)*j) !=
sizeof(unsigned long)*j) {
ERR("Error when writing to state file (6b)");
goto out;
}
j = 0;
}
}
for ( i = 0, j = 0; i < nr_pfns; )
{
if ( !is_mapped(live_pfn_to_mfn_table[i]) )
{
pfntab[j++] = i;
}
i++;
if ( j == 1024 || i == nr_pfns )
{
if ( write(io_fd, &pfntab, sizeof(unsigned long)*j) !=
(sizeof(unsigned long) * j) )
{
ERR("Error when writing to state file (6b)");
goto out;
}
j = 0;
}
}
}
/* Canonicalise the suspend-record frame number. */
if ( !translate_mfn_to_pfn(&ctxt.user_regs.esi) ){
if ( !translate_mfn_to_pfn(&ctxt.user_regs.esi) )
{
ERR("Suspend record is not in range of pseudophys map");
goto out;
}
/* Canonicalise each GDT frame number. */
for ( i = 0; i < ctxt.gdt_ents; i += 512 ) {
if ( !translate_mfn_to_pfn(&ctxt.gdt_frames[i]) ) {
for ( i = 0; i < ctxt.gdt_ents; i += 512 )
{
if ( !translate_mfn_to_pfn(&ctxt.gdt_frames[i]) )
{
ERR("GDT frame is not in range of pseudophys map");
goto out;
}
}
/* Canonicalise the page table base pointer. */
if ( !MFN_IS_IN_PSEUDOPHYS_MAP(ctxt.ctrlreg[3] >> PAGE_SHIFT) ) {
if ( !MFN_IS_IN_PSEUDOPHYS_MAP(ctxt.ctrlreg[3] >> PAGE_SHIFT) )
{
ERR("PT base is not in range of pseudophys map");
goto out;
}
ctxt.ctrlreg[3] = live_mfn_to_pfn_table[ctxt.ctrlreg[3] >> PAGE_SHIFT] <<
PAGE_SHIFT;
if (write(io_fd, &ctxt, sizeof(ctxt)) != sizeof(ctxt) ||
write(io_fd, live_shinfo, PAGE_SIZE) != PAGE_SIZE) {
if ( write(io_fd, &ctxt, sizeof(ctxt)) != sizeof(ctxt) ||
write(io_fd, live_shinfo, PAGE_SIZE) != PAGE_SIZE)
{
ERR("Error when writing to state file (1)");
goto out;
}
out:
if(live_shinfo)
if ( live_shinfo )
munmap(live_shinfo, PAGE_SIZE);
if(live_pfn_to_mfn_frame_list)
if ( live_pfn_to_mfn_frame_list )
munmap(live_pfn_to_mfn_frame_list, PAGE_SIZE);
if(live_pfn_to_mfn_table)
if ( live_pfn_to_mfn_table )
munmap(live_pfn_to_mfn_table, nr_pfns*4);
if(live_mfn_to_pfn_table)
if ( live_mfn_to_pfn_table )
munmap(live_mfn_to_pfn_table, PAGE_SIZE*1024);
free(pfn_type);
@@ -1063,3 +1103,13 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters,
DPRINTF("Save exit rc=%d\n",rc);
return !!rc;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+14 -5
View File
@@ -64,11 +64,11 @@ parseaout9image(
dstart = round_pgup(start + ehdr.text);
end = dstart + ehdr.data + ehdr.bss;
dsi->v_start = KZERO;
dsi->v_kernstart = start;
dsi->v_kernend = end;
dsi->v_kernentry = ehdr.entry;
dsi->v_end = end;
dsi->v_start = KZERO;
dsi->v_kernstart = start;
dsi->v_kernend = end;
dsi->v_kernentry = ehdr.entry;
dsi->v_end = end;
/* XXX load symbols */
@@ -168,3 +168,12 @@ get_header(
return ehdr;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+12 -2
View File
@@ -109,8 +109,8 @@ loadbinimage(
unsigned long *parray, struct domain_setup_info *dsi);
int probe_bin(char *image,
unsigned long image_size,
struct load_funcs *load_funcs)
unsigned long image_size,
struct load_funcs *load_funcs)
{
if ( NULL == findtable(image, image_size) )
{
@@ -297,3 +297,13 @@ loadbinimage(
return 0;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+13 -3
View File
@@ -30,8 +30,8 @@ loadelfsymtab(
struct domain_setup_info *dsi);
int probe_elf(char *image,
unsigned long image_size,
struct load_funcs *load_funcs)
unsigned long image_size,
struct load_funcs *load_funcs)
{
Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
@@ -116,7 +116,7 @@ static int parseelfimage(char *image,
return -EINVAL;
}
if ( (strstr(guestinfo, "PAE=yes") != NULL) )
dsi->pae_kernel = 1;
dsi->pae_kernel = 1;
break;
}
@@ -313,3 +313,13 @@ loadelfsymtab(
return 0;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+11 -1
View File
@@ -133,5 +133,15 @@ int xc_msr_write(int xc_handle, int cpu_mask, int msr, unsigned int low,
long xc_init_store(int xc_handle, int remote_port)
{
return ioctl(xc_handle, IOCTL_PRIVCMD_INITDOMAIN_STORE, remote_port);
return ioctl(xc_handle, IOCTL_PRIVCMD_INITDOMAIN_STORE, remote_port);
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+51 -41
View File
@@ -15,7 +15,7 @@ void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
void *addr;
addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0);
if ( addr == MAP_FAILED )
return NULL;
return NULL;
ioctlx.num=num;
ioctlx.dom=dom;
@@ -24,10 +24,10 @@ void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx ) < 0 )
{
int saved_errno = errno;
perror("XXXXXXXX");
(void)munmap(addr, num*PAGE_SIZE);
perror("XXXXXXXX");
(void)munmap(addr, num*PAGE_SIZE);
errno = saved_errno;
return NULL;
return NULL;
}
return addr;
@@ -36,15 +36,15 @@ void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
/*******************/
void *xc_map_foreign_range(int xc_handle, u32 dom,
int size, int prot,
unsigned long mfn )
int size, int prot,
unsigned long mfn )
{
privcmd_mmap_t ioctlx;
privcmd_mmap_entry_t entry;
void *addr;
addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
if ( addr == MAP_FAILED )
return NULL;
return NULL;
ioctlx.num=1;
ioctlx.dom=dom;
@@ -55,9 +55,9 @@ void *xc_map_foreign_range(int xc_handle, u32 dom,
if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx ) < 0 )
{
int saved_errno = errno;
(void)munmap(addr, size);
(void)munmap(addr, size);
errno = saved_errno;
return NULL;
return NULL;
}
return addr;
}
@@ -66,7 +66,7 @@ void *xc_map_foreign_range(int xc_handle, u32 dom,
/* NB: arr must be mlock'ed */
int xc_get_pfn_type_batch(int xc_handle,
u32 dom, int num, unsigned long *arr)
u32 dom, int num, unsigned long *arr)
{
dom0_op_t op;
op.cmd = DOM0_GETPAGEFRAMEINFO2;
@@ -116,8 +116,8 @@ int xc_mmuext_op(
if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
{
fprintf(stderr, "Dom_mmuext operation failed (rc=%ld errno=%d)-- need to"
" rebuild the user-space tool set?\n",ret,errno);
fprintf(stderr, "Dom_mmuext operation failed (rc=%ld errno=%d)-- need to"
" rebuild the user-space tool set?\n",ret,errno);
}
safe_munlock(op, nr_ops*sizeof(*op));
@@ -172,7 +172,7 @@ xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom)
}
int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu,
unsigned long long ptr, unsigned long long val)
unsigned long long ptr, unsigned long long val)
{
mmu->updates[mmu->idx].ptr = ptr;
mmu->updates[mmu->idx].val = val;
@@ -229,7 +229,7 @@ int xc_memory_op(int xc_handle,
if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
{
fprintf(stderr, "hypercall failed (rc=%ld errno=%d)-- need to"
fprintf(stderr, "hypercall failed (rc=%ld errno=%d)-- need to"
" rebuild the user-space tool set?\n",ret,errno);
}
@@ -275,16 +275,16 @@ unsigned long xc_get_m2p_start_mfn ( int xc_handle )
if ( ioctl( xc_handle, IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN, &mfn ) < 0 )
{
perror("xc_get_m2p_start_mfn:");
return 0;
perror("xc_get_m2p_start_mfn:");
return 0;
}
return mfn;
}
int xc_get_pfn_list(int xc_handle,
u32 domid,
unsigned long *pfn_buf,
unsigned long max_pfns)
u32 domid,
unsigned long *pfn_buf,
unsigned long max_pfns)
{
dom0_op_t op;
int ret;
@@ -306,16 +306,16 @@ int xc_get_pfn_list(int xc_handle,
#if 0
#ifdef DEBUG
DPRINTF(("Ret for xc_get_pfn_list is %d\n", ret));
if (ret >= 0) {
int i, j;
for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) {
fprintf(stderr, "0x%x: ", i);
for (j = 0; j < 16; j++)
fprintf(stderr, "0x%lx ", pfn_buf[i + j]);
fprintf(stderr, "\n");
}
}
DPRINTF(("Ret for xc_get_pfn_list is %d\n", ret));
if (ret >= 0) {
int i, j;
for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) {
fprintf(stderr, "0x%x: ", i);
for (j = 0; j < 16; j++)
fprintf(stderr, "0x%lx ", pfn_buf[i + j]);
fprintf(stderr, "\n");
}
}
#endif
#endif
@@ -324,10 +324,10 @@ int xc_get_pfn_list(int xc_handle,
#ifdef __ia64__
int xc_ia64_get_pfn_list(int xc_handle,
u32 domid,
unsigned long *pfn_buf,
unsigned int start_page,
unsigned int nr_pages)
u32 domid,
unsigned long *pfn_buf,
unsigned int start_page,
unsigned int nr_pages)
{
dom0_op_t op;
int ret;
@@ -372,9 +372,9 @@ long xc_get_tot_pages(int xc_handle, u32 domid)
}
int xc_copy_to_domain_page(int xc_handle,
u32 domid,
unsigned long dst_pfn,
void *src_page)
u32 domid,
unsigned long dst_pfn,
void *src_page)
{
void *vaddr = xc_map_foreign_range(
xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
@@ -465,18 +465,28 @@ unsigned long xc_make_page_below_4G(
unsigned long new_mfn;
if ( xc_domain_memory_decrease_reservation(
xc_handle, domid, 1, 0, &mfn) != 0 )
xc_handle, domid, 1, 0, &mfn) != 0 )
{
fprintf(stderr,"xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
return 0;
fprintf(stderr,"xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
return 0;
}
if ( xc_domain_memory_increase_reservation(
xc_handle, domid, 1, 0, 32, &new_mfn) != 0 )
{
fprintf(stderr,"xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
return 0;
fprintf(stderr,"xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
return 0;
}
return new_mfn;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+201 -195
View File
@@ -5,12 +5,9 @@
#define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */
#define X86_CR0_PG 0x80000000 /* Paging (RW) */
#define BSD_PAGE_MASK (PAGE_SIZE-1)
#define PG_FRAME (~((unsigned long)BSD_PAGE_MASK)
#define BSD_PAGE_MASK (PAGE_SIZE-1)
#define PDRSHIFT 22
#define PSL_T 0x00000100 /* trace enable bit */
#define PSL_T 0x00000100 /* trace enable bit */
#define VCPU 0 /* XXX */
/*
@@ -69,67 +66,66 @@ struct gdb_regs {
int xss; /* 64 */
};
#define FETCH_REGS(cpu) \
if (!regs_valid[cpu]) \
{ \
int retval = xc_domain_get_vcpu_context(xc_handle, domid, cpu, &ctxt[cpu]); \
if (retval) \
goto error_out; \
cr3[cpu] = ctxt[cpu].ctrlreg[3]; /* physical address */ \
regs_valid[cpu] = 1; \
} \
#define FETCH_REGS(cpu) \
if (!regs_valid[cpu]) \
{ \
int retval = xc_domain_get_vcpu_context( \
xc_handle, domid, cpu, &ctxt[cpu]); \
if (retval) \
goto error_out; \
cr3[cpu] = ctxt[cpu].ctrlreg[3]; /* physical address */ \
regs_valid[cpu] = 1; \
}
#define printval(x) printf("%s = %lx\n", #x, (long)x);
#define SET_PT_REGS(pt, xc) \
{ \
pt.ebx = xc.ebx; \
pt.ecx = xc.ecx; \
pt.edx = xc.edx; \
pt.esi = xc.esi; \
pt.edi = xc.edi; \
pt.ebp = xc.ebp; \
pt.eax = xc.eax; \
pt.eip = xc.eip; \
pt.xcs = xc.cs; \
pt.eflags = xc.eflags; \
pt.esp = xc.esp; \
pt.xss = xc.ss; \
pt.xes = xc.es; \
pt.xds = xc.ds; \
pt.xfs = xc.fs; \
pt.xgs = xc.gs; \
#define SET_PT_REGS(pt, xc) \
{ \
pt.ebx = xc.ebx; \
pt.ecx = xc.ecx; \
pt.edx = xc.edx; \
pt.esi = xc.esi; \
pt.edi = xc.edi; \
pt.ebp = xc.ebp; \
pt.eax = xc.eax; \
pt.eip = xc.eip; \
pt.xcs = xc.cs; \
pt.eflags = xc.eflags; \
pt.esp = xc.esp; \
pt.xss = xc.ss; \
pt.xes = xc.es; \
pt.xds = xc.ds; \
pt.xfs = xc.fs; \
pt.xgs = xc.gs; \
}
#define SET_XC_REGS(pt, xc) \
{ \
xc.ebx = pt->ebx; \
xc.ecx = pt->ecx; \
xc.edx = pt->edx; \
xc.esi = pt->esi; \
xc.edi = pt->edi; \
xc.ebp = pt->ebp; \
xc.eax = pt->eax; \
xc.eip = pt->eip; \
xc.cs = pt->xcs; \
xc.eflags = pt->eflags; \
xc.esp = pt->esp; \
xc.ss = pt->xss; \
xc.es = pt->xes; \
xc.ds = pt->xds; \
xc.fs = pt->xfs; \
xc.gs = pt->xgs; \
#define SET_XC_REGS(pt, xc) \
{ \
xc.ebx = pt->ebx; \
xc.ecx = pt->ecx; \
xc.edx = pt->edx; \
xc.esi = pt->esi; \
xc.edi = pt->edi; \
xc.ebp = pt->ebp; \
xc.eax = pt->eax; \
xc.eip = pt->eip; \
xc.cs = pt->xcs; \
xc.eflags = pt->eflags; \
xc.esp = pt->esp; \
xc.ss = pt->xss; \
xc.es = pt->xes; \
xc.ds = pt->xds; \
xc.fs = pt->xfs; \
xc.gs = pt->xgs; \
}
#define vtopdi(va) ((va) >> PDRSHIFT)
#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
/* XXX application state */
static int xc_handle;
static long nr_pages = 0;
unsigned long *page_array = NULL;
static long nr_pages = 0;
unsigned long *page_array = NULL;
static int regs_valid[MAX_VIRT_CPUS];
static unsigned long cr3[MAX_VIRT_CPUS];
static vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
@@ -160,64 +156,64 @@ map_domain_va(unsigned long domid, int cpu, void * guest_va, int perm)
static int prev_perm[MAX_VIRT_CPUS];
if (nr_pages != npgs) {
if (nr_pages > 0)
free(page_array);
nr_pages = npgs;
if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
printf("Could not allocate memory\n");
goto error_out;
}
if (nr_pages > 0)
free(page_array);
nr_pages = npgs;
if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
printf("Could not allocate memory\n");
goto error_out;
}
if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
printf("Could not get the page frame list\n");
goto error_out;
}
if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
printf("Could not get the page frame list\n");
goto error_out;
}
}
FETCH_REGS(cpu);
if (cr3[cpu] != cr3_phys[cpu])
{
cr3_phys[cpu] = cr3[cpu];
if (cr3_virt[cpu])
munmap(cr3_virt[cpu], PAGE_SIZE);
if ((cr3_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
PROT_READ,
cr3_phys[cpu] >> PAGE_SHIFT)) == NULL)
goto error_out;
cr3_phys[cpu] = cr3[cpu];
if (cr3_virt[cpu])
munmap(cr3_virt[cpu], PAGE_SIZE);
if ((cr3_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
PROT_READ,
cr3_phys[cpu] >> PAGE_SHIFT)) == NULL)
goto error_out;
}
if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */
goto error_out;
goto error_out;
if ((ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu]))
pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
if (pde != pde_phys[cpu])
{
pde_phys[cpu] = pde;
if (pde_virt[cpu])
munmap(pde_virt[cpu], PAGE_SIZE);
if ((pde_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
PROT_READ,
pde_phys[cpu] >> PAGE_SHIFT)) == NULL)
goto error_out;
pde_phys[cpu] = pde;
if (pde_virt[cpu])
munmap(pde_virt[cpu], PAGE_SIZE);
if ((pde_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
PROT_READ,
pde_phys[cpu] >> PAGE_SHIFT)) == NULL)
goto error_out;
}
if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */
goto error_out;
goto error_out;
if (ctxt[cpu].flags & VGCF_VMX_GUEST && paging_enabled(&ctxt[cpu]))
page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
if (page != page_phys[cpu] || perm != prev_perm[cpu])
{
page_phys[cpu] = page;
if (page_virt[cpu])
munmap(page_virt[cpu], PAGE_SIZE);
if ((page_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
perm,
page_phys[cpu] >> PAGE_SHIFT)) == NULL) {
printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va));
page_phys[cpu] = 0;
goto error_out;
}
prev_perm[cpu] = perm;
}
page_phys[cpu] = page;
if (page_virt[cpu])
munmap(page_virt[cpu], PAGE_SIZE);
if ((page_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
perm,
page_phys[cpu] >> PAGE_SHIFT)) == NULL) {
printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va));
page_phys[cpu] = 0;
goto error_out;
}
prev_perm[cpu] = perm;
}
return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
error_out:
@@ -234,29 +230,29 @@ xc_waitdomain(int domain, int *status, int options)
ts.tv_nsec = 10*1000*1000;
if (!xc_handle)
if ((xc_handle = xc_interface_open()) < 0)
{
printf("xc_interface_open failed\n");
return -1;
}
if ((xc_handle = xc_interface_open()) < 0)
{
printf("xc_interface_open failed\n");
return -1;
}
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = domain;
retry:
retval = do_dom0_op(xc_handle, &op);
if (retval || op.u.getdomaininfo.domain != domain) {
printf("getdomaininfo failed\n");
goto done;
printf("getdomaininfo failed\n");
goto done;
}
*status = op.u.getdomaininfo.flags;
if (options & WNOHANG)
goto done;
goto done;
if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)) {
nanosleep(&ts,NULL);
goto retry;
if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)) {
nanosleep(&ts,NULL);
goto retry;
}
done:
return retval;
@@ -278,107 +274,107 @@ xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata)
op.interface_version = DOM0_INTERFACE_VERSION;
if (!xc_handle)
if ((xc_handle = xc_interface_open()) < 0)
return -1;
if ((xc_handle = xc_interface_open()) < 0)
return -1;
#if 0
printf("%20s %d, %p, %p \n", ptrace_names[request], domid, addr, data);
#endif
switch (request) {
switch (request) {
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
if ((guest_va = (unsigned long *)map_domain_va(domid, cpu, addr, PROT_READ)) == NULL) {
status = EFAULT;
goto error_out;
}
if ((guest_va = (unsigned long *)map_domain_va(domid, cpu, addr, PROT_READ)) == NULL) {
status = EFAULT;
goto error_out;
}
retval = *guest_va;
break;
retval = *guest_va;
break;
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
if ((guest_va = (unsigned long *)map_domain_va(domid, cpu, addr, PROT_READ|PROT_WRITE)) == NULL) {
status = EFAULT;
goto error_out;
}
if ((guest_va = (unsigned long *)map_domain_va(domid, cpu, addr, PROT_READ|PROT_WRITE)) == NULL) {
status = EFAULT;
goto error_out;
}
*guest_va = (unsigned long)data;
break;
*guest_va = (unsigned long)data;
break;
case PTRACE_GETREGS:
case PTRACE_GETFPREGS:
case PTRACE_GETFPXREGS:
FETCH_REGS(cpu);
FETCH_REGS(cpu);
if (request == PTRACE_GETREGS) {
SET_PT_REGS(pt, ctxt[cpu].user_regs);
memcpy(data, &pt, sizeof(struct gdb_regs));
} else if (request == PTRACE_GETFPREGS)
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
else /*if (request == PTRACE_GETFPXREGS)*/
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
break;
if (request == PTRACE_GETREGS) {
SET_PT_REGS(pt, ctxt[cpu].user_regs);
memcpy(data, &pt, sizeof(struct gdb_regs));
} else if (request == PTRACE_GETFPREGS)
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
else /*if (request == PTRACE_GETFPXREGS)*/
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
break;
case PTRACE_SETREGS:
op.cmd = DOM0_SETDOMAININFO;
SET_XC_REGS(((struct gdb_regs *)data), ctxt[VCPU].user_regs);
op.u.setdomaininfo.domain = domid;
/* XXX need to understand multiple vcpus */
op.u.setdomaininfo.vcpu = cpu;
op.u.setdomaininfo.ctxt = &ctxt[cpu];
retval = do_dom0_op(xc_handle, &op);
if (retval)
goto error_out;
op.cmd = DOM0_SETDOMAININFO;
SET_XC_REGS(((struct gdb_regs *)data), ctxt[VCPU].user_regs);
op.u.setdomaininfo.domain = domid;
/* XXX need to understand multiple vcpus */
op.u.setdomaininfo.vcpu = cpu;
op.u.setdomaininfo.ctxt = &ctxt[cpu];
retval = do_dom0_op(xc_handle, &op);
if (retval)
goto error_out;
break;
break;
case PTRACE_ATTACH:
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = domid;
retval = do_dom0_op(xc_handle, &op);
if (retval || op.u.getdomaininfo.domain != domid) {
perror("dom0 op failed");
goto error_out;
}
if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) {
printf("domain currently paused\n");
goto error_out;
}
printf("domain not currently paused\n");
op.cmd = DOM0_PAUSEDOMAIN;
op.u.pausedomain.domain = domid;
retval = do_dom0_op(xc_handle, &op);
break;
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = domid;
retval = do_dom0_op(xc_handle, &op);
if (retval || op.u.getdomaininfo.domain != domid) {
perror("dom0 op failed");
goto error_out;
}
if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) {
printf("domain currently paused\n");
goto error_out;
}
printf("domain not currently paused\n");
op.cmd = DOM0_PAUSEDOMAIN;
op.u.pausedomain.domain = domid;
retval = do_dom0_op(xc_handle, &op);
break;
case PTRACE_SINGLESTEP:
ctxt[VCPU].user_regs.eflags |= PSL_T;
op.cmd = DOM0_SETDOMAININFO;
op.u.setdomaininfo.domain = domid;
op.u.setdomaininfo.vcpu = 0;
op.u.setdomaininfo.ctxt = &ctxt[cpu];
retval = do_dom0_op(xc_handle, &op);
if (retval) {
perror("dom0 op failed");
goto error_out;
}
/* FALLTHROUGH */
ctxt[VCPU].user_regs.eflags |= PSL_T;
op.cmd = DOM0_SETDOMAININFO;
op.u.setdomaininfo.domain = domid;
op.u.setdomaininfo.vcpu = 0;
op.u.setdomaininfo.ctxt = &ctxt[cpu];
retval = do_dom0_op(xc_handle, &op);
if (retval) {
perror("dom0 op failed");
goto error_out;
}
/* FALLTHROUGH */
case PTRACE_CONT:
case PTRACE_DETACH:
if (request != PTRACE_SINGLESTEP) {
FETCH_REGS(cpu);
/* Clear trace flag */
if (ctxt[cpu].user_regs.eflags & PSL_T) {
ctxt[cpu].user_regs.eflags &= ~PSL_T;
op.cmd = DOM0_SETDOMAININFO;
op.u.setdomaininfo.domain = domid;
op.u.setdomaininfo.vcpu = cpu;
op.u.setdomaininfo.ctxt = &ctxt[cpu];
retval = do_dom0_op(xc_handle, &op);
if (retval) {
perror("dom0 op failed");
goto error_out;
}
}
}
regs_valid[cpu] = 0;
op.cmd = DOM0_UNPAUSEDOMAIN;
op.u.unpausedomain.domain = domid > 0 ? domid : -domid;
retval = do_dom0_op(xc_handle, &op);
break;
if (request != PTRACE_SINGLESTEP) {
FETCH_REGS(cpu);
/* Clear trace flag */
if (ctxt[cpu].user_regs.eflags & PSL_T) {
ctxt[cpu].user_regs.eflags &= ~PSL_T;
op.cmd = DOM0_SETDOMAININFO;
op.u.setdomaininfo.domain = domid;
op.u.setdomaininfo.vcpu = cpu;
op.u.setdomaininfo.ctxt = &ctxt[cpu];
retval = do_dom0_op(xc_handle, &op);
if (retval) {
perror("dom0 op failed");
goto error_out;
}
}
}
regs_valid[cpu] = 0;
op.cmd = DOM0_UNPAUSEDOMAIN;
op.u.unpausedomain.domain = domid > 0 ? domid : -domid;
retval = do_dom0_op(xc_handle, &op);
break;
case PTRACE_SETFPREGS:
case PTRACE_SETFPXREGS:
case PTRACE_PEEKUSER:
@@ -386,20 +382,30 @@ xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata)
case PTRACE_SYSCALL:
case PTRACE_KILL:
#ifdef DEBUG
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
#endif
/* XXX not yet supported */
status = ENOSYS;
break;
/* XXX not yet supported */
status = ENOSYS;
break;
case PTRACE_TRACEME:
printf("PTRACE_TRACEME is an invalid request under Xen\n");
status = EINVAL;
printf("PTRACE_TRACEME is an invalid request under Xen\n");
status = EINVAL;
}
if (status) {
errno = status;
retval = -1;
errno = status;
retval = -1;
}
error_out:
return retval;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+132 -128
View File
@@ -3,12 +3,8 @@
#include "xc_private.h"
#include <time.h>
#define BSD_PAGE_MASK (PAGE_SIZE-1)
#define PG_FRAME (~((unsigned long)BSD_PAGE_MASK)
#define BSD_PAGE_MASK (PAGE_SIZE-1)
#define PDRSHIFT 22
#define PSL_T 0x00000100 /* trace enable bit */
#define VCPU 0 /* XXX */
/*
@@ -16,7 +12,6 @@
* ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
*/
struct gdb_regs {
long ebx; /* 0 */
long ecx; /* 4 */
@@ -38,44 +33,44 @@ struct gdb_regs {
};
#define printval(x) printf("%s = %lx\n", #x, (long)x);
#define SET_PT_REGS(pt, xc) \
{ \
pt.ebx = xc.ebx; \
pt.ecx = xc.ecx; \
pt.edx = xc.edx; \
pt.esi = xc.esi; \
pt.edi = xc.edi; \
pt.ebp = xc.ebp; \
pt.eax = xc.eax; \
pt.eip = xc.eip; \
pt.xcs = xc.cs; \
pt.eflags = xc.eflags; \
pt.esp = xc.esp; \
pt.xss = xc.ss; \
pt.xes = xc.es; \
pt.xds = xc.ds; \
pt.xfs = xc.fs; \
pt.xgs = xc.gs; \
#define SET_PT_REGS(pt, xc) \
{ \
pt.ebx = xc.ebx; \
pt.ecx = xc.ecx; \
pt.edx = xc.edx; \
pt.esi = xc.esi; \
pt.edi = xc.edi; \
pt.ebp = xc.ebp; \
pt.eax = xc.eax; \
pt.eip = xc.eip; \
pt.xcs = xc.cs; \
pt.eflags = xc.eflags; \
pt.esp = xc.esp; \
pt.xss = xc.ss; \
pt.xes = xc.es; \
pt.xds = xc.ds; \
pt.xfs = xc.fs; \
pt.xgs = xc.gs; \
}
#define SET_XC_REGS(pt, xc) \
{ \
xc.ebx = pt->ebx; \
xc.ecx = pt->ecx; \
xc.edx = pt->edx; \
xc.esi = pt->esi; \
xc.edi = pt->edi; \
xc.ebp = pt->ebp; \
xc.eax = pt->eax; \
xc.eip = pt->eip; \
xc.cs = pt->xcs; \
xc.eflags = pt->eflags; \
xc.esp = pt->esp; \
xc.ss = pt->xss; \
xc.es = pt->xes; \
xc.ds = pt->xds; \
xc.fs = pt->xfs; \
xc.gs = pt->xgs; \
#define SET_XC_REGS(pt, xc) \
{ \
xc.ebx = pt->ebx; \
xc.ecx = pt->ecx; \
xc.edx = pt->edx; \
xc.esi = pt->esi; \
xc.edi = pt->edi; \
xc.ebp = pt->ebp; \
xc.eax = pt->eax; \
xc.eip = pt->eip; \
xc.cs = pt->xcs; \
xc.eflags = pt->eflags; \
xc.esp = pt->esp; \
xc.ss = pt->xss; \
xc.es = pt->xes; \
xc.ds = pt->xds; \
xc.fs = pt->xfs; \
xc.gs = pt->xgs; \
}
@@ -84,10 +79,9 @@ struct gdb_regs {
/* XXX application state */
static long nr_pages = 0;
static unsigned long *p2m_array = NULL;
static unsigned long *m2p_array = NULL;
static 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];
static vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
@@ -117,54 +111,54 @@ map_domain_va(unsigned long domfd, int cpu, void * guest_va)
if (cr3[cpu] != cr3_phys[cpu])
{
cr3_phys[cpu] = cr3[cpu];
if (cr3_virt[cpu])
munmap(cr3_virt[cpu], PAGE_SIZE);
v = mmap(
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(cr3_phys[cpu]));
if (v == MAP_FAILED)
{
perror("mmap failed");
goto error_out;
}
{
perror("mmap failed");
goto error_out;
}
cr3_virt[cpu] = v;
}
if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */
goto error_out;
goto error_out;
if (ctxt[cpu].flags & VGCF_VMX_GUEST)
pde = p2m_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
pde = p2m_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
if (pde != pde_phys[cpu])
{
pde_phys[cpu] = pde;
if (pde_virt[cpu])
munmap(pde_virt[cpu], PAGE_SIZE);
v = mmap(
pde_phys[cpu] = pde;
if (pde_virt[cpu])
munmap(pde_virt[cpu], PAGE_SIZE);
v = mmap(
NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd,
map_mtop_offset(pde_phys[cpu]));
if (v == MAP_FAILED)
goto error_out;
goto error_out;
pde_virt[cpu] = v;
}
if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */
goto error_out;
goto error_out;
if (ctxt[cpu].flags & VGCF_VMX_GUEST)
page = p2m_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
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(
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) {
printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va));
page_phys[cpu] = 0;
goto error_out;
}
printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va));
page_phys[cpu] = 0;
goto error_out;
}
page_virt[cpu] = v;
}
}
return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
error_out:
@@ -181,37 +175,37 @@ xc_waitdomain_core(int domfd, int *status, int options)
if (nr_pages == 0) {
if (read(domfd, &header, sizeof(header)) != sizeof(header))
return -1;
if (read(domfd, &header, sizeof(header)) != sizeof(header))
return -1;
nr_pages = header.xch_nr_pages;
nr_vcpus = header.xch_nr_vcpus;
pages_offset = header.xch_pages_offset;
nr_pages = header.xch_nr_pages;
nr_vcpus = header.xch_nr_vcpus;
pages_offset = header.xch_pages_offset;
if (read(domfd, ctxt, sizeof(vcpu_guest_context_t)*nr_vcpus) !=
sizeof(vcpu_guest_context_t)*nr_vcpus)
return -1;
if (read(domfd, ctxt, sizeof(vcpu_guest_context_t)*nr_vcpus) !=
sizeof(vcpu_guest_context_t)*nr_vcpus)
return -1;
for (i = 0; i < nr_vcpus; i++) {
cr3[i] = ctxt[i].ctrlreg[3];
}
if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
printf("Could not allocate p2m_array\n");
goto error_out;
}
if (read(domfd, p2m_array, sizeof(unsigned long)*nr_pages) !=
sizeof(unsigned long)*nr_pages)
return -1;
for (i = 0; i < nr_vcpus; i++) {
cr3[i] = ctxt[i].ctrlreg[3];
}
if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
printf("Could not allocate p2m_array\n");
goto error_out;
}
if (read(domfd, p2m_array, sizeof(unsigned long)*nr_pages) !=
sizeof(unsigned long)*nr_pages)
return -1;
if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL) {
printf("Could not allocate m2p array\n");
goto error_out;
}
bzero(m2p_array, sizeof(unsigned long)* 1 << 20);
if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL) {
printf("Could not allocate m2p array\n");
goto error_out;
}
bzero(m2p_array, sizeof(unsigned long)* 1 << 20);
for (i = 0; i < nr_pages; i++) {
m2p_array[p2m_array[i]] = i;
}
for (i = 0; i < nr_pages; i++) {
m2p_array[p2m_array[i]] = i;
}
}
retval = 0;
@@ -234,38 +228,38 @@ xc_ptrace_core(enum __ptrace_request request, u32 domfd, long eaddr, long edata)
#if 0
printf("%20s %d, %p, %p \n", ptrace_names[request], domid, addr, data);
#endif
switch (request) {
switch (request) {
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
if ((guest_va = (unsigned long *)map_domain_va(domfd, cpu, addr)) == NULL) {
status = EFAULT;
goto error_out;
}
if ((guest_va = (unsigned long *)map_domain_va(domfd, cpu, addr)) == NULL) {
status = EFAULT;
goto error_out;
}
retval = *guest_va;
break;
retval = *guest_va;
break;
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
if ((guest_va = (unsigned long *)map_domain_va(domfd, cpu, addr)) == NULL) {
status = EFAULT;
goto error_out;
}
*guest_va = (unsigned long)data;
break;
if ((guest_va = (unsigned long *)map_domain_va(domfd, cpu, addr)) == NULL) {
status = EFAULT;
goto error_out;
}
*guest_va = (unsigned long)data;
break;
case PTRACE_GETREGS:
case PTRACE_GETFPREGS:
case PTRACE_GETFPXREGS:
if (request == PTRACE_GETREGS) {
SET_PT_REGS(pt, ctxt[cpu].user_regs);
memcpy(data, &pt, sizeof(struct gdb_regs));
} else if (request == PTRACE_GETFPREGS)
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
else /*if (request == PTRACE_GETFPXREGS)*/
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
break;
if (request == PTRACE_GETREGS) {
SET_PT_REGS(pt, ctxt[cpu].user_regs);
memcpy(data, &pt, sizeof(struct gdb_regs));
} else if (request == PTRACE_GETFPREGS)
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
else /*if (request == PTRACE_GETFPXREGS)*/
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
break;
case PTRACE_ATTACH:
retval = 0;
break;
retval = 0;
break;
case PTRACE_SETREGS:
case PTRACE_SINGLESTEP:
case PTRACE_CONT:
@@ -277,19 +271,29 @@ xc_ptrace_core(enum __ptrace_request request, u32 domfd, long eaddr, long edata)
case PTRACE_SYSCALL:
case PTRACE_KILL:
#ifdef DEBUG
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
#endif
status = ENOSYS;
break;
status = ENOSYS;
break;
case PTRACE_TRACEME:
printf("PTRACE_TRACEME is an invalid request under Xen\n");
status = EINVAL;
printf("PTRACE_TRACEME is an invalid request under Xen\n");
status = EINVAL;
}
if (status) {
errno = status;
retval = -1;
errno = status;
retval = -1;
}
error_out:
return retval;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
+167 -150
View File
@@ -109,9 +109,9 @@ static void build_e820map(struct mem_map *mem_mapp, unsigned long mem_size)
#ifdef __i386__
static int zap_mmio_range(int xc_handle, u32 dom,
l2_pgentry_32_t *vl2tab,
unsigned long mmio_range_start,
unsigned long mmio_range_size)
l2_pgentry_32_t *vl2tab,
unsigned long mmio_range_start,
unsigned long mmio_range_size)
{
unsigned long mmio_addr;
unsigned long mmio_range_end = mmio_range_start + mmio_range_size;
@@ -123,12 +123,14 @@ static int zap_mmio_range(int xc_handle, u32 dom,
vl2e = vl2tab[l2_table_offset(mmio_addr)];
if (vl2e == 0)
continue;
vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE, vl2e >> PAGE_SHIFT);
if (vl1tab == 0) {
PERROR("Failed zap MMIO range");
return -1;
}
vl1tab = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE, vl2e >> PAGE_SHIFT);
if ( vl1tab == 0 )
{
PERROR("Failed zap MMIO range");
return -1;
}
vl1tab[l1_table_offset(mmio_addr)] = 0;
munmap(vl1tab, PAGE_SIZE);
}
@@ -136,114 +138,118 @@ static int zap_mmio_range(int xc_handle, u32 dom,
}
static int zap_mmio_ranges(int xc_handle, u32 dom,
unsigned long l2tab,
struct mem_map *mem_mapp)
unsigned long l2tab,
struct mem_map *mem_mapp)
{
int i;
l2_pgentry_32_t *vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE,
l2tab >> PAGE_SHIFT);
if (vl2tab == 0)
return -1;
for (i = 0; i < mem_mapp->nr_map; i++) {
if ((mem_mapp->map[i].type == E820_IO)
&& (mem_mapp->map[i].caching_attr == MEMMAP_UC))
if (zap_mmio_range(xc_handle, dom, vl2tab,
mem_mapp->map[i].addr, mem_mapp->map[i].size) == -1)
return -1;
PROT_READ|PROT_WRITE,
l2tab >> PAGE_SHIFT);
if ( vl2tab == 0 )
return -1;
for ( i = 0; i < mem_mapp->nr_map; i++ )
{
if ( (mem_mapp->map[i].type == E820_IO) &&
(mem_mapp->map[i].caching_attr == MEMMAP_UC) &&
(zap_mmio_range(xc_handle, dom, vl2tab,
mem_mapp->map[i].addr,
mem_mapp->map[i].size) == -1) )
return -1;
}
munmap(vl2tab, PAGE_SIZE);
return 0;
}
#else
static int zap_mmio_range(int xc_handle, u32 dom,
l3_pgentry_t *vl3tab,
unsigned long mmio_range_start,
unsigned long mmio_range_size)
l3_pgentry_t *vl3tab,
unsigned long mmio_range_start,
unsigned long mmio_range_size)
{
unsigned long mmio_addr;
unsigned long mmio_range_end = mmio_range_start + mmio_range_size;
unsigned long vl2e = 0;
unsigned long vl3e;
l1_pgentry_t *vl1tab;
l2_pgentry_t *vl2tab;
unsigned long mmio_addr;
unsigned long mmio_range_end = mmio_range_start + mmio_range_size;
unsigned long vl2e = 0;
unsigned long vl3e;
l1_pgentry_t *vl1tab;
l2_pgentry_t *vl2tab;
mmio_addr = mmio_range_start & PAGE_MASK;
for ( ; mmio_addr < mmio_range_end; mmio_addr += PAGE_SIZE )
{
vl3e = vl3tab[l3_table_offset(mmio_addr)];
if ( vl3e == 0 )
continue;
mmio_addr = mmio_range_start & PAGE_MASK;
for ( ; mmio_addr < mmio_range_end; mmio_addr += PAGE_SIZE )
{
vl3e = vl3tab[l3_table_offset(mmio_addr)];
if ( vl3e == 0 )
continue;
vl2tab = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, vl3e>>PAGE_SHIFT);
if ( vl2tab == NULL )
{
PERROR("Failed zap MMIO range");
return -1;
}
vl2tab = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, vl3e>>PAGE_SHIFT);
if ( vl2tab == NULL )
{
PERROR("Failed zap MMIO range");
return -1;
}
vl2e = vl2tab[l2_table_offset(mmio_addr)];
if ( vl2e == 0 )
{
munmap(vl2tab, PAGE_SIZE);
continue;
}
vl2e = vl2tab[l2_table_offset(mmio_addr)];
if ( vl2e == 0 )
{
munmap(vl2tab, PAGE_SIZE);
continue;
}
vl1tab = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, vl2e>>PAGE_SHIFT);
if ( vl1tab == NULL )
{
PERROR("Failed zap MMIO range");
munmap(vl2tab, PAGE_SIZE);
return -1;
}
vl1tab = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, vl2e>>PAGE_SHIFT);
if ( vl1tab == NULL )
{
PERROR("Failed zap MMIO range");
munmap(vl2tab, PAGE_SIZE);
return -1;
}
vl1tab[l1_table_offset(mmio_addr)] = 0;
munmap(vl2tab, PAGE_SIZE);
munmap(vl1tab, PAGE_SIZE);
}
return 0;
vl1tab[l1_table_offset(mmio_addr)] = 0;
munmap(vl2tab, PAGE_SIZE);
munmap(vl1tab, PAGE_SIZE);
}
return 0;
}
static int zap_mmio_ranges(int xc_handle, u32 dom,
unsigned long l3tab,
struct mem_map *mem_mapp)
{
int i;
l3_pgentry_t *vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE,
l3tab >> PAGE_SHIFT);
if (vl3tab == 0)
return -1;
for (i = 0; i < mem_mapp->nr_map; i++) {
if ((mem_mapp->map[i].type == E820_IO)
&& (mem_mapp->map[i].caching_attr == MEMMAP_UC))
if (zap_mmio_range(xc_handle, dom, vl3tab,
mem_mapp->map[i].addr, mem_mapp->map[i].size) == -1)
return -1;
}
munmap(vl3tab, PAGE_SIZE);
return 0;
int i;
l3_pgentry_t *vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE,
l3tab >> PAGE_SHIFT);
if (vl3tab == 0)
return -1;
for (i = 0; i < mem_mapp->nr_map; i++) {
if ((mem_mapp->map[i].type == E820_IO)
&& (mem_mapp->map[i].caching_attr == MEMMAP_UC))
if (zap_mmio_range(xc_handle, dom, vl3tab,
mem_mapp->map[i].addr, mem_mapp->map[i].size) == -1)
return -1;
}
munmap(vl3tab, PAGE_SIZE);
return 0;
}
#endif
static int setup_guest(int xc_handle,
u32 dom, int memsize,
char *image, unsigned long image_size,
gzFile initrd_gfd, unsigned long initrd_len,
unsigned long nr_pages,
vcpu_guest_context_t *ctxt,
const char *cmdline,
unsigned long shared_info_frame,
unsigned int control_evtchn,
unsigned long flags,
unsigned int vcpus,
unsigned int store_evtchn,
unsigned long *store_mfn,
struct mem_map *mem_mapp
)
u32 dom, int memsize,
char *image, unsigned long image_size,
gzFile initrd_gfd, unsigned long initrd_len,
unsigned long nr_pages,
vcpu_guest_context_t *ctxt,
const char *cmdline,
unsigned long shared_info_frame,
unsigned int control_evtchn,
unsigned long flags,
unsigned int vcpus,
unsigned int store_evtchn,
unsigned long *store_mfn,
struct mem_map *mem_mapp
)
{
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
@@ -303,7 +309,8 @@ static int setup_guest(int xc_handle,
/* memsize is in megabytes */
v_end = memsize << 20;
vinitrd_end = v_end - PAGE_SIZE; /* leaving the top 4k untouched for IO requests page use */
/* leaving the top 4k untouched for IO requests page use */
vinitrd_end = v_end - PAGE_SIZE;
vinitrd_start = vinitrd_end - initrd_len;
vinitrd_start = vinitrd_start & (~(PAGE_SIZE - 1));
@@ -369,7 +376,7 @@ static int setup_guest(int xc_handle,
goto error_out;
}
xc_copy_to_domain_page(xc_handle, dom,
page_array[i>>PAGE_SHIFT], page);
page_array[i>>PAGE_SHIFT], page);
}
}
@@ -380,14 +387,14 @@ static int setup_guest(int xc_handle,
ppt_alloc = (vpt_start - dsi.v_start) >> PAGE_SHIFT;
if ( page_array[ppt_alloc] > 0xfffff )
{
unsigned long nmfn;
nmfn = xc_make_page_below_4G( xc_handle, dom, page_array[ppt_alloc] );
if ( nmfn == 0 )
{
fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
goto error_out;
}
page_array[ppt_alloc] = nmfn;
unsigned long nmfn;
nmfn = xc_make_page_below_4G( xc_handle, dom, page_array[ppt_alloc] );
if ( nmfn == 0 )
{
fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
goto error_out;
}
page_array[ppt_alloc] = nmfn;
}
#ifdef __i386__
@@ -448,8 +455,8 @@ static int setup_guest(int xc_handle,
munmap(vl2tab, PAGE_SIZE);
if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE,
l2tab >> PAGE_SHIFT)) == NULL )
PROT_READ|PROT_WRITE,
l2tab >> PAGE_SHIFT)) == NULL )
goto error_out;
memset(vl2tab, 0, PAGE_SIZE);
@@ -462,8 +469,8 @@ static int setup_guest(int xc_handle,
if ( vl1tab != NULL )
munmap(vl1tab, PAGE_SIZE);
if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
PROT_READ|PROT_WRITE,
l1tab >> PAGE_SHIFT)) == NULL )
PROT_READ|PROT_WRITE,
l1tab >> PAGE_SHIFT)) == NULL )
{
munmap(vl2tab, PAGE_SIZE);
goto error_out;
@@ -485,15 +492,15 @@ static int setup_guest(int xc_handle,
for ( count = 0; count < nr_pages; count++ )
{
if ( xc_add_mmu_update(xc_handle, mmu,
(page_array[count] << PAGE_SHIFT) |
MMU_MACHPHYS_UPDATE, count) )
goto error_out;
(page_array[count] << PAGE_SHIFT) |
MMU_MACHPHYS_UPDATE, count) )
goto error_out;
}
if ((boot_paramsp = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[(vboot_params_start-dsi.v_start)>>PAGE_SHIFT])) == 0)
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[(vboot_params_start-dsi.v_start)>>PAGE_SHIFT])) == 0)
goto error_out;
memset(boot_paramsp, 0, sizeof(*boot_paramsp));
@@ -558,9 +565,9 @@ static int setup_guest(int xc_handle,
#if defined (__i386__)
if (zap_mmio_ranges(xc_handle, dom, l2tab, mem_mapp) == -1)
#else
if (zap_mmio_ranges(xc_handle, dom, l3tab, mem_mapp) == -1)
if (zap_mmio_ranges(xc_handle, dom, l3tab, mem_mapp) == -1)
#endif
goto error_out;
goto error_out;
boot_paramsp->e820_map_nr = mem_mapp->nr_map;
for (i=0; i<mem_mapp->nr_map; i++) {
boot_paramsp->e820_map[i].addr = mem_mapp->map[i].addr;
@@ -572,9 +579,9 @@ static int setup_guest(int xc_handle,
munmap(boot_paramsp, PAGE_SIZE);
if ((boot_gdtp = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[(vboot_gdt_start-dsi.v_start)>>PAGE_SHIFT])) == 0)
goto error_out;
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[(vboot_gdt_start-dsi.v_start)>>PAGE_SHIFT])) == 0)
goto error_out;
memset(boot_gdtp, 0, PAGE_SIZE);
boot_gdtp[12*4 + 0] = boot_gdtp[13*4 + 0] = 0xffff; /* limit */
boot_gdtp[12*4 + 1] = boot_gdtp[13*4 + 1] = 0x0000; /* base */
@@ -584,9 +591,9 @@ static int setup_guest(int xc_handle,
/* shared_info page starts its life empty. */
if ((shared_info = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
shared_info_frame)) == 0)
goto error_out;
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
shared_info_frame)) == 0)
goto error_out;
memset(shared_info, 0, sizeof(shared_info_t));
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
@@ -595,9 +602,9 @@ static int setup_guest(int xc_handle,
/* Populate the event channel port in the shared page */
if ((sp = (shared_iopage_t *) xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[shared_page_frame])) == 0)
goto error_out;
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[shared_page_frame])) == 0)
goto error_out;
memset(sp, 0, PAGE_SIZE);
sp->sp_global.eport = control_evtchn;
munmap(sp, PAGE_SIZE);
@@ -622,7 +629,7 @@ static int setup_guest(int xc_handle,
ctxt->user_regs.edx = vboot_gdt_start;
ctxt->user_regs.eax = 0x800;
ctxt->user_regs.esp = vboot_gdt_end;
ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */
ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */
ctxt->user_regs.ecx = mem_mapp->nr_map;
ctxt->user_regs.esi = vboot_params_start;
ctxt->user_regs.edi = vboot_params_start + 0x2d0;
@@ -646,9 +653,9 @@ static int vmx_identify(void)
#ifdef __i386__
__asm__ __volatile__ ("pushl %%ebx; cpuid; popl %%ebx"
: "=a" (eax), "=c" (ecx)
: "0" (1)
: "dx");
: "=a" (eax), "=c" (ecx)
: "0" (1)
: "dx");
#elif defined __x86_64__
__asm__ __volatile__ ("pushq %%rbx; cpuid; popq %%rbx"
: "=a" (eax), "=c" (ecx)
@@ -663,17 +670,17 @@ static int vmx_identify(void)
}
int xc_vmx_build(int xc_handle,
u32 domid,
int memsize,
const char *image_name,
struct mem_map *mem_mapp,
const char *ramdisk_name,
const char *cmdline,
unsigned int control_evtchn,
unsigned long flags,
unsigned int vcpus,
unsigned int store_evtchn,
unsigned long *store_mfn)
u32 domid,
int memsize,
const char *image_name,
struct mem_map *mem_mapp,
const char *ramdisk_name,
const char *cmdline,
unsigned int control_evtchn,
unsigned long flags,
unsigned int vcpus,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
dom0_op_t launch_op, op;
int initrd_fd = -1;
@@ -745,11 +752,11 @@ int xc_vmx_build(int xc_handle,
}
if ( setup_guest(xc_handle, domid, memsize, image, image_size,
initrd_gfd, initrd_size, nr_pages,
ctxt, cmdline,
op.u.getdomaininfo.shared_info_frame,
control_evtchn, flags, vcpus, store_evtchn, store_mfn,
mem_mapp) < 0 )
initrd_gfd, initrd_size, nr_pages,
ctxt, cmdline,
op.u.getdomaininfo.shared_info_frame,
control_evtchn, flags, vcpus, store_evtchn, store_mfn,
mem_mapp) < 0 )
{
ERROR("Error constructing guest OS");
goto error_out;
@@ -780,8 +787,8 @@ int xc_vmx_build(int xc_handle,
/* Ring 1 stack is the initial stack. */
/*
ctxt->kernel_ss = FLAT_KERNEL_DS;
ctxt->kernel_sp = vstartinfo_start;
ctxt->kernel_ss = FLAT_KERNEL_DS;
ctxt->kernel_sp = vstartinfo_start;
*/
/* No debugging. */
memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
@@ -861,7 +868,7 @@ static int parseelfimage(char *elfbase,
return -EINVAL;
}
shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
(ehdr->e_shstrndx*ehdr->e_shentsize));
(ehdr->e_shstrndx*ehdr->e_shentsize));
shstrtab = elfbase + shdr->sh_offset;
for ( h = 0; h < ehdr->e_phnum; h++ )
@@ -916,9 +923,9 @@ loadelfimage(
{
pa = (phdr->p_paddr + done) - dsi->v_start - LINUX_PAGE_OFFSET;
if ((va = xc_map_foreign_range(
xch, dom, PAGE_SIZE, PROT_WRITE,
parray[pa>>PAGE_SHIFT])) == 0)
return -1;
xch, dom, PAGE_SIZE, PROT_WRITE,
parray[pa>>PAGE_SHIFT])) == 0)
return -1;
chunksz = phdr->p_filesz - done;
if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
@@ -931,9 +938,9 @@ loadelfimage(
{
pa = (phdr->p_paddr + done) - dsi->v_start - LINUX_PAGE_OFFSET;
if ((va = xc_map_foreign_range(
xch, dom, PAGE_SIZE, PROT_WRITE,
parray[pa>>PAGE_SHIFT])) == 0)
return -1;
xch, dom, PAGE_SIZE, PROT_WRITE,
parray[pa>>PAGE_SHIFT])) == 0)
return -1;
chunksz = phdr->p_memsz - done;
if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
@@ -944,3 +951,13 @@ loadelfimage(
return 0;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.