hw/i386/fw_cfg.c | 6 ++++++
target/i386/sev.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
target/i386/sev.h | 2 ++
3 files changed, 57 insertions(+)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index a283785a8d..9c069ddebe 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -23,6 +23,7 @@
#include "e820_memory_layout.h"
#include "kvm/kvm_i386.h"
#include "qapi/error.h"
+#include "target/i386/sev.h"
#include CONFIG_DEVICES
struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
@@ -131,6 +132,11 @@ FWCfgState *fw_cfg_arch_create(MachineState *ms,
&e820_reserve, sizeof(e820_reserve));
fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
sizeof(struct e820_entry) * e820_get_num_entries());
+ if (sev_has_accept_all_memory(ms->cgs)) {
+ bool accept_all = sev_accept_all_memory(ms->cgs);
+ fw_cfg_add_file(fw_cfg, "opt/ovmf/AcceptAllMemory",
+ &accept_all, sizeof(accept_all));
+ }
fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, &hpet_cfg, sizeof(hpet_cfg));
/* allocate memory for the NUMA channel: one (64bit) word for the number
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 32f7dbac4e..01399a304c 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -64,6 +64,7 @@ struct SevGuestState {
uint32_t cbitpos;
uint32_t reduced_phys_bits;
bool kernel_hashes;
+ int accept_all_memory;
/* runtime state */
uint32_t handle;
@@ -155,6 +156,15 @@ static const char *const sev_fw_errlist[] = {
[SEV_RET_SECURE_DATA_INVALID] = "Part-specific integrity check
failure",
};
+static QEnumLookup memory_acceptance_lookup = {
+ .array = (const char *const[]) {
+ "default",
+ "true",
+ "false",
+ },
+ .size = 3,
+};
+
#define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
static int
@@ -353,6 +363,21 @@ static void sev_guest_set_kernel_hashes(Object *obj, bool
value, Error **errp)
sev->kernel_hashes = value;
}
+static int sev_guest_get_accept_all_memory(Object *obj, Error **errp)
+{
+ SevGuestState *sev = SEV_GUEST(obj);
+
+ return sev->accept_all_memory;
+}
+
+static void
+sev_guest_set_accept_all_memory(Object *obj, int value, Error **errp)
+{
+ SevGuestState *sev = SEV_GUEST(obj);
+
+ sev->accept_all_memory = value;
+}
+
static void
sev_guest_class_init(ObjectClass *oc, void *data)
{
@@ -376,6 +401,14 @@ sev_guest_class_init(ObjectClass *oc, void *data)
sev_guest_set_kernel_hashes);
object_class_property_set_description(oc, "kernel-hashes",
"add kernel hashes to guest firmware for measured Linux boot");
+ object_class_property_add_enum(oc, "accept-all-memory",
+ "MemoryAcceptance",
+ &memory_acceptance_lookup,
+ sev_guest_get_accept_all_memory, sev_guest_set_accept_all_memory);
+ object_class_property_set_description(
+ oc, "accept-all-memory",
+ "false: Accept all memory, true: Accept up to 4G and leave the rest
unaccepted (UEFI"
+ " v2.9 memory type), default: default firmware behavior.");
}
static void
@@ -906,6 +939,22 @@ sev_vm_state_change(void *opaque, bool running, RunState
state)
}
}
+int sev_has_accept_all_memory(ConfidentialGuestSupport *cgs)
+{
+ SevGuestState *sev
+ = (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST);
+
+ return sev && sev->accept_all_memory != 0;
+}
+
+int sev_accept_all_memory(ConfidentialGuestSupport *cgs)
+{
+ SevGuestState *sev
+ = (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST);
+
+ return sev && sev->accept_all_memory == 1;
+}
+
int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
{
SevGuestState *sev
diff --git a/target/i386/sev.h b/target/i386/sev.h
index 7b1528248a..d61b6e9443 100644
--- a/target/i386/sev.h
+++ b/target/i386/sev.h
@@ -58,5 +58,7 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t
flash_size);
void sev_es_set_reset_vector(CPUState *cpu);
int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp);
+int sev_has_accept_all_memory(ConfidentialGuestSupport *cgs);
+int sev_accept_all_memory(ConfidentialGuestSupport *cgs);
#endif