For backward compatibility, the ACPI tables are loaded into the guest
memory. Windows scans the memory, finds the ACPI tables and uses them.
It ignores the ACPI tables provided by the UEFI. We are patching the
ACPI tables in the guest memory, so that's mostly fine. However, Windows
will break when the ACPI tables become to large or when we add entries
which can't be patched by bhyve. One example of an unpatchable entry, is
a TPM log. The TPM log has to be allocated by the guest firmware. As the
address of the TPM log is unpredictable, bhyve can't assign it in the
memory version of the ACPI tables. Additionally, this makes it
impossible for bhyve to calculate a correct checksum of the table.
By default ACPI tables are still loaded into guest memory for backward
compatibility. The new acpi_tables_in_memory config value can be set to
false to avoid this behaviour.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D39979
Section 7.10.3 of the NVME 1.4b specification states that the IEEE OUI
in the identify controller structure is stored in little-endian format
(unlike the embedded OUI in EUI64 identifiers).
Reviewed by: corvink, chuck, imp
Sponsored by: Chelsio Communications
Differential Revision: https://reviews.freebsd.org/D41487
At the moment, only a TPM passthru is supported. The cmdline looks like:
-l tpm,passthru,/dev/tpm0
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D32961
Windows requires a physical presence interface to recognize the TPM
device. Qemu's OVMF has an implementation for the PPI which can be
reused. Using the Qemu PPI makes it very easy because we don't have to
implement new PPI functionality into our OVMF. The Qemu implementation
is already there.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40462
To send commands to the TPM device, bhyve can use the host TPM driver by
reading and writing from /dev/tpmX. Using this approach, only the host
TPM driver has to detect and interact with the physical TPM interface.
This simplifies bhyve's code much. As the host TPM driver has to
interact with the TPM regardless of bhyve making use of it or not, makes
it a good approach.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40460
Trap accesses to the CRB MMIO range and emulate them properly.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40459
If a guest tries to reset the fwctl device while a pending request was
in flight, the fwctl state machine can be left in an incomplete state.
Specifically, rinfo is not cleared.
Normally the state machine for fwctl alternates between REQ (receiving
request) and RESP (sending response) and ignores port writes while in
RESP or port reads while in REQ. Once a guest completes the writes to
the port to send a request, the state machine transitions to RESP and
ignores future writes.
However, if a guest writes a full request and then resets the fwctl
device, the state would transition to REQ without draining the pending
response or discarding the received request. Instead, additional
port writes after the reset were treated as new payload bytes, but
were appended to the previously-received request and could overflow
the fget_str buffer.
To fix, fully reset the fwctl state machine if the guest requests a
reset.
admbugs: 998
Approved by: so
Reviewed by: markj
Reported by: Omri Ben Bassat <t-benbassato@microsoft.com>
Security: FreeBSD-SA-23:07.bhyve
Security: CVE-2023-3494
TPM commands can take up to several seconds to execute. If we hold the
CRB mutex while executing the command, MMIO accesses could be blocked
for a long time. Therefore, just copy all required values and work on
the copied values.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40724
At one point the RIP value was passed to fbsdrun_addcpu(), but this is
no longer the case. No functional change intended.
Reviewed by: jhb, corvink
Sponsored by: Innovate UK
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D40988
pci_cfgrw() may be called via a write to the extended config space,
which is memory-mapped. In this case, the name "eax" is misleading.
Give it a more generic name. No functional change intended.
Reviewed by: corvink, jhb
MFC after: 1 week
Sponsored by: Innovate UK
Differential Revision: https://reviews.freebsd.org/D40732
The device model effectively assumes that MSI-X is enabled (it never
asserts the legacy interrupt), so any guest which relies on being able
to use the legacy PCI interrupt will fail.
The WIP arm64 port does not implement legacy PCI interrupts, but NVMe
emulation is potentially useful there. Simply remove the call.
Reviewed by: corvink, chuck, jhb
Tested by: chuck
MFC after: 1 month
Sponsored by: Innovate UK
Differential Revision: https://reviews.freebsd.org/D40731
Unfortunately, this feature didn't receive much feedback in the past.
However, after committing this, some people came up and complain that
this feature requires some more discussion before upstreaming it.
Additionally, it wasn't a good idea to start this new feature by adding
a new command line parameter as it fixes the user interface.
This reverts commit c9fdd4f3cc.
tpm_intf.h was incorrectly committed with dos line endings.
Fixes: 0917f925b4 ("bhyve: add basic CRB interface for TPM devices")
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Commands send to a tpm are very slow. They can take up to several
seconds for completion. For that reason, create a thread which issues
the commands to the tpm device.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40458
Each tpm has a device specific table. Which table a tpm uses depends on
the tpm interface.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40457
In a subsquent commit the TPM emulation will build it's own TPM2 table.
This needs to be registered to the RSDT and XSDT. Instead of making the
rsdt and xsdt variables global, we can simply add a helper to basl.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40559
The bootindex option creates an entry in the "bootorder" fwcfg file.
This file can be picked up by the guest firmware to determine the
bootorder. Nevertheless, it's not guaranteed that the guest firmware
uses the bootorder. At the moment, our OVMF ignores the bootorder. This
will change in the future.
If guest firmware supports the "bootorder" fwcfg file and no device uses
the bootindex option, the boot order is determined by the firmware
itself. If one or more devices specify a bootindex, the first bootable
device with the lowest bootindex will be booted. It's not garanteed that
devices without a bootindex will be recognized as bootable from the
firmware in that case.
Reviewed by: jhb
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D39285
Qemu's fwcfg allows to define a bootorder. Therefore, the hypervisor has
to create a fwcfg item named bootorder, which has a newline seperated
list of boot entries. Qemu's OVMF will pick up the bootorder and applies
it.
Add the moment, bhyve's OVMF doesn't support a custom bootorder by
qemu's fwcfg. However, in the future bhyve will gain support for qemu's
OVMF. Additonally, we can port relevant parts from qemu's to bhyve's
OVMF implementation.
Reviewed by: jhb, markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D39284
Move some of its logic into fbsdrun_deletecpu(). This makes it easier
to split vmexit handlers into a separate file, which in turn makes
landing arm64 support easier. Also increase the scope of the mutex and
use it to synchronize updates to the vcpu mask. No functional change
intended.
Reviewed by: corvink, jhb
MFC after: 2 weeks
Sponsored by: Innovate UK
Differential Revision: https://reviews.freebsd.org/D40573
These exit handlers might not be used if the corresponding VM
capabilities are not set, but there is no harm in putting them into the
handler table regardless. Doing so simplifies initialization code,
makes it easier to split vmexit handlers into a separate file, and lets
us declare the handler table as const.
Reviewed by: corvink, jhb
MFC after: 2 weeks
Sponsored by: Innovate UK
Differential Revision: https://reviews.freebsd.org/D40572
Current snapshot implementation doesn't support multiple devices with
similar type. For example, two virtio-blk or two CD-ROM-s, etc.
So the following configuration cannot be restored.
bhyve \
-s 3,virtio-blk,disk.img \
-s 4,virtio-blk,disk2.img
In some cases it is restored silently, but doesn't work. In some cases
it fails during restore stage.
This commit fixes that issue.
Reviewed by: corvink, rew
MFC after: 1 week
Sponsored by: vStack
Differential Revision: https://reviews.freebsd.org/D40109
There is no error when dump doesn't have it, but to be more
consistent this PCI devices should be saved as well.
Reviewed by: corvink, rew
MFC after: 1 week
Sponsored by: vStack
Differential Revision: https://reviews.freebsd.org/D40108
Each device needs a unique identifier to store and restore snapshots
properly. Adding the pci bsf information to the device name creates a
unique identifier as a bsf can't be occupied twice.
Reviewed by: corvink
MFC after: 1 week
Sponsored by: vStack
Differential Revision: https://reviews.freebsd.org/D40107
Both devices and kernel struct can use the same 'lookup_dev'
function instead of having duplicated code.
Reviewed by: corvink, rew
MFC after: 1 week
Sponsored by: vStack
Differential Revision: https://reviews.freebsd.org/D40105
Using key 'structs' is ambiguous. This section contains data
related to the kernel. It should use a more informative naming.
Reviewed by: corvink, rew
MFC after: 1 week
Sponsored by: vStack
Differential Revision: https://reviews.freebsd.org/D40104
Add a basic emulation for the command and response buffer interface of
TPM devices. This commit only implements some CRB register and resets
them.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40456
At the moment, the emulation only opens a file descriptor to the TPM
device. Some subsequent commits will read and write from it.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40455
This struct will be used to implement various TPM emulations like a TPM
passthrough or a virtual TPM.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40454
The TPM version config node should always be set. If it's not set,
there's a bug in our code. An assertion is the correct way to check for
this.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40558
Don't allow access to the physical ASLS register. It contains a host
address which is meaningless for the guest. Additionally, it allows the
guest to safely rewrite this register.
This is the last commit required for GVT-d. Nevertheless, it might not
work due to missing firmware support.
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D26209
This makes the OpRegion accessible by the guest. However, the guest
doesn't know the address of the OpRegion. This will be fixed by an
upcoming commit.
The range of the OpRegion is added to the e820 table. This allows the
guest firmware to easily pick up this range and to reserve it properly.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40041
The OpRegion provides some configuration bits and ACPI methods used by
some Intel drivers. The guest needs access to it. In the first step,
we're reading it's address and size.
Reviewed by: jhb
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40040
This register contains a host physical address. This address is
meaningless for the guest. We have to emulate it and set it to a valid
guest physical address.
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40060
The graphics stolen memory is only GPU accessible. So, we don't have to
copy any data to it as the guest will be unable to access it anyway. We
just have to allocate and reserve some memory. That's done by adding an
E820 entry for the graphics stolen memory. The guest firmware will pick
up the E820 and reserve this range.
Note that we try to reuse the host address as Intel states that newer
Tiger Lake platforms need this [1].
[1]
e28d6fbfdf/devicemodel/hw/pci/passthrough.c (L626-L629)
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40059
This is the first step to emulate the graphics stolen memory register.
Note that the graphics stolen memory is somehow confusing. On the one
hand the Intel Open Source HD Graphics Programmers' Reference Manual
states that it's only GPU accessible. As the CPU can't access the area,
the guest shouldn't need it. On the other hand, the Intel GOP driver
refuses to work properly, if it's not set to a proper address.
Intel itself maps it into the guest by EPT [1]. At the moment, we're not
aware of any situation where this EPT mapping is required, so we don't
do it yet.
Intel also states that the Windows driver for Tiger Lake reads the
address of the graphics stolen memory [2]. As the GVT-d code doesn't
support Tiger Lake in its first implementation, we can't check how it
behaves. We should keep an eye on it.
[1]
e28d6fbfdf/devicemodel/hw/pci/passthrough.c (L655-L657)
[2]
e28d6fbfdf/devicemodel/hw/pci/passthrough.c (L626-L629)
Reviewed by: markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40039
Don't emulate anything yet. Just check if the user would like to pass an
Intel GPU to the guest.
Reviewed by: jhb, markj
MFC after: 1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D40038
This appears to have been reserved for some kind of debug hook, but it's
not implemented and appears never to have been used.
Reviewed by: corvink, jhb
MFC after: 1 week
Sponsored by: Innovate UK
Differential Revision: https://reviews.freebsd.org/D40555