aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/kvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/ppc/kvm.c')
-rw-r--r--target/ppc/kvm.c128
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,