Beispiel #1
0
static int alloc_magic_pages(struct xc_dom_image *dom)
{
    int rc, i;
    xen_pfn_t p2m[NR_MAGIC_PAGES];

    DOMPRINTF_CALLED(dom->xch);

    for (i = 0; i < NR_MAGIC_PAGES; i++)
        p2m[i] = dom->rambase_pfn + dom->total_pages + i;

    rc = xc_domain_populate_physmap_exact(
            dom->xch, dom->guest_domid, NR_MAGIC_PAGES,
            0, 0, p2m);
    if ( rc < 0 )
        return rc;

    dom->console_pfn = dom->rambase_pfn + dom->total_pages + CONSOLE_PFN_OFFSET;
    dom->xenstore_pfn = dom->rambase_pfn + dom->total_pages + XENSTORE_PFN_OFFSET;

    xc_clear_domain_page(dom->xch, dom->guest_domid, dom->console_pfn);
    xc_clear_domain_page(dom->xch, dom->guest_domid, dom->xenstore_pfn);
    xc_set_hvm_param(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_PFN,
            dom->console_pfn);
    xc_set_hvm_param(dom->xch, dom->guest_domid, HVM_PARAM_STORE_PFN,
            dom->xenstore_pfn);
    /* allocated by toolstack */
    xc_set_hvm_param(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_EVTCHN,
            dom->console_evtchn);
    xc_set_hvm_param(dom->xch, dom->guest_domid, HVM_PARAM_STORE_EVTCHN,
            dom->xenstore_evtchn);

    return 0;
}
Beispiel #2
0
/*
 * Process an HVM_PARAMS record from the stream.
 */
static int handle_hvm_params(struct xc_sr_context *ctx,
                             struct xc_sr_record *rec)
{
    xc_interface *xch = ctx->xch;
    struct xc_sr_rec_hvm_params *hdr = rec->data;
    struct xc_sr_rec_hvm_params_entry *entry = hdr->param;
    unsigned int i;
    int rc;

    if ( rec->length < sizeof(*hdr)
         || rec->length < sizeof(*hdr) + hdr->count * sizeof(*entry) )
    {
        ERROR("hvm_params record is too short");
        return -1;
    }

    for ( i = 0; i < hdr->count; i++, entry++ )
    {
        switch ( entry->index )
        {
        case HVM_PARAM_CONSOLE_PFN:
            ctx->restore.console_gfn = entry->value;
            xc_clear_domain_page(xch, ctx->domid, entry->value);
            break;
        case HVM_PARAM_STORE_PFN:
            ctx->restore.xenstore_gfn = entry->value;
            xc_clear_domain_page(xch, ctx->domid, entry->value);
            break;
        case HVM_PARAM_IOREQ_PFN:
        case HVM_PARAM_BUFIOREQ_PFN:
            xc_clear_domain_page(xch, ctx->domid, entry->value);
            break;
        }

        rc = xc_hvm_param_set(xch, ctx->domid, entry->index, entry->value);
        if ( rc < 0 )
        {
            PERROR("set HVM param %"PRId64" = 0x%016"PRIx64,
                   entry->index, entry->value);
            return rc;
        }
    }
    return 0;
}
static int clear_page(struct xc_dom_image *dom, xen_pfn_t pfn)
{
    xen_pfn_t dst;
    int rc;

    if ( pfn == 0 )
        return 0;

    dst = xc_dom_p2m_host(dom, pfn);
    xc_dom_printf("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n",
                  __FUNCTION__, pfn, dst);
    rc = xc_clear_domain_page(dom->guest_xc, dom->guest_domid, dst);
    if ( rc != 0 )
        xc_dom_panic(XC_INTERNAL_ERROR,
                     "%s: xc_clear_domain_page failed (pfn 0x%" PRIpfn
                     ", rc=%d)\n", __FUNCTION__, pfn, rc);
    return rc;
}
Beispiel #4
0
/*
 * Process an HVM_PARAMS record from the stream.
 */
static int handle_hvm_params(struct xc_sr_context *ctx,
                             struct xc_sr_record *rec)
{
    xc_interface *xch = ctx->xch;
    struct xc_sr_rec_hvm_params *hdr = rec->data;
    struct xc_sr_rec_hvm_params_entry *entry = hdr->param;
    unsigned int i;
    int rc;

    if ( rec->length < sizeof(*hdr) )
    {
        ERROR("HVM_PARAMS record truncated: length %u, header size %zu",
              rec->length, sizeof(*hdr));
        return -1;
    }

    if ( rec->length != (sizeof(*hdr) + hdr->count * sizeof(*entry)) )
    {
        ERROR("HVM_PARAMS record truncated: header %zu, count %u, "
              "expected len %zu, got %u",
              sizeof(*hdr), hdr->count, hdr->count * sizeof(*entry),
              rec->length);
        return -1;
    }

    /*
     * Tolerate empty records.  Older sending sides used to accidentally
     * generate them.
     */
    if ( hdr->count == 0 )
    {
        DBGPRINTF("Skipping empty HVM_PARAMS record\n");
        return 0;
    }

    for ( i = 0; i < hdr->count; i++, entry++ )
    {
        switch ( entry->index )
        {
        case HVM_PARAM_CONSOLE_PFN:
            ctx->restore.console_gfn = entry->value;
            xc_clear_domain_page(xch, ctx->domid, entry->value);
            break;
        case HVM_PARAM_STORE_PFN:
            ctx->restore.xenstore_gfn = entry->value;
            xc_clear_domain_page(xch, ctx->domid, entry->value);
            break;
        case HVM_PARAM_IOREQ_PFN:
        case HVM_PARAM_BUFIOREQ_PFN:
            xc_clear_domain_page(xch, ctx->domid, entry->value);
            break;
        }

        rc = xc_hvm_param_set(xch, ctx->domid, entry->index, entry->value);
        if ( rc < 0 )
        {
            PERROR("set HVM param %"PRId64" = 0x%016"PRIx64,
                   entry->index, entry->value);
            return rc;
        }
    }
    return 0;
}
Beispiel #5
0
static int
xc_ia64_hvm_recv_context(int xc_handle, int io_fd, uint32_t dom,
                         unsigned long shared_info_frame,
                         struct xen_ia64_p2m_table *p2m_table,
                         unsigned int store_evtchn, unsigned long *store_mfn,
                         unsigned int console_evtchn,
                         unsigned long *console_mfn)
{
    int rc = -1;
    xc_dominfo_t info;
    unsigned int i;
    
    /* cpumap */
    uint64_t *vcpumap = NULL;

    /* HVM: magic frames for ioreqs and xenstore comms */
    const int hvm_params[] = {
        HVM_PARAM_STORE_PFN,
        HVM_PARAM_IOREQ_PFN,
        HVM_PARAM_BUFIOREQ_PFN,
        HVM_PARAM_BUFPIOREQ_PFN,
    };
    const int NR_PARAMS = sizeof(hvm_params) / sizeof(hvm_params[0]);
    /* ioreq_pfn, bufioreq_pfn, store_pfn */
    uint64_t magic_pfns[NR_PARAMS];

    /* HVM: a buffer for holding HVM contxt */
    uint64_t rec_size = 0;
    uint8_t *hvm_buf = NULL;

    /* Read shared info.  */
    if (xc_ia64_recv_shared_info(xc_handle, io_fd, dom, shared_info_frame,
                                 NULL))
        goto out;

    /* vcpu map */
    if (xc_domain_getinfo(xc_handle, dom, 1, &info) != 1) {
        ERROR("Could not get domain info");
        goto out;
    }
    if (xc_ia64_recv_vcpumap(&info, io_fd, &vcpumap))
        goto out;
    
    /* vcpu context */
    for (i = 0; i <= info.max_vcpu_id; i++) {
        /* A copy of the CPU context of the guest. */
        vcpu_guest_context_any_t ctxt_any;

        if (!__test_bit(i, vcpumap))
            continue;

        if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, i, &ctxt_any))
            goto out;

        /* system context of vcpu is recieved as hvm context. */
    }    

    /* Set HVM-specific parameters */
    if (read_exact(io_fd, magic_pfns, sizeof(magic_pfns))) {
        ERROR("error reading magic page addresses");
        goto out;
    }

    /* These comms pages need to be zeroed at the start of day */
    for (i = 0; i < NR_PARAMS; i++) {
        rc = xc_clear_domain_page(xc_handle, dom, magic_pfns[i]);
        if (rc != 0) {
            ERROR("error zeroing magic pages: %i", rc);
            goto out;
        }
        rc = xc_set_hvm_param(xc_handle, dom, hvm_params[i], magic_pfns[i]);
        if (rc != 0) {
            ERROR("error setting HVM params: %i", rc);
            goto out;
        }
    }
    rc = xc_set_hvm_param(xc_handle, dom,
                          HVM_PARAM_STORE_EVTCHN, store_evtchn);
    if (rc != 0) {
        ERROR("error setting HVM params: %i", rc);
        goto out;
    }
    rc = -1;
    *store_mfn = magic_pfns[0];

    /* Read HVM context */
    if (read_exact(io_fd, &rec_size, sizeof(rec_size))) {
        ERROR("error read hvm context size!\n");
        goto out;
    }

    hvm_buf = malloc(rec_size);
    if (hvm_buf == NULL) {
        ERROR("memory alloc for hvm context buffer failed");
        errno = ENOMEM;
        goto out;
    }

    if (read_exact(io_fd, hvm_buf, rec_size)) {
        ERROR("error loading the HVM context");
        goto out;
    }

    rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_size);
    if (rc != 0) {
        ERROR("error setting the HVM context");
        goto out;
    }
       
    rc = 0;

out:
    if (vcpumap != NULL)
        free(vcpumap);
    if (hvm_buf != NULL)
        free(hvm_buf);
    return rc;
}