Compare commits
193 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d13b9e4a54 | ||
|
|
9b0eb5104f | ||
|
|
1b231e8f26 | ||
|
|
72db2d374f | ||
|
|
4a81d67680 | ||
|
|
820895b892 | ||
|
|
fa977aad67 | ||
|
|
e12b096972 | ||
|
|
321af9d3fa | ||
|
|
437417dac6 | ||
|
|
1c882e8210 | ||
|
|
56ee0ce804 | ||
|
|
36fe16995c | ||
|
|
03d11c6dca | ||
|
|
860a8b50a3 | ||
|
|
e03a166f4e | ||
|
|
819540ef60 | ||
|
|
ac2eeaf4a2 | ||
|
|
6f0f362e95 | ||
|
|
df99750b0d | ||
|
|
ae1705eda4 | ||
|
|
2c9915e371 | ||
|
|
b0886d6973 | ||
|
|
3da0f0e494 | ||
|
|
7813aa24ad | ||
|
|
9fd4ec0cb2 | ||
|
|
11319132f6 | ||
|
|
118a3e46df | ||
|
|
a1d39edf05 | ||
|
|
3c8db2995b | ||
|
|
94b122086c | ||
|
|
3a8358b856 | ||
|
|
a0a25c2263 | ||
|
|
433562d5e6 | ||
|
|
02d624f780 | ||
|
|
18b319791d | ||
|
|
ae1391d1da | ||
|
|
b2c919bcdc | ||
|
|
aa7c69b590 | ||
|
|
2410afb463 | ||
|
|
ab9bc0b91a | ||
|
|
45a5878924 | ||
|
|
05d9e2102f | ||
|
|
5e74fb7a2c | ||
|
|
5ca74db70f | ||
|
|
796bcd9463 | ||
|
|
2f3ccbe5b5 | ||
|
|
83c0f0e38c | ||
|
|
6b412efd3a | ||
|
|
9357a3d329 | ||
|
|
13d5ea1836 | ||
|
|
0b0493be25 | ||
|
|
1f15e4c9f0 | ||
|
|
a14b9df0cc | ||
|
|
baab233ea4 | ||
|
|
27e07ada8b | ||
|
|
d8e31efb54 | ||
|
|
3152a855e2 | ||
|
|
5e897fcf5f | ||
|
|
363c43d251 | ||
|
|
b359aee12a | ||
|
|
e1f1caf9d4 | ||
|
|
1b8cbfe6ee | ||
|
|
28cf6e1fe0 | ||
|
|
cdbcc2d68c | ||
|
|
e3da9ef694 | ||
|
|
2e638a41c1 | ||
|
|
2dd11a66a3 | ||
|
|
6c0cc4975e | ||
|
|
88f5e47bdc | ||
|
|
b3f4d68667 | ||
|
|
cddbb95e8d | ||
|
|
20a4ef0b4b | ||
|
|
4e70c6cffd | ||
|
|
0ad7dd2a3b | ||
|
|
a2be8f46c2 | ||
|
|
f2858dc109 | ||
|
|
0e50e2590d | ||
|
|
cf15fc547f | ||
|
|
4faecddc93 | ||
|
|
603f0584ab | ||
|
|
0cc701c26d | ||
|
|
2e8a084f49 | ||
|
|
ee127024c2 | ||
|
|
12c0f00dc9 | ||
|
|
b9014ea6e7 | ||
|
|
9fbb99a0ce | ||
|
|
8246d13768 | ||
|
|
7fd1a517b6 | ||
|
|
f49a1505e9 | ||
|
|
c7d60cec4a | ||
|
|
d816ca84fc | ||
|
|
ea8f948b5b | ||
|
|
21eadb015d | ||
|
|
455ea0ddd0 | ||
|
|
21c997995e | ||
|
|
6a1f916145 | ||
|
|
5c723c4d4f | ||
|
|
f354f3391d | ||
|
|
12bc0f50e7 | ||
|
|
2917525f2a | ||
|
|
35d3129006 | ||
|
|
df6b2acc8b | ||
|
|
7899521f1c | ||
|
|
ac7d60bdd8 | ||
|
|
6aaba1df5d | ||
|
|
7d33a9126a | ||
|
|
40e2695f58 | ||
|
|
e10e0a7eb4 | ||
|
|
476810b8e9 | ||
|
|
e3df38cf80 | ||
|
|
625bf5ceef | ||
|
|
18e4e0be1f | ||
|
|
158c1626b7 | ||
| aad9841219 | |||
|
|
921de6788a | ||
|
|
278898483e | ||
| 25e7bc99cc | |||
| adabbbb494 | |||
| c10c66077b | |||
| 4deb258e2e | |||
| 7399ffaeab | |||
| 942d785c74 | |||
| d133e7e5fe | |||
| 1a0440ded9 | |||
| 39ccf1d7f0 | |||
| 5aec4c3b9e | |||
|
|
b19143deea | ||
| 5224af8952 | |||
| f1eb2880a5 | |||
|
|
51bf974b6a | ||
|
|
a0aa455b00 | ||
|
|
bee1f08f69 | ||
|
|
fdf023d52d | ||
| 84e049d7ae | |||
|
|
52015d0078 | ||
|
|
9eef8908d2 | ||
|
|
ef1a23f0a5 | ||
|
|
b29e7f9aeb | ||
| 83389eed7e | |||
| 86ffcc5e3a | |||
|
|
bfa9615104 | ||
| ab15e51a01 | |||
| 06877cdc3d | |||
| cd664a9abb | |||
| 33d19cf4e1 | |||
| 37cc99737a | |||
| 31572a8b57 | |||
| caaba8677b | |||
| 5d3d60ccc5 | |||
| 71c72823d0 | |||
| ed0d90bb5f | |||
| 5a27b86dc6 | |||
| b7d4f949b3 | |||
| fbc4756925 | |||
| 527a5d3ed7 | |||
| e4a5f14170 | |||
| 39ef4b454c | |||
| 3f35213205 | |||
| 85343d8ccd | |||
| 150b5e071c | |||
| 06617e52e2 | |||
|
|
890a31ceaa | ||
| 40eb837e9b | |||
| 067e6183b0 | |||
| 59d94e7ffc | |||
|
|
386d4950ea | ||
|
|
63428b19f0 | ||
| a8776466de | |||
|
|
23964dfca0 | ||
|
|
3724ff19db | ||
| 9f24a3c6cc | |||
|
|
f30c826058 | ||
|
|
9b8a507ab1 | ||
| 766dcf5a0b | |||
|
|
81ccb369aa | ||
|
|
f9f3c4deda | ||
|
|
3f367b50a9 | ||
|
|
69dc441378 | ||
|
|
396fb12516 | ||
|
|
c3414ebae7 | ||
|
|
ae5b115e1a | ||
|
|
4f1e250c0d | ||
|
|
635dd43cf0 | ||
|
|
a4b62322d1 | ||
|
|
fe5a4218cb | ||
|
|
ca1c30aaca | ||
|
|
f04930b9c7 | ||
| 79113f134b | |||
| d5da72c920 | |||
| 107266f5bb | |||
| 37314a98fc | |||
| daa30db454 |
25
.gitmodules
vendored
25
.gitmodules
vendored
@@ -1,12 +1,12 @@
|
|||||||
[submodule "roms/seabios"]
|
[submodule "roms/seabios"]
|
||||||
path = roms/seabios
|
path = roms/seabios
|
||||||
url = https://gitlab.com/qemu-project/seabios.git/
|
url = https://github.com/openSUSE/qemu-seabios.git
|
||||||
[submodule "roms/SLOF"]
|
[submodule "roms/SLOF"]
|
||||||
path = roms/SLOF
|
path = roms/SLOF
|
||||||
url = https://gitlab.com/qemu-project/SLOF.git
|
url = https://github.com/openSUSE/qemu-SLOF.git
|
||||||
[submodule "roms/ipxe"]
|
[submodule "roms/ipxe"]
|
||||||
path = roms/ipxe
|
path = roms/ipxe
|
||||||
url = https://gitlab.com/qemu-project/ipxe.git
|
url = https://github.com/openSUSE/qemu-ipxe.git
|
||||||
[submodule "roms/openbios"]
|
[submodule "roms/openbios"]
|
||||||
path = roms/openbios
|
path = roms/openbios
|
||||||
url = https://gitlab.com/qemu-project/openbios.git
|
url = https://gitlab.com/qemu-project/openbios.git
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
url = https://gitlab.com/qemu-project/u-boot.git
|
url = https://gitlab.com/qemu-project/u-boot.git
|
||||||
[submodule "roms/skiboot"]
|
[submodule "roms/skiboot"]
|
||||||
path = roms/skiboot
|
path = roms/skiboot
|
||||||
url = https://gitlab.com/qemu-project/skiboot.git
|
url = https://github.com/openSUSE/qemu-skiboot.git
|
||||||
[submodule "roms/QemuMacDrivers"]
|
[submodule "roms/QemuMacDrivers"]
|
||||||
path = roms/QemuMacDrivers
|
path = roms/QemuMacDrivers
|
||||||
url = https://gitlab.com/qemu-project/QemuMacDrivers.git
|
url = https://gitlab.com/qemu-project/QemuMacDrivers.git
|
||||||
@@ -36,10 +36,25 @@
|
|||||||
url = https://gitlab.com/qemu-project/opensbi.git
|
url = https://gitlab.com/qemu-project/opensbi.git
|
||||||
[submodule "roms/qboot"]
|
[submodule "roms/qboot"]
|
||||||
path = roms/qboot
|
path = roms/qboot
|
||||||
url = https://gitlab.com/qemu-project/qboot.git
|
url = https://github.com/openSUSE/qemu-qboot.git
|
||||||
[submodule "roms/vbootrom"]
|
[submodule "roms/vbootrom"]
|
||||||
path = roms/vbootrom
|
path = roms/vbootrom
|
||||||
url = https://gitlab.com/qemu-project/vbootrom.git
|
url = https://gitlab.com/qemu-project/vbootrom.git
|
||||||
[submodule "tests/lcitool/libvirt-ci"]
|
[submodule "tests/lcitool/libvirt-ci"]
|
||||||
path = tests/lcitool/libvirt-ci
|
path = tests/lcitool/libvirt-ci
|
||||||
url = https://gitlab.com/libvirt/libvirt-ci.git
|
url = https://gitlab.com/libvirt/libvirt-ci.git
|
||||||
|
[submodule "subprojects/berkeley-softfloat-3"]
|
||||||
|
path = subprojects/berkeley-softfloat-3
|
||||||
|
url = https://gitlab.com/qemu-project/berkeley-softfloat-3
|
||||||
|
[submodule "subprojects/berkeley-testfloat-3"]
|
||||||
|
path = subprojects/berkeley-testfloat-3
|
||||||
|
url = https://gitlab.com/qemu-project/berkeley-testfloat-3
|
||||||
|
[submodule "subprojects/dtc"]
|
||||||
|
path = subprojects/dtc
|
||||||
|
url = https://gitlab.com/qemu-project/dtc.git
|
||||||
|
[submodule "subprojects/libvfio-user"]
|
||||||
|
path = subprojects/libvfio-user
|
||||||
|
url = https://gitlab.com/qemu-project/libvfio-user.git
|
||||||
|
[submodule "subprojects/keycodemapdb"]
|
||||||
|
path = subprojects/keycodemapdb
|
||||||
|
url = https://gitlab.com/qemu-project/keycodemapdb.git
|
||||||
|
|||||||
22
.obs/workflows.yml
Normal file
22
.obs/workflows.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
pr_workflow:
|
||||||
|
steps:
|
||||||
|
- branch_package:
|
||||||
|
source_project: Virtualization:Staging
|
||||||
|
source_package: qemu
|
||||||
|
target_project: Virtualization:Staging:PRs
|
||||||
|
filters:
|
||||||
|
event: pull_request
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- factory
|
||||||
|
rebuild_workflow:
|
||||||
|
steps:
|
||||||
|
# Will automatically rebuild the package
|
||||||
|
- trigger_services:
|
||||||
|
project: Virtualization:Staging
|
||||||
|
package: qemu
|
||||||
|
filters:
|
||||||
|
event: push
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- factory
|
||||||
@@ -69,16 +69,6 @@
|
|||||||
#define KVM_GUESTDBG_BLOCKIRQ 0
|
#define KVM_GUESTDBG_BLOCKIRQ 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define DEBUG_KVM
|
|
||||||
|
|
||||||
#ifdef DEBUG_KVM
|
|
||||||
#define DPRINTF(fmt, ...) \
|
|
||||||
do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
|
|
||||||
#else
|
|
||||||
#define DPRINTF(fmt, ...) \
|
|
||||||
do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct KVMParkedVcpu {
|
struct KVMParkedVcpu {
|
||||||
unsigned long vcpu_id;
|
unsigned long vcpu_id;
|
||||||
int kvm_fd;
|
int kvm_fd;
|
||||||
@@ -101,6 +91,8 @@ bool kvm_msi_use_devid;
|
|||||||
bool kvm_has_guest_debug;
|
bool kvm_has_guest_debug;
|
||||||
static int kvm_sstep_flags;
|
static int kvm_sstep_flags;
|
||||||
static bool kvm_immediate_exit;
|
static bool kvm_immediate_exit;
|
||||||
|
static bool kvm_guest_memfd_supported;
|
||||||
|
static uint64_t kvm_supported_memory_attributes;
|
||||||
static hwaddr kvm_max_slot_size = ~0;
|
static hwaddr kvm_max_slot_size = ~0;
|
||||||
|
|
||||||
static const KVMCapabilityInfo kvm_required_capabilites[] = {
|
static const KVMCapabilityInfo kvm_required_capabilites[] = {
|
||||||
@@ -292,34 +284,69 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
|
|||||||
static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, bool new)
|
static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, bool new)
|
||||||
{
|
{
|
||||||
KVMState *s = kvm_state;
|
KVMState *s = kvm_state;
|
||||||
struct kvm_userspace_memory_region mem;
|
struct kvm_userspace_memory_region2 mem;
|
||||||
|
static int cap_user_memory2 = -1;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (cap_user_memory2 == -1) {
|
||||||
|
cap_user_memory2 = kvm_check_extension(s, KVM_CAP_USER_MEMORY2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cap_user_memory2 && slot->guest_memfd >= 0) {
|
||||||
|
error_report("%s, KVM doesn't support KVM_CAP_USER_MEMORY2,"
|
||||||
|
" which is required by guest memfd!", __func__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
mem.slot = slot->slot | (kml->as_id << 16);
|
mem.slot = slot->slot | (kml->as_id << 16);
|
||||||
mem.guest_phys_addr = slot->start_addr;
|
mem.guest_phys_addr = slot->start_addr;
|
||||||
mem.userspace_addr = (unsigned long)slot->ram;
|
mem.userspace_addr = (unsigned long)slot->ram;
|
||||||
mem.flags = slot->flags;
|
mem.flags = slot->flags;
|
||||||
|
mem.guest_memfd = slot->guest_memfd;
|
||||||
|
mem.guest_memfd_offset = slot->guest_memfd_offset;
|
||||||
|
|
||||||
if (slot->memory_size && !new && (mem.flags ^ slot->old_flags) & KVM_MEM_READONLY) {
|
if (slot->memory_size && !new && (mem.flags ^ slot->old_flags) & KVM_MEM_READONLY) {
|
||||||
/* Set the slot size to 0 before setting the slot to the desired
|
/* Set the slot size to 0 before setting the slot to the desired
|
||||||
* value. This is needed based on KVM commit 75d61fbc. */
|
* value. This is needed based on KVM commit 75d61fbc. */
|
||||||
mem.memory_size = 0;
|
mem.memory_size = 0;
|
||||||
ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
|
|
||||||
|
if (cap_user_memory2) {
|
||||||
|
ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION2, &mem);
|
||||||
|
} else {
|
||||||
|
ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
|
||||||
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mem.memory_size = slot->memory_size;
|
mem.memory_size = slot->memory_size;
|
||||||
ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
|
if (cap_user_memory2) {
|
||||||
|
ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION2, &mem);
|
||||||
|
} else {
|
||||||
|
ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
|
||||||
|
}
|
||||||
slot->old_flags = mem.flags;
|
slot->old_flags = mem.flags;
|
||||||
err:
|
err:
|
||||||
trace_kvm_set_user_memory(mem.slot, mem.flags, mem.guest_phys_addr,
|
trace_kvm_set_user_memory(mem.slot >> 16, (uint16_t)mem.slot, mem.flags,
|
||||||
mem.memory_size, mem.userspace_addr, ret);
|
mem.guest_phys_addr, mem.memory_size,
|
||||||
|
mem.userspace_addr, mem.guest_memfd,
|
||||||
|
mem.guest_memfd_offset, ret);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_report("%s: KVM_SET_USER_MEMORY_REGION failed, slot=%d,"
|
if (cap_user_memory2) {
|
||||||
" start=0x%" PRIx64 ", size=0x%" PRIx64 ": %s",
|
error_report("%s: KVM_SET_USER_MEMORY_REGION2 failed, slot=%d,"
|
||||||
__func__, mem.slot, slot->start_addr,
|
" start=0x%" PRIx64 ", size=0x%" PRIx64 ","
|
||||||
(uint64_t)mem.memory_size, strerror(errno));
|
" flags=0x%" PRIx32 ", guest_memfd=%" PRId32 ","
|
||||||
|
" guest_memfd_offset=0x%" PRIx64 ": %s",
|
||||||
|
__func__, mem.slot, slot->start_addr,
|
||||||
|
(uint64_t)mem.memory_size, mem.flags,
|
||||||
|
mem.guest_memfd, (uint64_t)mem.guest_memfd_offset,
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
error_report("%s: KVM_SET_USER_MEMORY_REGION failed, slot=%d,"
|
||||||
|
" start=0x%" PRIx64 ", size=0x%" PRIx64 ": %s",
|
||||||
|
__func__, mem.slot, slot->start_addr,
|
||||||
|
(uint64_t)mem.memory_size, strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -331,7 +358,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
|
|||||||
struct KVMParkedVcpu *vcpu = NULL;
|
struct KVMParkedVcpu *vcpu = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
DPRINTF("kvm_destroy_vcpu\n");
|
trace_kvm_destroy_vcpu();
|
||||||
|
|
||||||
ret = kvm_arch_destroy_vcpu(cpu);
|
ret = kvm_arch_destroy_vcpu(cpu);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -341,7 +368,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
|
|||||||
mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
|
mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
|
||||||
if (mmap_size < 0) {
|
if (mmap_size < 0) {
|
||||||
ret = mmap_size;
|
ret = mmap_size;
|
||||||
DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
|
trace_kvm_failed_get_vcpu_mmap_size();
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,6 +418,11 @@ static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
|
|||||||
return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
|
return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __attribute__ ((weak)) kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
||||||
{
|
{
|
||||||
KVMState *s = kvm_state;
|
KVMState *s = kvm_state;
|
||||||
@@ -399,15 +431,27 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
|||||||
|
|
||||||
trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
|
trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tdx_pre_create_vcpu() may call cpu_x86_cpuid(). It in turn may call
|
||||||
|
* kvm_vm_ioctl(). Set cpu->kvm_state in advance to avoid NULL pointer
|
||||||
|
* dereference.
|
||||||
|
*/
|
||||||
|
cpu->kvm_state = s;
|
||||||
|
ret = kvm_arch_pre_create_vcpu(cpu, errp);
|
||||||
|
if (ret < 0) {
|
||||||
|
cpu->kvm_state = NULL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
|
ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed (%lu)",
|
error_setg_errno(errp, -ret, "kvm_init_vcpu: kvm_get_vcpu failed (%lu)",
|
||||||
kvm_arch_vcpu_id(cpu));
|
kvm_arch_vcpu_id(cpu));
|
||||||
|
cpu->kvm_state = NULL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->kvm_fd = ret;
|
cpu->kvm_fd = ret;
|
||||||
cpu->kvm_state = s;
|
|
||||||
cpu->vcpu_dirty = true;
|
cpu->vcpu_dirty = true;
|
||||||
cpu->dirty_pages = 0;
|
cpu->dirty_pages = 0;
|
||||||
cpu->throttle_us_per_full = 0;
|
cpu->throttle_us_per_full = 0;
|
||||||
@@ -443,7 +487,6 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
|||||||
PAGE_SIZE * KVM_DIRTY_LOG_PAGE_OFFSET);
|
PAGE_SIZE * KVM_DIRTY_LOG_PAGE_OFFSET);
|
||||||
if (cpu->kvm_dirty_gfns == MAP_FAILED) {
|
if (cpu->kvm_dirty_gfns == MAP_FAILED) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
DPRINTF("mmap'ing vcpu dirty gfns failed: %d\n", ret);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -475,6 +518,9 @@ static int kvm_mem_flags(MemoryRegion *mr)
|
|||||||
if (readonly && kvm_readonly_mem_allowed) {
|
if (readonly && kvm_readonly_mem_allowed) {
|
||||||
flags |= KVM_MEM_READONLY;
|
flags |= KVM_MEM_READONLY;
|
||||||
}
|
}
|
||||||
|
if (memory_region_has_guest_memfd(mr)) {
|
||||||
|
flags |= KVM_MEM_GUEST_MEMFD;
|
||||||
|
}
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1130,6 +1176,11 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We track the poisoned pages to be able to:
|
||||||
|
* - replace them on VM reset
|
||||||
|
* - block a migration for a VM with a poisoned page
|
||||||
|
*/
|
||||||
typedef struct HWPoisonPage {
|
typedef struct HWPoisonPage {
|
||||||
ram_addr_t ram_addr;
|
ram_addr_t ram_addr;
|
||||||
QLIST_ENTRY(HWPoisonPage) list;
|
QLIST_ENTRY(HWPoisonPage) list;
|
||||||
@@ -1163,6 +1214,11 @@ void kvm_hwpoison_page_add(ram_addr_t ram_addr)
|
|||||||
QLIST_INSERT_HEAD(&hwpoison_page_list, page, list);
|
QLIST_INSERT_HEAD(&hwpoison_page_list, page, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool kvm_hwpoisoned_mem(void)
|
||||||
|
{
|
||||||
|
return !QLIST_EMPTY(&hwpoison_page_list);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size)
|
static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size)
|
||||||
{
|
{
|
||||||
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
|
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
|
||||||
@@ -1266,6 +1322,46 @@ void kvm_set_max_memslot_size(hwaddr max_slot_size)
|
|||||||
kvm_max_slot_size = max_slot_size;
|
kvm_max_slot_size = max_slot_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int kvm_set_memory_attributes(hwaddr start, hwaddr size, uint64_t attr)
|
||||||
|
{
|
||||||
|
struct kvm_memory_attributes attrs;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (kvm_supported_memory_attributes == 0) {
|
||||||
|
error_report("No memory attribute supported by KVM\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((attr & kvm_supported_memory_attributes) != attr) {
|
||||||
|
error_report("memory attribute 0x%lx not supported by KVM,"
|
||||||
|
" supported bits are 0x%lx\n",
|
||||||
|
attr, kvm_supported_memory_attributes);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
attrs.attributes = attr;
|
||||||
|
attrs.address = start;
|
||||||
|
attrs.size = size;
|
||||||
|
attrs.flags = 0;
|
||||||
|
|
||||||
|
r = kvm_vm_ioctl(kvm_state, KVM_SET_MEMORY_ATTRIBUTES, &attrs);
|
||||||
|
if (r) {
|
||||||
|
error_report("failed to set memory (0x%lx+%#zx) with attr 0x%lx error '%s'",
|
||||||
|
start, size, attr, strerror(errno));
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kvm_set_memory_attributes_private(hwaddr start, hwaddr size)
|
||||||
|
{
|
||||||
|
return kvm_set_memory_attributes(start, size, KVM_MEMORY_ATTRIBUTE_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int kvm_set_memory_attributes_shared(hwaddr start, hwaddr size)
|
||||||
|
{
|
||||||
|
return kvm_set_memory_attributes(start, size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Called with KVMMemoryListener.slots_lock held */
|
/* Called with KVMMemoryListener.slots_lock held */
|
||||||
static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
||||||
MemoryRegionSection *section, bool add)
|
MemoryRegionSection *section, bool add)
|
||||||
@@ -1362,6 +1458,9 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
|||||||
mem->ram_start_offset = ram_start_offset;
|
mem->ram_start_offset = ram_start_offset;
|
||||||
mem->ram = ram;
|
mem->ram = ram;
|
||||||
mem->flags = kvm_mem_flags(mr);
|
mem->flags = kvm_mem_flags(mr);
|
||||||
|
mem->guest_memfd = mr->ram_block->guest_memfd;
|
||||||
|
mem->guest_memfd_offset = (uint8_t*)ram - mr->ram_block->host;
|
||||||
|
|
||||||
kvm_slot_init_dirty_bitmap(mem);
|
kvm_slot_init_dirty_bitmap(mem);
|
||||||
err = kvm_set_user_memory_region(kml, mem, true);
|
err = kvm_set_user_memory_region(kml, mem, true);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -1369,6 +1468,16 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
|||||||
strerror(-err));
|
strerror(-err));
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (memory_region_has_guest_memfd(mr)) {
|
||||||
|
err = kvm_set_memory_attributes_private(start_addr, slot_size);
|
||||||
|
if (err) {
|
||||||
|
error_report("%s: failed to set memory attribute private: %s\n",
|
||||||
|
__func__, strerror(-err));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
start_addr += slot_size;
|
start_addr += slot_size;
|
||||||
ram_start_offset += slot_size;
|
ram_start_offset += slot_size;
|
||||||
ram += slot_size;
|
ram += slot_size;
|
||||||
@@ -2396,6 +2505,11 @@ static int kvm_init(MachineState *ms)
|
|||||||
}
|
}
|
||||||
s->as = g_new0(struct KVMAs, s->nr_as);
|
s->as = g_new0(struct KVMAs, s->nr_as);
|
||||||
|
|
||||||
|
kvm_guest_memfd_supported = kvm_check_extension(s, KVM_CAP_GUEST_MEMFD);
|
||||||
|
|
||||||
|
ret = kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES);
|
||||||
|
kvm_supported_memory_attributes = ret > 0 ? ret : 0;
|
||||||
|
|
||||||
if (object_property_find(OBJECT(current_machine), "kvm-type")) {
|
if (object_property_find(OBJECT(current_machine), "kvm-type")) {
|
||||||
g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
|
g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
|
||||||
"kvm-type",
|
"kvm-type",
|
||||||
@@ -2816,12 +2930,101 @@ static void kvm_eat_signals(CPUState *cpu)
|
|||||||
} while (sigismember(&chkset, SIG_IPI));
|
} while (sigismember(&chkset, SIG_IPI));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
|
||||||
|
{
|
||||||
|
MemoryRegionSection section;
|
||||||
|
ram_addr_t offset;
|
||||||
|
MemoryRegion *mr;
|
||||||
|
RAMBlock *rb;
|
||||||
|
void *addr;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
trace_kvm_convert_memory(start, size, to_private ? "shared_to_private" : "private_to_shared");
|
||||||
|
|
||||||
|
if (!QEMU_PTR_IS_ALIGNED(start, qemu_host_page_size) ||
|
||||||
|
!QEMU_PTR_IS_ALIGNED(size, qemu_host_page_size)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!size) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
section = memory_region_find(get_system_memory(), start, size);
|
||||||
|
mr = section.mr;
|
||||||
|
if (!mr) {
|
||||||
|
/*
|
||||||
|
* Ignore converting non-assigned region to shared.
|
||||||
|
*
|
||||||
|
* TDX requires vMMIO region to be shared to inject #VE to guest.
|
||||||
|
* OVMF issues conservatively MapGPA(shared) on 32bit PCI MMIO region,
|
||||||
|
* and vIO-APIC 0xFEC00000 4K page.
|
||||||
|
* OVMF assigns 32bit PCI MMIO region to
|
||||||
|
* [top of low memory: typically 2GB=0xC000000, 0xFC00000)
|
||||||
|
*/
|
||||||
|
if (!to_private) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memory_region_has_guest_memfd(mr)) {
|
||||||
|
if (to_private) {
|
||||||
|
ret = kvm_set_memory_attributes_private(start, size);
|
||||||
|
} else {
|
||||||
|
ret = kvm_set_memory_attributes_shared(start, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
memory_region_unref(section.mr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = memory_region_get_ram_ptr(mr) + section.offset_within_region;
|
||||||
|
rb = qemu_ram_block_from_host(addr, false, &offset);
|
||||||
|
|
||||||
|
if (to_private) {
|
||||||
|
if (rb->page_size != qemu_host_page_size) {
|
||||||
|
/*
|
||||||
|
* shared memory is back'ed by hugetlb, which is supposed to be
|
||||||
|
* pre-allocated and doesn't need to be discarded
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
ret = ram_block_discard_range(rb, offset, size);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = ram_block_discard_guest_memfd_range(rb, offset, size);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Because vMMIO region must be shared, guest TD may convert vMMIO
|
||||||
|
* region to shared explicitly. Don't complain such case. See
|
||||||
|
* memory_region_type() for checking if the region is MMIO region.
|
||||||
|
*/
|
||||||
|
if (!to_private &&
|
||||||
|
!memory_region_is_ram(mr) &&
|
||||||
|
!memory_region_is_ram_device(mr) &&
|
||||||
|
!memory_region_is_rom(mr) &&
|
||||||
|
!memory_region_is_romd(mr)) {
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
error_report("Convert non guest_memfd backed memory region "
|
||||||
|
"(0x%"HWADDR_PRIx" ,+ 0x%"HWADDR_PRIx") to %s",
|
||||||
|
start, size, to_private ? "private" : "shared");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_region_unref(section.mr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_cpu_exec(CPUState *cpu)
|
int kvm_cpu_exec(CPUState *cpu)
|
||||||
{
|
{
|
||||||
struct kvm_run *run = cpu->kvm_run;
|
struct kvm_run *run = cpu->kvm_run;
|
||||||
int ret, run_ret;
|
int ret, run_ret;
|
||||||
|
|
||||||
DPRINTF("kvm_cpu_exec()\n");
|
trace_kvm_cpu_exec();
|
||||||
|
|
||||||
if (kvm_arch_process_async_events(cpu)) {
|
if (kvm_arch_process_async_events(cpu)) {
|
||||||
qatomic_set(&cpu->exit_request, 0);
|
qatomic_set(&cpu->exit_request, 0);
|
||||||
@@ -2848,7 +3051,7 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||||||
|
|
||||||
kvm_arch_pre_run(cpu, run);
|
kvm_arch_pre_run(cpu, run);
|
||||||
if (qatomic_read(&cpu->exit_request)) {
|
if (qatomic_read(&cpu->exit_request)) {
|
||||||
DPRINTF("interrupt exit requested\n");
|
trace_kvm_interrupt_exit_request();
|
||||||
/*
|
/*
|
||||||
* KVM requires us to reenter the kernel after IO exits to complete
|
* KVM requires us to reenter the kernel after IO exits to complete
|
||||||
* instruction emulation. This self-signal will ensure that we
|
* instruction emulation. This self-signal will ensure that we
|
||||||
@@ -2878,29 +3081,30 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||||||
|
|
||||||
if (run_ret < 0) {
|
if (run_ret < 0) {
|
||||||
if (run_ret == -EINTR || run_ret == -EAGAIN) {
|
if (run_ret == -EINTR || run_ret == -EAGAIN) {
|
||||||
DPRINTF("io window exit\n");
|
trace_kvm_io_window_exit();
|
||||||
kvm_eat_signals(cpu);
|
kvm_eat_signals(cpu);
|
||||||
ret = EXCP_INTERRUPT;
|
ret = EXCP_INTERRUPT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "error: kvm run failed %s\n",
|
if (!(run_ret == -EFAULT && run->exit_reason == KVM_EXIT_MEMORY_FAULT)) {
|
||||||
strerror(-run_ret));
|
fprintf(stderr, "error: kvm run failed %s\n",
|
||||||
|
strerror(-run_ret));
|
||||||
#ifdef TARGET_PPC
|
#ifdef TARGET_PPC
|
||||||
if (run_ret == -EBUSY) {
|
if (run_ret == -EBUSY) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"This is probably because your SMT is enabled.\n"
|
"This is probably because your SMT is enabled.\n"
|
||||||
"VCPU can only run on primary threads with all "
|
"VCPU can only run on primary threads with all "
|
||||||
"secondary threads offline.\n");
|
"secondary threads offline.\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_kvm_run_exit(cpu->cpu_index, run->exit_reason);
|
trace_kvm_run_exit(cpu->cpu_index, run->exit_reason);
|
||||||
switch (run->exit_reason) {
|
switch (run->exit_reason) {
|
||||||
case KVM_EXIT_IO:
|
case KVM_EXIT_IO:
|
||||||
DPRINTF("handle_io\n");
|
|
||||||
/* Called outside BQL */
|
/* Called outside BQL */
|
||||||
kvm_handle_io(run->io.port, attrs,
|
kvm_handle_io(run->io.port, attrs,
|
||||||
(uint8_t *)run + run->io.data_offset,
|
(uint8_t *)run + run->io.data_offset,
|
||||||
@@ -2910,7 +3114,6 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_MMIO:
|
case KVM_EXIT_MMIO:
|
||||||
DPRINTF("handle_mmio\n");
|
|
||||||
/* Called outside BQL */
|
/* Called outside BQL */
|
||||||
address_space_rw(&address_space_memory,
|
address_space_rw(&address_space_memory,
|
||||||
run->mmio.phys_addr, attrs,
|
run->mmio.phys_addr, attrs,
|
||||||
@@ -2920,11 +3123,9 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_IRQ_WINDOW_OPEN:
|
case KVM_EXIT_IRQ_WINDOW_OPEN:
|
||||||
DPRINTF("irq_window_open\n");
|
|
||||||
ret = EXCP_INTERRUPT;
|
ret = EXCP_INTERRUPT;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_SHUTDOWN:
|
case KVM_EXIT_SHUTDOWN:
|
||||||
DPRINTF("shutdown\n");
|
|
||||||
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
|
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
|
||||||
ret = EXCP_INTERRUPT;
|
ret = EXCP_INTERRUPT;
|
||||||
break;
|
break;
|
||||||
@@ -2959,6 +3160,7 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case KVM_EXIT_SYSTEM_EVENT:
|
case KVM_EXIT_SYSTEM_EVENT:
|
||||||
|
trace_kvm_run_exit_system_event(cpu->cpu_index, run->system_event.type);
|
||||||
switch (run->system_event.type) {
|
switch (run->system_event.type) {
|
||||||
case KVM_SYSTEM_EVENT_SHUTDOWN:
|
case KVM_SYSTEM_EVENT_SHUTDOWN:
|
||||||
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
|
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
|
||||||
@@ -2976,13 +3178,21 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTF("kvm_arch_handle_exit\n");
|
|
||||||
ret = kvm_arch_handle_exit(cpu, run);
|
ret = kvm_arch_handle_exit(cpu, run);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case KVM_EXIT_MEMORY_FAULT:
|
||||||
|
if (run->memory_fault.flags & ~KVM_MEMORY_EXIT_FLAG_PRIVATE) {
|
||||||
|
error_report("KVM_EXIT_MEMORY_FAULT: Unknown flag 0x%" PRIx64,
|
||||||
|
(uint64_t)run->memory_fault.flags);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret = kvm_convert_memory(run->memory_fault.gpa, run->memory_fault.size,
|
||||||
|
run->memory_fault.flags & KVM_MEMORY_EXIT_FLAG_PRIVATE);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTF("kvm_arch_handle_exit\n");
|
|
||||||
ret = kvm_arch_handle_exit(cpu, run);
|
ret = kvm_arch_handle_exit(cpu, run);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4077,3 +4287,25 @@ void query_stats_schemas_cb(StatsSchemaList **result, Error **errp)
|
|||||||
query_stats_schema_vcpu(first_cpu, &stats_args);
|
query_stats_schema_vcpu(first_cpu, &stats_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct kvm_create_guest_memfd guest_memfd = {
|
||||||
|
.size = size,
|
||||||
|
.flags = flags,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!kvm_guest_memfd_supported) {
|
||||||
|
error_setg(errp, "KVM doesn't support guest memfd\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_GUEST_MEMFD, &guest_memfd);
|
||||||
|
if (fd < 0) {
|
||||||
|
error_setg_errno(errp, errno, "Error creating kvm guest memfd");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d"
|
|||||||
kvm_irqchip_release_virq(int virq) "virq %d"
|
kvm_irqchip_release_virq(int virq) "virq %d"
|
||||||
kvm_set_ioeventfd_mmio(int fd, uint64_t addr, uint32_t val, bool assign, uint32_t size, bool datamatch) "fd: %d @0x%" PRIx64 " val=0x%x assign: %d size: %d match: %d"
|
kvm_set_ioeventfd_mmio(int fd, uint64_t addr, uint32_t val, bool assign, uint32_t size, bool datamatch) "fd: %d @0x%" PRIx64 " val=0x%x assign: %d size: %d match: %d"
|
||||||
kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint32_t val, bool assign, uint32_t size, bool datamatch) "fd: %d @0x%x val=0x%x assign: %d size: %d match: %d"
|
kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint32_t val, bool assign, uint32_t size, bool datamatch) "fd: %d @0x%x val=0x%x assign: %d size: %d match: %d"
|
||||||
kvm_set_user_memory(uint32_t slot, uint32_t flags, uint64_t guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, int ret) "Slot#%d flags=0x%x gpa=0x%"PRIx64 " size=0x%"PRIx64 " ua=0x%"PRIx64 " ret=%d"
|
kvm_set_user_memory(uint16_t as, uint16_t slot, uint32_t flags, uint64_t guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, uint32_t fd, uint64_t fd_offset, int ret) "AddrSpace#%d Slot#%d flags=0x%x gpa=0x%"PRIx64 " size=0x%"PRIx64 " ua=0x%"PRIx64 " guest_memfd=%d" " guest_memfd_offset=0x%" PRIx64 " ret=%d"
|
||||||
kvm_clear_dirty_log(uint32_t slot, uint64_t start, uint32_t size) "slot#%"PRId32" start 0x%"PRIx64" size 0x%"PRIx32
|
kvm_clear_dirty_log(uint32_t slot, uint64_t start, uint32_t size) "slot#%"PRId32" start 0x%"PRIx64" size 0x%"PRIx32
|
||||||
kvm_resample_fd_notify(int gsi) "gsi %d"
|
kvm_resample_fd_notify(int gsi) "gsi %d"
|
||||||
kvm_dirty_ring_full(int id) "vcpu %d"
|
kvm_dirty_ring_full(int id) "vcpu %d"
|
||||||
@@ -25,4 +25,10 @@ kvm_dirty_ring_reaper(const char *s) "%s"
|
|||||||
kvm_dirty_ring_reap(uint64_t count, int64_t t) "reaped %"PRIu64" pages (took %"PRIi64" us)"
|
kvm_dirty_ring_reap(uint64_t count, int64_t t) "reaped %"PRIu64" pages (took %"PRIi64" us)"
|
||||||
kvm_dirty_ring_reaper_kick(const char *reason) "%s"
|
kvm_dirty_ring_reaper_kick(const char *reason) "%s"
|
||||||
kvm_dirty_ring_flush(int finished) "%d"
|
kvm_dirty_ring_flush(int finished) "%d"
|
||||||
|
kvm_destroy_vcpu(void) ""
|
||||||
|
kvm_failed_get_vcpu_mmap_size(void) ""
|
||||||
|
kvm_cpu_exec(void) ""
|
||||||
|
kvm_interrupt_exit_request(void) ""
|
||||||
|
kvm_io_window_exit(void) ""
|
||||||
|
kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32
|
||||||
|
kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s"
|
||||||
|
|||||||
@@ -124,3 +124,13 @@ uint32_t kvm_dirty_ring_size(void)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool kvm_hwpoisoned_mem(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,31 +17,29 @@
|
|||||||
#include "sysemu/hostmem.h"
|
#include "sysemu/hostmem.h"
|
||||||
#include "hw/i386/hostmem-epc.h"
|
#include "hw/i386/hostmem-epc.h"
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
sgx_epc_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
sgx_epc_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||||
{
|
{
|
||||||
|
g_autofree char *name = NULL;
|
||||||
uint32_t ram_flags;
|
uint32_t ram_flags;
|
||||||
char *name;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (!backend->size) {
|
if (!backend->size) {
|
||||||
error_setg(errp, "can't create backend with size 0");
|
error_setg(errp, "can't create backend with size 0");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = qemu_open_old("/dev/sgx_vepc", O_RDWR);
|
fd = qemu_open_old("/dev/sgx_vepc", O_RDWR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
error_setg_errno(errp, errno,
|
error_setg_errno(errp, errno,
|
||||||
"failed to open /dev/sgx_vepc to alloc SGX EPC");
|
"failed to open /dev/sgx_vepc to alloc SGX EPC");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = object_get_canonical_path(OBJECT(backend));
|
name = object_get_canonical_path(OBJECT(backend));
|
||||||
ram_flags = (backend->share ? RAM_SHARED : 0) | RAM_PROTECTED;
|
ram_flags = (backend->share ? RAM_SHARED : 0) | RAM_PROTECTED;
|
||||||
memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
|
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
||||||
name, backend->size, ram_flags,
|
backend->size, ram_flags, fd, 0, errp);
|
||||||
fd, 0, errp);
|
|
||||||
g_free(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sgx_epc_backend_instance_init(Object *obj)
|
static void sgx_epc_backend_instance_init(Object *obj)
|
||||||
|
|||||||
@@ -36,24 +36,25 @@ struct HostMemoryBackendFile {
|
|||||||
OnOffAuto rom;
|
OnOffAuto rom;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_POSIX
|
#ifndef CONFIG_POSIX
|
||||||
error_setg(errp, "backend '%s' not supported on this host",
|
error_setg(errp, "backend '%s' not supported on this host",
|
||||||
object_get_typename(OBJECT(backend)));
|
object_get_typename(OBJECT(backend)));
|
||||||
|
return false;
|
||||||
#else
|
#else
|
||||||
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
|
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
|
||||||
|
g_autofree gchar *name = NULL;
|
||||||
uint32_t ram_flags;
|
uint32_t ram_flags;
|
||||||
gchar *name;
|
|
||||||
|
|
||||||
if (!backend->size) {
|
if (!backend->size) {
|
||||||
error_setg(errp, "can't create backend with size 0");
|
error_setg(errp, "can't create backend with size 0");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (!fb->mem_path) {
|
if (!fb->mem_path) {
|
||||||
error_setg(errp, "mem-path property not set");
|
error_setg(errp, "mem-path property not set");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (fb->rom) {
|
switch (fb->rom) {
|
||||||
@@ -65,18 +66,18 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
if (!fb->readonly) {
|
if (!fb->readonly) {
|
||||||
error_setg(errp, "property 'rom' = 'on' is not supported with"
|
error_setg(errp, "property 'rom' = 'on' is not supported with"
|
||||||
" 'readonly' = 'off'");
|
" 'readonly' = 'off'");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ON_OFF_AUTO_OFF:
|
case ON_OFF_AUTO_OFF:
|
||||||
if (fb->readonly && backend->share) {
|
if (fb->readonly && backend->share) {
|
||||||
error_setg(errp, "property 'rom' = 'off' is incompatible with"
|
error_setg(errp, "property 'rom' = 'off' is incompatible with"
|
||||||
" 'readonly' = 'on' and 'share' = 'on'");
|
" 'readonly' = 'on' and 'share' = 'on'");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
name = host_memory_backend_get_name(backend);
|
name = host_memory_backend_get_name(backend);
|
||||||
@@ -84,12 +85,12 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
|
ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
|
||||||
ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
|
ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
|
||||||
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
||||||
|
ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
|
||||||
ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
|
ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
|
||||||
ram_flags |= RAM_NAMED_FILE;
|
ram_flags |= RAM_NAMED_FILE;
|
||||||
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
|
return memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
|
||||||
backend->size, fb->align, ram_flags,
|
backend->size, fb->align, ram_flags,
|
||||||
fb->mem_path, fb->offset, errp);
|
fb->mem_path, fb->offset, errp);
|
||||||
g_free(name);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,17 +31,17 @@ struct HostMemoryBackendMemfd {
|
|||||||
bool seal;
|
bool seal;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||||
{
|
{
|
||||||
HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend);
|
HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend);
|
||||||
|
g_autofree char *name = NULL;
|
||||||
uint32_t ram_flags;
|
uint32_t ram_flags;
|
||||||
char *name;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (!backend->size) {
|
if (!backend->size) {
|
||||||
error_setg(errp, "can't create backend with size 0");
|
error_setg(errp, "can't create backend with size 0");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
|
fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
|
||||||
@@ -49,15 +49,15 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
|
F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
|
||||||
errp);
|
errp);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = host_memory_backend_get_name(backend);
|
name = host_memory_backend_get_name(backend);
|
||||||
ram_flags = backend->share ? RAM_SHARED : 0;
|
ram_flags = backend->share ? RAM_SHARED : 0;
|
||||||
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
||||||
memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
|
||||||
backend->size, ram_flags, fd, 0, errp);
|
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
||||||
g_free(name);
|
backend->size, ram_flags, fd, 0, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|||||||
@@ -16,23 +16,24 @@
|
|||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||||
{
|
{
|
||||||
|
g_autofree char *name = NULL;
|
||||||
uint32_t ram_flags;
|
uint32_t ram_flags;
|
||||||
char *name;
|
|
||||||
|
|
||||||
if (!backend->size) {
|
if (!backend->size) {
|
||||||
error_setg(errp, "can't create backend with size 0");
|
error_setg(errp, "can't create backend with size 0");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = host_memory_backend_get_name(backend);
|
name = host_memory_backend_get_name(backend);
|
||||||
ram_flags = backend->share ? RAM_SHARED : 0;
|
ram_flags = backend->share ? RAM_SHARED : 0;
|
||||||
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
||||||
memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend), name,
|
ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
|
||||||
backend->size, ram_flags, errp);
|
return memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend),
|
||||||
g_free(name);
|
name, backend->size,
|
||||||
|
ram_flags, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -219,7 +219,6 @@ static bool host_memory_backend_get_prealloc(Object *obj, Error **errp)
|
|||||||
static void host_memory_backend_set_prealloc(Object *obj, bool value,
|
static void host_memory_backend_set_prealloc(Object *obj, bool value,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
|
||||||
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
|
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
|
||||||
|
|
||||||
if (!backend->reserve && value) {
|
if (!backend->reserve && value) {
|
||||||
@@ -237,10 +236,8 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value,
|
|||||||
void *ptr = memory_region_get_ram_ptr(&backend->mr);
|
void *ptr = memory_region_get_ram_ptr(&backend->mr);
|
||||||
uint64_t sz = memory_region_size(&backend->mr);
|
uint64_t sz = memory_region_size(&backend->mr);
|
||||||
|
|
||||||
qemu_prealloc_mem(fd, ptr, sz, backend->prealloc_threads,
|
if (!qemu_prealloc_mem(fd, ptr, sz, backend->prealloc_threads,
|
||||||
backend->prealloc_context, &local_err);
|
backend->prealloc_context, errp)) {
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
backend->prealloc = true;
|
backend->prealloc = true;
|
||||||
@@ -279,6 +276,7 @@ static void host_memory_backend_init(Object *obj)
|
|||||||
/* TODO: convert access to globals to compat properties */
|
/* TODO: convert access to globals to compat properties */
|
||||||
backend->merge = machine_mem_merge(machine);
|
backend->merge = machine_mem_merge(machine);
|
||||||
backend->dump = machine_dump_guest_core(machine);
|
backend->dump = machine_dump_guest_core(machine);
|
||||||
|
backend->guest_memfd = machine_require_guest_memfd(machine);
|
||||||
backend->reserve = true;
|
backend->reserve = true;
|
||||||
backend->prealloc_threads = machine->smp.cpus;
|
backend->prealloc_threads = machine->smp.cpus;
|
||||||
}
|
}
|
||||||
@@ -324,91 +322,86 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
|
|||||||
{
|
{
|
||||||
HostMemoryBackend *backend = MEMORY_BACKEND(uc);
|
HostMemoryBackend *backend = MEMORY_BACKEND(uc);
|
||||||
HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
|
HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
|
||||||
Error *local_err = NULL;
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
uint64_t sz;
|
uint64_t sz;
|
||||||
|
|
||||||
if (bc->alloc) {
|
if (!bc->alloc) {
|
||||||
bc->alloc(backend, &local_err);
|
return;
|
||||||
if (local_err) {
|
}
|
||||||
goto out;
|
if (!bc->alloc(backend, errp)) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ptr = memory_region_get_ram_ptr(&backend->mr);
|
ptr = memory_region_get_ram_ptr(&backend->mr);
|
||||||
sz = memory_region_size(&backend->mr);
|
sz = memory_region_size(&backend->mr);
|
||||||
|
|
||||||
if (backend->merge) {
|
if (backend->merge) {
|
||||||
qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE);
|
qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE);
|
||||||
}
|
}
|
||||||
if (!backend->dump) {
|
if (!backend->dump) {
|
||||||
qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
|
qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
unsigned long lastbit = find_last_bit(backend->host_nodes, MAX_NODES);
|
unsigned long lastbit = find_last_bit(backend->host_nodes, MAX_NODES);
|
||||||
/* lastbit == MAX_NODES means maxnode = 0 */
|
/* lastbit == MAX_NODES means maxnode = 0 */
|
||||||
unsigned long maxnode = (lastbit + 1) % (MAX_NODES + 1);
|
unsigned long maxnode = (lastbit + 1) % (MAX_NODES + 1);
|
||||||
/* ensure policy won't be ignored in case memory is preallocated
|
/* ensure policy won't be ignored in case memory is preallocated
|
||||||
* before mbind(). note: MPOL_MF_STRICT is ignored on hugepages so
|
* before mbind(). note: MPOL_MF_STRICT is ignored on hugepages so
|
||||||
* this doesn't catch hugepage case. */
|
* this doesn't catch hugepage case. */
|
||||||
unsigned flags = MPOL_MF_STRICT | MPOL_MF_MOVE;
|
unsigned flags = MPOL_MF_STRICT | MPOL_MF_MOVE;
|
||||||
int mode = backend->policy;
|
int mode = backend->policy;
|
||||||
|
|
||||||
/* check for invalid host-nodes and policies and give more verbose
|
/* check for invalid host-nodes and policies and give more verbose
|
||||||
* error messages than mbind(). */
|
* error messages than mbind(). */
|
||||||
if (maxnode && backend->policy == MPOL_DEFAULT) {
|
if (maxnode && backend->policy == MPOL_DEFAULT) {
|
||||||
error_setg(errp, "host-nodes must be empty for policy default,"
|
error_setg(errp, "host-nodes must be empty for policy default,"
|
||||||
" or you should explicitly specify a policy other"
|
" or you should explicitly specify a policy other"
|
||||||
" than default");
|
" than default");
|
||||||
return;
|
return;
|
||||||
} else if (maxnode == 0 && backend->policy != MPOL_DEFAULT) {
|
} else if (maxnode == 0 && backend->policy != MPOL_DEFAULT) {
|
||||||
error_setg(errp, "host-nodes must be set for policy %s",
|
error_setg(errp, "host-nodes must be set for policy %s",
|
||||||
HostMemPolicy_str(backend->policy));
|
HostMemPolicy_str(backend->policy));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can have up to MAX_NODES nodes, but we need to pass maxnode+1
|
/* We can have up to MAX_NODES nodes, but we need to pass maxnode+1
|
||||||
* as argument to mbind() due to an old Linux bug (feature?) which
|
* as argument to mbind() due to an old Linux bug (feature?) which
|
||||||
* cuts off the last specified node. This means backend->host_nodes
|
* cuts off the last specified node. This means backend->host_nodes
|
||||||
* must have MAX_NODES+1 bits available.
|
* must have MAX_NODES+1 bits available.
|
||||||
*/
|
*/
|
||||||
assert(sizeof(backend->host_nodes) >=
|
assert(sizeof(backend->host_nodes) >=
|
||||||
BITS_TO_LONGS(MAX_NODES + 1) * sizeof(unsigned long));
|
BITS_TO_LONGS(MAX_NODES + 1) * sizeof(unsigned long));
|
||||||
assert(maxnode <= MAX_NODES);
|
assert(maxnode <= MAX_NODES);
|
||||||
|
|
||||||
#ifdef HAVE_NUMA_HAS_PREFERRED_MANY
|
#ifdef HAVE_NUMA_HAS_PREFERRED_MANY
|
||||||
if (mode == MPOL_PREFERRED && numa_has_preferred_many() > 0) {
|
if (mode == MPOL_PREFERRED && numa_has_preferred_many() > 0) {
|
||||||
/*
|
/*
|
||||||
* Replace with MPOL_PREFERRED_MANY otherwise the mbind() below
|
* Replace with MPOL_PREFERRED_MANY otherwise the mbind() below
|
||||||
* silently picks the first node.
|
* silently picks the first node.
|
||||||
*/
|
*/
|
||||||
mode = MPOL_PREFERRED_MANY;
|
mode = MPOL_PREFERRED_MANY;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (maxnode &&
|
if (maxnode &&
|
||||||
mbind(ptr, sz, mode, backend->host_nodes, maxnode + 1, flags)) {
|
mbind(ptr, sz, mode, backend->host_nodes, maxnode + 1, flags)) {
|
||||||
if (backend->policy != MPOL_DEFAULT || errno != ENOSYS) {
|
if (backend->policy != MPOL_DEFAULT || errno != ENOSYS) {
|
||||||
error_setg_errno(errp, errno,
|
error_setg_errno(errp, errno,
|
||||||
"cannot bind memory to host NUMA nodes");
|
"cannot bind memory to host NUMA nodes");
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Preallocate memory after the NUMA policy has been instantiated.
|
|
||||||
* This is necessary to guarantee memory is allocated with
|
|
||||||
* specified NUMA policy in place.
|
|
||||||
*/
|
|
||||||
if (backend->prealloc) {
|
|
||||||
qemu_prealloc_mem(memory_region_get_fd(&backend->mr), ptr, sz,
|
|
||||||
backend->prealloc_threads,
|
|
||||||
backend->prealloc_context, &local_err);
|
|
||||||
if (local_err) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
#endif
|
||||||
error_propagate(errp, local_err);
|
/* Preallocate memory after the NUMA policy has been instantiated.
|
||||||
|
* This is necessary to guarantee memory is allocated with
|
||||||
|
* specified NUMA policy in place.
|
||||||
|
*/
|
||||||
|
if (backend->prealloc && !qemu_prealloc_mem(memory_region_get_fd(&backend->mr),
|
||||||
|
ptr, sz,
|
||||||
|
backend->prealloc_threads,
|
||||||
|
backend->prealloc_context, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|||||||
2
block.c
2
block.c
@@ -6344,7 +6344,7 @@ BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
|
|||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
list = NULL;
|
list = NULL;
|
||||||
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
|
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
|
||||||
|
|||||||
@@ -226,6 +226,9 @@ typedef struct RawPosixAIOData {
|
|||||||
struct {
|
struct {
|
||||||
unsigned long op;
|
unsigned long op;
|
||||||
} zone_mgmt;
|
} zone_mgmt;
|
||||||
|
struct {
|
||||||
|
struct stat *st;
|
||||||
|
} fstat;
|
||||||
};
|
};
|
||||||
} RawPosixAIOData;
|
} RawPosixAIOData;
|
||||||
|
|
||||||
@@ -2613,6 +2616,34 @@ static void raw_close(BlockDriverState *bs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int handle_aiocb_fstat(void *opaque)
|
||||||
|
{
|
||||||
|
RawPosixAIOData *aiocb = opaque;
|
||||||
|
|
||||||
|
if (fstat(aiocb->aio_fildes, aiocb->fstat.st) < 0) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int coroutine_fn raw_co_fstat(BlockDriverState *bs, struct stat *st)
|
||||||
|
{
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
RawPosixAIOData acb;
|
||||||
|
|
||||||
|
acb = (RawPosixAIOData) {
|
||||||
|
.bs = bs,
|
||||||
|
.aio_fildes = s->fd,
|
||||||
|
.aio_type = QEMU_AIO_FSTAT,
|
||||||
|
.fstat = {
|
||||||
|
.st = st,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return raw_thread_pool_submit(handle_aiocb_fstat, &acb);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truncates the given regular file @fd to @offset and, when growing, fills the
|
* Truncates the given regular file @fd to @offset and, when growing, fills the
|
||||||
* new space according to @prealloc.
|
* new space according to @prealloc.
|
||||||
@@ -2857,11 +2888,14 @@ static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
|||||||
static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
|
static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
BDRVRawState *s = bs->opaque;
|
int ret;
|
||||||
|
|
||||||
if (fstat(s->fd, &st) < 0) {
|
ret = raw_co_fstat(bs, &st);
|
||||||
return -errno;
|
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int64_t)st.st_blocks * 512;
|
return (int64_t)st.st_blocks * 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ block_gen_c = custom_target('block-gen.c',
|
|||||||
'../include/block/dirty-bitmap.h',
|
'../include/block/dirty-bitmap.h',
|
||||||
'../include/block/block_int-io.h',
|
'../include/block/block_int-io.h',
|
||||||
'../include/block/block-global-state.h',
|
'../include/block/block-global-state.h',
|
||||||
|
'../include/block/qapi.h',
|
||||||
'../include/sysemu/block-backend-global-state.h',
|
'../include/sysemu/block-backend-global-state.h',
|
||||||
'../include/sysemu/block-backend-io.h',
|
'../include/sysemu/block-backend-io.h',
|
||||||
'coroutines.h'
|
'coroutines.h'
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
|
|||||||
bool writable = qdict_get_try_bool(qdict, "writable", false);
|
bool writable = qdict_get_try_bool(qdict, "writable", false);
|
||||||
bool all = qdict_get_try_bool(qdict, "all", false);
|
bool all = qdict_get_try_bool(qdict, "all", false);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
BlockInfoList *block_list, *info;
|
BlockBackend *blk;
|
||||||
SocketAddress *addr;
|
SocketAddress *addr;
|
||||||
NbdServerAddOptions export;
|
NbdServerAddOptions export;
|
||||||
|
|
||||||
@@ -425,18 +425,24 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then try adding all block devices. If one fails, close all and
|
/*
|
||||||
|
* Then try adding all block devices. If one fails, close all and
|
||||||
* exit.
|
* exit.
|
||||||
*/
|
*/
|
||||||
block_list = qmp_query_block(NULL);
|
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
|
||||||
|
BlockDriverState *bs = blk_bs(blk);
|
||||||
|
|
||||||
for (info = block_list; info; info = info->next) {
|
if (!*blk_name(blk) && !blk_get_attached_dev(blk)) {
|
||||||
if (!info->value->inserted) {
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bs = bdrv_skip_implicit_filters(bs);
|
||||||
|
if (!bs || !bs->drv) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
export = (NbdServerAddOptions) {
|
export = (NbdServerAddOptions) {
|
||||||
.device = info->value->device,
|
.device = g_strdup(blk_name(blk)),
|
||||||
.has_writable = true,
|
.has_writable = true,
|
||||||
.writable = writable,
|
.writable = writable,
|
||||||
};
|
};
|
||||||
@@ -449,8 +455,6 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qapi_free_BlockInfoList(block_list);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
hmp_handle_error(mon, local_err);
|
hmp_handle_error(mon, local_err);
|
||||||
}
|
}
|
||||||
@@ -744,7 +748,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_info_block(Monitor *mon, const QDict *qdict)
|
void coroutine_fn hmp_info_block(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
BlockInfoList *block_list, *info;
|
BlockInfoList *block_list, *info;
|
||||||
BlockDeviceInfoList *blockdev_list, *blockdev;
|
BlockDeviceInfoList *blockdev_list, *blockdev;
|
||||||
|
|||||||
32
block/qapi.c
32
block/qapi.c
@@ -41,10 +41,10 @@
|
|||||||
#include "qemu/qemu-print.h"
|
#include "qemu/qemu-print.h"
|
||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
|
|
||||||
BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
BlockDeviceInfo *coroutine_fn bdrv_block_device_info(BlockBackend *blk,
|
||||||
BlockDriverState *bs,
|
BlockDriverState *bs,
|
||||||
bool flat,
|
bool flat,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
ImageInfo **p_image_info;
|
ImageInfo **p_image_info;
|
||||||
ImageInfo *backing_info;
|
ImageInfo *backing_info;
|
||||||
@@ -234,8 +234,6 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp)
|
|||||||
int ret;
|
int ret;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
aio_context_acquire(bdrv_get_aio_context(bs));
|
|
||||||
|
|
||||||
size = bdrv_getlength(bs);
|
size = bdrv_getlength(bs);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
error_setg_errno(errp, -size, "Can't get image size '%s'",
|
error_setg_errno(errp, -size, "Can't get image size '%s'",
|
||||||
@@ -248,7 +246,9 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp)
|
|||||||
info->filename = g_strdup(bs->filename);
|
info->filename = g_strdup(bs->filename);
|
||||||
info->format = g_strdup(bdrv_get_format_name(bs));
|
info->format = g_strdup(bdrv_get_format_name(bs));
|
||||||
info->virtual_size = size;
|
info->virtual_size = size;
|
||||||
info->actual_size = bdrv_get_allocated_file_size(bs);
|
bdrv_graph_co_rdlock();
|
||||||
|
info->actual_size = bdrv_co_get_allocated_file_size(bs);
|
||||||
|
bdrv_graph_co_rdunlock();
|
||||||
info->has_actual_size = info->actual_size >= 0;
|
info->has_actual_size = info->actual_size >= 0;
|
||||||
if (bs->encrypted) {
|
if (bs->encrypted) {
|
||||||
info->encrypted = true;
|
info->encrypted = true;
|
||||||
@@ -304,7 +304,7 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
aio_context_release(bdrv_get_aio_context(bs));
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -374,7 +374,7 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bdrv_query_block_graph_info:
|
* bdrv_co_query_block_graph_info:
|
||||||
* @bs: root node to start from
|
* @bs: root node to start from
|
||||||
* @p_info: location to store image information
|
* @p_info: location to store image information
|
||||||
* @errp: location to store error information
|
* @errp: location to store error information
|
||||||
@@ -383,15 +383,17 @@ fail:
|
|||||||
*
|
*
|
||||||
* @p_info will be set only on success. On error, store error in @errp.
|
* @p_info will be set only on success. On error, store error in @errp.
|
||||||
*/
|
*/
|
||||||
void bdrv_query_block_graph_info(BlockDriverState *bs,
|
void coroutine_fn bdrv_co_query_block_graph_info(BlockDriverState *bs,
|
||||||
BlockGraphInfo **p_info,
|
BlockGraphInfo **p_info,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockGraphInfo *info;
|
BlockGraphInfo *info;
|
||||||
BlockChildInfoList **children_list_tail;
|
BlockChildInfoList **children_list_tail;
|
||||||
BdrvChild *c;
|
BdrvChild *c;
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
|
|
||||||
|
assert_bdrv_graph_readable();
|
||||||
|
|
||||||
info = g_new0(BlockGraphInfo, 1);
|
info = g_new0(BlockGraphInfo, 1);
|
||||||
bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), errp);
|
bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), errp);
|
||||||
if (*errp) {
|
if (*errp) {
|
||||||
@@ -407,7 +409,7 @@ void bdrv_query_block_graph_info(BlockDriverState *bs,
|
|||||||
QAPI_LIST_APPEND(children_list_tail, c_info);
|
QAPI_LIST_APPEND(children_list_tail, c_info);
|
||||||
|
|
||||||
c_info->name = g_strdup(c->name);
|
c_info->name = g_strdup(c->name);
|
||||||
bdrv_query_block_graph_info(c->bs, &c_info->info, errp);
|
bdrv_co_query_block_graph_info(c->bs, &c_info->info, errp);
|
||||||
if (*errp) {
|
if (*errp) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -665,13 +667,13 @@ bdrv_query_bds_stats(BlockDriverState *bs, bool blk_level)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockInfoList *qmp_query_block(Error **errp)
|
BlockInfoList *coroutine_fn qmp_query_block(Error **errp)
|
||||||
{
|
{
|
||||||
BlockInfoList *head = NULL, **p_next = &head;
|
BlockInfoList *head = NULL, **p_next = &head;
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
|
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
|
||||||
BlockInfoList *info;
|
BlockInfoList *info;
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ int bdrv_snapshot_list(BlockDriverState *bs,
|
|||||||
QEMUSnapshotInfo **psn_info)
|
QEMUSnapshotInfo **psn_info)
|
||||||
{
|
{
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
|
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
|
||||||
|
|||||||
@@ -2871,9 +2871,9 @@ void qmp_drive_backup(DriveBackup *backup, Error **errp)
|
|||||||
blockdev_do_action(&action, errp);
|
blockdev_do_action(&action, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDeviceInfoList *qmp_query_named_block_nodes(bool has_flat,
|
BlockDeviceInfoList *coroutine_fn qmp_query_named_block_nodes(bool has_flat,
|
||||||
bool flat,
|
bool flat,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
bool return_flat = has_flat && flat;
|
bool return_flat = has_flat && flat;
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
#define HW_POISON_H /* avoid poison since we patch against rules it "enforces" */
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define HW_POISON_H /* avoid poison since we patch against rules it "enforces" */
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
@@ -198,6 +199,17 @@ static void mux_chr_accept_input(Chardev *chr)
|
|||||||
be->chr_read(be->opaque,
|
be->chr_read(be->opaque,
|
||||||
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
|
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(TARGET_S390X)
|
||||||
|
/*
|
||||||
|
* We're still not able to sync producer and consumer, so let's wait a bit
|
||||||
|
* and try again by then.
|
||||||
|
*/
|
||||||
|
if (d->prod[m] != d->cons[m]) {
|
||||||
|
qemu_mod_timer(d->accept_timer, qemu_get_clock_ns(vm_clock)
|
||||||
|
+ (int64_t)100000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mux_chr_can_read(void *opaque)
|
static int mux_chr_can_read(void *opaque)
|
||||||
@@ -332,6 +344,10 @@ static void qemu_chr_open_mux(Chardev *chr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
d->focus = -1;
|
d->focus = -1;
|
||||||
|
#if defined(TARGET_S390X)
|
||||||
|
d->accept_timer = qemu_new_timer_ns(vm_clock,
|
||||||
|
(QEMUTimerCB *)mux_chr_accept_input, chr);
|
||||||
|
#endif
|
||||||
/* only default to opened state if we've realized the initial
|
/* only default to opened state if we've realized the initial
|
||||||
* set of muxes
|
* set of muxes
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define HW_POISON_H /* avoid poison since we patch against rules it "enforces" */
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ struct MuxChardev {
|
|||||||
Chardev parent;
|
Chardev parent;
|
||||||
CharBackend *backends[MAX_MUX];
|
CharBackend *backends[MAX_MUX];
|
||||||
CharBackend chr;
|
CharBackend chr;
|
||||||
|
#if defined(TARGET_S390X)
|
||||||
|
QEMUTimer *accept_timer;
|
||||||
|
#endif
|
||||||
int focus;
|
int focus;
|
||||||
int mux_cnt;
|
int mux_cnt;
|
||||||
int term_got_escape;
|
int term_got_escape;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#CONFIG_QXL=n
|
#CONFIG_QXL=n
|
||||||
#CONFIG_SEV=n
|
#CONFIG_SEV=n
|
||||||
#CONFIG_SGA=n
|
#CONFIG_SGA=n
|
||||||
|
#CONFIG_TDX=n
|
||||||
#CONFIG_TEST_DEVICES=n
|
#CONFIG_TEST_DEVICES=n
|
||||||
#CONFIG_TPM_CRB=n
|
#CONFIG_TPM_CRB=n
|
||||||
#CONFIG_TPM_TIS_ISA=n
|
#CONFIG_TPM_TIS_ISA=n
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
executable('ivshmem-client', files('ivshmem-client.c', 'main.c'), genh,
|
executable('ivshmem-client', files('ivshmem-client.c', 'main.c'), genh,
|
||||||
dependencies: glib,
|
dependencies: glib,
|
||||||
build_by_default: targetos == 'linux',
|
build_by_default: targetos == 'linux',
|
||||||
install: false)
|
install: true)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
executable('ivshmem-server', files('ivshmem-server.c', 'main.c'), genh,
|
executable('ivshmem-server', files('ivshmem-server.c', 'main.c'), genh,
|
||||||
dependencies: [qemuutil, rt],
|
dependencies: [qemuutil, rt],
|
||||||
build_by_default: targetos == 'linux',
|
build_by_default: targetos == 'linux',
|
||||||
install: false)
|
install: true)
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ if sphinx_build.found()
|
|||||||
sphinx_version = run_command(SPHINX_ARGS + ['--version'],
|
sphinx_version = run_command(SPHINX_ARGS + ['--version'],
|
||||||
check: true).stdout().split()[1]
|
check: true).stdout().split()[1]
|
||||||
if sphinx_version.version_compare('>=1.7.0')
|
if sphinx_version.version_compare('>=1.7.0')
|
||||||
SPHINX_ARGS += ['-j', 'auto']
|
SPHINX_ARGS += ['-j', '1']
|
||||||
else
|
else
|
||||||
nproc = find_program('nproc')
|
nproc = find_program('nproc')
|
||||||
if nproc.found()
|
if nproc.found()
|
||||||
jobs = run_command(nproc, check: true).stdout()
|
jobs = run_command(nproc, check: true).stdout()
|
||||||
SPHINX_ARGS += ['-j', jobs]
|
SPHINX_ARGS += ['-j', '1']
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ Supported mechanisms
|
|||||||
Currently supported confidential guest mechanisms are:
|
Currently supported confidential guest mechanisms are:
|
||||||
|
|
||||||
* AMD Secure Encrypted Virtualization (SEV) (see :doc:`i386/amd-memory-encryption`)
|
* AMD Secure Encrypted Virtualization (SEV) (see :doc:`i386/amd-memory-encryption`)
|
||||||
|
* Intel Trust Domain Extension (TDX) (see :doc:`i386/tdx`)
|
||||||
* POWER Protected Execution Facility (PEF) (see :ref:`power-papr-protected-execution-facility-pef`)
|
* POWER Protected Execution Facility (PEF) (see :ref:`power-papr-protected-execution-facility-pef`)
|
||||||
* s390x Protected Virtualization (PV) (see :doc:`s390x/protvirt`)
|
* s390x Protected Virtualization (PV) (see :doc:`s390x/protvirt`)
|
||||||
|
|
||||||
|
|||||||
143
docs/system/i386/tdx.rst
Normal file
143
docs/system/i386/tdx.rst
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
Intel Trusted Domain eXtension (TDX)
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Intel Trusted Domain eXtensions (TDX) refers to an Intel technology that extends
|
||||||
|
Virtual Machine Extensions (VMX) and Multi-Key Total Memory Encryption (MKTME)
|
||||||
|
with a new kind of virtual machine guest called a Trust Domain (TD). A TD runs
|
||||||
|
in a CPU mode that is designed to protect the confidentiality of its memory
|
||||||
|
contents and its CPU state from any other software, including the hosting
|
||||||
|
Virtual Machine Monitor (VMM), unless explicitly shared by the TD itself.
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
-------------
|
||||||
|
|
||||||
|
To run TD, the physical machine needs to have TDX module loaded and initialized
|
||||||
|
while KVM hypervisor has TDX support and has TDX enabled. If those requirements
|
||||||
|
are met, the ``KVM_CAP_VM_TYPES`` will report the support of ``KVM_X86_TDX_VM``.
|
||||||
|
|
||||||
|
Trust Domain Virtual Firmware (TDVF)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Trust Domain Virtual Firmware (TDVF) is required to provide TD services to boot
|
||||||
|
TD Guest OS. TDVF needs to be copied to guest private memory and measured before
|
||||||
|
the TD boots.
|
||||||
|
|
||||||
|
KVM vcpu ioctl ``KVM_MEMORY_MAPPING`` can be used to populates the TDVF content
|
||||||
|
into its private memory.
|
||||||
|
|
||||||
|
Since TDX doesn't support readonly memslot, TDVF cannot be mapped as pflash
|
||||||
|
device and it actually works as RAM. "-bios" option is chosen to load TDVF.
|
||||||
|
|
||||||
|
OVMF is the opensource firmware that implements the TDVF support. Thus the
|
||||||
|
command line to specify and load TDVF is ``-bios OVMF.fd``
|
||||||
|
|
||||||
|
KVM private memory
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
TD's memory (RAM) needs to be able to be transformed between private and shared.
|
||||||
|
Its BIOS (OVMF/TDVF) needs to be mapped as private as well. Thus QEMU needs to
|
||||||
|
allocate private guest memfd for them via KVM's IOCTL (KVM_CREATE_GUEST_MEMFD),
|
||||||
|
which requires KVM is newer enough that reports KVM_CAP_GUEST_MEMFD.
|
||||||
|
|
||||||
|
Feature Control
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Unlike non-TDX VM, the CPU features (enumerated by CPU or MSR) of a TD is not
|
||||||
|
under full control of VMM. VMM can only configure part of features of a TD on
|
||||||
|
``KVM_TDX_INIT_VM`` command of VM scope ``MEMORY_ENCRYPT_OP`` ioctl.
|
||||||
|
|
||||||
|
The configurable features have three types:
|
||||||
|
|
||||||
|
- Attributes:
|
||||||
|
- PKS (bit 30) controls whether Supervisor Protection Keys is exposed to TD,
|
||||||
|
which determines related CPUID bit and CR4 bit;
|
||||||
|
- PERFMON (bit 63) controls whether PMU is exposed to TD.
|
||||||
|
|
||||||
|
- XSAVE related features (XFAM):
|
||||||
|
XFAM is a 64b mask, which has the same format as XCR0 or IA32_XSS MSR. It
|
||||||
|
determines the set of extended features available for use by the guest TD.
|
||||||
|
|
||||||
|
- CPUID features:
|
||||||
|
Only some bits of some CPUID leaves are directly configurable by VMM.
|
||||||
|
|
||||||
|
What features can be configured is reported via TDX capabilities.
|
||||||
|
|
||||||
|
TDX capabilities
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The VM scope ``MEMORY_ENCRYPT_OP`` ioctl provides command ``KVM_TDX_CAPABILITIES``
|
||||||
|
to get the TDX capabilities from KVM. It returns a data structure of
|
||||||
|
``struct kvm_tdx_capabilites``, which tells the supported configuration of
|
||||||
|
attributes, XFAM and CPUIDs.
|
||||||
|
|
||||||
|
TD attestation
|
||||||
|
--------------
|
||||||
|
|
||||||
|
In TD guest, the attestation process is used to verify the TDX guest
|
||||||
|
trustworthiness to other entities before provisioning secrets to the guest.
|
||||||
|
|
||||||
|
TD attestation is initiated first by calling TDG.MR.REPORT inside TD to get the
|
||||||
|
REPORT. Then the REPORT data needs to be converted into a remotely verifiable
|
||||||
|
Quote by SGX Quoting Enclave (QE).
|
||||||
|
|
||||||
|
A host daemon, Quote Generation Service (QGS), provides the functionality of
|
||||||
|
SGX GE. It provides a socket address, to which a TD guest can connect via
|
||||||
|
"quote-generation-socket" property. On the request of <GETQUOTE> from TD guest,
|
||||||
|
QEMU sends the TDREPORT to QGS via "quote-generation-socket" socket, and gets
|
||||||
|
the returning Quoting and return it back to TD guest.
|
||||||
|
|
||||||
|
Though "quote-generation-socket" is optional for booting the TD guest, it's a
|
||||||
|
must for supporting TD guest atteatation.
|
||||||
|
|
||||||
|
Launching a TD (TDX VM)
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
To launch a TDX guest, below are new added and required:
|
||||||
|
|
||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
|qemu_system_x86| \\
|
||||||
|
-object tdx-guest,id=tdx0 \\
|
||||||
|
-machine ...,kernel-irqchip=split,confidential-guest-support=tdx0 \\
|
||||||
|
-bios OVMF.fd \\
|
||||||
|
|
||||||
|
If TD attestation support is wanted:
|
||||||
|
|
||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
|qemu_system_x86| \\
|
||||||
|
-object '{"qom-type":"tdx-guest","id":"tdx0","quote-generation-socket":{"type": "vsock", "cid":"1","port":"1234"}}' \\
|
||||||
|
-machine ...,kernel-irqchip=split,confidential-guest-support=tdx0 \\
|
||||||
|
-bios OVMF.fd \\
|
||||||
|
|
||||||
|
Debugging
|
||||||
|
---------
|
||||||
|
|
||||||
|
Bit 0 of TD attributes, is DEBUG bit, which decides if the TD runs in off-TD
|
||||||
|
debug mode. When in off-TD debug mode, TD's VCPU state and private memory are
|
||||||
|
accessible via given SEAMCALLs. This requires KVM to expose APIs to invoke those
|
||||||
|
SEAMCALLs and resonponding QEMU change.
|
||||||
|
|
||||||
|
It's targeted as future work.
|
||||||
|
|
||||||
|
restrictions
|
||||||
|
------------
|
||||||
|
|
||||||
|
- kernel-irqchip must be split;
|
||||||
|
|
||||||
|
- No readonly support for private memory;
|
||||||
|
|
||||||
|
- No SMM support: SMM support requires manipulating the guset register states
|
||||||
|
which is not allowed;
|
||||||
|
|
||||||
|
Live Migration
|
||||||
|
--------------
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
References
|
||||||
|
----------
|
||||||
|
|
||||||
|
- `TDX Homepage <https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html>`__
|
||||||
|
|
||||||
|
- `SGX QE <https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteGeneration>`__
|
||||||
@@ -29,6 +29,7 @@ Architectural features
|
|||||||
i386/kvm-pv
|
i386/kvm-pv
|
||||||
i386/sgx
|
i386/sgx
|
||||||
i386/amd-memory-encryption
|
i386/amd-memory-encryption
|
||||||
|
i386/tdx
|
||||||
|
|
||||||
OS requirements
|
OS requirements
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ ERST
|
|||||||
.help = "show info of one block device or all block devices "
|
.help = "show info of one block device or all block devices "
|
||||||
"(-n: show named nodes; -v: show details)",
|
"(-n: show named nodes; -v: show details)",
|
||||||
.cmd = hmp_info_block,
|
.cmd = hmp_info_block,
|
||||||
|
.coroutine = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
SRST
|
SRST
|
||||||
|
|||||||
@@ -247,7 +247,6 @@ static void aspeed_ast2400_soc_realize(DeviceState *dev, Error **errp)
|
|||||||
Aspeed2400SoCState *a = ASPEED2400_SOC(dev);
|
Aspeed2400SoCState *a = ASPEED2400_SOC(dev);
|
||||||
AspeedSoCState *s = ASPEED_SOC(dev);
|
AspeedSoCState *s = ASPEED_SOC(dev);
|
||||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||||
Error *err = NULL;
|
|
||||||
g_autofree char *sram_name = NULL;
|
g_autofree char *sram_name = NULL;
|
||||||
|
|
||||||
/* Default boot region (SPI memory or ROMs) */
|
/* Default boot region (SPI memory or ROMs) */
|
||||||
@@ -276,9 +275,8 @@ static void aspeed_ast2400_soc_realize(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
/* SRAM */
|
/* SRAM */
|
||||||
sram_name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index);
|
sram_name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index);
|
||||||
memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size, &err);
|
if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size,
|
||||||
if (err) {
|
errp)) {
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(s->memory,
|
memory_region_add_subregion(s->memory,
|
||||||
|
|||||||
@@ -282,7 +282,6 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
|
|||||||
Aspeed2600SoCState *a = ASPEED2600_SOC(dev);
|
Aspeed2600SoCState *a = ASPEED2600_SOC(dev);
|
||||||
AspeedSoCState *s = ASPEED_SOC(dev);
|
AspeedSoCState *s = ASPEED_SOC(dev);
|
||||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||||
Error *err = NULL;
|
|
||||||
qemu_irq irq;
|
qemu_irq irq;
|
||||||
g_autofree char *sram_name = NULL;
|
g_autofree char *sram_name = NULL;
|
||||||
|
|
||||||
@@ -355,9 +354,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
/* SRAM */
|
/* SRAM */
|
||||||
sram_name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index);
|
sram_name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index);
|
||||||
memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size, &err);
|
if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size,
|
||||||
if (err) {
|
errp)) {
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(s->memory,
|
memory_region_add_subregion(s->memory,
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
FslIMX25State *s = FSL_IMX25(dev);
|
FslIMX25State *s = FSL_IMX25(dev);
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
|
if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
|
||||||
return;
|
return;
|
||||||
@@ -281,28 +280,22 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
|
|||||||
FSL_IMX25_WDT_IRQ));
|
FSL_IMX25_WDT_IRQ));
|
||||||
|
|
||||||
/* initialize 2 x 16 KB ROM */
|
/* initialize 2 x 16 KB ROM */
|
||||||
memory_region_init_rom(&s->rom[0], OBJECT(dev), "imx25.rom0",
|
if (!memory_region_init_rom(&s->rom[0], OBJECT(dev), "imx25.rom0",
|
||||||
FSL_IMX25_ROM0_SIZE, &err);
|
FSL_IMX25_ROM0_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
|
||||||
&s->rom[0]);
|
&s->rom[0]);
|
||||||
memory_region_init_rom(&s->rom[1], OBJECT(dev), "imx25.rom1",
|
if (!memory_region_init_rom(&s->rom[1], OBJECT(dev), "imx25.rom1",
|
||||||
FSL_IMX25_ROM1_SIZE, &err);
|
FSL_IMX25_ROM1_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM1_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM1_ADDR,
|
||||||
&s->rom[1]);
|
&s->rom[1]);
|
||||||
|
|
||||||
/* initialize internal RAM (128 KB) */
|
/* initialize internal RAM (128 KB) */
|
||||||
memory_region_init_ram(&s->iram, NULL, "imx25.iram", FSL_IMX25_IRAM_SIZE,
|
if (!memory_region_init_ram(&s->iram, NULL, "imx25.iram",
|
||||||
&err);
|
FSL_IMX25_IRAM_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ADDR,
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
FslIMX31State *s = FSL_IMX31(dev);
|
FslIMX31State *s = FSL_IMX31(dev);
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
|
if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
|
||||||
return;
|
return;
|
||||||
@@ -188,30 +187,24 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
|
|||||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, FSL_IMX31_WDT_ADDR);
|
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, FSL_IMX31_WDT_ADDR);
|
||||||
|
|
||||||
/* On a real system, the first 16k is a `secure boot rom' */
|
/* On a real system, the first 16k is a `secure boot rom' */
|
||||||
memory_region_init_rom(&s->secure_rom, OBJECT(dev), "imx31.secure_rom",
|
if (!memory_region_init_rom(&s->secure_rom, OBJECT(dev), "imx31.secure_rom",
|
||||||
FSL_IMX31_SECURE_ROM_SIZE, &err);
|
FSL_IMX31_SECURE_ROM_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX31_SECURE_ROM_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX31_SECURE_ROM_ADDR,
|
||||||
&s->secure_rom);
|
&s->secure_rom);
|
||||||
|
|
||||||
/* There is also a 16k ROM */
|
/* There is also a 16k ROM */
|
||||||
memory_region_init_rom(&s->rom, OBJECT(dev), "imx31.rom",
|
if (!memory_region_init_rom(&s->rom, OBJECT(dev), "imx31.rom",
|
||||||
FSL_IMX31_ROM_SIZE, &err);
|
FSL_IMX31_ROM_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX31_ROM_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX31_ROM_ADDR,
|
||||||
&s->rom);
|
&s->rom);
|
||||||
|
|
||||||
/* initialize internal RAM (16 KB) */
|
/* initialize internal RAM (16 KB) */
|
||||||
memory_region_init_ram(&s->iram, NULL, "imx31.iram", FSL_IMX31_IRAM_SIZE,
|
if (!memory_region_init_ram(&s->iram, NULL, "imx31.iram",
|
||||||
&err);
|
FSL_IMX31_IRAM_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ADDR,
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
|
|||||||
MachineState *ms = MACHINE(qdev_get_machine());
|
MachineState *ms = MACHINE(qdev_get_machine());
|
||||||
FslIMX6State *s = FSL_IMX6(dev);
|
FslIMX6State *s = FSL_IMX6(dev);
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
Error *err = NULL;
|
|
||||||
unsigned int smp_cpus = ms->smp.cpus;
|
unsigned int smp_cpus = ms->smp.cpus;
|
||||||
|
|
||||||
if (smp_cpus > FSL_IMX6_NUM_CPUS) {
|
if (smp_cpus > FSL_IMX6_NUM_CPUS) {
|
||||||
@@ -423,30 +422,24 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ROM memory */
|
/* ROM memory */
|
||||||
memory_region_init_rom(&s->rom, OBJECT(dev), "imx6.rom",
|
if (!memory_region_init_rom(&s->rom, OBJECT(dev), "imx6.rom",
|
||||||
FSL_IMX6_ROM_SIZE, &err);
|
FSL_IMX6_ROM_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX6_ROM_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX6_ROM_ADDR,
|
||||||
&s->rom);
|
&s->rom);
|
||||||
|
|
||||||
/* CAAM memory */
|
/* CAAM memory */
|
||||||
memory_region_init_rom(&s->caam, OBJECT(dev), "imx6.caam",
|
if (!memory_region_init_rom(&s->caam, OBJECT(dev), "imx6.caam",
|
||||||
FSL_IMX6_CAAM_MEM_SIZE, &err);
|
FSL_IMX6_CAAM_MEM_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX6_CAAM_MEM_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX6_CAAM_MEM_ADDR,
|
||||||
&s->caam);
|
&s->caam);
|
||||||
|
|
||||||
/* OCRAM memory */
|
/* OCRAM memory */
|
||||||
memory_region_init_ram(&s->ocram, NULL, "imx6.ocram", FSL_IMX6_OCRAM_SIZE,
|
if (!memory_region_init_ram(&s->ocram, NULL, "imx6.ocram",
|
||||||
&err);
|
FSL_IMX6_OCRAM_SIZE, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ADDR,
|
memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ADDR,
|
||||||
|
|||||||
@@ -291,12 +291,9 @@ static void integratorcm_realize(DeviceState *d, Error **errp)
|
|||||||
{
|
{
|
||||||
IntegratorCMState *s = INTEGRATOR_CM(d);
|
IntegratorCMState *s = INTEGRATOR_CM(d);
|
||||||
SysBusDevice *dev = SYS_BUS_DEVICE(d);
|
SysBusDevice *dev = SYS_BUS_DEVICE(d);
|
||||||
Error *local_err = NULL;
|
|
||||||
|
|
||||||
memory_region_init_ram(&s->flash, OBJECT(d), "integrator.flash", 0x100000,
|
if (!memory_region_init_ram(&s->flash, OBJECT(d), "integrator.flash",
|
||||||
&local_err);
|
0x100000, errp)) {
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
|
|||||||
{
|
{
|
||||||
NRF51State *s = NRF51_SOC(dev_soc);
|
NRF51State *s = NRF51_SOC(dev_soc);
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
Error *err = NULL;
|
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
hwaddr base_addr = 0;
|
hwaddr base_addr = 0;
|
||||||
|
|
||||||
@@ -92,10 +91,8 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
|
|||||||
|
|
||||||
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
|
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
|
||||||
|
|
||||||
memory_region_init_ram(&s->sram, OBJECT(s), "nrf51.sram", s->sram_size,
|
if (!memory_region_init_ram(&s->sram, OBJECT(s), "nrf51.sram", s->sram_size,
|
||||||
&err);
|
errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion(&s->container, NRF51_SRAM_BASE, &s->sram);
|
memory_region_add_subregion(&s->container, NRF51_SRAM_BASE, &s->sram);
|
||||||
|
|||||||
@@ -418,6 +418,9 @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
|
|||||||
|
|
||||||
xen_block_set_size(blockdev);
|
xen_block_set_size(blockdev);
|
||||||
|
|
||||||
|
if (!monitor_add_blk(conf->blk, blockdev->drive->id, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
blockdev->dataplane =
|
blockdev->dataplane =
|
||||||
xen_block_dataplane_create(xendev, blk, conf->logical_block_size,
|
xen_block_dataplane_create(xendev, blk, conf->logical_block_size,
|
||||||
blockdev->props.iothread);
|
blockdev->props.iothread);
|
||||||
@@ -874,6 +877,8 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
|
|||||||
const char *mode = qdict_get_try_str(opts, "mode");
|
const char *mode = qdict_get_try_str(opts, "mode");
|
||||||
const char *direct_io_safe = qdict_get_try_str(opts, "direct-io-safe");
|
const char *direct_io_safe = qdict_get_try_str(opts, "direct-io-safe");
|
||||||
const char *discard_enable = qdict_get_try_str(opts, "discard-enable");
|
const char *discard_enable = qdict_get_try_str(opts, "discard-enable");
|
||||||
|
const char *suse_diskcache_disable_flush = qdict_get_try_str(opts,
|
||||||
|
"suse-diskcache-disable-flush");
|
||||||
char *driver = NULL;
|
char *driver = NULL;
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
XenBlockDrive *drive = NULL;
|
XenBlockDrive *drive = NULL;
|
||||||
@@ -954,6 +959,16 @@ static XenBlockDrive *xen_block_drive_create(const char *id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (suse_diskcache_disable_flush) {
|
||||||
|
unsigned long value;
|
||||||
|
if (!qemu_strtoul(suse_diskcache_disable_flush, NULL, 2, &value) && !!value) {
|
||||||
|
QDict *cache_qdict = qdict_new();
|
||||||
|
|
||||||
|
qdict_put_bool(cache_qdict, "no-flush", true);
|
||||||
|
qdict_put_obj(file_layer, "cache", QOBJECT(cache_qdict));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is necessary to turn file locking off as an emulated device
|
* It is necessary to turn file locking off as an emulated device
|
||||||
* may have already opened the same image file.
|
* may have already opened the same image file.
|
||||||
|
|||||||
@@ -1189,6 +1189,11 @@ bool machine_mem_merge(MachineState *machine)
|
|||||||
return machine->mem_merge;
|
return machine->mem_merge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool machine_require_guest_memfd(MachineState *machine)
|
||||||
|
{
|
||||||
|
return machine->require_guest_memfd;
|
||||||
|
}
|
||||||
|
|
||||||
static char *cpu_slot_to_string(const CPUArchId *cpu)
|
static char *cpu_slot_to_string(const CPUArchId *cpu)
|
||||||
{
|
{
|
||||||
GString *s = g_string_new(NULL);
|
GString *s = g_string_new(NULL);
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ config SGX
|
|||||||
bool
|
bool
|
||||||
depends on KVM
|
depends on KVM
|
||||||
|
|
||||||
|
config TDX
|
||||||
|
bool
|
||||||
|
select X86_FW_OVMF
|
||||||
|
depends on KVM
|
||||||
|
|
||||||
config PC
|
config PC
|
||||||
bool
|
bool
|
||||||
imply APPLESMC
|
imply APPLESMC
|
||||||
@@ -26,6 +31,7 @@ config PC
|
|||||||
imply QXL
|
imply QXL
|
||||||
imply SEV
|
imply SEV
|
||||||
imply SGX
|
imply SGX
|
||||||
|
imply TDX
|
||||||
imply TEST_DEVICES
|
imply TEST_DEVICES
|
||||||
imply TPM_CRB
|
imply TPM_CRB
|
||||||
imply TPM_TIS_ISA
|
imply TPM_TIS_ISA
|
||||||
|
|||||||
@@ -975,7 +975,8 @@ static void build_dbg_aml(Aml *table)
|
|||||||
aml_append(table, scope);
|
aml_append(table, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Aml *build_link_dev(const char *name, uint8_t uid, Aml *reg)
|
static Aml *build_link_dev(const char *name, uint8_t uid, Aml *reg,
|
||||||
|
bool level_trigger_unsupported)
|
||||||
{
|
{
|
||||||
Aml *dev;
|
Aml *dev;
|
||||||
Aml *crs;
|
Aml *crs;
|
||||||
@@ -987,7 +988,10 @@ static Aml *build_link_dev(const char *name, uint8_t uid, Aml *reg)
|
|||||||
aml_append(dev, aml_name_decl("_UID", aml_int(uid)));
|
aml_append(dev, aml_name_decl("_UID", aml_int(uid)));
|
||||||
|
|
||||||
crs = aml_resource_template();
|
crs = aml_resource_template();
|
||||||
aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
|
aml_append(crs, aml_interrupt(AML_CONSUMER,
|
||||||
|
level_trigger_unsupported ?
|
||||||
|
AML_EDGE : AML_LEVEL,
|
||||||
|
AML_ACTIVE_HIGH,
|
||||||
AML_SHARED, irqs, ARRAY_SIZE(irqs)));
|
AML_SHARED, irqs, ARRAY_SIZE(irqs)));
|
||||||
aml_append(dev, aml_name_decl("_PRS", crs));
|
aml_append(dev, aml_name_decl("_PRS", crs));
|
||||||
|
|
||||||
@@ -1011,7 +1015,8 @@ static Aml *build_link_dev(const char *name, uint8_t uid, Aml *reg)
|
|||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Aml *build_gsi_link_dev(const char *name, uint8_t uid, uint8_t gsi)
|
static Aml *build_gsi_link_dev(const char *name, uint8_t uid,
|
||||||
|
uint8_t gsi, bool level_trigger_unsupported)
|
||||||
{
|
{
|
||||||
Aml *dev;
|
Aml *dev;
|
||||||
Aml *crs;
|
Aml *crs;
|
||||||
@@ -1024,7 +1029,10 @@ static Aml *build_gsi_link_dev(const char *name, uint8_t uid, uint8_t gsi)
|
|||||||
|
|
||||||
crs = aml_resource_template();
|
crs = aml_resource_template();
|
||||||
irqs = gsi;
|
irqs = gsi;
|
||||||
aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
|
aml_append(crs, aml_interrupt(AML_CONSUMER,
|
||||||
|
level_trigger_unsupported ?
|
||||||
|
AML_EDGE : AML_LEVEL,
|
||||||
|
AML_ACTIVE_HIGH,
|
||||||
AML_SHARED, &irqs, 1));
|
AML_SHARED, &irqs, 1));
|
||||||
aml_append(dev, aml_name_decl("_PRS", crs));
|
aml_append(dev, aml_name_decl("_PRS", crs));
|
||||||
|
|
||||||
@@ -1043,7 +1051,7 @@ static Aml *build_gsi_link_dev(const char *name, uint8_t uid, uint8_t gsi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* _CRS method - get current settings */
|
/* _CRS method - get current settings */
|
||||||
static Aml *build_iqcr_method(bool is_piix4)
|
static Aml *build_iqcr_method(bool is_piix4, bool level_trigger_unsupported)
|
||||||
{
|
{
|
||||||
Aml *if_ctx;
|
Aml *if_ctx;
|
||||||
uint32_t irqs;
|
uint32_t irqs;
|
||||||
@@ -1051,7 +1059,9 @@ static Aml *build_iqcr_method(bool is_piix4)
|
|||||||
Aml *crs = aml_resource_template();
|
Aml *crs = aml_resource_template();
|
||||||
|
|
||||||
irqs = 0;
|
irqs = 0;
|
||||||
aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL,
|
aml_append(crs, aml_interrupt(AML_CONSUMER,
|
||||||
|
level_trigger_unsupported ?
|
||||||
|
AML_EDGE : AML_LEVEL,
|
||||||
AML_ACTIVE_HIGH, AML_SHARED, &irqs, 1));
|
AML_ACTIVE_HIGH, AML_SHARED, &irqs, 1));
|
||||||
aml_append(method, aml_name_decl("PRR0", crs));
|
aml_append(method, aml_name_decl("PRR0", crs));
|
||||||
|
|
||||||
@@ -1085,7 +1095,7 @@ static Aml *build_irq_status_method(void)
|
|||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void build_piix4_pci0_int(Aml *table)
|
static void build_piix4_pci0_int(Aml *table, bool level_trigger_unsupported)
|
||||||
{
|
{
|
||||||
Aml *dev;
|
Aml *dev;
|
||||||
Aml *crs;
|
Aml *crs;
|
||||||
@@ -1098,12 +1108,16 @@ static void build_piix4_pci0_int(Aml *table)
|
|||||||
aml_append(sb_scope, pci0_scope);
|
aml_append(sb_scope, pci0_scope);
|
||||||
|
|
||||||
aml_append(sb_scope, build_irq_status_method());
|
aml_append(sb_scope, build_irq_status_method());
|
||||||
aml_append(sb_scope, build_iqcr_method(true));
|
aml_append(sb_scope, build_iqcr_method(true, level_trigger_unsupported));
|
||||||
|
|
||||||
aml_append(sb_scope, build_link_dev("LNKA", 0, aml_name("PRQ0")));
|
aml_append(sb_scope, build_link_dev("LNKA", 0, aml_name("PRQ0"),
|
||||||
aml_append(sb_scope, build_link_dev("LNKB", 1, aml_name("PRQ1")));
|
level_trigger_unsupported));
|
||||||
aml_append(sb_scope, build_link_dev("LNKC", 2, aml_name("PRQ2")));
|
aml_append(sb_scope, build_link_dev("LNKB", 1, aml_name("PRQ1"),
|
||||||
aml_append(sb_scope, build_link_dev("LNKD", 3, aml_name("PRQ3")));
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_link_dev("LNKC", 2, aml_name("PRQ2"),
|
||||||
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_link_dev("LNKD", 3, aml_name("PRQ3"),
|
||||||
|
level_trigger_unsupported));
|
||||||
|
|
||||||
dev = aml_device("LNKS");
|
dev = aml_device("LNKS");
|
||||||
{
|
{
|
||||||
@@ -1112,7 +1126,9 @@ static void build_piix4_pci0_int(Aml *table)
|
|||||||
|
|
||||||
crs = aml_resource_template();
|
crs = aml_resource_template();
|
||||||
irqs = 9;
|
irqs = 9;
|
||||||
aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL,
|
aml_append(crs, aml_interrupt(AML_CONSUMER,
|
||||||
|
level_trigger_unsupported ?
|
||||||
|
AML_EDGE : AML_LEVEL,
|
||||||
AML_ACTIVE_HIGH, AML_SHARED,
|
AML_ACTIVE_HIGH, AML_SHARED,
|
||||||
&irqs, 1));
|
&irqs, 1));
|
||||||
aml_append(dev, aml_name_decl("_PRS", crs));
|
aml_append(dev, aml_name_decl("_PRS", crs));
|
||||||
@@ -1198,7 +1214,7 @@ static Aml *build_q35_routing_table(const char *str)
|
|||||||
return pkg;
|
return pkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void build_q35_pci0_int(Aml *table)
|
static void build_q35_pci0_int(Aml *table, bool level_trigger_unsupported)
|
||||||
{
|
{
|
||||||
Aml *method;
|
Aml *method;
|
||||||
Aml *sb_scope = aml_scope("_SB");
|
Aml *sb_scope = aml_scope("_SB");
|
||||||
@@ -1237,25 +1253,41 @@ static void build_q35_pci0_int(Aml *table)
|
|||||||
aml_append(sb_scope, pci0_scope);
|
aml_append(sb_scope, pci0_scope);
|
||||||
|
|
||||||
aml_append(sb_scope, build_irq_status_method());
|
aml_append(sb_scope, build_irq_status_method());
|
||||||
aml_append(sb_scope, build_iqcr_method(false));
|
aml_append(sb_scope, build_iqcr_method(false, level_trigger_unsupported));
|
||||||
|
|
||||||
aml_append(sb_scope, build_link_dev("LNKA", 0, aml_name("PRQA")));
|
aml_append(sb_scope, build_link_dev("LNKA", 0, aml_name("PRQA"),
|
||||||
aml_append(sb_scope, build_link_dev("LNKB", 1, aml_name("PRQB")));
|
level_trigger_unsupported));
|
||||||
aml_append(sb_scope, build_link_dev("LNKC", 2, aml_name("PRQC")));
|
aml_append(sb_scope, build_link_dev("LNKB", 1, aml_name("PRQB"),
|
||||||
aml_append(sb_scope, build_link_dev("LNKD", 3, aml_name("PRQD")));
|
level_trigger_unsupported));
|
||||||
aml_append(sb_scope, build_link_dev("LNKE", 4, aml_name("PRQE")));
|
aml_append(sb_scope, build_link_dev("LNKC", 2, aml_name("PRQC"),
|
||||||
aml_append(sb_scope, build_link_dev("LNKF", 5, aml_name("PRQF")));
|
level_trigger_unsupported));
|
||||||
aml_append(sb_scope, build_link_dev("LNKG", 6, aml_name("PRQG")));
|
aml_append(sb_scope, build_link_dev("LNKD", 3, aml_name("PRQD"),
|
||||||
aml_append(sb_scope, build_link_dev("LNKH", 7, aml_name("PRQH")));
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_link_dev("LNKE", 4, aml_name("PRQE"),
|
||||||
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_link_dev("LNKF", 5, aml_name("PRQF"),
|
||||||
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_link_dev("LNKG", 6, aml_name("PRQG"),
|
||||||
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_link_dev("LNKH", 7, aml_name("PRQH"),
|
||||||
|
level_trigger_unsupported));
|
||||||
|
|
||||||
aml_append(sb_scope, build_gsi_link_dev("GSIA", 0x10, 0x10));
|
aml_append(sb_scope, build_gsi_link_dev("GSIA", 0x10, 0x10,
|
||||||
aml_append(sb_scope, build_gsi_link_dev("GSIB", 0x11, 0x11));
|
level_trigger_unsupported));
|
||||||
aml_append(sb_scope, build_gsi_link_dev("GSIC", 0x12, 0x12));
|
aml_append(sb_scope, build_gsi_link_dev("GSIB", 0x11, 0x11,
|
||||||
aml_append(sb_scope, build_gsi_link_dev("GSID", 0x13, 0x13));
|
level_trigger_unsupported));
|
||||||
aml_append(sb_scope, build_gsi_link_dev("GSIE", 0x14, 0x14));
|
aml_append(sb_scope, build_gsi_link_dev("GSIC", 0x12, 0x12,
|
||||||
aml_append(sb_scope, build_gsi_link_dev("GSIF", 0x15, 0x15));
|
level_trigger_unsupported));
|
||||||
aml_append(sb_scope, build_gsi_link_dev("GSIG", 0x16, 0x16));
|
aml_append(sb_scope, build_gsi_link_dev("GSID", 0x13, 0x13,
|
||||||
aml_append(sb_scope, build_gsi_link_dev("GSIH", 0x17, 0x17));
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_gsi_link_dev("GSIE", 0x14, 0x14,
|
||||||
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_gsi_link_dev("GSIF", 0x15, 0x15,
|
||||||
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_gsi_link_dev("GSIG", 0x16, 0x16,
|
||||||
|
level_trigger_unsupported));
|
||||||
|
aml_append(sb_scope, build_gsi_link_dev("GSIH", 0x17, 0x17,
|
||||||
|
level_trigger_unsupported));
|
||||||
|
|
||||||
aml_append(table, sb_scope);
|
aml_append(table, sb_scope);
|
||||||
}
|
}
|
||||||
@@ -1436,6 +1468,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
|||||||
PCMachineState *pcms = PC_MACHINE(machine);
|
PCMachineState *pcms = PC_MACHINE(machine);
|
||||||
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
|
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
|
||||||
X86MachineState *x86ms = X86_MACHINE(machine);
|
X86MachineState *x86ms = X86_MACHINE(machine);
|
||||||
|
bool level_trigger_unsupported = x86ms->eoi_intercept_unsupported;
|
||||||
AcpiMcfgInfo mcfg;
|
AcpiMcfgInfo mcfg;
|
||||||
bool mcfg_valid = !!acpi_get_mcfg(&mcfg);
|
bool mcfg_valid = !!acpi_get_mcfg(&mcfg);
|
||||||
uint32_t nr_mem = machine->ram_slots;
|
uint32_t nr_mem = machine->ram_slots;
|
||||||
@@ -1468,7 +1501,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
|||||||
if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
|
if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
|
||||||
build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
|
build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
|
||||||
}
|
}
|
||||||
build_piix4_pci0_int(dsdt);
|
build_piix4_pci0_int(dsdt, level_trigger_unsupported);
|
||||||
} else if (q35) {
|
} else if (q35) {
|
||||||
sb_scope = aml_scope("_SB");
|
sb_scope = aml_scope("_SB");
|
||||||
dev = aml_device("PCI0");
|
dev = aml_device("PCI0");
|
||||||
@@ -1512,7 +1545,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
|||||||
if (pm->pcihp_bridge_en) {
|
if (pm->pcihp_bridge_en) {
|
||||||
build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
|
build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
|
||||||
}
|
}
|
||||||
build_q35_pci0_int(dsdt);
|
build_q35_pci0_int(dsdt, level_trigger_unsupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (misc->has_hpet) {
|
if (misc->has_hpet) {
|
||||||
|
|||||||
@@ -100,9 +100,11 @@ void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
|
|||||||
int i;
|
int i;
|
||||||
bool x2apic_mode = false;
|
bool x2apic_mode = false;
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(x86ms);
|
MachineClass *mc = MACHINE_GET_CLASS(x86ms);
|
||||||
|
X86MachineClass *x86mc = X86_MACHINE_GET_CLASS(x86ms);
|
||||||
const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(x86ms));
|
const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(x86ms));
|
||||||
AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = oem_id,
|
AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = oem_id,
|
||||||
.oem_table_id = oem_table_id };
|
.oem_table_id = oem_table_id };
|
||||||
|
bool level_trigger_unsupported = x86ms->eoi_intercept_unsupported;
|
||||||
|
|
||||||
acpi_table_begin(&table, table_data);
|
acpi_table_begin(&table, table_data);
|
||||||
/* Local APIC Address */
|
/* Local APIC Address */
|
||||||
@@ -122,18 +124,42 @@ void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
|
|||||||
IO_APIC_SECONDARY_ADDRESS, IO_APIC_SECONDARY_IRQBASE);
|
IO_APIC_SECONDARY_ADDRESS, IO_APIC_SECONDARY_IRQBASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x86ms->apic_xrupt_override) {
|
if (level_trigger_unsupported) {
|
||||||
build_xrupt_override(table_data, 0, 2,
|
/* Force edge trigger */
|
||||||
0 /* Flags: Conforms to the specifications of the bus */);
|
if (x86mc->apic_xrupt_override) {
|
||||||
}
|
build_xrupt_override(table_data, 0, 2,
|
||||||
|
/* Flags: active high, edge triggered */
|
||||||
for (i = 1; i < 16; i++) {
|
1 | (1 << 2));
|
||||||
if (!(x86ms->pci_irq_mask & (1 << i))) {
|
}
|
||||||
/* No need for a INT source override structure. */
|
|
||||||
continue;
|
for (i = x86mc->apic_xrupt_override ? 1 : 0; i < 16; i++) {
|
||||||
|
build_xrupt_override(table_data, i, i,
|
||||||
|
/* Flags: active high, edge triggered */
|
||||||
|
1 | (1 << 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x86ms->ioapic2) {
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
build_xrupt_override(table_data, IO_APIC_SECONDARY_IRQBASE + i,
|
||||||
|
IO_APIC_SECONDARY_IRQBASE + i,
|
||||||
|
/* Flags: active high, edge triggered */
|
||||||
|
1 | (1 << 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (x86mc->apic_xrupt_override) {
|
||||||
|
build_xrupt_override(table_data, 0, 2,
|
||||||
|
0 /* Flags: Conforms to the specifications of the bus */);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < 16; i++) {
|
||||||
|
if (!(x86ms->pci_irq_mask & (1 << i))) {
|
||||||
|
/* No need for a INT source override structure. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
build_xrupt_override(table_data, i, i,
|
||||||
|
0xd /* Flags: Active high, Level Triggered */);
|
||||||
}
|
}
|
||||||
build_xrupt_override(table_data, i, i,
|
|
||||||
0xd /* Flags: Active high, Level Triggered */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x2apic_mode) {
|
if (x2apic_mode) {
|
||||||
|
|||||||
@@ -48,15 +48,25 @@ const char *fw_cfg_arch_key_name(uint16_t key)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
|
void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SMBIOS
|
#ifdef CONFIG_SMBIOS
|
||||||
uint8_t *smbios_tables, *smbios_anchor;
|
uint8_t *smbios_tables, *smbios_anchor;
|
||||||
size_t smbios_tables_len, smbios_anchor_len;
|
size_t smbios_tables_len, smbios_anchor_len;
|
||||||
struct smbios_phys_mem_area *mem_array;
|
struct smbios_phys_mem_area *mem_array;
|
||||||
unsigned i, array_count;
|
unsigned i, array_count;
|
||||||
|
MachineState *ms = MACHINE(pcms);
|
||||||
|
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
|
||||||
|
MachineClass *mc = MACHINE_GET_CLASS(pcms);
|
||||||
X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
|
X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
|
||||||
|
|
||||||
|
if (pcmc->smbios_defaults) {
|
||||||
|
/* These values are guest ABI, do not change */
|
||||||
|
smbios_set_defaults("QEMU", mc->desc, mc->name,
|
||||||
|
pcmc->smbios_legacy_mode, pcmc->smbios_uuid_encoded,
|
||||||
|
pcms->smbios_entry_point_type);
|
||||||
|
}
|
||||||
|
|
||||||
/* tell smbios about cpuid version and features */
|
/* tell smbios about cpuid version and features */
|
||||||
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
|
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#define HW_I386_FW_CFG_H
|
#define HW_I386_FW_CFG_H
|
||||||
|
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
|
#include "hw/i386/pc.h"
|
||||||
#include "hw/nvram/fw_cfg.h"
|
#include "hw/nvram/fw_cfg.h"
|
||||||
|
|
||||||
#define FW_CFG_IO_BASE 0x510
|
#define FW_CFG_IO_BASE 0x510
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
FWCfgState *fw_cfg_arch_create(MachineState *ms,
|
FWCfgState *fw_cfg_arch_create(MachineState *ms,
|
||||||
uint16_t boot_cpus,
|
uint16_t boot_cpus,
|
||||||
uint16_t apic_id_limit);
|
uint16_t apic_id_limit);
|
||||||
void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg);
|
void fw_cfg_build_smbios(PCMachineState *ms, FWCfgState *fw_cfg);
|
||||||
void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg);
|
void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg);
|
||||||
void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg);
|
void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg);
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files(
|
|||||||
'port92.c'))
|
'port92.c'))
|
||||||
i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('pc_sysfw_ovmf.c'),
|
i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('pc_sysfw_ovmf.c'),
|
||||||
if_false: files('pc_sysfw_ovmf-stubs.c'))
|
if_false: files('pc_sysfw_ovmf-stubs.c'))
|
||||||
|
i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c', 'tdvf-hob.c'))
|
||||||
|
|
||||||
subdir('kvm')
|
subdir('kvm')
|
||||||
subdir('xen')
|
subdir('xen')
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
|
|||||||
&error_abort);
|
&error_abort);
|
||||||
isa_bus_register_input_irqs(isa_bus, x86ms->gsi);
|
isa_bus_register_input_irqs(isa_bus, x86ms->gsi);
|
||||||
|
|
||||||
ioapic_init_gsi(gsi_state, "machine");
|
ioapic_init_gsi(gsi_state, OBJECT(mms));
|
||||||
if (ioapics > 1) {
|
if (ioapics > 1) {
|
||||||
x86ms->ioapic2 = ioapic_init_secondary(gsi_state);
|
x86ms->ioapic2 = ioapic_init_secondary(gsi_state);
|
||||||
}
|
}
|
||||||
|
|||||||
37
hw/i386/pc.c
37
hw/i386/pc.c
@@ -43,6 +43,7 @@
|
|||||||
#include "sysemu/xen.h"
|
#include "sysemu/xen.h"
|
||||||
#include "sysemu/reset.h"
|
#include "sysemu/reset.h"
|
||||||
#include "kvm/kvm_i386.h"
|
#include "kvm/kvm_i386.h"
|
||||||
|
#include "kvm/tdx.h"
|
||||||
#include "hw/xen/xen.h"
|
#include "hw/xen/xen.h"
|
||||||
#include "qapi/qmp/qlist.h"
|
#include "qapi/qmp/qlist.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
@@ -692,22 +693,13 @@ void pc_machine_done(Notifier *notifier, void *data)
|
|||||||
|
|
||||||
acpi_setup();
|
acpi_setup();
|
||||||
if (x86ms->fw_cfg) {
|
if (x86ms->fw_cfg) {
|
||||||
fw_cfg_build_smbios(MACHINE(pcms), x86ms->fw_cfg);
|
fw_cfg_build_smbios(pcms, x86ms->fw_cfg);
|
||||||
fw_cfg_build_feature_control(MACHINE(pcms), x86ms->fw_cfg);
|
fw_cfg_build_feature_control(MACHINE(pcms), x86ms->fw_cfg);
|
||||||
/* update FW_CFG_NB_CPUS to account for -device added CPUs */
|
/* update FW_CFG_NB_CPUS to account for -device added CPUs */
|
||||||
fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
|
fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pc_guest_info_init(PCMachineState *pcms)
|
|
||||||
{
|
|
||||||
X86MachineState *x86ms = X86_MACHINE(pcms);
|
|
||||||
|
|
||||||
x86ms->apic_xrupt_override = true;
|
|
||||||
pcms->machine_done.notify = pc_machine_done;
|
|
||||||
qemu_add_machine_init_done_notifier(&pcms->machine_done);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setup pci memory address space mapping into system address space */
|
/* setup pci memory address space mapping into system address space */
|
||||||
void pc_pci_as_mapping_init(MemoryRegion *system_memory,
|
void pc_pci_as_mapping_init(MemoryRegion *system_memory,
|
||||||
MemoryRegion *pci_address_space)
|
MemoryRegion *pci_address_space)
|
||||||
@@ -1036,16 +1028,18 @@ void pc_memory_init(PCMachineState *pcms,
|
|||||||
/* Initialize PC system firmware */
|
/* Initialize PC system firmware */
|
||||||
pc_system_firmware_init(pcms, rom_memory);
|
pc_system_firmware_init(pcms, rom_memory);
|
||||||
|
|
||||||
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
|
if (!is_tdx_vm()) {
|
||||||
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
|
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
|
||||||
&error_fatal);
|
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
|
||||||
if (pcmc->pci_enabled) {
|
&error_fatal);
|
||||||
memory_region_set_readonly(option_rom_mr, true);
|
if (pcmc->pci_enabled) {
|
||||||
|
memory_region_set_readonly(option_rom_mr, true);
|
||||||
|
}
|
||||||
|
memory_region_add_subregion_overlap(rom_memory,
|
||||||
|
PC_ROM_MIN_VGA,
|
||||||
|
option_rom_mr,
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
memory_region_add_subregion_overlap(rom_memory,
|
|
||||||
PC_ROM_MIN_VGA,
|
|
||||||
option_rom_mr,
|
|
||||||
1);
|
|
||||||
|
|
||||||
fw_cfg = fw_cfg_arch_create(machine,
|
fw_cfg = fw_cfg_arch_create(machine,
|
||||||
x86ms->boot_cpus, x86ms->apic_id_limit);
|
x86ms->boot_cpus, x86ms->apic_id_limit);
|
||||||
@@ -1753,6 +1747,9 @@ static void pc_machine_initfn(Object *obj)
|
|||||||
object_property_add_alias(OBJECT(pcms), "pcspk-audiodev",
|
object_property_add_alias(OBJECT(pcms), "pcspk-audiodev",
|
||||||
OBJECT(pcms->pcspk), "audiodev");
|
OBJECT(pcms->pcspk), "audiodev");
|
||||||
cxl_machine_init(obj, &pcms->cxl_devices_state);
|
cxl_machine_init(obj, &pcms->cxl_devices_state);
|
||||||
|
|
||||||
|
pcms->machine_done.notify = pc_machine_done;
|
||||||
|
qemu_add_machine_init_done_notifier(&pcms->machine_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pc_machine_kvm_type(MachineState *machine, const char *kvm_type)
|
int pc_machine_kvm_type(MachineState *machine, const char *kvm_type)
|
||||||
@@ -1806,6 +1803,7 @@ static bool pc_hotplug_allowed(MachineState *ms, DeviceState *dev, Error **errp)
|
|||||||
static void pc_machine_class_init(ObjectClass *oc, void *data)
|
static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
MachineClass *mc = MACHINE_CLASS(oc);
|
MachineClass *mc = MACHINE_CLASS(oc);
|
||||||
|
X86MachineClass *x86mc = X86_MACHINE_CLASS(oc);
|
||||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(oc);
|
PCMachineClass *pcmc = PC_MACHINE_CLASS(oc);
|
||||||
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
|
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
|
||||||
|
|
||||||
@@ -1825,6 +1823,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
pcmc->pvh_enabled = true;
|
pcmc->pvh_enabled = true;
|
||||||
pcmc->kvmclock_create_always = true;
|
pcmc->kvmclock_create_always = true;
|
||||||
pcmc->resizable_acpi_blob = true;
|
pcmc->resizable_acpi_blob = true;
|
||||||
|
x86mc->apic_xrupt_override = true;
|
||||||
assert(!mc->get_hotplug_handler);
|
assert(!mc->get_hotplug_handler);
|
||||||
mc->get_hotplug_handler = pc_get_hotplug_handler;
|
mc->get_hotplug_handler = pc_get_hotplug_handler;
|
||||||
mc->hotplug_allowed = pc_hotplug_allowed;
|
mc->hotplug_allowed = pc_hotplug_allowed;
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
#include "hw/rtc/mc146818rtc.h"
|
#include "hw/rtc/mc146818rtc.h"
|
||||||
#include "hw/southbridge/piix.h"
|
#include "hw/southbridge/piix.h"
|
||||||
#include "hw/display/ramfb.h"
|
#include "hw/display/ramfb.h"
|
||||||
#include "hw/firmware/smbios.h"
|
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
#include "hw/pci/pci_ids.h"
|
#include "hw/pci/pci_ids.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
@@ -112,6 +111,7 @@ static void pc_init1(MachineState *machine,
|
|||||||
X86MachineState *x86ms = X86_MACHINE(machine);
|
X86MachineState *x86ms = X86_MACHINE(machine);
|
||||||
MemoryRegion *system_memory = get_system_memory();
|
MemoryRegion *system_memory = get_system_memory();
|
||||||
MemoryRegion *system_io = get_system_io();
|
MemoryRegion *system_io = get_system_io();
|
||||||
|
Object *phb = NULL;
|
||||||
PCIBus *pci_bus = NULL;
|
PCIBus *pci_bus = NULL;
|
||||||
ISABus *isa_bus;
|
ISABus *isa_bus;
|
||||||
Object *piix4_pm = NULL;
|
Object *piix4_pm = NULL;
|
||||||
@@ -195,8 +195,6 @@ static void pc_init1(MachineState *machine,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pcmc->pci_enabled) {
|
if (pcmc->pci_enabled) {
|
||||||
Object *phb;
|
|
||||||
|
|
||||||
pci_memory = g_new(MemoryRegion, 1);
|
pci_memory = g_new(MemoryRegion, 1);
|
||||||
memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
|
memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
|
||||||
rom_memory = pci_memory;
|
rom_memory = pci_memory;
|
||||||
@@ -230,17 +228,6 @@ static void pc_init1(MachineState *machine,
|
|||||||
&error_abort);
|
&error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
pc_guest_info_init(pcms);
|
|
||||||
|
|
||||||
if (pcmc->smbios_defaults) {
|
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
|
||||||
/* These values are guest ABI, do not change */
|
|
||||||
smbios_set_defaults("QEMU", mc->desc,
|
|
||||||
mc->name, pcmc->smbios_legacy_mode,
|
|
||||||
pcmc->smbios_uuid_encoded,
|
|
||||||
pcms->smbios_entry_point_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate ram and load rom/bios */
|
/* allocate ram and load rom/bios */
|
||||||
if (!xen_enabled()) {
|
if (!xen_enabled()) {
|
||||||
pc_memory_init(pcms, system_memory, rom_memory, hole64_size);
|
pc_memory_init(pcms, system_memory, rom_memory, hole64_size);
|
||||||
@@ -323,8 +310,8 @@ static void pc_init1(MachineState *machine,
|
|||||||
pc_i8259_create(isa_bus, gsi_state->i8259_irq);
|
pc_i8259_create(isa_bus, gsi_state->i8259_irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcmc->pci_enabled) {
|
if (phb) {
|
||||||
ioapic_init_gsi(gsi_state, "i440fx");
|
ioapic_init_gsi(gsi_state, phb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcg_enabled()) {
|
if (tcg_enabled()) {
|
||||||
@@ -344,11 +331,8 @@ static void pc_init1(MachineState *machine,
|
|||||||
|
|
||||||
pc_nic_init(pcmc, isa_bus, pci_bus, pcms->xenbus);
|
pc_nic_init(pcmc, isa_bus, pci_bus, pcms->xenbus);
|
||||||
|
|
||||||
if (pcmc->pci_enabled) {
|
|
||||||
pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_IDE_ISA
|
#ifdef CONFIG_IDE_ISA
|
||||||
else {
|
if (!pcmc->pci_enabled) {
|
||||||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -366,10 +350,11 @@ static void pc_init1(MachineState *machine,
|
|||||||
busname[4] = '0' + i;
|
busname[4] = '0' + i;
|
||||||
idebus[i] = qdev_get_child_bus(DEVICE(dev), busname);
|
idebus[i] = qdev_get_child_bus(DEVICE(dev), busname);
|
||||||
}
|
}
|
||||||
pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
|
||||||
|
|
||||||
if (piix4_pm) {
|
if (piix4_pm) {
|
||||||
smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
|
smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
#include "hw/i386/amd_iommu.h"
|
#include "hw/i386/amd_iommu.h"
|
||||||
#include "hw/i386/intel_iommu.h"
|
#include "hw/i386/intel_iommu.h"
|
||||||
#include "hw/display/ramfb.h"
|
#include "hw/display/ramfb.h"
|
||||||
#include "hw/firmware/smbios.h"
|
|
||||||
#include "hw/ide/pci.h"
|
#include "hw/ide/pci.h"
|
||||||
#include "hw/ide/ahci.h"
|
#include "hw/ide/ahci.h"
|
||||||
#include "hw/intc/ioapic.h"
|
#include "hw/intc/ioapic.h"
|
||||||
@@ -130,8 +129,7 @@ static void pc_q35_init(MachineState *machine)
|
|||||||
ISADevice *rtc_state;
|
ISADevice *rtc_state;
|
||||||
MemoryRegion *system_memory = get_system_memory();
|
MemoryRegion *system_memory = get_system_memory();
|
||||||
MemoryRegion *system_io = get_system_io();
|
MemoryRegion *system_io = get_system_io();
|
||||||
MemoryRegion *pci_memory;
|
MemoryRegion *pci_memory = g_new(MemoryRegion, 1);
|
||||||
MemoryRegion *rom_memory;
|
|
||||||
GSIState *gsi_state;
|
GSIState *gsi_state;
|
||||||
ISABus *isa_bus;
|
ISABus *isa_bus;
|
||||||
int i;
|
int i;
|
||||||
@@ -143,6 +141,8 @@ static void pc_q35_init(MachineState *machine)
|
|||||||
bool keep_pci_slot_hpc;
|
bool keep_pci_slot_hpc;
|
||||||
uint64_t pci_hole64_size = 0;
|
uint64_t pci_hole64_size = 0;
|
||||||
|
|
||||||
|
assert(pcmc->pci_enabled);
|
||||||
|
|
||||||
/* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
|
/* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
|
||||||
* and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
|
* and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
|
||||||
* also known as MMCFG).
|
* also known as MMCFG).
|
||||||
@@ -189,37 +189,16 @@ static void pc_q35_init(MachineState *machine)
|
|||||||
kvmclock_create(pcmc->kvmclock_create_always);
|
kvmclock_create(pcmc->kvmclock_create_always);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pci enabled */
|
|
||||||
if (pcmc->pci_enabled) {
|
|
||||||
pci_memory = g_new(MemoryRegion, 1);
|
|
||||||
memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
|
|
||||||
rom_memory = pci_memory;
|
|
||||||
} else {
|
|
||||||
pci_memory = NULL;
|
|
||||||
rom_memory = system_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
pc_guest_info_init(pcms);
|
|
||||||
|
|
||||||
if (pcmc->smbios_defaults) {
|
|
||||||
/* These values are guest ABI, do not change */
|
|
||||||
smbios_set_defaults("QEMU", mc->desc,
|
|
||||||
mc->name, pcmc->smbios_legacy_mode,
|
|
||||||
pcmc->smbios_uuid_encoded,
|
|
||||||
pcms->smbios_entry_point_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create pci host bus */
|
/* create pci host bus */
|
||||||
phb = OBJECT(qdev_new(TYPE_Q35_HOST_DEVICE));
|
phb = OBJECT(qdev_new(TYPE_Q35_HOST_DEVICE));
|
||||||
|
|
||||||
if (pcmc->pci_enabled) {
|
pci_hole64_size = object_property_get_uint(phb,
|
||||||
pci_hole64_size = object_property_get_uint(phb,
|
PCI_HOST_PROP_PCI_HOLE64_SIZE,
|
||||||
PCI_HOST_PROP_PCI_HOLE64_SIZE,
|
&error_abort);
|
||||||
&error_abort);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate ram and load rom/bios */
|
/* allocate ram and load rom/bios */
|
||||||
pc_memory_init(pcms, system_memory, rom_memory, pci_hole64_size);
|
memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
|
||||||
|
pc_memory_init(pcms, system_memory, pci_memory, pci_hole64_size);
|
||||||
|
|
||||||
object_property_add_child(OBJECT(machine), "q35", phb);
|
object_property_add_child(OBJECT(machine), "q35", phb);
|
||||||
object_property_set_link(phb, PCI_HOST_PROP_RAM_MEM,
|
object_property_set_link(phb, PCI_HOST_PROP_RAM_MEM,
|
||||||
@@ -236,6 +215,8 @@ static void pc_q35_init(MachineState *machine)
|
|||||||
x86ms->above_4g_mem_size, NULL);
|
x86ms->above_4g_mem_size, NULL);
|
||||||
object_property_set_bool(phb, PCI_HOST_BYPASS_IOMMU,
|
object_property_set_bool(phb, PCI_HOST_BYPASS_IOMMU,
|
||||||
pcms->default_bus_bypass_iommu, NULL);
|
pcms->default_bus_bypass_iommu, NULL);
|
||||||
|
object_property_set_bool(phb, PCI_HOST_PROP_SMM_RANGES,
|
||||||
|
x86_machine_is_smm_enabled(x86ms), NULL);
|
||||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(phb), &error_fatal);
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(phb), &error_fatal);
|
||||||
|
|
||||||
/* pci */
|
/* pci */
|
||||||
@@ -243,14 +224,14 @@ static void pc_q35_init(MachineState *machine)
|
|||||||
pcms->bus = host_bus;
|
pcms->bus = host_bus;
|
||||||
|
|
||||||
/* irq lines */
|
/* irq lines */
|
||||||
gsi_state = pc_gsi_create(&x86ms->gsi, pcmc->pci_enabled);
|
gsi_state = pc_gsi_create(&x86ms->gsi, true);
|
||||||
|
|
||||||
/* create ISA bus */
|
/* create ISA bus */
|
||||||
lpc = pci_new_multifunction(PCI_DEVFN(ICH9_LPC_DEV, ICH9_LPC_FUNC),
|
lpc = pci_new_multifunction(PCI_DEVFN(ICH9_LPC_DEV, ICH9_LPC_FUNC),
|
||||||
TYPE_ICH9_LPC_DEVICE);
|
TYPE_ICH9_LPC_DEVICE);
|
||||||
qdev_prop_set_bit(DEVICE(lpc), "smm-enabled",
|
|
||||||
x86_machine_is_smm_enabled(x86ms));
|
|
||||||
lpc_dev = DEVICE(lpc);
|
lpc_dev = DEVICE(lpc);
|
||||||
|
qdev_prop_set_bit(lpc_dev, "smm-enabled",
|
||||||
|
x86_machine_is_smm_enabled(x86ms));
|
||||||
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
|
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
|
||||||
qdev_connect_gpio_out_named(lpc_dev, ICH9_GPIO_GSI, i, x86ms->gsi[i]);
|
qdev_connect_gpio_out_named(lpc_dev, ICH9_GPIO_GSI, i, x86ms->gsi[i]);
|
||||||
}
|
}
|
||||||
@@ -286,9 +267,7 @@ static void pc_q35_init(MachineState *machine)
|
|||||||
pc_i8259_create(isa_bus, gsi_state->i8259_irq);
|
pc_i8259_create(isa_bus, gsi_state->i8259_irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcmc->pci_enabled) {
|
ioapic_init_gsi(gsi_state, OBJECT(phb));
|
||||||
ioapic_init_gsi(gsi_state, "q35");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tcg_enabled()) {
|
if (tcg_enabled()) {
|
||||||
x86_register_ferr_irq(x86ms->gsi[13]);
|
x86_register_ferr_irq(x86ms->gsi[13]);
|
||||||
@@ -412,10 +391,6 @@ static void pc_q35_8_0_machine_options(MachineClass *m)
|
|||||||
pc_q35_8_1_machine_options(m);
|
pc_q35_8_1_machine_options(m);
|
||||||
compat_props_add(m->compat_props, hw_compat_8_0, hw_compat_8_0_len);
|
compat_props_add(m->compat_props, hw_compat_8_0, hw_compat_8_0_len);
|
||||||
compat_props_add(m->compat_props, pc_compat_8_0, pc_compat_8_0_len);
|
compat_props_add(m->compat_props, pc_compat_8_0, pc_compat_8_0_len);
|
||||||
|
|
||||||
/* For pc-q35-8.0 and older, use SMBIOS 2.8 by default */
|
|
||||||
pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
|
|
||||||
m->max_cpus = 288;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_Q35_MACHINE(v8_0, "pc-q35-8.0", NULL,
|
DEFINE_Q35_MACHINE(v8_0, "pc-q35-8.0", NULL,
|
||||||
@@ -448,6 +423,10 @@ static void pc_q35_7_0_machine_options(MachineClass *m)
|
|||||||
pcmc->enforce_amd_1tb_hole = false;
|
pcmc->enforce_amd_1tb_hole = false;
|
||||||
compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
|
compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
|
||||||
compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
|
compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
|
||||||
|
|
||||||
|
/* For pc-q35-7.0 and older, use SMBIOS 2.8 by default */
|
||||||
|
pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
|
||||||
|
m->max_cpus = 288;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_Q35_MACHINE(v7_0, "pc-q35-7.0", NULL,
|
DEFINE_Q35_MACHINE(v7_0, "pc-q35-7.0", NULL,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "hw/block/flash.h"
|
#include "hw/block/flash.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "sev.h"
|
#include "sev.h"
|
||||||
|
#include "kvm/tdx.h"
|
||||||
|
|
||||||
#define FLASH_SECTOR_SIZE 4096
|
#define FLASH_SECTOR_SIZE 4096
|
||||||
|
|
||||||
@@ -107,17 +108,15 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms)
|
|||||||
{
|
{
|
||||||
char *prop_name;
|
char *prop_name;
|
||||||
int i;
|
int i;
|
||||||
Object *dev_obj;
|
|
||||||
|
|
||||||
assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);
|
assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
|
for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
|
||||||
dev_obj = OBJECT(pcms->flash[i]);
|
if (!qdev_is_realized(DEVICE(pcms->flash[i]))) {
|
||||||
if (!object_property_get_bool(dev_obj, "realized", &error_abort)) {
|
|
||||||
prop_name = g_strdup_printf("pflash%d", i);
|
prop_name = g_strdup_printf("pflash%d", i);
|
||||||
object_property_del(OBJECT(pcms), prop_name);
|
object_property_del(OBJECT(pcms), prop_name);
|
||||||
g_free(prop_name);
|
g_free(prop_name);
|
||||||
object_unparent(dev_obj);
|
object_unparent(OBJECT(pcms->flash[i]));
|
||||||
pcms->flash[i] = NULL;
|
pcms->flash[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,5 +264,11 @@ void x86_firmware_configure(void *ptr, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sev_encrypt_flash(ptr, size, &error_fatal);
|
sev_encrypt_flash(ptr, size, &error_fatal);
|
||||||
|
} else if (is_tdx_vm()) {
|
||||||
|
ret = tdx_parse_tdvf(ptr, size);
|
||||||
|
if (ret) {
|
||||||
|
error_report("failed to parse TDVF for TDX VM");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
147
hw/i386/tdvf-hob.c
Normal file
147
hw/i386/tdvf-hob.c
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
* Copyright (c) 2020 Intel Corporation
|
||||||
|
* Author: Isaku Yamahata <isaku.yamahata at gmail.com>
|
||||||
|
* <isaku.yamahata at intel.com>
|
||||||
|
*
|
||||||
|
* 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 "qemu/log.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
|
#include "e820_memory_layout.h"
|
||||||
|
#include "hw/i386/pc.h"
|
||||||
|
#include "hw/i386/x86.h"
|
||||||
|
#include "hw/pci/pcie_host.h"
|
||||||
|
#include "sysemu/kvm.h"
|
||||||
|
#include "standard-headers/uefi/uefi.h"
|
||||||
|
#include "tdvf-hob.h"
|
||||||
|
|
||||||
|
typedef struct TdvfHob {
|
||||||
|
hwaddr hob_addr;
|
||||||
|
void *ptr;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
/* working area */
|
||||||
|
void *current;
|
||||||
|
void *end;
|
||||||
|
} TdvfHob;
|
||||||
|
|
||||||
|
static uint64_t tdvf_current_guest_addr(const TdvfHob *hob)
|
||||||
|
{
|
||||||
|
return hob->hob_addr + (hob->current - hob->ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tdvf_align(TdvfHob *hob, size_t align)
|
||||||
|
{
|
||||||
|
hob->current = QEMU_ALIGN_PTR_UP(hob->current, align);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *tdvf_get_area(TdvfHob *hob, uint64_t size)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
if (hob->current + size > hob->end) {
|
||||||
|
error_report("TD_HOB overrun, size = 0x%" PRIx64, size);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hob->current;
|
||||||
|
hob->current += size;
|
||||||
|
tdvf_align(hob, 8);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tdvf_hob_add_memory_resources(TdxGuest *tdx, TdvfHob *hob)
|
||||||
|
{
|
||||||
|
EFI_HOB_RESOURCE_DESCRIPTOR *region;
|
||||||
|
EFI_RESOURCE_ATTRIBUTE_TYPE attr;
|
||||||
|
EFI_RESOURCE_TYPE resource_type;
|
||||||
|
|
||||||
|
TdxRamEntry *e;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < tdx->nr_ram_entries; i++) {
|
||||||
|
e = &tdx->ram_entries[i];
|
||||||
|
|
||||||
|
if (e->type == TDX_RAM_UNACCEPTED) {
|
||||||
|
resource_type = EFI_RESOURCE_MEMORY_UNACCEPTED;
|
||||||
|
attr = EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED;
|
||||||
|
} else if (e->type == TDX_RAM_ADDED){
|
||||||
|
resource_type = EFI_RESOURCE_SYSTEM_MEMORY;
|
||||||
|
attr = EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE;
|
||||||
|
} else {
|
||||||
|
error_report("unknown TDX_RAM_ENTRY type %d", e->type);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
region = tdvf_get_area(hob, sizeof(*region));
|
||||||
|
*region = (EFI_HOB_RESOURCE_DESCRIPTOR) {
|
||||||
|
.Header = {
|
||||||
|
.HobType = EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
|
||||||
|
.HobLength = cpu_to_le16(sizeof(*region)),
|
||||||
|
.Reserved = cpu_to_le32(0),
|
||||||
|
},
|
||||||
|
.Owner = EFI_HOB_OWNER_ZERO,
|
||||||
|
.ResourceType = cpu_to_le32(resource_type),
|
||||||
|
.ResourceAttribute = cpu_to_le32(attr),
|
||||||
|
.PhysicalStart = cpu_to_le64(e->address),
|
||||||
|
.ResourceLength = cpu_to_le64(e->length),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob)
|
||||||
|
{
|
||||||
|
TdvfHob hob = {
|
||||||
|
.hob_addr = td_hob->address,
|
||||||
|
.size = td_hob->size,
|
||||||
|
.ptr = td_hob->mem_ptr,
|
||||||
|
|
||||||
|
.current = td_hob->mem_ptr,
|
||||||
|
.end = td_hob->mem_ptr + td_hob->size,
|
||||||
|
};
|
||||||
|
|
||||||
|
EFI_HOB_GENERIC_HEADER *last_hob;
|
||||||
|
EFI_HOB_HANDOFF_INFO_TABLE *hit;
|
||||||
|
|
||||||
|
/* Note, Efi{Free}Memory{Bottom,Top} are ignored, leave 'em zeroed. */
|
||||||
|
hit = tdvf_get_area(&hob, sizeof(*hit));
|
||||||
|
*hit = (EFI_HOB_HANDOFF_INFO_TABLE) {
|
||||||
|
.Header = {
|
||||||
|
.HobType = EFI_HOB_TYPE_HANDOFF,
|
||||||
|
.HobLength = cpu_to_le16(sizeof(*hit)),
|
||||||
|
.Reserved = cpu_to_le32(0),
|
||||||
|
},
|
||||||
|
.Version = cpu_to_le32(EFI_HOB_HANDOFF_TABLE_VERSION),
|
||||||
|
.BootMode = cpu_to_le32(0),
|
||||||
|
.EfiMemoryTop = cpu_to_le64(0),
|
||||||
|
.EfiMemoryBottom = cpu_to_le64(0),
|
||||||
|
.EfiFreeMemoryTop = cpu_to_le64(0),
|
||||||
|
.EfiFreeMemoryBottom = cpu_to_le64(0),
|
||||||
|
.EfiEndOfHobList = cpu_to_le64(0), /* initialized later */
|
||||||
|
};
|
||||||
|
|
||||||
|
tdvf_hob_add_memory_resources(tdx, &hob);
|
||||||
|
|
||||||
|
last_hob = tdvf_get_area(&hob, sizeof(*last_hob));
|
||||||
|
*last_hob = (EFI_HOB_GENERIC_HEADER) {
|
||||||
|
.HobType = EFI_HOB_TYPE_END_OF_HOB_LIST,
|
||||||
|
.HobLength = cpu_to_le16(sizeof(*last_hob)),
|
||||||
|
.Reserved = cpu_to_le32(0),
|
||||||
|
};
|
||||||
|
hit->EfiEndOfHobList = tdvf_current_guest_addr(&hob);
|
||||||
|
}
|
||||||
24
hw/i386/tdvf-hob.h
Normal file
24
hw/i386/tdvf-hob.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef HW_I386_TD_HOB_H
|
||||||
|
#define HW_I386_TD_HOB_H
|
||||||
|
|
||||||
|
#include "hw/i386/tdvf.h"
|
||||||
|
#include "target/i386/kvm/tdx.h"
|
||||||
|
|
||||||
|
void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob);
|
||||||
|
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE \
|
||||||
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT | \
|
||||||
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
|
||||||
|
EFI_RESOURCE_ATTRIBUTE_TESTED)
|
||||||
|
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED \
|
||||||
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT | \
|
||||||
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
|
||||||
|
EFI_RESOURCE_ATTRIBUTE_TESTED)
|
||||||
|
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_TDVF_MMIO \
|
||||||
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT | \
|
||||||
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
|
||||||
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE)
|
||||||
|
|
||||||
|
#endif
|
||||||
200
hw/i386/tdvf.c
Normal file
200
hw/i386/tdvf.c
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
* Copyright (c) 2020 Intel Corporation
|
||||||
|
* Author: Isaku Yamahata <isaku.yamahata at gmail.com>
|
||||||
|
* <isaku.yamahata at intel.com>
|
||||||
|
*
|
||||||
|
* 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 "qemu/error-report.h"
|
||||||
|
|
||||||
|
#include "hw/i386/pc.h"
|
||||||
|
#include "hw/i386/tdvf.h"
|
||||||
|
#include "sysemu/kvm.h"
|
||||||
|
|
||||||
|
#define TDX_METADATA_OFFSET_GUID "e47a6535-984a-4798-865e-4685a7bf8ec2"
|
||||||
|
#define TDX_METADATA_VERSION 1
|
||||||
|
#define TDVF_SIGNATURE 0x46564454 /* TDVF as little endian */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t DataOffset;
|
||||||
|
uint32_t RawDataSize;
|
||||||
|
uint64_t MemoryAddress;
|
||||||
|
uint64_t MemoryDataSize;
|
||||||
|
uint32_t Type;
|
||||||
|
uint32_t Attributes;
|
||||||
|
} TdvfSectionEntry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t Signature;
|
||||||
|
uint32_t Length;
|
||||||
|
uint32_t Version;
|
||||||
|
uint32_t NumberOfSectionEntries;
|
||||||
|
TdvfSectionEntry SectionEntries[];
|
||||||
|
} TdvfMetadata;
|
||||||
|
|
||||||
|
struct tdx_metadata_offset {
|
||||||
|
uint32_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
static TdvfMetadata *tdvf_get_metadata(void *flash_ptr, int size)
|
||||||
|
{
|
||||||
|
TdvfMetadata *metadata;
|
||||||
|
uint32_t offset = 0;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
if ((uint32_t) size != size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pc_system_ovmf_table_find(TDX_METADATA_OFFSET_GUID, &data, NULL)) {
|
||||||
|
offset = size - le32_to_cpu(((struct tdx_metadata_offset *)data)->offset);
|
||||||
|
|
||||||
|
if (offset + sizeof(*metadata) > size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error_report("Cannot find TDX_METADATA_OFFSET_GUID");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata = flash_ptr + offset;
|
||||||
|
|
||||||
|
/* Finally, verify the signature to determine if this is a TDVF image. */
|
||||||
|
metadata->Signature = le32_to_cpu(metadata->Signature);
|
||||||
|
if (metadata->Signature != TDVF_SIGNATURE) {
|
||||||
|
error_report("Invalid TDVF signature in metadata!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check that the TDVF doesn't overlap its own metadata. */
|
||||||
|
metadata->Length = le32_to_cpu(metadata->Length);
|
||||||
|
if (offset + metadata->Length > size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only version 1 is supported/defined. */
|
||||||
|
metadata->Version = le32_to_cpu(metadata->Version);
|
||||||
|
if (metadata->Version != TDX_METADATA_VERSION) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tdvf_parse_and_check_section_entry(const TdvfSectionEntry *src,
|
||||||
|
TdxFirmwareEntry *entry)
|
||||||
|
{
|
||||||
|
entry->data_offset = le32_to_cpu(src->DataOffset);
|
||||||
|
entry->data_len = le32_to_cpu(src->RawDataSize);
|
||||||
|
entry->address = le64_to_cpu(src->MemoryAddress);
|
||||||
|
entry->size = le64_to_cpu(src->MemoryDataSize);
|
||||||
|
entry->type = le32_to_cpu(src->Type);
|
||||||
|
entry->attributes = le32_to_cpu(src->Attributes);
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
if (entry->size < entry->data_len) {
|
||||||
|
error_report("Broken metadata RawDataSize 0x%x MemoryDataSize 0x%lx",
|
||||||
|
entry->data_len, entry->size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!QEMU_IS_ALIGNED(entry->address, TARGET_PAGE_SIZE)) {
|
||||||
|
error_report("MemoryAddress 0x%lx not page aligned", entry->address);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!QEMU_IS_ALIGNED(entry->size, TARGET_PAGE_SIZE)) {
|
||||||
|
error_report("MemoryDataSize 0x%lx not page aligned", entry->size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (entry->type) {
|
||||||
|
case TDVF_SECTION_TYPE_BFV:
|
||||||
|
case TDVF_SECTION_TYPE_CFV:
|
||||||
|
/* The sections that must be copied from firmware image to TD memory */
|
||||||
|
if (entry->data_len == 0) {
|
||||||
|
error_report("%d section with RawDataSize == 0", entry->type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TDVF_SECTION_TYPE_TD_HOB:
|
||||||
|
case TDVF_SECTION_TYPE_TEMP_MEM:
|
||||||
|
/* The sections that no need to be copied from firmware image */
|
||||||
|
if (entry->data_len != 0) {
|
||||||
|
error_report("%d section with RawDataSize 0x%x != 0",
|
||||||
|
entry->type, entry->data_len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error_report("TDVF contains unsupported section type %d", entry->type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size)
|
||||||
|
{
|
||||||
|
TdvfSectionEntry *sections;
|
||||||
|
TdvfMetadata *metadata;
|
||||||
|
ssize_t entries_size;
|
||||||
|
uint32_t len, i;
|
||||||
|
|
||||||
|
metadata = tdvf_get_metadata(flash_ptr, size);
|
||||||
|
if (!metadata) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//load and parse metadata entries
|
||||||
|
fw->nr_entries = le32_to_cpu(metadata->NumberOfSectionEntries);
|
||||||
|
if (fw->nr_entries < 2) {
|
||||||
|
error_report("Invalid number of fw entries (%u) in TDVF", fw->nr_entries);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = le32_to_cpu(metadata->Length);
|
||||||
|
entries_size = fw->nr_entries * sizeof(TdvfSectionEntry);
|
||||||
|
if (len != sizeof(*metadata) + entries_size) {
|
||||||
|
error_report("TDVF metadata len (0x%x) mismatch, expected (0x%x)",
|
||||||
|
len, (uint32_t)(sizeof(*metadata) + entries_size));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fw->entries = g_new(TdxFirmwareEntry, fw->nr_entries);
|
||||||
|
sections = g_new(TdvfSectionEntry, fw->nr_entries);
|
||||||
|
|
||||||
|
if (!memcpy(sections, (void *)metadata + sizeof(*metadata), entries_size)) {
|
||||||
|
error_report("Failed to read TDVF section entries");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < fw->nr_entries; i++) {
|
||||||
|
if (tdvf_parse_and_check_section_entry(§ions[i], &fw->entries[i])) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free(sections);
|
||||||
|
|
||||||
|
fw->mem_ptr = flash_ptr;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
g_free(sections);
|
||||||
|
fw->entries = 0;
|
||||||
|
g_free(fw->entries);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
@@ -47,6 +47,7 @@
|
|||||||
#include "hw/intc/i8259.h"
|
#include "hw/intc/i8259.h"
|
||||||
#include "hw/rtc/mc146818rtc.h"
|
#include "hw/rtc/mc146818rtc.h"
|
||||||
#include "target/i386/sev.h"
|
#include "target/i386/sev.h"
|
||||||
|
#include "kvm/tdx.h"
|
||||||
|
|
||||||
#include "hw/acpi/cpu_hotplug.h"
|
#include "hw/acpi/cpu_hotplug.h"
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
@@ -636,20 +637,19 @@ void gsi_handler(void *opaque, int n, int level)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
|
void ioapic_init_gsi(GSIState *gsi_state, Object *parent)
|
||||||
{
|
{
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
SysBusDevice *d;
|
SysBusDevice *d;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
assert(parent_name);
|
assert(parent);
|
||||||
if (kvm_ioapic_in_kernel()) {
|
if (kvm_ioapic_in_kernel()) {
|
||||||
dev = qdev_new(TYPE_KVM_IOAPIC);
|
dev = qdev_new(TYPE_KVM_IOAPIC);
|
||||||
} else {
|
} else {
|
||||||
dev = qdev_new(TYPE_IOAPIC);
|
dev = qdev_new(TYPE_IOAPIC);
|
||||||
}
|
}
|
||||||
object_property_add_child(object_resolve_path(parent_name, NULL),
|
object_property_add_child(parent, "ioapic", OBJECT(dev));
|
||||||
"ioapic", OBJECT(dev));
|
|
||||||
d = SYS_BUS_DEVICE(dev);
|
d = SYS_BUS_DEVICE(dev);
|
||||||
sysbus_realize_and_unref(d, &error_fatal);
|
sysbus_realize_and_unref(d, &error_fatal);
|
||||||
sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS);
|
sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS);
|
||||||
@@ -1154,9 +1154,17 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
|
|||||||
(bios_size % 65536) != 0) {
|
(bios_size % 65536) != 0) {
|
||||||
goto bios_error;
|
goto bios_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
bios = g_malloc(sizeof(*bios));
|
bios = g_malloc(sizeof(*bios));
|
||||||
memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
|
if (is_tdx_vm()) {
|
||||||
if (sev_enabled()) {
|
memory_region_init_ram_guest_memfd(bios, NULL, "pc.bios", bios_size,
|
||||||
|
&error_fatal);
|
||||||
|
tdx_set_tdvf_region(bios);
|
||||||
|
} else {
|
||||||
|
memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sev_enabled() || is_tdx_vm()) {
|
||||||
/*
|
/*
|
||||||
* The concept of a "reset" simply doesn't exist for
|
* The concept of a "reset" simply doesn't exist for
|
||||||
* confidential computing guests, we have to destroy and
|
* confidential computing guests, we have to destroy and
|
||||||
@@ -1178,17 +1186,20 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
|
|||||||
}
|
}
|
||||||
g_free(filename);
|
g_free(filename);
|
||||||
|
|
||||||
/* map the last 128KB of the BIOS in ISA space */
|
/* For TDX, alias different GPAs to same private memory is not supported */
|
||||||
isa_bios_size = MIN(bios_size, 128 * KiB);
|
if (!is_tdx_vm()) {
|
||||||
isa_bios = g_malloc(sizeof(*isa_bios));
|
/* map the last 128KB of the BIOS in ISA space */
|
||||||
memory_region_init_alias(isa_bios, NULL, "isa-bios", bios,
|
isa_bios_size = MIN(bios_size, 128 * KiB);
|
||||||
bios_size - isa_bios_size, isa_bios_size);
|
isa_bios = g_malloc(sizeof(*isa_bios));
|
||||||
memory_region_add_subregion_overlap(rom_memory,
|
memory_region_init_alias(isa_bios, NULL, "isa-bios", bios,
|
||||||
0x100000 - isa_bios_size,
|
bios_size - isa_bios_size, isa_bios_size);
|
||||||
isa_bios,
|
memory_region_add_subregion_overlap(rom_memory,
|
||||||
1);
|
0x100000 - isa_bios_size,
|
||||||
if (!isapc_ram_fw) {
|
isa_bios,
|
||||||
memory_region_set_readonly(isa_bios, true);
|
1);
|
||||||
|
if (!isapc_ram_fw) {
|
||||||
|
memory_region_set_readonly(isa_bios, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* map all the bios at the top of memory */
|
/* map all the bios at the top of memory */
|
||||||
@@ -1386,6 +1397,17 @@ static void machine_set_sgx_epc(Object *obj, Visitor *v, const char *name,
|
|||||||
qapi_free_SgxEPCList(list);
|
qapi_free_SgxEPCList(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int x86_kvm_type(MachineState *ms, const char *vm_type)
|
||||||
|
{
|
||||||
|
X86MachineState *x86ms = X86_MACHINE(ms);
|
||||||
|
int kvm_type;
|
||||||
|
|
||||||
|
kvm_type = kvm_enabled() ? kvm_get_vm_type(ms, vm_type) : 0;
|
||||||
|
x86ms->vm_type = kvm_type;
|
||||||
|
|
||||||
|
return kvm_type;
|
||||||
|
}
|
||||||
|
|
||||||
static void x86_machine_initfn(Object *obj)
|
static void x86_machine_initfn(Object *obj)
|
||||||
{
|
{
|
||||||
X86MachineState *x86ms = X86_MACHINE(obj);
|
X86MachineState *x86ms = X86_MACHINE(obj);
|
||||||
@@ -1399,6 +1421,7 @@ static void x86_machine_initfn(Object *obj)
|
|||||||
x86ms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
|
x86ms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
|
||||||
x86ms->bus_lock_ratelimit = 0;
|
x86ms->bus_lock_ratelimit = 0;
|
||||||
x86ms->above_4g_mem_start = 4 * GiB;
|
x86ms->above_4g_mem_start = 4 * GiB;
|
||||||
|
x86ms->eoi_intercept_unsupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x86_machine_class_init(ObjectClass *oc, void *data)
|
static void x86_machine_class_init(ObjectClass *oc, void *data)
|
||||||
@@ -1410,6 +1433,7 @@ static void x86_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
mc->cpu_index_to_instance_props = x86_cpu_index_to_props;
|
mc->cpu_index_to_instance_props = x86_cpu_index_to_props;
|
||||||
mc->get_default_cpu_node_id = x86_get_default_cpu_node_id;
|
mc->get_default_cpu_node_id = x86_get_default_cpu_node_id;
|
||||||
mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids;
|
mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids;
|
||||||
|
mc->kvm_type = x86_kvm_type;
|
||||||
x86mc->save_tsc_khz = true;
|
x86mc->save_tsc_khz = true;
|
||||||
x86mc->fwcfg_dma_enabled = true;
|
x86mc->fwcfg_dma_enabled = true;
|
||||||
nc->nmi_monitor_handler = x86_nmi;
|
nc->nmi_monitor_handler = x86_nmi;
|
||||||
|
|||||||
@@ -476,7 +476,6 @@ static void setup_interrupt(IVShmemState *s, int vector, Error **errp)
|
|||||||
|
|
||||||
static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
|
static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
@@ -496,10 +495,9 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
|
|||||||
size = buf.st_size;
|
size = buf.st_size;
|
||||||
|
|
||||||
/* mmap the region and map into the BAR2 */
|
/* mmap the region and map into the BAR2 */
|
||||||
memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s), "ivshmem.bar2",
|
if (!memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s),
|
||||||
size, RAM_SHARED, fd, 0, &local_err);
|
"ivshmem.bar2", size, RAM_SHARED,
|
||||||
if (local_err) {
|
fd, 0, errp)) {
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8466,36 +8466,26 @@ static void nvme_pci_reset(DeviceState *qdev)
|
|||||||
nvme_ctrl_reset(n, NVME_RESET_FUNCTION);
|
nvme_ctrl_reset(n, NVME_RESET_FUNCTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvme_sriov_pre_write_ctrl(PCIDevice *dev, uint32_t address,
|
static void nvme_sriov_post_write_config(PCIDevice *dev, uint16_t old_num_vfs)
|
||||||
uint32_t val, int len)
|
|
||||||
{
|
{
|
||||||
NvmeCtrl *n = NVME(dev);
|
NvmeCtrl *n = NVME(dev);
|
||||||
NvmeSecCtrlEntry *sctrl;
|
NvmeSecCtrlEntry *sctrl;
|
||||||
uint16_t sriov_cap = dev->exp.sriov_cap;
|
int i;
|
||||||
uint32_t off = address - sriov_cap;
|
|
||||||
int i, num_vfs;
|
|
||||||
|
|
||||||
if (!sriov_cap) {
|
for (i = pcie_sriov_num_vfs(dev); i < old_num_vfs; i++) {
|
||||||
return;
|
sctrl = &n->sec_ctrl_list.sec[i];
|
||||||
}
|
nvme_virt_set_state(n, le16_to_cpu(sctrl->scid), false);
|
||||||
|
|
||||||
if (range_covers_byte(off, len, PCI_SRIOV_CTRL)) {
|
|
||||||
if (!(val & PCI_SRIOV_CTRL_VFE)) {
|
|
||||||
num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
|
|
||||||
for (i = 0; i < num_vfs; i++) {
|
|
||||||
sctrl = &n->sec_ctrl_list.sec[i];
|
|
||||||
nvme_virt_set_state(n, le16_to_cpu(sctrl->scid), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvme_pci_write_config(PCIDevice *dev, uint32_t address,
|
static void nvme_pci_write_config(PCIDevice *dev, uint32_t address,
|
||||||
uint32_t val, int len)
|
uint32_t val, int len)
|
||||||
{
|
{
|
||||||
nvme_sriov_pre_write_ctrl(dev, address, val, len);
|
uint16_t old_num_vfs = pcie_sriov_num_vfs(dev);
|
||||||
|
|
||||||
pci_default_write_config(dev, address, val, len);
|
pci_default_write_config(dev, address, val, len);
|
||||||
pcie_cap_flr_write_config(dev, address, val, len);
|
pcie_cap_flr_write_config(dev, address, val, len);
|
||||||
|
nvme_sriov_post_write_config(dev, old_num_vfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VMStateDescription nvme_vmstate = {
|
static const VMStateDescription nvme_vmstate = {
|
||||||
|
|||||||
@@ -336,12 +336,9 @@ static void nrf51_nvm_init(Object *obj)
|
|||||||
static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
|
static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
NRF51NVMState *s = NRF51_NVM(dev);
|
NRF51NVMState *s = NRF51_NVM(dev);
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
|
if (!memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
|
||||||
"nrf51_soc.flash", s->flash_size, &err);
|
"nrf51_soc.flash", s->flash_size, errp)) {
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ static Property q35_host_props[] = {
|
|||||||
mch.below_4g_mem_size, 0),
|
mch.below_4g_mem_size, 0),
|
||||||
DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
|
DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
|
||||||
mch.above_4g_mem_size, 0),
|
mch.above_4g_mem_size, 0),
|
||||||
|
DEFINE_PROP_BOOL(PCI_HOST_PROP_SMM_RANGES, Q35PCIHost,
|
||||||
|
mch.has_smm_ranges, true),
|
||||||
DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true),
|
DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
@@ -214,6 +216,7 @@ static void q35_host_initfn(Object *obj)
|
|||||||
/* mch's object_initialize resets the default value, set it again */
|
/* mch's object_initialize resets the default value, set it again */
|
||||||
qdev_prop_set_uint64(DEVICE(s), PCI_HOST_PROP_PCI_HOLE64_SIZE,
|
qdev_prop_set_uint64(DEVICE(s), PCI_HOST_PROP_PCI_HOLE64_SIZE,
|
||||||
Q35_PCI_HOST_HOLE64_SIZE_DEFAULT);
|
Q35_PCI_HOST_HOLE64_SIZE_DEFAULT);
|
||||||
|
|
||||||
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
|
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
|
||||||
q35_host_get_pci_hole_start,
|
q35_host_get_pci_hole_start,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
@@ -476,6 +479,10 @@ static void mch_write_config(PCIDevice *d,
|
|||||||
mch_update_pciexbar(mch);
|
mch_update_pciexbar(mch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mch->has_smm_ranges) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ranges_overlap(address, len, MCH_HOST_BRIDGE_SMRAM,
|
if (ranges_overlap(address, len, MCH_HOST_BRIDGE_SMRAM,
|
||||||
MCH_HOST_BRIDGE_SMRAM_SIZE)) {
|
MCH_HOST_BRIDGE_SMRAM_SIZE)) {
|
||||||
mch_update_smram(mch);
|
mch_update_smram(mch);
|
||||||
@@ -494,10 +501,13 @@ static void mch_write_config(PCIDevice *d,
|
|||||||
static void mch_update(MCHPCIState *mch)
|
static void mch_update(MCHPCIState *mch)
|
||||||
{
|
{
|
||||||
mch_update_pciexbar(mch);
|
mch_update_pciexbar(mch);
|
||||||
|
|
||||||
mch_update_pam(mch);
|
mch_update_pam(mch);
|
||||||
mch_update_smram(mch);
|
if (mch->has_smm_ranges) {
|
||||||
mch_update_ext_tseg_mbytes(mch);
|
mch_update_smram(mch);
|
||||||
mch_update_smbase_smram(mch);
|
mch_update_ext_tseg_mbytes(mch);
|
||||||
|
mch_update_smbase_smram(mch);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pci hole goes from end-of-low-ram to io-apic.
|
* pci hole goes from end-of-low-ram to io-apic.
|
||||||
@@ -538,19 +548,21 @@ static void mch_reset(DeviceState *qdev)
|
|||||||
pci_set_quad(d->config + MCH_HOST_BRIDGE_PCIEXBAR,
|
pci_set_quad(d->config + MCH_HOST_BRIDGE_PCIEXBAR,
|
||||||
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
|
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
|
||||||
|
|
||||||
d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
|
if (mch->has_smm_ranges) {
|
||||||
d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
|
d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
|
||||||
d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK;
|
d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
|
||||||
d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK;
|
d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK;
|
||||||
|
d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK;
|
||||||
|
|
||||||
if (mch->ext_tseg_mbytes > 0) {
|
if (mch->ext_tseg_mbytes > 0) {
|
||||||
pci_set_word(d->config + MCH_HOST_BRIDGE_EXT_TSEG_MBYTES,
|
pci_set_word(d->config + MCH_HOST_BRIDGE_EXT_TSEG_MBYTES,
|
||||||
MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY);
|
MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY);
|
||||||
|
}
|
||||||
|
|
||||||
|
d->config[MCH_HOST_BRIDGE_F_SMBASE] = 0;
|
||||||
|
d->wmask[MCH_HOST_BRIDGE_F_SMBASE] = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->config[MCH_HOST_BRIDGE_F_SMBASE] = 0;
|
|
||||||
d->wmask[MCH_HOST_BRIDGE_F_SMBASE] = 0xff;
|
|
||||||
|
|
||||||
mch_update(mch);
|
mch_update(mch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,6 +580,20 @@ static void mch_realize(PCIDevice *d, Error **errp)
|
|||||||
/* setup pci memory mapping */
|
/* setup pci memory mapping */
|
||||||
pc_pci_as_mapping_init(mch->system_memory, mch->pci_address_space);
|
pc_pci_as_mapping_init(mch->system_memory, mch->pci_address_space);
|
||||||
|
|
||||||
|
/* PAM */
|
||||||
|
init_pam(&mch->pam_regions[0], OBJECT(mch), mch->ram_memory,
|
||||||
|
mch->system_memory, mch->pci_address_space,
|
||||||
|
PAM_BIOS_BASE, PAM_BIOS_SIZE);
|
||||||
|
for (i = 0; i < ARRAY_SIZE(mch->pam_regions) - 1; ++i) {
|
||||||
|
init_pam(&mch->pam_regions[i + 1], OBJECT(mch), mch->ram_memory,
|
||||||
|
mch->system_memory, mch->pci_address_space,
|
||||||
|
PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mch->has_smm_ranges) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* if *disabled* show SMRAM to all CPUs */
|
/* if *disabled* show SMRAM to all CPUs */
|
||||||
memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
|
memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
|
||||||
mch->pci_address_space, MCH_HOST_BRIDGE_SMRAM_C_BASE,
|
mch->pci_address_space, MCH_HOST_BRIDGE_SMRAM_C_BASE,
|
||||||
@@ -634,15 +660,6 @@ static void mch_realize(PCIDevice *d, Error **errp)
|
|||||||
|
|
||||||
object_property_add_const_link(qdev_get_machine(), "smram",
|
object_property_add_const_link(qdev_get_machine(), "smram",
|
||||||
OBJECT(&mch->smram));
|
OBJECT(&mch->smram));
|
||||||
|
|
||||||
init_pam(&mch->pam_regions[0], OBJECT(mch), mch->ram_memory,
|
|
||||||
mch->system_memory, mch->pci_address_space,
|
|
||||||
PAM_BIOS_BASE, PAM_BIOS_SIZE);
|
|
||||||
for (i = 0; i < ARRAY_SIZE(mch->pam_regions) - 1; ++i) {
|
|
||||||
init_pam(&mch->pam_regions[i + 1], OBJECT(mch), mch->ram_memory,
|
|
||||||
mch->system_memory, mch->pci_address_space,
|
|
||||||
PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t mch_mcfg_base(void)
|
uint64_t mch_mcfg_base(void)
|
||||||
|
|||||||
@@ -345,8 +345,10 @@ static void raven_realize(PCIDevice *d, Error **errp)
|
|||||||
d->config[PCI_LATENCY_TIMER] = 0x10;
|
d->config[PCI_LATENCY_TIMER] = 0x10;
|
||||||
d->config[PCI_CAPABILITY_LIST] = 0x00;
|
d->config[PCI_CAPABILITY_LIST] = 0x00;
|
||||||
|
|
||||||
memory_region_init_rom_nomigrate(&s->bios, OBJECT(s), "bios", BIOS_SIZE,
|
if (!memory_region_init_rom_nomigrate(&s->bios, OBJECT(s), "bios",
|
||||||
&error_fatal);
|
BIOS_SIZE, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE),
|
memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE),
|
||||||
&s->bios);
|
&s->bios);
|
||||||
if (s->bios_name) {
|
if (s->bios_name) {
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "migration/blocker.h"
|
#include "migration/blocker.h"
|
||||||
#include "exec/confidential-guest-support.h"
|
#include "exec/confidential-guest-support.h"
|
||||||
#include "hw/ppc/pef.h"
|
|
||||||
|
|
||||||
#define TYPE_PEF_GUEST "pef-guest"
|
#define TYPE_PEF_GUEST "pef-guest"
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(PefGuest, PEF_GUEST)
|
OBJECT_DECLARE_SIMPLE_TYPE(PefGuest, PEF_GUEST)
|
||||||
@@ -93,7 +92,7 @@ static int kvmppc_svm_off(Error **errp)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
static int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
||||||
{
|
{
|
||||||
if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) {
|
if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -107,7 +106,7 @@ int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
return kvmppc_svm_init(cgs, errp);
|
return kvmppc_svm_init(cgs, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pef_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp)
|
static int pef_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp)
|
||||||
{
|
{
|
||||||
if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) {
|
if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -131,6 +130,10 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(PefGuest,
|
|||||||
|
|
||||||
static void pef_guest_class_init(ObjectClass *oc, void *data)
|
static void pef_guest_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
|
ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
|
||||||
|
|
||||||
|
klass->kvm_init = pef_kvm_init;
|
||||||
|
klass->kvm_reset = pef_kvm_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pef_guest_init(Object *obj)
|
static void pef_guest_init(Object *obj)
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ static void rs6000mc_realize(DeviceState *dev, Error **errp)
|
|||||||
RS6000MCState *s = RS6000MC(dev);
|
RS6000MCState *s = RS6000MC(dev);
|
||||||
int socket = 0;
|
int socket = 0;
|
||||||
unsigned int ram_size = s->ram_size / MiB;
|
unsigned int ram_size = s->ram_size / MiB;
|
||||||
Error *local_err = NULL;
|
|
||||||
|
|
||||||
while (socket < 6) {
|
while (socket < 6) {
|
||||||
if (ram_size >= 64) {
|
if (ram_size >= 64) {
|
||||||
@@ -165,10 +164,8 @@ static void rs6000mc_realize(DeviceState *dev, Error **errp)
|
|||||||
if (s->simm_size[socket]) {
|
if (s->simm_size[socket]) {
|
||||||
char name[] = "simm.?";
|
char name[] = "simm.?";
|
||||||
name[5] = socket + '0';
|
name[5] = socket + '0';
|
||||||
memory_region_init_ram(&s->simm[socket], OBJECT(dev), name,
|
if (!memory_region_init_ram(&s->simm[socket], OBJECT(dev), name,
|
||||||
s->simm_size[socket] * MiB, &local_err);
|
s->simm_size[socket] * MiB, errp)) {
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memory_region_add_subregion_overlap(get_system_memory(), 0,
|
memory_region_add_subregion_overlap(get_system_memory(), 0,
|
||||||
|
|||||||
@@ -74,6 +74,7 @@
|
|||||||
#include "hw/virtio/vhost-scsi-common.h"
|
#include "hw/virtio/vhost-scsi-common.h"
|
||||||
|
|
||||||
#include "exec/ram_addr.h"
|
#include "exec/ram_addr.h"
|
||||||
|
#include "exec/confidential-guest-support.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
@@ -86,7 +87,6 @@
|
|||||||
#include "hw/ppc/spapr_tpm_proxy.h"
|
#include "hw/ppc/spapr_tpm_proxy.h"
|
||||||
#include "hw/ppc/spapr_nvdimm.h"
|
#include "hw/ppc/spapr_nvdimm.h"
|
||||||
#include "hw/ppc/spapr_numa.h"
|
#include "hw/ppc/spapr_numa.h"
|
||||||
#include "hw/ppc/pef.h"
|
|
||||||
|
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
|
|
||||||
@@ -1687,7 +1687,9 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
|
|||||||
qemu_guest_getrandom_nofail(spapr->fdt_rng_seed, 32);
|
qemu_guest_getrandom_nofail(spapr->fdt_rng_seed, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
pef_kvm_reset(machine->cgs, &error_fatal);
|
if (machine->cgs) {
|
||||||
|
confidential_guest_kvm_reset(machine->cgs, &error_fatal);
|
||||||
|
}
|
||||||
spapr_caps_apply(spapr);
|
spapr_caps_apply(spapr);
|
||||||
|
|
||||||
first_ppc_cpu = POWERPC_CPU(first_cpu);
|
first_ppc_cpu = POWERPC_CPU(first_cpu);
|
||||||
@@ -2810,7 +2812,9 @@ static void spapr_machine_init(MachineState *machine)
|
|||||||
/*
|
/*
|
||||||
* if Secure VM (PEF) support is configured, then initialize it
|
* if Secure VM (PEF) support is configured, then initialize it
|
||||||
*/
|
*/
|
||||||
pef_kvm_init(machine->cgs, &error_fatal);
|
if (machine->cgs) {
|
||||||
|
confidential_guest_kvm_init(machine->cgs, &error_fatal);
|
||||||
|
}
|
||||||
|
|
||||||
msi_nonbroken = true;
|
msi_nonbroken = true;
|
||||||
|
|
||||||
@@ -4647,13 +4651,10 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
mc->block_default_type = IF_SCSI;
|
mc->block_default_type = IF_SCSI;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setting max_cpus to INT32_MAX. Both KVM and TCG max_cpus values
|
* While KVM determines max cpus in kvm_init() using kvm_max_vcpus(),
|
||||||
* should be limited by the host capability instead of hardcoded.
|
* In TCG the limit is restricted by the range of CPU IPIs available.
|
||||||
* max_cpus for KVM guests will be checked in kvm_init(), and TCG
|
|
||||||
* guests are welcome to have as many CPUs as the host are capable
|
|
||||||
* of emulate.
|
|
||||||
*/
|
*/
|
||||||
mc->max_cpus = INT32_MAX;
|
mc->max_cpus = SPAPR_IRQ_NR_IPIS;
|
||||||
|
|
||||||
mc->no_parallel = 1;
|
mc->no_parallel = 1;
|
||||||
mc->default_boot_order = "";
|
mc->default_boot_order = "";
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
|
QEMU_BUILD_BUG_ON(SPAPR_IRQ_NR_IPIS > SPAPR_XIRQ_BASE);
|
||||||
|
|
||||||
static const TypeInfo spapr_intc_info = {
|
static const TypeInfo spapr_intc_info = {
|
||||||
.name = TYPE_SPAPR_INTC,
|
.name = TYPE_SPAPR_INTC,
|
||||||
.parent = TYPE_INTERFACE,
|
.parent = TYPE_INTERFACE,
|
||||||
@@ -329,7 +331,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
dev = qdev_new(TYPE_SPAPR_XIVE);
|
dev = qdev_new(TYPE_SPAPR_XIVE);
|
||||||
qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_XIRQ_BASE);
|
qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_IRQ_NR_IPIS);
|
||||||
/*
|
/*
|
||||||
* 8 XIVE END structures per CPU. One for each available
|
* 8 XIVE END structures per CPU. One for each available
|
||||||
* priority
|
* priority
|
||||||
@@ -356,7 +358,7 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
|
spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr,
|
||||||
smc->nr_xirqs + SPAPR_XIRQ_BASE);
|
smc->nr_xirqs + SPAPR_IRQ_NR_IPIS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mostly we don't actually need this until reset, except that not
|
* Mostly we don't actually need this until reset, except that not
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "exec/ram_addr.h"
|
#include "exec/ram_addr.h"
|
||||||
|
#include "exec/confidential-guest-support.h"
|
||||||
#include "hw/s390x/s390-virtio-hcall.h"
|
#include "hw/s390x/s390-virtio-hcall.h"
|
||||||
#include "hw/s390x/sclp.h"
|
#include "hw/s390x/sclp.h"
|
||||||
#include "hw/s390x/s390_flic.h"
|
#include "hw/s390x/s390_flic.h"
|
||||||
@@ -267,7 +268,9 @@ static void ccw_init(MachineState *machine)
|
|||||||
s390_init_cpus(machine);
|
s390_init_cpus(machine);
|
||||||
|
|
||||||
/* Need CPU model to be determined before we can set up PV */
|
/* Need CPU model to be determined before we can set up PV */
|
||||||
s390_pv_init(machine->cgs, &error_fatal);
|
if (machine->cgs) {
|
||||||
|
confidential_guest_kvm_init(machine->cgs, &error_fatal);
|
||||||
|
}
|
||||||
|
|
||||||
s390_flic_init();
|
s390_flic_init();
|
||||||
|
|
||||||
|
|||||||
@@ -1928,7 +1928,7 @@ static void megasas_command_cancelled(SCSIRequest *req)
|
|||||||
{
|
{
|
||||||
MegasasCmd *cmd = req->hba_private;
|
MegasasCmd *cmd = req->hba_private;
|
||||||
|
|
||||||
if (!cmd) {
|
if (!cmd || !cmd->frame) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cmd->frame->header.cmd_status = MFI_STAT_SCSI_IO_FAILED;
|
cmd->frame->header.cmd_status = MFI_STAT_SCSI_IO_FAILED;
|
||||||
|
|||||||
@@ -327,11 +327,17 @@ static void scsi_read_complete(void * opaque, int ret)
|
|||||||
if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
|
if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
|
||||||
(ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
|
(ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
|
||||||
s->blocksize = ldl_be_p(&r->buf[4]);
|
s->blocksize = ldl_be_p(&r->buf[4]);
|
||||||
s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
|
BlockBackend *blk = s->conf.blk;
|
||||||
|
BlockDriverState *bs = blk_bs(blk);
|
||||||
|
s->max_lba = bs->total_sectors - 1;
|
||||||
|
stl_be_p(&r->buf[0], s->max_lba);
|
||||||
} else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
|
} else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
|
||||||
(r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
|
(r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
|
||||||
s->blocksize = ldl_be_p(&r->buf[8]);
|
s->blocksize = ldl_be_p(&r->buf[8]);
|
||||||
s->max_lba = ldq_be_p(&r->buf[0]);
|
BlockBackend *blk = s->conf.blk;
|
||||||
|
BlockDriverState *bs = blk_bs(blk);
|
||||||
|
s->max_lba = bs->total_sectors - 1;
|
||||||
|
stq_be_p(&r->buf[0], s->max_lba);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -396,7 +402,10 @@ static void scsi_write_complete(void * opaque, int ret)
|
|||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
if (ret || r->req.io_canceled) {
|
if (ret || r->req.io_canceled ||
|
||||||
|
r->io_header.status != SCSI_HOST_OK ||
|
||||||
|
(r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) ||
|
||||||
|
r->io_header.status != GOOD) {
|
||||||
scsi_command_complete_noio(r, ret);
|
scsi_command_complete_noio(r, ret);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1263,6 +1263,7 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
|||||||
struct smbios_structure_header *header;
|
struct smbios_structure_header *header;
|
||||||
int size;
|
int size;
|
||||||
struct smbios_table *table; /* legacy mode only */
|
struct smbios_table *table; /* legacy mode only */
|
||||||
|
uint8_t *dbl_nulls, *orig_end;
|
||||||
|
|
||||||
if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) {
|
if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) {
|
||||||
return;
|
return;
|
||||||
@@ -1275,11 +1276,21 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: standard double '\0' terminator expected, per smbios spec.
|
* NOTE: standard double '\0' terminator expected, per smbios spec,
|
||||||
* (except in legacy mode, where the second '\0' is implicit and
|
* unless the data is formatted for legacy mode, which is used by
|
||||||
* will be inserted by the BIOS).
|
* pc-i440fx-2.0 and earlier machine types. Legacy mode structures
|
||||||
|
* without strings have no '\0' terminators, and those with strings
|
||||||
|
* also don't have an additional '\0' terminator at the end of the
|
||||||
|
* final string '\0' terminator. The BIOS will add the '\0' terminators
|
||||||
|
* to comply with the smbios spec.
|
||||||
|
* For greater compatibility, regardless of the machine type used,
|
||||||
|
* either format is accepted.
|
||||||
*/
|
*/
|
||||||
smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size);
|
smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size + 2);
|
||||||
|
orig_end = smbios_tables + smbios_tables_len + size;
|
||||||
|
/* add extra null bytes to end in case of legacy file data */
|
||||||
|
*orig_end = '\0';
|
||||||
|
*(orig_end + 1) = '\0';
|
||||||
header = (struct smbios_structure_header *)(smbios_tables +
|
header = (struct smbios_structure_header *)(smbios_tables +
|
||||||
smbios_tables_len);
|
smbios_tables_len);
|
||||||
|
|
||||||
@@ -1297,6 +1308,20 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
|||||||
}
|
}
|
||||||
set_bit(header->type, have_binfile_bitmap);
|
set_bit(header->type, have_binfile_bitmap);
|
||||||
}
|
}
|
||||||
|
for (dbl_nulls = smbios_tables + smbios_tables_len + header->length;
|
||||||
|
dbl_nulls + 2 <= orig_end; dbl_nulls++) {
|
||||||
|
if (*dbl_nulls == '\0' && *(dbl_nulls + 1) == '\0') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dbl_nulls + 2 < orig_end) {
|
||||||
|
error_setg(errp, "SMBIOS file data malformed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* increase size by how many extra nulls were actually needed */
|
||||||
|
size += dbl_nulls + 2 - orig_end;
|
||||||
|
smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size);
|
||||||
|
set_bit(header->type, have_binfile_bitmap);
|
||||||
|
|
||||||
if (header->type == 4) {
|
if (header->type == 4) {
|
||||||
smbios_type4_count++;
|
smbios_type4_count++;
|
||||||
@@ -1316,6 +1341,17 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
|||||||
* delete the one we don't need from smbios_set_defaults(),
|
* delete the one we don't need from smbios_set_defaults(),
|
||||||
* once we know which machine version has been requested.
|
* once we know which machine version has been requested.
|
||||||
*/
|
*/
|
||||||
|
if (dbl_nulls + 2 == orig_end) {
|
||||||
|
/* chop off nulls to get legacy format */
|
||||||
|
if (header->length + 2 == size) {
|
||||||
|
size -= 2;
|
||||||
|
} else {
|
||||||
|
size -= 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* undo conversion from legacy format to per-spec format */
|
||||||
|
size -= dbl_nulls + 2 - orig_end;
|
||||||
|
}
|
||||||
if (!smbios_entries) {
|
if (!smbios_entries) {
|
||||||
smbios_entries_len = sizeof(uint16_t);
|
smbios_entries_len = sizeof(uint16_t);
|
||||||
smbios_entries = g_malloc0(smbios_entries_len);
|
smbios_entries = g_malloc0(smbios_entries_len);
|
||||||
|
|||||||
@@ -577,12 +577,9 @@ static void idreg_realize(DeviceState *ds, Error **errp)
|
|||||||
{
|
{
|
||||||
IDRegState *s = MACIO_ID_REGISTER(ds);
|
IDRegState *s = MACIO_ID_REGISTER(ds);
|
||||||
SysBusDevice *dev = SYS_BUS_DEVICE(ds);
|
SysBusDevice *dev = SYS_BUS_DEVICE(ds);
|
||||||
Error *local_err = NULL;
|
|
||||||
|
|
||||||
memory_region_init_ram_nomigrate(&s->mem, OBJECT(ds), "sun4m.idreg",
|
if (!memory_region_init_ram_nomigrate(&s->mem, OBJECT(ds), "sun4m.idreg",
|
||||||
sizeof(idreg_data), &local_err);
|
sizeof(idreg_data), errp)) {
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,12 +628,9 @@ static void afx_realize(DeviceState *ds, Error **errp)
|
|||||||
{
|
{
|
||||||
AFXState *s = TCX_AFX(ds);
|
AFXState *s = TCX_AFX(ds);
|
||||||
SysBusDevice *dev = SYS_BUS_DEVICE(ds);
|
SysBusDevice *dev = SYS_BUS_DEVICE(ds);
|
||||||
Error *local_err = NULL;
|
|
||||||
|
|
||||||
memory_region_init_ram_nomigrate(&s->mem, OBJECT(ds), "sun4m.afx", 4,
|
if (!memory_region_init_ram_nomigrate(&s->mem, OBJECT(ds), "sun4m.afx",
|
||||||
&local_err);
|
4, errp)) {
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,12 +709,9 @@ static void prom_realize(DeviceState *ds, Error **errp)
|
|||||||
{
|
{
|
||||||
PROMState *s = OPENPROM(ds);
|
PROMState *s = OPENPROM(ds);
|
||||||
SysBusDevice *dev = SYS_BUS_DEVICE(ds);
|
SysBusDevice *dev = SYS_BUS_DEVICE(ds);
|
||||||
Error *local_err = NULL;
|
|
||||||
|
|
||||||
memory_region_init_ram_nomigrate(&s->prom, OBJECT(ds), "sun4m.prom",
|
if (!memory_region_init_ram_nomigrate(&s->prom, OBJECT(ds), "sun4m.prom",
|
||||||
PROM_SIZE_MAX, &local_err);
|
PROM_SIZE_MAX, errp)) {
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -454,12 +454,9 @@ static void prom_realize(DeviceState *ds, Error **errp)
|
|||||||
{
|
{
|
||||||
PROMState *s = OPENPROM(ds);
|
PROMState *s = OPENPROM(ds);
|
||||||
SysBusDevice *dev = SYS_BUS_DEVICE(ds);
|
SysBusDevice *dev = SYS_BUS_DEVICE(ds);
|
||||||
Error *local_err = NULL;
|
|
||||||
|
|
||||||
memory_region_init_ram_nomigrate(&s->prom, OBJECT(ds), "sun4u.prom",
|
if (!memory_region_init_ram_nomigrate(&s->prom, OBJECT(ds), "sun4u.prom",
|
||||||
PROM_SIZE_MAX, &local_err);
|
PROM_SIZE_MAX, errp)) {
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -605,8 +605,7 @@ static int virtio_mem_set_block_state(VirtIOMEM *vmem, uint64_t start_gpa,
|
|||||||
int fd = memory_region_get_fd(&vmem->memdev->mr);
|
int fd = memory_region_get_fd(&vmem->memdev->mr);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
qemu_prealloc_mem(fd, area, size, 1, NULL, &local_err);
|
if (!qemu_prealloc_mem(fd, area, size, 1, NULL, &local_err)) {
|
||||||
if (local_err) {
|
|
||||||
static bool warned;
|
static bool warned;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1249,8 +1248,7 @@ static int virtio_mem_prealloc_range_cb(VirtIOMEM *vmem, void *arg,
|
|||||||
int fd = memory_region_get_fd(&vmem->memdev->mr);
|
int fd = memory_region_get_fd(&vmem->memdev->mr);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
qemu_prealloc_mem(fd, area, size, 1, NULL, &local_err);
|
if (!qemu_prealloc_mem(fd, area, size, 1, NULL, &local_err)) {
|
||||||
if (local_err) {
|
|
||||||
error_report_err(local_err);
|
error_report_err(local_err);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ void hmp_eject(Monitor *mon, const QDict *qdict);
|
|||||||
|
|
||||||
void hmp_qemu_io(Monitor *mon, const QDict *qdict);
|
void hmp_qemu_io(Monitor *mon, const QDict *qdict);
|
||||||
|
|
||||||
void hmp_info_block(Monitor *mon, const QDict *qdict);
|
void coroutine_fn hmp_info_block(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
|
void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
|
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
|
void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
|
||||||
|
|||||||
@@ -25,14 +25,14 @@
|
|||||||
#ifndef BLOCK_QAPI_H
|
#ifndef BLOCK_QAPI_H
|
||||||
#define BLOCK_QAPI_H
|
#define BLOCK_QAPI_H
|
||||||
|
|
||||||
|
#include "block/block-common.h"
|
||||||
#include "block/graph-lock.h"
|
#include "block/graph-lock.h"
|
||||||
#include "block/snapshot.h"
|
#include "block/snapshot.h"
|
||||||
#include "qapi/qapi-types-block-core.h"
|
#include "qapi/qapi-types-block-core.h"
|
||||||
|
|
||||||
BlockDeviceInfo * GRAPH_RDLOCK
|
BlockDeviceInfo *coroutine_fn GRAPH_RDLOCK
|
||||||
bdrv_block_device_info(BlockBackend *blk, BlockDriverState *bs,
|
bdrv_block_device_info(BlockBackend *blk, BlockDriverState *bs, bool flat,
|
||||||
bool flat, Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
int GRAPH_RDLOCK
|
int GRAPH_RDLOCK
|
||||||
bdrv_query_snapshot_info_list(BlockDriverState *bs,
|
bdrv_query_snapshot_info_list(BlockDriverState *bs,
|
||||||
SnapshotInfoList **p_list,
|
SnapshotInfoList **p_list,
|
||||||
@@ -40,7 +40,10 @@ bdrv_query_snapshot_info_list(BlockDriverState *bs,
|
|||||||
void GRAPH_RDLOCK
|
void GRAPH_RDLOCK
|
||||||
bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p_info, bool flat,
|
bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p_info, bool flat,
|
||||||
bool skip_implicit_filters, Error **errp);
|
bool skip_implicit_filters, Error **errp);
|
||||||
void GRAPH_RDLOCK
|
void coroutine_fn GRAPH_RDLOCK
|
||||||
|
bdrv_co_query_block_graph_info(BlockDriverState *bs, BlockGraphInfo **p_info,
|
||||||
|
Error **errp);
|
||||||
|
void co_wrapper_bdrv_rdlock
|
||||||
bdrv_query_block_graph_info(BlockDriverState *bs, BlockGraphInfo **p_info,
|
bdrv_query_block_graph_info(BlockDriverState *bs, BlockGraphInfo **p_info,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#define QEMU_AIO_ZONE_REPORT 0x0100
|
#define QEMU_AIO_ZONE_REPORT 0x0100
|
||||||
#define QEMU_AIO_ZONE_MGMT 0x0200
|
#define QEMU_AIO_ZONE_MGMT 0x0200
|
||||||
#define QEMU_AIO_ZONE_APPEND 0x0400
|
#define QEMU_AIO_ZONE_APPEND 0x0400
|
||||||
|
#define QEMU_AIO_FSTAT 0x0800
|
||||||
#define QEMU_AIO_TYPE_MASK \
|
#define QEMU_AIO_TYPE_MASK \
|
||||||
(QEMU_AIO_READ | \
|
(QEMU_AIO_READ | \
|
||||||
QEMU_AIO_WRITE | \
|
QEMU_AIO_WRITE | \
|
||||||
@@ -42,7 +43,8 @@
|
|||||||
QEMU_AIO_TRUNCATE | \
|
QEMU_AIO_TRUNCATE | \
|
||||||
QEMU_AIO_ZONE_REPORT | \
|
QEMU_AIO_ZONE_REPORT | \
|
||||||
QEMU_AIO_ZONE_MGMT | \
|
QEMU_AIO_ZONE_MGMT | \
|
||||||
QEMU_AIO_ZONE_APPEND)
|
QEMU_AIO_ZONE_APPEND | \
|
||||||
|
QEMU_AIO_FSTAT)
|
||||||
|
|
||||||
/* AIO flags */
|
/* AIO flags */
|
||||||
#define QEMU_AIO_MISALIGNED 0x1000
|
#define QEMU_AIO_MISALIGNED 0x1000
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "qemu/coroutine.h"
|
#include "qemu/coroutine.h"
|
||||||
#include "qemu/throttle.h"
|
#include "qemu/throttle.h"
|
||||||
|
#include "block/block_int.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
|
||||||
/* The ThrottleGroupMember structure indicates membership in a ThrottleGroup
|
/* The ThrottleGroupMember structure indicates membership in a ThrottleGroup
|
||||||
|
|||||||
@@ -23,7 +23,10 @@
|
|||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
|
||||||
#define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
|
#define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport, CONFIDENTIAL_GUEST_SUPPORT)
|
OBJECT_DECLARE_TYPE(ConfidentialGuestSupport,
|
||||||
|
ConfidentialGuestSupportClass,
|
||||||
|
CONFIDENTIAL_GUEST_SUPPORT)
|
||||||
|
|
||||||
|
|
||||||
struct ConfidentialGuestSupport {
|
struct ConfidentialGuestSupport {
|
||||||
Object parent;
|
Object parent;
|
||||||
@@ -55,8 +58,37 @@ struct ConfidentialGuestSupport {
|
|||||||
|
|
||||||
typedef struct ConfidentialGuestSupportClass {
|
typedef struct ConfidentialGuestSupportClass {
|
||||||
ObjectClass parent;
|
ObjectClass parent;
|
||||||
|
|
||||||
|
int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp);
|
||||||
|
int (*kvm_reset)(ConfidentialGuestSupport *cgs, Error **errp);
|
||||||
} ConfidentialGuestSupportClass;
|
} ConfidentialGuestSupportClass;
|
||||||
|
|
||||||
|
static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
ConfidentialGuestSupportClass *klass;
|
||||||
|
|
||||||
|
klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs);
|
||||||
|
if (klass->kvm_init) {
|
||||||
|
return klass->kvm_init(cgs, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int confidential_guest_kvm_reset(ConfidentialGuestSupport *cgs,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
ConfidentialGuestSupportClass *klass;
|
||||||
|
|
||||||
|
klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs);
|
||||||
|
if (klass->kvm_reset) {
|
||||||
|
return klass->kvm_reset(cgs, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !CONFIG_USER_ONLY */
|
#endif /* !CONFIG_USER_ONLY */
|
||||||
|
|
||||||
#endif /* QEMU_CONFIDENTIAL_GUEST_SUPPORT_H */
|
#endif /* QEMU_CONFIDENTIAL_GUEST_SUPPORT_H */
|
||||||
|
|||||||
@@ -175,6 +175,8 @@ typedef int (RAMBlockIterFunc)(RAMBlock *rb, void *opaque);
|
|||||||
|
|
||||||
int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
|
int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
|
||||||
int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length);
|
int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length);
|
||||||
|
int ram_block_discard_guest_memfd_range(RAMBlock *rb, uint64_t start,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -243,6 +243,9 @@ typedef struct IOMMUTLBEvent {
|
|||||||
/* RAM FD is opened read-only */
|
/* RAM FD is opened read-only */
|
||||||
#define RAM_READONLY_FD (1 << 11)
|
#define RAM_READONLY_FD (1 << 11)
|
||||||
|
|
||||||
|
/* RAM can be private that has kvm guest memfd backend */
|
||||||
|
#define RAM_GUEST_MEMFD (1 << 12)
|
||||||
|
|
||||||
static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
|
static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
|
||||||
IOMMUNotifierFlag flags,
|
IOMMUNotifierFlag flags,
|
||||||
hwaddr start, hwaddr end,
|
hwaddr start, hwaddr end,
|
||||||
@@ -1288,8 +1291,10 @@ void memory_region_init_io(MemoryRegion *mr,
|
|||||||
*
|
*
|
||||||
* Note that this function does not do anything to cause the data in the
|
* Note that this function does not do anything to cause the data in the
|
||||||
* RAM memory region to be migrated; that is the responsibility of the caller.
|
* RAM memory region to be migrated; that is the responsibility of the caller.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_ram_nomigrate(MemoryRegion *mr,
|
bool memory_region_init_ram_nomigrate(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
@@ -1305,13 +1310,16 @@ void memory_region_init_ram_nomigrate(MemoryRegion *mr,
|
|||||||
* @name: Region name, becomes part of RAMBlock name used in migration stream
|
* @name: Region name, becomes part of RAMBlock name used in migration stream
|
||||||
* must be unique within any device
|
* must be unique within any device
|
||||||
* @size: size of the region.
|
* @size: size of the region.
|
||||||
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_NORESERVE.
|
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_NORESERVE,
|
||||||
|
* RAM_GUEST_MEMFD.
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
*
|
*
|
||||||
* Note that this function does not do anything to cause the data in the
|
* Note that this function does not do anything to cause the data in the
|
||||||
* RAM memory region to be migrated; that is the responsibility of the caller.
|
* RAM memory region to be migrated; that is the responsibility of the caller.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
|
bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
@@ -1338,8 +1346,10 @@ void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
|
|||||||
*
|
*
|
||||||
* Note that this function does not do anything to cause the data in the
|
* Note that this function does not do anything to cause the data in the
|
||||||
* RAM memory region to be migrated; that is the responsibility of the caller.
|
* RAM memory region to be migrated; that is the responsibility of the caller.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_resizeable_ram(MemoryRegion *mr,
|
bool memory_region_init_resizeable_ram(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
@@ -1363,15 +1373,17 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
|
|||||||
* (getpagesize()) will be used.
|
* (getpagesize()) will be used.
|
||||||
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
|
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
|
||||||
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
|
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
|
||||||
* RAM_READONLY_FD
|
* RAM_READONLY_FD, RAM_GUEST_MEMFD
|
||||||
* @path: the path in which to allocate the RAM.
|
* @path: the path in which to allocate the RAM.
|
||||||
* @offset: offset within the file referenced by path
|
* @offset: offset within the file referenced by path
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
*
|
*
|
||||||
* Note that this function does not do anything to cause the data in the
|
* Note that this function does not do anything to cause the data in the
|
||||||
* RAM memory region to be migrated; that is the responsibility of the caller.
|
* RAM memory region to be migrated; that is the responsibility of the caller.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_ram_from_file(MemoryRegion *mr,
|
bool memory_region_init_ram_from_file(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
@@ -1391,15 +1403,17 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
|
|||||||
* @size: size of the region.
|
* @size: size of the region.
|
||||||
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
|
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
|
||||||
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
|
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
|
||||||
* RAM_READONLY_FD
|
* RAM_READONLY_FD, RAM_GUEST_MEMFD
|
||||||
* @fd: the fd to mmap.
|
* @fd: the fd to mmap.
|
||||||
* @offset: offset within the file referenced by fd
|
* @offset: offset within the file referenced by fd
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
*
|
*
|
||||||
* Note that this function does not do anything to cause the data in the
|
* Note that this function does not do anything to cause the data in the
|
||||||
* RAM memory region to be migrated; that is the responsibility of the caller.
|
* RAM memory region to be migrated; that is the responsibility of the caller.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_ram_from_fd(MemoryRegion *mr,
|
bool memory_region_init_ram_from_fd(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
@@ -1494,8 +1508,10 @@ void memory_region_init_alias(MemoryRegion *mr,
|
|||||||
* must be unique within any device
|
* must be unique within any device
|
||||||
* @size: size of the region.
|
* @size: size of the region.
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_rom_nomigrate(MemoryRegion *mr,
|
bool memory_region_init_rom_nomigrate(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
@@ -1517,8 +1533,10 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr,
|
|||||||
* must be unique within any device
|
* must be unique within any device
|
||||||
* @size: size of the region.
|
* @size: size of the region.
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
bool memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const MemoryRegionOps *ops,
|
const MemoryRegionOps *ops,
|
||||||
void *opaque,
|
void *opaque,
|
||||||
@@ -1576,13 +1594,21 @@ void memory_region_init_iommu(void *_iommu_mr,
|
|||||||
* give the RAM block a unique name for migration purposes.
|
* give the RAM block a unique name for migration purposes.
|
||||||
* We should lift this restriction and allow arbitrary Objects.
|
* We should lift this restriction and allow arbitrary Objects.
|
||||||
* If you pass a non-NULL non-device @owner then we will assert.
|
* If you pass a non-NULL non-device @owner then we will assert.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_ram(MemoryRegion *mr,
|
bool memory_region_init_ram(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
|
bool memory_region_init_ram_guest_memfd(MemoryRegion *mr,
|
||||||
|
Object *owner,
|
||||||
|
const char *name,
|
||||||
|
uint64_t size,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* memory_region_init_rom: Initialize a ROM memory region.
|
* memory_region_init_rom: Initialize a ROM memory region.
|
||||||
*
|
*
|
||||||
@@ -1603,8 +1629,10 @@ void memory_region_init_ram(MemoryRegion *mr,
|
|||||||
* must be unique within any device
|
* must be unique within any device
|
||||||
* @size: size of the region.
|
* @size: size of the region.
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_rom(MemoryRegion *mr,
|
bool memory_region_init_rom(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const char *name,
|
const char *name,
|
||||||
uint64_t size,
|
uint64_t size,
|
||||||
@@ -1634,8 +1662,10 @@ void memory_region_init_rom(MemoryRegion *mr,
|
|||||||
* must be unique within any device
|
* must be unique within any device
|
||||||
* @size: size of the region.
|
* @size: size of the region.
|
||||||
* @errp: pointer to Error*, to store an error if it happens.
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void memory_region_init_rom_device(MemoryRegion *mr,
|
bool memory_region_init_rom_device(MemoryRegion *mr,
|
||||||
Object *owner,
|
Object *owner,
|
||||||
const MemoryRegionOps *ops,
|
const MemoryRegionOps *ops,
|
||||||
void *opaque,
|
void *opaque,
|
||||||
@@ -1702,6 +1732,16 @@ static inline bool memory_region_is_romd(MemoryRegion *mr)
|
|||||||
*/
|
*/
|
||||||
bool memory_region_is_protected(MemoryRegion *mr);
|
bool memory_region_is_protected(MemoryRegion *mr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* memory_region_has_guest_memfd: check whether a memory region has guest_memfd
|
||||||
|
* associated
|
||||||
|
*
|
||||||
|
* Returns %true if a memory region's ram_block has valid guest_memfd assigned.
|
||||||
|
*
|
||||||
|
* @mr: the memory region being queried
|
||||||
|
*/
|
||||||
|
bool memory_region_has_guest_memfd(MemoryRegion *mr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* memory_region_get_iommu: check whether a memory region is an iommu
|
* memory_region_get_iommu: check whether a memory region is an iommu
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ long qemu_maxrampagesize(void);
|
|||||||
* @mr: the memory region where the ram block is
|
* @mr: the memory region where the ram block is
|
||||||
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
|
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
|
||||||
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
|
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
|
||||||
* RAM_READONLY_FD
|
* RAM_READONLY_FD, RAM_GUEST_MEMFD
|
||||||
* @mem_path or @fd: specify the backing file or device
|
* @mem_path or @fd: specify the backing file or device
|
||||||
* @offset: Offset into target file
|
* @offset: Offset into target file
|
||||||
* @errp: pointer to Error*, to store an error if it happens
|
* @errp: pointer to Error*, to store an error if it happens
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ struct RAMBlock {
|
|||||||
QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers;
|
QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers;
|
||||||
int fd;
|
int fd;
|
||||||
uint64_t fd_offset;
|
uint64_t fd_offset;
|
||||||
|
int guest_memfd;
|
||||||
size_t page_size;
|
size_t page_size;
|
||||||
/* dirty bitmap used during migration */
|
/* dirty bitmap used during migration */
|
||||||
unsigned long *bmap;
|
unsigned long *bmap;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ bool machine_usb(MachineState *machine);
|
|||||||
int machine_phandle_start(MachineState *machine);
|
int machine_phandle_start(MachineState *machine);
|
||||||
bool machine_dump_guest_core(MachineState *machine);
|
bool machine_dump_guest_core(MachineState *machine);
|
||||||
bool machine_mem_merge(MachineState *machine);
|
bool machine_mem_merge(MachineState *machine);
|
||||||
|
bool machine_require_guest_memfd(MachineState *machine);
|
||||||
HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
|
HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
|
||||||
void machine_set_cpu_numa_node(MachineState *machine,
|
void machine_set_cpu_numa_node(MachineState *machine,
|
||||||
const CpuInstanceProperties *props,
|
const CpuInstanceProperties *props,
|
||||||
@@ -364,6 +365,7 @@ struct MachineState {
|
|||||||
char *dt_compatible;
|
char *dt_compatible;
|
||||||
bool dump_guest_core;
|
bool dump_guest_core;
|
||||||
bool mem_merge;
|
bool mem_merge;
|
||||||
|
bool require_guest_memfd;
|
||||||
bool usb;
|
bool usb;
|
||||||
bool usb_disabled;
|
bool usb_disabled;
|
||||||
char *firmware;
|
char *firmware;
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include "hw/hotplug.h"
|
#include "hw/hotplug.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "hw/i386/sgx-epc.h"
|
#include "hw/i386/sgx-epc.h"
|
||||||
#include "hw/firmware/smbios.h"
|
|
||||||
#include "hw/cxl/cxl.h"
|
#include "hw/cxl/cxl.h"
|
||||||
|
|
||||||
#define HPET_INTCAP "hpet-intcap"
|
#define HPET_INTCAP "hpet-intcap"
|
||||||
@@ -152,8 +151,6 @@ extern int fd_bootchk;
|
|||||||
|
|
||||||
void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
|
void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
|
||||||
|
|
||||||
void pc_guest_info_init(PCMachineState *pcms);
|
|
||||||
|
|
||||||
#define PCI_HOST_PROP_RAM_MEM "ram-mem"
|
#define PCI_HOST_PROP_RAM_MEM "ram-mem"
|
||||||
#define PCI_HOST_PROP_PCI_MEM "pci-mem"
|
#define PCI_HOST_PROP_PCI_MEM "pci-mem"
|
||||||
#define PCI_HOST_PROP_SYSTEM_MEM "system-mem"
|
#define PCI_HOST_PROP_SYSTEM_MEM "system-mem"
|
||||||
@@ -165,6 +162,7 @@ void pc_guest_info_init(PCMachineState *pcms);
|
|||||||
#define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size"
|
#define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size"
|
||||||
#define PCI_HOST_BELOW_4G_MEM_SIZE "below-4g-mem-size"
|
#define PCI_HOST_BELOW_4G_MEM_SIZE "below-4g-mem-size"
|
||||||
#define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size"
|
#define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size"
|
||||||
|
#define PCI_HOST_PROP_SMM_RANGES "smm-ranges"
|
||||||
|
|
||||||
|
|
||||||
void pc_pci_as_mapping_init(MemoryRegion *system_memory,
|
void pc_pci_as_mapping_init(MemoryRegion *system_memory,
|
||||||
|
|||||||
58
include/hw/i386/tdvf.h
Normal file
58
include/hw/i386/tdvf.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
* Copyright (c) 2020 Intel Corporation
|
||||||
|
* Author: Isaku Yamahata <isaku.yamahata at gmail.com>
|
||||||
|
* <isaku.yamahata at intel.com>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HW_I386_TDVF_H
|
||||||
|
#define HW_I386_TDVF_H
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
|
||||||
|
#define TDVF_SECTION_TYPE_BFV 0
|
||||||
|
#define TDVF_SECTION_TYPE_CFV 1
|
||||||
|
#define TDVF_SECTION_TYPE_TD_HOB 2
|
||||||
|
#define TDVF_SECTION_TYPE_TEMP_MEM 3
|
||||||
|
|
||||||
|
#define TDVF_SECTION_ATTRIBUTES_MR_EXTEND (1U << 0)
|
||||||
|
#define TDVF_SECTION_ATTRIBUTES_PAGE_AUG (1U << 1)
|
||||||
|
|
||||||
|
typedef struct TdxFirmwareEntry {
|
||||||
|
uint32_t data_offset;
|
||||||
|
uint32_t data_len;
|
||||||
|
uint64_t address;
|
||||||
|
uint64_t size;
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t attributes;
|
||||||
|
|
||||||
|
void *mem_ptr;
|
||||||
|
} TdxFirmwareEntry;
|
||||||
|
|
||||||
|
typedef struct TdxFirmware {
|
||||||
|
void *mem_ptr;
|
||||||
|
|
||||||
|
uint32_t nr_entries;
|
||||||
|
TdxFirmwareEntry *entries;
|
||||||
|
} TdxFirmware;
|
||||||
|
|
||||||
|
#define for_each_tdx_fw_entry(fw, e) \
|
||||||
|
for (e = (fw)->entries; e != (fw)->entries + (fw)->nr_entries; e++)
|
||||||
|
|
||||||
|
int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size);
|
||||||
|
|
||||||
|
#endif /* HW_I386_TDVF_H */
|
||||||
@@ -34,6 +34,8 @@ struct X86MachineClass {
|
|||||||
bool save_tsc_khz;
|
bool save_tsc_khz;
|
||||||
/* use DMA capable linuxboot option rom */
|
/* use DMA capable linuxboot option rom */
|
||||||
bool fwcfg_dma_enabled;
|
bool fwcfg_dma_enabled;
|
||||||
|
/* CPU and apic information: */
|
||||||
|
bool apic_xrupt_override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct X86MachineState {
|
struct X86MachineState {
|
||||||
@@ -41,6 +43,7 @@ struct X86MachineState {
|
|||||||
MachineState parent;
|
MachineState parent;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
unsigned int vm_type;
|
||||||
|
|
||||||
/* Pointers to devices and objects: */
|
/* Pointers to devices and objects: */
|
||||||
ISADevice *rtc;
|
ISADevice *rtc;
|
||||||
@@ -57,7 +60,7 @@ struct X86MachineState {
|
|||||||
uint64_t above_4g_mem_start;
|
uint64_t above_4g_mem_start;
|
||||||
|
|
||||||
/* CPU and apic information: */
|
/* CPU and apic information: */
|
||||||
bool apic_xrupt_override;
|
bool eoi_intercept_unsupported;
|
||||||
unsigned pci_irq_mask;
|
unsigned pci_irq_mask;
|
||||||
unsigned apic_id_limit;
|
unsigned apic_id_limit;
|
||||||
uint16_t boot_cpus;
|
uint16_t boot_cpus;
|
||||||
@@ -138,7 +141,7 @@ typedef struct GSIState {
|
|||||||
|
|
||||||
qemu_irq x86_allocate_cpu_irq(void);
|
qemu_irq x86_allocate_cpu_irq(void);
|
||||||
void gsi_handler(void *opaque, int n, int level);
|
void gsi_handler(void *opaque, int n, int level);
|
||||||
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
|
void ioapic_init_gsi(GSIState *gsi_state, Object *parent);
|
||||||
DeviceState *ioapic_init_secondary(GSIState *gsi_state);
|
DeviceState *ioapic_init_secondary(GSIState *gsi_state);
|
||||||
|
|
||||||
/* pc_sysfw.c */
|
/* pc_sysfw.c */
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ struct MCHPCIState {
|
|||||||
MemoryRegion tseg_blackhole, tseg_window;
|
MemoryRegion tseg_blackhole, tseg_window;
|
||||||
MemoryRegion smbase_blackhole, smbase_window;
|
MemoryRegion smbase_blackhole, smbase_window;
|
||||||
bool has_smram_at_smbase;
|
bool has_smram_at_smbase;
|
||||||
|
bool has_smm_ranges;
|
||||||
Range pci_hole;
|
Range pci_hole;
|
||||||
uint64_t below_4g_mem_size;
|
uint64_t below_4g_mem_size;
|
||||||
uint64_t above_4g_mem_size;
|
uint64_t above_4g_mem_size;
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* PEF (Protected Execution Facility) for POWER support
|
|
||||||
*
|
|
||||||
* Copyright Red Hat.
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HW_PPC_PEF_H
|
|
||||||
#define HW_PPC_PEF_H
|
|
||||||
|
|
||||||
int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp);
|
|
||||||
int pef_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp);
|
|
||||||
|
|
||||||
#endif /* HW_PPC_PEF_H */
|
|
||||||
@@ -14,9 +14,21 @@
|
|||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IRQ range offsets per device type
|
* The XIVE IRQ backend uses the same layout as the XICS backend but
|
||||||
|
* covers the full range of the IRQ number space. The IRQ numbers for
|
||||||
|
* the CPU IPIs are allocated at the bottom of this space, below 4K,
|
||||||
|
* to preserve compatibility with XICS which does not use that range.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU IPI range (XIVE only)
|
||||||
*/
|
*/
|
||||||
#define SPAPR_IRQ_IPI 0x0
|
#define SPAPR_IRQ_IPI 0x0
|
||||||
|
#define SPAPR_IRQ_NR_IPIS 0x1000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IRQ range offsets per device type
|
||||||
|
*/
|
||||||
|
|
||||||
#define SPAPR_XIRQ_BASE XICS_IRQ_BASE /* 0x1000 */
|
#define SPAPR_XIRQ_BASE XICS_IRQ_BASE /* 0x1000 */
|
||||||
#define SPAPR_IRQ_EPOW (SPAPR_XIRQ_BASE + 0x0000)
|
#define SPAPR_IRQ_EPOW (SPAPR_XIRQ_BASE + 0x0000)
|
||||||
|
|||||||
@@ -678,8 +678,10 @@ typedef struct ThreadContext ThreadContext;
|
|||||||
* memory area starting at @area with the size of @sz. After a successful call,
|
* memory area starting at @area with the size of @sz. After a successful call,
|
||||||
* each page in the area was faulted in writable at least once, for example,
|
* each page in the area was faulted in writable at least once, for example,
|
||||||
* after allocating file blocks for mapped files.
|
* after allocating file blocks for mapped files.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
*/
|
*/
|
||||||
void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads,
|
bool qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads,
|
||||||
ThreadContext *tc, Error **errp);
|
ThreadContext *tc, Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ extern "C" {
|
|||||||
* Format modifiers may change any property of the buffer, including the number
|
* Format modifiers may change any property of the buffer, including the number
|
||||||
* of planes and/or the required allocation size. Format modifiers are
|
* of planes and/or the required allocation size. Format modifiers are
|
||||||
* vendor-namespaced, and as such the relationship between a fourcc code and a
|
* vendor-namespaced, and as such the relationship between a fourcc code and a
|
||||||
* modifier is specific to the modifer being used. For example, some modifiers
|
* modifier is specific to the modifier being used. For example, some modifiers
|
||||||
* may preserve meaning - such as number of planes - from the fourcc code,
|
* may preserve meaning - such as number of planes - from the fourcc code,
|
||||||
* whereas others may not.
|
* whereas others may not.
|
||||||
*
|
*
|
||||||
@@ -78,7 +78,7 @@ extern "C" {
|
|||||||
* format.
|
* format.
|
||||||
* - Higher-level programs interfacing with KMS/GBM/EGL/Vulkan/etc: these users
|
* - Higher-level programs interfacing with KMS/GBM/EGL/Vulkan/etc: these users
|
||||||
* see modifiers as opaque tokens they can check for equality and intersect.
|
* see modifiers as opaque tokens they can check for equality and intersect.
|
||||||
* These users musn't need to know to reason about the modifier value
|
* These users mustn't need to know to reason about the modifier value
|
||||||
* (i.e. they are not expected to extract information out of the modifier).
|
* (i.e. they are not expected to extract information out of the modifier).
|
||||||
*
|
*
|
||||||
* Vendors should document their modifier usage in as much detail as
|
* Vendors should document their modifier usage in as much detail as
|
||||||
@@ -322,6 +322,8 @@ extern "C" {
|
|||||||
* index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
|
* index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian
|
||||||
*/
|
*/
|
||||||
#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
|
#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */
|
||||||
|
#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */
|
||||||
|
#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2 plane YCbCr MSB aligned
|
* 2 plane YCbCr MSB aligned
|
||||||
@@ -537,7 +539,7 @@ extern "C" {
|
|||||||
* This is a tiled layout using 4Kb tiles in row-major layout.
|
* This is a tiled layout using 4Kb tiles in row-major layout.
|
||||||
* Within the tile pixels are laid out in 16 256 byte units / sub-tiles which
|
* Within the tile pixels are laid out in 16 256 byte units / sub-tiles which
|
||||||
* are arranged in four groups (two wide, two high) with column-major layout.
|
* are arranged in four groups (two wide, two high) with column-major layout.
|
||||||
* Each group therefore consits out of four 256 byte units, which are also laid
|
* Each group therefore consists out of four 256 byte units, which are also laid
|
||||||
* out as 2x2 column-major.
|
* out as 2x2 column-major.
|
||||||
* 256 byte units are made out of four 64 byte blocks of pixels, producing
|
* 256 byte units are made out of four 64 byte blocks of pixels, producing
|
||||||
* either a square block or a 2:1 unit.
|
* either a square block or a 2:1 unit.
|
||||||
@@ -1100,7 +1102,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The top 4 bits (out of the 56 bits alloted for specifying vendor specific
|
* The top 4 bits (out of the 56 bits allotted for specifying vendor specific
|
||||||
* modifiers) denote the category for modifiers. Currently we have three
|
* modifiers) denote the category for modifiers. Currently we have three
|
||||||
* categories of modifiers ie AFBC, MISC and AFRC. We can have a maximum of
|
* categories of modifiers ie AFBC, MISC and AFRC. We can have a maximum of
|
||||||
* sixteen different categories.
|
* sixteen different categories.
|
||||||
@@ -1416,7 +1418,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier)
|
|||||||
* Amlogic FBC Memory Saving mode
|
* Amlogic FBC Memory Saving mode
|
||||||
*
|
*
|
||||||
* Indicates the storage is packed when pixel size is multiple of word
|
* Indicates the storage is packed when pixel size is multiple of word
|
||||||
* boudaries, i.e. 8bit should be stored in this mode to save allocation
|
* boundaries, i.e. 8bit should be stored in this mode to save allocation
|
||||||
* memory.
|
* memory.
|
||||||
*
|
*
|
||||||
* This mode reduces body layout to 3072 bytes per 64x32 superblock with
|
* This mode reduces body layout to 3072 bytes per 64x32 superblock with
|
||||||
|
|||||||
@@ -1266,6 +1266,8 @@ struct ethtool_rxfh_indir {
|
|||||||
* hardware hash key.
|
* hardware hash key.
|
||||||
* @hfunc: Defines the current RSS hash function used by HW (or to be set to).
|
* @hfunc: Defines the current RSS hash function used by HW (or to be set to).
|
||||||
* Valid values are one of the %ETH_RSS_HASH_*.
|
* Valid values are one of the %ETH_RSS_HASH_*.
|
||||||
|
* @input_xfrm: Defines how the input data is transformed. Valid values are one
|
||||||
|
* of %RXH_XFRM_*.
|
||||||
* @rsvd8: Reserved for future use; see the note on reserved space.
|
* @rsvd8: Reserved for future use; see the note on reserved space.
|
||||||
* @rsvd32: Reserved for future use; see the note on reserved space.
|
* @rsvd32: Reserved for future use; see the note on reserved space.
|
||||||
* @rss_config: RX ring/queue index for each hash value i.e., indirection table
|
* @rss_config: RX ring/queue index for each hash value i.e., indirection table
|
||||||
@@ -1285,7 +1287,8 @@ struct ethtool_rxfh {
|
|||||||
uint32_t indir_size;
|
uint32_t indir_size;
|
||||||
uint32_t key_size;
|
uint32_t key_size;
|
||||||
uint8_t hfunc;
|
uint8_t hfunc;
|
||||||
uint8_t rsvd8[3];
|
uint8_t input_xfrm;
|
||||||
|
uint8_t rsvd8[2];
|
||||||
uint32_t rsvd32;
|
uint32_t rsvd32;
|
||||||
uint32_t rss_config[];
|
uint32_t rss_config[];
|
||||||
};
|
};
|
||||||
@@ -1992,6 +1995,15 @@ static inline int ethtool_validate_duplex(uint8_t duplex)
|
|||||||
|
|
||||||
#define WOL_MODE_COUNT 8
|
#define WOL_MODE_COUNT 8
|
||||||
|
|
||||||
|
/* RSS hash function data
|
||||||
|
* XOR the corresponding source and destination fields of each specified
|
||||||
|
* protocol. Both copies of the XOR'ed fields are fed into the RSS and RXHASH
|
||||||
|
* calculation. Note that this XORing reduces the input set entropy and could
|
||||||
|
* be exploited to reduce the RSS queue spread.
|
||||||
|
*/
|
||||||
|
#define RXH_XFRM_SYM_XOR (1 << 0)
|
||||||
|
#define RXH_XFRM_NO_CHANGE 0xff
|
||||||
|
|
||||||
/* L2-L4 network traffic flow types */
|
/* L2-L4 network traffic flow types */
|
||||||
#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */
|
#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */
|
||||||
#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */
|
#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */
|
||||||
@@ -2128,18 +2140,6 @@ enum ethtool_reset_flags {
|
|||||||
* refused. For drivers: ignore this field (use kernel's
|
* refused. For drivers: ignore this field (use kernel's
|
||||||
* __ETHTOOL_LINK_MODE_MASK_NBITS instead), any change to it will
|
* __ETHTOOL_LINK_MODE_MASK_NBITS instead), any change to it will
|
||||||
* be overwritten by kernel.
|
* be overwritten by kernel.
|
||||||
* @supported: Bitmap with each bit meaning given by
|
|
||||||
* %ethtool_link_mode_bit_indices for the link modes, physical
|
|
||||||
* connectors and other link features for which the interface
|
|
||||||
* supports autonegotiation or auto-detection. Read-only.
|
|
||||||
* @advertising: Bitmap with each bit meaning given by
|
|
||||||
* %ethtool_link_mode_bit_indices for the link modes, physical
|
|
||||||
* connectors and other link features that are advertised through
|
|
||||||
* autonegotiation or enabled for auto-detection.
|
|
||||||
* @lp_advertising: Bitmap with each bit meaning given by
|
|
||||||
* %ethtool_link_mode_bit_indices for the link modes, and other
|
|
||||||
* link features that the link partner advertised through
|
|
||||||
* autonegotiation; 0 if unknown or not applicable. Read-only.
|
|
||||||
* @transceiver: Used to distinguish different possible PHY types,
|
* @transceiver: Used to distinguish different possible PHY types,
|
||||||
* reported consistently by PHYLIB. Read-only.
|
* reported consistently by PHYLIB. Read-only.
|
||||||
* @master_slave_cfg: Master/slave port mode.
|
* @master_slave_cfg: Master/slave port mode.
|
||||||
@@ -2181,6 +2181,21 @@ enum ethtool_reset_flags {
|
|||||||
* %set_link_ksettings() should validate all fields other than @cmd
|
* %set_link_ksettings() should validate all fields other than @cmd
|
||||||
* and @link_mode_masks_nwords that are not described as read-only or
|
* and @link_mode_masks_nwords that are not described as read-only or
|
||||||
* deprecated, and must ignore all fields described as read-only.
|
* deprecated, and must ignore all fields described as read-only.
|
||||||
|
*
|
||||||
|
* @link_mode_masks is divided into three bitfields, each of length
|
||||||
|
* @link_mode_masks_nwords:
|
||||||
|
* - supported: Bitmap with each bit meaning given by
|
||||||
|
* %ethtool_link_mode_bit_indices for the link modes, physical
|
||||||
|
* connectors and other link features for which the interface
|
||||||
|
* supports autonegotiation or auto-detection. Read-only.
|
||||||
|
* - advertising: Bitmap with each bit meaning given by
|
||||||
|
* %ethtool_link_mode_bit_indices for the link modes, physical
|
||||||
|
* connectors and other link features that are advertised through
|
||||||
|
* autonegotiation or enabled for auto-detection.
|
||||||
|
* - lp_advertising: Bitmap with each bit meaning given by
|
||||||
|
* %ethtool_link_mode_bit_indices for the link modes, and other
|
||||||
|
* link features that the link partner advertised through
|
||||||
|
* autonegotiation; 0 if unknown or not applicable. Read-only.
|
||||||
*/
|
*/
|
||||||
struct ethtool_link_settings {
|
struct ethtool_link_settings {
|
||||||
uint32_t cmd;
|
uint32_t cmd;
|
||||||
|
|||||||
@@ -209,7 +209,7 @@
|
|||||||
* - add FUSE_HAS_EXPIRE_ONLY
|
* - add FUSE_HAS_EXPIRE_ONLY
|
||||||
*
|
*
|
||||||
* 7.39
|
* 7.39
|
||||||
* - add FUSE_DIRECT_IO_RELAX
|
* - add FUSE_DIRECT_IO_ALLOW_MMAP
|
||||||
* - add FUSE_STATX and related structures
|
* - add FUSE_STATX and related structures
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -405,8 +405,7 @@ struct fuse_file_lock {
|
|||||||
* FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir,
|
* FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir,
|
||||||
* symlink and mknod (single group that matches parent)
|
* symlink and mknod (single group that matches parent)
|
||||||
* FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation
|
* FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation
|
||||||
* FUSE_DIRECT_IO_RELAX: relax restrictions in FOPEN_DIRECT_IO mode, for now
|
* FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode.
|
||||||
* allow shared mmap
|
|
||||||
*/
|
*/
|
||||||
#define FUSE_ASYNC_READ (1 << 0)
|
#define FUSE_ASYNC_READ (1 << 0)
|
||||||
#define FUSE_POSIX_LOCKS (1 << 1)
|
#define FUSE_POSIX_LOCKS (1 << 1)
|
||||||
@@ -445,7 +444,10 @@ struct fuse_file_lock {
|
|||||||
#define FUSE_HAS_INODE_DAX (1ULL << 33)
|
#define FUSE_HAS_INODE_DAX (1ULL << 33)
|
||||||
#define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
|
#define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
|
||||||
#define FUSE_HAS_EXPIRE_ONLY (1ULL << 35)
|
#define FUSE_HAS_EXPIRE_ONLY (1ULL << 35)
|
||||||
#define FUSE_DIRECT_IO_RELAX (1ULL << 36)
|
#define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36)
|
||||||
|
|
||||||
|
/* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */
|
||||||
|
#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CUSE INIT request/reply flags
|
* CUSE INIT request/reply flags
|
||||||
|
|||||||
@@ -80,6 +80,7 @@
|
|||||||
#define PCI_HEADER_TYPE_NORMAL 0
|
#define PCI_HEADER_TYPE_NORMAL 0
|
||||||
#define PCI_HEADER_TYPE_BRIDGE 1
|
#define PCI_HEADER_TYPE_BRIDGE 1
|
||||||
#define PCI_HEADER_TYPE_CARDBUS 2
|
#define PCI_HEADER_TYPE_CARDBUS 2
|
||||||
|
#define PCI_HEADER_TYPE_MFD 0x80 /* Multi-Function Device (possible) */
|
||||||
|
|
||||||
#define PCI_BIST 0x0f /* 8 bits */
|
#define PCI_BIST 0x0f /* 8 bits */
|
||||||
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
|
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
|
||||||
@@ -637,6 +638,7 @@
|
|||||||
#define PCI_EXP_RTCAP 0x1e /* Root Capabilities */
|
#define PCI_EXP_RTCAP 0x1e /* Root Capabilities */
|
||||||
#define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */
|
#define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */
|
||||||
#define PCI_EXP_RTSTA 0x20 /* Root Status */
|
#define PCI_EXP_RTSTA 0x20 /* Root Status */
|
||||||
|
#define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff /* PME Requester ID */
|
||||||
#define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */
|
#define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */
|
||||||
#define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */
|
#define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */
|
||||||
/*
|
/*
|
||||||
@@ -930,12 +932,13 @@
|
|||||||
|
|
||||||
/* Process Address Space ID */
|
/* Process Address Space ID */
|
||||||
#define PCI_PASID_CAP 0x04 /* PASID feature register */
|
#define PCI_PASID_CAP 0x04 /* PASID feature register */
|
||||||
#define PCI_PASID_CAP_EXEC 0x02 /* Exec permissions Supported */
|
#define PCI_PASID_CAP_EXEC 0x0002 /* Exec permissions Supported */
|
||||||
#define PCI_PASID_CAP_PRIV 0x04 /* Privilege Mode Supported */
|
#define PCI_PASID_CAP_PRIV 0x0004 /* Privilege Mode Supported */
|
||||||
|
#define PCI_PASID_CAP_WIDTH 0x1f00
|
||||||
#define PCI_PASID_CTRL 0x06 /* PASID control register */
|
#define PCI_PASID_CTRL 0x06 /* PASID control register */
|
||||||
#define PCI_PASID_CTRL_ENABLE 0x01 /* Enable bit */
|
#define PCI_PASID_CTRL_ENABLE 0x0001 /* Enable bit */
|
||||||
#define PCI_PASID_CTRL_EXEC 0x02 /* Exec permissions Enable */
|
#define PCI_PASID_CTRL_EXEC 0x0002 /* Exec permissions Enable */
|
||||||
#define PCI_PASID_CTRL_PRIV 0x04 /* Privilege Mode Enable */
|
#define PCI_PASID_CTRL_PRIV 0x0004 /* Privilege Mode Enable */
|
||||||
#define PCI_EXT_CAP_PASID_SIZEOF 8
|
#define PCI_EXT_CAP_PASID_SIZEOF 8
|
||||||
|
|
||||||
/* Single Root I/O Virtualization */
|
/* Single Root I/O Virtualization */
|
||||||
@@ -975,6 +978,8 @@
|
|||||||
#define PCI_LTR_VALUE_MASK 0x000003ff
|
#define PCI_LTR_VALUE_MASK 0x000003ff
|
||||||
#define PCI_LTR_SCALE_MASK 0x00001c00
|
#define PCI_LTR_SCALE_MASK 0x00001c00
|
||||||
#define PCI_LTR_SCALE_SHIFT 10
|
#define PCI_LTR_SCALE_SHIFT 10
|
||||||
|
#define PCI_LTR_NOSNOOP_VALUE 0x03ff0000 /* Max No-Snoop Latency Value */
|
||||||
|
#define PCI_LTR_NOSNOOP_SCALE 0x1c000000 /* Scale for Max Value */
|
||||||
#define PCI_EXT_CAP_LTR_SIZEOF 8
|
#define PCI_EXT_CAP_LTR_SIZEOF 8
|
||||||
|
|
||||||
/* Access Control Service */
|
/* Access Control Service */
|
||||||
@@ -1042,9 +1047,16 @@
|
|||||||
#define PCI_EXP_DPC_STATUS 0x08 /* DPC Status */
|
#define PCI_EXP_DPC_STATUS 0x08 /* DPC Status */
|
||||||
#define PCI_EXP_DPC_STATUS_TRIGGER 0x0001 /* Trigger Status */
|
#define PCI_EXP_DPC_STATUS_TRIGGER 0x0001 /* Trigger Status */
|
||||||
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006 /* Trigger Reason */
|
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006 /* Trigger Reason */
|
||||||
|
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR 0x0000 /* Uncorrectable error */
|
||||||
|
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE 0x0002 /* Rcvd ERR_NONFATAL */
|
||||||
|
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE 0x0004 /* Rcvd ERR_FATAL */
|
||||||
|
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_IN_EXT 0x0006 /* Reason in Trig Reason Extension field */
|
||||||
#define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008 /* Interrupt Status */
|
#define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008 /* Interrupt Status */
|
||||||
#define PCI_EXP_DPC_RP_BUSY 0x0010 /* Root Port Busy */
|
#define PCI_EXP_DPC_RP_BUSY 0x0010 /* Root Port Busy */
|
||||||
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */
|
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */
|
||||||
|
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO 0x0000 /* RP PIO error */
|
||||||
|
#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_SW_TRIGGER 0x0020 /* DPC SW Trigger bit */
|
||||||
|
#define PCI_EXP_DPC_RP_PIO_FEP 0x1f00 /* RP PIO First Err Ptr */
|
||||||
|
|
||||||
#define PCI_EXP_DPC_SOURCE_ID 0x0A /* DPC Source Identifier */
|
#define PCI_EXP_DPC_SOURCE_ID 0x0A /* DPC Source Identifier */
|
||||||
|
|
||||||
@@ -1088,6 +1100,8 @@
|
|||||||
#define PCI_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */
|
#define PCI_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */
|
||||||
#define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */
|
#define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */
|
||||||
#define PCI_L1SS_CTL2 0x0c /* Control 2 Register */
|
#define PCI_L1SS_CTL2 0x0c /* Control 2 Register */
|
||||||
|
#define PCI_L1SS_CTL2_T_PWR_ON_SCALE 0x00000003 /* T_POWER_ON Scale */
|
||||||
|
#define PCI_L1SS_CTL2_T_PWR_ON_VALUE 0x000000f8 /* T_POWER_ON Value */
|
||||||
|
|
||||||
/* Designated Vendor-Specific (DVSEC, PCI_EXT_CAP_ID_DVSEC) */
|
/* Designated Vendor-Specific (DVSEC, PCI_EXT_CAP_ID_DVSEC) */
|
||||||
#define PCI_DVSEC_HEADER1 0x4 /* Designated Vendor-Specific Header1 */
|
#define PCI_DVSEC_HEADER1 0x4 /* Designated Vendor-Specific Header1 */
|
||||||
|
|||||||
@@ -185,5 +185,12 @@ struct vhost_vdpa_iova_range {
|
|||||||
* DRIVER_OK
|
* DRIVER_OK
|
||||||
*/
|
*/
|
||||||
#define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6
|
#define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6
|
||||||
|
/* Device may expose the virtqueue's descriptor area, driver area and
|
||||||
|
* device area to a different group for ASID binding than where its
|
||||||
|
* buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID.
|
||||||
|
*/
|
||||||
|
#define VHOST_BACKEND_F_DESC_ASID 0x7
|
||||||
|
/* IOTLB don't flush memory mapping across device reset */
|
||||||
|
#define VHOST_BACKEND_F_IOTLB_PERSIST 0x8
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
* rest are per-device feature bits.
|
* rest are per-device feature bits.
|
||||||
*/
|
*/
|
||||||
#define VIRTIO_TRANSPORT_F_START 28
|
#define VIRTIO_TRANSPORT_F_START 28
|
||||||
#define VIRTIO_TRANSPORT_F_END 41
|
#define VIRTIO_TRANSPORT_F_END 42
|
||||||
|
|
||||||
#ifndef VIRTIO_CONFIG_NO_LEGACY
|
#ifndef VIRTIO_CONFIG_NO_LEGACY
|
||||||
/* Do we get callbacks when the ring is completely used, even if we've
|
/* Do we get callbacks when the ring is completely used, even if we've
|
||||||
@@ -103,8 +103,19 @@
|
|||||||
*/
|
*/
|
||||||
#define VIRTIO_F_NOTIFICATION_DATA 38
|
#define VIRTIO_F_NOTIFICATION_DATA 38
|
||||||
|
|
||||||
|
/* This feature indicates that the driver uses the data provided by the device
|
||||||
|
* as a virtqueue identifier in available buffer notifications.
|
||||||
|
*/
|
||||||
|
#define VIRTIO_F_NOTIF_CONFIG_DATA 39
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This feature indicates that the driver can reset a queue individually.
|
* This feature indicates that the driver can reset a queue individually.
|
||||||
*/
|
*/
|
||||||
#define VIRTIO_F_RING_RESET 40
|
#define VIRTIO_F_RING_RESET 40
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This feature indicates that the device support administration virtqueues.
|
||||||
|
*/
|
||||||
|
#define VIRTIO_F_ADMIN_VQ 41
|
||||||
|
|
||||||
#endif /* _LINUX_VIRTIO_CONFIG_H */
|
#endif /* _LINUX_VIRTIO_CONFIG_H */
|
||||||
|
|||||||
@@ -166,6 +166,20 @@ struct virtio_pci_common_cfg {
|
|||||||
uint32_t queue_used_hi; /* read-write */
|
uint32_t queue_used_hi; /* read-write */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Warning: do not use sizeof on this: use offsetofend for
|
||||||
|
* specific fields you need.
|
||||||
|
*/
|
||||||
|
struct virtio_pci_modern_common_cfg {
|
||||||
|
struct virtio_pci_common_cfg cfg;
|
||||||
|
|
||||||
|
uint16_t queue_notify_data; /* read-write */
|
||||||
|
uint16_t queue_reset; /* read-write */
|
||||||
|
|
||||||
|
uint16_t admin_queue_index; /* read-only */
|
||||||
|
uint16_t admin_queue_num; /* read-only */
|
||||||
|
};
|
||||||
|
|
||||||
/* Fields in VIRTIO_PCI_CAP_PCI_CFG: */
|
/* Fields in VIRTIO_PCI_CAP_PCI_CFG: */
|
||||||
struct virtio_pci_cfg_cap {
|
struct virtio_pci_cfg_cap {
|
||||||
struct virtio_pci_cap cap;
|
struct virtio_pci_cap cap;
|
||||||
@@ -204,7 +218,72 @@ struct virtio_pci_cfg_cap {
|
|||||||
#define VIRTIO_PCI_COMMON_Q_USEDHI 52
|
#define VIRTIO_PCI_COMMON_Q_USEDHI 52
|
||||||
#define VIRTIO_PCI_COMMON_Q_NDATA 56
|
#define VIRTIO_PCI_COMMON_Q_NDATA 56
|
||||||
#define VIRTIO_PCI_COMMON_Q_RESET 58
|
#define VIRTIO_PCI_COMMON_Q_RESET 58
|
||||||
|
#define VIRTIO_PCI_COMMON_ADM_Q_IDX 60
|
||||||
|
#define VIRTIO_PCI_COMMON_ADM_Q_NUM 62
|
||||||
|
|
||||||
#endif /* VIRTIO_PCI_NO_MODERN */
|
#endif /* VIRTIO_PCI_NO_MODERN */
|
||||||
|
|
||||||
|
/* Admin command status. */
|
||||||
|
#define VIRTIO_ADMIN_STATUS_OK 0
|
||||||
|
|
||||||
|
/* Admin command opcode. */
|
||||||
|
#define VIRTIO_ADMIN_CMD_LIST_QUERY 0x0
|
||||||
|
#define VIRTIO_ADMIN_CMD_LIST_USE 0x1
|
||||||
|
|
||||||
|
/* Admin command group type. */
|
||||||
|
#define VIRTIO_ADMIN_GROUP_TYPE_SRIOV 0x1
|
||||||
|
|
||||||
|
/* Transitional device admin command. */
|
||||||
|
#define VIRTIO_ADMIN_CMD_LEGACY_COMMON_CFG_WRITE 0x2
|
||||||
|
#define VIRTIO_ADMIN_CMD_LEGACY_COMMON_CFG_READ 0x3
|
||||||
|
#define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_WRITE 0x4
|
||||||
|
#define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ 0x5
|
||||||
|
#define VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO 0x6
|
||||||
|
|
||||||
|
struct QEMU_PACKED virtio_admin_cmd_hdr {
|
||||||
|
uint16_t opcode;
|
||||||
|
/*
|
||||||
|
* 1 - SR-IOV
|
||||||
|
* 2-65535 - reserved
|
||||||
|
*/
|
||||||
|
uint16_t group_type;
|
||||||
|
/* Unused, reserved for future extensions. */
|
||||||
|
uint8_t reserved1[12];
|
||||||
|
uint64_t group_member_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QEMU_PACKED virtio_admin_cmd_status {
|
||||||
|
uint16_t status;
|
||||||
|
uint16_t status_qualifier;
|
||||||
|
/* Unused, reserved for future extensions. */
|
||||||
|
uint8_t reserved2[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QEMU_PACKED virtio_admin_cmd_legacy_wr_data {
|
||||||
|
uint8_t offset; /* Starting offset of the register(s) to write. */
|
||||||
|
uint8_t reserved[7];
|
||||||
|
uint8_t registers[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QEMU_PACKED virtio_admin_cmd_legacy_rd_data {
|
||||||
|
uint8_t offset; /* Starting offset of the register(s) to read. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_END 0
|
||||||
|
#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_OWNER_DEV 0x1
|
||||||
|
#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_OWNER_MEM 0x2
|
||||||
|
|
||||||
|
#define VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO 4
|
||||||
|
|
||||||
|
struct QEMU_PACKED virtio_admin_cmd_notify_info_data {
|
||||||
|
uint8_t flags; /* 0 = end of list, 1 = owner device, 2 = member device */
|
||||||
|
uint8_t bar; /* BAR of the member or the owner device */
|
||||||
|
uint8_t padding[6];
|
||||||
|
uint64_t offset; /* Offset within bar. */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct virtio_admin_cmd_notify_info_result {
|
||||||
|
struct virtio_admin_cmd_notify_info_data entries[VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO];
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,6 +14,13 @@
|
|||||||
#include "standard-headers/linux/virtio_ids.h"
|
#include "standard-headers/linux/virtio_ids.h"
|
||||||
#include "standard-headers/linux/virtio_config.h"
|
#include "standard-headers/linux/virtio_config.h"
|
||||||
|
|
||||||
|
/* Feature bits */
|
||||||
|
/* guest physical address range will be indicated as shared memory region 0 */
|
||||||
|
#define VIRTIO_PMEM_F_SHMEM_REGION 0
|
||||||
|
|
||||||
|
/* shmid of the shared memory region corresponding to the pmem */
|
||||||
|
#define VIRTIO_PMEM_SHMEM_REGION_ID 0
|
||||||
|
|
||||||
struct virtio_pmem_config {
|
struct virtio_pmem_config {
|
||||||
uint64_t start;
|
uint64_t start;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
|||||||
198
include/standard-headers/uefi/uefi.h
Normal file
198
include/standard-headers/uefi/uefi.h
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Intel Corporation
|
||||||
|
*
|
||||||
|
* Author: Isaku Yamahata <isaku.yamahata at gmail.com>
|
||||||
|
* <isaku.yamahata at intel.com>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HW_I386_UEFI_H
|
||||||
|
#define HW_I386_UEFI_H
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*
|
||||||
|
* basic EFI definitions
|
||||||
|
* supplemented with UEFI Specification Version 2.8 (Errata A)
|
||||||
|
* released February 2020
|
||||||
|
*/
|
||||||
|
/* UEFI integer is little endian */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t Data1;
|
||||||
|
uint16_t Data2;
|
||||||
|
uint16_t Data3;
|
||||||
|
uint8_t Data4[8];
|
||||||
|
} EFI_GUID;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EfiReservedMemoryType,
|
||||||
|
EfiLoaderCode,
|
||||||
|
EfiLoaderData,
|
||||||
|
EfiBootServicesCode,
|
||||||
|
EfiBootServicesData,
|
||||||
|
EfiRuntimeServicesCode,
|
||||||
|
EfiRuntimeServicesData,
|
||||||
|
EfiConventionalMemory,
|
||||||
|
EfiUnusableMemory,
|
||||||
|
EfiACPIReclaimMemory,
|
||||||
|
EfiACPIMemoryNVS,
|
||||||
|
EfiMemoryMappedIO,
|
||||||
|
EfiMemoryMappedIOPortSpace,
|
||||||
|
EfiPalCode,
|
||||||
|
EfiPersistentMemory,
|
||||||
|
EfiUnacceptedMemoryType,
|
||||||
|
EfiMaxMemoryType
|
||||||
|
} EFI_MEMORY_TYPE;
|
||||||
|
|
||||||
|
#define EFI_HOB_HANDOFF_TABLE_VERSION 0x0009
|
||||||
|
|
||||||
|
#define EFI_HOB_TYPE_HANDOFF 0x0001
|
||||||
|
#define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
|
||||||
|
#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
|
||||||
|
#define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
|
||||||
|
#define EFI_HOB_TYPE_FV 0x0005
|
||||||
|
#define EFI_HOB_TYPE_CPU 0x0006
|
||||||
|
#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
|
||||||
|
#define EFI_HOB_TYPE_FV2 0x0009
|
||||||
|
#define EFI_HOB_TYPE_LOAD_PEIM_UNUSED 0x000A
|
||||||
|
#define EFI_HOB_TYPE_UEFI_CAPSULE 0x000B
|
||||||
|
#define EFI_HOB_TYPE_FV3 0x000C
|
||||||
|
#define EFI_HOB_TYPE_UNUSED 0xFFFE
|
||||||
|
#define EFI_HOB_TYPE_END_OF_HOB_LIST 0xFFFF
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t HobType;
|
||||||
|
uint16_t HobLength;
|
||||||
|
uint32_t Reserved;
|
||||||
|
} EFI_HOB_GENERIC_HEADER;
|
||||||
|
|
||||||
|
typedef uint64_t EFI_PHYSICAL_ADDRESS;
|
||||||
|
typedef uint32_t EFI_BOOT_MODE;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
uint32_t Version;
|
||||||
|
EFI_BOOT_MODE BootMode;
|
||||||
|
EFI_PHYSICAL_ADDRESS EfiMemoryTop;
|
||||||
|
EFI_PHYSICAL_ADDRESS EfiMemoryBottom;
|
||||||
|
EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop;
|
||||||
|
EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom;
|
||||||
|
EFI_PHYSICAL_ADDRESS EfiEndOfHobList;
|
||||||
|
} EFI_HOB_HANDOFF_INFO_TABLE;
|
||||||
|
|
||||||
|
#define EFI_RESOURCE_SYSTEM_MEMORY 0x00000000
|
||||||
|
#define EFI_RESOURCE_MEMORY_MAPPED_IO 0x00000001
|
||||||
|
#define EFI_RESOURCE_IO 0x00000002
|
||||||
|
#define EFI_RESOURCE_FIRMWARE_DEVICE 0x00000003
|
||||||
|
#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004
|
||||||
|
#define EFI_RESOURCE_MEMORY_RESERVED 0x00000005
|
||||||
|
#define EFI_RESOURCE_IO_RESERVED 0x00000006
|
||||||
|
#define EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
|
||||||
|
#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008
|
||||||
|
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_PRESENT 0x00000001
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_INITIALIZED 0x00000002
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_TESTED 0x00000004
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC 0x00000008
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC 0x00000010
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 0x00000020
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 0x00000040
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED 0x00000080
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED 0x00000100
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED 0x00000200
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE 0x00000400
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE 0x00000800
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE 0x00001000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 0x00002000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO 0x00004000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO 0x00008000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO 0x00010000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED 0x00020000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED 0x00040000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00080000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE 0x00100000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE 0x00200000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE 0x00400000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_PERSISTENT 0x00800000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE 0x01000000
|
||||||
|
#define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE 0x02000000
|
||||||
|
|
||||||
|
typedef uint32_t EFI_RESOURCE_TYPE;
|
||||||
|
typedef uint32_t EFI_RESOURCE_ATTRIBUTE_TYPE;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
EFI_GUID Owner;
|
||||||
|
EFI_RESOURCE_TYPE ResourceType;
|
||||||
|
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
|
||||||
|
EFI_PHYSICAL_ADDRESS PhysicalStart;
|
||||||
|
uint64_t ResourceLength;
|
||||||
|
} EFI_HOB_RESOURCE_DESCRIPTOR;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
EFI_GUID Name;
|
||||||
|
|
||||||
|
/* guid specific data follows */
|
||||||
|
} EFI_HOB_GUID_TYPE;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||||
|
uint64_t Length;
|
||||||
|
} EFI_HOB_FIRMWARE_VOLUME;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||||
|
uint64_t Length;
|
||||||
|
EFI_GUID FvName;
|
||||||
|
EFI_GUID FileName;
|
||||||
|
} EFI_HOB_FIRMWARE_VOLUME2;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||||
|
uint64_t Length;
|
||||||
|
uint32_t AuthenticationStatus;
|
||||||
|
bool ExtractedFv;
|
||||||
|
EFI_GUID FvName;
|
||||||
|
EFI_GUID FileName;
|
||||||
|
} EFI_HOB_FIRMWARE_VOLUME3;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
uint8_t SizeOfMemorySpace;
|
||||||
|
uint8_t SizeOfIoSpace;
|
||||||
|
uint8_t Reserved[6];
|
||||||
|
} EFI_HOB_CPU;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
} EFI_HOB_MEMORY_POOL;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_HOB_GENERIC_HEADER Header;
|
||||||
|
|
||||||
|
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||||
|
uint64_t Length;
|
||||||
|
} EFI_HOB_UEFI_CAPSULE;
|
||||||
|
|
||||||
|
#define EFI_HOB_OWNER_ZERO \
|
||||||
|
((EFI_GUID){ 0x00000000, 0x0000, 0x0000, \
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } })
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -47,7 +47,15 @@ OBJECT_DECLARE_TYPE(HostMemoryBackend, HostMemoryBackendClass,
|
|||||||
struct HostMemoryBackendClass {
|
struct HostMemoryBackendClass {
|
||||||
ObjectClass parent_class;
|
ObjectClass parent_class;
|
||||||
|
|
||||||
void (*alloc)(HostMemoryBackend *backend, Error **errp);
|
/**
|
||||||
|
* alloc: Allocate memory from backend.
|
||||||
|
*
|
||||||
|
* @backend: the #HostMemoryBackend.
|
||||||
|
* @errp: pointer to Error*, to store an error if it happens.
|
||||||
|
*
|
||||||
|
* Return: true on success, else false setting @errp with error.
|
||||||
|
*/
|
||||||
|
bool (*alloc)(HostMemoryBackend *backend, Error **errp);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +74,7 @@ struct HostMemoryBackend {
|
|||||||
uint64_t size;
|
uint64_t size;
|
||||||
bool merge, dump, use_canonical_path;
|
bool merge, dump, use_canonical_path;
|
||||||
bool prealloc, is_mapped, share, reserve;
|
bool prealloc, is_mapped, share, reserve;
|
||||||
|
bool guest_memfd;
|
||||||
uint32_t prealloc_threads;
|
uint32_t prealloc_threads;
|
||||||
ThreadContext *prealloc_context;
|
ThreadContext *prealloc_context;
|
||||||
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
|
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
|
||||||
|
|||||||
@@ -341,6 +341,7 @@ int kvm_arch_get_default_type(MachineState *ms);
|
|||||||
|
|
||||||
int kvm_arch_init(MachineState *ms, KVMState *s);
|
int kvm_arch_init(MachineState *ms, KVMState *s);
|
||||||
|
|
||||||
|
int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp);
|
||||||
int kvm_arch_init_vcpu(CPUState *cpu);
|
int kvm_arch_init_vcpu(CPUState *cpu);
|
||||||
int kvm_arch_destroy_vcpu(CPUState *cpu);
|
int kvm_arch_destroy_vcpu(CPUState *cpu);
|
||||||
|
|
||||||
@@ -538,4 +539,17 @@ bool kvm_arch_cpu_check_are_resettable(void);
|
|||||||
bool kvm_dirty_ring_enabled(void);
|
bool kvm_dirty_ring_enabled(void);
|
||||||
|
|
||||||
uint32_t kvm_dirty_ring_size(void);
|
uint32_t kvm_dirty_ring_size(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kvm_hwpoisoned_mem - indicate if there is any hwpoisoned page
|
||||||
|
* reported for the VM.
|
||||||
|
*/
|
||||||
|
bool kvm_hwpoisoned_mem(void);
|
||||||
|
|
||||||
|
int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp);
|
||||||
|
|
||||||
|
int kvm_set_memory_attributes_private(hwaddr start, hwaddr size);
|
||||||
|
int kvm_set_memory_attributes_shared(hwaddr start, hwaddr size);
|
||||||
|
|
||||||
|
int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ typedef struct KVMSlot
|
|||||||
int as_id;
|
int as_id;
|
||||||
/* Cache of the offset in ram address space */
|
/* Cache of the offset in ram address space */
|
||||||
ram_addr_t ram_start_offset;
|
ram_addr_t ram_start_offset;
|
||||||
|
int guest_memfd;
|
||||||
|
hwaddr guest_memfd_offset;
|
||||||
} KVMSlot;
|
} KVMSlot;
|
||||||
|
|
||||||
typedef struct KVMMemoryUpdate {
|
typedef struct KVMMemoryUpdate {
|
||||||
|
|||||||
@@ -491,6 +491,38 @@ struct kvm_smccc_filter {
|
|||||||
#define KVM_HYPERCALL_EXIT_SMC (1U << 0)
|
#define KVM_HYPERCALL_EXIT_SMC (1U << 0)
|
||||||
#define KVM_HYPERCALL_EXIT_16BIT (1U << 1)
|
#define KVM_HYPERCALL_EXIT_16BIT (1U << 1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get feature ID registers userspace writable mask.
|
||||||
|
*
|
||||||
|
* From DDI0487J.a, D19.2.66 ("ID_AA64MMFR2_EL1, AArch64 Memory Model
|
||||||
|
* Feature Register 2"):
|
||||||
|
*
|
||||||
|
* "The Feature ID space is defined as the System register space in
|
||||||
|
* AArch64 with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7},
|
||||||
|
* op2=={0-7}."
|
||||||
|
*
|
||||||
|
* This covers all currently known R/O registers that indicate
|
||||||
|
* anything useful feature wise, including the ID registers.
|
||||||
|
*
|
||||||
|
* If we ever need to introduce a new range, it will be described as
|
||||||
|
* such in the range field.
|
||||||
|
*/
|
||||||
|
#define KVM_ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2) \
|
||||||
|
({ \
|
||||||
|
__u64 __op1 = (op1) & 3; \
|
||||||
|
__op1 -= (__op1 == 3); \
|
||||||
|
(__op1 << 6 | ((crm) & 7) << 3 | (op2)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define KVM_ARM_FEATURE_ID_RANGE 0
|
||||||
|
#define KVM_ARM_FEATURE_ID_RANGE_SIZE (3 * 8 * 8)
|
||||||
|
|
||||||
|
struct reg_mask_range {
|
||||||
|
__u64 addr; /* Pointer to mask array */
|
||||||
|
__u32 range; /* Requested range */
|
||||||
|
__u32 reserved[13];
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ARM_KVM_H__ */
|
#endif /* __ARM_KVM_H__ */
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ __SYSCALL(__NR_fremovexattr, sys_fremovexattr)
|
|||||||
#define __NR_getcwd 17
|
#define __NR_getcwd 17
|
||||||
__SYSCALL(__NR_getcwd, sys_getcwd)
|
__SYSCALL(__NR_getcwd, sys_getcwd)
|
||||||
#define __NR_lookup_dcookie 18
|
#define __NR_lookup_dcookie 18
|
||||||
__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
|
__SYSCALL(__NR_lookup_dcookie, sys_ni_syscall)
|
||||||
#define __NR_eventfd2 19
|
#define __NR_eventfd2 19
|
||||||
__SYSCALL(__NR_eventfd2, sys_eventfd2)
|
__SYSCALL(__NR_eventfd2, sys_eventfd2)
|
||||||
#define __NR_epoll_create1 20
|
#define __NR_epoll_create1 20
|
||||||
@@ -816,15 +816,34 @@ __SYSCALL(__NR_process_mrelease, sys_process_mrelease)
|
|||||||
__SYSCALL(__NR_futex_waitv, sys_futex_waitv)
|
__SYSCALL(__NR_futex_waitv, sys_futex_waitv)
|
||||||
#define __NR_set_mempolicy_home_node 450
|
#define __NR_set_mempolicy_home_node 450
|
||||||
__SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node)
|
__SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node)
|
||||||
|
|
||||||
#define __NR_cachestat 451
|
#define __NR_cachestat 451
|
||||||
__SYSCALL(__NR_cachestat, sys_cachestat)
|
__SYSCALL(__NR_cachestat, sys_cachestat)
|
||||||
|
|
||||||
#define __NR_fchmodat2 452
|
#define __NR_fchmodat2 452
|
||||||
__SYSCALL(__NR_fchmodat2, sys_fchmodat2)
|
__SYSCALL(__NR_fchmodat2, sys_fchmodat2)
|
||||||
|
#define __NR_map_shadow_stack 453
|
||||||
|
__SYSCALL(__NR_map_shadow_stack, sys_map_shadow_stack)
|
||||||
|
#define __NR_futex_wake 454
|
||||||
|
__SYSCALL(__NR_futex_wake, sys_futex_wake)
|
||||||
|
#define __NR_futex_wait 455
|
||||||
|
__SYSCALL(__NR_futex_wait, sys_futex_wait)
|
||||||
|
#define __NR_futex_requeue 456
|
||||||
|
__SYSCALL(__NR_futex_requeue, sys_futex_requeue)
|
||||||
|
|
||||||
|
#define __NR_statmount 457
|
||||||
|
__SYSCALL(__NR_statmount, sys_statmount)
|
||||||
|
|
||||||
|
#define __NR_listmount 458
|
||||||
|
__SYSCALL(__NR_listmount, sys_listmount)
|
||||||
|
|
||||||
|
#define __NR_lsm_get_self_attr 459
|
||||||
|
__SYSCALL(__NR_lsm_get_self_attr, sys_lsm_get_self_attr)
|
||||||
|
#define __NR_lsm_set_self_attr 460
|
||||||
|
__SYSCALL(__NR_lsm_set_self_attr, sys_lsm_set_self_attr)
|
||||||
|
#define __NR_lsm_list_modules 461
|
||||||
|
__SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules)
|
||||||
|
|
||||||
#undef __NR_syscalls
|
#undef __NR_syscalls
|
||||||
#define __NR_syscalls 453
|
#define __NR_syscalls 462
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 32 bit systems traditionally used different
|
* 32 bit systems traditionally used different
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user