From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:59942) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R9GcU-00057R-FB for qemu-devel@nongnu.org; Thu, 29 Sep 2011 09:25:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R9GcO-0008AB-3a for qemu-devel@nongnu.org; Thu, 29 Sep 2011 09:25:46 -0400 Received: from cantor2.suse.de ([195.135.220.15]:40895 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R9GcN-00089w-Je for qemu-devel@nongnu.org; Thu, 29 Sep 2011 09:25:40 -0400 Mime-Version: 1.0 (Apple Message framework v1084) Content-Type: text/plain; charset=us-ascii From: Alexander Graf In-Reply-To: <1317278706-16105-3-git-send-email-david@gibson.dropbear.id.au> Date: Thu, 29 Sep 2011 15:25:37 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: References: <1317278706-16105-1-git-send-email-david@gibson.dropbear.id.au> <1317278706-16105-3-git-send-email-david@gibson.dropbear.id.au> Subject: Re: [Qemu-devel] [PATCH 2/3] pseries: Allow KVM Book3S-HV on PPC970 CPUS List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: David Gibson Cc: qemu-devel@nongnu.org On 29.09.2011, at 08:45, David Gibson wrote: > At present, using the hypervisor aware Book3S-HV KVM will only work > with qemu on POWER7 CPUs. PPC970 CPUs also have hypervisor > capability, but they lack the VRMA feature which makes assigning guest > memory easier. >=20 > In order to allow KVM Book3S-HV on PPC970, we need to specially > allocate the first chunk of guest memory (the "Real Mode Area" or > RMA), so that it is physically contiguous. >=20 > Sufficiently recent host kernels allow such contiguous RMAs to be > allocated, with a kvm capability advertising whether the feature is > available and/or necessary on this hardware. This patch enables qemu > to use this support, thus allowing kvm acceleration of pseries qemu > machines on PPC970 hardware. >=20 > Signed-off-by: Paul Mackerras > Signed-off-by: David Gibson > --- > hw/spapr.c | 50 = ++++++++++++++++++++++++++++++++++++++++-------- > target-ppc/kvm.c | 51 = ++++++++++++++++++++++++++++++++++++++++++++++++++ > target-ppc/kvm_ppc.h | 6 +++++ > 3 files changed, 98 insertions(+), 9 deletions(-) >=20 > diff --git a/hw/spapr.c b/hw/spapr.c > index ba9ae1c..d51425a 100644 > --- a/hw/spapr.c > +++ b/hw/spapr.c > @@ -89,6 +89,7 @@ qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t = *irq_num) > } >=20 > static void *spapr_create_fdt_skel(const char *cpu_model, > + target_phys_addr_t rma_size, > target_phys_addr_t initrd_base, > target_phys_addr_t initrd_size, > const char *boot_device, > @@ -97,7 +98,9 @@ static void *spapr_create_fdt_skel(const char = *cpu_model, > { > void *fdt; > CPUState *env; > - uint64_t mem_reg_property[] =3D { 0, cpu_to_be64(ram_size) }; > + uint64_t mem_reg_property_rma[] =3D { 0, cpu_to_be64(rma_size) }; > + uint64_t mem_reg_property_nonrma[] =3D { cpu_to_be64(rma_size), > + cpu_to_be64(ram_size - = rma_size) }; > uint32_t start_prop =3D cpu_to_be32(initrd_base); > uint32_t end_prop =3D cpu_to_be32(initrd_base + initrd_size); > uint32_t pft_size_prop[] =3D {0, cpu_to_be32(hash_shift)}; > @@ -143,15 +146,25 @@ static void *spapr_create_fdt_skel(const char = *cpu_model, >=20 > _FDT((fdt_end_node(fdt))); >=20 > - /* memory node */ > + /* memory node(s) */ > _FDT((fdt_begin_node(fdt, "memory@0"))); >=20 > _FDT((fdt_property_string(fdt, "device_type", "memory"))); > - _FDT((fdt_property(fdt, "reg", > - mem_reg_property, sizeof(mem_reg_property)))); > - > + _FDT((fdt_property(fdt, "reg", mem_reg_property_rma, > + sizeof(mem_reg_property_rma)))); > _FDT((fdt_end_node(fdt))); >=20 > + if (ram_size > rma_size) { > + char mem_name[32]; > + > + sprintf(mem_name, "memory@%" PRIx64, (uint64_t)rma_size); > + _FDT((fdt_begin_node(fdt, mem_name))); > + _FDT((fdt_property_string(fdt, "device_type", "memory"))); > + _FDT((fdt_property(fdt, "reg", mem_reg_property_nonrma, > + sizeof(mem_reg_property_nonrma)))); > + _FDT((fdt_end_node(fdt))); > + } =20 > + > /* cpus */ > _FDT((fdt_begin_node(fdt, "cpus"))); >=20 > @@ -341,6 +354,7 @@ static void ppc_spapr_init(ram_addr_t ram_size, > { > CPUState *env; > int i; > + target_phys_addr_t rma_alloc_size, rma_size; > ram_addr_t ram_offset; > uint32_t initrd_base; > long kernel_size, initrd_size, fw_size; > @@ -350,10 +364,23 @@ static void ppc_spapr_init(ram_addr_t ram_size, > spapr =3D g_malloc(sizeof(*spapr)); > cpu_ppc_hypercall =3D emulate_spapr_hypercall; >=20 > + /* Allocate RMA if necessary */ > + rma_alloc_size =3D kvmppc_alloc_rma("ppc_spapr.rma"); > + > + if (rma_alloc_size =3D=3D -1) { > + hw_error("qemu: Unable to create RMA\n"); > + exit(1); > + } > + if (rma_alloc_size && (rma_alloc_size < ram_size)) { > + rma_size =3D rma_alloc_size; > + } else { > + rma_size =3D ram_size; > + } > + > /* We place the device tree just below either the top of RAM, or > * 2GB, so that it can be processed with 32-bit code if > * necessary */ > - spapr->fdt_addr =3D MIN(ram_size, 0x80000000) - FDT_MAX_SIZE; > + spapr->fdt_addr =3D MIN(rma_size, 0x80000000) - FDT_MAX_SIZE; The change looks sane, so I'd assume the description above is now wrong = :) > spapr->rtas_addr =3D spapr->fdt_addr - RTAS_MAX_SIZE; >=20 > /* init CPUs */ > @@ -378,8 +405,13 @@ static void ppc_spapr_init(ram_addr_t ram_size, >=20 > /* allocate RAM */ > spapr->ram_limit =3D ram_size; > - ram_offset =3D qemu_ram_alloc(NULL, "ppc_spapr.ram", = spapr->ram_limit); > - cpu_register_physical_memory(0, ram_size, ram_offset); > + if (spapr->ram_limit > rma_alloc_size) { > + ram_addr_t nonrma_base =3D rma_alloc_size; > + ram_addr_t nonrma_size =3D spapr->ram_limit - rma_alloc_size; > + > + ram_offset =3D qemu_ram_alloc(NULL, "ppc_spapr.ram", = nonrma_size); > + cpu_register_physical_memory(nonrma_base, nonrma_size, = ram_offset); > + } >=20 > /* allocate hash page table. For now we always make this 16mb, > * later we should probably make it scale to the size of guest > @@ -503,7 +535,7 @@ static void ppc_spapr_init(ram_addr_t ram_size, > } >=20 > /* Prepare the device tree */ > - spapr->fdt_skel =3D spapr_create_fdt_skel(cpu_model, > + spapr->fdt_skel =3D spapr_create_fdt_skel(cpu_model, rma_size, > initrd_base, initrd_size, > boot_device, = kernel_cmdline, > pteg_shift + 7); > diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c > index 2c1bc7a..37ee902 100644 > --- a/target-ppc/kvm.c > +++ b/target-ppc/kvm.c > @@ -55,6 +55,9 @@ static int cap_interrupt_level =3D false; > static int cap_segstate; > static int cap_booke_sregs; > static int cap_ppc_smt =3D 0; > +#ifdef KVM_CAP_PPC_RMA No need for these ifdefs anymore thanks to qemu local kvm headers :) Alex