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:
Peter Maydell
2022-02-06 10:46:46 +00:00
29 changed files with 1429 additions and 36 deletions
Vendored
+1 -1
View File
@@ -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);
+6
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -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'))
+15
View File
@@ -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)
+15
View File
@@ -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);
+15
View File
@@ -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
View File
@@ -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)
+24
View File
@@ -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
+1
View File
@@ -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
+64 -22
View File
@@ -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;
+1 -1
View File
@@ -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