Commit f57bceb6 authored by Robert Hoo's avatar Robert Hoo Committed by Eduardo Habkost
Browse files

kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl



Add kvm_get_supported_feature_msrs() to get supported MSR feature index list.
Add kvm_arch_get_supported_msr_feature() to get each MSR features value.

Signed-off-by: default avatarRobert Hoo <robert.hu@linux.intel.com>
Message-Id: <1539578845-37944-2-git-send-email-robert.hu@linux.intel.com>
Reviewed-by: default avatarEduardo Habkost <ehabkost@redhat.com>
Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
parent 38bf9e3b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension);

uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
                                      uint32_t index, int reg);
uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);


void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);

+80 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ static int has_pit_state2;
static bool has_msr_mcg_ext_ctl;

static struct kvm_cpuid2 *cpuid_cache;
static struct kvm_msr_list *kvm_feature_msrs;

int kvm_has_pit_state2(void)
{
@@ -420,6 +421,42 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
    return ret;
}

uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
{
    struct {
        struct kvm_msrs info;
        struct kvm_msr_entry entries[1];
    } msr_data;
    uint32_t ret;

    if (kvm_feature_msrs == NULL) { /* Host doesn't support feature MSRs */
        return 0;
    }

    /* Check if requested MSR is supported feature MSR */
    int i;
    for (i = 0; i < kvm_feature_msrs->nmsrs; i++)
        if (kvm_feature_msrs->indices[i] == index) {
            break;
        }
    if (i == kvm_feature_msrs->nmsrs) {
        return 0; /* if the feature MSR is not supported, simply return 0 */
    }

    msr_data.info.nmsrs = 1;
    msr_data.entries[0].index = index;

    ret = kvm_ioctl(s, KVM_GET_MSRS, &msr_data);
    if (ret != 1) {
        error_report("KVM get MSR (index=0x%x) feature failed, %s",
            index, strerror(-ret));
        exit(1);
    }

    return msr_data.entries[0].data;
}


typedef struct HWPoisonPage {
    ram_addr_t ram_addr;
    QLIST_ENTRY(HWPoisonPage) list;
@@ -1286,6 +1323,47 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
    }
}

static int kvm_get_supported_feature_msrs(KVMState *s)
{
    int ret = 0;

    if (kvm_feature_msrs != NULL) {
        return 0;
    }

    if (!kvm_check_extension(s, KVM_CAP_GET_MSR_FEATURES)) {
        return 0;
    }

    struct kvm_msr_list msr_list;

    msr_list.nmsrs = 0;
    ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, &msr_list);
    if (ret < 0 && ret != -E2BIG) {
        error_report("Fetch KVM feature MSR list failed: %s",
            strerror(-ret));
        return ret;
    }

    assert(msr_list.nmsrs > 0);
    kvm_feature_msrs = (struct kvm_msr_list *) \
        g_malloc0(sizeof(msr_list) +
                 msr_list.nmsrs * sizeof(msr_list.indices[0]));

    kvm_feature_msrs->nmsrs = msr_list.nmsrs;
    ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, kvm_feature_msrs);

    if (ret < 0) {
        error_report("Fetch KVM feature MSR list failed: %s",
            strerror(-ret));
        g_free(kvm_feature_msrs);
        kvm_feature_msrs = NULL;
        return ret;
    }

    return 0;
}

static int kvm_get_supported_msrs(KVMState *s)
{
    static int kvm_supported_msrs;
@@ -1439,6 +1517,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
        return ret;
    }

    kvm_get_supported_feature_msrs(s);

    uname(&utsname);
    lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;