@@ -5,6 +5,7 @@
#include "kvm/util.h"
#include <string.h>
+#include <asm/e820.h>
#include "bios/bios-rom.h"
@@ -54,50 +55,50 @@ static void setup_irq_handler(struct kvm *kvm, struct irq_handler *handler)
*/
static void e820_setup(struct kvm *kvm)
{
- struct e820_entry *mem_map;
- unsigned char *size;
+ struct e820map *e820;
+ struct e820entry *mem_map;
unsigned int i = 0;
- size = guest_flat_to_host(kvm, E820_MAP_SIZE);
- mem_map = guest_flat_to_host(kvm, E820_MAP_START);
+ e820 = guest_flat_to_host(kvm, E820_MAP_START);
+ mem_map = e820->map;
- mem_map[i++] = (struct e820_entry) {
+ mem_map[i++] = (struct e820entry) {
.addr = REAL_MODE_IVT_BEGIN,
.size = EBDA_START - REAL_MODE_IVT_BEGIN,
- .type = E820_MEM_USABLE,
+ .type = E820_RAM,
};
- mem_map[i++] = (struct e820_entry) {
+ mem_map[i++] = (struct e820entry) {
.addr = EBDA_START,
.size = VGA_RAM_BEGIN - EBDA_START,
- .type = E820_MEM_RESERVED,
+ .type = E820_RESERVED,
};
- mem_map[i++] = (struct e820_entry) {
+ mem_map[i++] = (struct e820entry) {
.addr = MB_BIOS_BEGIN,
.size = MB_BIOS_END - MB_BIOS_BEGIN,
- .type = E820_MEM_RESERVED,
+ .type = E820_RESERVED,
};
if (kvm->ram_size < KVM_32BIT_GAP_START) {
- mem_map[i++] = (struct e820_entry) {
+ mem_map[i++] = (struct e820entry) {
.addr = BZ_KERNEL_START,
.size = kvm->ram_size - BZ_KERNEL_START,
- .type = E820_MEM_USABLE,
+ .type = E820_RAM,
};
} else {
- mem_map[i++] = (struct e820_entry) {
+ mem_map[i++] = (struct e820entry) {
.addr = BZ_KERNEL_START,
.size = KVM_32BIT_GAP_START - BZ_KERNEL_START,
- .type = E820_MEM_USABLE,
+ .type = E820_RAM,
};
- mem_map[i++] = (struct e820_entry) {
+ mem_map[i++] = (struct e820entry) {
.addr = 0x100000000ULL,
.size = kvm->ram_size - KVM_32BIT_GAP_START,
- .type = E820_MEM_USABLE,
+ .type = E820_RAM,
};
}
- BUILD_BUG_ON(i > E820_MEM_AREAS);
+ BUILD_BUG_ON(i > E820_X_MAX);
- *size = i;
+ e820->nr_map = i;
}
/**
@@ -4,6 +4,8 @@
#include "kvm/bios.h"
#include "kvm/util.h"
+#include <asm/e820.h>
+
static inline void set_fs(u16 seg)
{
asm volatile("movw %0,%%fs" : : "rm" (seg));
@@ -18,37 +20,48 @@ static inline u8 rdfs8(unsigned long addr)
return v;
}
+static inline u32 rdfs32(unsigned long addr)
+{
+ u32 v;
+
+ asm volatile("addr32 movl %%fs:%1,%0" : "=q" (v) : "m" (*(u32 *)addr));
+
+ return v;
+}
+
bioscall void e820_query_map(struct e820_query *query)
{
- u8 map_size;
+ struct e820map *e820;
+ u32 map_size;
u16 fs_seg;
u32 ndx;
- fs_seg = flat_to_seg16(E820_MAP_SIZE);
+ e820 = (struct e820map *)E820_MAP_START;
+ fs_seg = flat_to_seg16(E820_MAP_START);
set_fs(fs_seg);
ndx = query->ebx;
- map_size = rdfs8(flat_to_off16(E820_MAP_SIZE, fs_seg));
+ map_size = rdfs32(flat_to_off16((u32)&e820->nr_map, fs_seg));
if (ndx < map_size) {
- unsigned long start;
+ u32 start;
unsigned int i;
u8 *p;
- fs_seg = flat_to_seg16(E820_MAP_START);
+ fs_seg = flat_to_seg16(E820_MAP_START);
set_fs(fs_seg);
- start = E820_MAP_START + sizeof(struct e820_entry) * ndx;
+ start = (u32)&e820->map[ndx];
p = (void *) query->edi;
- for (i = 0; i < sizeof(struct e820_entry); i++)
+ for (i = 0; i < sizeof(struct e820entry); i++)
*p++ = rdfs8(flat_to_off16(start + i, fs_seg));
}
query->eax = SMAP;
- query->ecx = sizeof(struct e820_entry);
+ query->ecx = sizeof(struct e820entry);
query->ebx = ++ndx;
if (ndx >= map_size)
@@ -24,8 +24,7 @@
#define EBDA_START 0x0009fc00
#define EBDA_END 0x0009ffff
-#define E820_MAP_SIZE EBDA_START
-#define E820_MAP_START (EBDA_START + 0x01)
+#define E820_MAP_START EBDA_START
#define MB_BIOS_BEGIN 0x000f0000
#define MB_BIOS_END 0x000fffff
@@ -5,17 +5,6 @@
#define SMAP 0x534d4150 /* ASCII "SMAP" */
-#define E820_MEM_USABLE 1
-#define E820_MEM_RESERVED 2
-
-#define E820_MEM_AREAS 5
-
-struct e820_entry {
- u64 addr; /* start of memory segment */
- u64 size; /* size of memory segment */
- u32 type; /* type of memory segment */
-} __attribute__((packed));
-
struct e820_query {
u32 eax;
u32 ebx;
Several cleanups in the patch: - Use kernel headers for e820 types and definitions. - A byte sized entry count for e820 enteries was used, this should be dword sized. Update in-memory layout and bios code to fix it. - Use struct e820map to calculate offsets used by bios code. Signed-off-by: Sasha Levin <levinsasha928@gmail.com> --- tools/kvm/bios.c | 37 +++++++++++++++++++------------------ tools/kvm/bios/e820.c | 29 +++++++++++++++++++++-------- tools/kvm/include/kvm/bios.h | 3 +-- tools/kvm/include/kvm/e820.h | 11 ----------- 4 files changed, 41 insertions(+), 39 deletions(-)