From mboxrd@z Thu Jan 1 00:00:00 1970 From: Keir Fraser Subject: Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM Date: Fri, 22 Jul 2011 17:38:31 +0100 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Bei Guan , Xen Devel Cc: edk2-devel@lists.sourceforge.net, Jordan Justen , Tim Deegan , Andrei Warkentin List-Id: xen-devel@lists.xenproject.org On 22/07/2011 17:23, "Bei Guan" wrote: > Hi, >=20 > My name is Bei Guan and I am one of this year's GSOS students for Tianoco= re. > My project is to enable Xen support in OVMF and the following is about my > patch for Xen-unstable. Could you give me some comments? Thank you very m= uch. >=20 > This patch can enable Xen-unstable hvmloader to load OVMF BIOS as Xen HVM= UEFI > support. It supports OVMF BIOS in IA32 and X86 environment. The loaded OV= MF > BIOS can get Xen SMBIOS and ACPI tables contents inside itself. >=20 > In order to be clear, I divide the patch into three parts: > ovmf_xen_support.patch=A0=A0 Enable Xen hvmloader to load OVMF Looks pretty decent. I wonder why you need to change get_shared_info() -- the existing mapping location is unused at the time hvmloader runs, and you instead map it over the top of a page of RAM. If you want shared_info mappe= d elsewhere, you can map it wherever you like as soon as your BIOS payload takes over. I'd also need to see what you use mem_back_ram() for, and maybe give it a better name, but I'm not against extracting that functionality into a function for the use of BIOS-specific handlers if the use is sane. -- Keir > ovmf_firmware.patch=A0=A0=A0=A0=A0=A0=A0 OVMF binary files > ovmf_xl_xend.patch=A0=A0=A0=A0=A0=A0=A0=A0 Add hvmloader/bios xenstore key in libxl and x= end >=20 > Usage: > Add an option field in HVM config file. > # OVMF support. When enabled, hvmloader can load OVMF bios of > IA32("ovmf-ia32") and X64("ovmf-x64") > hvmbios =3D "ovmf-ia32" > #hvmbios =3D "ovmf-x64" >=20 > Note: > You should enable the HVM guest ACPI: acpi=3D1 > You can use the OVMF to boot into a UEFI-aware OS, such as > ubuntu-10.10-desktop-amd64. > iso. Just set the "disk" option like this: > disk =3D [ 'file:/root/.img,ioemu:hda,w', > 'file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r' ] >=20 >=20 > ovmf_xen_support.patch: > ------ >=20 > # HG changeset patch > # User gbtju85@gmail.com > # >=20 > diff -r e298ce67777e tools/firmware/hvmloader/Makefile > --- a/tools/firmware/hvmloader/Makefile=A0=A0=A0 Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/Makefile=A0=A0=A0 Fri Jul 22 23:00:20 2011 +0800 > @@ -43,6 +43,19 @@ > =A0CFLAGS +=3D -DENABLE_ROMBIOS > =A0ROMBIOS_ROM :=3D $(ROMBIOS_DIR)/BIOS-bochs-latest > =A0endif > +OVMF_DIR :=3D=A0 ../ovmf > +OVMF32_ROM :=3D $(OVMF_DIR)/ovmf-ia32.bin > +OVMF64_ROM :=3D $(OVMF_DIR)/ovmf-x64.bin > +OVMF32_CIRRUS_VGA_ROM :=3D $(OVMF_DIR)/ovmf-ia32-cirrus-vga.bin > +OVMF64_CIRRUS_VGA_ROM :=3D $(OVMF_DIR)/ovmf-x64-cirrus-vga.bin > + > +ifneq ($(OVMF32_ROM),) > +OBJS +=3D ovmf.o > +endif > + > +ifneq ($(OVMF64_ROM),) > +OBJS +=3D ovmf.o > +endif > =A0 > =A0ifneq ($(SEABIOS_DIR),) > =A0OBJS +=3D seabios.o > @@ -69,7 +82,7 @@ > =A0=A0=A0=A0 $(OBJCOPY) hvmloader.tmp hvmloader > =A0=A0=A0=A0 rm -f hvmloader.tmp > =A0 > -roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > ../etherboot/eb-roms.h > +roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > $(OVMF32_ROM) $(OVMF64_ROM) $(OVMF32_CIRRUS_VGA_ROM) $(OVMF64_CIRRUS_VGA_= ROM) > ../etherboot/eb-roms.h > =A0=A0=A0=A0 echo "/* Autogenerated file. DO NOT EDIT */" > $@.new > =A0 > =A0ifneq ($(ROMBIOS_ROM),) > @@ -84,6 +97,30 @@ > =A0=A0=A0=A0 echo "#endif" >> $@.new > =A0endif > =A0 > +ifneq ($(OVMF32_ROM),) > +=A0=A0=A0 echo "#ifdef ROM_INCLUDE_OVMF32" >> $@.new > +=A0=A0=A0 sh ./mkhex ovmf32 $(OVMF32_ROM) >> $@.new > +=A0=A0=A0 echo "#endif" >> $@.new=A0=A0=A0 > +endif=20 > + > +ifneq ($(OVMF64_ROM),) > +=A0=A0=A0 echo "#ifdef ROM_INCLUDE_OVMF64" >> $@.new > +=A0=A0=A0 sh ./mkhex ovmf64 $(OVMF64_ROM) >> $@.new > +=A0=A0=A0 echo "#endif" >> $@.new=A0=A0=A0 > +endif=20 > + > +ifneq ($(OVMF32_CIRRUS_VGA_ROM),) > +=A0=A0=A0 echo "#ifdef ROM_INCLUDE_OVMF32_CIRRUS_VGA" >> $@.new > +=A0=A0=A0 sh ./mkhex ovmf32_cirrus_vga $(OVMF32_CIRRUS_VGA_ROM) >> $@.new > +=A0=A0=A0 echo "#endif" >> $@.new > +endif=20 > + > +ifneq ($(OVMF64_CIRRUS_VGA_ROM),) > +=A0=A0=A0 echo "#ifdef ROM_INCLUDE_OVMF64_CIRRUS_VGA" >> $@.new > +=A0=A0=A0 sh ./mkhex ovmf64_cirrus_vga $(OVMF64_CIRRUS_VGA_ROM) >> $@.new > +=A0=A0=A0 echo "#endif" >> $@.new=A0=A0=A0 > +endif=20 > + > =A0ifneq ($(STDVGA_ROM),) > =A0=A0=A0=A0 echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new > =A0=A0=A0=A0 sh ./mkhex vgabios_stdvga $(STDVGA_ROM) >> $@.new > diff -r e298ce67777e tools/firmware/hvmloader/config.h > --- a/tools/firmware/hvmloader/config.h=A0=A0=A0 Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/config.h=A0=A0=A0 Fri Jul 22 23:00:20 2011 +0800 > @@ -3,7 +3,7 @@ > =A0 > =A0#include > =A0 > -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; > +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt, VGA_custom }; > =A0extern enum virtual_vga virtual_vga; > =A0 > =A0struct bios_config { > @@ -16,6 +16,9 @@ > =A0=A0=A0=A0 /* Physical address to load at */ > =A0=A0=A0=A0 unsigned int bios_address; > =A0 > +=A0=A0=A0 /* Custom load function. */ > +=A0=A0=A0 void (*load)(const struct bios_config *config); > +=A0=A0=A0 void (*pci_setup)(void); > =A0=A0=A0=A0 /* ROMS */ > =A0=A0=A0=A0 int load_roms; > =A0=A0=A0=A0 unsigned int optionrom_start, optionrom_end; > @@ -36,6 +39,8 @@ > =A0 > =A0extern struct bios_config rombios_config; > =A0extern struct bios_config seabios_config; > +extern struct bios_config ovmf32_config; > +extern struct bios_config ovmf64_config; > =A0 > =A0#define PAGE_SHIFT 12 > =A0#define PAGE_SIZE=A0 (1ul << PAGE_SHIFT) > diff -r e298ce67777e tools/firmware/hvmloader/hvmloader.c > --- a/tools/firmware/hvmloader/hvmloader.c=A0=A0=A0 Mon Jul 18 14:38:31 2011 +0= 100 > +++ b/tools/firmware/hvmloader/hvmloader.c=A0=A0=A0 Fri Jul 22 23:00:20 2011 +0= 800 > @@ -360,6 +360,8 @@ > =A0#ifdef ENABLE_SEABIOS > =A0=A0=A0=A0 { "seabios", &seabios_config, }, > =A0#endif > +=A0=A0=A0 { "ovmf-ia32", &ovmf32_config, }, > +=A0=A0=A0 { "ovmf-x64", &ovmf64_config, }, > =A0=A0=A0=A0 { NULL, NULL } > =A0}; > =A0 > @@ -416,9 +418,13 @@ > =A0=A0=A0=A0=A0=A0=A0=A0 bios->create_smbios_tables(); > =A0=A0=A0=A0 } > =A0 > -=A0=A0=A0 printf("Loading %s ...\n", bios->name); > -=A0=A0=A0 memcpy((void *)bios->bios_address, bios->image, > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 bios->image_size); > +=A0=A0=A0 if (bios->load) { > +=A0=A0=A0=A0=A0=A0=A0 bios->load(bios); > +=A0=A0=A0 } else { > +=A0=A0=A0=A0=A0=A0=A0 printf("Loading %s ...\n", bios->name); > +=A0=A0=A0=A0=A0=A0=A0 memcpy((void *)bios->bios_address, bios->image, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 bios->image_size); > +=A0=A0=A0 } > =A0 > =A0=A0=A0=A0 if (bios->bios_relocate) > =A0=A0=A0=A0=A0=A0=A0=A0 bios->bios_relocate(); > @@ -451,8 +457,10 @@ > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 vgabios_sz =3D round_option_rom( > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > +=A0=A0=A0=A0=A0=A0=A0 case VGA_custom: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > =A0=A0=A0=A0=A0=A0=A0=A0 default: > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 printf("No emulated VGA adaptor ...\n"); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 printf("No emulated VGA adaptor ROM...\n"); > =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > =A0=A0=A0=A0=A0=A0=A0=A0 } > =A0 > diff -r e298ce67777e tools/firmware/hvmloader/ovmf.c > --- /dev/null=A0=A0=A0 Thu Jan 01 00:00:00 1970 +0000 > +++ b/tools/firmware/hvmloader/ovmf.c=A0=A0=A0 Fri Jul 22 23:00:20 2011 +0800 > @@ -0,0 +1,189 @@ > +/* > + * HVM OVMF UEFI support. > + * > + * Bei Guan, gbtju85@gmail.com > + * Andrei Warkentin, andreiw@motorola.com > + * Leendert van Doorn, leendert@watson.ibm.com > + * Copyright (c) 2005, International Business Machines Corporation. > + * Copyright (c) 2006, Keir Fraser, XenSource Inc. > + * Copyright (c) 2011, Citrix Inc. > + * > + * This program is free software; you can redistribute it and/or modify = it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOU= T > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE.=A0 See the GNU General Public License= for > + * more details. > + * > + * You should have received a copy of the GNU General Public License alo= ng > with > + * this program; if not, write to the Free Software Foundation, Inc., 59 > Temple > + * Place - Suite 330, Boston, MA 02111-1307 USA. > + */ > + > +#include "config.h" > +#include "smbios_types.h" > +#include "acpi/acpi2_0.h" > +#include "apic_regs.h" > +#include "../rombios/config.h" > +#include "util.h" > +#include "pci_regs.h" > +#include "hypercall.h" > + > +#include > +#include > +#include > + > +#define ROM_INCLUDE_OVMF32 > +#define ROM_INCLUDE_OVMF64 > +#define ROM_INCLUDE_OVMF32_CIRRUS_VGA > +#define ROM_INCLUDE_OVMF64_CIRRUS_VGA > +#include "roms.inc" > + > +#define OVMF_BEGIN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 0xFFF00000ULL > +#define OVMF_SIZE=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 0x00100000ULL > +#define OVMF_MAXOFFSET=A0=A0=A0=A0=A0=A0=A0=A0=A0 0x000FFFFFULL > +#define OVMF_END=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (OVMF_BEGIN + OVMF_SIZE) > +#define LOWCHUNK_BEGIN=A0=A0=A0=A0=A0=A0=A0=A0=A0 0x000F0000 > +#define LOWCHUNK_SIZE=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 0x00010000 > +#define LOWCHUNK_MAXOFFSET=A0=A0=A0=A0=A0 0x0000FFFF > +#define LOWCHUNK_END=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (OVMF_BEGIN + OVMF_SIZE) > + > +/* > + * Set up an empty TSS area for virtual 8086 mode to use. > + * The only important thing is that it musn't have any bits set > + * in the interrupt redirection bitmap, so all zeros will do. > + */ > +static void ovmf_init_vm86_tss(void) > +{ > +=A0=A0=A0 void *tss; > +=A0=A0=A0 struct xen_hvm_param p; > + > +=A0=A0=A0 tss =3D mem_alloc(128, 128); > +=A0=A0=A0 memset(tss, 0, 128); > +=A0=A0=A0 p.domid =3D DOMID_SELF; > +=A0=A0=A0 p.index =3D HVM_PARAM_VM86_TSS; > +=A0=A0=A0 p.value =3D virt_to_phys(tss); > +=A0=A0=A0 hypercall_hvm_op(HVMOP_set_param, &p); > +=A0=A0=A0 printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); > +} > + > +static void ovmf_load(const struct bios_config *config) > +{ > +=A0=A0=A0 xen_pfn_t mfn; > +=A0=A0=A0 uint64_t addr =3D OVMF_BEGIN; > + > +=A0=A0=A0 virtual_vga =3D VGA_custom; > + > +=A0=A0=A0 /* Copy video ROM. */ > +=A0=A0=A0 if (config =3D=3D &ovmf32_config) { > +=A0=A0=A0=A0=A0=A0=A0 memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ovmf32_cirrus_vga, sizeof(ovmf32_cirrus_vga)); > +=A0=A0=A0=A0=A0=A0=A0 printf("OVMF32 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf32_cirrus_vga)); > +=A0=A0=A0 } else if (config =3D=3D &ovmf64_config) { > +=A0=A0=A0=A0=A0=A0=A0 memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ovmf64_cirrus_vga, sizeof(ovmf64_cirrus_vga)); > +=A0=A0=A0=A0=A0=A0=A0 printf("OVMF64 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf64_cirrus_vga)); > +=A0=A0=A0 } > + > +=A0=A0=A0 /* Copy low-reset vector portion. */ > +=A0=A0=A0 memcpy((void *) LOWCHUNK_BEGIN, (uint8_t *) config->image > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 + OVMF_SIZE > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 - LOWCHUNK_SIZE, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 LOWCHUNK_SIZE); > + > +=A0=A0=A0 /* Ensure we have backing page prior to moving FD. */ > +=A0=A0=A0 while ((addr >> PAGE_SHIFT) !=3D (OVMF_END >> PAGE_SHIFT)) { > +=A0=A0=A0=A0=A0=A0=A0 mfn =3D (uint32_t) (addr >> PAGE_SHIFT); > +=A0=A0=A0=A0=A0=A0=A0 addr +=3D PAGE_SIZE; > + > +=A0=A0=A0=A0=A0=A0=A0 BUG_ON(mem_back_ram(mfn)); > +=A0=A0=A0 } > + > +=A0=A0=A0 printf("Initialized FD backing pages...\n"); > + > +=A0=A0=A0 /* Copy FD. */ > +=A0=A0=A0 memcpy((void *) OVMF_BEGIN, config->image, OVMF_SIZE); > +=A0=A0=A0 printf("Load complete!\n"); > +} > + > +static void ovmf_acpi_build_tables(void) > +{ > +=A0=A0=A0 acpi_build_tables(ACPI_PHYSICAL_ADDRESS); > +} > + > +static void ovmf_create_smbios_tables(void) > +{ > +=A0=A0=A0 hvm_write_smbios_tables(SMBIOS_PHYSICAL_ADDRESS, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 SMBIOS_PHYSICAL_ADDRESS + sizeof(struct > smbios_entry_point), > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 SMBIOS_PHYSICAL_END); > +} > + > +struct bios_config ovmf32_config =3D=A0 { > +=A0=A0=A0 .name =3D "OVMF-IA32", > + > +=A0=A0=A0 .image =3D ovmf32, > +=A0=A0=A0 .image_size =3D sizeof(ovmf32), > + > +=A0=A0=A0 .bios_address =3D 0, > +=A0=A0=A0 .load =3D ovmf_load, > + > +=A0=A0=A0 .load_roms =3D 0, > + > +=A0=A0=A0 .optionrom_start =3D 0, > +=A0=A0=A0 .optionrom_end =3D 0, > + > +=A0=A0=A0 .bios_info_setup =3D NULL, > +=A0=A0=A0 .bios_info_finish =3D NULL, > + > +=A0=A0=A0 .bios_relocate =3D NULL, > + > +=A0=A0=A0 .vm86_setup =3D ovmf_init_vm86_tss, > +=A0=A0=A0 .e820_setup =3D NULL, > + > +=A0=A0=A0 .acpi_build_tables =3D ovmf_acpi_build_tables, > +=A0=A0=A0 .create_mp_tables =3D NULL, > +=A0=A0=A0 .create_smbios_tables =3D ovmf_create_smbios_tables, > +=A0=A0=A0 .create_pir_tables =3D NULL, > +}; > + > +struct bios_config ovmf64_config =3D=A0 { > +=A0=A0=A0 .name =3D "OVMF-X64", > + > +=A0=A0=A0 .image =3D ovmf64, > +=A0=A0=A0 .image_size =3D sizeof(ovmf64), > + > +=A0=A0=A0 .bios_address =3D 0, > +=A0=A0=A0 .load =3D ovmf_load, > + > +=A0=A0=A0 .load_roms =3D 0, > + > +=A0=A0=A0 .optionrom_start =3D 0, > +=A0=A0=A0 .optionrom_end =3D 0, > + > +=A0=A0=A0 .bios_info_setup =3D NULL, > +=A0=A0=A0 .bios_info_finish =3D NULL, > + > +=A0=A0=A0 .bios_relocate =3D NULL, > + > +=A0=A0=A0 .vm86_setup =3D ovmf_init_vm86_tss, > +=A0=A0=A0 .e820_setup =3D NULL, > + > +=A0=A0=A0 .acpi_build_tables =3D ovmf_acpi_build_tables, > +=A0=A0=A0 .create_mp_tables =3D NULL, > +=A0=A0=A0 .create_smbios_tables =3D ovmf_create_smbios_tables, > +=A0=A0=A0 .create_pir_tables =3D NULL, > +}; > + > +/* > + * Local variables: > + * mode: C > + * c-set-style: "BSD" > + * c-basic-offset: 4 > + * tab-width: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff -r e298ce67777e tools/firmware/hvmloader/util.c > --- a/tools/firmware/hvmloader/util.c=A0=A0=A0 Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/util.c=A0=A0=A0 Fri Jul 22 23:00:20 2011 +0800 > @@ -303,12 +303,54 @@ > =A0=A0=A0=A0 *p =3D '\0'; > =A0} > =A0 > +/* > + * Ensures mfn is backed by an accessible RAM page. > + * Returns 0 on success. > + */ > +int mem_back_ram(xen_pfn_t mfn) > +{ > +=A0=A0=A0 struct xen_add_to_physmap xatp; > +=A0=A0=A0 struct xen_memory_reservation xmr; > +=A0=A0=A0 static int over_allocated =3D 0; > + > +=A0=A0=A0 if ( !over_allocated ) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 xmr.domid =3D DOMID_SELF; > +=A0=A0=A0=A0=A0=A0=A0 xmr.mem_flags =3D 0; > +=A0=A0=A0=A0=A0=A0=A0 xmr.extent_order =3D 0; > +=A0=A0=A0=A0=A0=A0=A0 xmr.nr_extents =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 set_xen_guest_handle(xmr.extent_start, &mfn); > +=A0=A0=A0=A0=A0=A0=A0 if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) =3D=3D 1 ) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return 0; > +=A0=A0=A0=A0=A0=A0=A0 over_allocated =3D 1; > +=A0=A0=A0 } > + > +=A0=A0=A0 /* > +=A0=A0=A0=A0 * Couldn't allocate more memory for domain, > +=A0=A0=A0=A0 * move an existing physical page from end > +=A0=A0=A0=A0 * of RAM. > +=A0=A0=A0=A0 */ > +=A0=A0=A0 if ( hvm_info->high_mem_pgend ) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 xatp.idx =3D --hvm_info->high_mem_pgend; > +=A0=A0=A0=A0=A0=A0=A0 if ( xatp.idx =3D=3D (1ull << (32 - PAGE_SHIFT)) ) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 hvm_info->high_mem_pgend =3D 0; > +=A0=A0=A0 } > +=A0=A0=A0 else > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 xatp.idx =3D --hvm_info->low_mem_pgend; > +=A0=A0=A0 } > +=A0=A0=A0 xatp.domid =3D DOMID_SELF; > +=A0=A0=A0 xatp.space =3D XENMAPSPACE_gmfn; > +=A0=A0=A0 xatp.gpfn=A0 =3D mfn; > +=A0=A0=A0 if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) !=3D 0 ) > +=A0=A0=A0=A0=A0=A0=A0 BUG(); > +=A0=A0=A0 return 0; > +} > + > =A0void *mem_alloc(uint32_t size, uint32_t align) > =A0{ > =A0=A0=A0=A0 static uint32_t reserve =3D RESERVED_MEMBASE - 1; > -=A0=A0=A0 static int over_allocated; > -=A0=A0=A0 struct xen_add_to_physmap xatp; > -=A0=A0=A0 struct xen_memory_reservation xmr; > =A0=A0=A0=A0 xen_pfn_t mfn; > =A0=A0=A0=A0 uint32_t s, e; > =A0 > @@ -326,35 +368,7 @@ > =A0=A0=A0=A0=A0=A0=A0=A0 reserve +=3D PAGE_SIZE; > =A0=A0=A0=A0=A0=A0=A0=A0 mfn =3D reserve >> PAGE_SHIFT; > =A0 > -=A0=A0=A0=A0=A0=A0=A0 /* Try to allocate a brand new page in the reserved area. */ > -=A0=A0=A0=A0=A0=A0=A0 if ( !over_allocated ) > -=A0=A0=A0=A0=A0=A0=A0 { > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 xmr.domid =3D DOMID_SELF; > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 xmr.mem_flags =3D 0; > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 xmr.extent_order =3D 0; > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 xmr.nr_extents =3D 1; > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 set_xen_guest_handle(xmr.extent_start, &mfn); > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) =3D=3D 1= ) > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 continue; > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 over_allocated =3D 1; > -=A0=A0=A0=A0=A0=A0=A0 } > - > -=A0=A0=A0=A0=A0=A0=A0 /* Otherwise, relocate a page from the ordinary RAM map. */ > -=A0=A0=A0=A0=A0=A0=A0 if ( hvm_info->high_mem_pgend ) > -=A0=A0=A0=A0=A0=A0=A0 { > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 xatp.idx =3D --hvm_info->high_mem_pgend; > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if ( xatp.idx =3D=3D (1ull << (32 - PAGE_SHIFT)) ) > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 hvm_info->high_mem_pgend =3D 0; > -=A0=A0=A0=A0=A0=A0=A0 } > -=A0=A0=A0=A0=A0=A0=A0 else > -=A0=A0=A0=A0=A0=A0=A0 { > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 xatp.idx =3D --hvm_info->low_mem_pgend; > -=A0=A0=A0=A0=A0=A0=A0 } > -=A0=A0=A0=A0=A0=A0=A0 xatp.domid =3D DOMID_SELF; > -=A0=A0=A0=A0=A0=A0=A0 xatp.space =3D XENMAPSPACE_gmfn; > -=A0=A0=A0=A0=A0=A0=A0 xatp.gpfn=A0 =3D mfn; > -=A0=A0=A0=A0=A0=A0=A0 if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) !=3D 0 ) > -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 BUG(); > +=A0=A0=A0=A0=A0=A0=A0 BUG_ON(mem_back_ram(mfn)); > =A0=A0=A0=A0 } > =A0 > =A0=A0=A0=A0 reserve =3D e; > @@ -624,22 +638,24 @@ > =A0=A0=A0=A0 return table; > =A0} > =A0 > -struct shared_info *get_shared_info(void) > +static struct shared_info *shared_info =3D NULL; > + > +struct shared_info *get_shared_info(void) > =A0{ > -=A0=A0=A0 static struct shared_info *shared_info =3D NULL; > =A0=A0=A0=A0 struct xen_add_to_physmap xatp; > =A0 > =A0=A0=A0=A0 if ( shared_info !=3D NULL ) > =A0=A0=A0=A0=A0=A0=A0=A0 return shared_info; > =A0 > +=A0=A0=A0 /* Guarantee shinfo lives in a safe (reserved) place */ > +=A0=A0=A0 shared_info =3D mem_alloc(PAGE_SIZE, PAGE_SIZE); > + > =A0=A0=A0=A0 xatp.domid =3D DOMID_SELF; > =A0=A0=A0=A0 xatp.space =3D XENMAPSPACE_shared_info; > =A0=A0=A0=A0 xatp.idx=A0=A0 =3D 0; > -=A0=A0=A0 xatp.gpfn=A0 =3D 0xfffffu; > -=A0=A0=A0 shared_info =3D (struct shared_info *)(xatp.gpfn << PAGE_SHIFT); > +=A0=A0=A0 xatp.gpfn=A0 =3D ((uint32_t) shared_info) >> PAGE_SHIFT; > =A0=A0=A0=A0 if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) !=3D 0 ) > =A0=A0=A0=A0=A0=A0=A0=A0 BUG(); > - > =A0=A0=A0=A0 return shared_info; > =A0} > =A0 > diff -r e298ce67777e tools/firmware/hvmloader/util.h > --- a/tools/firmware/hvmloader/util.h=A0=A0=A0 Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/util.h=A0=A0=A0 Fri Jul 22 23:00:20 2011 +0800 > @@ -3,6 +3,7 @@ > =A0 > =A0#include > =A0#include > +#include > =A0#include > =A0 > =A0#define __STR(...) #__VA_ARGS__ > @@ -164,6 +165,9 @@ > =A0int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)))= ; > =A0int vprintf(const char *fmt, va_list ap); > =A0 > +/* Create RAM backing for guest machine frame. */ > +int mem_back_ram(xen_pfn_t mfn); > + > =A0/* Allocate memory in a reserved region below 4GB. */ > =A0void *mem_alloc(uint32_t size, uint32_t align); > =A0#define virt_to_phys(v) ((unsigned long)(v)) >=20 >=20 > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel