File:  [Qemu by Fabrice Bellard] / qemu / xen-all.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:34:57 2018 UTC (2 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1101, HEAD
qemu 1.1.1

    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:  * Contributions after 2012-01-13 are licensed under the terms of the
    8:  * GNU GPL, version 2 or (at your option) any later version.
    9:  */
   10: 
   11: #include <sys/mman.h>
   12: 
   13: #include "hw/pci.h"
   14: #include "hw/pc.h"
   15: #include "hw/xen_common.h"
   16: #include "hw/xen_backend.h"
   17: 
   18: #include "range.h"
   19: #include "xen-mapcache.h"
   20: #include "trace.h"
   21: #include "exec-memory.h"
   22: 
   23: #include <xen/hvm/ioreq.h>
   24: #include <xen/hvm/params.h>
   25: #include <xen/hvm/e820.h>
   26: 
   27: //#define DEBUG_XEN
   28: 
   29: #ifdef DEBUG_XEN
   30: #define DPRINTF(fmt, ...) \
   31:     do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0)
   32: #else
   33: #define DPRINTF(fmt, ...) \
   34:     do { } while (0)
   35: #endif
   36: 
   37: static MemoryRegion ram_memory, ram_640k, ram_lo, ram_hi;
   38: static MemoryRegion *framebuffer;
   39: 
   40: /* Compatibility with older version */
   41: #if __XEN_LATEST_INTERFACE_VERSION__ < 0x0003020a
   42: static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
   43: {
   44:     return shared_page->vcpu_iodata[i].vp_eport;
   45: }
   46: static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
   47: {
   48:     return &shared_page->vcpu_iodata[vcpu].vp_ioreq;
   49: }
   50: #  define FMT_ioreq_size PRIx64
   51: #else
   52: static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
   53: {
   54:     return shared_page->vcpu_ioreq[i].vp_eport;
   55: }
   56: static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
   57: {
   58:     return &shared_page->vcpu_ioreq[vcpu];
   59: }
   60: #  define FMT_ioreq_size "u"
   61: #endif
   62: #ifndef HVM_PARAM_BUFIOREQ_EVTCHN
   63: #define HVM_PARAM_BUFIOREQ_EVTCHN 26
   64: #endif
   65: 
   66: #define BUFFER_IO_MAX_DELAY  100
   67: 
   68: typedef struct XenPhysmap {
   69:     target_phys_addr_t start_addr;
   70:     ram_addr_t size;
   71:     char *name;
   72:     target_phys_addr_t phys_offset;
   73: 
   74:     QLIST_ENTRY(XenPhysmap) list;
   75: } XenPhysmap;
   76: 
   77: typedef struct XenIOState {
   78:     shared_iopage_t *shared_page;
   79:     buffered_iopage_t *buffered_io_page;
   80:     QEMUTimer *buffered_io_timer;
   81:     /* the evtchn port for polling the notification, */
   82:     evtchn_port_t *ioreq_local_port;
   83:     /* evtchn local port for buffered io */
   84:     evtchn_port_t bufioreq_local_port;
   85:     /* the evtchn fd for polling */
   86:     XenEvtchn xce_handle;
   87:     /* which vcpu we are serving */
   88:     int send_vcpu;
   89: 
   90:     struct xs_handle *xenstore;
   91:     MemoryListener memory_listener;
   92:     QLIST_HEAD(, XenPhysmap) physmap;
   93:     target_phys_addr_t free_phys_offset;
   94:     const XenPhysmap *log_for_dirtybit;
   95: 
   96:     Notifier exit;
   97:     Notifier suspend;
   98: } XenIOState;
   99: 
  100: /* Xen specific function for piix pci */
  101: 
  102: int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
  103: {
  104:     return irq_num + ((pci_dev->devfn >> 3) << 2);
  105: }
  106: 
  107: void xen_piix3_set_irq(void *opaque, int irq_num, int level)
  108: {
  109:     xc_hvm_set_pci_intx_level(xen_xc, xen_domid, 0, 0, irq_num >> 2,
  110:                               irq_num & 3, level);
  111: }
  112: 
  113: void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
  114: {
  115:     int i;
  116: 
  117:     /* Scan for updates to PCI link routes (0x60-0x63). */
  118:     for (i = 0; i < len; i++) {
  119:         uint8_t v = (val >> (8 * i)) & 0xff;
  120:         if (v & 0x80) {
  121:             v = 0;
  122:         }
  123:         v &= 0xf;
  124:         if (((address + i) >= 0x60) && ((address + i) <= 0x63)) {
  125:             xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v);
  126:         }
  127:     }
  128: }
  129: 
  130: void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
  131: {
  132:     xen_xc_hvm_inject_msi(xen_xc, xen_domid, addr, data);
  133: }
  134: 
  135: static void xen_suspend_notifier(Notifier *notifier, void *data)
  136: {
  137:     xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3);
  138: }
  139: 
  140: /* Xen Interrupt Controller */
  141: 
  142: static void xen_set_irq(void *opaque, int irq, int level)
  143: {
  144:     xc_hvm_set_isa_irq_level(xen_xc, xen_domid, irq, level);
  145: }
  146: 
  147: qemu_irq *xen_interrupt_controller_init(void)
  148: {
  149:     return qemu_allocate_irqs(xen_set_irq, NULL, 16);
  150: }
  151: 
  152: /* Memory Ops */
  153: 
  154: static void xen_ram_init(ram_addr_t ram_size)
  155: {
  156:     MemoryRegion *sysmem = get_system_memory();
  157:     ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
  158:     ram_addr_t block_len;
  159: 
  160:     block_len = ram_size;
  161:     if (ram_size >= HVM_BELOW_4G_RAM_END) {
  162:         /* Xen does not allocate the memory continuously, and keep a hole at
  163:          * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH
  164:          */
  165:         block_len += HVM_BELOW_4G_MMIO_LENGTH;
  166:     }
  167:     memory_region_init_ram(&ram_memory, "xen.ram", block_len);
  168:     vmstate_register_ram_global(&ram_memory);
  169: 
  170:     if (ram_size >= HVM_BELOW_4G_RAM_END) {
  171:         above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END;
  172:         below_4g_mem_size = HVM_BELOW_4G_RAM_END;
  173:     } else {
  174:         below_4g_mem_size = ram_size;
  175:     }
  176: 
  177:     memory_region_init_alias(&ram_640k, "xen.ram.640k",
  178:                              &ram_memory, 0, 0xa0000);
  179:     memory_region_add_subregion(sysmem, 0, &ram_640k);
  180:     /* Skip of the VGA IO memory space, it will be registered later by the VGA
  181:      * emulated device.
  182:      *
  183:      * The area between 0xc0000 and 0x100000 will be used by SeaBIOS to load
  184:      * the Options ROM, so it is registered here as RAM.
  185:      */
  186:     memory_region_init_alias(&ram_lo, "xen.ram.lo",
  187:                              &ram_memory, 0xc0000, below_4g_mem_size - 0xc0000);
  188:     memory_region_add_subregion(sysmem, 0xc0000, &ram_lo);
  189:     if (above_4g_mem_size > 0) {
  190:         memory_region_init_alias(&ram_hi, "xen.ram.hi",
  191:                                  &ram_memory, 0x100000000ULL,
  192:                                  above_4g_mem_size);
  193:         memory_region_add_subregion(sysmem, 0x100000000ULL, &ram_hi);
  194:     }
  195: }
  196: 
  197: void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr)
  198: {
  199:     unsigned long nr_pfn;
  200:     xen_pfn_t *pfn_list;
  201:     int i;
  202: 
  203:     if (runstate_check(RUN_STATE_INMIGRATE)) {
  204:         /* RAM already populated in Xen */
  205:         fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
  206:                 " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
  207:                 __func__, size, ram_addr); 
  208:         return;
  209:     }
  210: 
  211:     if (mr == &ram_memory) {
  212:         return;
  213:     }
  214: 
  215:     trace_xen_ram_alloc(ram_addr, size);
  216: 
  217:     nr_pfn = size >> TARGET_PAGE_BITS;
  218:     pfn_list = g_malloc(sizeof (*pfn_list) * nr_pfn);
  219: 
  220:     for (i = 0; i < nr_pfn; i++) {
  221:         pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
  222:     }
  223: 
  224:     if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
  225:         hw_error("xen: failed to populate ram at " RAM_ADDR_FMT, ram_addr);
  226:     }
  227: 
  228:     g_free(pfn_list);
  229: }
  230: 
  231: static XenPhysmap *get_physmapping(XenIOState *state,
  232:                                    target_phys_addr_t start_addr, ram_addr_t size)
  233: {
  234:     XenPhysmap *physmap = NULL;
  235: 
  236:     start_addr &= TARGET_PAGE_MASK;
  237: 
  238:     QLIST_FOREACH(physmap, &state->physmap, list) {
  239:         if (range_covers_byte(physmap->start_addr, physmap->size, start_addr)) {
  240:             return physmap;
  241:         }
  242:     }
  243:     return NULL;
  244: }
  245: 
  246: static target_phys_addr_t xen_phys_offset_to_gaddr(target_phys_addr_t start_addr,
  247:                                                    ram_addr_t size, void *opaque)
  248: {
  249:     target_phys_addr_t addr = start_addr & TARGET_PAGE_MASK;
  250:     XenIOState *xen_io_state = opaque;
  251:     XenPhysmap *physmap = NULL;
  252: 
  253:     QLIST_FOREACH(physmap, &xen_io_state->physmap, list) {
  254:         if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) {
  255:             return physmap->start_addr;
  256:         }
  257:     }
  258: 
  259:     return start_addr;
  260: }
  261: 
  262: #if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340
  263: static int xen_add_to_physmap(XenIOState *state,
  264:                               target_phys_addr_t start_addr,
  265:                               ram_addr_t size,
  266:                               MemoryRegion *mr,
  267:                               target_phys_addr_t offset_within_region)
  268: {
  269:     unsigned long i = 0;
  270:     int rc = 0;
  271:     XenPhysmap *physmap = NULL;
  272:     target_phys_addr_t pfn, start_gpfn;
  273:     target_phys_addr_t phys_offset = memory_region_get_ram_addr(mr);
  274:     char path[80], value[17];
  275: 
  276:     if (get_physmapping(state, start_addr, size)) {
  277:         return 0;
  278:     }
  279:     if (size <= 0) {
  280:         return -1;
  281:     }
  282: 
  283:     /* Xen can only handle a single dirty log region for now and we want
  284:      * the linear framebuffer to be that region.
  285:      * Avoid tracking any regions that is not videoram and avoid tracking
  286:      * the legacy vga region. */
  287:     if (mr == framebuffer && start_addr > 0xbffff) {
  288:         goto go_physmap;
  289:     }
  290:     return -1;
  291: 
  292: go_physmap:
  293:     DPRINTF("mapping vram to %llx - %llx\n", start_addr, start_addr + size);
  294: 
  295:     pfn = phys_offset >> TARGET_PAGE_BITS;
  296:     start_gpfn = start_addr >> TARGET_PAGE_BITS;
  297:     for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
  298:         unsigned long idx = pfn + i;
  299:         xen_pfn_t gpfn = start_gpfn + i;
  300: 
  301:         rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn);
  302:         if (rc) {
  303:             DPRINTF("add_to_physmap MFN %"PRI_xen_pfn" to PFN %"
  304:                     PRI_xen_pfn" failed: %d\n", idx, gpfn, rc);
  305:             return -rc;
  306:         }
  307:     }
  308: 
  309:     physmap = g_malloc(sizeof (XenPhysmap));
  310: 
  311:     physmap->start_addr = start_addr;
  312:     physmap->size = size;
  313:     physmap->name = (char *)mr->name;
  314:     physmap->phys_offset = phys_offset;
  315: 
  316:     QLIST_INSERT_HEAD(&state->physmap, physmap, list);
  317: 
  318:     xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
  319:                                    start_addr >> TARGET_PAGE_BITS,
  320:                                    (start_addr + size) >> TARGET_PAGE_BITS,
  321:                                    XEN_DOMCTL_MEM_CACHEATTR_WB);
  322: 
  323:     snprintf(path, sizeof(path),
  324:             "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
  325:             xen_domid, (uint64_t)phys_offset);
  326:     snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
  327:     if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
  328:         return -1;
  329:     }
  330:     snprintf(path, sizeof(path),
  331:             "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
  332:             xen_domid, (uint64_t)phys_offset);
  333:     snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
  334:     if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
  335:         return -1;
  336:     }
  337:     if (mr->name) {
  338:         snprintf(path, sizeof(path),
  339:                 "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
  340:                 xen_domid, (uint64_t)phys_offset);
  341:         if (!xs_write(state->xenstore, 0, path, mr->name, strlen(mr->name))) {
  342:             return -1;
  343:         }
  344:     }
  345: 
  346:     return 0;
  347: }
  348: 
  349: static int xen_remove_from_physmap(XenIOState *state,
  350:                                    target_phys_addr_t start_addr,
  351:                                    ram_addr_t size)
  352: {
  353:     unsigned long i = 0;
  354:     int rc = 0;
  355:     XenPhysmap *physmap = NULL;
  356:     target_phys_addr_t phys_offset = 0;
  357: 
  358:     physmap = get_physmapping(state, start_addr, size);
  359:     if (physmap == NULL) {
  360:         return -1;
  361:     }
  362: 
  363:     phys_offset = physmap->phys_offset;
  364:     size = physmap->size;
  365: 
  366:     DPRINTF("unmapping vram to %llx - %llx, from %llx\n",
  367:             phys_offset, phys_offset + size, start_addr);
  368: 
  369:     size >>= TARGET_PAGE_BITS;
  370:     start_addr >>= TARGET_PAGE_BITS;
  371:     phys_offset >>= TARGET_PAGE_BITS;
  372:     for (i = 0; i < size; i++) {
  373:         unsigned long idx = start_addr + i;
  374:         xen_pfn_t gpfn = phys_offset + i;
  375: 
  376:         rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn);
  377:         if (rc) {
  378:             fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"
  379:                     PRI_xen_pfn" failed: %d\n", idx, gpfn, rc);
  380:             return -rc;
  381:         }
  382:     }
  383: 
  384:     QLIST_REMOVE(physmap, list);
  385:     if (state->log_for_dirtybit == physmap) {
  386:         state->log_for_dirtybit = NULL;
  387:     }
  388:     free(physmap);
  389: 
  390:     return 0;
  391: }
  392: 
  393: #else
  394: static int xen_add_to_physmap(XenIOState *state,
  395:                               target_phys_addr_t start_addr,
  396:                               ram_addr_t size,
  397:                               MemoryRegion *mr,
  398:                               target_phys_addr_t offset_within_region)
  399: {
  400:     return -ENOSYS;
  401: }
  402: 
  403: static int xen_remove_from_physmap(XenIOState *state,
  404:                                    target_phys_addr_t start_addr,
  405:                                    ram_addr_t size)
  406: {
  407:     return -ENOSYS;
  408: }
  409: #endif
  410: 
  411: static void xen_set_memory(struct MemoryListener *listener,
  412:                            MemoryRegionSection *section,
  413:                            bool add)
  414: {
  415:     XenIOState *state = container_of(listener, XenIOState, memory_listener);
  416:     target_phys_addr_t start_addr = section->offset_within_address_space;
  417:     ram_addr_t size = section->size;
  418:     bool log_dirty = memory_region_is_logging(section->mr);
  419:     hvmmem_type_t mem_type;
  420: 
  421:     if (!memory_region_is_ram(section->mr)) {
  422:         return;
  423:     }
  424: 
  425:     if (!(section->mr != &ram_memory
  426:           && ( (log_dirty && add) || (!log_dirty && !add)))) {
  427:         return;
  428:     }
  429: 
  430:     trace_xen_client_set_memory(start_addr, size, log_dirty);
  431: 
  432:     start_addr &= TARGET_PAGE_MASK;
  433:     size = TARGET_PAGE_ALIGN(size);
  434: 
  435:     if (add) {
  436:         if (!memory_region_is_rom(section->mr)) {
  437:             xen_add_to_physmap(state, start_addr, size,
  438:                                section->mr, section->offset_within_region);
  439:         } else {
  440:             mem_type = HVMMEM_ram_ro;
  441:             if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type,
  442:                                     start_addr >> TARGET_PAGE_BITS,
  443:                                     size >> TARGET_PAGE_BITS)) {
  444:                 DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n",
  445:                         start_addr);
  446:             }
  447:         }
  448:     } else {
  449:         if (xen_remove_from_physmap(state, start_addr, size) < 0) {
  450:             DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr);
  451:         }
  452:     }
  453: }
  454: 
  455: static void xen_begin(MemoryListener *listener)
  456: {
  457: }
  458: 
  459: static void xen_commit(MemoryListener *listener)
  460: {
  461: }
  462: 
  463: static void xen_region_add(MemoryListener *listener,
  464:                            MemoryRegionSection *section)
  465: {
  466:     xen_set_memory(listener, section, true);
  467: }
  468: 
  469: static void xen_region_del(MemoryListener *listener,
  470:                            MemoryRegionSection *section)
  471: {
  472:     xen_set_memory(listener, section, false);
  473: }
  474: 
  475: static void xen_region_nop(MemoryListener *listener,
  476:                            MemoryRegionSection *section)
  477: {
  478: }
  479: 
  480: static void xen_sync_dirty_bitmap(XenIOState *state,
  481:                                   target_phys_addr_t start_addr,
  482:                                   ram_addr_t size)
  483: {
  484:     target_phys_addr_t npages = size >> TARGET_PAGE_BITS;
  485:     const int width = sizeof(unsigned long) * 8;
  486:     unsigned long bitmap[(npages + width - 1) / width];
  487:     int rc, i, j;
  488:     const XenPhysmap *physmap = NULL;
  489: 
  490:     physmap = get_physmapping(state, start_addr, size);
  491:     if (physmap == NULL) {
  492:         /* not handled */
  493:         return;
  494:     }
  495: 
  496:     if (state->log_for_dirtybit == NULL) {
  497:         state->log_for_dirtybit = physmap;
  498:     } else if (state->log_for_dirtybit != physmap) {
  499:         /* Only one range for dirty bitmap can be tracked. */
  500:         return;
  501:     }
  502: 
  503:     rc = xc_hvm_track_dirty_vram(xen_xc, xen_domid,
  504:                                  start_addr >> TARGET_PAGE_BITS, npages,
  505:                                  bitmap);
  506:     if (rc < 0) {
  507:         if (rc != -ENODATA) {
  508:             fprintf(stderr, "xen: track_dirty_vram failed (0x" TARGET_FMT_plx
  509:                     ", 0x" TARGET_FMT_plx "): %s\n",
  510:                     start_addr, start_addr + size, strerror(-rc));
  511:         }
  512:         return;
  513:     }
  514: 
  515:     for (i = 0; i < ARRAY_SIZE(bitmap); i++) {
  516:         unsigned long map = bitmap[i];
  517:         while (map != 0) {
  518:             j = ffsl(map) - 1;
  519:             map &= ~(1ul << j);
  520:             memory_region_set_dirty(framebuffer,
  521:                                     (i * width + j) * TARGET_PAGE_SIZE,
  522:                                     TARGET_PAGE_SIZE);
  523:         };
  524:     }
  525: }
  526: 
  527: static void xen_log_start(MemoryListener *listener,
  528:                           MemoryRegionSection *section)
  529: {
  530:     XenIOState *state = container_of(listener, XenIOState, memory_listener);
  531: 
  532:     xen_sync_dirty_bitmap(state, section->offset_within_address_space,
  533:                           section->size);
  534: }
  535: 
  536: static void xen_log_stop(MemoryListener *listener, MemoryRegionSection *section)
  537: {
  538:     XenIOState *state = container_of(listener, XenIOState, memory_listener);
  539: 
  540:     state->log_for_dirtybit = NULL;
  541:     /* Disable dirty bit tracking */
  542:     xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
  543: }
  544: 
  545: static void xen_log_sync(MemoryListener *listener, MemoryRegionSection *section)
  546: {
  547:     XenIOState *state = container_of(listener, XenIOState, memory_listener);
  548: 
  549:     xen_sync_dirty_bitmap(state, section->offset_within_address_space,
  550:                           section->size);
  551: }
  552: 
  553: static void xen_log_global_start(MemoryListener *listener)
  554: {
  555: }
  556: 
  557: static void xen_log_global_stop(MemoryListener *listener)
  558: {
  559: }
  560: 
  561: static void xen_eventfd_add(MemoryListener *listener,
  562:                             MemoryRegionSection *section,
  563:                             bool match_data, uint64_t data, int fd)
  564: {
  565: }
  566: 
  567: static void xen_eventfd_del(MemoryListener *listener,
  568:                             MemoryRegionSection *section,
  569:                             bool match_data, uint64_t data, int fd)
  570: {
  571: }
  572: 
  573: static MemoryListener xen_memory_listener = {
  574:     .begin = xen_begin,
  575:     .commit = xen_commit,
  576:     .region_add = xen_region_add,
  577:     .region_del = xen_region_del,
  578:     .region_nop = xen_region_nop,
  579:     .log_start = xen_log_start,
  580:     .log_stop = xen_log_stop,
  581:     .log_sync = xen_log_sync,
  582:     .log_global_start = xen_log_global_start,
  583:     .log_global_stop = xen_log_global_stop,
  584:     .eventfd_add = xen_eventfd_add,
  585:     .eventfd_del = xen_eventfd_del,
  586:     .priority = 10,
  587: };
  588: 
  589: /* VCPU Operations, MMIO, IO ring ... */
  590: 
  591: static void xen_reset_vcpu(void *opaque)
  592: {
  593:     CPUArchState *env = opaque;
  594: 
  595:     env->halted = 1;
  596: }
  597: 
  598: void xen_vcpu_init(void)
  599: {
  600:     CPUArchState *first_cpu;
  601: 
  602:     if ((first_cpu = qemu_get_cpu(0))) {
  603:         qemu_register_reset(xen_reset_vcpu, first_cpu);
  604:         xen_reset_vcpu(first_cpu);
  605:     }
  606:     /* if rtc_clock is left to default (host_clock), disable it */
  607:     if (rtc_clock == host_clock) {
  608:         qemu_clock_enable(rtc_clock, false);
  609:     }
  610: }
  611: 
  612: /* get the ioreq packets from share mem */
  613: static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
  614: {
  615:     ioreq_t *req = xen_vcpu_ioreq(state->shared_page, vcpu);
  616: 
  617:     if (req->state != STATE_IOREQ_READY) {
  618:         DPRINTF("I/O request not ready: "
  619:                 "%x, ptr: %x, port: %"PRIx64", "
  620:                 "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
  621:                 req->state, req->data_is_ptr, req->addr,
  622:                 req->data, req->count, req->size);
  623:         return NULL;
  624:     }
  625: 
  626:     xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
  627: 
  628:     req->state = STATE_IOREQ_INPROCESS;
  629:     return req;
  630: }
  631: 
  632: /* use poll to get the port notification */
  633: /* ioreq_vec--out,the */
  634: /* retval--the number of ioreq packet */
  635: static ioreq_t *cpu_get_ioreq(XenIOState *state)
  636: {
  637:     int i;
  638:     evtchn_port_t port;
  639: 
  640:     port = xc_evtchn_pending(state->xce_handle);
  641:     if (port == state->bufioreq_local_port) {
  642:         qemu_mod_timer(state->buffered_io_timer,
  643:                 BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
  644:         return NULL;
  645:     }
  646: 
  647:     if (port != -1) {
  648:         for (i = 0; i < smp_cpus; i++) {
  649:             if (state->ioreq_local_port[i] == port) {
  650:                 break;
  651:             }
  652:         }
  653: 
  654:         if (i == smp_cpus) {
  655:             hw_error("Fatal error while trying to get io event!\n");
  656:         }
  657: 
  658:         /* unmask the wanted port again */
  659:         xc_evtchn_unmask(state->xce_handle, port);
  660: 
  661:         /* get the io packet from shared memory */
  662:         state->send_vcpu = i;
  663:         return cpu_get_ioreq_from_shared_memory(state, i);
  664:     }
  665: 
  666:     /* read error or read nothing */
  667:     return NULL;
  668: }
  669: 
  670: static uint32_t do_inp(pio_addr_t addr, unsigned long size)
  671: {
  672:     switch (size) {
  673:         case 1:
  674:             return cpu_inb(addr);
  675:         case 2:
  676:             return cpu_inw(addr);
  677:         case 4:
  678:             return cpu_inl(addr);
  679:         default:
  680:             hw_error("inp: bad size: %04"FMT_pioaddr" %lx", addr, size);
  681:     }
  682: }
  683: 
  684: static void do_outp(pio_addr_t addr,
  685:         unsigned long size, uint32_t val)
  686: {
  687:     switch (size) {
  688:         case 1:
  689:             return cpu_outb(addr, val);
  690:         case 2:
  691:             return cpu_outw(addr, val);
  692:         case 4:
  693:             return cpu_outl(addr, val);
  694:         default:
  695:             hw_error("outp: bad size: %04"FMT_pioaddr" %lx", addr, size);
  696:     }
  697: }
  698: 
  699: static void cpu_ioreq_pio(ioreq_t *req)
  700: {
  701:     int i, sign;
  702: 
  703:     sign = req->df ? -1 : 1;
  704: 
  705:     if (req->dir == IOREQ_READ) {
  706:         if (!req->data_is_ptr) {
  707:             req->data = do_inp(req->addr, req->size);
  708:         } else {
  709:             uint32_t tmp;
  710: 
  711:             for (i = 0; i < req->count; i++) {
  712:                 tmp = do_inp(req->addr, req->size);
  713:                 cpu_physical_memory_write(req->data + (sign * i * req->size),
  714:                         (uint8_t *) &tmp, req->size);
  715:             }
  716:         }
  717:     } else if (req->dir == IOREQ_WRITE) {
  718:         if (!req->data_is_ptr) {
  719:             do_outp(req->addr, req->size, req->data);
  720:         } else {
  721:             for (i = 0; i < req->count; i++) {
  722:                 uint32_t tmp = 0;
  723: 
  724:                 cpu_physical_memory_read(req->data + (sign * i * req->size),
  725:                         (uint8_t*) &tmp, req->size);
  726:                 do_outp(req->addr, req->size, tmp);
  727:             }
  728:         }
  729:     }
  730: }
  731: 
  732: static void cpu_ioreq_move(ioreq_t *req)
  733: {
  734:     int i, sign;
  735: 
  736:     sign = req->df ? -1 : 1;
  737: 
  738:     if (!req->data_is_ptr) {
  739:         if (req->dir == IOREQ_READ) {
  740:             for (i = 0; i < req->count; i++) {
  741:                 cpu_physical_memory_read(req->addr + (sign * i * req->size),
  742:                         (uint8_t *) &req->data, req->size);
  743:             }
  744:         } else if (req->dir == IOREQ_WRITE) {
  745:             for (i = 0; i < req->count; i++) {
  746:                 cpu_physical_memory_write(req->addr + (sign * i * req->size),
  747:                         (uint8_t *) &req->data, req->size);
  748:             }
  749:         }
  750:     } else {
  751:         uint64_t tmp;
  752: 
  753:         if (req->dir == IOREQ_READ) {
  754:             for (i = 0; i < req->count; i++) {
  755:                 cpu_physical_memory_read(req->addr + (sign * i * req->size),
  756:                         (uint8_t*) &tmp, req->size);
  757:                 cpu_physical_memory_write(req->data + (sign * i * req->size),
  758:                         (uint8_t*) &tmp, req->size);
  759:             }
  760:         } else if (req->dir == IOREQ_WRITE) {
  761:             for (i = 0; i < req->count; i++) {
  762:                 cpu_physical_memory_read(req->data + (sign * i * req->size),
  763:                         (uint8_t*) &tmp, req->size);
  764:                 cpu_physical_memory_write(req->addr + (sign * i * req->size),
  765:                         (uint8_t*) &tmp, req->size);
  766:             }
  767:         }
  768:     }
  769: }
  770: 
  771: static void handle_ioreq(ioreq_t *req)
  772: {
  773:     if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
  774:             (req->size < sizeof (target_ulong))) {
  775:         req->data &= ((target_ulong) 1 << (8 * req->size)) - 1;
  776:     }
  777: 
  778:     switch (req->type) {
  779:         case IOREQ_TYPE_PIO:
  780:             cpu_ioreq_pio(req);
  781:             break;
  782:         case IOREQ_TYPE_COPY:
  783:             cpu_ioreq_move(req);
  784:             break;
  785:         case IOREQ_TYPE_TIMEOFFSET:
  786:             break;
  787:         case IOREQ_TYPE_INVALIDATE:
  788:             xen_invalidate_map_cache();
  789:             break;
  790:         default:
  791:             hw_error("Invalid ioreq type 0x%x\n", req->type);
  792:     }
  793: }
  794: 
  795: static int handle_buffered_iopage(XenIOState *state)
  796: {
  797:     buf_ioreq_t *buf_req = NULL;
  798:     ioreq_t req;
  799:     int qw;
  800: 
  801:     if (!state->buffered_io_page) {
  802:         return 0;
  803:     }
  804: 
  805:     memset(&req, 0x00, sizeof(req));
  806: 
  807:     while (state->buffered_io_page->read_pointer != state->buffered_io_page->write_pointer) {
  808:         buf_req = &state->buffered_io_page->buf_ioreq[
  809:             state->buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM];
  810:         req.size = 1UL << buf_req->size;
  811:         req.count = 1;
  812:         req.addr = buf_req->addr;
  813:         req.data = buf_req->data;
  814:         req.state = STATE_IOREQ_READY;
  815:         req.dir = buf_req->dir;
  816:         req.df = 1;
  817:         req.type = buf_req->type;
  818:         req.data_is_ptr = 0;
  819:         qw = (req.size == 8);
  820:         if (qw) {
  821:             buf_req = &state->buffered_io_page->buf_ioreq[
  822:                 (state->buffered_io_page->read_pointer + 1) % IOREQ_BUFFER_SLOT_NUM];
  823:             req.data |= ((uint64_t)buf_req->data) << 32;
  824:         }
  825: 
  826:         handle_ioreq(&req);
  827: 
  828:         xen_mb();
  829:         state->buffered_io_page->read_pointer += qw ? 2 : 1;
  830:     }
  831: 
  832:     return req.count;
  833: }
  834: 
  835: static void handle_buffered_io(void *opaque)
  836: {
  837:     XenIOState *state = opaque;
  838: 
  839:     if (handle_buffered_iopage(state)) {
  840:         qemu_mod_timer(state->buffered_io_timer,
  841:                 BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
  842:     } else {
  843:         qemu_del_timer(state->buffered_io_timer);
  844:         xc_evtchn_unmask(state->xce_handle, state->bufioreq_local_port);
  845:     }
  846: }
  847: 
  848: static void cpu_handle_ioreq(void *opaque)
  849: {
  850:     XenIOState *state = opaque;
  851:     ioreq_t *req = cpu_get_ioreq(state);
  852: 
  853:     handle_buffered_iopage(state);
  854:     if (req) {
  855:         handle_ioreq(req);
  856: 
  857:         if (req->state != STATE_IOREQ_INPROCESS) {
  858:             fprintf(stderr, "Badness in I/O request ... not in service?!: "
  859:                     "%x, ptr: %x, port: %"PRIx64", "
  860:                     "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
  861:                     req->state, req->data_is_ptr, req->addr,
  862:                     req->data, req->count, req->size);
  863:             destroy_hvm_domain(false);
  864:             return;
  865:         }
  866: 
  867:         xen_wmb(); /* Update ioreq contents /then/ update state. */
  868: 
  869:         /*
  870:          * We do this before we send the response so that the tools
  871:          * have the opportunity to pick up on the reset before the
  872:          * guest resumes and does a hlt with interrupts disabled which
  873:          * causes Xen to powerdown the domain.
  874:          */
  875:         if (runstate_is_running()) {
  876:             if (qemu_shutdown_requested_get()) {
  877:                 destroy_hvm_domain(false);
  878:             }
  879:             if (qemu_reset_requested_get()) {
  880:                 qemu_system_reset(VMRESET_REPORT);
  881:                 destroy_hvm_domain(true);
  882:             }
  883:         }
  884: 
  885:         req->state = STATE_IORESP_READY;
  886:         xc_evtchn_notify(state->xce_handle, state->ioreq_local_port[state->send_vcpu]);
  887:     }
  888: }
  889: 
  890: static int store_dev_info(int domid, CharDriverState *cs, const char *string)
  891: {
  892:     struct xs_handle *xs = NULL;
  893:     char *path = NULL;
  894:     char *newpath = NULL;
  895:     char *pts = NULL;
  896:     int ret = -1;
  897: 
  898:     /* Only continue if we're talking to a pty. */
  899:     if (strncmp(cs->filename, "pty:", 4)) {
  900:         return 0;
  901:     }
  902:     pts = cs->filename + 4;
  903: 
  904:     /* We now have everything we need to set the xenstore entry. */
  905:     xs = xs_open(0);
  906:     if (xs == NULL) {
  907:         fprintf(stderr, "Could not contact XenStore\n");
  908:         goto out;
  909:     }
  910: 
  911:     path = xs_get_domain_path(xs, domid);
  912:     if (path == NULL) {
  913:         fprintf(stderr, "xs_get_domain_path() error\n");
  914:         goto out;
  915:     }
  916:     newpath = realloc(path, (strlen(path) + strlen(string) +
  917:                 strlen("/tty") + 1));
  918:     if (newpath == NULL) {
  919:         fprintf(stderr, "realloc error\n");
  920:         goto out;
  921:     }
  922:     path = newpath;
  923: 
  924:     strcat(path, string);
  925:     strcat(path, "/tty");
  926:     if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
  927:         fprintf(stderr, "xs_write for '%s' fail", string);
  928:         goto out;
  929:     }
  930:     ret = 0;
  931: 
  932: out:
  933:     free(path);
  934:     xs_close(xs);
  935: 
  936:     return ret;
  937: }
  938: 
  939: void xenstore_store_pv_console_info(int i, CharDriverState *chr)
  940: {
  941:     if (i == 0) {
  942:         store_dev_info(xen_domid, chr, "/console");
  943:     } else {
  944:         char buf[32];
  945:         snprintf(buf, sizeof(buf), "/device/console/%d", i);
  946:         store_dev_info(xen_domid, chr, buf);
  947:     }
  948: }
  949: 
  950: static void xenstore_record_dm_state(struct xs_handle *xs, const char *state)
  951: {
  952:     char path[50];
  953: 
  954:     if (xs == NULL) {
  955:         fprintf(stderr, "xenstore connection not initialized\n");
  956:         exit(1);
  957:     }
  958: 
  959:     snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", xen_domid);
  960:     if (!xs_write(xs, XBT_NULL, path, state, strlen(state))) {
  961:         fprintf(stderr, "error recording dm state\n");
  962:         exit(1);
  963:     }
  964: }
  965: 
  966: static void xen_main_loop_prepare(XenIOState *state)
  967: {
  968:     int evtchn_fd = -1;
  969: 
  970:     if (state->xce_handle != XC_HANDLER_INITIAL_VALUE) {
  971:         evtchn_fd = xc_evtchn_fd(state->xce_handle);
  972:     }
  973: 
  974:     state->buffered_io_timer = qemu_new_timer_ms(rt_clock, handle_buffered_io,
  975:                                                  state);
  976: 
  977:     if (evtchn_fd != -1) {
  978:         qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
  979:     }
  980: }
  981: 
  982: 
  983: /* Initialise Xen */
  984: 
  985: static void xen_change_state_handler(void *opaque, int running,
  986:                                      RunState state)
  987: {
  988:     if (running) {
  989:         /* record state running */
  990:         xenstore_record_dm_state(xenstore, "running");
  991:     }
  992: }
  993: 
  994: static void xen_hvm_change_state_handler(void *opaque, int running,
  995:                                          RunState rstate)
  996: {
  997:     XenIOState *xstate = opaque;
  998:     if (running) {
  999:         xen_main_loop_prepare(xstate);
 1000:     }
 1001: }
 1002: 
 1003: static void xen_exit_notifier(Notifier *n, void *data)
 1004: {
 1005:     XenIOState *state = container_of(n, XenIOState, exit);
 1006: 
 1007:     xc_evtchn_close(state->xce_handle);
 1008:     xs_daemon_close(state->xenstore);
 1009: }
 1010: 
 1011: int xen_init(void)
 1012: {
 1013:     xen_xc = xen_xc_interface_open(0, 0, 0);
 1014:     if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
 1015:         xen_be_printf(NULL, 0, "can't open xen interface\n");
 1016:         return -1;
 1017:     }
 1018:     qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
 1019: 
 1020:     return 0;
 1021: }
 1022: 
 1023: static void xen_read_physmap(XenIOState *state)
 1024: {
 1025:     XenPhysmap *physmap = NULL;
 1026:     unsigned int len, num, i;
 1027:     char path[80], *value = NULL;
 1028:     char **entries = NULL;
 1029: 
 1030:     snprintf(path, sizeof(path),
 1031:             "/local/domain/0/device-model/%d/physmap", xen_domid);
 1032:     entries = xs_directory(state->xenstore, 0, path, &num);
 1033:     if (entries == NULL)
 1034:         return;
 1035: 
 1036:     for (i = 0; i < num; i++) {
 1037:         physmap = g_malloc(sizeof (XenPhysmap));
 1038:         physmap->phys_offset = strtoull(entries[i], NULL, 16);
 1039:         snprintf(path, sizeof(path),
 1040:                 "/local/domain/0/device-model/%d/physmap/%s/start_addr",
 1041:                 xen_domid, entries[i]);
 1042:         value = xs_read(state->xenstore, 0, path, &len);
 1043:         if (value == NULL) {
 1044:             free(physmap);
 1045:             continue;
 1046:         }
 1047:         physmap->start_addr = strtoull(value, NULL, 16);
 1048:         free(value);
 1049: 
 1050:         snprintf(path, sizeof(path),
 1051:                 "/local/domain/0/device-model/%d/physmap/%s/size",
 1052:                 xen_domid, entries[i]);
 1053:         value = xs_read(state->xenstore, 0, path, &len);
 1054:         if (value == NULL) {
 1055:             free(physmap);
 1056:             continue;
 1057:         }
 1058:         physmap->size = strtoull(value, NULL, 16);
 1059:         free(value);
 1060: 
 1061:         snprintf(path, sizeof(path),
 1062:                 "/local/domain/0/device-model/%d/physmap/%s/name",
 1063:                 xen_domid, entries[i]);
 1064:         physmap->name = xs_read(state->xenstore, 0, path, &len);
 1065: 
 1066:         QLIST_INSERT_HEAD(&state->physmap, physmap, list);
 1067:     }
 1068:     free(entries);
 1069:     return;
 1070: }
 1071: 
 1072: int xen_hvm_init(void)
 1073: {
 1074:     int i, rc;
 1075:     unsigned long ioreq_pfn;
 1076:     unsigned long bufioreq_evtchn;
 1077:     XenIOState *state;
 1078: 
 1079:     state = g_malloc0(sizeof (XenIOState));
 1080: 
 1081:     state->xce_handle = xen_xc_evtchn_open(NULL, 0);
 1082:     if (state->xce_handle == XC_HANDLER_INITIAL_VALUE) {
 1083:         perror("xen: event channel open");
 1084:         return -errno;
 1085:     }
 1086: 
 1087:     state->xenstore = xs_daemon_open();
 1088:     if (state->xenstore == NULL) {
 1089:         perror("xen: xenstore open");
 1090:         return -errno;
 1091:     }
 1092: 
 1093:     state->exit.notify = xen_exit_notifier;
 1094:     qemu_add_exit_notifier(&state->exit);
 1095: 
 1096:     state->suspend.notify = xen_suspend_notifier;
 1097:     qemu_register_suspend_notifier(&state->suspend);
 1098: 
 1099:     xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
 1100:     DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
 1101:     state->shared_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
 1102:                                               PROT_READ|PROT_WRITE, ioreq_pfn);
 1103:     if (state->shared_page == NULL) {
 1104:         hw_error("map shared IO page returned error %d handle=" XC_INTERFACE_FMT,
 1105:                  errno, xen_xc);
 1106:     }
 1107: 
 1108:     xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
 1109:     DPRINTF("buffered io page at pfn %lx\n", ioreq_pfn);
 1110:     state->buffered_io_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,
 1111:                                                    PROT_READ|PROT_WRITE, ioreq_pfn);
 1112:     if (state->buffered_io_page == NULL) {
 1113:         hw_error("map buffered IO page returned error %d", errno);
 1114:     }
 1115: 
 1116:     state->ioreq_local_port = g_malloc0(smp_cpus * sizeof (evtchn_port_t));
 1117: 
 1118:     /* FIXME: how about if we overflow the page here? */
 1119:     for (i = 0; i < smp_cpus; i++) {
 1120:         rc = xc_evtchn_bind_interdomain(state->xce_handle, xen_domid,
 1121:                                         xen_vcpu_eport(state->shared_page, i));
 1122:         if (rc == -1) {
 1123:             fprintf(stderr, "bind interdomain ioctl error %d\n", errno);
 1124:             return -1;
 1125:         }
 1126:         state->ioreq_local_port[i] = rc;
 1127:     }
 1128: 
 1129:     rc = xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_BUFIOREQ_EVTCHN,
 1130:             &bufioreq_evtchn);
 1131:     if (rc < 0) {
 1132:         fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN\n");
 1133:         return -1;
 1134:     }
 1135:     rc = xc_evtchn_bind_interdomain(state->xce_handle, xen_domid,
 1136:             (uint32_t)bufioreq_evtchn);
 1137:     if (rc == -1) {
 1138:         fprintf(stderr, "bind interdomain ioctl error %d\n", errno);
 1139:         return -1;
 1140:     }
 1141:     state->bufioreq_local_port = rc;
 1142: 
 1143:     /* Init RAM management */
 1144:     xen_map_cache_init(xen_phys_offset_to_gaddr, state);
 1145:     xen_ram_init(ram_size);
 1146: 
 1147:     qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
 1148: 
 1149:     state->memory_listener = xen_memory_listener;
 1150:     QLIST_INIT(&state->physmap);
 1151:     memory_listener_register(&state->memory_listener, get_system_memory());
 1152:     state->log_for_dirtybit = NULL;
 1153: 
 1154:     /* Initialize backend core & drivers */
 1155:     if (xen_be_init() != 0) {
 1156:         fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__);
 1157:         exit(1);
 1158:     }
 1159:     xen_be_register("console", &xen_console_ops);
 1160:     xen_be_register("vkbd", &xen_kbdmouse_ops);
 1161:     xen_be_register("qdisk", &xen_blkdev_ops);
 1162:     xen_read_physmap(state);
 1163: 
 1164:     return 0;
 1165: }
 1166: 
 1167: void destroy_hvm_domain(bool reboot)
 1168: {
 1169:     XenXC xc_handle;
 1170:     int sts;
 1171: 
 1172:     xc_handle = xen_xc_interface_open(0, 0, 0);
 1173:     if (xc_handle == XC_HANDLER_INITIAL_VALUE) {
 1174:         fprintf(stderr, "Cannot acquire xenctrl handle\n");
 1175:     } else {
 1176:         sts = xc_domain_shutdown(xc_handle, xen_domid,
 1177:                                  reboot ? SHUTDOWN_reboot : SHUTDOWN_poweroff);
 1178:         if (sts != 0) {
 1179:             fprintf(stderr, "xc_domain_shutdown failed to issue %s, "
 1180:                     "sts %d, %s\n", reboot ? "reboot" : "poweroff",
 1181:                     sts, strerror(errno));
 1182:         } else {
 1183:             fprintf(stderr, "Issued domain %d %s\n", xen_domid,
 1184:                     reboot ? "reboot" : "poweroff");
 1185:         }
 1186:         xc_interface_close(xc_handle);
 1187:     }
 1188: }
 1189: 
 1190: void xen_register_framebuffer(MemoryRegion *mr)
 1191: {
 1192:     framebuffer = mr;
 1193: }

unix.superglobalmegacorp.com