Beispiel #1
0
uint64_t xen_memshare(xen_interface_t *xen, domid_t domID, domid_t cloneID) {

    uint64_t shared = 0;

#if __XEN_INTERFACE_VERSION__ < 0x00040600
    uint64_t page, max_page = xc_domain_maximum_gpfn(xen->xc, domID);
#else
    xen_pfn_t page, max_page;
    if (xc_domain_maximum_gpfn(xen->xc, domID, &max_page)) {
        printf("Failed to get max gpfn from Xen!\n");
        goto done;
    }
#endif

    if (!max_page) {
        printf("Failed to get max gpfn!\n");
        goto done;
    }

    if (xc_memshr_control(xen->xc, domID, 1)) {
        printf("Failed to enable memsharing on origin!\n");
        goto done;
    }
    if (xc_memshr_control(xen->xc, cloneID, 1)) {
        printf("Failed to enable memsharing on clone!\n");
        goto done;
    }

    /*
     * page will underflow when done
     */
    for (page = max_page; page <= max_page; page--) {
        uint64_t shandle, chandle;

        if (xc_memshr_nominate_gfn(xen->xc, domID, page, &shandle))
            continue;
        if (xc_memshr_nominate_gfn(xen->xc, cloneID, page, &chandle))
            continue;
        if (xc_memshr_share_gfns(xen->xc, domID, page, shandle, cloneID, page,
            chandle))
            continue;

        shared++;
    }

    done: return shared;
}
Beispiel #2
0
int main(int argc, char **argv) {

    if (argc < 3) {
        printf("Usage: %s origin-domID clone-domID\n", argv[0]);
        return 1;
    }

    domid_t origin = atoi(argv[1]), clone = atoi(argv[2]);

    xc_interface *xc = xc_interface_open(0, 0, 0);
    vcpu_guest_context_any_t vcpu_context;

    uint32_t hvm_context_size;
    uint8_t *hvm_context;

    if (xc == NULL) {
        fprintf(stderr, "xc_interface_open() failed!\n");
        return 0;
    }

    if (xc_vcpu_getcontext(xc, origin, 0, &vcpu_context)) {
        printf("Failed to get the VCPU context of domain %u\n", origin);
        return 1;
    }

    printf("Setting VCPU context of clone\n");

    if (xc_vcpu_setcontext(xc, clone, 0, &vcpu_context)) {
        printf("Failed to set the VCPU context of domain %u\n", clone);
    }

    /*printf("Setting HVM parameters of clone\n");

    int hvm_param_copy = 0;
    while (hvm_param_copy < HVM_PARAM_COUNT) {
        unsigned long value = 0;
        xc_get_hvm_param(xc, origin, hvm_params[hvm_param_copy], &value);
        if (value) {
            switch (hvm_params[hvm_param_copy]) {
            case HVM_PARAM_CONSOLE_PFN:
            case HVM_PARAM_IOREQ_PFN:
            case HVM_PARAM_BUFIOREQ_PFN:
            case HVM_PARAM_STORE_PFN:
                break;
            default:
                printf("Setting HVM param %i with value %lu\n",
                    hvm_params[hvm_param_copy], value);

                xc_set_hvm_param(xc, clone, hvm_params[hvm_param_copy], value);
            break;
            }
        }
        hvm_param_copy++;
    }*/

    hvm_context_size = xc_domain_hvm_getcontext(xc, origin, NULL, 0);
    if (hvm_context_size <= 0) {
        printf("HVM context size <= 0. Not an HVM domain?\n");
        return 1;
    }

    hvm_context = malloc(hvm_context_size * sizeof(uint8_t));

    if (xc_domain_hvm_getcontext(xc, origin, hvm_context, hvm_context_size)
            <= 0) {
        printf("Failed to get HVM context.\n");
        return 1;
    }

    xc_dominfo_t info;
    xc_domain_getinfo(xc, origin, 1, &info);
    int page = xc_domain_maximum_gpfn(xc, origin) + 1;
    printf("Sharing memory.. Origin domain has %lu kb ram and %i pages.\n",
            info.max_memkb, page);

    xc_memshr_control(xc, origin, 1);
    xc_memshr_control(xc, clone, 1);

    uint64_t shandle, chandle;
    int shared = 0;
    while (page >= 0) {
        page--;
        if (xc_memshr_nominate_gfn(xc, origin, page, &shandle)) {
            continue;
        }
        if (xc_memshr_nominate_gfn(xc, clone, page, &chandle)) {
            continue;
        }

        if (xc_memshr_share_gfns(xc, origin, page, shandle, clone, page,
                chandle))
            continue;

        shared++;
    }

    printf("Shared %i pages\n", shared);

    /*hvm_param_copy = 0;
    while (hvm_param_copy < HVM_PARAM_COUNT) {
        unsigned long value = 0;
        switch(hvm_params[hvm_param_copy]) {
            case HVM_PARAM_CONSOLE_PFN:
            case HVM_PARAM_IOREQ_PFN:
            case HVM_PARAM_BUFIOREQ_PFN:
            case HVM_PARAM_STORE_PFN:
                xc_get_hvm_param(xc, origin, hvm_params[hvm_param_copy], &value);
                if (value) {
                    printf("Setting HVM param %i with value %lu\n",
                        hvm_params[hvm_param_copy], value);

                    xc_clear_domain_page(xc, clone, hvm_params[hvm_param_copy]);
                    xc_set_hvm_param(xc, clone, hvm_params[hvm_param_copy], value);
                }
            break;
        }

        hvm_param_copy++;
    }*/

    /*printf("Setting HVM context of clone\n");

    if (xc_domain_hvm_setcontext(xc, clone, hvm_context, hvm_context_size)) {
        printf("Failed to set HVM context.\n");
        return 1;
    }*/

    xc_interface_close(xc);
    return 0;
}