mirror of https://gitee.com/openkylin/qemu.git
pc, acpi, virtio: fixes, test speedup for rc1
Some fixes all over the place. Notably vhost-user gained a new message to set endian-ness. Borderline for 2.10 but seems to be the only way to fix legacy guests. Also pc tests are run on kvm now. Not a fix at all but doesn't touch qemu itself, so I merged it since I had to run these a lot and I just got tired of waiting for these to finish. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJZgPRvAAoJECgfDbjSjVRpUKAH/RE1PohaH/klzEVFLPZUdISN /1zOdFN0BgVOUxS2udLVdZBUrWBiJWt11fbzASeGtOu3ruTpVfp69C7HUH8z4MOB cyBWgtcf7qQc9cqE0VGO1kLU+ujSyPlkZonjWVfeCrf298SElIXUNVXcihqVsglA VAL+tIUFT2Bbc3SH5xGsqHCMAy1hNRkEuF5t7enphOoxm7CdqghDLMfUEW65igYg XNt3DELfFDQVnwGP8DWSWjgLVAvGAGWGNHQ9QD/FO5mdVrXh1lukV8ZtXf6K2VJc svR670n3ZbMOkEIOGJYcYUFEKMgJXLNEpQX8WRM+vjnuEpDML6bBROtA8hckRv8= =9TSs -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging pc, acpi, virtio: fixes, test speedup for rc1 Some fixes all over the place. Notably vhost-user gained a new message to set endian-ness. Borderline for 2.10 but seems to be the only way to fix legacy guests. Also pc tests are run on kvm now. Not a fix at all but doesn't touch qemu itself, so I merged it since I had to run these a lot and I just got tired of waiting for these to finish. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Tue 01 Aug 2017 22:36:47 BST # gpg: using RSA key 0x281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: pc: acpi: force FADT rev1 for 440fx based machine types pc: make 'pc.rom' readonly when machine has PCI enabled vhost-user: fix watcher need be removed when vhost-user hotplug tests/bios-tables-test: Compiler warning fix accel: cleanup error output intel_iommu: use access_flags for iotlb intel_iommu: fix iova for pt vhost-user: fix legacy cross-endian configurations vhost: fix a memory leak tests: switch pxe and vm gen id tests to use kvm Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d3d183a638
|
@ -326,6 +326,7 @@ Protocol features
|
|||
#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
|
||||
#define VHOST_USER_PROTOCOL_F_MTU 4
|
||||
#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
|
||||
#define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6
|
||||
|
||||
Master message types
|
||||
--------------------
|
||||
|
@ -580,6 +581,21 @@ Master message types
|
|||
This request should be send only when VIRTIO_F_IOMMU_PLATFORM feature
|
||||
has been successfully negotiated.
|
||||
|
||||
* VHOST_USER_SET_VRING_ENDIAN
|
||||
|
||||
Id: 23
|
||||
Equivalent ioctl: VHOST_SET_VRING_ENDIAN
|
||||
Master payload: vring state description
|
||||
|
||||
Set the endianess of a VQ for legacy devices. Little-endian is indicated
|
||||
with state.num set to 0 and big-endian is indicated with state.num set
|
||||
to 1. Other values are invalid.
|
||||
This request should be sent only when VHOST_USER_PROTOCOL_F_CROSS_ENDIAN
|
||||
has been negotiated.
|
||||
Backends that negotiated this feature should handle both endianesses
|
||||
and expect this message once (per VQ) during device configuration
|
||||
(ie. before the master starts the VQ).
|
||||
|
||||
Slave message types
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ typedef struct AcpiMcfgInfo {
|
|||
} AcpiMcfgInfo;
|
||||
|
||||
typedef struct AcpiPmInfo {
|
||||
bool force_rev1_fadt;
|
||||
bool s3_disabled;
|
||||
bool s4_disabled;
|
||||
bool pcihp_bridge_en;
|
||||
|
@ -129,10 +130,13 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
|
|||
Object *obj = NULL;
|
||||
QObject *o;
|
||||
|
||||
pm->force_rev1_fadt = false;
|
||||
pm->cpu_hp_io_base = 0;
|
||||
pm->pcihp_io_base = 0;
|
||||
pm->pcihp_io_len = 0;
|
||||
if (piix) {
|
||||
/* w2k requires FADT(rev1) or it won't boot, keep PC compatible */
|
||||
pm->force_rev1_fadt = true;
|
||||
obj = piix;
|
||||
pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
|
||||
pm->pcihp_io_base =
|
||||
|
@ -304,6 +308,9 @@ static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, AcpiPmInfo *pm)
|
|||
fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
|
||||
}
|
||||
fadt->century = RTC_CENTURY;
|
||||
if (pm->force_rev1_fadt) {
|
||||
return;
|
||||
}
|
||||
|
||||
fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_RESET_REG_SUP);
|
||||
fadt->reset_value = 0xf;
|
||||
|
@ -342,6 +349,8 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
|
|||
unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
|
||||
unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
|
||||
unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
|
||||
int fadt_size = sizeof(*fadt);
|
||||
int rev = 3;
|
||||
|
||||
/* FACS address to be filled by Guest linker */
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
|
@ -353,12 +362,17 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
|
|||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
|
||||
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
|
||||
if (pm->force_rev1_fadt) {
|
||||
rev = 1;
|
||||
fadt_size = offsetof(typeof(*fadt), reset_register);
|
||||
} else {
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
|
||||
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
|
||||
}
|
||||
|
||||
build_header(linker, table_data,
|
||||
(void *)fadt, "FACP", sizeof(*fadt), 3, oem_id, oem_table_id);
|
||||
(void *)fadt, "FACP", fadt_size, rev, oem_id, oem_table_id);
|
||||
}
|
||||
|
||||
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
||||
|
|
|
@ -237,8 +237,7 @@ out:
|
|||
|
||||
static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
|
||||
uint16_t domain_id, hwaddr addr, uint64_t slpte,
|
||||
bool read_flags, bool write_flags,
|
||||
uint32_t level)
|
||||
uint8_t access_flags, uint32_t level)
|
||||
{
|
||||
VTDIOTLBEntry *entry = g_malloc(sizeof(*entry));
|
||||
uint64_t *key = g_malloc(sizeof(*key));
|
||||
|
@ -253,8 +252,7 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
|
|||
entry->gfn = gfn;
|
||||
entry->domain_id = domain_id;
|
||||
entry->slpte = slpte;
|
||||
entry->read_flags = read_flags;
|
||||
entry->write_flags = write_flags;
|
||||
entry->access_flags = access_flags;
|
||||
entry->mask = vtd_slpt_level_page_mask(level);
|
||||
*key = vtd_get_iotlb_key(gfn, source_id, level);
|
||||
g_hash_table_replace(s->iotlb, key, entry);
|
||||
|
@ -1087,6 +1085,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
|
|||
bool is_fpd_set = false;
|
||||
bool reads = true;
|
||||
bool writes = true;
|
||||
uint8_t access_flags;
|
||||
VTDIOTLBEntry *iotlb_entry;
|
||||
|
||||
/*
|
||||
|
@ -1101,8 +1100,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
|
|||
trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte,
|
||||
iotlb_entry->domain_id);
|
||||
slpte = iotlb_entry->slpte;
|
||||
reads = iotlb_entry->read_flags;
|
||||
writes = iotlb_entry->write_flags;
|
||||
access_flags = iotlb_entry->access_flags;
|
||||
page_mask = iotlb_entry->mask;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1139,9 +1137,9 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
|
|||
* Also, let's ignore IOTLB caching as well for PT devices.
|
||||
*/
|
||||
if (vtd_ce_get_type(&ce) == VTD_CONTEXT_TT_PASS_THROUGH) {
|
||||
entry->iova = addr & VTD_PAGE_MASK;
|
||||
entry->iova = addr & VTD_PAGE_MASK_4K;
|
||||
entry->translated_addr = entry->iova;
|
||||
entry->addr_mask = VTD_PAGE_MASK;
|
||||
entry->addr_mask = ~VTD_PAGE_MASK_4K;
|
||||
entry->perm = IOMMU_RW;
|
||||
trace_vtd_translate_pt(source_id, entry->iova);
|
||||
|
||||
|
@ -1172,13 +1170,14 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
|
|||
}
|
||||
|
||||
page_mask = vtd_slpt_level_page_mask(level);
|
||||
access_flags = IOMMU_ACCESS_FLAG(reads, writes);
|
||||
vtd_update_iotlb(s, source_id, VTD_CONTEXT_ENTRY_DID(ce.hi), addr, slpte,
|
||||
reads, writes, level);
|
||||
access_flags, level);
|
||||
out:
|
||||
entry->iova = addr & page_mask;
|
||||
entry->translated_addr = vtd_get_slpte_addr(slpte) & page_mask;
|
||||
entry->addr_mask = ~page_mask;
|
||||
entry->perm = IOMMU_ACCESS_FLAG(reads, writes);
|
||||
entry->perm = access_flags;
|
||||
return true;
|
||||
|
||||
error:
|
||||
|
|
|
@ -384,7 +384,6 @@ typedef struct VTDIOTLBPageInvInfo VTDIOTLBPageInvInfo;
|
|||
/* Pagesize of VTD paging structures, including root and context tables */
|
||||
#define VTD_PAGE_SHIFT 12
|
||||
#define VTD_PAGE_SIZE (1ULL << VTD_PAGE_SHIFT)
|
||||
#define VTD_PAGE_MASK (VTD_PAGE_SIZE - 1)
|
||||
|
||||
#define VTD_PAGE_SHIFT_4K 12
|
||||
#define VTD_PAGE_MASK_4K (~((1ULL << VTD_PAGE_SHIFT_4K) - 1))
|
||||
|
|
|
@ -1443,6 +1443,9 @@ void pc_memory_init(PCMachineState *pcms,
|
|||
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
|
||||
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
|
||||
&error_fatal);
|
||||
if (pcmc->pci_enabled) {
|
||||
memory_region_set_readonly(option_rom_mr, true);
|
||||
}
|
||||
memory_region_add_subregion_overlap(rom_memory,
|
||||
PC_ROM_MIN_VGA,
|
||||
option_rom_mr,
|
||||
|
|
|
@ -52,11 +52,13 @@ static int vhost_kernel_memslots_limit(struct vhost_dev *dev)
|
|||
&s, NULL, NULL)) {
|
||||
uint64_t val = g_ascii_strtoull(s, NULL, 10);
|
||||
if (!((val == G_MAXUINT64 || !val) && errno)) {
|
||||
g_free(s);
|
||||
return val;
|
||||
}
|
||||
error_report("ignoring invalid max_mem_regions value in vhost module:"
|
||||
" %s", s);
|
||||
}
|
||||
g_free(s);
|
||||
return limit;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ enum VhostUserProtocolFeature {
|
|||
VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
|
||||
VHOST_USER_PROTOCOL_F_NET_MTU = 4,
|
||||
VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
|
||||
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
|
||||
|
||||
VHOST_USER_PROTOCOL_F_MAX
|
||||
};
|
||||
|
@ -63,6 +64,7 @@ typedef enum VhostUserRequest {
|
|||
VHOST_USER_NET_SET_MTU = 20,
|
||||
VHOST_USER_SET_SLAVE_REQ_FD = 21,
|
||||
VHOST_USER_IOTLB_MSG = 22,
|
||||
VHOST_USER_SET_VRING_ENDIAN = 23,
|
||||
VHOST_USER_MAX
|
||||
} VhostUserRequest;
|
||||
|
||||
|
@ -367,8 +369,25 @@ static int vhost_user_set_vring_addr(struct vhost_dev *dev,
|
|||
static int vhost_user_set_vring_endian(struct vhost_dev *dev,
|
||||
struct vhost_vring_state *ring)
|
||||
{
|
||||
bool cross_endian = virtio_has_feature(dev->protocol_features,
|
||||
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN);
|
||||
VhostUserMsg msg = {
|
||||
.request = VHOST_USER_SET_VRING_ENDIAN,
|
||||
.flags = VHOST_USER_VERSION,
|
||||
.payload.state = *ring,
|
||||
.size = sizeof(msg.payload.state),
|
||||
};
|
||||
|
||||
if (!cross_endian) {
|
||||
error_report("vhost-user trying to send unhandled ioctl");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vhost_set_vring(struct vhost_dev *dev,
|
||||
|
|
|
@ -103,8 +103,7 @@ struct VTDIOTLBEntry {
|
|||
uint16_t domain_id;
|
||||
uint64_t slpte;
|
||||
uint64_t mask;
|
||||
bool read_flags;
|
||||
bool write_flags;
|
||||
uint8_t access_flags;
|
||||
};
|
||||
|
||||
/* VT-d Source-ID Qualifier types */
|
||||
|
|
|
@ -151,6 +151,10 @@ static void vhost_user_cleanup(NetClientState *nc)
|
|||
s->vhost_net = NULL;
|
||||
}
|
||||
if (nc->queue_index == 0) {
|
||||
if (s->watch) {
|
||||
g_source_remove(s->watch);
|
||||
s->watch = 0;
|
||||
}
|
||||
qemu_chr_fe_deinit(&s->chr, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ static void test_acpi_rsdt_table(test_data *data)
|
|||
/* compute the table entries in rsdt */
|
||||
tables_nr = (rsdt_table->length - sizeof(AcpiRsdtDescriptorRev1)) /
|
||||
sizeof(uint32_t);
|
||||
g_assert_cmpint(tables_nr, >, 0);
|
||||
g_assert(tables_nr > 0);
|
||||
|
||||
/* get the addresses of the tables pointed by rsdt */
|
||||
tables = g_new0(uint32_t, tables_nr);
|
||||
|
|
|
@ -25,7 +25,7 @@ static void test_pxe_one(const char *params, bool ipv6)
|
|||
{
|
||||
char *args;
|
||||
|
||||
args = g_strdup_printf("-machine accel=tcg -nodefaults -boot order=n "
|
||||
args = g_strdup_printf("-machine accel=kvm:tcg -nodefaults -boot order=n "
|
||||
"-netdev user,id=" NETNAME ",tftp=./,bootfile=%s,"
|
||||
"ipv4=%s,ipv6=%s %s", disk, ipv6 ? "off" : "on",
|
||||
ipv6 ? "on" : "off", params);
|
||||
|
|
|
@ -132,7 +132,7 @@ static char disk[] = "tests/vmgenid-test-disk-XXXXXX";
|
|||
|
||||
static char *guid_cmd_strdup(const char *guid)
|
||||
{
|
||||
return g_strdup_printf("-machine accel=tcg "
|
||||
return g_strdup_printf("-machine accel=kvm:tcg "
|
||||
"-device vmgenid,id=testvgid,guid=%s "
|
||||
"-drive id=hd0,if=none,file=%s,format=raw "
|
||||
"-device ide-hd,drive=hd0 ",
|
||||
|
|
Loading…
Reference in New Issue