Page MenuHomeFreeBSD

D36990.id111789.diff
No OneTemporary

D36990.id111789.diff

diff --git a/usr.sbin/bhyve/basl.h b/usr.sbin/bhyve/basl.h
--- a/usr.sbin/bhyve/basl.h
+++ b/usr.sbin/bhyve/basl.h
@@ -21,6 +21,8 @@
#define BASL_TABLE_ALIGNMENT 0x10
#define BASL_TABLE_ALIGNMENT_FACS 0x40
+#define BASL_TABLE_CHECKSUM_LEN_FULL_TABLE (-1)
+
#define BASL_EXEC(x) \
do { \
const int error = (x); \
@@ -40,6 +42,8 @@
int basl_init();
int basl_table_append_bytes(struct basl_table *table, const void *bytes,
uint32_t len);
+int basl_table_append_checksum(struct basl_table *table, uint32_t start,
+ uint32_t len);
int basl_table_append_gas(struct basl_table *table, uint8_t space_id,
uint8_t bit_width, uint8_t bit_offset, uint8_t access_width,
uint64_t address);
diff --git a/usr.sbin/bhyve/basl.c b/usr.sbin/bhyve/basl.c
--- a/usr.sbin/bhyve/basl.c
+++ b/usr.sbin/bhyve/basl.c
@@ -36,6 +36,16 @@
STAILQ_HEAD(basl_table_list, basl_table) basl_tables = STAILQ_HEAD_INITIALIZER(
basl_tables);
+struct basl_table_checksum {
+ STAILQ_ENTRY(basl_table_checksum) chain;
+ struct basl_table *table;
+ uint32_t off;
+ uint32_t start;
+ uint32_t len;
+};
+STAILQ_HEAD(basl_table_checksum_list, basl_table_checksum) basl_checksums =
+ STAILQ_HEAD_INITIALIZER(basl_checksums);
+
struct basl_table_length {
STAILQ_ENTRY(basl_table_length) chain;
struct basl_table *table;
@@ -130,6 +140,57 @@
return (0);
}
+static int
+basl_finish_patch_checksums()
+{
+ struct basl_table_checksum *checksum;
+ STAILQ_FOREACH (checksum, &basl_checksums, chain) {
+ const struct basl_table *const table = checksum->table;
+
+ uint32_t len = checksum->len;
+ if (len == BASL_TABLE_CHECKSUM_LEN_FULL_TABLE) {
+ len = table->len;
+ }
+
+ /*
+ * Guest bios versions without qemu fwcfg support search for
+ * ACPI tables in the guest memory and install them as is.
+ * Therefore, patch the checksum in the guest memory copies to a
+ * correct value.
+ */
+ const uint64_t gpa = BHYVE_ACPI_BASE + table->off +
+ checksum->start;
+ if ((gpa < BHYVE_ACPI_BASE) ||
+ (gpa < BHYVE_ACPI_BASE + table->off)) {
+ warnx("%s: invalid gpa (off 0x%8x start 0x%8x)",
+ __func__, table->off, checksum->start);
+ return (EFAULT);
+ }
+
+ uint8_t *const gva = (uint8_t *)vm_map_gpa(table->ctx, gpa,
+ len);
+ if (gva == NULL) {
+ warnx("%s: could not map gpa [ 0x%16lx, 0x%16lx ]",
+ __func__, gpa, gpa + len);
+ return (ENOMEM);
+ }
+ uint8_t *const checksum_gva = gva + checksum->off;
+ if (checksum_gva < gva) {
+ warnx("%s: invalid checksum offset 0x%8x", __func__,
+ checksum->off);
+ return (EFAULT);
+ }
+
+ uint8_t sum = 0;
+ for (uint32_t i = 0; i < len; ++i) {
+ sum += *(gva + i);
+ }
+ *checksum_gva = -sum;
+ }
+
+ return (0);
+}
+
static int
basl_finish_set_length()
{
@@ -155,6 +216,7 @@
BASL_EXEC(basl_finish_set_length());
BASL_EXEC(basl_finish_alloc());
+ BASL_EXEC(basl_finish_patch_checksums());
return (0);
}
@@ -165,6 +227,27 @@
return (0);
}
+static int
+basl_table_add_checksum(struct basl_table *const table, const uint32_t off,
+ const uint32_t start, const uint32_t len)
+{
+ struct basl_table_checksum *const checksum = calloc(1,
+ sizeof(struct basl_table_checksum));
+ if (checksum == NULL) {
+ warnx("%s: failed to allocate checksum", __func__);
+ return (ENOMEM);
+ }
+
+ checksum->table = table;
+ checksum->off = off;
+ checksum->start = start;
+ checksum->len = len;
+
+ STAILQ_INSERT_TAIL(&basl_checksums, checksum, chain);
+
+ return (0);
+}
+
static int
basl_table_add_length(struct basl_table *const table, const uint32_t off,
const uint8_t size)
@@ -213,6 +296,20 @@
return (0);
}
+int
+basl_table_append_checksum(struct basl_table *const table, const uint32_t start,
+ const uint32_t len)
+{
+ if (table == NULL) {
+ return (EINVAL);
+ }
+
+ BASL_EXEC(basl_table_add_checksum(table, table->len, start, len));
+ BASL_EXEC(basl_table_append_int(table, 0, 1));
+
+ return (0);
+}
+
int
basl_table_append_gas(struct basl_table *const table, const uint8_t space_id,
const uint8_t bit_width, const uint8_t bit_offset,

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 27, 2:06 AM (11 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26239305
Default Alt Text
D36990.id111789.diff (4 KB)

Event Timeline