From mboxrd@z Thu Jan 1 00:00:00 1970 From: Benjamin Herrenschmidt Subject: [PATCH 2/2] pseries: Correctly create ibm,segment-page-sizes property Date: Tue, 19 Jun 2012 15:56:30 +1000 Message-ID: <1340085390.28143.3.camel@pasglop> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Cc: kvm-ppc@vger.kernel.org, Alexander Graf , kvm@vger.kernel.org To: "qemu-devel@nongnu.org" Return-path: Sender: kvm-ppc-owner@vger.kernel.org List-Id: kvm.vger.kernel.org The core tcg/kvm code for ppc64 now has at least the outline capability to support pagesizes beyond the standard 4k and 16MB. The CPUState is initialized with information advertising the available pagesizes and their correct encodings, and under the right KVM setup this will be populated with page sizes beyond the standard. Obviously guests can't use the extra page sizes unless they know they're present. For the pseries machine, at least, there is a defined method for conveying exactly this information, the "ibm-segment-page-sizes" property in the guest device tree. This patch generates this property using the supported page size information that's already in the CPUState. Signed-off-by: Nishanth Aravamudan Signed-off-by: David Gibson Signed-off-by: Benjamin Herrenschmidt --- hw/spapr.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index b20f70d..a22a6b6 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -149,6 +149,40 @@ static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) return ret; } + +static size_t create_page_sizes_prop(CPUPPCState *env, uint32_t *prop, + size_t maxsize) +{ + size_t maxcells = maxsize / sizeof(uint32_t); + int i, j, count; + uint32_t *p = prop; + + for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) { + struct ppc_one_seg_page_size *sps = &env->sps.sps[i]; + + if (!sps->page_shift) { + break; + } + for (count = 0; count < PPC_PAGE_SIZES_MAX_SZ; count++) { + if (sps->enc[count].page_shift == 0) { + break; + } + } + if ((p - prop) >= (maxcells - 3 - count * 2)) { + break; + } + *(p++) = cpu_to_be32(sps->page_shift); + *(p++) = cpu_to_be32(sps->slb_enc); + *(p++) = cpu_to_be32(count); + for (j = 0; j < count; j++) { + *(p++) = cpu_to_be32(sps->enc[j].page_shift); + *(p++) = cpu_to_be32(sps->enc[j].pte_enc); + } + } + + return (p - prop) * sizeof(uint32_t); +} + static void *spapr_create_fdt_skel(const char *cpu_model, target_phys_addr_t rma_size, target_phys_addr_t initrd_base, @@ -304,6 +338,8 @@ static void *spapr_create_fdt_skel(const char *cpu_model, 0xffffffff, 0xffffffff}; uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000; + uint32_t page_sizes_prop[64]; + size_t page_sizes_prop_size; if ((index % smt) != 0) { continue; @@ -368,6 +404,13 @@ static void *spapr_create_fdt_skel(const char *cpu_model, _FDT((fdt_property_cell(fdt, "ibm,dfp", 1))); } + page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop, + sizeof(page_sizes_prop)); + if (page_sizes_prop_size) { + _FDT((fdt_property(fdt, "ibm,segment-page-sizes", + page_sizes_prop, page_sizes_prop_size))); + } + _FDT((fdt_end_node(fdt))); } From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:59039) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SgrQb-0001wN-8f for qemu-devel@nongnu.org; Tue, 19 Jun 2012 01:56:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SgrQZ-0003xm-Ag for qemu-devel@nongnu.org; Tue, 19 Jun 2012 01:56:36 -0400 Received: from gate.crashing.org ([63.228.1.57]:60215) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SgrQZ-0003xV-1O for qemu-devel@nongnu.org; Tue, 19 Jun 2012 01:56:35 -0400 Message-ID: <1340085390.28143.3.camel@pasglop> From: Benjamin Herrenschmidt Date: Tue, 19 Jun 2012 15:56:30 +1000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Mime-Version: 1.0 Subject: [Qemu-devel] [PATCH 2/2] pseries: Correctly create ibm, segment-page-sizes property List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "qemu-devel@nongnu.org" Cc: Alexander Graf , kvm-ppc@vger.kernel.org, kvm@vger.kernel.org The core tcg/kvm code for ppc64 now has at least the outline capability to support pagesizes beyond the standard 4k and 16MB. The CPUState is initialized with information advertising the available pagesizes and their correct encodings, and under the right KVM setup this will be populated with page sizes beyond the standard. Obviously guests can't use the extra page sizes unless they know they're present. For the pseries machine, at least, there is a defined method for conveying exactly this information, the "ibm-segment-page-sizes" property in the guest device tree. This patch generates this property using the supported page size information that's already in the CPUState. Signed-off-by: Nishanth Aravamudan Signed-off-by: David Gibson Signed-off-by: Benjamin Herrenschmidt --- hw/spapr.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index b20f70d..a22a6b6 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -149,6 +149,40 @@ static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) return ret; } + +static size_t create_page_sizes_prop(CPUPPCState *env, uint32_t *prop, + size_t maxsize) +{ + size_t maxcells = maxsize / sizeof(uint32_t); + int i, j, count; + uint32_t *p = prop; + + for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) { + struct ppc_one_seg_page_size *sps = &env->sps.sps[i]; + + if (!sps->page_shift) { + break; + } + for (count = 0; count < PPC_PAGE_SIZES_MAX_SZ; count++) { + if (sps->enc[count].page_shift == 0) { + break; + } + } + if ((p - prop) >= (maxcells - 3 - count * 2)) { + break; + } + *(p++) = cpu_to_be32(sps->page_shift); + *(p++) = cpu_to_be32(sps->slb_enc); + *(p++) = cpu_to_be32(count); + for (j = 0; j < count; j++) { + *(p++) = cpu_to_be32(sps->enc[j].page_shift); + *(p++) = cpu_to_be32(sps->enc[j].pte_enc); + } + } + + return (p - prop) * sizeof(uint32_t); +} + static void *spapr_create_fdt_skel(const char *cpu_model, target_phys_addr_t rma_size, target_phys_addr_t initrd_base, @@ -304,6 +338,8 @@ static void *spapr_create_fdt_skel(const char *cpu_model, 0xffffffff, 0xffffffff}; uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000; + uint32_t page_sizes_prop[64]; + size_t page_sizes_prop_size; if ((index % smt) != 0) { continue; @@ -368,6 +404,13 @@ static void *spapr_create_fdt_skel(const char *cpu_model, _FDT((fdt_property_cell(fdt, "ibm,dfp", 1))); } + page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop, + sizeof(page_sizes_prop)); + if (page_sizes_prop_size) { + _FDT((fdt_property(fdt, "ibm,segment-page-sizes", + page_sizes_prop, page_sizes_prop_size))); + } + _FDT((fdt_end_node(fdt))); } From mboxrd@z Thu Jan 1 00:00:00 1970 From: Benjamin Herrenschmidt Date: Tue, 19 Jun 2012 05:56:30 +0000 Subject: [PATCH 2/2] pseries: Correctly create ibm,segment-page-sizes property Message-Id: <1340085390.28143.3.camel@pasglop> List-Id: References: <1335505904.4578.10.camel@pasglop> In-Reply-To: <1335505904.4578.10.camel@pasglop> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: "qemu-devel@nongnu.org" Cc: kvm-ppc@vger.kernel.org, Alexander Graf , kvm@vger.kernel.org The core tcg/kvm code for ppc64 now has at least the outline capability to support pagesizes beyond the standard 4k and 16MB. The CPUState is initialized with information advertising the available pagesizes and their correct encodings, and under the right KVM setup this will be populated with page sizes beyond the standard. Obviously guests can't use the extra page sizes unless they know they're present. For the pseries machine, at least, there is a defined method for conveying exactly this information, the "ibm-segment-page-sizes" property in the guest device tree. This patch generates this property using the supported page size information that's already in the CPUState. Signed-off-by: Nishanth Aravamudan Signed-off-by: David Gibson Signed-off-by: Benjamin Herrenschmidt --- hw/spapr.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index b20f70d..a22a6b6 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -149,6 +149,40 @@ static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) return ret; } + +static size_t create_page_sizes_prop(CPUPPCState *env, uint32_t *prop, + size_t maxsize) +{ + size_t maxcells = maxsize / sizeof(uint32_t); + int i, j, count; + uint32_t *p = prop; + + for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) { + struct ppc_one_seg_page_size *sps = &env->sps.sps[i]; + + if (!sps->page_shift) { + break; + } + for (count = 0; count < PPC_PAGE_SIZES_MAX_SZ; count++) { + if (sps->enc[count].page_shift = 0) { + break; + } + } + if ((p - prop) >= (maxcells - 3 - count * 2)) { + break; + } + *(p++) = cpu_to_be32(sps->page_shift); + *(p++) = cpu_to_be32(sps->slb_enc); + *(p++) = cpu_to_be32(count); + for (j = 0; j < count; j++) { + *(p++) = cpu_to_be32(sps->enc[j].page_shift); + *(p++) = cpu_to_be32(sps->enc[j].pte_enc); + } + } + + return (p - prop) * sizeof(uint32_t); +} + static void *spapr_create_fdt_skel(const char *cpu_model, target_phys_addr_t rma_size, target_phys_addr_t initrd_base, @@ -304,6 +338,8 @@ static void *spapr_create_fdt_skel(const char *cpu_model, 0xffffffff, 0xffffffff}; uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000; + uint32_t page_sizes_prop[64]; + size_t page_sizes_prop_size; if ((index % smt) != 0) { continue; @@ -368,6 +404,13 @@ static void *spapr_create_fdt_skel(const char *cpu_model, _FDT((fdt_property_cell(fdt, "ibm,dfp", 1))); } + page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop, + sizeof(page_sizes_prop)); + if (page_sizes_prop_size) { + _FDT((fdt_property(fdt, "ibm,segment-page-sizes", + page_sizes_prop, page_sizes_prop_size))); + } + _FDT((fdt_end_node(fdt))); }