Revision e68cb8b4

b/hw/ppc/spapr.c
735 735
{
736 736
    sPAPREnvironment *spapr = opaque;
737 737

  
738
    spapr->htab_save_index = 0;
739
    spapr->htab_first_pass = true;
740

  
741 738
    /* "Iteration" header */
742 739
    qemu_put_be32(f, spapr->htab_shift);
743 740

  
741
    if (spapr->htab) {
742
        spapr->htab_save_index = 0;
743
        spapr->htab_first_pass = true;
744
    } else {
745
        assert(kvm_enabled());
746

  
747
        spapr->htab_fd = kvmppc_get_htab_fd(false);
748
        if (spapr->htab_fd < 0) {
749
            fprintf(stderr, "Unable to open fd for reading hash table from KVM: %s\n",
750
                    strerror(errno));
751
            return -1;
752
        }
753
    }
754

  
755

  
744 756
    return 0;
745 757
}
746 758

  
747
#define MAX_ITERATION_NS    5000000 /* 5 ms */
748

  
749 759
static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr,
750 760
                                 int64_t max_ns)
751 761
{
......
796 806
    spapr->htab_save_index = index;
797 807
}
798 808

  
799
static bool htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr,
800
                                 int64_t max_ns)
809
static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr,
810
                                int64_t max_ns)
801 811
{
802 812
    bool final = max_ns < 0;
803 813
    int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
......
870 880

  
871 881
    spapr->htab_save_index = index;
872 882

  
873
    return (examined >= htabslots) && (sent == 0);
883
    return (examined >= htabslots) && (sent == 0) ? 1 : 0;
874 884
}
875 885

  
886
#define MAX_ITERATION_NS    5000000 /* 5 ms */
887
#define MAX_KVM_BUF_SIZE    2048
888

  
876 889
static int htab_save_iterate(QEMUFile *f, void *opaque)
877 890
{
878 891
    sPAPREnvironment *spapr = opaque;
879
    bool nothingleft = false;;
892
    int rc = 0;
880 893

  
881 894
    /* Iteration header */
882 895
    qemu_put_be32(f, 0);
883 896

  
884
    if (spapr->htab_first_pass) {
897
    if (!spapr->htab) {
898
        assert(kvm_enabled());
899

  
900
        rc = kvmppc_save_htab(f, spapr->htab_fd,
901
                              MAX_KVM_BUF_SIZE, MAX_ITERATION_NS);
902
        if (rc < 0) {
903
            return rc;
904
        }
905
    } else  if (spapr->htab_first_pass) {
885 906
        htab_save_first_pass(f, spapr, MAX_ITERATION_NS);
886 907
    } else {
887
        nothingleft = htab_save_later_pass(f, spapr, MAX_ITERATION_NS);
908
        rc = htab_save_later_pass(f, spapr, MAX_ITERATION_NS);
888 909
    }
889 910

  
890 911
    /* End marker */
......
892 913
    qemu_put_be16(f, 0);
893 914
    qemu_put_be16(f, 0);
894 915

  
895
    return nothingleft ? 1 : 0;
916
    return rc;
896 917
}
897 918

  
898 919
static int htab_save_complete(QEMUFile *f, void *opaque)
......
902 923
    /* Iteration header */
903 924
    qemu_put_be32(f, 0);
904 925

  
905
    htab_save_later_pass(f, spapr, -1);
926
    if (!spapr->htab) {
927
        int rc;
928

  
929
        assert(kvm_enabled());
930

  
931
        rc = kvmppc_save_htab(f, spapr->htab_fd, MAX_KVM_BUF_SIZE, -1);
932
        if (rc < 0) {
933
            return rc;
934
        }
935
        close(spapr->htab_fd);
936
        spapr->htab_fd = -1;
937
    } else {
938
        htab_save_later_pass(f, spapr, -1);
939
    }
906 940

  
907 941
    /* End marker */
908 942
    qemu_put_be32(f, 0);
......
916 950
{
917 951
    sPAPREnvironment *spapr = opaque;
918 952
    uint32_t section_hdr;
953
    int fd = -1;
919 954

  
920 955
    if (version_id < 1 || version_id > 1) {
921 956
        fprintf(stderr, "htab_load() bad version\n");
......
932 967
        return 0;
933 968
    }
934 969

  
970
    if (!spapr->htab) {
971
        assert(kvm_enabled());
972

  
973
        fd = kvmppc_get_htab_fd(true);
974
        if (fd < 0) {
975
            fprintf(stderr, "Unable to open fd to restore KVM hash table: %s\n",
976
                    strerror(errno));
977
        }
978
    }
979

  
935 980
    while (true) {
936 981
        uint32_t index;
937 982
        uint16_t n_valid, n_invalid;
......
945 990
            break;
946 991
        }
947 992

  
948
        if ((index + n_valid + n_invalid) >=
993
        if ((index + n_valid + n_invalid) >
949 994
            (HTAB_SIZE(spapr) / HASH_PTE_SIZE_64)) {
950 995
            /* Bad index in stream */
951 996
            fprintf(stderr, "htab_load() bad index %d (%hd+%hd entries) "
952
                    "in htab stream\n", index, n_valid, n_invalid);
997
                    "in htab stream (htab_shift=%d)\n", index, n_valid, n_invalid,
998
                    spapr->htab_shift);
953 999
            return -EINVAL;
954 1000
        }
955 1001

  
956
        if (n_valid) {
957
            qemu_get_buffer(f, HPTE(spapr->htab, index),
958
                            HASH_PTE_SIZE_64 * n_valid);
959
        }
960
        if (n_invalid) {
961
            memset(HPTE(spapr->htab, index + n_valid), 0,
962
                   HASH_PTE_SIZE_64 * n_invalid);
1002
        if (spapr->htab) {
1003
            if (n_valid) {
1004
                qemu_get_buffer(f, HPTE(spapr->htab, index),
1005
                                HASH_PTE_SIZE_64 * n_valid);
1006
            }
1007
            if (n_invalid) {
1008
                memset(HPTE(spapr->htab, index + n_valid), 0,
1009
                       HASH_PTE_SIZE_64 * n_invalid);
1010
            }
1011
        } else {
1012
            int rc;
1013

  
1014
            assert(fd >= 0);
1015

  
1016
            rc = kvmppc_load_htab_chunk(f, fd, index, n_valid, n_invalid);
1017
            if (rc < 0) {
1018
                return rc;
1019
            }
963 1020
        }
964 1021
    }
965 1022

  
1023
    if (!spapr->htab) {
1024
        assert(fd >= 0);
1025
        close(fd);
1026
    }
1027

  
966 1028
    return 0;
967 1029
}
968 1030

  
b/include/hw/ppc/spapr.h
37 37
    /* Migration state */
38 38
    int htab_save_index;
39 39
    bool htab_first_pass;
40
    int htab_fd;
40 41
} sPAPREnvironment;
41 42

  
42 43
#define H_SUCCESS         0
b/target-ppc/kvm.c
65 65
static int cap_epr;
66 66
static int cap_ppc_watchdog;
67 67
static int cap_papr;
68
static int cap_htab_fd;
68 69

  
69 70
/* XXX We have a race condition where we actually have a level triggered
70 71
 *     interrupt, but the infrastructure can't expose that yet, so the guest
......
101 102
    cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
102 103
    /* Note: we don't set cap_papr here, because this capability is
103 104
     * only activated after this by kvmppc_set_papr() */
105
    cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
104 106

  
105 107
    if (!cap_interrupt_level) {
106 108
        fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
......
1788 1790
}
1789 1791

  
1790 1792

  
1793
int kvmppc_get_htab_fd(bool write)
1794
{
1795
    struct kvm_get_htab_fd s = {
1796
        .flags = write ? KVM_GET_HTAB_WRITE : 0,
1797
        .start_index = 0,
1798
    };
1799

  
1800
    if (!cap_htab_fd) {
1801
        fprintf(stderr, "KVM version doesn't support saving the hash table\n");
1802
        return -1;
1803
    }
1804

  
1805
    return kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &s);
1806
}
1807

  
1808
int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns)
1809
{
1810
    int64_t starttime = qemu_get_clock_ns(rt_clock);
1811
    uint8_t buf[bufsize];
1812
    ssize_t rc;
1813

  
1814
    do {
1815
        rc = read(fd, buf, bufsize);
1816
        if (rc < 0) {
1817
            fprintf(stderr, "Error reading data from KVM HTAB fd: %s\n",
1818
                    strerror(errno));
1819
            return rc;
1820
        } else if (rc) {
1821
            /* Kernel already retuns data in BE format for the file */
1822
            qemu_put_buffer(f, buf, rc);
1823
        }
1824
    } while ((rc != 0)
1825
             && ((max_ns < 0)
1826
                 || ((qemu_get_clock_ns(rt_clock) - starttime) < max_ns)));
1827

  
1828
    return (rc == 0) ? 1 : 0;
1829
}
1830

  
1831
int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
1832
                           uint16_t n_valid, uint16_t n_invalid)
1833
{
1834
    struct kvm_get_htab_header *buf;
1835
    size_t chunksize = sizeof(*buf) + n_valid*HASH_PTE_SIZE_64;
1836
    ssize_t rc;
1837

  
1838
    buf = alloca(chunksize);
1839
    /* This is KVM on ppc, so this is all big-endian */
1840
    buf->index = index;
1841
    buf->n_valid = n_valid;
1842
    buf->n_invalid = n_invalid;
1843

  
1844
    qemu_get_buffer(f, (void *)(buf + 1), HASH_PTE_SIZE_64*n_valid);
1845

  
1846
    rc = write(fd, buf, chunksize);
1847
    if (rc < 0) {
1848
        fprintf(stderr, "Error writing KVM hash table: %s\n",
1849
                strerror(errno));
1850
        return rc;
1851
    }
1852
    if (rc != chunksize) {
1853
        /* We should never get a short write on a single chunk */
1854
        fprintf(stderr, "Short write, restoring KVM hash table\n");
1855
        return -1;
1856
    }
1857
    return 0;
1858
}
1859

  
1791 1860
bool kvm_arch_stop_on_emulation_error(CPUState *cpu)
1792 1861
{
1793 1862
    return true;
b/target-ppc/kvm_ppc.h
38 38
#endif /* !CONFIG_USER_ONLY */
39 39
int kvmppc_fixup_cpu(PowerPCCPU *cpu);
40 40
bool kvmppc_has_cap_epr(void);
41
int kvmppc_get_htab_fd(bool write);
42
int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns);
43
int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
44
                           uint16_t n_valid, uint16_t n_invalid);
41 45

  
42 46
#else
43 47

  
......
159 163
{
160 164
    return false;
161 165
}
166

  
167
static inline int kvmppc_get_htab_fd(bool write)
168
{
169
    return -1;
170
}
171

  
172
static inline int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize,
173
                                   int64_t max_ns)
174
{
175
    abort();
176
}
177

  
178
static inline int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
179
                                         uint16_t n_valid, uint16_t n_invalid)
180
{
181
    abort();
182
}
183

  
162 184
#endif
163 185

  
164 186
#ifndef CONFIG_KVM

Also available in: Unified diff