mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-14 17:07:24 +00:00
virtio,acpi,pci,pc: backlog from pre-5.0
Mostly fixes, cleanups, but also new features for arm/virt and pc acpi. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAl6wJjoPHG1zdEByZWRo YXQuY29tAAoJECgfDbjSjVRp1jkH/3Ilvrk6OEtKvOdgXbg2kwm6PYNuvVUZDAN5 mvMTjnGJFyGt/6REgMR0u6qRerNw7L9vpXeb2AzIvAYxxMVvQks2biOQN16BHL9E P6y9OZDyjDyyOW2f3bEvi58u0d7FOYIZXCdV0vfYk4cM6sxaxHcE4zjOKyUq5tQl R0JTKQZsWV7yI9wjEx16BaVOuZUVjoo9ym9QjiSFDEHKPlaQzBXbXKttXySgoM7i IKZ3YqKH6U2mgtfyYUhpvBh+4Bkhzrd+hsXelGBqJUMRrYuP9E57rWvHy6aSIJgj +HBgqJUZ0RCQk6kR11ZX3SUKeLEYgRP3SiF52FtX/p12vgqe4Lk= =GV25 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging virtio,acpi,pci,pc: backlog from pre-5.0 Mostly fixes, cleanups, but also new features for arm/virt and pc acpi. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Mon 04 May 2020 15:27:06 BST # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # 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: (29 commits) hw/i386: Make vmmouse helpers static hw/i386: Add 'vmport.h' local header hw/i386/vmport: Remove unused 'hw/input/i8042.h' include hw/i386/pc: Create 'vmport' device in place acpi: unit-test: Update WAET ACPI Table expected binaries acpi: Add Windows ACPI Emulated Device Table (WAET) acpi: unit-test: Ignore diff in WAET ACPI table Refactor vhost_user_set_mem_table functions tests/acpi: add expected tables for bios-tables-test bios-tables-test: test pc-dimm and nvdimm coldplug for arm/virt tests: Update ACPI tables list for upcoming arm/virt test changes hw/arm/virt: Add nvdimm hotplug support hw/arm/virt: Add nvdimm hot-plug infrastructure nvdimm: Use configurable ACPI IO base and size hw/acpi/nvdimm: Fix for NVDIMM incorrect DSM output buffer length acpi: DSDT without _STA checkpatch: ignore allowed diff list checkpatch: fix acpi check with multiple file name vhost-user-blk: fix invalid memory access virtio-pci: update virtio pci bar layout documentation ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
5375af3cd7
@ -63,7 +63,8 @@ GED IO interface (4 byte access)
|
||||
bits:
|
||||
0: Memory hotplug event
|
||||
1: System power down event
|
||||
2-31: Reserved
|
||||
2: NVDIMM hotplug event
|
||||
3-31: Reserved
|
||||
|
||||
**write_access:**
|
||||
|
||||
|
@ -20,6 +20,6 @@ common-obj-$(CONFIG_TPM) += tpm.o
|
||||
common-obj-$(CONFIG_IPMI) += ipmi.o
|
||||
common-obj-$(call lnot,$(CONFIG_IPMI)) += ipmi-stub.o
|
||||
else
|
||||
common-obj-y += acpi-stub.o
|
||||
common-obj-y += acpi-stub.o aml-build-stub.o
|
||||
endif
|
||||
common-obj-$(CONFIG_ALL) += acpi-stub.o acpi-x86-stub.o ipmi-stub.o
|
||||
common-obj-$(CONFIG_ALL) += acpi-stub.o aml-build-stub.o acpi-x86-stub.o ipmi-stub.o
|
||||
|
79
hw/acpi/aml-build-stub.c
Normal file
79
hw/acpi/aml-build-stub.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* ACPI aml builder stubs for platforms that don't support ACPI.
|
||||
*
|
||||
* Copyright (c) 2006 Fabrice Bellard
|
||||
* Copyright (c) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/acpi/acpi.h"
|
||||
#include "hw/acpi/aml-build.h"
|
||||
|
||||
void aml_append(Aml *parent_ctx, Aml *child)
|
||||
{
|
||||
}
|
||||
|
||||
Aml *aml_resource_template(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_device(const char *name_format, ...)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_eisaid(const char *str)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_name_decl(const char *name, Aml *val)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
|
||||
uint8_t aln, uint8_t len)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_irq_no_flags(uint8_t irq)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_int(const uint64_t val)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_package(uint8_t num_elements)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
|
||||
uint8_t channel)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
|
||||
{
|
||||
return NULL;
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
#include "hw/acpi/generic_event_device.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "hw/mem/nvdimm.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/error-report.h"
|
||||
@ -23,6 +24,7 @@
|
||||
static const uint32_t ged_supported_events[] = {
|
||||
ACPI_GED_MEM_HOTPLUG_EVT,
|
||||
ACPI_GED_PWR_DOWN_EVT,
|
||||
ACPI_GED_NVDIMM_HOTPLUG_EVT,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -110,6 +112,11 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
|
||||
aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
|
||||
aml_int(0x80)));
|
||||
break;
|
||||
case ACPI_GED_NVDIMM_HOTPLUG_EVT:
|
||||
aml_append(if_ctx,
|
||||
aml_notify(aml_name("\\_SB.NVDR"),
|
||||
aml_int(0x80)));
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Please make sure all the events in ged_supported_events[]
|
||||
@ -175,7 +182,11 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
AcpiGedState *s = ACPI_GED(hotplug_dev);
|
||||
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||
acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
|
||||
nvdimm_acpi_plug_cb(hotplug_dev, dev);
|
||||
} else {
|
||||
acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
|
||||
}
|
||||
} else {
|
||||
error_setg(errp, "virt: device plug request for unsupported device"
|
||||
" type: %s", object_get_typename(OBJECT(dev)));
|
||||
@ -192,6 +203,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
|
||||
sel = ACPI_GED_MEM_HOTPLUG_EVT;
|
||||
} else if (ev & ACPI_POWER_DOWN_STATUS) {
|
||||
sel = ACPI_GED_PWR_DOWN_EVT;
|
||||
} else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
|
||||
sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
|
||||
} else {
|
||||
/* Unknown event. Return without generating interrupt. */
|
||||
warn_report("GED: Unsupported event %d. No irq injected", ev);
|
||||
|
@ -900,11 +900,13 @@ void nvdimm_acpi_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev)
|
||||
}
|
||||
|
||||
void nvdimm_init_acpi_state(NVDIMMState *state, MemoryRegion *io,
|
||||
struct AcpiGenericAddress dsm_io,
|
||||
FWCfgState *fw_cfg, Object *owner)
|
||||
{
|
||||
state->dsm_io = dsm_io;
|
||||
memory_region_init_io(&state->io_mr, owner, &nvdimm_dsm_ops, state,
|
||||
"nvdimm-acpi-io", NVDIMM_ACPI_IO_LEN);
|
||||
memory_region_add_subregion(io, NVDIMM_ACPI_IO_BASE, &state->io_mr);
|
||||
"nvdimm-acpi-io", dsm_io.bit_width >> 3);
|
||||
memory_region_add_subregion(io, dsm_io.address, &state->io_mr);
|
||||
|
||||
state->dsm_mem = g_array_new(false, true /* clear */, 1);
|
||||
acpi_data_push(state->dsm_mem, sizeof(NvdimmDsmIn));
|
||||
@ -933,12 +935,15 @@ void nvdimm_init_acpi_state(NVDIMMState *state, MemoryRegion *io,
|
||||
|
||||
#define NVDIMM_QEMU_RSVD_UUID "648B9CF2-CDA1-4312-8AD9-49C4AF32BD62"
|
||||
|
||||
static void nvdimm_build_common_dsm(Aml *dev)
|
||||
static void nvdimm_build_common_dsm(Aml *dev,
|
||||
NVDIMMState *nvdimm_state)
|
||||
{
|
||||
Aml *method, *ifctx, *function, *handle, *uuid, *dsm_mem, *elsectx2;
|
||||
Aml *elsectx, *unsupport, *unpatched, *expected_uuid, *uuid_invalid;
|
||||
Aml *pckg, *pckg_index, *pckg_buf, *field, *dsm_out_buf, *dsm_out_buf_size;
|
||||
Aml *whilectx, *offset;
|
||||
uint8_t byte_list[1];
|
||||
AmlRegionSpace rs;
|
||||
|
||||
method = aml_method(NVDIMM_COMMON_DSM, 5, AML_SERIALIZED);
|
||||
uuid = aml_arg(0);
|
||||
@ -949,9 +954,16 @@ static void nvdimm_build_common_dsm(Aml *dev)
|
||||
|
||||
aml_append(method, aml_store(aml_name(NVDIMM_ACPI_MEM_ADDR), dsm_mem));
|
||||
|
||||
if (nvdimm_state->dsm_io.space_id == AML_AS_SYSTEM_IO) {
|
||||
rs = AML_SYSTEM_IO;
|
||||
} else {
|
||||
rs = AML_SYSTEM_MEMORY;
|
||||
}
|
||||
|
||||
/* map DSM memory and IO into ACPI namespace. */
|
||||
aml_append(method, aml_operation_region(NVDIMM_DSM_IOPORT, AML_SYSTEM_IO,
|
||||
aml_int(NVDIMM_ACPI_IO_BASE), NVDIMM_ACPI_IO_LEN));
|
||||
aml_append(method, aml_operation_region(NVDIMM_DSM_IOPORT, rs,
|
||||
aml_int(nvdimm_state->dsm_io.address),
|
||||
nvdimm_state->dsm_io.bit_width >> 3));
|
||||
aml_append(method, aml_operation_region(NVDIMM_DSM_MEMORY,
|
||||
AML_SYSTEM_MEMORY, dsm_mem, sizeof(NvdimmDsmIn)));
|
||||
|
||||
@ -966,7 +978,7 @@ static void nvdimm_build_common_dsm(Aml *dev)
|
||||
field = aml_field(NVDIMM_DSM_IOPORT, AML_DWORD_ACC, AML_NOLOCK,
|
||||
AML_PRESERVE);
|
||||
aml_append(field, aml_named_field(NVDIMM_DSM_NOTIFY,
|
||||
NVDIMM_ACPI_IO_LEN * BITS_PER_BYTE));
|
||||
nvdimm_state->dsm_io.bit_width));
|
||||
aml_append(method, field);
|
||||
|
||||
/*
|
||||
@ -1091,13 +1103,46 @@ static void nvdimm_build_common_dsm(Aml *dev)
|
||||
/* RLEN is not included in the payload returned to guest. */
|
||||
aml_append(method, aml_subtract(aml_name(NVDIMM_DSM_OUT_BUF_SIZE),
|
||||
aml_int(4), dsm_out_buf_size));
|
||||
|
||||
/*
|
||||
* As per ACPI spec 6.3, Table 19-419 Object Conversion Rules, if
|
||||
* the Buffer Field <= to the size of an Integer (in bits), it will
|
||||
* be treated as an integer. Moreover, the integer size depends on
|
||||
* DSDT tables revision number. If revision number is < 2, integer
|
||||
* size is 32 bits, otherwise it is 64 bits.
|
||||
* Because of this CreateField() canot be used if RLEN < Integer Size.
|
||||
*
|
||||
* Also please note that APCI ASL operator SizeOf() doesn't support
|
||||
* Integer and there isn't any other way to figure out the Integer
|
||||
* size. Hence we assume 8 byte as Integer size and if RLEN < 8 bytes,
|
||||
* build dsm_out_buf byte by byte.
|
||||
*/
|
||||
ifctx = aml_if(aml_lless(dsm_out_buf_size, aml_int(8)));
|
||||
offset = aml_local(2);
|
||||
aml_append(ifctx, aml_store(aml_int(0), offset));
|
||||
aml_append(ifctx, aml_name_decl("TBUF", aml_buffer(1, NULL)));
|
||||
aml_append(ifctx, aml_store(aml_buffer(0, NULL), dsm_out_buf));
|
||||
|
||||
whilectx = aml_while(aml_lless(offset, dsm_out_buf_size));
|
||||
/* Copy 1 byte at offset from ODAT to temporary buffer(TBUF). */
|
||||
aml_append(whilectx, aml_store(aml_derefof(aml_index(
|
||||
aml_name(NVDIMM_DSM_OUT_BUF), offset)),
|
||||
aml_index(aml_name("TBUF"), aml_int(0))));
|
||||
aml_append(whilectx, aml_concatenate(dsm_out_buf, aml_name("TBUF"),
|
||||
dsm_out_buf));
|
||||
aml_append(whilectx, aml_increment(offset));
|
||||
aml_append(ifctx, whilectx);
|
||||
|
||||
aml_append(ifctx, aml_return(dsm_out_buf));
|
||||
aml_append(method, ifctx);
|
||||
|
||||
/* If RLEN >= Integer size, just use CreateField() operator */
|
||||
aml_append(method, aml_store(aml_shiftleft(dsm_out_buf_size, aml_int(3)),
|
||||
dsm_out_buf_size));
|
||||
aml_append(method, aml_create_field(aml_name(NVDIMM_DSM_OUT_BUF),
|
||||
aml_int(0), dsm_out_buf_size, "OBUF"));
|
||||
aml_append(method, aml_concatenate(aml_buffer(0, NULL), aml_name("OBUF"),
|
||||
dsm_out_buf));
|
||||
aml_append(method, aml_return(dsm_out_buf));
|
||||
aml_append(method, aml_return(aml_name("OBUF")));
|
||||
|
||||
aml_append(dev, method);
|
||||
}
|
||||
|
||||
@ -1234,7 +1279,8 @@ static void nvdimm_build_nvdimm_devices(Aml *root_dev, uint32_t ram_slots)
|
||||
}
|
||||
|
||||
static void nvdimm_build_ssdt(GArray *table_offsets, GArray *table_data,
|
||||
BIOSLinker *linker, GArray *dsm_dma_area,
|
||||
BIOSLinker *linker,
|
||||
NVDIMMState *nvdimm_state,
|
||||
uint32_t ram_slots)
|
||||
{
|
||||
Aml *ssdt, *sb_scope, *dev;
|
||||
@ -1262,7 +1308,7 @@ static void nvdimm_build_ssdt(GArray *table_offsets, GArray *table_data,
|
||||
*/
|
||||
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0012")));
|
||||
|
||||
nvdimm_build_common_dsm(dev);
|
||||
nvdimm_build_common_dsm(dev, nvdimm_state);
|
||||
|
||||
/* 0 is reserved for root device. */
|
||||
nvdimm_build_device_dsm(dev, 0);
|
||||
@ -1281,7 +1327,7 @@ static void nvdimm_build_ssdt(GArray *table_offsets, GArray *table_data,
|
||||
NVDIMM_ACPI_MEM_ADDR);
|
||||
|
||||
bios_linker_loader_alloc(linker,
|
||||
NVDIMM_DSM_MEM_FILE, dsm_dma_area,
|
||||
NVDIMM_DSM_MEM_FILE, nvdimm_state->dsm_mem,
|
||||
sizeof(NvdimmDsmIn), false /* high memory */);
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_TABLE_FILE, mem_addr_offset, sizeof(uint32_t),
|
||||
@ -1303,7 +1349,7 @@ void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
|
||||
return;
|
||||
}
|
||||
|
||||
nvdimm_build_ssdt(table_offsets, table_data, linker, state->dsm_mem,
|
||||
nvdimm_build_ssdt(table_offsets, table_data, linker, state,
|
||||
ram_slots);
|
||||
|
||||
device_list = nvdimm_get_device_list();
|
||||
|
@ -25,6 +25,7 @@ config ARM_VIRT
|
||||
select DIMM
|
||||
select ACPI_MEMORY_HOTPLUG
|
||||
select ACPI_HW_REDUCED
|
||||
select ACPI_NVDIMM
|
||||
|
||||
config CHEETAH
|
||||
bool
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "hw/pci/pcie_host.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/arm/virt.h"
|
||||
#include "hw/mem/nvdimm.h"
|
||||
#include "sysemu/numa.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "kvm_arm.h"
|
||||
@ -826,6 +827,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
||||
}
|
||||
}
|
||||
|
||||
if (ms->nvdimms_state->is_enabled) {
|
||||
nvdimm_build_acpi(table_offsets, tables_blob, tables->linker,
|
||||
ms->nvdimms_state, ms->ram_slots);
|
||||
}
|
||||
|
||||
if (its_class_name() && !vmc->no_its) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_iort(tables_blob, tables->linker, vms);
|
||||
|
@ -150,6 +150,7 @@ static const MemMapEntry base_memmap[] = {
|
||||
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
|
||||
[VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
|
||||
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
|
||||
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
|
||||
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
|
||||
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
|
||||
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
|
||||
@ -567,6 +568,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
|
||||
event |= ACPI_GED_MEM_HOTPLUG_EVT;
|
||||
}
|
||||
|
||||
if (ms->nvdimms_state->is_enabled) {
|
||||
event |= ACPI_GED_NVDIMM_HOTPLUG_EVT;
|
||||
}
|
||||
|
||||
dev = qdev_create(NULL, TYPE_ACPI_GED);
|
||||
qdev_prop_set_uint32(dev, "ged-event", event);
|
||||
|
||||
@ -1884,6 +1889,18 @@ static void machvirt_init(MachineState *machine)
|
||||
|
||||
create_platform_bus(vms);
|
||||
|
||||
if (machine->nvdimms_state->is_enabled) {
|
||||
const struct AcpiGenericAddress arm_virt_nvdimm_acpi_dsmio = {
|
||||
.space_id = AML_AS_SYSTEM_MEMORY,
|
||||
.address = vms->memmap[VIRT_NVDIMM_ACPI].base,
|
||||
.bit_width = NVDIMM_ACPI_IO_LEN << 3
|
||||
};
|
||||
|
||||
nvdimm_init_acpi_state(machine->nvdimms_state, sysmem,
|
||||
arm_virt_nvdimm_acpi_dsmio,
|
||||
vms->fw_cfg, OBJECT(vms));
|
||||
}
|
||||
|
||||
vms->bootinfo.ram_size = machine->ram_size;
|
||||
vms->bootinfo.nb_cpus = smp_cpus;
|
||||
vms->bootinfo.board_id = -1;
|
||||
@ -2075,19 +2092,20 @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||||
const MachineState *ms = MACHINE(hotplug_dev);
|
||||
const bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
|
||||
|
||||
if (is_nvdimm) {
|
||||
error_setg(errp, "nvdimm is not yet supported");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vms->acpi_dev) {
|
||||
error_setg(errp,
|
||||
"memory hotplug is not enabled: missing acpi-ged device");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_nvdimm && !ms->nvdimms_state->is_enabled) {
|
||||
error_setg(errp, "nvdimm is not enabled: add 'nvdimm=on' to '-M'");
|
||||
return;
|
||||
}
|
||||
|
||||
pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
|
||||
}
|
||||
|
||||
@ -2095,6 +2113,8 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||||
MachineState *ms = MACHINE(hotplug_dev);
|
||||
bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
|
||||
Error *local_err = NULL;
|
||||
|
||||
pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err);
|
||||
@ -2102,6 +2122,10 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (is_nvdimm) {
|
||||
nvdimm_plug(ms->nvdimms_state);
|
||||
}
|
||||
|
||||
hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev),
|
||||
dev, &error_abort);
|
||||
|
||||
@ -2226,6 +2250,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
||||
hc->plug = virt_machine_device_plug_cb;
|
||||
hc->unplug_request = virt_machine_device_unplug_request_cb;
|
||||
mc->numa_mem_supported = true;
|
||||
mc->nvdimm_supported = true;
|
||||
mc->auto_enable_numa_with_memhp = true;
|
||||
mc->default_ram_id = "mach-virt.ram";
|
||||
|
||||
|
@ -441,7 +441,9 @@ reconnect:
|
||||
|
||||
virtio_err:
|
||||
g_free(s->vhost_vqs);
|
||||
s->vhost_vqs = NULL;
|
||||
g_free(s->inflight);
|
||||
s->inflight = NULL;
|
||||
for (i = 0; i < s->num_queues; i++) {
|
||||
virtio_delete_queue(s->virtqs[i]);
|
||||
}
|
||||
@ -462,7 +464,9 @@ static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
|
||||
vhost_dev_cleanup(&s->dev);
|
||||
vhost_dev_free_inflight(s->inflight);
|
||||
g_free(s->vhost_vqs);
|
||||
s->vhost_vqs = NULL;
|
||||
g_free(s->inflight);
|
||||
s->inflight = NULL;
|
||||
|
||||
for (i = 0; i < s->num_queues; i++) {
|
||||
virtio_delete_queue(s->virtqs[i]);
|
||||
|
@ -114,6 +114,7 @@ static void virtio_vga_base_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
*/
|
||||
vpci_dev->modern_mem_bar_idx = 2;
|
||||
vpci_dev->msix_bar_idx = 4;
|
||||
vpci_dev->modern_io_bar_idx = 5;
|
||||
|
||||
if (!(vpci_dev->flags & VIRTIO_PCI_FLAG_PAGE_PER_VQ)) {
|
||||
/*
|
||||
|
@ -128,6 +128,12 @@ typedef struct FwCfgTPMConfig {
|
||||
|
||||
static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg);
|
||||
|
||||
const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio = {
|
||||
.space_id = AML_AS_SYSTEM_IO,
|
||||
.address = NVDIMM_ACPI_IO_BASE,
|
||||
.bit_width = NVDIMM_ACPI_IO_LEN << 3
|
||||
};
|
||||
|
||||
static void init_common_fadt_data(MachineState *ms, Object *o,
|
||||
AcpiFadtData *data)
|
||||
{
|
||||
@ -1151,14 +1157,11 @@ static Aml *build_kbd_device_aml(void)
|
||||
{
|
||||
Aml *dev;
|
||||
Aml *crs;
|
||||
Aml *method;
|
||||
|
||||
dev = aml_device("KBD");
|
||||
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0303")));
|
||||
|
||||
method = aml_method("_STA", 0, AML_NOTSERIALIZED);
|
||||
aml_append(method, aml_return(aml_int(0x0f)));
|
||||
aml_append(dev, method);
|
||||
aml_append(dev, aml_name_decl("_STA", aml_int(0xf)));
|
||||
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs, aml_io(AML_DECODE16, 0x0060, 0x0060, 0x01, 0x01));
|
||||
@ -1173,14 +1176,11 @@ static Aml *build_mouse_device_aml(void)
|
||||
{
|
||||
Aml *dev;
|
||||
Aml *crs;
|
||||
Aml *method;
|
||||
|
||||
dev = aml_device("MOU");
|
||||
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0F13")));
|
||||
|
||||
method = aml_method("_STA", 0, AML_NOTSERIALIZED);
|
||||
aml_append(method, aml_return(aml_int(0x0f)));
|
||||
aml_append(dev, method);
|
||||
aml_append(dev, aml_name_decl("_STA", aml_int(0xf)));
|
||||
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs, aml_irq_no_flags(12));
|
||||
@ -1294,6 +1294,7 @@ static void build_isa_devices_aml(Aml *table)
|
||||
error_report("No ISA bus, unable to define IPMI ACPI data");
|
||||
} else {
|
||||
build_acpi_ipmi_devices(scope, BUS(obj), "\\_SB.PCI0.ISA");
|
||||
isa_build_aml(ISA_BUS(obj), scope);
|
||||
}
|
||||
|
||||
aml_append(table, scope);
|
||||
@ -2238,9 +2239,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
||||
TPM_CRB_ADDR_SIZE, AML_READ_WRITE));
|
||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||
|
||||
method = aml_method("_STA", 0, AML_NOTSERIALIZED);
|
||||
aml_append(method, aml_return(aml_int(0x0f)));
|
||||
aml_append(dev, method);
|
||||
aml_append(dev, aml_name_decl("_STA", aml_int(0xf)));
|
||||
|
||||
tpm_build_ppi_acpi(tpm, dev);
|
||||
|
||||
@ -2513,6 +2512,34 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
|
||||
build_header(linker, table_data, (void *)(table_data->data + dmar_start),
|
||||
"DMAR", table_data->len - dmar_start, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows ACPI Emulated Devices Table
|
||||
* (Version 1.0 - April 6, 2009)
|
||||
* Spec: http://download.microsoft.com/download/7/E/7/7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2/WAET.docx
|
||||
*
|
||||
* Helpful to speedup Windows guests and ignored by others.
|
||||
*/
|
||||
static void
|
||||
build_waet(GArray *table_data, BIOSLinker *linker)
|
||||
{
|
||||
int waet_start = table_data->len;
|
||||
|
||||
/* WAET header */
|
||||
acpi_data_push(table_data, sizeof(AcpiTableHeader));
|
||||
/*
|
||||
* Set "ACPI PM timer good" flag.
|
||||
*
|
||||
* Tells Windows guests that our ACPI PM timer is reliable in the
|
||||
* sense that guest can read it only once to obtain a reliable value.
|
||||
* Which avoids costly VMExits caused by guest re-reading it unnecessarily.
|
||||
*/
|
||||
build_append_int_noprefix(table_data, 1 << 1 /* ACPI PM timer good */, 4);
|
||||
|
||||
build_header(linker, table_data, (void *)(table_data->data + waet_start),
|
||||
"WAET", table_data->len - waet_start, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* IVRS table as specified in AMD IOMMU Specification v2.62, Section 5.2
|
||||
* accessible here http://support.amd.com/TechDocs/48882_IOMMU.pdf
|
||||
@ -2860,6 +2887,9 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
machine->nvdimms_state, machine->ram_slots);
|
||||
}
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_waet(tables_blob, tables->linker);
|
||||
|
||||
/* Add tables supplied by user (if any) */
|
||||
for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
|
||||
unsigned len = acpi_table_len(u);
|
||||
|
@ -1,6 +1,9 @@
|
||||
|
||||
#ifndef HW_I386_ACPI_BUILD_H
|
||||
#define HW_I386_ACPI_BUILD_H
|
||||
#include "hw/acpi/acpi-defs.h"
|
||||
|
||||
extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
|
||||
|
||||
void acpi_setup(void);
|
||||
|
||||
|
@ -91,6 +91,7 @@
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "config-devices.h"
|
||||
#include "e820_memory_layout.h"
|
||||
#include "vmport.h"
|
||||
#include "fw_cfg.h"
|
||||
#include "trace.h"
|
||||
|
||||
@ -1152,7 +1153,7 @@ static void pc_superio_init(ISABus *isa_bus, bool create_fdctrl, bool no_vmport)
|
||||
|
||||
i8042 = isa_create_simple(isa_bus, "i8042");
|
||||
if (!no_vmport) {
|
||||
vmport_init(isa_bus);
|
||||
isa_create_simple(isa_bus, TYPE_VMPORT);
|
||||
vmmouse = isa_try_create(isa_bus, "vmmouse");
|
||||
} else {
|
||||
vmmouse = NULL;
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "migration/misc.h"
|
||||
#include "sysemu/numa.h"
|
||||
#include "hw/mem/nvdimm.h"
|
||||
#include "hw/i386/acpi-build.h"
|
||||
|
||||
#define MAX_IDE_BUS 2
|
||||
|
||||
@ -297,6 +298,7 @@ static void pc_init1(MachineState *machine,
|
||||
|
||||
if (machine->nvdimms_state->is_enabled) {
|
||||
nvdimm_init_acpi_state(machine->nvdimms_state, system_io,
|
||||
x86_nvdimm_acpi_dsmio,
|
||||
x86ms->fw_cfg, OBJECT(pcms));
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/numa.h"
|
||||
#include "hw/mem/nvdimm.h"
|
||||
#include "hw/i386/acpi-build.h"
|
||||
|
||||
/* ICH9 AHCI has 6 ports */
|
||||
#define MAX_SATA_PORTS 6
|
||||
@ -315,6 +316,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
|
||||
if (machine->nvdimms_state->is_enabled) {
|
||||
nvdimm_init_acpi_state(machine->nvdimms_state, system_io,
|
||||
x86_nvdimm_acpi_dsmio,
|
||||
x86ms->fw_cfg, OBJECT(pcms));
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,11 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "ui/console.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "hw/input/i8042.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "vmport.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/* debug only vmmouse */
|
||||
//#define DEBUG_VMMOUSE
|
||||
@ -70,6 +71,26 @@ typedef struct VMMouseState
|
||||
ISAKBDState *i8042;
|
||||
} VMMouseState;
|
||||
|
||||
static void vmmouse_get_data(uint32_t *data)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(current_cpu);
|
||||
CPUX86State *env = &cpu->env;
|
||||
|
||||
data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX];
|
||||
data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX];
|
||||
data[4] = env->regs[R_ESI]; data[5] = env->regs[R_EDI];
|
||||
}
|
||||
|
||||
static void vmmouse_set_data(const uint32_t *data)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(current_cpu);
|
||||
CPUX86State *env = &cpu->env;
|
||||
|
||||
env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1];
|
||||
env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3];
|
||||
env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5];
|
||||
}
|
||||
|
||||
static uint32_t vmmouse_get_status(VMMouseState *s)
|
||||
{
|
||||
DPRINTF("vmmouse_get_status()\n");
|
||||
|
@ -23,10 +23,10 @@
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/isa/isa.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "hw/input/i8042.h"
|
||||
#include "sysemu/hw_accel.h"
|
||||
#include "qemu/log.h"
|
||||
#include "vmport.h"
|
||||
#include "cpu.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define VMPORT_CMD_GETVERSION 0x0a
|
||||
@ -109,27 +109,6 @@ static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr)
|
||||
return ram_size;
|
||||
}
|
||||
|
||||
/* vmmouse helpers */
|
||||
void vmmouse_get_data(uint32_t *data)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(current_cpu);
|
||||
CPUX86State *env = &cpu->env;
|
||||
|
||||
data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX];
|
||||
data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX];
|
||||
data[4] = env->regs[R_ESI]; data[5] = env->regs[R_EDI];
|
||||
}
|
||||
|
||||
void vmmouse_set_data(const uint32_t *data)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(current_cpu);
|
||||
CPUX86State *env = &cpu->env;
|
||||
|
||||
env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1];
|
||||
env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3];
|
||||
env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5];
|
||||
}
|
||||
|
||||
static const MemoryRegionOps vmport_ops = {
|
||||
.read = vmport_ioport_read,
|
||||
.write = vmport_ioport_write,
|
||||
|
34
hw/i386/vmport.h
Normal file
34
hw/i386/vmport.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* QEMU VMPort emulation
|
||||
*
|
||||
* Copyright (C) 2007 Hervé Poussineau
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HW_I386_VMPORT_H
|
||||
#define HW_I386_VMPORT_H
|
||||
|
||||
#define TYPE_VMPORT "vmport"
|
||||
|
||||
typedef uint32_t (VMPortReadFunc)(void *opaque, uint32_t address);
|
||||
|
||||
void vmport_register(unsigned char command, VMPortReadFunc *func, void *opaque);
|
||||
|
||||
#endif
|
@ -207,6 +207,21 @@ ISADevice *isa_vga_init(ISABus *bus)
|
||||
}
|
||||
}
|
||||
|
||||
void isa_build_aml(ISABus *bus, Aml *scope)
|
||||
{
|
||||
BusChild *kid;
|
||||
ISADevice *dev;
|
||||
ISADeviceClass *dc;
|
||||
|
||||
QTAILQ_FOREACH(kid, &bus->parent_obj.children, sibling) {
|
||||
dev = ISA_DEVICE(kid->child);
|
||||
dc = ISA_DEVICE_GET_CLASS(dev);
|
||||
if (dc->build_aml) {
|
||||
dc->build_aml(dev, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
|
||||
{
|
||||
ISADevice *d = ISA_DEVICE(dev);
|
||||
|
@ -8,4 +8,4 @@ config MEM_DEVICE
|
||||
config NVDIMM
|
||||
bool
|
||||
default y
|
||||
depends on (PC || PSERIES)
|
||||
depends on (PC || PSERIES || ARM_VIRT)
|
||||
|
@ -415,6 +415,7 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
{
|
||||
PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
|
||||
uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
|
||||
uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP);
|
||||
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
||||
|
||||
/* Don't send event when device is enabled during qemu machine creation:
|
||||
@ -430,6 +431,13 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if hot-plug is disabled on the slot */
|
||||
if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) {
|
||||
error_setg(errp, "Hot-plug failed: unsupported by the port device '%s'",
|
||||
DEVICE(hotplug_pdev)->id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* To enable multifunction hot-plug, we just ensure the function
|
||||
* 0 added last. When function 0 is added, we set the sltsta and
|
||||
* inform OS via event notification.
|
||||
@ -441,7 +449,7 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
|
||||
PCI_EXP_LNKSTA_DLLLA);
|
||||
}
|
||||
pcie_cap_slot_event(PCI_DEVICE(hotplug_dev),
|
||||
pcie_cap_slot_event(hotplug_pdev,
|
||||
PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP);
|
||||
}
|
||||
}
|
||||
@ -470,8 +478,19 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
Error *local_err = NULL;
|
||||
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
||||
PCIBus *bus = pci_get_bus(pci_dev);
|
||||
PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
|
||||
uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
|
||||
uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP);
|
||||
|
||||
pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, &local_err);
|
||||
/* Check if hot-unplug is disabled on the slot */
|
||||
if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) {
|
||||
error_setg(errp, "Hot-unplug failed: "
|
||||
"unsupported by the port device '%s'",
|
||||
DEVICE(hotplug_pdev)->id);
|
||||
return;
|
||||
}
|
||||
|
||||
pcie_cap_slot_plug_common(hotplug_pdev, dev, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
@ -490,7 +509,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
return;
|
||||
}
|
||||
|
||||
pcie_cap_slot_push_attention_button(PCI_DEVICE(hotplug_dev));
|
||||
pcie_cap_slot_push_attention_button(hotplug_pdev);
|
||||
}
|
||||
|
||||
/* pci express slot for pci express root/downstream port
|
||||
|
@ -908,7 +908,6 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ISADevice *isadev = ISA_DEVICE(dev);
|
||||
RTCState *s = MC146818_RTC(dev);
|
||||
int base = 0x70;
|
||||
|
||||
s->cmos_data[RTC_REG_A] = 0x26;
|
||||
s->cmos_data[RTC_REG_B] = 0x02;
|
||||
@ -951,7 +950,7 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
|
||||
qemu_register_suspend_notifier(&s->suspend_notifier);
|
||||
|
||||
memory_region_init_io(&s->io, OBJECT(s), &cmos_ops, s, "rtc", 2);
|
||||
isa_register_ioport(isadev, &s->io, base);
|
||||
isa_register_ioport(isadev, &s->io, RTC_ISA_BASE);
|
||||
|
||||
/* register rtc 0x70 port for coalesced_pio */
|
||||
memory_region_set_flush_coalesced(&s->io);
|
||||
@ -960,7 +959,7 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
|
||||
memory_region_add_subregion(&s->io, 0, &s->coalesced_io);
|
||||
memory_region_add_coalescing(&s->coalesced_io, 0, 1);
|
||||
|
||||
qdev_set_legacy_instance_id(dev, base, 3);
|
||||
qdev_set_legacy_instance_id(dev, RTC_ISA_BASE, 3);
|
||||
qemu_register_reset(rtc_reset, s);
|
||||
|
||||
object_property_add_tm(OBJECT(s), "date", rtc_get_date, NULL);
|
||||
|
@ -407,18 +407,79 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vhost_user_fill_set_mem_table_msg(struct vhost_user *u,
|
||||
struct vhost_dev *dev,
|
||||
VhostUserMsg *msg,
|
||||
int *fds, size_t *fd_num,
|
||||
bool track_ramblocks)
|
||||
{
|
||||
int i, fd;
|
||||
ram_addr_t offset;
|
||||
MemoryRegion *mr;
|
||||
struct vhost_memory_region *reg;
|
||||
|
||||
msg->hdr.request = VHOST_USER_SET_MEM_TABLE;
|
||||
|
||||
for (i = 0; i < dev->mem->nregions; ++i) {
|
||||
reg = dev->mem->regions + i;
|
||||
|
||||
assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
|
||||
mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
|
||||
&offset);
|
||||
fd = memory_region_get_fd(mr);
|
||||
if (fd > 0) {
|
||||
if (track_ramblocks) {
|
||||
assert(*fd_num < VHOST_MEMORY_MAX_NREGIONS);
|
||||
trace_vhost_user_set_mem_table_withfd(*fd_num, mr->name,
|
||||
reg->memory_size,
|
||||
reg->guest_phys_addr,
|
||||
reg->userspace_addr,
|
||||
offset);
|
||||
u->region_rb_offset[i] = offset;
|
||||
u->region_rb[i] = mr->ram_block;
|
||||
} else if (*fd_num == VHOST_MEMORY_MAX_NREGIONS) {
|
||||
error_report("Failed preparing vhost-user memory table msg");
|
||||
return -1;
|
||||
}
|
||||
msg->payload.memory.regions[*fd_num].userspace_addr =
|
||||
reg->userspace_addr;
|
||||
msg->payload.memory.regions[*fd_num].memory_size =
|
||||
reg->memory_size;
|
||||
msg->payload.memory.regions[*fd_num].guest_phys_addr =
|
||||
reg->guest_phys_addr;
|
||||
msg->payload.memory.regions[*fd_num].mmap_offset = offset;
|
||||
fds[(*fd_num)++] = fd;
|
||||
} else if (track_ramblocks) {
|
||||
u->region_rb_offset[i] = 0;
|
||||
u->region_rb[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
msg->payload.memory.nregions = *fd_num;
|
||||
|
||||
if (!*fd_num) {
|
||||
error_report("Failed initializing vhost-user memory map, "
|
||||
"consider using -object memory-backend-file share=on");
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg->hdr.size = sizeof(msg->payload.memory.nregions);
|
||||
msg->hdr.size += sizeof(msg->payload.memory.padding);
|
||||
msg->hdr.size += *fd_num * sizeof(VhostUserMemoryRegion);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
|
||||
struct vhost_memory *mem)
|
||||
{
|
||||
struct vhost_user *u = dev->opaque;
|
||||
int fds[VHOST_MEMORY_MAX_NREGIONS];
|
||||
int i, fd;
|
||||
size_t fd_num = 0;
|
||||
VhostUserMsg msg_reply;
|
||||
int region_i, msg_i;
|
||||
|
||||
VhostUserMsg msg = {
|
||||
.hdr.request = VHOST_USER_SET_MEM_TABLE,
|
||||
.hdr.flags = VHOST_USER_VERSION,
|
||||
};
|
||||
|
||||
@ -433,48 +494,11 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev,
|
||||
u->region_rb_len = dev->mem->nregions;
|
||||
}
|
||||
|
||||
for (i = 0; i < dev->mem->nregions; ++i) {
|
||||
struct vhost_memory_region *reg = dev->mem->regions + i;
|
||||
ram_addr_t offset;
|
||||
MemoryRegion *mr;
|
||||
|
||||
assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
|
||||
mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
|
||||
&offset);
|
||||
fd = memory_region_get_fd(mr);
|
||||
if (fd > 0) {
|
||||
assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
|
||||
trace_vhost_user_set_mem_table_withfd(fd_num, mr->name,
|
||||
reg->memory_size,
|
||||
reg->guest_phys_addr,
|
||||
reg->userspace_addr, offset);
|
||||
u->region_rb_offset[i] = offset;
|
||||
u->region_rb[i] = mr->ram_block;
|
||||
msg.payload.memory.regions[fd_num].userspace_addr =
|
||||
reg->userspace_addr;
|
||||
msg.payload.memory.regions[fd_num].memory_size = reg->memory_size;
|
||||
msg.payload.memory.regions[fd_num].guest_phys_addr =
|
||||
reg->guest_phys_addr;
|
||||
msg.payload.memory.regions[fd_num].mmap_offset = offset;
|
||||
fds[fd_num++] = fd;
|
||||
} else {
|
||||
u->region_rb_offset[i] = 0;
|
||||
u->region_rb[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
msg.payload.memory.nregions = fd_num;
|
||||
|
||||
if (!fd_num) {
|
||||
error_report("Failed initializing vhost-user memory map, "
|
||||
"consider using -object memory-backend-file share=on");
|
||||
if (vhost_user_fill_set_mem_table_msg(u, dev, &msg, fds, &fd_num,
|
||||
true) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.hdr.size = sizeof(msg.payload.memory.nregions);
|
||||
msg.hdr.size += sizeof(msg.payload.memory.padding);
|
||||
msg.hdr.size += fd_num * sizeof(VhostUserMemoryRegion);
|
||||
|
||||
if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -545,7 +569,6 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
|
||||
{
|
||||
struct vhost_user *u = dev->opaque;
|
||||
int fds[VHOST_MEMORY_MAX_NREGIONS];
|
||||
int i, fd;
|
||||
size_t fd_num = 0;
|
||||
bool do_postcopy = u->postcopy_listen && u->postcopy_fd.handler;
|
||||
bool reply_supported = virtio_has_feature(dev->protocol_features,
|
||||
@ -559,7 +582,6 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
|
||||
}
|
||||
|
||||
VhostUserMsg msg = {
|
||||
.hdr.request = VHOST_USER_SET_MEM_TABLE,
|
||||
.hdr.flags = VHOST_USER_VERSION,
|
||||
};
|
||||
|
||||
@ -567,42 +589,11 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
|
||||
msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
|
||||
}
|
||||
|
||||
for (i = 0; i < dev->mem->nregions; ++i) {
|
||||
struct vhost_memory_region *reg = dev->mem->regions + i;
|
||||
ram_addr_t offset;
|
||||
MemoryRegion *mr;
|
||||
|
||||
assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
|
||||
mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
|
||||
&offset);
|
||||
fd = memory_region_get_fd(mr);
|
||||
if (fd > 0) {
|
||||
if (fd_num == VHOST_MEMORY_MAX_NREGIONS) {
|
||||
error_report("Failed preparing vhost-user memory table msg");
|
||||
return -1;
|
||||
}
|
||||
msg.payload.memory.regions[fd_num].userspace_addr =
|
||||
reg->userspace_addr;
|
||||
msg.payload.memory.regions[fd_num].memory_size = reg->memory_size;
|
||||
msg.payload.memory.regions[fd_num].guest_phys_addr =
|
||||
reg->guest_phys_addr;
|
||||
msg.payload.memory.regions[fd_num].mmap_offset = offset;
|
||||
fds[fd_num++] = fd;
|
||||
}
|
||||
}
|
||||
|
||||
msg.payload.memory.nregions = fd_num;
|
||||
|
||||
if (!fd_num) {
|
||||
error_report("Failed initializing vhost-user memory map, "
|
||||
"consider using -object memory-backend-file share=on");
|
||||
if (vhost_user_fill_set_mem_table_msg(u, dev, &msg, fds, &fd_num,
|
||||
false) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.hdr.size = sizeof(msg.payload.memory.nregions);
|
||||
msg.hdr.size += sizeof(msg.payload.memory.padding);
|
||||
msg.hdr.size += fd_num * sizeof(VhostUserMemoryRegion);
|
||||
|
||||
if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1514,7 +1514,7 @@ void vhost_dev_set_config_notifier(struct vhost_dev *hdev,
|
||||
|
||||
void vhost_dev_free_inflight(struct vhost_inflight *inflight)
|
||||
{
|
||||
if (inflight->addr) {
|
||||
if (inflight && inflight->addr) {
|
||||
qemu_memfd_free(inflight->addr, inflight->size, inflight->fd);
|
||||
inflight->addr = NULL;
|
||||
inflight->fd = -1;
|
||||
|
@ -1705,6 +1705,7 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
|
||||
*
|
||||
* region 0 -- virtio legacy io bar
|
||||
* region 1 -- msi-x bar
|
||||
* region 2 -- virtio modern io bar (off by default)
|
||||
* region 4+5 -- virtio modern memory (64bit) bar
|
||||
*
|
||||
*/
|
||||
|
@ -33,7 +33,6 @@ struct Aml {
|
||||
uint8_t op;
|
||||
AmlBlockFlags block_flags;
|
||||
};
|
||||
typedef struct Aml Aml;
|
||||
|
||||
typedef enum {
|
||||
AML_COMPATIBILITY = 0,
|
||||
|
@ -82,6 +82,7 @@
|
||||
*/
|
||||
#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
|
||||
#define ACPI_GED_PWR_DOWN_EVT 0x2
|
||||
#define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
|
||||
|
||||
typedef struct GEDState {
|
||||
MemoryRegion io;
|
||||
|
@ -79,6 +79,7 @@ enum {
|
||||
VIRT_SECURE_MEM,
|
||||
VIRT_PCDIMM_ACPI,
|
||||
VIRT_ACPI_GED,
|
||||
VIRT_NVDIMM_ACPI,
|
||||
VIRT_LOWMEMMAP_LAST,
|
||||
};
|
||||
|
||||
|
@ -129,19 +129,6 @@ typedef struct PCMachineClass {
|
||||
|
||||
GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled);
|
||||
|
||||
/* vmport.c */
|
||||
#define TYPE_VMPORT "vmport"
|
||||
typedef uint32_t (VMPortReadFunc)(void *opaque, uint32_t address);
|
||||
|
||||
static inline void vmport_init(ISABus *bus)
|
||||
{
|
||||
isa_create_simple(bus, TYPE_VMPORT);
|
||||
}
|
||||
|
||||
void vmport_register(unsigned char command, VMPortReadFunc *func, void *opaque);
|
||||
void vmmouse_get_data(uint32_t *data);
|
||||
void vmmouse_set_data(const uint32_t *data);
|
||||
|
||||
/* pc.c */
|
||||
extern int fd_bootchk;
|
||||
|
||||
|
@ -69,6 +69,7 @@ typedef struct IsaDmaClass {
|
||||
|
||||
typedef struct ISADeviceClass {
|
||||
DeviceClass parent_class;
|
||||
void (*build_aml)(ISADevice *dev, Aml *scope);
|
||||
} ISADeviceClass;
|
||||
|
||||
struct ISABus {
|
||||
@ -107,6 +108,7 @@ ISADevice *isa_try_create(ISABus *bus, const char *name);
|
||||
ISADevice *isa_create_simple(ISABus *bus, const char *name);
|
||||
|
||||
ISADevice *isa_vga_init(ISABus *bus);
|
||||
void isa_build_aml(ISABus *bus, Aml *scope);
|
||||
|
||||
/**
|
||||
* isa_register_ioport: Install an I/O port region on the ISA bus.
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "hw/acpi/bios-linker-loader.h"
|
||||
#include "qemu/uuid.h"
|
||||
#include "hw/acpi/aml-build.h"
|
||||
|
||||
#define NVDIMM_DEBUG 0
|
||||
#define nvdimm_debug(fmt, ...) \
|
||||
@ -147,10 +148,12 @@ struct NVDIMMState {
|
||||
*/
|
||||
int32_t persistence;
|
||||
char *persistence_string;
|
||||
struct AcpiGenericAddress dsm_io;
|
||||
};
|
||||
typedef struct NVDIMMState NVDIMMState;
|
||||
|
||||
void nvdimm_init_acpi_state(NVDIMMState *state, MemoryRegion *io,
|
||||
struct AcpiGenericAddress dsm_io,
|
||||
FWCfgState *fw_cfg, Object *owner);
|
||||
void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
|
||||
BIOSLinker *linker, NVDIMMState *state,
|
||||
|
@ -47,6 +47,7 @@ typedef struct RTCState {
|
||||
} RTCState;
|
||||
|
||||
#define RTC_ISA_IRQ 8
|
||||
#define RTC_ISA_BASE 0x70
|
||||
|
||||
ISADevice *mc146818_rtc_init(ISABus *bus, int base_year,
|
||||
qemu_irq intercept_irq);
|
||||
|
@ -24,6 +24,7 @@
|
||||
typedef struct AdapterInfo AdapterInfo;
|
||||
typedef struct AddressSpace AddressSpace;
|
||||
typedef struct AioContext AioContext;
|
||||
typedef struct Aml Aml;
|
||||
typedef struct AnnounceTimer AnnounceTimer;
|
||||
typedef struct BdrvDirtyBitmap BdrvDirtyBitmap;
|
||||
typedef struct BdrvDirtyBitmapIter BdrvDirtyBitmapIter;
|
||||
|
@ -35,8 +35,6 @@ my $summary_file = 0;
|
||||
my $root;
|
||||
my %debug;
|
||||
my $help = 0;
|
||||
my $acpi_testexpected;
|
||||
my $acpi_nontestexpected;
|
||||
|
||||
sub help {
|
||||
my ($exitcode) = @_;
|
||||
@ -1261,21 +1259,23 @@ sub WARN {
|
||||
# According to tests/qtest/bios-tables-test.c: do not
|
||||
# change expected file in the same commit with adding test
|
||||
sub checkfilename {
|
||||
my ($name) = @_;
|
||||
if ($name =~ m#^tests/data/acpi/# and
|
||||
# make exception for a shell script that rebuilds the files
|
||||
not $name =~ m#^\.sh$# or
|
||||
$name =~ m#^tests/qtest/bios-tables-test-allowed-diff.h$#) {
|
||||
$acpi_testexpected = $name;
|
||||
} else {
|
||||
$acpi_nontestexpected = $name;
|
||||
my ($name, $acpi_testexpected, $acpi_nontestexpected) = @_;
|
||||
|
||||
# Note: shell script that rebuilds the expected files is in the same
|
||||
# directory as files themselves.
|
||||
# Note: allowed diff list can be changed both when changing expected
|
||||
# files and when changing tests.
|
||||
if ($name =~ m#^tests/data/acpi/# and not $name =~ m#^\.sh$#) {
|
||||
$$acpi_testexpected = $name;
|
||||
} elsif ($name =~ m#^tests/qtest/bios-tables-test-allowed-diff.h$#) {
|
||||
$$acpi_nontestexpected = $name;
|
||||
}
|
||||
if (defined $acpi_testexpected and defined $acpi_nontestexpected) {
|
||||
if (defined $$acpi_testexpected and defined $$acpi_nontestexpected) {
|
||||
ERROR("Do not add expected files together with tests, " .
|
||||
"follow instructions in " .
|
||||
"tests/qtest/bios-tables-test.c: both " .
|
||||
$acpi_testexpected . " and " .
|
||||
$acpi_nontestexpected . " found\n");
|
||||
$$acpi_testexpected . " and " .
|
||||
$$acpi_nontestexpected . " found\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1325,6 +1325,9 @@ sub process {
|
||||
my %suppress_whiletrailers;
|
||||
my %suppress_export;
|
||||
|
||||
my $acpi_testexpected;
|
||||
my $acpi_nontestexpected;
|
||||
|
||||
# Pre-scan the patch sanitizing the lines.
|
||||
|
||||
sanitise_line_reset();
|
||||
@ -1454,11 +1457,11 @@ sub process {
|
||||
if ($line =~ /^diff --git.*?(\S+)$/) {
|
||||
$realfile = $1;
|
||||
$realfile =~ s@^([^/]*)/@@ if (!$file);
|
||||
checkfilename($realfile);
|
||||
checkfilename($realfile, \$acpi_testexpected, \$acpi_nontestexpected);
|
||||
} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
|
||||
$realfile = $1;
|
||||
$realfile =~ s@^([^/]*)/@@ if (!$file);
|
||||
checkfilename($realfile);
|
||||
checkfilename($realfile, \$acpi_testexpected, \$acpi_nontestexpected);
|
||||
|
||||
$p1_prefix = $1;
|
||||
if (!$file && $tree && $p1_prefix ne '' &&
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
tests/data/acpi/pc/WAET
Normal file
BIN
tests/data/acpi/pc/WAET
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
tests/data/acpi/q35/WAET
Normal file
BIN
tests/data/acpi/q35/WAET
Normal file
Binary file not shown.
Binary file not shown.
BIN
tests/data/acpi/virt/NFIT.memhp
Normal file
BIN
tests/data/acpi/virt/NFIT.memhp
Normal file
Binary file not shown.
BIN
tests/data/acpi/virt/SSDT.memhp
Normal file
BIN
tests/data/acpi/virt/SSDT.memhp
Normal file
Binary file not shown.
@ -927,12 +927,17 @@ static void test_acpi_virt_tcg_memhp(void)
|
||||
};
|
||||
|
||||
data.variant = ".memhp";
|
||||
test_acpi_one(" -cpu cortex-a57"
|
||||
test_acpi_one(" -machine nvdimm=on"
|
||||
" -cpu cortex-a57"
|
||||
" -m 256M,slots=3,maxmem=1G"
|
||||
" -object memory-backend-ram,id=ram0,size=128M"
|
||||
" -object memory-backend-ram,id=ram1,size=128M"
|
||||
" -numa node,memdev=ram0 -numa node,memdev=ram1"
|
||||
" -numa dist,src=0,dst=1,val=21",
|
||||
" -numa dist,src=0,dst=1,val=21"
|
||||
" -object memory-backend-ram,id=ram2,size=128M"
|
||||
" -object memory-backend-ram,id=nvm0,size=128M"
|
||||
" -device pc-dimm,id=dimm0,memdev=ram2,node=0"
|
||||
" -device nvdimm,id=dimm1,memdev=nvm0,node=1",
|
||||
&data);
|
||||
|
||||
free_test_data(&data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user