]> Git Repo - qemu.git/blob - xen-all.c
Merge branch 'ppc-next' of git://repo.or.cz/qemu/agraf
[qemu.git] / xen-all.c
1 /*
2  * Copyright (C) 2010       Citrix Ltd.
3  *
4  * This work is licensed under the terms of the GNU GPL, version 2.  See
5  * the COPYING file in the top-level directory.
6  *
7  */
8
9 #include <sys/mman.h>
10
11 #include "hw/pci.h"
12 #include "hw/pc.h"
13 #include "hw/xen_common.h"
14 #include "hw/xen_backend.h"
15
16 #include "range.h"
17 #include "xen-mapcache.h"
18 #include "trace.h"
19
20 #include <xen/hvm/ioreq.h>
21 #include <xen/hvm/params.h>
22
23 //#define DEBUG_XEN
24
25 #ifdef DEBUG_XEN
26 #define DPRINTF(fmt, ...) \
27     do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0)
28 #else
29 #define DPRINTF(fmt, ...) \
30     do { } while (0)
31 #endif
32
33 /* Compatibility with older version */
34 #if __XEN_LATEST_INTERFACE_VERSION__ < 0x0003020a
35 static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
36 {
37     return shared_page->vcpu_iodata[i].vp_eport;
38 }
39 static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
40 {
41     return &shared_page->vcpu_iodata[vcpu].vp_ioreq;
42 }
43 #  define FMT_ioreq_size PRIx64
44 #else
45 static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
46 {
47     return shared_page->vcpu_ioreq[i].vp_eport;
48 }
49 static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
50 {
51     return &shared_page->vcpu_ioreq[vcpu];
52 }
53 #  define FMT_ioreq_size "u"
54 #endif
55
56 #define BUFFER_IO_MAX_DELAY  100
57
58 typedef struct XenPhysmap {
59     target_phys_addr_t start_addr;
60     ram_addr_t size;
61     target_phys_addr_t phys_offset;
62
63     QLIST_ENTRY(XenPhysmap) list;
64 } XenPhysmap;
65
66 typedef struct XenIOState {
67     shared_iopage_t *shared_page;
68     buffered_iopage_t *buffered_io_page;
69     QEMUTimer *buffered_io_timer;
70     /* the evtchn port for polling the notification, */
71     evtchn_port_t *ioreq_local_port;
72     /* the evtchn fd for polling */
73     XenEvtchn xce_handle;
74     /* which vcpu we are serving */
75     int send_vcpu;
76
77     struct xs_handle *xenstore;
78     CPUPhysMemoryClient client;
79     QLIST_HEAD(, XenPhysmap) physmap;
80     const XenPhysmap *log_for_dirtybit;
81
82     Notifier exit;
83 } XenIOState;
84
85 /* Xen specific function for piix pci */
86
87 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
88 {
89     return irq_num + ((pci_dev->devfn >> 3) << 2);
90 }
91
92 void xen_piix3_set_irq(void *opaque, int irq_num, int level)
93 {
94     xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num >> 2,
95                               irq_num & 3, level);
96 }
97
98 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
99 {
100     int i;
101
102     /* Scan for updates to PCI link routes (0x60-0x63). */
103     for (i = 0; i < len; i++) {
104         uint8_t v = (val >> (8 * i)) & 0xff;
105         if (v & 0x80) {
106             v = 0;
107         }
108         v &= 0xf;
109         if (((address + i) >= 0x60) && ((address + i) <= 0x63)) {
110             xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v);
111         }
112     }
113 }
114
115 void xen_cmos_set_s3_resume(void *opaque, int irq, int level)
116 {
117     pc_cmos_set_s3_resume(opaque, irq, level);
118     if (level) {
119         xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3);
120     }
121 }
122
123 /* Xen Interrupt Controller */
124
125 static void xen_set_irq(void *opaque, int irq, int level)
126 {
127     xc_hvm_set_isa_irq_level(xen_xc, xen_domid, irq, level);
128 }
129
130 qemu_irq *xen_interrupt_controller_init(void)
131 {
132     return qemu_allocate_irqs(xen_set_irq, NULL, 16);
133 }
134
135 /* Memory Ops */
136
137 static void xen_ram_init(ram_addr_t ram_size)
138 {
139     RAMBlock *new_block;
140     ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
141
142     new_block = qemu_mallocz(sizeof (*new_block));
143     pstrcpy(new_block->idstr, sizeof (new_block->idstr), "xen.ram");
144     new_block->host = NULL;
145     new_block->offset = 0;
146     new_block->length = ram_size;
147
148     QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
149
150     ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
151                                        new_block->length >> TARGET_PAGE_BITS);
152     memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
153            0xff, new_block->length >> TARGET_PAGE_BITS);
154
155     if (ram_size >= 0xe0000000 ) {
156         above_4g_mem_size = ram_size - 0xe0000000;
157         below_4g_mem_size = 0xe0000000;
158     } else {
159         below_4g_mem_size = ram_size;
160     }
161
162     cpu_register_physical_memory(0, below_4g_mem_size, new_block->offset);
163 #if TARGET_PHYS_ADDR_BITS > 32
164     if (above_4g_mem_size > 0) {
165         cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
166                                      new_block->offset + below_4g_mem_size);
167     }
168 #endif
169 }
170
171 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
172 {
173     unsigned long nr_pfn;
174     xen_pfn_t *pfn_list;
175     int i;
176
177     trace_xen_ram_alloc(ram_addr, size);
178
179     nr_pfn = size >> TARGET_PAGE_BITS;
180     pfn_list = qemu_malloc(sizeof (*pfn_list) * nr_pfn);
181
182     for (i = 0; i < nr_pfn; i++) {
183         pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
184     }
185
186     if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
187         hw_error("xen: failed to populate ram at %lx", ram_addr);
188     }
189
190     qemu_free(pfn_list);
191 }
192
193 static XenPhysmap *get_physmapping(XenIOState *state,
194                                    target_phys_addr_t start_addr, ram_addr_t size)
195 {
196     XenPhysmap *physmap = NULL;
197
198     start_addr &= TARGET_PAGE_MASK;
199
200     QLIST_FOREACH(physmap, &state->physmap, list) {
201         if (range_covers_byte(physmap->start_addr, physmap->size, start_addr)) {
202             return physmap;
203         }
204     }
205     return NULL;
206 }
207
208 #if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340
209 static int xen_add_to_physmap(XenIOState *state,
210                               target_phys_addr_t start_addr,
211                               ram_addr_t size,
212                               target_phys_addr_t phys_offset)
213 {
214     unsigned long i = 0;
215     int rc = 0;
216     XenPhysmap *physmap = NULL;
217     target_phys_addr_t pfn, start_gpfn;
218     RAMBlock *block;
219
220     if (get_physmapping(state, start_addr, size)) {
221         return 0;
222     }
223     if (size <= 0) {
224         return -1;
225     }
226
227     /* Xen can only handle a single dirty log region for now and we want
228      * the linear framebuffer to be that region.
229      * Avoid tracking any regions that is not videoram and avoid tracking
230      * the legacy vga region. */
231     QLIST_FOREACH(block, &ram_list.blocks, next) {
232         if (!strcmp(block->idstr, "vga.vram") && block->offset == phys_offset
233                 && start_addr > 0xbffff) {
234             goto go_physmap;
235         }
236     }
237     return -1;
238
239 go_physmap:
240     DPRINTF("mapping vram to %llx - %llx, from %llx\n",
241             start_addr, start_addr + size, phys_offset);
242
243     pfn = phys_offset >> TARGET_PAGE_BITS;
244     start_gpfn = start_addr >> TARGET_PAGE_BITS;
245     for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
246         unsigned long idx = pfn + i;
247         xen_pfn_t gpfn = start_gpfn + i;
248
249         rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn);
250         if (rc) {
251             DPRINTF("add_to_physmap MFN %"PRI_xen_pfn" to PFN %"
252                     PRI_xen_pfn" failed: %d\n", idx, gpfn, rc);
253             return -rc;
254         }
255     }
256
257     physmap = qemu_malloc(sizeof (XenPhysmap));
258
259     physmap->start_addr = start_addr;
260     physmap->size = size;
261     physmap->phys_offset = phys_offset;
262
263     QLIST_INSERT_HEAD(&state->physmap, physmap, list);
264
265     xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
266                                    start_addr >> TARGET_PAGE_BITS,
267                                    (start_addr + size) >> TARGET_PAGE_BITS,
268                                    XEN_DOMCTL_MEM_CACHEATTR_WB);
269     return 0;
270 }
271
272 static int xen_remove_from_physmap(XenIOState *state,
273                                    target_phys_addr_t start_addr,
274                                    ram_addr_t size)
275 {
276     unsigned long i = 0;
277     int rc = 0;
278     XenPhysmap *physmap = NULL;
279     target_phys_addr_t phys_offset = 0;
280
281     physmap = get_physmapping(state, start_addr, size);
282     if (physmap == NULL) {
283         return -1;
284     }
285
286     phys_offset = physmap->phys_offset;
287     size = physmap->size;
288
289     DPRINTF("unmapping vram to %llx - %llx, from %llx\n",
290             phys_offset, phys_offset + size, start_addr);
291
292     size >>= TARGET_PAGE_BITS;
293     start_addr >>= TARGET_PAGE_BITS;
294     phys_offset >>= TARGET_PAGE_BITS;
295     for (i = 0; i < size; i++) {
296         unsigned long idx = start_addr + i;
297         xen_pfn_t gpfn = phys_offset + i;
298
299         rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn);
300         if (rc) {
301             fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"
302                     PRI_xen_pfn" failed: %d\n", idx, gpfn, rc);
303             return -rc;
304         }
305     }
306
307     QLIST_REMOVE(physmap, list);
308     if (state->log_for_dirtybit == physmap) {
309         state->log_for_dirtybit = NULL;
310     }
311     free(physmap);
312
313     return 0;
314 }
315
316 #else
317 static int xen_add_to_physmap(XenIOState *state,
318                               target_phys_addr_t start_addr,
319                               ram_addr_t size,
320                               target_phys_addr_t phys_offset)
321 {
322     return -ENOSYS;
323 }
324
325 static int xen_remove_from_physmap(XenIOState *state,
326                                    target_phys_addr_t start_addr,
327                                    ram_addr_t size)
328 {
329     return -ENOSYS;
330 }
331 #endif
332
333 static void xen_client_set_memory(struct CPUPhysMemoryClient *client,
334                                   target_phys_addr_t start_addr,
335                                   ram_addr_t size,
336                                   ram_addr_t phys_offset,
337                                   bool log_dirty)
338 {
339     XenIOState *state = container_of(client, XenIOState, client);
340     ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;
341     hvmmem_type_t mem_type;
342
343     if (!(start_addr != phys_offset
344           && ( (log_dirty && flags < IO_MEM_UNASSIGNED)
345                || (!log_dirty && flags == IO_MEM_UNASSIGNED)))) {
346         return;
347     }
348
349     trace_xen_client_set_memory(start_addr, size, phys_offset, log_dirty);
350
351     start_addr &= TARGET_PAGE_MASK;
352     size = TARGET_PAGE_ALIGN(size);
353     phys_offset &= TARGET_PAGE_MASK;
354
355     switch (flags) {
356     case IO_MEM_RAM:
357         xen_add_to_physmap(state, start_addr, size, phys_offset);
358         break;
359     case IO_MEM_ROM:
360         mem_type = HVMMEM_ram_ro;
361         if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type,
362                                 start_addr >> TARGET_PAGE_BITS,
363                                 size >> TARGET_PAGE_BITS)) {
364             DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n",
365                     start_addr);
366         }
367         break;
368     case IO_MEM_UNASSIGNED:
369         if (xen_remove_from_physmap(state, start_addr, size) < 0) {
370             DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr);
371         }
372         break;
373     }
374 }
375
376 static int xen_sync_dirty_bitmap(XenIOState *state,
377                                  target_phys_addr_t start_addr,
378                                  ram_addr_t size)
379 {
380     target_phys_addr_t npages = size >> TARGET_PAGE_BITS;
381     target_phys_addr_t vram_offset = 0;
382     const int width = sizeof(unsigned long) * 8;
383     unsigned long bitmap[(npages + width - 1) / width];
384     int rc, i, j;
385     const XenPhysmap *physmap = NULL;
386
387     physmap = get_physmapping(state, start_addr, size);
388     if (physmap == NULL) {
389         /* not handled */
390         return -1;
391     }
392
393     if (state->log_for_dirtybit == NULL) {
394         state->log_for_dirtybit = physmap;
395     } else if (state->log_for_dirtybit != physmap) {
396         return -1;
397     }
398     vram_offset = physmap->phys_offset;
399
400     rc = xc_hvm_track_dirty_vram(xen_xc, xen_domid,
401                                  start_addr >> TARGET_PAGE_BITS, npages,
402                                  bitmap);
403     if (rc) {
404         return rc;
405     }
406
407     for (i = 0; i < ARRAY_SIZE(bitmap); i++) {
408         unsigned long map = bitmap[i];
409         while (map != 0) {
410             j = ffsl(map) - 1;
411             map &= ~(1ul << j);
412             cpu_physical_memory_set_dirty(vram_offset + (i * width + j) * TARGET_PAGE_SIZE);
413         };
414     }
415
416     return 0;
417 }
418
419 static int xen_log_start(CPUPhysMemoryClient *client, target_phys_addr_t phys_addr, ram_addr_t size)
420 {
421     XenIOState *state = container_of(client, XenIOState, client);
422
423     return xen_sync_dirty_bitmap(state, phys_addr, size);
424 }
425
426 static int xen_log_stop(CPUPhysMemoryClient *client, target_phys_addr_t phys_addr, ram_addr_t size)
427 {
428     XenIOState *state = container_of(client, XenIOState, client);
429
430     state->log_for_dirtybit = NULL;
431     /* Disable dirty bit tracking */
432     return xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
433 }
434
435 static int xen_client_sync_dirty_bitmap(struct CPUPhysMemoryClient *client,
436                                         target_phys_addr_t start_addr,
437                                         target_phys_addr_t end_addr)
438 {
439     XenIOState *state = container_of(client, XenIOState, client);
440
441     return xen_sync_dirty_bitmap(state, start_addr, end_addr - start_addr);
442 }
443
444 static int xen_client_migration_log(struct CPUPhysMemoryClient *client,
445                                     int enable)
446 {
447     return 0;
448 }
449
450 static CPUPhysMemoryClient xen_cpu_phys_memory_client = {
451     .set_memory = xen_client_set_memory,
452     .sync_dirty_bitmap = xen_client_sync_dirty_bitmap,
453     .migration_log = xen_client_migration_log,
454     .log_start = xen_log_start,
455     .log_stop = xen_log_stop,
456 };
457
458 /* VCPU Operations, MMIO, IO ring ... */
459
460 static void xen_reset_vcpu(void *opaque)
461 {
462     CPUState *env = opaque;
463
464     env->halted = 1;
465 }
466
467 void xen_vcpu_init(void)
468 {
469     CPUState *first_cpu;
470
471     if ((first_cpu = qemu_get_cpu(0))) {
472         qemu_register_reset(xen_reset_vcpu, first_cpu);
473         xen_reset_vcpu(first_cpu);
474     }
475 }
476
477 /* get the ioreq packets from share mem */
478 static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
479 {
480     ioreq_t *req = xen_vcpu_ioreq(state->shared_page, vcpu);
481
482     if (req->state != STATE_IOREQ_READY) {
483         DPRINTF("I/O request not ready: "
484                 "%x, ptr: %x, port: %"PRIx64", "
485                 "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
486                 req->state, req->data_is_ptr, req->addr,
487                 req->data, req->count, req->size);
488         return NULL;
489     }
490
491     xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
492
493     req->state = STATE_IOREQ_INPROCESS;
494     return req;
495 }
496
497 /* use poll to get the port notification */
498 /* ioreq_vec--out,the */
499 /* retval--the number of ioreq packet */
500 static ioreq_t *cpu_get_ioreq(XenIOState *state)
501 {
502     int i;
503     evtchn_port_t port;
504
505     port = xc_evtchn_pending(state->xce_handle);
506     if (port != -1) {
507         for (i = 0; i < smp_cpus; i++) {
508             if (state->ioreq_local_port[i] == port) {
509                 break;
510             }
511         }
512
513         if (i == smp_cpus) {
514             hw_error("Fatal error while trying to get io event!\n");
515         }
516
517         /* unmask the wanted port again */
518         xc_evtchn_unmask(state->xce_handle, port);
519
520         /* get the io packet from shared memory */
521         state->send_vcpu = i;
522         return cpu_get_ioreq_from_shared_memory(state, i);
523     }
524
525     /* read error or read nothing */
526     return NULL;
527 }
528
529 static uint32_t do_inp(pio_addr_t addr, unsigned long size)
530 {
531     switch (size) {
532         case 1:
533             return cpu_inb(addr);
534         case 2:
535             return cpu_inw(addr);
536         case 4:
537             return cpu_inl(addr);
538         default:
539             hw_error("inp: bad size: %04"FMT_pioaddr" %lx", addr, size);
540     }
541 }
542
543 static void do_outp(pio_addr_t addr,
544         unsigned long size, uint32_t val)
545 {
546     switch (size) {
547         case 1:
548             return cpu_outb(addr, val);
549         case 2:
550             return cpu_outw(addr, val);
551         case 4:
552             return cpu_outl(addr, val);
553         default:
554             hw_error("outp: bad size: %04"FMT_pioaddr" %lx", addr, size);
555     }
556 }
557
558 static void cpu_ioreq_pio(ioreq_t *req)
559 {
560     int i, sign;
561
562     sign = req->df ? -1 : 1;
563
564     if (req->dir == IOREQ_READ) {
565         if (!req->data_is_ptr) {
566             req->data = do_inp(req->addr, req->size);
567         } else {
568             uint32_t tmp;
569
570             for (i = 0; i < req->count; i++) {
571                 tmp = do_inp(req->addr, req->size);
572                 cpu_physical_memory_write(req->data + (sign * i * req->size),
573                         (uint8_t *) &tmp, req->size);
574             }
575         }
576     } else if (req->dir == IOREQ_WRITE) {
577         if (!req->data_is_ptr) {
578             do_outp(req->addr, req->size, req->data);
579         } else {
580             for (i = 0; i < req->count; i++) {
581                 uint32_t tmp = 0;
582
583                 cpu_physical_memory_read(req->data + (sign * i * req->size),
584                         (uint8_t*) &tmp, req->size);
585                 do_outp(req->addr, req->size, tmp);
586             }
587         }
588     }
589 }
590
591 static void cpu_ioreq_move(ioreq_t *req)
592 {
593     int i, sign;
594
595     sign = req->df ? -1 : 1;
596
597     if (!req->data_is_ptr) {
598         if (req->dir == IOREQ_READ) {
599             for (i = 0; i < req->count; i++) {
600                 cpu_physical_memory_read(req->addr + (sign * i * req->size),
601                         (uint8_t *) &req->data, req->size);
602             }
603         } else if (req->dir == IOREQ_WRITE) {
604             for (i = 0; i < req->count; i++) {
605                 cpu_physical_memory_write(req->addr + (sign * i * req->size),
606                         (uint8_t *) &req->data, req->size);
607             }
608         }
609     } else {
610         target_ulong tmp;
611
612         if (req->dir == IOREQ_READ) {
613             for (i = 0; i < req->count; i++) {
614                 cpu_physical_memory_read(req->addr + (sign * i * req->size),
615                         (uint8_t*) &tmp, req->size);
616                 cpu_physical_memory_write(req->data + (sign * i * req->size),
617                         (uint8_t*) &tmp, req->size);
618             }
619         } else if (req->dir == IOREQ_WRITE) {
620             for (i = 0; i < req->count; i++) {
621                 cpu_physical_memory_read(req->data + (sign * i * req->size),
622                         (uint8_t*) &tmp, req->size);
623                 cpu_physical_memory_write(req->addr + (sign * i * req->size),
624                         (uint8_t*) &tmp, req->size);
625             }
626         }
627     }
628 }
629
630 static void handle_ioreq(ioreq_t *req)
631 {
632     if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
633             (req->size < sizeof (target_ulong))) {
634         req->data &= ((target_ulong) 1 << (8 * req->size)) - 1;
635     }
636
637     switch (req->type) {
638         case IOREQ_TYPE_PIO:
639             cpu_ioreq_pio(req);
640             break;
641         case IOREQ_TYPE_COPY:
642             cpu_ioreq_move(req);
643             break;
644         case IOREQ_TYPE_TIMEOFFSET:
645             break;
646         case IOREQ_TYPE_INVALIDATE:
647             qemu_invalidate_map_cache();
648             break;
649         default:
650             hw_error("Invalid ioreq type 0x%x\n", req->type);
651     }
652 }
653
654 static void handle_buffered_iopage(XenIOState *state)
655 {
656     buf_ioreq_t *buf_req = NULL;
657     ioreq_t req;
658     int qw;
659
660     if (!state->buffered_io_page) {
661         return;
662     }
663
664     while (state->buffered_io_page->read_pointer != state->buffered_io_page->write_pointer) {
665         buf_req = &state->buffered_io_page->buf_ioreq[
666             state->buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM];
667         req.size = 1UL << buf_req->size;
668         req.count = 1;
669         req.addr = buf_req->addr;
670         req.data = buf_req->data;
671         req.state = STATE_IOREQ_READY;
672         req.dir = buf_req->dir;
673         req.df = 1;
674         req.type = buf_req->type;
675         req.data_is_ptr = 0;
676         qw = (req.size == 8);
677         if (qw) {
678             buf_req = &state->buffered_io_page->buf_ioreq[
679                 (state->buffered_io_page->read_pointer + 1) % IOREQ_BUFFER_SLOT_NUM];
680             req.data |= ((uint64_t)buf_req->data) << 32;
681         }
682
683         handle_ioreq(&req);
684
685         xen_mb();
686         state->buffered_io_page->read_pointer += qw ? 2 : 1;
687     }
688 }
689
690 static void handle_buffered_io(void *opaque)
691 {
692     XenIOState *state = opaque;
693
694     handle_buffered_iopage(state);
695     qemu_mod_timer(state->buffered_io_timer,
696                    BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
697 }
698
699 static void cpu_handle_ioreq(void *opaque)
700 {
701     XenIOState *state = opaque;
702     ioreq_t *req = cpu_get_ioreq(state);
703
704     handle_buffered_iopage(state);
705     if (req) {
706         handle_ioreq(req);
707
708         if (req->state != STATE_IOREQ_INPROCESS) {
709             fprintf(stderr, "Badness in I/O request ... not in service?!: "
710                     "%x, ptr: %x, port: %"PRIx64", "
711                     "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
712                     req->state, req->data_is_ptr, req->addr,
713                     req->data, req->count, req->size);
714             destroy_hvm_domain();
715             return;
716         }
717
718         xen_wmb(); /* Update ioreq contents /then/ update state. */
719
720         /*
721          * We do this before we send the response so that the tools
722          * have the opportunity to pick up on the reset before the
723          * guest resumes and does a hlt with interrupts disabled which
724          * causes Xen to powerdown the domain.
725          */
726         if (vm_running) {
727             if (qemu_shutdown_requested_get()) {
728                 destroy_hvm_domain();
729             }
730             if (qemu_reset_requested_get()) {
731                 qemu_system_reset(VMRESET_REPORT);
732             }
733         }
734
735         req->state = STATE_IORESP_READY;
736         xc_evtchn_notify(state->xce_handle, state->ioreq_local_port[state->send_vcpu]);
737     }
738 }
739
740 static void xenstore_record_dm_state(XenIOState *s, const char *state)
741 {
742     char path[50];
743
744     snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", xen_domid);
745     if (!xs_write(s->xenstore, XBT_NULL, path, state, strlen(state))) {
746         fprintf(stderr, "error recording dm state\n");
747         exit(1);
748     }
749 }
750
751 static void xen_main_loop_prepare(XenIOState *state)
752 {
753     int evtchn_fd = -1;
754
755     if (state->xce_handle != XC_HANDLER_INITIAL_VALUE) {
756         evtchn_fd = xc_evtchn_fd(state->xce_handle);
757     }
758
759     state->buffered_io_timer = qemu_new_timer_ms(rt_clock, handle_buffered_io,
760                                                  state);
761     qemu_mod_timer(state->buffered_io_timer, qemu_get_clock_ms(rt_clock));
762
763     if (evtchn_fd != -1) {
764         qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
765     }
766
767     /* record state running */
768     xenstore_record_dm_state(state, "running");
769 }
770
771
772 /* Initialise Xen */
773
774 static void xen_vm_change_state_handler(void *opaque, int running, int reason)
775 {
776     XenIOState *state = opaque;
777     if (running) {
778         xen_main_loop_prepare(state);
779     }
780 }
781
782 static void xen_exit_notifier(Notifier *n)
783 {
784     XenIOState *state = container_of(n, XenIOState, exit);
785
786     xc_evtchn_close(state->xce_handle);
787     xs_daemon_close(state->xenstore);
788 }
789
790 int xen_init(void)
791 {
792     xen_xc = xen_xc_interface_open(0, 0, 0);
793     if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
794         xen_be_printf(NULL, 0, "can't open xen interface\n");
795         return -1;
796     }
797
798     return 0;
799 }
800
801 int xen_hvm_init(void)
802 {
803     int i, rc;
804     unsigned long ioreq_pfn;
805     XenIOState *state;
806
807     state = qemu_mallocz(sizeof (XenIOState));
808
809     state->xce_handle = xen_xc_evtchn_open(NULL, 0);
810     if (state->xce_handle == XC_HANDLER_INITIAL_VALUE) {
811         perror("xen: event channel open");
812         return -errno;
813     }
814
815     state->xenstore = xs_daemon_open();
816     if (state->xenstore == NULL) {
817         perror("xen: xenstore open");
818         return -errno;
819     }
820
821     state->exit.notify = xen_exit_notifier;
822     qemu_add_exit_notifier(&state->exit);
823
824     xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
825     DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
826     state->shared_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
827                                               PROT_READ|PROT_WRITE, ioreq_pfn);
828     if (state->shared_page == NULL) {
829         hw_error("map shared IO page returned error %d handle=" XC_INTERFACE_FMT,
830                  errno, xen_xc);
831     }
832
833     xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
834     DPRINTF("buffered io page at pfn %lx\n", ioreq_pfn);
835     state->buffered_io_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
836                                                    PROT_READ|PROT_WRITE, ioreq_pfn);
837     if (state->buffered_io_page == NULL) {
838         hw_error("map buffered IO page returned error %d", errno);
839     }
840
841     state->ioreq_local_port = qemu_mallocz(smp_cpus * sizeof (evtchn_port_t));
842
843     /* FIXME: how about if we overflow the page here? */
844     for (i = 0; i < smp_cpus; i++) {
845         rc = xc_evtchn_bind_interdomain(state->xce_handle, xen_domid,
846                                         xen_vcpu_eport(state->shared_page, i));
847         if (rc == -1) {
848             fprintf(stderr, "bind interdomain ioctl error %d\n", errno);
849             return -1;
850         }
851         state->ioreq_local_port[i] = rc;
852     }
853
854     /* Init RAM management */
855     qemu_map_cache_init();
856     xen_ram_init(ram_size);
857
858     qemu_add_vm_change_state_handler(xen_vm_change_state_handler, state);
859
860     state->client = xen_cpu_phys_memory_client;
861     QLIST_INIT(&state->physmap);
862     cpu_register_phys_memory_client(&state->client);
863     state->log_for_dirtybit = NULL;
864
865     return 0;
866 }
867
868 void destroy_hvm_domain(void)
869 {
870     XenXC xc_handle;
871     int sts;
872
873     xc_handle = xen_xc_interface_open(0, 0, 0);
874     if (xc_handle == XC_HANDLER_INITIAL_VALUE) {
875         fprintf(stderr, "Cannot acquire xenctrl handle\n");
876     } else {
877         sts = xc_domain_shutdown(xc_handle, xen_domid, SHUTDOWN_poweroff);
878         if (sts != 0) {
879             fprintf(stderr, "? xc_domain_shutdown failed to issue poweroff, "
880                     "sts %d, %s\n", sts, strerror(errno));
881         } else {
882             fprintf(stderr, "Issued domain %d poweroff\n", xen_domid);
883         }
884         xc_interface_close(xc_handle);
885     }
886 }
This page took 0.076097 seconds and 4 git commands to generate.