diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-03-02 13:50:54 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-03-02 13:50:55 +0000 |
commit | ab711e216b8a4c663ab89f50f2c6f10e8a4f8a54 (patch) | |
tree | 48857a7040750d379ec301f0f134a978885d8741 /target/ppc/kvm.c | |
parent | 4bc0d39a2fd066e64c5e59947228beb41d3e4ffc (diff) | |
parent | 356bb70ed1a8a741413d55e3dbc5ccd02c53d794 (diff) |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.9-20170301' into staging
ppc patch queue for 2017-03-01
I was hoping to get this pull request squeezed in before the soft
freeze, but I ran into some difficulties during testing. Everything
here was at least posted before the soft freeze, so I'm hoping we can
still merge it for 2.9.
The biggest things here are:
* Cleanups to handling of hashed page tables, that will make
adding support for the POWER9 MMU easier
* Cleanups to the XICS interrupt controller that will make
implementing the powernv machine easier
* TCG implementation of extended overflow and carry handling for
POWER9
It also includes:
* Increasing the CPU limit for pseries to 1024 vCPUs
* Generating proper OF node names in qemu (making hotplug and
coldplug logic closer together)
# gpg: Signature made Wed 01 Mar 2017 04:43:06 GMT
# gpg: using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392
* remotes/dgibson/tags/ppc-for-2.9-20170301: (50 commits)
Add PowerPC 32-bit guest memory dump support
ppc/xics: rename 'ICPState *' variables to 'icp'
ppc/xics: move InterruptStatsProvider to the sPAPR machine
ppc/xics: move ics-simple post_load under the machine
ppc/xics: remove the XICSState classes
ppc/xics: export the XICS init routines
ppc/xics: move the ICP array under the sPAPR machine
ppc/xics: register the reset handler of ICP objects
ppc/xics: simplify spapr_dt_xics() interface
ppc/xics: use the QOM interface to grab an ICP
ppc/xics: move the cpu_setup() handler under the ICPState class
ppc/xics: simplify the cpu_setup() handler
ppc/xics: move kernel_xics_fd out of KVMXICSState
ppc/xics: extend the QOM interface to handle ICPs
ppc/xics: remove the XICS list of ICS
ppc/xics: register the reset handler of ICS objects
ppc/xics: remove xics_find_source()
ppc/xics: use the QOM interface to resend irqs
ppc/xics: use the QOM interface to get irqs
ppc/xics: use the QOM interface under the sPAPR machine
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/ppc/kvm.c')
-rw-r--r-- | target/ppc/kvm.c | 128 |
1 files changed, 62 insertions, 66 deletions
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 52bbea514a..acc40ece65 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1251,7 +1251,7 @@ static int kvmppc_get_books_sregs(PowerPCCPU *cpu) return ret; } - if (!env->external_htab) { + if (!cpu->vhyp) { ppc_store_sdr1(env, sregs.u.s.sdr1); } @@ -2596,89 +2596,85 @@ void kvm_arch_init_irq_routing(KVMState *s) { } -struct kvm_get_htab_buf { - struct kvm_get_htab_header header; - /* - * We require one extra byte for read - */ - target_ulong hpte[(HPTES_PER_GROUP * 2) + 1]; -}; - -uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index) +void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n) { - int htab_fd; - struct kvm_get_htab_fd ghf; - struct kvm_get_htab_buf *hpte_buf; + struct kvm_get_htab_fd ghf = { + .flags = 0, + .start_index = ptex, + }; + int fd, rc; + int i; - ghf.flags = 0; - ghf.start_index = pte_index; - htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); - if (htab_fd < 0) { - goto error_out; + fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); + if (fd < 0) { + hw_error("kvmppc_read_hptes: Unable to open HPT fd"); } - hpte_buf = g_malloc0(sizeof(*hpte_buf)); - /* - * Read the hpte group - */ - if (read(htab_fd, hpte_buf, sizeof(*hpte_buf)) < 0) { - goto out_close; - } + i = 0; + while (i < n) { + struct kvm_get_htab_header *hdr; + int m = n < HPTES_PER_GROUP ? n : HPTES_PER_GROUP; + char buf[sizeof(*hdr) + m * HASH_PTE_SIZE_64]; - close(htab_fd); - return (uint64_t)(uintptr_t) hpte_buf->hpte; + rc = read(fd, buf, sizeof(buf)); + if (rc < 0) { + hw_error("kvmppc_read_hptes: Unable to read HPTEs"); + } -out_close: - g_free(hpte_buf); - close(htab_fd); -error_out: - return 0; -} + hdr = (struct kvm_get_htab_header *)buf; + while ((i < n) && ((char *)hdr < (buf + rc))) { + int invalid = hdr->n_invalid; -void kvmppc_hash64_free_pteg(uint64_t token) -{ - struct kvm_get_htab_buf *htab_buf; + if (hdr->index != (ptex + i)) { + hw_error("kvmppc_read_hptes: Unexpected HPTE index %"PRIu32 + " != (%"HWADDR_PRIu" + %d", hdr->index, ptex, i); + } + + memcpy(hptes + i, hdr + 1, HASH_PTE_SIZE_64 * hdr->n_valid); + i += hdr->n_valid; - htab_buf = container_of((void *)(uintptr_t) token, struct kvm_get_htab_buf, - hpte); - g_free(htab_buf); - return; + if ((n - i) < invalid) { + invalid = n - i; + } + memset(hptes + i, 0, invalid * HASH_PTE_SIZE_64); + i += hdr->n_invalid; + + hdr = (struct kvm_get_htab_header *) + ((char *)(hdr + 1) + HASH_PTE_SIZE_64 * hdr->n_valid); + } + } + + close(fd); } -void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, - target_ulong pte0, target_ulong pte1) +void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t pte1) { - int htab_fd; + int fd, rc; struct kvm_get_htab_fd ghf; - struct kvm_get_htab_buf hpte_buf; + struct { + struct kvm_get_htab_header hdr; + uint64_t pte0; + uint64_t pte1; + } buf; ghf.flags = 0; ghf.start_index = 0; /* Ignored */ - htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); - if (htab_fd < 0) { - goto error_out; - } - - hpte_buf.header.n_valid = 1; - hpte_buf.header.n_invalid = 0; - hpte_buf.header.index = pte_index; - hpte_buf.hpte[0] = pte0; - hpte_buf.hpte[1] = pte1; - /* - * Write the hpte entry. - * CAUTION: write() has the warn_unused_result attribute. Hence we - * need to check the return value, even though we do nothing. - */ - if (write(htab_fd, &hpte_buf, sizeof(hpte_buf)) < 0) { - goto out_close; + fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf); + if (fd < 0) { + hw_error("kvmppc_write_hpte: Unable to open HPT fd"); } -out_close: - close(htab_fd); - return; + buf.hdr.n_valid = 1; + buf.hdr.n_invalid = 0; + buf.hdr.index = ptex; + buf.pte0 = cpu_to_be64(pte0); + buf.pte1 = cpu_to_be64(pte1); -error_out: - return; + rc = write(fd, &buf, sizeof(buf)); + if (rc != sizeof(buf)) { + hw_error("kvmppc_write_hpte: Unable to update KVM HPT"); + } + close(fd); } int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, |