ia64/xen-unstable

view tools/libxc/xc_core.c @ 9488:0a6f5527ca4b

[IA64] set itv handoff as masked and enable reading irr[0-3]

Set initial vcpu itv handoff state to mask the timer vector.
This seems to match hardware and makes logical sense from a
spurious interrupt perspective. Enable vcpu_get_irr[0-3]
functions as they seem to work and have the proper backing.
This enables the check_sal_cache_flush() in arch/ia64/kernel.sal.c
to work unmodified, allowing us to remove the Xen changes from
the file (and thus the file from the sparse tree).

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild.aw
date Tue Apr 04 09:39:45 2006 -0600 (2006-04-04)
parents 96e3b02ec931
children 74ee53209cca
line source
1 #include "xg_private.h"
2 #define ELFSIZE 32
3 #include "xc_elf.h"
4 #include <stdlib.h>
5 #include <unistd.h>
7 /* number of pages to write at a time */
8 #define DUMP_INCREMENT (4 * 1024)
9 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
11 static int
12 copy_from_domain_page(int xc_handle,
13 uint32_t domid,
14 unsigned long mfn,
15 void *dst_page)
16 {
17 void *vaddr = xc_map_foreign_range(
18 xc_handle, domid, PAGE_SIZE, PROT_READ, mfn);
19 if ( vaddr == NULL )
20 return -1;
21 memcpy(dst_page, vaddr, PAGE_SIZE);
22 munmap(vaddr, PAGE_SIZE);
23 return 0;
24 }
26 int
27 xc_domain_dumpcore_via_callback(int xc_handle,
28 uint32_t domid,
29 void *args,
30 dumpcore_rtn_t dump_rtn)
31 {
32 unsigned long nr_pages;
33 unsigned long *page_array = NULL;
34 xc_dominfo_t info;
35 int i, nr_vcpus = 0;
36 char *dump_mem, *dump_mem_start = NULL;
37 struct xc_core_header header;
38 vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
39 char dummy[PAGE_SIZE];
40 int dummy_len;
41 int sts;
43 if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
44 {
45 PERROR("Could not allocate dump_mem");
46 goto error_out;
47 }
49 if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
50 {
51 PERROR("Could not get info for domain");
52 goto error_out;
53 }
55 if ( domid != info.domid )
56 {
57 PERROR("Domain %d does not exist", domid);
58 goto error_out;
59 }
61 for ( i = 0; i <= info.max_vcpu_id; i++ )
62 if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0)
63 nr_vcpus++;
65 nr_pages = info.nr_pages;
67 header.xch_magic = XC_CORE_MAGIC;
68 header.xch_nr_vcpus = nr_vcpus;
69 header.xch_nr_pages = nr_pages;
70 header.xch_ctxt_offset = sizeof(struct xc_core_header);
71 header.xch_index_offset = sizeof(struct xc_core_header) +
72 sizeof(vcpu_guest_context_t)*nr_vcpus;
73 dummy_len = (sizeof(struct xc_core_header) +
74 (sizeof(vcpu_guest_context_t) * nr_vcpus) +
75 (nr_pages * sizeof(unsigned long)));
76 header.xch_pages_offset = round_pgup(dummy_len);
78 sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header));
79 if ( sts != 0 )
80 goto error_out;
82 sts = dump_rtn(args, (char *)&ctxt, sizeof(ctxt[0]) * nr_vcpus);
83 if ( sts != 0 )
84 goto error_out;
86 if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
87 {
88 printf("Could not allocate memory\n");
89 goto error_out;
90 }
91 if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
92 {
93 printf("Could not get the page frame list\n");
94 goto error_out;
95 }
96 sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(unsigned long));
97 if ( sts != 0 )
98 goto error_out;
100 /* Pad the output data to page alignment. */
101 memset(dummy, 0, PAGE_SIZE);
102 sts = dump_rtn(args, dummy, header.xch_pages_offset - dummy_len);
103 if ( sts != 0 )
104 goto error_out;
106 for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ )
107 {
108 copy_from_domain_page(xc_handle, domid, page_array[i], dump_mem);
109 dump_mem += PAGE_SIZE;
110 if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) )
111 {
112 sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
113 if ( sts != 0 )
114 goto error_out;
115 dump_mem = dump_mem_start;
116 }
117 }
119 free(dump_mem_start);
120 free(page_array);
121 return 0;
123 error_out:
124 free(dump_mem_start);
125 free(page_array);
126 return -1;
127 }
129 /* Callback args for writing to a local dump file. */
130 struct dump_args {
131 int fd;
132 };
134 /* Callback routine for writing to a local dump file. */
135 static int local_file_dump(void *args, char *buffer, unsigned int length)
136 {
137 struct dump_args *da = args;
138 int bytes, offset;
140 for ( offset = 0; offset < length; offset += bytes )
141 {
142 bytes = write(da->fd, &buffer[offset], length-offset);
143 if ( bytes <= 0 )
144 {
145 PERROR("Failed to write buffer: %s", strerror(errno));
146 return -errno;
147 }
148 }
150 return 0;
151 }
153 int
154 xc_domain_dumpcore(int xc_handle,
155 uint32_t domid,
156 const char *corename)
157 {
158 struct dump_args da;
159 int sts;
161 if ( (da.fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0 )
162 {
163 PERROR("Could not open corefile %s: %s", corename, strerror(errno));
164 return -errno;
165 }
167 sts = xc_domain_dumpcore_via_callback(
168 xc_handle, domid, &da, &local_file_dump);
170 close(da.fd);
172 return sts;
173 }
175 /*
176 * Local variables:
177 * mode: C
178 * c-set-style: "BSD"
179 * c-basic-offset: 4
180 * tab-width: 4
181 * indent-tabs-mode: nil
182 * End:
183 */