qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* VFIO bugfix for AMD SEV (Alex)
* Kconfig improvements (Julio, Philippe)
* MemoryRegion reference counting bugfix (King Wang)
* Build system cleanups (Marc-André, myself)
* rdmacm-mux off-by-one (Marc-André)
* ZBC passthrough fixes (Shinichiro, myself)
* WHPX build fix (Stefan)
* char-pty fix (Wei Yang)

# gpg: Signature made Tue 16 Jul 2019 08:31:27 BST
# gpg: using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
vl: make sure char-pty message displayed by moving setbuf to the beginning
create_config: remove $(CONFIG_SOFTMMU) hack
Makefile: do not repeat $(CONFIG_SOFTMMU) in hw/Makefile.objs
hw/usb/Kconfig: USB_XHCI_NEC requires USB_XHCI
hw/usb/Kconfig: Add CONFIG_USB_EHCI_PCI
target/i386: sev: Do not unpin ram device memory region
checkpatch: detect doubly-encoded UTF-8
hw/lm32/Kconfig: Milkymist One provides a USB 1.1 Controller
util: merge main-loop.c and iohandler.c
Fix broken build with WHPX enabled
memory: unref the memory region in simplify flatview
hw/i386: turn off vmport if CONFIG_VMPORT is disabled
rdmacm-mux: fix strcpy string warning
build-sys: remove slirp cflags from main-loop.o
iscsi: base all handling of check condition on scsi_sense_to_errno
iscsi: fix busy/timeout/task set full
scsi: add guest-recoverable ZBC errors
scsi: explicitly list guest-recoverable sense codes
scsi-disk: pass sense correctly for guest-recoverable errors

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+276 -203
+14 -15
block/iscsi.c
··· 225 225 226 226 static int iscsi_translate_sense(struct scsi_sense *sense) 227 227 { 228 - return - scsi_sense_to_errno(sense->key, 229 - (sense->ascq & 0xFF00) >> 8, 230 - sense->ascq & 0xFF); 228 + return scsi_sense_to_errno(sense->key, 229 + (sense->ascq & 0xFF00) >> 8, 230 + sense->ascq & 0xFF); 231 231 } 232 232 233 233 /* Called (via iscsi_service) with QemuMutex held. */ ··· 244 244 245 245 if (status != SCSI_STATUS_GOOD) { 246 246 if (iTask->retries++ < ISCSI_CMD_RETRIES) { 247 - if (status == SCSI_STATUS_CHECK_CONDITION 248 - && task->sense.key == SCSI_SENSE_UNIT_ATTENTION) { 249 - error_report("iSCSI CheckCondition: %s", 250 - iscsi_get_error(iscsi)); 251 - iTask->do_retry = 1; 252 - goto out; 253 - } 254 247 if (status == SCSI_STATUS_BUSY || 255 248 status == SCSI_STATUS_TIMEOUT || 256 249 status == SCSI_STATUS_TASK_SET_FULL) { ··· 272 265 timer_mod(&iTask->retry_timer, 273 266 qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + retry_time); 274 267 iTask->do_retry = 1; 275 - return; 268 + } 269 + } else if (status == SCSI_STATUS_CHECK_CONDITION) { 270 + int error = iscsi_translate_sense(&task->sense); 271 + if (error == EAGAIN) { 272 + error_report("iSCSI CheckCondition: %s", 273 + iscsi_get_error(iscsi)); 274 + iTask->do_retry = 1; 275 + } else { 276 + iTask->err_code = -error; 277 + iTask->err_str = g_strdup(iscsi_get_error(iscsi)); 276 278 } 277 279 } 278 - iTask->err_code = iscsi_translate_sense(&task->sense); 279 - iTask->err_str = g_strdup(iscsi_get_error(iscsi)); 280 280 } 281 281 282 - out: 283 282 if (iTask->co) { 284 283 aio_bh_schedule_oneshot(iTask->iscsilun->aio_context, 285 284 iscsi_co_generic_bh_cb, iTask); ··· 974 973 if (status < 0) { 975 974 error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s", 976 975 iscsi_get_error(iscsi)); 977 - acb->status = iscsi_translate_sense(&acb->task->sense); 976 + acb->status = -iscsi_translate_sense(&acb->task->sense); 978 977 } 979 978 980 979 acb->ioh->driver_status = 0;
+1 -1
configure
··· 7159 7159 fi 7160 7160 7161 7161 if test "$tpm" = "yes"; then 7162 - echo 'CONFIG_TPM=$(CONFIG_SOFTMMU)' >> $config_host_mak 7162 + echo 'CONFIG_TPM=y' >> $config_host_mak 7163 7163 fi 7164 7164 7165 7165 echo "TRACE_BACKENDS=$trace_backends" >> $config_host_mak
+1 -1
contrib/rdmacm-mux/main.c
··· 115 115 116 116 case 's': 117 117 /* This is temporary, final name will build below */ 118 - strncpy(unix_socket_path, optarg, SOCKET_PATH_MAX); 118 + strncpy(unix_socket_path, optarg, SOCKET_PATH_MAX - 1); 119 119 break; 120 120 121 121 case 'p':
+32 -29
hw/Makefile.objs
··· 1 + devices-dirs-y = core/ 2 + ifeq ($(CONFIG_SOFTMMU), y) 1 3 devices-dirs-$(call lor,$(CONFIG_VIRTIO_9P),$(call land,$(CONFIG_VIRTFS),$(CONFIG_XEN))) += 9pfs/ 2 - devices-dirs-$(CONFIG_SOFTMMU) += acpi/ 3 - devices-dirs-$(CONFIG_SOFTMMU) += adc/ 4 - devices-dirs-$(CONFIG_SOFTMMU) += audio/ 5 - devices-dirs-$(CONFIG_SOFTMMU) += block/ 6 - devices-dirs-$(CONFIG_SOFTMMU) += bt/ 7 - devices-dirs-$(CONFIG_SOFTMMU) += char/ 8 - devices-dirs-$(CONFIG_SOFTMMU) += cpu/ 9 - devices-dirs-$(CONFIG_SOFTMMU) += display/ 10 - devices-dirs-$(CONFIG_SOFTMMU) += dma/ 11 - devices-dirs-$(CONFIG_SOFTMMU) += gpio/ 4 + devices-dirs-y += acpi/ 5 + devices-dirs-y += adc/ 6 + devices-dirs-y += audio/ 7 + devices-dirs-y += block/ 8 + devices-dirs-y += bt/ 9 + devices-dirs-y += char/ 10 + devices-dirs-y += cpu/ 11 + devices-dirs-y += display/ 12 + devices-dirs-y += dma/ 13 + devices-dirs-y += gpio/ 12 14 devices-dirs-$(CONFIG_HYPERV) += hyperv/ 13 15 devices-dirs-$(CONFIG_I2C) += i2c/ 14 - devices-dirs-$(CONFIG_SOFTMMU) += ide/ 15 - devices-dirs-$(CONFIG_SOFTMMU) += input/ 16 - devices-dirs-$(CONFIG_SOFTMMU) += intc/ 16 + devices-dirs-y += ide/ 17 + devices-dirs-y += input/ 18 + devices-dirs-y += intc/ 17 19 devices-dirs-$(CONFIG_IPACK) += ipack/ 18 20 devices-dirs-$(CONFIG_IPMI) += ipmi/ 19 - devices-dirs-$(CONFIG_SOFTMMU) += isa/ 20 - devices-dirs-$(CONFIG_SOFTMMU) += misc/ 21 - devices-dirs-$(CONFIG_SOFTMMU) += net/ 22 - devices-dirs-$(CONFIG_SOFTMMU) += rdma/ 23 - devices-dirs-$(CONFIG_SOFTMMU) += nvram/ 24 - devices-dirs-$(CONFIG_SOFTMMU) += pci/ 21 + devices-dirs-y += isa/ 22 + devices-dirs-y += misc/ 23 + devices-dirs-y += net/ 24 + devices-dirs-y += rdma/ 25 + devices-dirs-y += nvram/ 26 + devices-dirs-y += pci/ 25 27 devices-dirs-$(CONFIG_PCI) += pci-bridge/ pci-host/ 26 - devices-dirs-$(CONFIG_SOFTMMU) += pcmcia/ 28 + devices-dirs-y += pcmcia/ 27 29 devices-dirs-$(CONFIG_SCSI) += scsi/ 28 - devices-dirs-$(CONFIG_SOFTMMU) += sd/ 29 - devices-dirs-$(CONFIG_SOFTMMU) += ssi/ 30 - devices-dirs-$(CONFIG_SOFTMMU) += timer/ 30 + devices-dirs-y += sd/ 31 + devices-dirs-y += ssi/ 32 + devices-dirs-y += timer/ 31 33 devices-dirs-$(CONFIG_TPM) += tpm/ 32 - devices-dirs-$(CONFIG_SOFTMMU) += usb/ 34 + devices-dirs-y += usb/ 33 35 devices-dirs-$(CONFIG_VFIO) += vfio/ 34 - devices-dirs-$(CONFIG_SOFTMMU) += virtio/ 35 - devices-dirs-$(CONFIG_SOFTMMU) += watchdog/ 36 - devices-dirs-$(CONFIG_SOFTMMU) += xen/ 36 + devices-dirs-y += virtio/ 37 + devices-dirs-y += watchdog/ 38 + devices-dirs-y += xen/ 37 39 devices-dirs-$(CONFIG_MEM_DEVICE) += mem/ 38 - devices-dirs-$(CONFIG_SOFTMMU) += smbios/ 39 40 devices-dirs-y += semihosting/ 40 - devices-dirs-y += core/ 41 + devices-dirs-y += smbios/ 42 + endif 43 + 41 44 common-obj-y += $(devices-dirs-y) 42 45 obj-y += $(devices-dirs-y)
+2 -2
hw/i386/Kconfig
··· 51 51 config I440FX 52 52 bool 53 53 imply E1000_PCI 54 + imply VMPORT 54 55 select PC_PCI 55 56 select PC_ACPI 56 57 select ACPI_SMBUS ··· 58 59 select IDE_PIIX 59 60 select DIMM 60 61 select SMBIOS 61 - select VMPORT 62 62 select VMMOUSE 63 63 select FW_CFG_DMA 64 64 ··· 77 77 imply VTD 78 78 imply AMD_IOMMU 79 79 imply E1000E_PCI_EXPRESS 80 + imply VMPORT 80 81 select PC_PCI 81 82 select PC_ACPI 82 83 select PCI_EXPRESS_Q35 ··· 84 85 select AHCI_ICH9 85 86 select DIMM 86 87 select SMBIOS 87 - select VMPORT 88 88 select VMMOUSE 89 89 select FW_CFG_DMA 90 90
+5
hw/i386/pc.c
··· 83 83 #include "hw/mem/memory-device.h" 84 84 #include "sysemu/replay.h" 85 85 #include "qapi/qmp/qerror.h" 86 + #include "config-devices.h" 86 87 87 88 /* debug PC/ISA interrupts */ 88 89 //#define DEBUG_IRQ ··· 2793 2794 2794 2795 pcms->max_ram_below_4g = 0; /* use default */ 2795 2796 pcms->smm = ON_OFF_AUTO_AUTO; 2797 + #ifdef CONFIG_VMPORT 2796 2798 pcms->vmport = ON_OFF_AUTO_AUTO; 2799 + #else 2800 + pcms->vmport = ON_OFF_AUTO_OFF; 2801 + #endif /* CONFIG_VMPORT */ 2797 2802 /* acpi build is enabled by default if machine supports it */ 2798 2803 pcms->acpi_build_enabled = PC_MACHINE_GET_CLASS(pcms)->has_acpi_build; 2799 2804 pcms->smbus_enabled = true;
+1
hw/lm32/Kconfig
··· 11 11 select PFLASH_CFI01 12 12 select FRAMEBUFFER 13 13 select SD 14 + select USB_OHCI
+12 -3
hw/scsi/scsi-disk.c
··· 62 62 DMAIOFunc *dma_readv; 63 63 DMAIOFunc *dma_writev; 64 64 bool (*need_fua_emulation)(SCSICommand *cmd); 65 + void (*update_sense)(SCSIRequest *r); 65 66 } SCSIDiskClass; 66 67 67 68 typedef struct SCSIDiskReq { ··· 438 439 { 439 440 bool is_read = (r->req.cmd.mode == SCSI_XFER_FROM_DEV); 440 441 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); 442 + SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s)); 441 443 BlockErrorAction action = blk_get_error_action(s->qdev.conf.blk, 442 444 is_read, error); 443 445 ··· 452 454 * pause the host. 453 455 */ 454 456 assert(r->status && *r->status); 455 - error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense)); 456 - if (error == ECANCELED || error == EAGAIN || error == ENOTCONN || 457 - error == 0) { 457 + if (scsi_sense_buf_is_guest_recoverable(r->req.sense, sizeof(r->req.sense))) { 458 458 /* These errors are handled by guest. */ 459 + sdc->update_sense(&r->req); 459 460 scsi_req_complete(&r->req, *r->status); 460 461 return true; 461 462 } 463 + error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense)); 462 464 break; 463 465 case ENOMEDIUM: 464 466 scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); ··· 2894 2896 } 2895 2897 } 2896 2898 2899 + static void scsi_block_update_sense(SCSIRequest *req) 2900 + { 2901 + SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); 2902 + SCSIBlockReq *br = DO_UPCAST(SCSIBlockReq, req, r); 2903 + r->req.sense_len = MIN(br->io_header.sb_len_wr, sizeof(r->req.sense)); 2904 + } 2897 2905 #endif 2898 2906 2899 2907 static ··· 3059 3067 sc->parse_cdb = scsi_block_parse_cdb; 3060 3068 sdc->dma_readv = scsi_block_dma_readv; 3061 3069 sdc->dma_writev = scsi_block_dma_writev; 3070 + sdc->update_sense = scsi_block_update_sense; 3062 3071 sdc->need_fua_emulation = scsi_block_no_fua; 3063 3072 dc->desc = "SCSI block device passthrough"; 3064 3073 dc->props = scsi_block_properties;
+7 -4
hw/usb/Kconfig
··· 19 19 20 20 config USB_EHCI 21 21 bool 22 + select USB 23 + 24 + config USB_EHCI_PCI 25 + bool 22 26 default y if PCI_DEVICES 23 - depends on PCI 24 - select USB 27 + select USB_EHCI 25 28 26 29 config USB_EHCI_SYSBUS 27 30 bool 28 - select USB 31 + select USB_EHCI 29 32 30 33 config USB_XHCI 31 34 bool ··· 37 40 bool 38 41 default y if PCI_DEVICES 39 42 depends on PCI 40 - select USB 43 + select USB_XHCI 41 44 42 45 config USB_MUSB 43 46 bool
+3 -2
hw/usb/Makefile.objs
··· 6 6 common-obj-$(CONFIG_USB_UHCI) += hcd-uhci.o 7 7 common-obj-$(CONFIG_USB_OHCI) += hcd-ohci.o 8 8 common-obj-$(CONFIG_USB_OHCI_PCI) += hcd-ohci-pci.o 9 - common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o hcd-ehci-pci.o 10 - common-obj-$(CONFIG_USB_EHCI_SYSBUS) += hcd-ehci.o hcd-ehci-sysbus.o 9 + common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o 10 + common-obj-$(CONFIG_USB_EHCI_PCI) += hcd-ehci-pci.o 11 + common-obj-$(CONFIG_USB_EHCI_SYSBUS) += hcd-ehci-sysbus.o 11 12 common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o 12 13 common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o 13 14 common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
+1
include/scsi/utils.h
··· 106 106 107 107 int scsi_sense_to_errno(int key, int asc, int ascq); 108 108 int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size); 109 + bool scsi_sense_buf_is_guest_recoverable(const uint8_t *sense, size_t sense_size); 109 110 110 111 int scsi_convert_sense(uint8_t *in_buf, int in_len, 111 112 uint8_t *buf, int len, bool fixed);
+4 -1
memory.c
··· 321 321 /* Attempt to simplify a view by merging adjacent ranges */ 322 322 static void flatview_simplify(FlatView *view) 323 323 { 324 - unsigned i, j; 324 + unsigned i, j, k; 325 325 326 326 i = 0; 327 327 while (i < view->nr) { ··· 332 332 ++j; 333 333 } 334 334 ++i; 335 + for (k = i; k < j; k++) { 336 + memory_region_unref(view->ranges[k].mr); 337 + } 335 338 memmove(&view->ranges[i], &view->ranges[j], 336 339 (view->nr - j) * sizeof(view->ranges[j])); 337 340 view->nr -= j - i;
+16
scripts/checkpatch.pl
··· 262 262 | $NON_ASCII_UTF8 263 263 }x; 264 264 265 + # some readers default to ISO-8859-1 when showing email source. detect 266 + # when UTF-8 is incorrectly interpreted as ISO-8859-1 and reencoded back. 267 + # False positives are possible but very unlikely. 268 + our $UTF8_MOJIBAKE = qr{ 269 + \xC3[\x82-\x9F] \xC2[\x80-\xBF] # c2-df 80-bf 270 + | \xC3\xA0 \xC2[\xA0-\xBF] \xC2[\x80-\xBF] # e0 a0-bf 80-bf 271 + | \xC3[\xA1-\xAC\xAE\xAF] (?: \xC2[\x80-\xBF]){2} # e1-ec/ee/ef 80-bf 80-bf 272 + | \xC3\xAD \xC2[\x80-\x9F] \xC2[\x80-\xBF] # ed 80-9f 80-bf 273 + | \xC3\xB0 \xC2[\x90-\xBF] (?: \xC2[\x80-\xBF]){2} # f0 90-bf 80-bf 80-bf 274 + | \xC3[\xB1-\xB3] (?: \xC2[\x80-\xBF]){3} # f1-f3 80-bf 80-bf 80-bf 275 + | \xC3\xB4 \xC2[\x80-\x8F] (?: \xC2[\x80-\xBF]){2} # f4 80-b8 80-bf 80-bf 276 + }x; 277 + 265 278 # There are still some false positives, but this catches most 266 279 # common cases. 267 280 our $typeTypedefs = qr{(?x: ··· 1506 1519 ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 1507 1520 } 1508 1521 1522 + if ($rawline =~ m/$UTF8_MOJIBAKE/) { 1523 + ERROR("Doubly-encoded UTF-8\n" . $herecurr); 1524 + } 1509 1525 # Check if it's the start of a commit log 1510 1526 # (not a header line and we haven't seen the patch filename) 1511 1527 if ($in_header_lines && $realfile =~ /^$/ &&
+1 -1
scripts/create_config
··· 54 54 done 55 55 echo " NULL" 56 56 ;; 57 - CONFIG_*='$(CONFIG_SOFTMMU)'|CONFIG_*=y) # configuration 57 + CONFIG_*=y) # configuration 58 58 name=${line%=*} 59 59 echo "#define $name 1" 60 60 ;;
+50 -3
scsi/utils.c
··· 336 336 } 337 337 } 338 338 339 + static bool scsi_sense_is_guest_recoverable(int key, int asc, int ascq) 340 + { 341 + switch (key) { 342 + case NO_SENSE: 343 + case RECOVERED_ERROR: 344 + case UNIT_ATTENTION: 345 + case ABORTED_COMMAND: 346 + return true; 347 + case NOT_READY: 348 + case ILLEGAL_REQUEST: 349 + case DATA_PROTECT: 350 + /* Parse ASCQ */ 351 + break; 352 + default: 353 + return false; 354 + } 355 + 356 + switch ((asc << 8) | ascq) { 357 + case 0x1a00: /* PARAMETER LIST LENGTH ERROR */ 358 + case 0x2000: /* INVALID OPERATION CODE */ 359 + case 0x2400: /* INVALID FIELD IN CDB */ 360 + case 0x2500: /* LOGICAL UNIT NOT SUPPORTED */ 361 + case 0x2600: /* INVALID FIELD IN PARAMETER LIST */ 362 + 363 + case 0x2104: /* UNALIGNED WRITE COMMAND */ 364 + case 0x2105: /* WRITE BOUNDARY VIOLATION */ 365 + case 0x2106: /* ATTEMPT TO READ INVALID DATA */ 366 + case 0x550e: /* INSUFFICIENT ZONE RESOURCES */ 367 + 368 + case 0x0401: /* NOT READY, IN PROGRESS OF BECOMING READY */ 369 + case 0x0402: /* NOT READY, INITIALIZING COMMAND REQUIRED */ 370 + return true; 371 + default: 372 + return false; 373 + } 374 + } 375 + 339 376 int scsi_sense_to_errno(int key, int asc, int ascq) 340 377 { 341 378 switch (key) { 342 379 case NO_SENSE: 343 380 case RECOVERED_ERROR: 344 381 case UNIT_ATTENTION: 345 - /* These sense keys are not errors */ 346 - return 0; 382 + return EAGAIN; 347 383 case ABORTED_COMMAND: /* COMMAND ABORTED */ 348 384 return ECANCELED; 349 385 case NOT_READY: ··· 372 408 case 0x2700: /* WRITE PROTECTED */ 373 409 return EACCES; 374 410 case 0x0401: /* NOT READY, IN PROGRESS OF BECOMING READY */ 375 - return EAGAIN; 411 + return EINPROGRESS; 376 412 case 0x0402: /* NOT READY, INITIALIZING COMMAND REQUIRED */ 377 413 return ENOTCONN; 378 414 default: ··· 389 425 390 426 sense = scsi_parse_sense_buf(in_buf, in_len); 391 427 return scsi_sense_to_errno(sense.key, sense.asc, sense.ascq); 428 + } 429 + 430 + bool scsi_sense_buf_is_guest_recoverable(const uint8_t *in_buf, size_t in_len) 431 + { 432 + SCSISense sense; 433 + if (in_len < 1) { 434 + return false; 435 + } 436 + 437 + sense = scsi_parse_sense_buf(in_buf, in_len); 438 + return scsi_sense_is_guest_recoverable(sense.key, sense.asc, sense.ascq); 392 439 } 393 440 394 441 const char *scsi_command_name(uint8_t cmd)
+11
target/i386/sev.c
··· 161 161 { 162 162 int r; 163 163 struct kvm_enc_region range; 164 + ram_addr_t offset; 165 + MemoryRegion *mr; 166 + 167 + /* 168 + * The RAM device presents a memory region that should be treated 169 + * as IO region and should not have been pinned. 170 + */ 171 + mr = memory_region_from_host(host, &offset); 172 + if (mr && memory_region_is_ram_device(mr)) { 173 + return; 174 + } 164 175 165 176 range.addr = (__u64)(unsigned long)host; 166 177 range.size = size;
+2 -2
target/i386/whpx-all.c
··· 1396 1396 } 1397 1397 1398 1398 memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY)); 1399 - prop.ProcessorCount = smp_cpus; 1399 + prop.ProcessorCount = ms->smp.cpus; 1400 1400 hr = whp_dispatch.WHvSetPartitionProperty( 1401 1401 whpx->partition, 1402 1402 WHvPartitionPropertyCodeProcessorCount, ··· 1405 1405 1406 1406 if (FAILED(hr)) { 1407 1407 error_report("WHPX: Failed to set partition core count to %d," 1408 - " hr=%08lx", smp_cores, hr); 1408 + " hr=%08lx", ms->smp.cores, hr); 1409 1409 ret = -EINVAL; 1410 1410 goto error; 1411 1411 }
+1 -2
util/Makefile.objs
··· 2 2 util-obj-y += bufferiszero.o 3 3 util-obj-y += lockcnt.o 4 4 util-obj-y += aiocb.o async.o aio-wait.o thread-pool.o qemu-timer.o 5 - util-obj-y += main-loop.o iohandler.o 6 - main-loop.o-cflags := $(SLIRP_CFLAGS) 5 + util-obj-y += main-loop.o 7 6 util-obj-$(call lnot,$(CONFIG_ATOMIC64)) += atomic64.o 8 7 util-obj-$(CONFIG_POSIX) += aio-posix.o 9 8 util-obj-$(CONFIG_POSIX) += compatfd.o
-135
util/iohandler.c
··· 1 - /* 2 - * QEMU System Emulator - managing I/O handler 3 - * 4 - * Copyright (c) 2003-2008 Fabrice Bellard 5 - * 6 - * Permission is hereby granted, free of charge, to any person obtaining a copy 7 - * of this software and associated documentation files (the "Software"), to deal 8 - * in the Software without restriction, including without limitation the rights 9 - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 - * copies of the Software, and to permit persons to whom the Software is 11 - * furnished to do so, subject to the following conditions: 12 - * 13 - * The above copyright notice and this permission notice shall be included in 14 - * all copies or substantial portions of the Software. 15 - * 16 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 - * THE SOFTWARE. 23 - */ 24 - 25 - #include "qemu/osdep.h" 26 - #include "qapi/error.h" 27 - #include "qemu/queue.h" 28 - #include "block/aio.h" 29 - #include "qemu/main-loop.h" 30 - 31 - #ifndef _WIN32 32 - #include <sys/wait.h> 33 - #endif 34 - 35 - /* This context runs on top of main loop. We can't reuse qemu_aio_context 36 - * because iohandlers mustn't be polled by aio_poll(qemu_aio_context). */ 37 - static AioContext *iohandler_ctx; 38 - 39 - static void iohandler_init(void) 40 - { 41 - if (!iohandler_ctx) { 42 - iohandler_ctx = aio_context_new(&error_abort); 43 - } 44 - } 45 - 46 - AioContext *iohandler_get_aio_context(void) 47 - { 48 - iohandler_init(); 49 - return iohandler_ctx; 50 - } 51 - 52 - GSource *iohandler_get_g_source(void) 53 - { 54 - iohandler_init(); 55 - return aio_get_g_source(iohandler_ctx); 56 - } 57 - 58 - void qemu_set_fd_handler(int fd, 59 - IOHandler *fd_read, 60 - IOHandler *fd_write, 61 - void *opaque) 62 - { 63 - iohandler_init(); 64 - aio_set_fd_handler(iohandler_ctx, fd, false, 65 - fd_read, fd_write, NULL, opaque); 66 - } 67 - 68 - void event_notifier_set_handler(EventNotifier *e, 69 - EventNotifierHandler *handler) 70 - { 71 - iohandler_init(); 72 - aio_set_event_notifier(iohandler_ctx, e, false, 73 - handler, NULL); 74 - } 75 - 76 - /* reaping of zombies. right now we're not passing the status to 77 - anyone, but it would be possible to add a callback. */ 78 - #ifndef _WIN32 79 - typedef struct ChildProcessRecord { 80 - int pid; 81 - QLIST_ENTRY(ChildProcessRecord) next; 82 - } ChildProcessRecord; 83 - 84 - static QLIST_HEAD(, ChildProcessRecord) child_watches = 85 - QLIST_HEAD_INITIALIZER(child_watches); 86 - 87 - static QEMUBH *sigchld_bh; 88 - 89 - static void sigchld_handler(int signal) 90 - { 91 - qemu_bh_schedule(sigchld_bh); 92 - } 93 - 94 - static void sigchld_bh_handler(void *opaque) 95 - { 96 - ChildProcessRecord *rec, *next; 97 - 98 - QLIST_FOREACH_SAFE(rec, &child_watches, next, next) { 99 - if (waitpid(rec->pid, NULL, WNOHANG) == rec->pid) { 100 - QLIST_REMOVE(rec, next); 101 - g_free(rec); 102 - } 103 - } 104 - } 105 - 106 - static void qemu_init_child_watch(void) 107 - { 108 - struct sigaction act; 109 - sigchld_bh = qemu_bh_new(sigchld_bh_handler, NULL); 110 - 111 - memset(&act, 0, sizeof(act)); 112 - act.sa_handler = sigchld_handler; 113 - act.sa_flags = SA_NOCLDSTOP; 114 - sigaction(SIGCHLD, &act, NULL); 115 - } 116 - 117 - int qemu_add_child_watch(pid_t pid) 118 - { 119 - ChildProcessRecord *rec; 120 - 121 - if (!sigchld_bh) { 122 - qemu_init_child_watch(); 123 - } 124 - 125 - QLIST_FOREACH(rec, &child_watches, next) { 126 - if (rec->pid == pid) { 127 - return 1; 128 - } 129 - } 130 - rec = g_malloc0(sizeof(ChildProcessRecord)); 131 - rec->pid = pid; 132 - QLIST_INSERT_HEAD(&child_watches, rec, next); 133 - return 0; 134 - } 135 - #endif
+110
util/main-loop.c
··· 32 32 #include "qemu/main-loop.h" 33 33 #include "block/aio.h" 34 34 #include "qemu/error-report.h" 35 + #include "qemu/queue.h" 36 + 37 + #ifndef _WIN32 38 + #include <sys/wait.h> 39 + #endif 35 40 36 41 #ifndef _WIN32 37 42 ··· 525 530 { 526 531 return aio_bh_new(qemu_aio_context, cb, opaque); 527 532 } 533 + 534 + /* 535 + * Functions to operate on the I/O handler AioContext. 536 + * This context runs on top of main loop. We can't reuse qemu_aio_context 537 + * because iohandlers mustn't be polled by aio_poll(qemu_aio_context). 538 + */ 539 + static AioContext *iohandler_ctx; 540 + 541 + static void iohandler_init(void) 542 + { 543 + if (!iohandler_ctx) { 544 + iohandler_ctx = aio_context_new(&error_abort); 545 + } 546 + } 547 + 548 + AioContext *iohandler_get_aio_context(void) 549 + { 550 + iohandler_init(); 551 + return iohandler_ctx; 552 + } 553 + 554 + GSource *iohandler_get_g_source(void) 555 + { 556 + iohandler_init(); 557 + return aio_get_g_source(iohandler_ctx); 558 + } 559 + 560 + void qemu_set_fd_handler(int fd, 561 + IOHandler *fd_read, 562 + IOHandler *fd_write, 563 + void *opaque) 564 + { 565 + iohandler_init(); 566 + aio_set_fd_handler(iohandler_ctx, fd, false, 567 + fd_read, fd_write, NULL, opaque); 568 + } 569 + 570 + void event_notifier_set_handler(EventNotifier *e, 571 + EventNotifierHandler *handler) 572 + { 573 + iohandler_init(); 574 + aio_set_event_notifier(iohandler_ctx, e, false, 575 + handler, NULL); 576 + } 577 + 578 + /* reaping of zombies. right now we're not passing the status to 579 + anyone, but it would be possible to add a callback. */ 580 + #ifndef _WIN32 581 + typedef struct ChildProcessRecord { 582 + int pid; 583 + QLIST_ENTRY(ChildProcessRecord) next; 584 + } ChildProcessRecord; 585 + 586 + static QLIST_HEAD(, ChildProcessRecord) child_watches = 587 + QLIST_HEAD_INITIALIZER(child_watches); 588 + 589 + static QEMUBH *sigchld_bh; 590 + 591 + static void sigchld_handler(int signal) 592 + { 593 + qemu_bh_schedule(sigchld_bh); 594 + } 595 + 596 + static void sigchld_bh_handler(void *opaque) 597 + { 598 + ChildProcessRecord *rec, *next; 599 + 600 + QLIST_FOREACH_SAFE(rec, &child_watches, next, next) { 601 + if (waitpid(rec->pid, NULL, WNOHANG) == rec->pid) { 602 + QLIST_REMOVE(rec, next); 603 + g_free(rec); 604 + } 605 + } 606 + } 607 + 608 + static void qemu_init_child_watch(void) 609 + { 610 + struct sigaction act; 611 + sigchld_bh = qemu_bh_new(sigchld_bh_handler, NULL); 612 + 613 + memset(&act, 0, sizeof(act)); 614 + act.sa_handler = sigchld_handler; 615 + act.sa_flags = SA_NOCLDSTOP; 616 + sigaction(SIGCHLD, &act, NULL); 617 + } 618 + 619 + int qemu_add_child_watch(pid_t pid) 620 + { 621 + ChildProcessRecord *rec; 622 + 623 + if (!sigchld_bh) { 624 + qemu_init_child_watch(); 625 + } 626 + 627 + QLIST_FOREACH(rec, &child_watches, next) { 628 + if (rec->pid == pid) { 629 + return 1; 630 + } 631 + } 632 + rec = g_malloc0(sizeof(ChildProcessRecord)); 633 + rec->pid = pid; 634 + QLIST_INSERT_HEAD(&child_watches, rec, next); 635 + return 0; 636 + } 637 + #endif
+2 -2
vl.c
··· 2890 2890 char *dir, **dirs; 2891 2891 BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); 2892 2892 2893 + os_set_line_buffering(); 2894 + 2893 2895 error_init(argv[0]); 2894 2896 module_call_init(MODULE_INIT_TRACE); 2895 2897 ··· 4245 4247 /* fall back to the -kernel/-append */ 4246 4248 semihosting_arg_fallback(kernel_filename, kernel_cmdline); 4247 4249 } 4248 - 4249 - os_set_line_buffering(); 4250 4250 4251 4251 /* spice needs the timers to be initialized by this point */ 4252 4252 qemu_spice_init();