QEMU e820 reservation patch
Hi, Kevin and I have agreed on the approach for this one now. So here is the latest version of the patch for QEMU, submitting e820 reservation entries via fw_cfg. Cheers, Jes Use qemu-cfg to provide the BIOS with an optional table of e820 entries. Notify the BIOS of the location of the TSS+EPT range to by reserving it via the e820 table. This matches a corresponding patch for Seabios, however older versions of Seabios will default to the hardcoded address range and stay compatible with current QEMU. Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									ed487bb1d6
								
							
						
					
					
						commit
						4c5b10b7b6
					
				
							
								
								
									
										35
									
								
								hw/pc.c
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								hw/pc.c
									
									
									
									
									
								
							@ -59,6 +59,7 @@
 | 
			
		||||
#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
 | 
			
		||||
#define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
 | 
			
		||||
#define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2)
 | 
			
		||||
#define FW_CFG_E820_TABLE (FW_CFG_ARCH_LOCAL + 3)
 | 
			
		||||
 | 
			
		||||
#define MAX_IDE_BUS 2
 | 
			
		||||
 | 
			
		||||
@ -67,6 +68,21 @@ static RTCState *rtc_state;
 | 
			
		||||
static PITState *pit;
 | 
			
		||||
static PCII440FXState *i440fx_state;
 | 
			
		||||
 | 
			
		||||
#define E820_NR_ENTRIES		16
 | 
			
		||||
 | 
			
		||||
struct e820_entry {
 | 
			
		||||
    uint64_t address;
 | 
			
		||||
    uint64_t length;
 | 
			
		||||
    uint32_t type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct e820_table {
 | 
			
		||||
    uint32_t count;
 | 
			
		||||
    struct e820_entry entry[E820_NR_ENTRIES];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct e820_table e820_table;
 | 
			
		||||
 | 
			
		||||
typedef struct isa_irq_state {
 | 
			
		||||
    qemu_irq *i8259;
 | 
			
		||||
    qemu_irq *ioapic;
 | 
			
		||||
@ -435,6 +451,23 @@ static void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
 | 
			
		||||
{
 | 
			
		||||
    int index = e820_table.count;
 | 
			
		||||
    struct e820_entry *entry;
 | 
			
		||||
 | 
			
		||||
    if (index >= E820_NR_ENTRIES)
 | 
			
		||||
        return -EBUSY;
 | 
			
		||||
    entry = &e820_table.entry[index];
 | 
			
		||||
 | 
			
		||||
    entry->address = address;
 | 
			
		||||
    entry->length = length;
 | 
			
		||||
    entry->type = type;
 | 
			
		||||
 | 
			
		||||
    e820_table.count++;
 | 
			
		||||
    return e820_table.count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *bochs_bios_init(void)
 | 
			
		||||
{
 | 
			
		||||
    void *fw_cfg;
 | 
			
		||||
@ -466,6 +499,8 @@ static void *bochs_bios_init(void)
 | 
			
		||||
    if (smbios_table)
 | 
			
		||||
        fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
 | 
			
		||||
                         smbios_table, smbios_len);
 | 
			
		||||
    fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, (uint8_t *)&e820_table,
 | 
			
		||||
                     sizeof(struct e820_table));
 | 
			
		||||
 | 
			
		||||
    /* allocate memory for the NUMA channel: one (64bit) word for the number
 | 
			
		||||
     * of nodes, one word for each VCPU->node and one word for each node to
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								hw/pc.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								hw/pc.h
									
									
									
									
									
								
							@ -150,4 +150,14 @@ void isa_cirrus_vga_init(void);
 | 
			
		||||
void isa_ne2000_init(int base, int irq, NICInfo *nd);
 | 
			
		||||
 | 
			
		||||
int cpu_is_bsp(CPUState *env);
 | 
			
		||||
 | 
			
		||||
/* e820 types */
 | 
			
		||||
#define E820_RAM        1
 | 
			
		||||
#define E820_RESERVED   2
 | 
			
		||||
#define E820_ACPI       3
 | 
			
		||||
#define E820_NVS        4
 | 
			
		||||
#define E820_UNUSABLE   5
 | 
			
		||||
 | 
			
		||||
int e820_add_entry(uint64_t, uint64_t, uint32_t);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@
 | 
			
		||||
#include "cpu.h"
 | 
			
		||||
#include "gdbstub.h"
 | 
			
		||||
#include "host-utils.h"
 | 
			
		||||
#include "hw/pc.h"
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_KVM_PARA
 | 
			
		||||
#include <linux/kvm_para.h>
 | 
			
		||||
@ -362,6 +363,13 @@ int kvm_arch_init(KVMState *s, int smp_cpus)
 | 
			
		||||
     * as unavaible memory.  FIXME, need to ensure the e820 map deals with
 | 
			
		||||
     * this?
 | 
			
		||||
     */
 | 
			
		||||
    /*
 | 
			
		||||
     * Tell fw_cfg to notify the BIOS to reserve the range.
 | 
			
		||||
     */
 | 
			
		||||
    if (e820_add_entry(0xfffbc000, 0x4000, E820_RESERVED) < 0) {
 | 
			
		||||
        perror("e820_add_entry() table is full");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    return kvm_vm_ioctl(s, KVM_SET_TSS_ADDR, 0xfffbd000);
 | 
			
		||||
}
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user