static void init_hypercalls(void) { uint32_t eax, ebx, ecx, edx; unsigned long i; char signature[13]; xen_extraversion_t extraversion; uint32_t base; for ( base = 0x40000000; base < 0x40010000; base += 0x100 ) { cpuid(base, &eax, &ebx, &ecx, &edx); *(uint32_t *)(signature + 0) = ebx; *(uint32_t *)(signature + 4) = ecx; *(uint32_t *)(signature + 8) = edx; signature[12] = '\0'; if ( !strcmp("XenVMMXenVMM", signature) ) break; } BUG_ON(strcmp("XenVMMXenVMM", signature) || ((eax - base) < 2)); /* Fill in hypercall transfer pages. */ cpuid(base + 2, &eax, &ebx, &ecx, &edx); for ( i = 0; i < eax; i++ ) wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i); /* Print version information. */ cpuid(base + 1, &eax, &ebx, &ecx, &edx); hypercall_xen_version(XENVER_extraversion, extraversion); printf("Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion); }
/* Fill in hypercall transfer pages. */ void xen_hypercall_setup(void) { u32 eax, ebx, ecx, edx; xen_extraversion_t extraversion; unsigned long i; if (!runningOnXen()) return; cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx); xen_hypercall_page = (unsigned long)memalign_high(PAGE_SIZE, eax*PAGE_SIZE); if (!xen_hypercall_page) panic("unable to allocate Xen hypercall page\n"); dprintf(1, "Allocated Xen hypercall page at %lx\n", xen_hypercall_page); for ( i = 0; i < eax; i++ ) wrmsr(ebx, xen_hypercall_page + (i << 12) + i); /* Print version information. */ cpuid(xen_cpuid_base + 1, &eax, &ebx, &ecx, &edx); hypercall_xen_version(XENVER_extraversion, extraversion); dprintf(1, "Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion); }