diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-02-13 18:24:07 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-02-13 18:24:08 +0000 |
commit | bec9c64ef7be8063f1192608b83877bc5c9ea217 (patch) | |
tree | e3dd26e9a874b7a8ee86d977ed51146f06312035 /target | |
parent | b734ed9de10dbf10a873ae4b44cb1c13f59213d0 (diff) | |
parent | 7524a39d8c7c9ff54504cfeb784909e4f49d6f30 (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* CAN bus (will be under network maintainner)
* scsi-block opblockers (myself)
* Dirty log bitmap cleanup (myself)
* SDHCI improvements and tests (Philippe)
* HAX support for larger guest sizese (Yu Ning)
# gpg: Signature made Tue 13 Feb 2018 15:37:14 GMT
# gpg: using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>"
# 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: (48 commits)
travis: use libgcc-4.8-dev (libgcc-6-dev is not available on Ubuntu 14.04)
memory: unify loops to sync dirty log bitmap
memory: hide memory_region_sync_dirty_bitmap behind DirtyBitmapSnapshot
memory: remove memory_region_test_and_clear_dirty
g364fb: switch to using DirtyBitmapSnapshot
sdhci: add Spec v4.2 register definitions
sdhci: add a check_capab_v3() qtest
sdhci: check Spec v3 capabilities qtest
hw/arm/xilinx_zynqmp: enable the UHS-I mode
hw/arm/xilinx_zynqmp: fix the capabilities/spec version to match the datasheet
hw/arm/fsl-imx6: implement SDHCI Spec. v3
hw/arm/bcm2835_peripherals: change maximum block size to 1kB
hw/arm/bcm2835_peripherals: implement SDHCI Spec v3
sdhci: implement CMD/DAT[] fields in the Present State register
sdhci: implement UHS-I voltage switch
sdbus: add trace events
sdhci: implement the Host Control 2 register (tuning sequence)
sdhci: rename the hostctl1 register
sdhci: add support for v3 capabilities
hw/arm/xilinx_zynq: fix the capabilities register to match the datasheet
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/i386/hax-all.c | 2 | ||||
-rw-r--r-- | target/i386/hax-darwin.c | 27 | ||||
-rw-r--r-- | target/i386/hax-darwin.h | 1 | ||||
-rw-r--r-- | target/i386/hax-i386.h | 1 | ||||
-rw-r--r-- | target/i386/hax-interface.h | 8 | ||||
-rw-r--r-- | target/i386/hax-mem.c | 34 | ||||
-rw-r--r-- | target/i386/hax-windows.c | 38 | ||||
-rw-r--r-- | target/i386/hax-windows.h | 2 |
8 files changed, 88 insertions, 25 deletions
diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c index bc9a12c1ee..cad7531406 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -103,6 +103,8 @@ static int hax_get_capability(struct hax_state *hax) return -ENOTSUP; } + hax->supports_64bit_ramblock = !!(cap->winfo & HAX_CAP_64BIT_RAMBLOCK); + if (cap->wstatus & HAX_CAP_MEMQUOTA) { if (cap->mem_quota < hax->mem_quota) { fprintf(stderr, "The VM memory needed exceeds the driver limit.\n"); diff --git a/target/i386/hax-darwin.c b/target/i386/hax-darwin.c index ee9417454c..acdde476a0 100644 --- a/target/i386/hax-darwin.c +++ b/target/i386/hax-darwin.c @@ -28,21 +28,36 @@ hax_fd hax_mod_open(void) return fd; } -int hax_populate_ram(uint64_t va, uint32_t size) +int hax_populate_ram(uint64_t va, uint64_t size) { int ret; - struct hax_alloc_ram_info info; if (!hax_global.vm || !hax_global.vm->fd) { fprintf(stderr, "Allocate memory before vm create?\n"); return -EINVAL; } - info.size = size; - info.va = va; - ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ALLOC_RAM, &info); + if (hax_global.supports_64bit_ramblock) { + struct hax_ramblock_info ramblock = { + .start_va = va, + .size = size, + .reserved = 0 + }; + + ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ADD_RAMBLOCK, &ramblock); + } else { + struct hax_alloc_ram_info info = { + .size = (uint32_t)size, + .pad = 0, + .va = va + }; + + ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ALLOC_RAM, &info); + } if (ret < 0) { - fprintf(stderr, "Failed to allocate %x memory\n", size); + fprintf(stderr, "Failed to register RAM block: ret=%d, va=0x%" PRIx64 + ", size=0x%" PRIx64 ", method=%s\n", ret, va, size, + hax_global.supports_64bit_ramblock ? "new" : "legacy"); return ret; } return 0; diff --git a/target/i386/hax-darwin.h b/target/i386/hax-darwin.h index fb8e25a096..51af0e8c88 100644 --- a/target/i386/hax-darwin.h +++ b/target/i386/hax-darwin.h @@ -44,6 +44,7 @@ static inline void hax_close_fd(hax_fd fd) #define HAX_VM_IOCTL_SET_RAM _IOWR(0, 0x82, struct hax_set_ram_info) #define HAX_VM_IOCTL_VCPU_DESTROY _IOW(0, 0x83, uint32_t) #define HAX_VM_IOCTL_NOTIFY_QEMU_VERSION _IOW(0, 0x84, struct hax_qemu_version) +#define HAX_VM_IOCTL_ADD_RAMBLOCK _IOW(0, 0x85, struct hax_ramblock_info) #define HAX_VCPU_IOCTL_RUN _IO(0, 0xc0) #define HAX_VCPU_IOCTL_SET_MSRS _IOWR(0, 0xc1, struct hax_msr_data) diff --git a/target/i386/hax-i386.h b/target/i386/hax-i386.h index 8ffe91fcb5..6abc156f88 100644 --- a/target/i386/hax-i386.h +++ b/target/i386/hax-i386.h @@ -37,6 +37,7 @@ struct hax_state { uint32_t version; struct hax_vm *vm; uint64_t mem_quota; + bool supports_64bit_ramblock; }; #define HAX_MAX_VCPU 0x10 diff --git a/target/i386/hax-interface.h b/target/i386/hax-interface.h index d141308831..93d5fcb1dc 100644 --- a/target/i386/hax-interface.h +++ b/target/i386/hax-interface.h @@ -308,6 +308,13 @@ struct hax_alloc_ram_info { uint32_t pad; uint64_t va; } __attribute__ ((__packed__)); + +struct hax_ramblock_info { + uint64_t start_va; + uint64_t size; + uint64_t reserved; +} __attribute__ ((__packed__)); + #define HAX_RAM_INFO_ROM 0x01 /* Read-Only */ #define HAX_RAM_INFO_INVALID 0x80 /* Unmapped, usually used for MMIO */ struct hax_set_ram_info { @@ -327,6 +334,7 @@ struct hax_set_ram_info { #define HAX_CAP_MEMQUOTA 0x2 #define HAX_CAP_UG 0x4 +#define HAX_CAP_64BIT_RAMBLOCK 0x8 struct hax_capabilityinfo { /* bit 0: 1 - working diff --git a/target/i386/hax-mem.c b/target/i386/hax-mem.c index 27a0d214f2..f46e85544d 100644 --- a/target/i386/hax-mem.c +++ b/target/i386/hax-mem.c @@ -174,6 +174,7 @@ static void hax_process_section(MemoryRegionSection *section, uint8_t flags) ram_addr_t size = int128_get64(section->size); unsigned int delta; uint64_t host_va; + uint32_t max_mapping_size; /* We only care about RAM and ROM regions */ if (!memory_region_is_ram(mr)) { @@ -206,10 +207,23 @@ static void hax_process_section(MemoryRegionSection *section, uint8_t flags) flags |= HAX_RAM_INFO_ROM; } - /* the kernel module interface uses 32-bit sizes (but we could split...) */ - g_assert(size <= UINT32_MAX); - - hax_update_mapping(start_pa, size, host_va, flags); + /* + * The kernel module interface uses 32-bit sizes: + * https://github.com/intel/haxm/blob/master/API.md#hax_vm_ioctl_set_ram + * + * If the mapping size is longer than 32 bits, we can't process it in one + * call into the kernel. Instead, we split the mapping into smaller ones, + * and call hax_update_mapping() on each. + */ + max_mapping_size = UINT32_MAX & qemu_real_host_page_mask; + while (size > max_mapping_size) { + hax_update_mapping(start_pa, max_mapping_size, host_va, flags); + start_pa += max_mapping_size; + size -= max_mapping_size; + host_va += max_mapping_size; + } + /* Now size <= max_mapping_size */ + hax_update_mapping(start_pa, (uint32_t)size, host_va, flags); } static void hax_region_add(MemoryListener *listener, @@ -283,12 +297,16 @@ static MemoryListener hax_memory_listener = { static void hax_ram_block_added(RAMBlockNotifier *n, void *host, size_t size) { /* - * In HAX, QEMU allocates the virtual address, and HAX kernel - * populates the memory with physical memory. Currently we have no - * paging, so user should make sure enough free memory in advance. + * We must register each RAM block with the HAXM kernel module, or + * hax_set_ram() will fail for any mapping into the RAM block: + * https://github.com/intel/haxm/blob/master/API.md#hax_vm_ioctl_alloc_ram + * + * Old versions of the HAXM kernel module (< 6.2.0) used to preallocate all + * host physical pages for the RAM block as part of this registration + * process, hence the name hax_populate_ram(). */ if (hax_populate_ram((uint64_t)(uintptr_t)host, size) < 0) { - fprintf(stderr, "HAX failed to populate RAM"); + fprintf(stderr, "HAX failed to populate RAM\n"); abort(); } } diff --git a/target/i386/hax-windows.c b/target/i386/hax-windows.c index 15a180b646..b1ac737ae4 100644 --- a/target/i386/hax-windows.c +++ b/target/i386/hax-windows.c @@ -58,10 +58,9 @@ static int hax_open_device(hax_fd *fd) return fd; } -int hax_populate_ram(uint64_t va, uint32_t size) +int hax_populate_ram(uint64_t va, uint64_t size) { int ret; - struct hax_alloc_ram_info info; HANDLE hDeviceVM; DWORD dSize = 0; @@ -70,18 +69,35 @@ int hax_populate_ram(uint64_t va, uint32_t size) return -EINVAL; } - info.size = size; - info.va = va; - hDeviceVM = hax_global.vm->fd; - - ret = DeviceIoControl(hDeviceVM, - HAX_VM_IOCTL_ALLOC_RAM, - &info, sizeof(info), NULL, 0, &dSize, - (LPOVERLAPPED) NULL); + if (hax_global.supports_64bit_ramblock) { + struct hax_ramblock_info ramblock = { + .start_va = va, + .size = size, + .reserved = 0 + }; + + ret = DeviceIoControl(hDeviceVM, + HAX_VM_IOCTL_ADD_RAMBLOCK, + &ramblock, sizeof(ramblock), NULL, 0, &dSize, + (LPOVERLAPPED) NULL); + } else { + struct hax_alloc_ram_info info = { + .size = (uint32_t) size, + .pad = 0, + .va = va + }; + + ret = DeviceIoControl(hDeviceVM, + HAX_VM_IOCTL_ALLOC_RAM, + &info, sizeof(info), NULL, 0, &dSize, + (LPOVERLAPPED) NULL); + } if (!ret) { - fprintf(stderr, "Failed to allocate %x memory\n", size); + fprintf(stderr, "Failed to register RAM block: va=0x%" PRIx64 + ", size=0x%" PRIx64 ", method=%s\n", va, size, + hax_global.supports_64bit_ramblock ? "new" : "legacy"); return ret; } diff --git a/target/i386/hax-windows.h b/target/i386/hax-windows.h index 20e2f85407..12cbd813dc 100644 --- a/target/i386/hax-windows.h +++ b/target/i386/hax-windows.h @@ -57,6 +57,8 @@ static inline int hax_invalid_fd(hax_fd fd) METHOD_BUFFERED, FILE_ANY_ACCESS) #define HAX_VM_IOCTL_VCPU_DESTROY CTL_CODE(HAX_DEVICE_TYPE, 0x905, \ METHOD_BUFFERED, FILE_ANY_ACCESS) +#define HAX_VM_IOCTL_ADD_RAMBLOCK CTL_CODE(HAX_DEVICE_TYPE, 0x913, \ + METHOD_BUFFERED, FILE_ANY_ACCESS) #define HAX_VCPU_IOCTL_RUN CTL_CODE(HAX_DEVICE_TYPE, 0x906, \ METHOD_BUFFERED, FILE_ANY_ACCESS) |