Revision 0c31b744

b/target-i386/kvm.c
92 92
    return cpuid;
93 93
}
94 94

  
95
#ifdef CONFIG_KVM_PARA
96
struct kvm_para_features {
97
    int cap;
98
    int feature;
99
} para_features[] = {
100
    { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
101
    { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
102
    { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
103
#ifdef KVM_CAP_ASYNC_PF
104
    { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
105
#endif
106
    { -1, -1 }
107
};
108

  
109
static int get_para_features(CPUState *env)
110
{
111
    int i, features = 0;
112

  
113
    for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
114
        if (kvm_check_extension(env->kvm_state, para_features[i].cap)) {
115
            features |= (1 << para_features[i].feature);
116
        }
117
    }
118

  
119
    return features;
120
}
121
#endif
122

  
123

  
95 124
uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
96 125
                                      uint32_t index, int reg)
97 126
{
......
99 128
    int i, max;
100 129
    uint32_t ret = 0;
101 130
    uint32_t cpuid_1_edx;
131
#ifdef CONFIG_KVM_PARA
132
    int has_kvm_features = 0;
133
#endif
102 134

  
103 135
    max = 1;
104 136
    while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) {
......
108 140
    for (i = 0; i < cpuid->nent; ++i) {
109 141
        if (cpuid->entries[i].function == function &&
110 142
            cpuid->entries[i].index == index) {
143
#ifdef CONFIG_KVM_PARA
144
            if (cpuid->entries[i].function == KVM_CPUID_FEATURES) {
145
                has_kvm_features = 1;
146
            }
147
#endif
111 148
            switch (reg) {
112 149
            case R_EAX:
113 150
                ret = cpuid->entries[i].eax;
......
140 177

  
141 178
    qemu_free(cpuid);
142 179

  
143
    return ret;
144
}
145

  
146 180
#ifdef CONFIG_KVM_PARA
147
struct kvm_para_features {
148
    int cap;
149
    int feature;
150
} para_features[] = {
151
    { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
152
    { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
153
    { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
154
#ifdef KVM_CAP_ASYNC_PF
155
    { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
156
#endif
157
    { -1, -1 }
158
};
159

  
160
static int get_para_features(CPUState *env)
161
{
162
    int i, features = 0;
163

  
164
    for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
165
        if (kvm_check_extension(env->kvm_state, para_features[i].cap)) {
166
            features |= (1 << para_features[i].feature);
167
        }
181
    /* fallback for older kernels */
182
    if (!has_kvm_features && (function == KVM_CPUID_FEATURES)) {
183
        ret = get_para_features(env);
168 184
    }
169
#ifdef KVM_CAP_ASYNC_PF
170
    has_msr_async_pf_en = features & (1 << KVM_FEATURE_ASYNC_PF);
171 185
#endif
172
    return features;
186

  
187
    return ret;
173 188
}
174
#endif /* CONFIG_KVM_PARA */
175 189

  
176 190
typedef struct HWPoisonPage {
177 191
    ram_addr_t ram_addr;
......
397 411
    c = &cpuid_data.entries[cpuid_i++];
398 412
    memset(c, 0, sizeof(*c));
399 413
    c->function = KVM_CPUID_FEATURES;
400
    c->eax = env->cpuid_kvm_features & get_para_features(env);
414
    c->eax = env->cpuid_kvm_features & kvm_arch_get_supported_cpuid(env,
415
                                                KVM_CPUID_FEATURES, 0, R_EAX);
416

  
417
#ifdef KVM_CAP_ASYNC_PF
418
    has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
419
#endif
420

  
401 421
#endif
402 422

  
403 423
    cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);

Also available in: Unified diff