1
2
3
4
5
6
7
8
9
10
11#include "qemu/osdep.h"
12#include "qemu/units.h"
13#include "qapi/error.h"
14#include "qapi/qapi-commands-migration.h"
15#include "trace.h"
16
17#include "hw/i386/pc.h"
18#include "hw/irq.h"
19#include "hw/i386/apic-msidef.h"
20#include "hw/xen/xen-x86.h"
21#include "qemu/range.h"
22
23#include "hw/xen/xen-hvm-common.h"
24#include "hw/xen/arch_hvm.h"
25#include <xen/hvm/e820.h>
26
27static MemoryRegion ram_640k, ram_lo, ram_hi;
28static MemoryRegion *framebuffer;
29static bool xen_in_migration;
30
31
32
33
34
35
36
37
38
39#ifndef IOREQ_TYPE_VMWARE_PORT
40#define IOREQ_TYPE_VMWARE_PORT 3
41struct vmware_regs {
42 uint32_t esi;
43 uint32_t edi;
44 uint32_t ebx;
45 uint32_t ecx;
46 uint32_t edx;
47};
48typedef struct vmware_regs vmware_regs_t;
49
50struct shared_vmport_iopage {
51 struct vmware_regs vcpu_vmport_regs[1];
52};
53typedef struct shared_vmport_iopage shared_vmport_iopage_t;
54#endif
55
56static shared_vmport_iopage_t *shared_vmport_page;
57
58static QLIST_HEAD(, XenPhysmap) xen_physmap;
59static const XenPhysmap *log_for_dirtybit;
60
61static unsigned long *dirty_bitmap;
62static Notifier suspend;
63static Notifier wakeup;
64
65
66
67int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
68{
69 return irq_num + (PCI_SLOT(pci_dev->devfn) << 2);
70}
71
72void xen_intx_set_irq(void *opaque, int irq_num, int level)
73{
74 xen_set_pci_intx_level(xen_domid, 0, 0, irq_num >> 2,
75 irq_num & 3, level);
76}
77
78int xen_set_pci_link_route(uint8_t link, uint8_t irq)
79{
80 return xendevicemodel_set_pci_link_route(xen_dmod, xen_domid, link, irq);
81}
82
83int xen_is_pirq_msi(uint32_t msi_data)
84{
85
86
87
88 return ((msi_data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT) == 0;
89}
90
91void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
92{
93 xen_inject_msi(xen_domid, addr, data);
94}
95
96static void xen_suspend_notifier(Notifier *notifier, void *data)
97{
98 xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3);
99}
100
101
102
103static void xen_set_irq(void *opaque, int irq, int level)
104{
105 xen_set_isa_irq_level(xen_domid, irq, level);
106}
107
108qemu_irq *xen_interrupt_controller_init(void)
109{
110 return qemu_allocate_irqs(xen_set_irq, NULL, 16);
111}
112
113
114
115static void xen_ram_init(PCMachineState *pcms,
116 ram_addr_t ram_size, MemoryRegion **ram_memory_p)
117{
118 X86MachineState *x86ms = X86_MACHINE(pcms);
119 MemoryRegion *sysmem = get_system_memory();
120 ram_addr_t block_len;
121 uint64_t user_lowmem =
122 object_property_get_uint(qdev_get_machine(),
123 PC_MACHINE_MAX_RAM_BELOW_4G,
124 &error_abort);
125
126
127
128
129 if (!user_lowmem) {
130 user_lowmem = HVM_BELOW_4G_RAM_END;
131 }
132 if (HVM_BELOW_4G_RAM_END <= user_lowmem) {
133 user_lowmem = HVM_BELOW_4G_RAM_END;
134 }
135
136 if (ram_size >= user_lowmem) {
137 x86ms->above_4g_mem_size = ram_size - user_lowmem;
138 x86ms->below_4g_mem_size = user_lowmem;
139 } else {
140 x86ms->above_4g_mem_size = 0;
141 x86ms->below_4g_mem_size = ram_size;
142 }
143 if (!x86ms->above_4g_mem_size) {
144 block_len = ram_size;
145 } else {
146
147
148
149
150 block_len = (4 * GiB) + x86ms->above_4g_mem_size;
151 }
152 memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len,
153 &error_fatal);
154 *ram_memory_p = &ram_memory;
155
156 memory_region_init_alias(&ram_640k, NULL, "xen.ram.640k",
157 &ram_memory, 0, 0xa0000);
158 memory_region_add_subregion(sysmem, 0, &ram_640k);
159
160
161
162
163
164
165 memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo",
166 &ram_memory, 0xc0000,
167 x86ms->below_4g_mem_size - 0xc0000);
168 memory_region_add_subregion(sysmem, 0xc0000, &ram_lo);
169 if (x86ms->above_4g_mem_size > 0) {
170 memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi",
171 &ram_memory, 0x100000000ULL,
172 x86ms->above_4g_mem_size);
173 memory_region_add_subregion(sysmem, 0x100000000ULL, &ram_hi);
174 }
175}
176
177static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
178{
179 XenPhysmap *physmap = NULL;
180
181 start_addr &= TARGET_PAGE_MASK;
182
183 QLIST_FOREACH(physmap, &xen_physmap, list) {
184 if (range_covers_byte(physmap->start_addr, physmap->size, start_addr)) {
185 return physmap;
186 }
187 }
188 return NULL;
189}
190
191static hwaddr xen_phys_offset_to_gaddr(hwaddr phys_offset, ram_addr_t size)
192{
193 hwaddr addr = phys_offset & TARGET_PAGE_MASK;
194 XenPhysmap *physmap = NULL;
195
196 QLIST_FOREACH(physmap, &xen_physmap, list) {
197 if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) {
198 return physmap->start_addr + (phys_offset - physmap->phys_offset);
199 }
200 }
201
202 return phys_offset;
203}
204
205#ifdef XEN_COMPAT_PHYSMAP
206static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
207{
208 char path[80], value[17];
209
210 snprintf(path, sizeof(path),
211 "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
212 xen_domid, (uint64_t)physmap->phys_offset);
213 snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->start_addr);
214 if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
215 return -1;
216 }
217 snprintf(path, sizeof(path),
218 "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
219 xen_domid, (uint64_t)physmap->phys_offset);
220 snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
221 if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
222 return -1;
223 }
224 if (physmap->name) {
225 snprintf(path, sizeof(path),
226 "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
227 xen_domid, (uint64_t)physmap->phys_offset);
228 if (!xs_write(state->xenstore, 0, path,
229 physmap->name, strlen(physmap->name))) {
230 return -1;
231 }
232 }
233 return 0;
234}
235#else
236static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
237{
238 return 0;
239}
240#endif
241
242static int xen_add_to_physmap(XenIOState *state,
243 hwaddr start_addr,
244 ram_addr_t size,
245 MemoryRegion *mr,
246 hwaddr offset_within_region)
247{
248 unsigned long nr_pages;
249 int rc = 0;
250 XenPhysmap *physmap = NULL;
251 hwaddr pfn, start_gpfn;
252 hwaddr phys_offset = memory_region_get_ram_addr(mr);
253 const char *mr_name;
254
255 if (get_physmapping(start_addr, size)) {
256 return 0;
257 }
258 if (size <= 0) {
259 return -1;
260 }
261
262
263
264
265
266 if (mr == framebuffer && start_addr > 0xbffff) {
267 goto go_physmap;
268 }
269 return -1;
270
271go_physmap:
272 DPRINTF("mapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx"\n",
273 start_addr, start_addr + size);
274
275 mr_name = memory_region_name(mr);
276
277 physmap = g_new(XenPhysmap, 1);
278
279 physmap->start_addr = start_addr;
280 physmap->size = size;
281 physmap->name = mr_name;
282 physmap->phys_offset = phys_offset;
283
284 QLIST_INSERT_HEAD(&xen_physmap, physmap, list);
285
286 if (runstate_check(RUN_STATE_INMIGRATE)) {
287
288
289 uint8_t *p = xen_replace_cache_entry(phys_offset, start_addr, size);
290 assert(p && p == memory_region_get_ram_ptr(mr));
291
292 return 0;
293 }
294
295 pfn = phys_offset >> TARGET_PAGE_BITS;
296 start_gpfn = start_addr >> TARGET_PAGE_BITS;
297 nr_pages = size >> TARGET_PAGE_BITS;
298 rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, nr_pages, pfn,
299 start_gpfn);
300 if (rc) {
301 int saved_errno = errno;
302
303 error_report("relocate_memory %lu pages from GFN %"HWADDR_PRIx
304 " to GFN %"HWADDR_PRIx" failed: %s",
305 nr_pages, pfn, start_gpfn, strerror(saved_errno));
306 errno = saved_errno;
307 return -1;
308 }
309
310 rc = xendevicemodel_pin_memory_cacheattr(xen_dmod, xen_domid,
311 start_addr >> TARGET_PAGE_BITS,
312 (start_addr + size - 1) >> TARGET_PAGE_BITS,
313 XEN_DOMCTL_MEM_CACHEATTR_WB);
314 if (rc) {
315 error_report("pin_memory_cacheattr failed: %s", strerror(errno));
316 }
317 return xen_save_physmap(state, physmap);
318}
319
320static int xen_remove_from_physmap(XenIOState *state,
321 hwaddr start_addr,
322 ram_addr_t size)
323{
324 int rc = 0;
325 XenPhysmap *physmap = NULL;
326 hwaddr phys_offset = 0;
327
328 physmap = get_physmapping(start_addr, size);
329 if (physmap == NULL) {
330 return -1;
331 }
332
333 phys_offset = physmap->phys_offset;
334 size = physmap->size;
335
336 DPRINTF("unmapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx", at "
337 "%"HWADDR_PRIx"\n", start_addr, start_addr + size, phys_offset);
338
339 size >>= TARGET_PAGE_BITS;
340 start_addr >>= TARGET_PAGE_BITS;
341 phys_offset >>= TARGET_PAGE_BITS;
342 rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, size, start_addr,
343 phys_offset);
344 if (rc) {
345 int saved_errno = errno;
346
347 error_report("relocate_memory "RAM_ADDR_FMT" pages"
348 " from GFN %"HWADDR_PRIx
349 " to GFN %"HWADDR_PRIx" failed: %s",
350 size, start_addr, phys_offset, strerror(saved_errno));
351 errno = saved_errno;
352 return -1;
353 }
354
355 QLIST_REMOVE(physmap, list);
356 if (log_for_dirtybit == physmap) {
357 log_for_dirtybit = NULL;
358 g_free(dirty_bitmap);
359 dirty_bitmap = NULL;
360 }
361 g_free(physmap);
362
363 return 0;
364}
365
366static void xen_sync_dirty_bitmap(XenIOState *state,
367 hwaddr start_addr,
368 ram_addr_t size)
369{
370 hwaddr npages = size >> TARGET_PAGE_BITS;
371 const int width = sizeof(unsigned long) * 8;
372 size_t bitmap_size = DIV_ROUND_UP(npages, width);
373 int rc, i, j;
374 const XenPhysmap *physmap = NULL;
375
376 physmap = get_physmapping(start_addr, size);
377 if (physmap == NULL) {
378
379 return;
380 }
381
382 if (log_for_dirtybit == NULL) {
383 log_for_dirtybit = physmap;
384 dirty_bitmap = g_new(unsigned long, bitmap_size);
385 } else if (log_for_dirtybit != physmap) {
386
387 return;
388 }
389
390 rc = xen_track_dirty_vram(xen_domid, start_addr >> TARGET_PAGE_BITS,
391 npages, dirty_bitmap);
392 if (rc < 0) {
393#ifndef ENODATA
394#define ENODATA ENOENT
395#endif
396 if (errno == ENODATA) {
397 memory_region_set_dirty(framebuffer, 0, size);
398 DPRINTF("xen: track_dirty_vram failed (0x" HWADDR_FMT_plx
399 ", 0x" HWADDR_FMT_plx "): %s\n",
400 start_addr, start_addr + size, strerror(errno));
401 }
402 return;
403 }
404
405 for (i = 0; i < bitmap_size; i++) {
406 unsigned long map = dirty_bitmap[i];
407 while (map != 0) {
408 j = ctzl(map);
409 map &= ~(1ul << j);
410 memory_region_set_dirty(framebuffer,
411 (i * width + j) * TARGET_PAGE_SIZE,
412 TARGET_PAGE_SIZE);
413 };
414 }
415}
416
417static void xen_log_start(MemoryListener *listener,
418 MemoryRegionSection *section,
419 int old, int new)
420{
421 XenIOState *state = container_of(listener, XenIOState, memory_listener);
422
423 if (new & ~old & (1 << DIRTY_MEMORY_VGA)) {
424 xen_sync_dirty_bitmap(state, section->offset_within_address_space,
425 int128_get64(section->size));
426 }
427}
428
429static void xen_log_stop(MemoryListener *listener, MemoryRegionSection *section,
430 int old, int new)
431{
432 if (old & ~new & (1 << DIRTY_MEMORY_VGA)) {
433 log_for_dirtybit = NULL;
434 g_free(dirty_bitmap);
435 dirty_bitmap = NULL;
436
437 xen_track_dirty_vram(xen_domid, 0, 0, NULL);
438 }
439}
440
441static void xen_log_sync(MemoryListener *listener, MemoryRegionSection *section)
442{
443 XenIOState *state = container_of(listener, XenIOState, memory_listener);
444
445 xen_sync_dirty_bitmap(state, section->offset_within_address_space,
446 int128_get64(section->size));
447}
448
449static void xen_log_global_start(MemoryListener *listener)
450{
451 if (xen_enabled()) {
452 xen_in_migration = true;
453 }
454}
455
456static void xen_log_global_stop(MemoryListener *listener)
457{
458 xen_in_migration = false;
459}
460
461static const MemoryListener xen_memory_listener = {
462 .name = "xen-memory",
463 .region_add = xen_region_add,
464 .region_del = xen_region_del,
465 .log_start = xen_log_start,
466 .log_stop = xen_log_stop,
467 .log_sync = xen_log_sync,
468 .log_global_start = xen_log_global_start,
469 .log_global_stop = xen_log_global_stop,
470 .priority = MEMORY_LISTENER_PRIORITY_ACCEL,
471};
472
473static void regs_to_cpu(vmware_regs_t *vmport_regs, ioreq_t *req)
474{
475 X86CPU *cpu;
476 CPUX86State *env;
477
478 cpu = X86_CPU(current_cpu);
479 env = &cpu->env;
480 env->regs[R_EAX] = req->data;
481 env->regs[R_EBX] = vmport_regs->ebx;
482 env->regs[R_ECX] = vmport_regs->ecx;
483 env->regs[R_EDX] = vmport_regs->edx;
484 env->regs[R_ESI] = vmport_regs->esi;
485 env->regs[R_EDI] = vmport_regs->edi;
486}
487
488static void regs_from_cpu(vmware_regs_t *vmport_regs)
489{
490 X86CPU *cpu = X86_CPU(current_cpu);
491 CPUX86State *env = &cpu->env;
492
493 vmport_regs->ebx = env->regs[R_EBX];
494 vmport_regs->ecx = env->regs[R_ECX];
495 vmport_regs->edx = env->regs[R_EDX];
496 vmport_regs->esi = env->regs[R_ESI];
497 vmport_regs->edi = env->regs[R_EDI];
498}
499
500static void handle_vmport_ioreq(XenIOState *state, ioreq_t *req)
501{
502 vmware_regs_t *vmport_regs;
503
504 assert(shared_vmport_page);
505 vmport_regs =
506 &shared_vmport_page->vcpu_vmport_regs[state->send_vcpu];
507 QEMU_BUILD_BUG_ON(sizeof(*req) < sizeof(*vmport_regs));
508
509 current_cpu = state->cpu_by_vcpu_id[state->send_vcpu];
510 regs_to_cpu(vmport_regs, req);
511 cpu_ioreq_pio(req);
512 regs_from_cpu(vmport_regs);
513 current_cpu = NULL;
514}
515
516#ifdef XEN_COMPAT_PHYSMAP
517static void xen_read_physmap(XenIOState *state)
518{
519 XenPhysmap *physmap = NULL;
520 unsigned int len, num, i;
521 char path[80], *value = NULL;
522 char **entries = NULL;
523
524 snprintf(path, sizeof(path),
525 "/local/domain/0/device-model/%d/physmap", xen_domid);
526 entries = xs_directory(state->xenstore, 0, path, &num);
527 if (entries == NULL)
528 return;
529
530 for (i = 0; i < num; i++) {
531 physmap = g_new(XenPhysmap, 1);
532 physmap->phys_offset = strtoull(entries[i], NULL, 16);
533 snprintf(path, sizeof(path),
534 "/local/domain/0/device-model/%d/physmap/%s/start_addr",
535 xen_domid, entries[i]);
536 value = xs_read(state->xenstore, 0, path, &len);
537 if (value == NULL) {
538 g_free(physmap);
539 continue;
540 }
541 physmap->start_addr = strtoull(value, NULL, 16);
542 free(value);
543
544 snprintf(path, sizeof(path),
545 "/local/domain/0/device-model/%d/physmap/%s/size",
546 xen_domid, entries[i]);
547 value = xs_read(state->xenstore, 0, path, &len);
548 if (value == NULL) {
549 g_free(physmap);
550 continue;
551 }
552 physmap->size = strtoull(value, NULL, 16);
553 free(value);
554
555 snprintf(path, sizeof(path),
556 "/local/domain/0/device-model/%d/physmap/%s/name",
557 xen_domid, entries[i]);
558 physmap->name = xs_read(state->xenstore, 0, path, &len);
559
560 QLIST_INSERT_HEAD(&xen_physmap, physmap, list);
561 }
562 free(entries);
563}
564#else
565static void xen_read_physmap(XenIOState *state)
566{
567}
568#endif
569
570static void xen_wakeup_notifier(Notifier *notifier, void *data)
571{
572 xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 0);
573}
574
575void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
576{
577 MachineState *ms = MACHINE(pcms);
578 unsigned int max_cpus = ms->smp.max_cpus;
579 int rc;
580 xen_pfn_t ioreq_pfn;
581 XenIOState *state;
582
583 state = g_new0(XenIOState, 1);
584
585 xen_register_ioreq(state, max_cpus, &xen_memory_listener);
586
587 QLIST_INIT(&xen_physmap);
588 xen_read_physmap(state);
589
590 suspend.notify = xen_suspend_notifier;
591 qemu_register_suspend_notifier(&suspend);
592
593 wakeup.notify = xen_wakeup_notifier;
594 qemu_register_wakeup_notifier(&wakeup);
595
596 rc = xen_get_vmport_regs_pfn(xen_xc, xen_domid, &ioreq_pfn);
597 if (!rc) {
598 DPRINTF("shared vmport page at pfn %lx\n", ioreq_pfn);
599 shared_vmport_page =
600 xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
601 1, &ioreq_pfn, NULL);
602 if (shared_vmport_page == NULL) {
603 error_report("map shared vmport IO page returned error %d handle=%p",
604 errno, xen_xc);
605 goto err;
606 }
607 } else if (rc != -ENOSYS) {
608 error_report("get vmport regs pfn returned error %d, rc=%d",
609 errno, rc);
610 goto err;
611 }
612
613 xen_ram_init(pcms, ms->ram_size, ram_memory);
614
615
616 pcms->acpi_build_enabled = false;
617
618 return;
619
620err:
621 error_report("xen hardware virtual machine initialisation failed");
622 exit(1);
623}
624
625void xen_register_framebuffer(MemoryRegion *mr)
626{
627 framebuffer = mr;
628}
629
630void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
631{
632 if (unlikely(xen_in_migration)) {
633 int rc;
634 ram_addr_t start_pfn, nb_pages;
635
636 start = xen_phys_offset_to_gaddr(start, length);
637
638 if (length == 0) {
639 length = TARGET_PAGE_SIZE;
640 }
641 start_pfn = start >> TARGET_PAGE_BITS;
642 nb_pages = ((start + length + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS)
643 - start_pfn;
644 rc = xen_modified_memory(xen_domid, start_pfn, nb_pages);
645 if (rc) {
646 fprintf(stderr,
647 "%s failed for "RAM_ADDR_FMT" ("RAM_ADDR_FMT"): %i, %s\n",
648 __func__, start, nb_pages, errno, strerror(errno));
649 }
650 }
651}
652
653void qmp_xen_set_global_dirty_log(bool enable, Error **errp)
654{
655 if (enable) {
656 memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION);
657 } else {
658 memory_global_dirty_log_stop(GLOBAL_DIRTY_MIGRATION);
659 }
660}
661
662void arch_xen_set_memory(XenIOState *state, MemoryRegionSection *section,
663 bool add)
664{
665 hwaddr start_addr = section->offset_within_address_space;
666 ram_addr_t size = int128_get64(section->size);
667 bool log_dirty = memory_region_is_logging(section->mr, DIRTY_MEMORY_VGA);
668 hvmmem_type_t mem_type;
669
670 if (!memory_region_is_ram(section->mr)) {
671 return;
672 }
673
674 if (log_dirty != add) {
675 return;
676 }
677
678 trace_xen_client_set_memory(start_addr, size, log_dirty);
679
680 start_addr &= TARGET_PAGE_MASK;
681 size = TARGET_PAGE_ALIGN(size);
682
683 if (add) {
684 if (!memory_region_is_rom(section->mr)) {
685 xen_add_to_physmap(state, start_addr, size,
686 section->mr, section->offset_within_region);
687 } else {
688 mem_type = HVMMEM_ram_ro;
689 if (xen_set_mem_type(xen_domid, mem_type,
690 start_addr >> TARGET_PAGE_BITS,
691 size >> TARGET_PAGE_BITS)) {
692 DPRINTF("xen_set_mem_type error, addr: "HWADDR_FMT_plx"\n",
693 start_addr);
694 }
695 }
696 } else {
697 if (xen_remove_from_physmap(state, start_addr, size) < 0) {
698 DPRINTF("physmapping does not exist at "HWADDR_FMT_plx"\n", start_addr);
699 }
700 }
701}
702
703void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
704{
705 switch (req->type) {
706 case IOREQ_TYPE_VMWARE_PORT:
707 handle_vmport_ioreq(state, req);
708 break;
709 default:
710 hw_error("Invalid ioreq type 0x%x\n", req->type);
711 }
712
713 return;
714}
715