Page MenuHomeFreeBSD

D33188.diff
No OneTemporary

D33188.diff

diff --git a/lib/libvmmapi/Makefile b/lib/libvmmapi/Makefile
--- a/lib/libvmmapi/Makefile
+++ b/lib/libvmmapi/Makefile
@@ -5,8 +5,15 @@
SRCS= vmmapi.c vmmapi_freebsd.c
INCS= vmmapi.h
+# acpi.c includes acpixf.h which defines some unused parameters in release
+# code. Therefore, the option -Wno-unused-parameter is required for compiling.
+# Remove it as far as possible.
+CWARNFLAGS.vmmapi.c= -Wno-unused-parameter
+CWARNFLAGS.vmmapi_freebsd.c= -Wno-unused-parameter
+
LIBADD= util
CFLAGS+= -I${.CURDIR}
+CFLAGS+= -I${SRCTOP}/sys
.include <bsd.lib.mk>
diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h
--- a/lib/libvmmapi/vmmapi.h
+++ b/lib/libvmmapi/vmmapi.h
@@ -37,6 +37,8 @@
#include <stdbool.h>
+#include <contrib/dev/acpica/include/acpi.h>
+
/*
* API version for out-of-tree consumers like grub-bhyve for making compile
* time decisions.
@@ -190,6 +192,11 @@
int vm_get_intinfo(struct vmctx *ctx, int vcpu, uint64_t *i1, uint64_t *i2);
int vm_set_intinfo(struct vmctx *ctx, int vcpu, uint64_t exit_intinfo);
+/*
+ * Return current resources (CRS) used by an ACPI device.
+ */
+int vm_acpi_device_get_crs(struct vmctx *const ctx, const char *const name, ACPI_BUFFER *const crs);
+
const cap_ioctl_t *vm_get_ioctls(size_t *len);
/*
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -1062,6 +1062,46 @@
return ioctl(ctx->fd, VM_PPTDEV_DISABLE_MSIX, &ppt);
}
+int
+vm_acpi_device_get_crs(struct vmctx *const ctx, const char *const name,
+ ACPI_BUFFER *const crs)
+{
+ if (crs == NULL) {
+ return (EINVAL);
+ }
+
+ char path[NAME_MAX];
+ snprintf(path, NAME_MAX, "\\_SB.%s", name);
+
+ /* get required size to hold CRS data */
+ struct vm_acpi_device_info acpi_device_info = {
+ .type = VM_ACPI_DEVICE_INFO_CRS,
+ .path = path,
+ };
+ int error = ioctl(ctx->fd, VM_GET_ACPI_DEVICE_INFO, &acpi_device_info);
+ if (error) {
+ return (error);
+ }
+
+ /* allocate buffer for CRS */
+ crs->Pointer = malloc(acpi_device_info.buffer_length);
+ if (crs->Pointer == NULL) {
+ return (ENOMEM);
+ }
+ crs->Length = acpi_device_info.buffer_length;
+
+ /* get CRS data */
+ acpi_device_info.buffer = crs->Pointer;
+ acpi_device_info.buffer_length = crs->Length;
+ error = ioctl(ctx->fd, VM_GET_ACPI_DEVICE_INFO, &acpi_device_info);
+ if (error) {
+ free(crs->Pointer);
+ crs->Length = 0;
+ }
+
+ return (error);
+}
+
uint64_t *
vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv,
int *ret_entries)
@@ -1694,7 +1734,8 @@
VM_ACTIVATE_CPU, VM_GET_CPUS, VM_SUSPEND_CPU, VM_RESUME_CPU,
VM_SET_INTINFO, VM_GET_INTINFO,
VM_RTC_WRITE, VM_RTC_READ, VM_RTC_SETTIME, VM_RTC_GETTIME,
- VM_RESTART_INSTRUCTION, VM_SET_TOPOLOGY, VM_GET_TOPOLOGY };
+ VM_RESTART_INSTRUCTION, VM_SET_TOPOLOGY, VM_GET_TOPOLOGY,
+ VM_GET_ACPI_DEVICE_INFO };
if (len == NULL) {
cmds = malloc(sizeof(vm_ioctl_cmds));
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -741,6 +741,10 @@
} u;
};
+enum vm_acpi_device_info_type {
+ VM_ACPI_DEVICE_INFO_CRS,
+};
+
/* APIs to inject faults into the guest */
void vm_inject_fault(void *vm, int vcpuid, int vector, int errcode_valid,
int errcode);
diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -256,6 +256,13 @@
};
_Static_assert(sizeof(struct vm_readwrite_kernemu_device) == 24, "ABI");
+struct vm_acpi_device_info {
+ const char *path;
+ void *buffer;
+ size_t buffer_length;
+ enum vm_acpi_device_info_type type;
+};
+
enum {
/* general routines */
IOCNUM_ABIVERS = 0,
@@ -341,6 +348,9 @@
IOCNUM_RTC_SETTIME = 102,
IOCNUM_RTC_GETTIME = 103,
+ /* ACPI */
+ IOCNUM_GET_ACPI_DEVICE_INFO = 110,
+
/* checkpoint */
IOCNUM_SNAPSHOT_REQ = 113,
@@ -471,6 +481,8 @@
_IOR('v', IOCNUM_RTC_GETTIME, struct vm_rtc_time)
#define VM_RESTART_INSTRUCTION \
_IOW('v', IOCNUM_RESTART_INSTRUCTION, int)
+#define VM_GET_ACPI_DEVICE_INFO \
+ _IOWR('v', IOCNUM_GET_ACPI_DEVICE_INFO, struct vm_acpi_device_info)
#define VM_SNAPSHOT_REQ \
_IOWR('v', IOCNUM_SNAPSHOT_REQ, struct vm_snapshot_meta)
#define VM_RESTORE_TIME \
diff --git a/sys/amd64/vmm/io/acpi.h b/sys/amd64/vmm/io/acpi.h
new file mode 100644
--- /dev/null
+++ b/sys/amd64/vmm/io/acpi.h
@@ -0,0 +1,17 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#pragma once
+
+#include <machine/vmm.h>
+#include <machine/vmm_dev.h>
+
+/*
+ * Executes the CRS (Current Resources) method of an ACPI device.
+ */
+int vmm_acpi_get_crs(const char *const device_path, void *const buffer,
+ size_t *const buffer_length);
diff --git a/sys/amd64/vmm/io/acpi.c b/sys/amd64/vmm/io/acpi.c
new file mode 100644
--- /dev/null
+++ b/sys/amd64/vmm/io/acpi.c
@@ -0,0 +1,60 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <c.koehne@beckhoff.com>
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/acpixf.h>
+
+#include "acpi.h"
+
+int
+vmm_acpi_get_crs(const char *const device_path, void *const buffer,
+ size_t *const buffer_length)
+{
+ if (device_path == NULL || buffer_length == NULL) {
+ return (EINVAL);
+ }
+
+ /* get device handle */
+ ACPI_HANDLE acpi_device;
+ ACPI_STRING const path = strdup(device_path, M_TEMP);
+ ACPI_STATUS status = AcpiGetHandle(NULL, path, &acpi_device);
+ if (!ACPI_SUCCESS(status)) {
+ printf("%s: failed to get handle for ACPI device \"%s\" (%x)\n",
+ __func__, device_path, status);
+ return (ENOENT);
+ }
+
+ /* get current resources */
+ ACPI_BUFFER resources = { ACPI_ALLOCATE_BUFFER };
+ status = AcpiGetCurrentResources(acpi_device, &resources);
+ if (!ACPI_SUCCESS(status)) {
+ printf(
+ "%s: failed to get current resources of ACPI device \"%s\" (%x)\n",
+ __func__, device_path, status);
+ return (ENODEV);
+ }
+
+ /* copy data to user space buffer */
+ int error = 0;
+ if (buffer == NULL) {
+ *buffer_length = resources.Length;
+ } else {
+ size_t bytes_to_write = MIN(*buffer_length, resources.Length);
+ error = copyout(resources.Pointer, buffer, bytes_to_write);
+ }
+
+ AcpiOsFree(resources.Pointer);
+
+ return (error);
+}
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -63,6 +63,7 @@
#include "vmm_lapic.h"
#include "vmm_stat.h"
#include "vmm_mem.h"
+#include "io/acpi.h"
#include "io/ppt.h"
#include "io/vatpic.h"
#include "io/vioapic.h"
@@ -390,6 +391,8 @@
struct vm_memmap *mm;
struct vm_munmap *mu;
struct vm_cpu_topology *topology;
+ struct vm_acpi_device_info *acpi_device_info;
+ char acpi_device_path[NAME_MAX];
struct vm_readwrite_kernemu_device *kernemu;
uint64_t *regvals;
int *regnums;
@@ -870,6 +873,23 @@
&topology->threads, &topology->maxcpus);
error = 0;
break;
+ case VM_GET_ACPI_DEVICE_INFO:
+ acpi_device_info = (struct vm_acpi_device_info *)data;
+ /* copy device name into kernel space */
+ error = copyinstr(acpi_device_info->path, acpi_device_path,
+ sizeof(acpi_device_path), NULL);
+ if (error) {
+ break;
+ }
+ /* handle request */
+ switch (acpi_device_info->type) {
+ case VM_ACPI_DEVICE_INFO_CRS:
+ error = vmm_acpi_get_crs(acpi_device_path,
+ acpi_device_info->buffer,
+ &acpi_device_info->buffer_length);
+ break;
+ }
+ break;
#ifdef BHYVE_SNAPSHOT
case VM_SNAPSHOT_REQ:
snapshot_meta = (struct vm_snapshot_meta *)data;
diff --git a/sys/modules/vmm/Makefile b/sys/modules/vmm/Makefile
--- a/sys/modules/vmm/Makefile
+++ b/sys/modules/vmm/Makefile
@@ -29,7 +29,8 @@
x86.c
.PATH: ${SRCTOP}/sys/amd64/vmm/io
-SRCS+= iommu.c \
+SRCS+= acpi.c \
+ iommu.c \
ppt.c \
vatpic.c \
vatpit.c \
diff --git a/usr.sbin/bhyvectl/Makefile b/usr.sbin/bhyvectl/Makefile
--- a/usr.sbin/bhyvectl/Makefile
+++ b/usr.sbin/bhyvectl/Makefile
@@ -14,6 +14,7 @@
WARNS?= 3
+CFLAGS+= -I${SRCTOP}/sys
CFLAGS+= -I${SRCTOP}/sys/amd64/vmm
.if ${MK_BHYVE_SNAPSHOT} != "no"
diff --git a/usr.sbin/bhyveload/Makefile b/usr.sbin/bhyveload/Makefile
--- a/usr.sbin/bhyveload/Makefile
+++ b/usr.sbin/bhyveload/Makefile
@@ -10,5 +10,6 @@
WARNS?= 3
CFLAGS+=-I${SRCTOP}/stand/userboot
+CFLAGS+= -I${SRCTOP}/sys
.include <bsd.prog.mk>

File Metadata

Mime Type
text/plain
Expires
Fri, Feb 14, 9:11 PM (20 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16647967
Default Alt Text
D33188.diff (8 KB)

Event Timeline