mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio,pc: features, cleanups, fixes Part of ACPI ERST support fixes, cleanups Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Sun 06 Feb 2022 09:36:24 GMT # 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: (24 commits) util/oslib-posix: Fix missing unlock in the error path of os_mem_prealloc() ACPI ERST: step 6 of bios-tables-test.c ACPI ERST: bios-tables-test testcase ACPI ERST: qtest for ERST ACPI ERST: create ACPI ERST table for pc/x86 machines ACPI ERST: build the ACPI ERST table ACPI ERST: support for ACPI ERST feature ACPI ERST: header file for ERST ACPI ERST: PCI device_id for ERST ACPI ERST: bios-tables-test.c steps 1 and 2 libvhost-user: Map shared RAM with MAP_NORESERVE to support virtio-mem with hugetlb libvhost-user: handle removal of identical regions libvhost-user: prevent over-running max RAM slots libvhost-user: fix VHOST_USER_REM_MEM_REG not closing the fd libvhost-user: Simplify VHOST_USER_REM_MEM_REG libvhost-user: Add vu_add_mem_reg input validation libvhost-user: Add vu_rem_mem_reg input validation tests: acpi: test short OEM_ID/OEM_TABLE_ID values in test_oem_fields() tests: acpi: update expected blobs acpi: fix OEM ID/OEM Table ID padding ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -2768,7 +2768,7 @@ cat > $TMPC << EOF
|
||||
#include <cpuid.h>
|
||||
int main(void) {
|
||||
unsigned a, b, c, d;
|
||||
int max = __get_cpuid_max(0, 0);
|
||||
unsigned max = __get_cpuid_max(0, 0);
|
||||
|
||||
if (max >= 1) {
|
||||
__cpuid(1, a, b, c, d);
|
||||
|
||||
@@ -10,6 +10,7 @@ config ACPI_X86
|
||||
select ACPI_HMAT
|
||||
select ACPI_PIIX4
|
||||
select ACPI_PCIHP
|
||||
select ACPI_ERST
|
||||
|
||||
config ACPI_X86_ICH
|
||||
bool
|
||||
@@ -60,3 +61,8 @@ config ACPI_HW_REDUCED
|
||||
select ACPI
|
||||
select ACPI_MEMORY_HOTPLUG
|
||||
select ACPI_NVDIMM
|
||||
|
||||
config ACPI_ERST
|
||||
bool
|
||||
default y
|
||||
depends on ACPI && PCI
|
||||
|
||||
+2
-2
@@ -1724,9 +1724,9 @@ void acpi_table_begin(AcpiTable *desc, GArray *array)
|
||||
build_append_int_noprefix(array, 0, 4); /* Length */
|
||||
build_append_int_noprefix(array, desc->rev, 1); /* Revision */
|
||||
build_append_int_noprefix(array, 0, 1); /* Checksum */
|
||||
build_append_padded_str(array, desc->oem_id, 6, ' '); /* OEMID */
|
||||
build_append_padded_str(array, desc->oem_id, 6, '\0'); /* OEMID */
|
||||
/* OEM Table ID */
|
||||
build_append_padded_str(array, desc->oem_table_id, 8, ' ');
|
||||
build_append_padded_str(array, desc->oem_table_id, 8, '\0');
|
||||
build_append_int_noprefix(array, 1, 4); /* OEM Revision */
|
||||
g_array_append_vals(array, ACPI_BUILD_APPNAME8, 4); /* Creator ID */
|
||||
build_append_int_noprefix(array, 1, 4); /* Creator Revision */
|
||||
|
||||
+1051
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_true: files('pcihp.c'))
|
||||
acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_false: files('acpi-pci-hotplug-stub.c'))
|
||||
acpi_ss.add(when: 'CONFIG_ACPI_VIOT', if_true: files('viot.c'))
|
||||
acpi_ss.add(when: 'CONFIG_ACPI_X86_ICH', if_true: files('ich9.c', 'tco.c'))
|
||||
acpi_ss.add(when: 'CONFIG_ACPI_ERST', if_true: files('erst.c'))
|
||||
acpi_ss.add(when: 'CONFIG_IPMI', if_true: files('ipmi.c'), if_false: files('ipmi-stub.c'))
|
||||
acpi_ss.add(when: 'CONFIG_PC', if_false: files('acpi-x86-stub.c'))
|
||||
acpi_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
|
||||
|
||||
@@ -55,3 +55,18 @@ piix4_gpe_writeb(uint64_t addr, unsigned width, uint64_t val) "addr: 0x%" PRIx64
|
||||
# tco.c
|
||||
tco_timer_reload(int ticks, int msec) "ticks=%d (%d ms)"
|
||||
tco_timer_expired(int timeouts_no, bool strap, bool no_reboot) "timeouts_no=%d no_reboot=%d/%d"
|
||||
|
||||
# erst.c
|
||||
acpi_erst_reg_write(uint64_t addr, uint64_t val, unsigned size) "addr: 0x%04" PRIx64 " <== 0x%016" PRIx64 " (size: %u)"
|
||||
acpi_erst_reg_read(uint64_t addr, uint64_t val, unsigned size) " addr: 0x%04" PRIx64 " ==> 0x%016" PRIx64 " (size: %u)"
|
||||
acpi_erst_mem_write(uint64_t addr, uint64_t val, unsigned size) "addr: 0x%06" PRIx64 " <== 0x%016" PRIx64 " (size: %u)"
|
||||
acpi_erst_mem_read(uint64_t addr, uint64_t val, unsigned size) " addr: 0x%06" PRIx64 " ==> 0x%016" PRIx64 " (size: %u)"
|
||||
acpi_erst_pci_bar_0(uint64_t addr) "BAR0: 0x%016" PRIx64
|
||||
acpi_erst_pci_bar_1(uint64_t addr) "BAR1: 0x%016" PRIx64
|
||||
acpi_erst_realizefn_in(void)
|
||||
acpi_erst_realizefn_out(unsigned size) "total nvram size %u bytes"
|
||||
acpi_erst_reset_in(unsigned record_count) "record_count %u"
|
||||
acpi_erst_reset_out(unsigned record_count) "record_count %u"
|
||||
acpi_erst_post_load(void *header, unsigned slot_size) "header: 0x%p slot_size %u"
|
||||
acpi_erst_class_init_in(void)
|
||||
acpi_erst_class_init_out(void)
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "sysemu/tpm.h"
|
||||
#include "hw/acpi/tpm.h"
|
||||
#include "hw/acpi/vmgenid.h"
|
||||
#include "hw/acpi/erst.h"
|
||||
#include "sysemu/tpm_backend.h"
|
||||
#include "hw/rtc/mc146818rtc_regs.h"
|
||||
#include "migration/vmstate.h"
|
||||
@@ -74,6 +75,8 @@
|
||||
#include "hw/acpi/hmat.h"
|
||||
#include "hw/acpi/viot.h"
|
||||
|
||||
#include CONFIG_DEVICES
|
||||
|
||||
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
|
||||
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
|
||||
* a little bit, there should be plenty of free space since the DSDT
|
||||
@@ -2575,6 +2578,18 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
|
||||
x86ms->oem_table_id);
|
||||
|
||||
#ifdef CONFIG_ACPI_ERST
|
||||
{
|
||||
Object *erst_dev;
|
||||
erst_dev = find_erst_dev();
|
||||
if (erst_dev) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_erst(tables_blob, tables->linker, erst_dev,
|
||||
x86ms->oem_id, x86ms->oem_table_id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vmgenid_dev = find_vmgenid_dev();
|
||||
if (vmgenid_dev) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "hw/acpi/bios-linker-loader.h"
|
||||
#include "hw/acpi/generic_event_device.h"
|
||||
#include "hw/acpi/utils.h"
|
||||
#include "hw/acpi/erst.h"
|
||||
#include "hw/i386/fw_cfg.h"
|
||||
#include "hw/i386/microvm.h"
|
||||
#include "hw/pci/pci.h"
|
||||
@@ -40,6 +41,8 @@
|
||||
#include "acpi-common.h"
|
||||
#include "acpi-microvm.h"
|
||||
|
||||
#include CONFIG_DEVICES
|
||||
|
||||
static void acpi_dsdt_add_virtio(Aml *scope,
|
||||
MicrovmMachineState *mms)
|
||||
{
|
||||
@@ -207,6 +210,18 @@ static void acpi_build_microvm(AcpiBuildTables *tables,
|
||||
ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
|
||||
x86ms->oem_table_id);
|
||||
|
||||
#ifdef CONFIG_ACPI_ERST
|
||||
{
|
||||
Object *erst_dev;
|
||||
erst_dev = find_erst_dev();
|
||||
if (erst_dev) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_erst(tables_blob, tables->linker, erst_dev,
|
||||
x86ms->oem_id, x86ms->oem_table_id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
xsdt = tables_blob->len;
|
||||
build_xsdt(tables_blob, tables->linker, table_offsets, x86ms->oem_id,
|
||||
x86ms->oem_table_id);
|
||||
|
||||
+4
-1
@@ -357,10 +357,12 @@ static void pc_compat_1_4_fn(MachineState *machine)
|
||||
pc_compat_1_5_fn(machine);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ISAPC
|
||||
static void pc_init_isa(MachineState *machine)
|
||||
{
|
||||
pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, TYPE_I440FX_PCI_DEVICE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
static void pc_xen_hvm_init_pci(MachineState *machine)
|
||||
@@ -916,6 +918,7 @@ void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id)
|
||||
pci_config_set_revision(bridge_dev->config, pch_rev_id);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ISAPC
|
||||
static void isapc_machine_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
@@ -935,7 +938,7 @@ static void isapc_machine_options(MachineClass *m)
|
||||
|
||||
DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
|
||||
isapc_machine_options);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
static void xenfv_4_2_machine_options(MachineClass *m)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* ACPI Error Record Serialization Table, ERST, Implementation
|
||||
*
|
||||
* ACPI ERST introduced in ACPI 4.0, June 16, 2009.
|
||||
* ACPI Platform Error Interfaces : Error Serialization
|
||||
*
|
||||
* Copyright (c) 2021 Oracle and/or its affiliates.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef HW_ACPI_ERST_H
|
||||
#define HW_ACPI_ERST_H
|
||||
|
||||
void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
|
||||
#define TYPE_ACPI_ERST "acpi-erst"
|
||||
|
||||
/* returns NULL unless there is exactly one device */
|
||||
static inline Object *find_erst_dev(void)
|
||||
{
|
||||
return object_resolve_path_type("", TYPE_ACPI_ERST, NULL);
|
||||
}
|
||||
#endif
|
||||
@@ -108,6 +108,7 @@ extern bool pci_available;
|
||||
#define PCI_DEVICE_ID_REDHAT_MDPY 0x000f
|
||||
#define PCI_DEVICE_ID_REDHAT_NVME 0x0010
|
||||
#define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011
|
||||
#define PCI_DEVICE_ID_REDHAT_ACPI_ERST 0x0012
|
||||
#define PCI_DEVICE_ID_REDHAT_QXL 0x0100
|
||||
|
||||
#define FMT_PCIBUS PRIx64
|
||||
|
||||
@@ -690,6 +690,29 @@ vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
|
||||
VuDevRegion *dev_region = &dev->regions[dev->nregions];
|
||||
void *mmap_addr;
|
||||
|
||||
if (vmsg->fd_num != 1) {
|
||||
vmsg_close_fds(vmsg);
|
||||
vu_panic(dev, "VHOST_USER_ADD_MEM_REG received %d fds - only 1 fd "
|
||||
"should be sent for this message type", vmsg->fd_num);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vmsg->size < VHOST_USER_MEM_REG_SIZE) {
|
||||
close(vmsg->fds[0]);
|
||||
vu_panic(dev, "VHOST_USER_ADD_MEM_REG requires a message size of at "
|
||||
"least %d bytes and only %d bytes were received",
|
||||
VHOST_USER_MEM_REG_SIZE, vmsg->size);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dev->nregions == VHOST_USER_MAX_RAM_SLOTS) {
|
||||
close(vmsg->fds[0]);
|
||||
vu_panic(dev, "failing attempt to hot add memory via "
|
||||
"VHOST_USER_ADD_MEM_REG message because the backend has "
|
||||
"no free ram slots available");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are in postcopy mode and we receive a u64 payload with a 0 value
|
||||
* we know all the postcopy client bases have been received, and we
|
||||
@@ -728,12 +751,12 @@ vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
|
||||
* accessing it before we userfault.
|
||||
*/
|
||||
mmap_addr = mmap(0, dev_region->size + dev_region->mmap_offset,
|
||||
PROT_NONE, MAP_SHARED,
|
||||
PROT_NONE, MAP_SHARED | MAP_NORESERVE,
|
||||
vmsg->fds[0], 0);
|
||||
} else {
|
||||
mmap_addr = mmap(0, dev_region->size + dev_region->mmap_offset,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, vmsg->fds[0],
|
||||
0);
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NORESERVE,
|
||||
vmsg->fds[0], 0);
|
||||
}
|
||||
|
||||
if (mmap_addr == MAP_FAILED) {
|
||||
@@ -796,10 +819,24 @@ static inline bool reg_equal(VuDevRegion *vudev_reg,
|
||||
|
||||
static bool
|
||||
vu_rem_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
|
||||
int i, j;
|
||||
bool found = false;
|
||||
VuDevRegion shadow_regions[VHOST_USER_MAX_RAM_SLOTS] = {};
|
||||
VhostUserMemoryRegion m = vmsg->payload.memreg.region, *msg_region = &m;
|
||||
int i;
|
||||
bool found = false;
|
||||
|
||||
if (vmsg->fd_num != 1) {
|
||||
vmsg_close_fds(vmsg);
|
||||
vu_panic(dev, "VHOST_USER_REM_MEM_REG received %d fds - only 1 fd "
|
||||
"should be sent for this message type", vmsg->fd_num);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vmsg->size < VHOST_USER_MEM_REG_SIZE) {
|
||||
close(vmsg->fds[0]);
|
||||
vu_panic(dev, "VHOST_USER_REM_MEM_REG requires a message size of at "
|
||||
"least %d bytes and only %d bytes were received",
|
||||
VHOST_USER_MEM_REG_SIZE, vmsg->size);
|
||||
return false;
|
||||
}
|
||||
|
||||
DPRINT("Removing region:\n");
|
||||
DPRINT(" guest_phys_addr: 0x%016"PRIx64"\n",
|
||||
@@ -811,35 +848,40 @@ vu_rem_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
|
||||
DPRINT(" mmap_offset 0x%016"PRIx64"\n",
|
||||
msg_region->mmap_offset);
|
||||
|
||||
for (i = 0, j = 0; i < dev->nregions; i++) {
|
||||
if (!reg_equal(&dev->regions[i], msg_region)) {
|
||||
shadow_regions[j].gpa = dev->regions[i].gpa;
|
||||
shadow_regions[j].size = dev->regions[i].size;
|
||||
shadow_regions[j].qva = dev->regions[i].qva;
|
||||
shadow_regions[j].mmap_addr = dev->regions[i].mmap_addr;
|
||||
shadow_regions[j].mmap_offset = dev->regions[i].mmap_offset;
|
||||
j++;
|
||||
} else {
|
||||
found = true;
|
||||
for (i = 0; i < dev->nregions; i++) {
|
||||
if (reg_equal(&dev->regions[i], msg_region)) {
|
||||
VuDevRegion *r = &dev->regions[i];
|
||||
void *m = (void *) (uintptr_t) r->mmap_addr;
|
||||
|
||||
if (m) {
|
||||
munmap(m, r->size + r->mmap_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Shift all affected entries by 1 to close the hole at index i and
|
||||
* zero out the last entry.
|
||||
*/
|
||||
memmove(dev->regions + i, dev->regions + i + 1,
|
||||
sizeof(VuDevRegion) * (dev->nregions - i - 1));
|
||||
memset(dev->regions + dev->nregions - 1, 0, sizeof(VuDevRegion));
|
||||
DPRINT("Successfully removed a region\n");
|
||||
dev->nregions--;
|
||||
i--;
|
||||
|
||||
found = true;
|
||||
|
||||
/* Continue the search for eventual duplicates. */
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
memcpy(dev->regions, shadow_regions,
|
||||
sizeof(VuDevRegion) * VHOST_USER_MAX_RAM_SLOTS);
|
||||
DPRINT("Successfully removed a region\n");
|
||||
dev->nregions--;
|
||||
vmsg_set_reply_u64(vmsg, 0);
|
||||
} else {
|
||||
vu_panic(dev, "Specified region not found\n");
|
||||
}
|
||||
|
||||
close(vmsg->fds[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -878,7 +920,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
|
||||
* accessing it before we userfault
|
||||
*/
|
||||
mmap_addr = mmap(0, dev_region->size + dev_region->mmap_offset,
|
||||
PROT_NONE, MAP_SHARED,
|
||||
PROT_NONE, MAP_SHARED | MAP_NORESERVE,
|
||||
vmsg->fds[i], 0);
|
||||
|
||||
if (mmap_addr == MAP_FAILED) {
|
||||
@@ -965,7 +1007,7 @@ vu_set_mem_table_exec(VuDev *dev, VhostUserMsg *vmsg)
|
||||
* mapped address has to be page aligned, and we use huge
|
||||
* pages. */
|
||||
mmap_addr = mmap(0, dev_region->size + dev_region->mmap_offset,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NORESERVE,
|
||||
vmsg->fds[i], 0);
|
||||
|
||||
if (mmap_addr == MAP_FAILED) {
|
||||
|
||||
@@ -129,6 +129,8 @@ typedef struct VhostUserMemoryRegion {
|
||||
uint64_t mmap_offset;
|
||||
} VhostUserMemoryRegion;
|
||||
|
||||
#define VHOST_USER_MEM_REG_SIZE (sizeof(VhostUserMemoryRegion))
|
||||
|
||||
typedef struct VhostUserMemory {
|
||||
uint32_t nregions;
|
||||
uint32_t padding;
|
||||
|
||||
@@ -3747,7 +3747,7 @@ static void tcg_target_init(TCGContext *s)
|
||||
{
|
||||
#ifdef CONFIG_CPUID_H
|
||||
unsigned a, b, c, d, b7 = 0;
|
||||
int max = __get_cpuid_max(0, 0);
|
||||
unsigned max = __get_cpuid_max(0, 0);
|
||||
|
||||
if (max >= 7) {
|
||||
/* BMI1 is available on AMD Piledriver and Intel Haswell CPUs. */
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user