Ejemplo n.º 1
0
/**
 * Handles ATAPI_PTV4V_OPEN command from qemu stubdom.
 * @param[in] hs: Helper state pointer.
 * @param[in] buf: Data packet received from qemu.
 * @param[in] len: Length of data packet received.
 * @returns 0 on success, -1 on errror.
 */
static int atapi_ptv4v_open(ATAPIPTHelperState *hs, uint8_t *buf, size_t len)
{
    pt_v4vcmd_open_request_t *request = (pt_v4vcmd_open_request_t *)buf;
    pt_v4vcmd_open_response_t response;
    ATAPIPTDeviceState *ds;

    if (len != sizeof(*request)) {
        PT_LOG("error: mismatch buffer size %d vs %d", len, sizeof(*request));
        return -1;
    }

    ds = init_device_state(hs, request->device_path);
    if (!ds) {
        PT_LOG("error: unable to open device path!\n");
        return -1;
    }

    response.cmd = ATAPI_PTV4V_OPEN;
    response.device_id = ds->device_id;

    PT_LOG("opened %s - id = %d\n", ds->device_path, ds->device_id);

    if (!pt_v4v_send_message(hs, &response, sizeof(response))) {
        PT_LOG("error: failed to send a message to %s", ds->device_path);
        return -1;
    }

    return 0;
}
Ejemplo n.º 2
0
/**
 * Handles ATAPI_PTV4V_ACQUIRE_LOCK command from qemu stubdom.
 * @param[in] hs: Helper state pointer.
 * @param[in] buf: Data packet received from qemu.
 * @param[in] len: Length of data packet received.
 * @returns 0 on success, -1 on errror.
 */
static int atapi_ptv4v_acquire_lock(ATAPIPTHelperState* hs, uint8_t *buf,
                                    size_t len)
{
    pt_v4vcmd_acquire_lock_request_t *request;
    pt_v4vcmd_acquire_lock_response_t response;
    ATAPIPTDeviceState *ds;

    request = (pt_v4vcmd_acquire_lock_request_t *)buf;

    if (len != sizeof(*request)) {
        PT_LOG("error: mismatch buffer size %d vs %d", len, sizeof(*request));
        return -1;
    }

    ds = device_id_to_device_state(hs, request->device_id);
    if (ds == NULL) {
        PT_LOG("error: invalid device id!\n");
        return -1;
    }

    acquire_global_lock(ds);

    response.cmd = ATAPI_PTV4V_ACQUIRE_LOCK;
    response.device_id = ds->device_id;
    response.lock_state = ds->lock_state;

    PT_LOG("acquire lock for %s = %d\n", ds->device_path, ds->lock_state);

    if (!pt_v4v_send_message(hs, &response, sizeof(response))) {
        PT_LOG("error: failed to send a message to %s", ds->device_path);
        return -1;
    }

    return 0;
}
Ejemplo n.º 3
0
/* Being called each time a mmio region has been updated */
void pt_iomem_map(PCIDevice *d, int i, uint32_t e_phys, uint32_t e_size,
                  int type)
{
    struct pt_dev *assigned_device  = (struct pt_dev *)d; 
    uint32_t old_ebase = assigned_device->bases[i].e_physbase;
    int first_map = ( assigned_device->bases[i].e_size == 0 );
    int ret = 0;

    assigned_device->bases[i].e_physbase = e_phys;
    assigned_device->bases[i].e_size= e_size;

    PT_LOG("e_phys=%08x maddr=%08x type=%d len=%08x index=%d\n",
        e_phys, assigned_device->bases[i].access.maddr, type, e_size, i);

    if ( e_size == 0 )
        return;

    if ( !first_map )
    {
        /* Remove old mapping */
        ret = xc_domain_memory_mapping(xc_handle, domid,
                old_ebase >> XC_PAGE_SHIFT,
                assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT,
                (e_size+XC_PAGE_SIZE-1) >> XC_PAGE_SHIFT,
                DPCI_REMOVE_MAPPING);
        if ( ret != 0 )
        {
            PT_LOG("Error: remove old mapping failed!\n");
            return;
        }
    }
Ejemplo n.º 4
0
/**
 * Initializes helper state.
 * @param[in] hs
 * @returns 0 on succes, otherwise -1.
 */
static int init_helper_state(ATAPIPTHelperState *hs)
{
    uint32_t v4v_ring_size = V4V_ATAPI_PT_RING_SIZE;

    hs->v4v_fd = v4v_socket(SOCK_DGRAM);

    if (hs->v4v_fd == -1) {
        PT_LOG("unable to create a v4vsocket");
        return -1;
    }

    hs->local_addr.port = ATAPI_CDROM_PORT;
    hs->local_addr.domain = V4V_DOMID_ANY;

    hs->remote_addr.port = V4V_PORT_NONE;
    hs->remote_addr.domain = hs->stubdom_id;

    ioctl(hs->v4v_fd, V4VIOCSETRINGSIZE, &v4v_ring_size);
    if (v4v_bind(hs->v4v_fd, &hs->local_addr, hs->stubdom_id) == -1) {
        PT_LOG("unable to bind the v4vsocket");
        v4v_close(hs->v4v_fd);
        hs->v4v_fd = -1;
        return -1;
    }

    return 0;
}
Ejemplo n.º 5
0
/*
 * register VGA resources for the domain with assigned gfx
 */
int register_vga_regions(struct pt_dev *real_device)
{
    u32 vendor_id, igd_opregion;
    int ret = 0;

    if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 )
        return ret;

    ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3B0,
            0x3B0, 0xC, DPCI_ADD_MAPPING);

    ret |= xc_domain_ioport_mapping(xc_handle, domid, 0x3C0,
            0x3C0, 0x20, DPCI_ADD_MAPPING);

    ret |= xc_domain_memory_mapping(xc_handle, domid,
            0xa0000 >> XC_PAGE_SHIFT,
            0xa0000 >> XC_PAGE_SHIFT,
            0x20,
            DPCI_ADD_MAPPING);

    /* 1:1 map ASL Storage register value */
    vendor_id = pt_pci_host_read(0, 2, 0, 0, 2);
    igd_opregion = pt_pci_host_read(0, 2, 0, 0xfc, 4);
    if ( (vendor_id == 0x8086) && igd_opregion )
    {
        ret |= xc_domain_memory_mapping(xc_handle, domid,
                igd_opregion >> XC_PAGE_SHIFT,
                igd_opregion >> XC_PAGE_SHIFT,
                2,
                DPCI_ADD_MAPPING);
        PT_LOG("register_vga: igd_opregion = %x\n", igd_opregion);
    }
Ejemplo n.º 6
0
uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len)
{
    uint32_t val;

    assert(pci_dev->devfn == 0x00);
    if ( !igd_passthru ) {
        return pci_default_read_config(pci_dev, config_addr, len);
    }

    switch (config_addr)
    {
        case 0x00:        /* vendor id */
        case 0x02:        /* device id */
        case 0x52:        /* processor graphics control register */
        case 0xa0:        /* top of memory */
        case 0xb0:        /* ILK: BSM: should read from dev 2 offset 0x5c */
        case 0x58:        /* SNB: PAVPC Offset */
        case 0xa4:        /* SNB: graphics base of stolen memory */
        case 0xa8:        /* SNB: base of GTT stolen memory */
            val = pt_pci_host_read(0, PCI_SLOT(pci_dev->devfn),
                                   0, config_addr, len);
            PT_LOG("pci_config_read: %x:%x.%x: addr=%x len=%x val=%x\n",
                   pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn),
                   PCI_FUNC(pci_dev->devfn), config_addr, len, val);
            break;
        default:
            val = pci_default_read_config(pci_dev, config_addr, len);
    }
    return val;
}
Ejemplo n.º 7
0
PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs) 
{
#ifdef SOLARIS
	thr_setconcurrency(numCPUs);	
#else
	PT_LOG("PR_SetConcurrency");
#endif
}
Ejemplo n.º 8
0
/**
 * Handles ATAPI_PTV4V_SG_GET_RESERVED_SIZE command from qemu stubdom.
 * @param[in] hs: Helper state pointer.
 * @param[in] buf: Data packet received from qemu.
 * @param[in] len: Length of data packet received.
 * @returns 0 on success, -1 on errror.
 */
static int atapi_ptv4v_sg_get_reserved_size(ATAPIPTHelperState* hs,
                                            uint8_t *buf, size_t len)
{
    pt_v4vcmd_sg_get_reserved_size_request_t *request;
    pt_v4vcmd_sg_get_reserved_size_response_t response;
    ATAPIPTDeviceState *ds;

    request = (pt_v4vcmd_sg_get_reserved_size_request_t *)buf;

    if (len != sizeof(*request)) {
        PT_LOG("error: mismatch buffer size %d vs %d", len, sizeof(*request));
        return -1;
    }

    ds = device_id_to_device_state(hs, request->device_id);
    if (ds == NULL) {
        PT_LOG("error: invalid device id!\n");
        return -1;
    }

    response.cmd = ATAPI_PTV4V_SG_GET_RESERVED_SIZE;
    response.device_id = ds->device_id;

    if (ioctl(ds->device_fd, SG_GET_RESERVED_SIZE, &response.size) < 0) {
        PT_LOG("SG_GET_RESERVED_SIZE error %s - %s",
                ds->device_path, strerror(errno));
        return -1;
    }

    PT_LOG("sg get reserved size for %s = %d\n", ds->device_path,
            (int)response.size);

    if (!pt_v4v_send_message(hs, &response, sizeof(response))) {
        PT_LOG("error: failed to send a message to %s", ds->device_path);
        return -1;
    }

    return 0;
}
Ejemplo n.º 9
0
/**
 * Handles ATAPI_PTV4V_RELEASE_LOCK command from qemu stubdom.
 * @param[in] hs: Helper state pointer.
 * @param[in] buf: Data packet received from qemu.
 * @param[in] len: Length of data packet received.
 * @returns 0 on success, -1 on errror.
 */
static int atapi_ptv4v_release_lock(ATAPIPTHelperState* hs, uint8_t *buf,
                                    size_t len)
{
    pt_v4vcmd_release_lock_request_t *request;
    ATAPIPTDeviceState *ds;

    request = (pt_v4vcmd_release_lock_request_t *)buf;

    if (len != sizeof(*request)) {
        PT_LOG("error: mismatch buffer size %d vs %d", len, sizeof(*request));
        return -1;
    }

    ds = device_id_to_device_state(hs, request->device_id);
    if (ds == NULL) {
        PT_LOG("error: invalid device id!\n");
        return -1;
    }

    release_global_lock(ds);

    PT_LOG("release lock for %s = %d\n", ds->device_path, ds->lock_state);
    return 0;
}
Ejemplo n.º 10
0
/**
 * Grabs global exclusive lock.
 * @param[in] ds
 * @returns 1 if lock held, 0 otherwise
 */
static int acquire_global_lock(ATAPIPTDeviceState *ds)
{
    struct flock lock = {0};

    if (ds->lock_state == ATAPI_PT_LOCK_STATE_LOCKED_BY_ME) {
        /* already have lock */
        return 1;
    }

    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    if (fcntl(ds->lock_fd, F_SETLK, &lock) == 0) {
        PT_LOG("locked by me: %s\n", ds->device_path);
        ds->lock_state = ATAPI_PT_LOCK_STATE_LOCKED_BY_ME;
        return 1;
    }

    PT_LOG("locked by other: %s\n", ds->device_path);
    ds->lock_state = ATAPI_PT_LOCK_STATE_LOCKED_BY_OTHER;
    return 0;
}
Ejemplo n.º 11
0
/**
 * Releases global exclusive lock.
 * @param[in] ds
 */
static void release_global_lock(ATAPIPTDeviceState *ds)
{
    struct flock lock = {0};

    if (ds->lock_state != ATAPI_PT_LOCK_STATE_LOCKED_BY_ME) {
        /* we don't have the lock, nothing to do */
        return;
    }

    lock.l_type = F_UNLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    fcntl(ds->lock_fd, F_SETLK, &lock);

    ds->lock_state = ATAPI_PT_LOCK_STATE_UNLOCKED;

    PT_LOG("released lock: %s\n", ds->device_path);
}
Ejemplo n.º 12
0
void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr, uint32_t val, int len)
{
    assert(pci_dev->devfn == 0x00);
    if ( !igd_passthru ) {
        pci_default_write_config(pci_dev, config_addr, val, len);
        return;
    }

    switch (config_addr)
    {
        case 0x58:        // PAVPC Offset
            pt_pci_host_write(0, 0, 0, config_addr, val, len);
            PT_LOG("pci_config_write: %x:%x.%x: addr=%x len=%x val=%x\n",
                   pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn),
                   PCI_FUNC(pci_dev->devfn), config_addr, len, val);
            break;
        default:
            pci_default_write_config(pci_dev, config_addr, val, len);
    }
}
Ejemplo n.º 13
0
/**
 * Handles ATAPI_PTV4V_SG_IO command from qemu stubdom.
 * @param[in] hs: Helper state pointer.
 * @param[in] buf: Data packet received from qemu.
 * @param[in] len: Length of data packet received.
 * @returns 0 on success, -1 on errror.
 */
static int atapi_ptv4v_sg_io(ATAPIPTHelperState* hs, uint8_t *buf, size_t len)
{
    pt_v4vcmd_sg_io_request_t *request = (pt_v4vcmd_sg_io_request_t *)buf;

    /* TODO: MAX_V4V_MSG_SIZE :( - din/dout data needs be contrained properly */
    uint8_t buf_out[MAX_V4V_MSG_SIZE] = {0, };
    pt_v4vcmd_sg_io_response_t *response;

    ATAPIPTDeviceState *ds;
    struct sg_io_v4 cmd;

    response = (pt_v4vcmd_sg_io_response_t *)buf_out;

    /* len must at least be size of request */
    if (len < sizeof(*request)) {
        PT_LOG("error: bad buffer size %d vs %d", len, sizeof(*request));
        return -1;
    }

    /* now validate true length using data len in request */
    if (len != sizeof(*request) + request->dout_data_len) {
        PT_LOG("error: buffer size %d vs %d", len,
                sizeof(*request) + request->dout_data_len);
        return -1;
    }

    ds = device_id_to_device_state(hs, request->device_id);
    if (ds == NULL) {
        PT_LOG("error: invalid device id!\n");
        return -1;
    }

    /* setup sgio cmd struct with incoming copy */
    memcpy(&cmd, &request->sgio, sizeof(cmd));

    /* init the sgio pointers */
    cmd.request = (uintptr_t)&request->request_data[0];
    cmd.response = (uintptr_t)&response->sense_data[0];

    if (cmd.dout_xfer_len > 0) {
        cmd.dout_xferp = (uintptr_t)&request->dout_data[0];
        cmd.din_xferp = (uintptr_t)NULL;
    } else {
        cmd.dout_xferp = (uintptr_t)NULL;
        cmd.din_xferp = (uintptr_t)&response->din_data[0];
    }

    /* validate sense ("response") data len */
    if (cmd.max_response_len > sizeof(response->sense_data)) {
        PT_LOG("error: invalid max_response_len! %d\n", cmd.max_response_len);
        return -1;
    }

    /* make sure din_xfer_len will fit in response */
    if (sizeof(buf_out) < sizeof(response) + cmd.din_xfer_len) {
        PT_LOG("error: bad din_xfer_len %d", cmd.din_xfer_len);
        return -1;
    }

    /* fire off ioctl */
    if (ioctl(ds->device_fd, SG_IO, &cmd) < 0) {
        PT_LOG("SG_IO error %s - %s", ds->device_path, strerror(errno));
        return -1;
    }

    PT_DEBUG("SG_IO complete %s\n", ds->device_path);

    /* scrub outgoing pointers */
    cmd.request = 0;
    cmd.response = 0;
    cmd.dout_xferp = 0;
    cmd.din_xferp = 0;

    /* populate outgoing packet */
    response->cmd = ATAPI_PTV4V_SG_IO;
    response->device_id = ds->device_id;
    memcpy(&response->sgio, &cmd, sizeof(response->sgio));
    response->din_data_len = cmd.din_xfer_len;
    /* response.sense_data is populated by SG_IO */
    /* response.din_data is populated by SG_IO */

    len = sizeof(*response) + cmd.din_xfer_len;
    if (!pt_v4v_send_message(hs, response, len)) {
       PT_LOG("error: failed to send a message to %s", ds->device_path);
       return -1;
    }

    return 0;
}
Ejemplo n.º 14
0
static int pch_map_irq(PCIDevice *pci_dev, int irq_num)
{
    PT_LOG("pch_map_irq called\n");
    return irq_num;
}
Ejemplo n.º 15
0
static void signal_handler(int sig)
{
    PT_LOG("handle signal %d", sig);
    exit_cleanup(0);
}
Ejemplo n.º 16
0
/**
 * Initializes device state if device not already opened.
 * @param[in] device_path File path to device (e.g. /dev/bsg/1:0:0:0)
 * @returns Pointer to device state, otherwise NULL on error.
 */
static ATAPIPTDeviceState *init_device_state(ATAPIPTHelperState *hs,
                                             const char *device_path)
{
    ATAPIPTDeviceState *ds = NULL;
    int i;

    if (!device_path) {
        return NULL;
    }

    for (i = 0; i < MAX_ATAPI_PT_DEVICES; i++) {
        ds = &hs->devices[i];
        if (ds->device_path[0] == 0) {
            /* device_path is blank, this slot is free to use */
            break;
        }
        if (strcmp(hs->devices[i].device_path, device_path) == 0) {
            /* found matching device already open */
            return ds;
        }
    }

    if (i == MAX_ATAPI_PT_DEVICES) {
        /* no available slots */
        PT_LOG("error: ran out of slots!\n");
        return NULL;
    }

    /* before we register - parse path & make sure it is legit */
    if (sscanf(device_path, "/dev/bsg/%d:%d:%d:%d", &ds->device_addr_a,
                                                 &ds->device_addr_b,
                                                 &ds->device_addr_c,
                                                 &ds->device_addr_d) != 4) {
        PT_LOG("error: invalid device path: %s!\n", ds->device_path);
        return NULL;
    }

    snprintf(ds->device_path, sizeof(ds->device_path), "/dev/bsg/%d:%d:%d:%d",
             ds->device_addr_a, ds->device_addr_b,
             ds->device_addr_c, ds->device_addr_d);

    /* make sure the device path is what we think it is */
    if (strcmp(device_path, ds->device_path) != 0) {
        PT_LOG("error: bad path: %s vs %s\n", device_path, ds->device_path);
        return NULL;
    }

    /* open descriptor to device */
    ds->device_fd = open(device_path, O_RDWR | O_NONBLOCK);
    if (ds->device_fd < 0) {
        PT_LOG("error: unable to open device path: %s!\n", device_path);
        return NULL;
    }

    /* set device id (index into devices) */
    ds->device_id = i;

    snprintf(ds->lock_file_path, sizeof(ds->lock_file_path),
          "/var/lock/xen-atapi-pt-lock-%d_%d_%d_%d",
          ds->device_addr_a,
          ds->device_addr_b,
          ds->device_addr_c,
          ds->device_addr_d);


    /* open lock file */
    ds->lock_fd = open(ds->lock_file_path, O_RDWR | O_CREAT, 0666);
    if (ds->lock_fd < 0) {
        PT_LOG("error: unable to open lock file: %s!\n", ds->lock_file_path);
        close(ds->device_fd);
        ds->device_fd = -1;
        return NULL;
    }

    /* assume unlocked for init - doesn't have to be true */
    ds->lock_state = ATAPI_PT_LOCK_STATE_UNLOCKED;

    return ds;
}
Ejemplo n.º 17
0
int main(int const argc, char const* const* argv)
{
    openlog(NULL, LOG_NDELAY, LOG_DAEMON);

    PT_LOG("starting %s\n", argv[0]);

    memset(&g_hs, 0, sizeof(g_hs));

    if (argc != 3) {
        PT_LOG("wrong syntax: should be %s <target_id> <stubdom_id>", argv[0]);
        return -1;
    }

    g_hs.stubdom_id = atoi(argv[2]);

    if (g_hs.stubdom_id <= 0) {
        PT_LOG("bad stubdom id (%d)", g_hs.stubdom_id);
        return -1;
    }

    signal(SIGINT, signal_handler);

    if (init_helper_state(&g_hs) != 0) {
        PT_LOG("failed to init helper!\n");
        return -1;
    }

    while (!pending_exit) {
        int ret;
        uint8_t io_buf[MAX_V4V_MSG_SIZE] = {0,};

        PT_DEBUG("wait for command from stubdom (%d)", g_hs.stubdom_id);

        /* updates global remote_addr on per-packet basis */
        ret = v4v_recvfrom(g_hs.v4v_fd, io_buf, sizeof(io_buf),
                           0, &g_hs.remote_addr);

        if (ret < 0) {
            PT_LOG("v4v_recvfrom failed!\n");
            break;
        }

        switch (io_buf[0]) {
            case ATAPI_PTV4V_OPEN:
                PT_LOG("ATAPI_PTV4V_OPEN\n");
                ret = atapi_ptv4v_open(&g_hs, io_buf, ret);
                break;
            case ATAPI_PTV4V_SG_IO:
                PT_DEBUG("ATAPI_PTV4V_SG_IO\n");
                ret = atapi_ptv4v_sg_io(&g_hs, io_buf, ret);
                break;
            case ATAPI_PTV4V_SG_GET_RESERVED_SIZE:
                PT_LOG("ATAPI_PTV4V_SG_GET_RESERVED_SIZE\n");
                ret = atapi_ptv4v_sg_get_reserved_size(&g_hs, io_buf, ret);
                break;
            case ATAPI_PTV4V_ACQUIRE_LOCK:
                PT_LOG("ATAPI_PTV4V_ACQUIRE_LOCK\n");
                ret = atapi_ptv4v_acquire_lock(&g_hs, io_buf, ret);
                break;
            case ATAPI_PTV4V_RELEASE_LOCK:
                PT_LOG("ATAPI_PTV4V_RELEASE_LOCK\n");
                ret = atapi_ptv4v_release_lock(&g_hs, io_buf, ret);
                break;
            default:
                PT_LOG("bad command = %d", io_buf[0]);
                ret = -1;
                break;
        }

        if (ret < 0) {
            PT_LOG("command failed!\n");
            break;
        }
    }

    PT_LOG("exiting...\n");
    exit_cleanup(0);
    return 0;
}
Ejemplo n.º 18
0
** File:   ptmisc.c
** Descritpion:  Implemenation of miscellaneous methods for pthreads
*/

#if defined(_PR_PTHREADS)

#include "primpl.h"

#include <stdio.h>
#ifdef SOLARIS
#include <thread.h>
#endif

#define PT_LOG(f)

void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")}
void _PR_InitStacks(void) {PT_LOG("_PR_InitStacks")}

PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs) 
{
#ifdef SOLARIS
	thr_setconcurrency(numCPUs);	
#else
	PT_LOG("PR_SetConcurrency");
#endif
}

PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 flag)
    {PT_LOG("PR_SetThreadRecycleMode")}

#endif /* defined(_PR_PTHREADS) */