Beispiel #1
0
int cpuid_viridian_leaves(unsigned int leaf, unsigned int *eax,
                          unsigned int *ebx, unsigned int *ecx,
                          unsigned int *edx)
{
    struct domain *d = current->domain;

    if ( !is_viridian_domain(d) )
        return 0;

    leaf -= 0x40000000;
    if ( leaf > 6 )
        return 0;

    *eax = *ebx = *ecx = *edx = 0;
    switch ( leaf )
    {
    case 0:
        *eax = 0x40000006; /* Maximum leaf */
        *ebx = 0x7263694d; /* Magic numbers  */
        *ecx = 0x666F736F;
        *edx = 0x76482074;
        break;
    case 1:
        *eax = 0x31237648; /* Version number */
        break;
    case 2:
        /* Hypervisor information, but only if the guest has set its
           own version number. */
        if ( d->arch.hvm_domain.viridian.guest_os_id.raw == 0 )
            break;
        *eax = 1; /* Build number */
        *ebx = (xen_major_version() << 16) | xen_minor_version();
        *ecx = 0; /* SP */
        *edx = 0; /* Service branch and number */
        break;
    case 3:
        /* Which hypervisor MSRs are available to the guest */
        *eax = (CPUID3A_MSR_APIC_ACCESS |
                CPUID3A_MSR_HYPERCALL   |
                CPUID3A_MSR_VP_INDEX);
        break;
    case 4:
        /* Recommended hypercall usage. */
        if ( (d->arch.hvm_domain.viridian.guest_os_id.raw == 0) ||
             (d->arch.hvm_domain.viridian.guest_os_id.fields.os < 4) )
            break;
        *eax = (CPUID4A_MSR_BASED_APIC |
                CPUID4A_RELAX_TIMER_INT);
        *ebx = 2047; /* long spin count */
        break;
    }

    return 1;
}
static ofdn_t ofd_xen_props(void *m, struct domain *d, ulong shared_info)
{
    ofdn_t n;
    static const char path[] = "/xen";
    static const char console[] = "/xen/console";

    n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
    if (n > 0) {
        char xen[256];
        int xl;
        u64 val[2];
        s32 dom_id;

        dom_id = d->domain_id;

        ofd_prop_add(m, n, "reg", &dom_id, sizeof (dom_id));
        ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);

        xl = snprintf(xen, sizeof (xen), "Xen-%d.%d%s",
                xen_major_version(), xen_minor_version(), xen_extra_version());
        ASSERT(xl < sizeof (xen));
        ofd_prop_add(m, n, "version", xen, xl + 1);

        /* convert xen pointer to guest physical */
        val[0] = shared_info;
        val[1] = PAGE_SIZE;
        ofd_prop_add(m, n, "shared-info", val, sizeof (val));

        /* reserve PAGE_SIZE @ addr shared info */
        ofd_prop_add(m, n, "reserved", val, sizeof (val));

        /* flags |= SIF_PROVILEDGED; */
        ofd_prop_add(m, n, "privileged", NULL, 0);

        /* flags |= SIF_INITDOMAIN; */
        ofd_prop_add(m, n, "initdomain", NULL, 0);

        /* tell dom0 that Xen depends on it to have power control */
        if (!rtas_entry)
            ofd_prop_add(m, n, "power-control", NULL, 0);

        /* tell dom0 where granted pages go in the linear map */
        val[0] = cpu_foreign_map_order();
        val[1] = d->arch.foreign_mfn_count;
        ofd_prop_add(m, n, "foreign-map", val, sizeof (val));

        n = ofd_node_add(m, n, console, sizeof (console));
        if (n > 0) {
            val[0] = 0;
            ofd_prop_add(m, n, "interrupts", &val[0], sizeof (val[0]));
        }
    }
    return n;
}
Beispiel #3
0
/* XXX could/should be common code */
static void print_xen_info(void)
{
    char taint_str[TAINT_STRING_MAX_LEN];

    printk("----[ Xen-%d.%d%s  %s  debug=%c  %s ]----\n",
           xen_major_version(), xen_minor_version(), xen_extra_version(),
#ifdef CONFIG_ARM_32
           "arm32",
#else
           "arm64",
#endif
           debug_build() ? 'y' : 'n', print_tainted(taint_str));
}
Beispiel #4
0
/* XXX could/should be common code */
static void print_xen_info(void)
{
    char taint_str[TAINT_STRING_MAX_LEN];
    char debug = 'n';

#ifndef NDEBUG
    debug = 'y';
#endif

    printk("----[ Xen-%d.%d%s  x86_64  debug=%c  %s ]----\n",
           xen_major_version(), xen_minor_version(), xen_extra_version(),
           debug, print_tainted(taint_str));
}
Beispiel #5
0
/* Set up the single Xen-specific-info crash note. */
crash_xen_info_t *kexec_crash_save_info(void)
{
    int cpu = smp_processor_id();
    crash_xen_info_t info;
    crash_xen_info_t *out = (crash_xen_info_t *)ELFNOTE_DESC(xen_crash_note);

    BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus));

    memset(&info, 0, sizeof(info));
    info.xen_major_version = xen_major_version();
    info.xen_minor_version = xen_minor_version();
    info.xen_extra_version = __pa(xen_extra_version());
    info.xen_changeset = __pa(xen_changeset());
    info.xen_compiler = __pa(xen_compiler());
    info.xen_compile_date = __pa(xen_compile_date());
    info.xen_compile_time = __pa(xen_compile_time());
    info.tainted = tainted;

    /* Copy from guaranteed-aligned local copy to possibly-unaligned dest. */
    memcpy(out, &info, sizeof(info));

    return out;
}
Beispiel #6
0
void cpuid_viridian_leaves(const struct vcpu *v, uint32_t leaf,
                           uint32_t subleaf, struct cpuid_leaf *res)
{
    const struct domain *d = v->domain;

    ASSERT(is_viridian_domain(d));
    ASSERT(leaf >= 0x40000000 && leaf < 0x40000100);

    leaf -= 0x40000000;

    switch ( leaf )
    {
    case 0:
        res->a = 0x40000006; /* Maximum leaf */
        res->b = 0x7263694d; /* Magic numbers  */
        res->c = 0x666F736F;
        res->d = 0x76482074;
        break;

    case 1:
        res->a = 0x31237648; /* Version number */
        break;

    case 2:
        /* Hypervisor information, but only if the guest has set its
           own version number. */
        if ( d->arch.hvm_domain.viridian.guest_os_id.raw == 0 )
            break;
        res->a = 1; /* Build number */
        res->b = (xen_major_version() << 16) | xen_minor_version();
        res->c = 0; /* SP */
        res->d = 0; /* Service branch and number */
        break;

    case 3:
        /* Which hypervisor MSRs are available to the guest */
        res->a = (CPUID3A_MSR_APIC_ACCESS |
                  CPUID3A_MSR_HYPERCALL   |
                  CPUID3A_MSR_VP_INDEX);
        if ( !(viridian_feature_mask(d) & HVMPV_no_freq) )
            res->a |= CPUID3A_MSR_FREQ;
        if ( viridian_feature_mask(d) & HVMPV_time_ref_count )
            res->a |= CPUID3A_MSR_TIME_REF_COUNT;
        if ( viridian_feature_mask(d) & HVMPV_reference_tsc )
            res->a |= CPUID3A_MSR_REFERENCE_TSC;
        break;

    case 4:
        /* Recommended hypercall usage. */
        if ( (d->arch.hvm_domain.viridian.guest_os_id.raw == 0) ||
             (d->arch.hvm_domain.viridian.guest_os_id.fields.os < 4) )
            break;
        res->a = CPUID4A_RELAX_TIMER_INT;
        if ( viridian_feature_mask(d) & HVMPV_hcall_remote_tlb_flush )
            res->a |= CPUID4A_HCALL_REMOTE_TLB_FLUSH;
        if ( !cpu_has_vmx_apic_reg_virt )
            res->a |= CPUID4A_MSR_BASED_APIC;
        res->b = 2047; /* long spin count */
        break;

    case 6:
        /* Detected and in use hardware features. */
        if ( cpu_has_vmx_virtualize_apic_accesses )
            res->a |= CPUID6A_APIC_OVERLAY;
        if ( cpu_has_vmx_msr_bitmap || (read_efer() & EFER_SVME) )
            res->a |= CPUID6A_MSR_BITMAPS;
        if ( hap_enabled(d) )
            res->a |= CPUID6A_NESTED_PAGING;
        break;
    }
}
Beispiel #7
0
int cpuid_viridian_leaves(unsigned int leaf, unsigned int *eax,
                          unsigned int *ebx, unsigned int *ecx,
                          unsigned int *edx)
{
    struct domain *d = current->domain;

    if ( !is_viridian_domain(d) )
        return 0;

    leaf -= 0x40000000;
    if ( leaf > 6 )
        return 0;

    *eax = *ebx = *ecx = *edx = 0;
    switch ( leaf )
    {
    case 0:
        *eax = 0x40000006; /* Maximum leaf */
        *ebx = 0x7263694d; /* Magic numbers  */
        *ecx = 0x666F736F;
        *edx = 0x76482074;
        break;
    case 1:
        *eax = 0x31237648; /* Version number */
        break;
    case 2:
        /* Hypervisor information, but only if the guest has set its
           own version number. */
        if ( d->arch.hvm_domain.viridian.guest_os_id.raw == 0 )
            break;
        *eax = 1; /* Build number */
        *ebx = (xen_major_version() << 16) | xen_minor_version();
        *ecx = 0; /* SP */
        *edx = 0; /* Service branch and number */
        break;
    case 3:
        /* Which hypervisor MSRs are available to the guest */
        *eax = (CPUID3A_MSR_APIC_ACCESS |
                CPUID3A_MSR_HYPERCALL   |
                CPUID3A_MSR_VP_INDEX);
        break;
    case 4:
        /* Recommended hypercall usage. */
        if ( (d->arch.hvm_domain.viridian.guest_os_id.raw == 0) ||
             (d->arch.hvm_domain.viridian.guest_os_id.fields.os < 4) )
            break;
        *eax = CPUID4A_RELAX_TIMER_INT;
        if ( !cpu_has_vmx_apic_reg_virt )
            *eax |= CPUID4A_MSR_BASED_APIC;
        *ebx = 2047; /* long spin count */
        break;
    case 6:
        /* Detected and in use hardware features. */
        if ( cpu_has_vmx_virtualize_apic_accesses )
            *eax |= CPUID6A_APIC_OVERLAY;
        if ( cpu_has_vmx_msr_bitmap || (read_efer() & EFER_SVME) )
            *eax |= CPUID6A_MSR_BITMAPS;
        if ( hap_enabled(d) )
            *eax |= CPUID6A_NESTED_PAGING;
        break;
    }

    return 1;
}