#define DEEP_DEBUG 0
#define SHALLOW_DEBUG 0
-#if DEEP_DEBUG
-#define DEEP_DEBUG_PRINT(fmt, args...) printk((fmt), ##args)
+#if DEEP_DEBUG == 1
+#define DEEP_DEBUG_PRINT(fmt, args...) DEBUG(fmt, ##args)
#else
#define DEEP_DEBUG_PRINT(fmt, args...)
#endif
-#if SHALLOW_DEBUG
-#define SHALLOW_DEBUG_PRINT(fmt, args...) printk((fmt), ##args)
+#if SHALLOW_DEBUG == 1
+#define SHALLOW_DEBUG_PRINT(fmt, args...) INFO(fmt, ##args)
#else
#define SHALLOW_DEBUG_PRINT(fmt, args...)
#endif
-#define ERROR(fmt, args...) printk((fmt), ##args)
-#define INFO(fmt, args...) printk((fmt), ##args)
-
struct palacios_host_device_user {
spinlock_t lock;
int connected; // is the user space connected to this?
char url[MAX_URL]; // what is the url describing the device
v3_guest_dev_t guestdev; // what is the palacios-side device
+ v3_guest_dev_intr_t guestintr; // what is the palacios-side device interrupt info
wait_queue_head_t user_wait_queue; // user space processes waiting on us (should be only one)
wait_queue_head_t host_wait_queue; // host threads (should only be one) waiting on user space
static void palacios_host_dev_user_free(struct palacios_host_device_user *dev)
{
if (dev->req) {
- kfree(dev->req);
+ palacios_free(dev->req);
dev->req=0;
}
if (dev->resp) {
- kfree(dev->resp);
+ palacios_free(dev->resp);
dev->resp=0;
}
- kfree(dev);
+ palacios_free(dev);
}
if ((*r)==0) {
// allocate it
DEEP_DEBUG_PRINT("palacios: hostdev: attempt alloc\n");
- *r = kmalloc(sizeof(struct palacios_host_dev_host_request_response)+data_size,GFP_KERNEL);
- DEEP_DEBUG_PRINT("palacios: hostdev: kmalloc done\n");
+ *r = palacios_alloc(sizeof(struct palacios_host_dev_host_request_response)+data_size);
+ DEEP_DEBUG_PRINT("palacios: hostdev: palacios_alloc done\n");
if ((*r)==0) {
ERROR("palacios: hostdev: failed to allocate\n");
return -1;
struct palacios_host_dev_host_request_response *new;
if (!copy) {
- kfree(*r);
+ palacios_free(*r);
*r=0;
}
- new = kmalloc(sizeof(struct palacios_host_dev_host_request_response)+data_size,GFP_KERNEL);
+ new = palacios_alloc(sizeof(struct palacios_host_dev_host_request_response)+data_size);
if (!new) {
ERROR("palacios: hostdev: failed to reallocate\n");
return -1;
if (copy) {
memcpy(new->data,(*r)->data,(*r)->data_len-sizeof(struct palacios_host_dev_host_request_response));
new->data_len=(*r)->data_len;
- kfree(*r);
+ palacios_free(*r);
}
*r=new;
DEEP_DEBUG_PRINT("palacios: hostdev: reallocated\n");
return -EFAULT;
}
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
+
+
+ // register ourselves on the user wait queue
+ poll_wait(filp, &(dev->user_wait_queue), poll_tb);
if (dev->waiting) {
// Yes, we have a request if you want it!
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: hostdev: poll done immediate\n");
return POLLIN | POLLRDNORM;
}
// No request yet, so we need to wait for one to show up.
- // register ourselves on the user wait queue
- poll_wait(filp, &(dev->user_wait_queue), poll_tb);
-
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: hostdev: poll delayed\n");
// We will get called again when that queue is woken up
INFO("palacios: user side is closing host device \"%s\"\n",dev->url);
- spin_lock_irqsave(&(dev->lock), f);
+ palacios_spinlock_lock_irqsave(&(dev->lock), f);
dev->connected = 0;
- spin_unlock_irqrestore(&(dev->lock), f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock), f);
// it is the palacios->host interface's responsibility to ignore
// reads/writes until connected is true
return 0;
}
-static int host_dev_ioctl(struct inode *ip, struct file *fp, unsigned int val, unsigned long arg)
+static long host_dev_ioctl(struct file * fp, unsigned int val, unsigned long arg)
{
void __user *argp = (void __user *)arg;
switch (op.type) {
case PALACIOS_HOST_DEV_USER_REQUEST_READ_GUEST: {
- void *temp = kmalloc(op.len,GFP_KERNEL);
+ void *temp = palacios_alloc(op.len);
DEEP_DEBUG_PRINT("palacios: hostdev: read guest\n");
temp,
op.len) != op.len) {
ERROR("palacios: unable to read enough from guest for host device \"%s\"\n",dev->url);
- kfree(temp);
+ palacios_free(temp);
return -EFAULT;
}
if (copy_to_user(op.data,temp,op.len)) {
ERROR("palacios: unable to copy to user for host device \"%s\"\n",dev->url);
- kfree(temp);
+ palacios_free(temp);
return -EFAULT;
}
- kfree(temp);
+ palacios_free(temp);
return op.len;
}
DEEP_DEBUG_PRINT("palacios: hostdev: write guest\n");
- temp = kmalloc(op.len,GFP_KERNEL);
+ temp = palacios_alloc(op.len);
if (!temp) {
ERROR("palacios: unable to allocate enough for write guest request for host device \"%s\"\n",dev->url);
if (copy_from_user(temp,op.data,op.len)) {
ERROR("palacios: unable to copy from user for host device \"%s\"\n",dev->url);
- kfree(temp);
+ palacios_free(temp);
return -EFAULT;
}
temp,
op.len) != op.len) {
ERROR("palacios: unable to write enough to guest for host device \"%s\"\n",dev->url);
- kfree(temp);
+ palacios_free(temp);
return -EFAULT;
}
- kfree(temp);
+ palacios_free(temp);
return op.len;
}
break;
- case PALACIOS_HOST_DEV_USER_REQUEST_IRQ_GUEST: {
+ case PALACIOS_HOST_DEV_USER_REQUEST_IRQ_RAISE_GUEST: {
- DEEP_DEBUG_PRINT("palacios: hostdev: irq guest\n");
+ DEEP_DEBUG_PRINT("palacios: hostdev: irq raise guest\n");
- return v3_host_dev_raise_irq(dev, dev->guestdev, op.irq);
+ return v3_host_dev_raise_irq(dev, dev->guestdev, dev->guestintr, op.irq);
+ }
+ break;
+ case PALACIOS_HOST_DEV_USER_REQUEST_IRQ_LOWER_GUEST: {
+
+ DEEP_DEBUG_PRINT("palacios: hostdev: irq lower guest\n");
+
+ return v3_host_dev_lower_irq(dev, dev->guestdev, dev->guestintr, op.irq);
}
break;
DEEP_DEBUG_PRINT("palacios: hostdev: request size of request\n");
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
if (!(dev->waiting)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: hostdev: no request available\n");
schedule(); // avoid livelock for polling user space process SUSPICOUS
return 0; // no request available now
}
if (copy_to_user(argp,&(dev->req->data_len),sizeof(uint64_t))) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: unable to copy to user for host device \"%s\"\n",dev->url);
return -EFAULT; // failed to copy!
}
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: hostdev: have request\n");
unsigned long f;
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: hostdev: pull request\n");
if (!(dev->waiting) || !(dev->req)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: hostdev: no request to pull\n");
return 0; // no request available now
}
if (copy_to_user(argp,dev->req,dev->req->data_len)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: unable to copy to user for host device \"%s\"\n",dev->url);
return -EFAULT; // failed to copy!
}
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: hostdev: request pulled\n");
uint64_t user_datalen;
uint64_t old_len;
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: hostdev: push response\n");
if (!(dev->waiting)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: hostdev: no matching request for pushed response\n");
return 0; // no request outstanding, so we do not need a response!
}
if (copy_from_user(&user_datalen,argp,sizeof(uint64_t))) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: unable to copy from user for host device \"%s\"\n",dev->url);
return -EFAULT; // failed to copy!
}
if (user_datalen<sizeof(struct palacios_host_dev_host_request_response)) {
// bad user
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: user has response that is too small on host device \"%s\"\n",dev->url);
return -EFAULT;
}
// we drop the lock, turn on interrupts, resize, and then retry
DEEP_DEBUG_PRINT("palacios: response not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
if (palacios_resize_reqresp(&(dev->resp),user_datalen-sizeof(struct palacios_host_dev_host_request_response),0)) {
ERROR("palacios: unable to resize to accept response of size %llu from user for host device \"%s\"\n",user_datalen,dev->url);
// There shouldn't be a race here, since there should
// be exactly one user space thread giving us a response for this device
// and it is blocked waiting for us to finish
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: reacuired lock on device \"%s\"\n",dev->url);
}
}
old_len = dev->resp->len;
if (copy_from_user(dev->resp, argp, user_datalen)) {
dev->resp->len=old_len;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: unable to copy from user for host device \"%s\"\n",dev->url);
return -EFAULT; // failed to copy!
}
// now have valid response!
dev->waiting=0;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
// wake the palacios side up so that it sees it
cycle_response_request(dev);
}
-static long host_dev_compat_ioctl(struct file * filp, unsigned int ioctl, unsigned long arg)
-{
- return host_dev_ioctl(NULL, filp, ioctl, arg);
-}
-
static struct file_operations host_dev_fops = {
.poll = host_dev_poll,
.release = host_dev_release,
-#ifdef HAVE_COMPAT_IOCTL
- .compat_ioctl = host_dev_compat_ioctl,
-#else
- .ioctl = host_dev_ioctl,
-#endif
+ .compat_ioctl = host_dev_ioctl,
+ .unlocked_ioctl = host_dev_ioctl,
};
if (copy_from_user(url, argp, MAX_URL)) {
- printk("copy from user error getting url for host device connect...\n");
+ ERROR("copy from user error getting url for host device connect...\n");
return -EFAULT;
}
// URL. If we don't find it after a while, we give up
for (i=0;i<RENDEZVOUS_WAIT_SECS/RENDEZVOUS_RETRY_SECS;i++) {
- spin_lock_irqsave(&(host_dev->lock),f1);
+ palacios_spinlock_lock_irqsave(&(host_dev->lock),f1);
list_for_each_entry(dev,&(host_dev->devs), node) {
if (!strncasecmp(url,dev->url,MAX_URL)) {
// found it
- spin_lock_irqsave(&(dev->lock),f2);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f2);
if (dev->connected) {
ERROR("palacios: device for \"%s\" is already connected!\n",url);
- spin_unlock_irqrestore(&(dev->lock),f2);
- spin_unlock_irqrestore(&(host_dev->lock),f1);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f2);
+ palacios_spinlock_unlock_irqrestore(&(host_dev->lock),f1);
return -1;
} else {
dev->fd = anon_inode_getfd("v3-hostdev", &host_dev_fops, dev, 0);
if (dev->fd<0) {
ERROR("palacios: cannot create fd for device \"%s\"\n",url);
- spin_unlock_irqrestore(&(dev->lock),f2);
- spin_unlock_irqrestore(&(host_dev->lock),f1);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f2);
+ palacios_spinlock_unlock_irqrestore(&(host_dev->lock),f1);
return -1;
}
dev->connected=1;
dev->waiting=0;
if (dev->req) {
- kfree(dev->req);
+ palacios_free(dev->req);
dev->req=0;
}
if (dev->resp) {
- kfree(dev->resp);
+ palacios_free(dev->resp);
dev->resp=0;
}
INFO("palacios: connected fd for device \"%s\"\n",url);
- spin_unlock_irqrestore(&(dev->lock),f2);
- spin_unlock_irqrestore(&(host_dev->lock),f1);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f2);
+ palacios_spinlock_unlock_irqrestore(&(host_dev->lock),f1);
return dev->fd;
}
- spin_unlock_irqrestore(&(dev->lock),f2);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f2);
}
}
- spin_unlock_irqrestore(&(host_dev->lock),f1);
+ palacios_spinlock_unlock_irqrestore(&(host_dev->lock),f1);
ssleep(RENDEZVOUS_RETRY_SECS);
}
// Now wait until we are noticed!
for (i=0;i<RENDEZVOUS_WAIT_SECS/RENDEZVOUS_RETRY_SECS;i++) {
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
if (dev->connected) {
INFO("palacios: connection with user side established for host device \"%s\" fd=%d\n",dev->url,dev->fd);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
return 0;
}
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ssleep(RENDEZVOUS_RETRY_SECS);
}
static v3_host_dev_t palacios_host_dev_open_deferred(char *url,
v3_bus_class_t bus,
v3_guest_dev_t gdev,
+ v3_guest_dev_intr_t gintr,
void *host_priv_data)
{
struct v3_guest *guest= (struct v3_guest*)host_priv_data;
host_dev = get_vm_ext_data(guest, "HOST_DEVICE_INTERFACE");
if (host_dev == NULL) {
- printk("Error locating vm host data for HOST_DEVICE_INTERFACE\n");
+ ERROR("Error locating vm host data for HOST_DEVICE_INTERFACE\n");
return 0;
}
}
// Check to see if a device of this url already exists, which would be ugly
- spin_lock_irqsave(&(host_dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(host_dev->lock),f);
list_for_each_entry(dev,&(host_dev->devs), node) {
if (!strncasecmp(url,dev->url,MAX_URL)) {
// found it
- spin_unlock_irqrestore(&(host_dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(host_dev->lock),f);
ERROR("palacios: a host device with url \"%s\" already exists in the guest!\n",url);
return NULL;
}
}
- spin_unlock_irqrestore(&(host_dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(host_dev->lock),f);
INFO("palacios: creating host device \"%s\"\n",url);
- dev = kmalloc(sizeof(struct palacios_host_device_user),GFP_KERNEL);
+ dev = palacios_alloc(sizeof(struct palacios_host_device_user));
if (!dev) {
ERROR("palacios: cannot allocate for host device \"%s\"\n",url);
dev->guestdev = gdev;
+ dev->guestintr = gintr;
+
dev->guest = guest;
- spin_lock_init(&(dev->lock));
+ palacios_spinlock_init(&(dev->lock));
init_waitqueue_head(&(dev->user_wait_queue));
init_waitqueue_head(&(dev->host_wait_queue));
// Insert ourselves into the list
- spin_lock_irqsave(&(host_dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(host_dev->lock),f);
list_add(&(dev->node),&(host_dev->devs));
- spin_unlock_irqrestore(&(host_dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(host_dev->lock),f);
INFO("palacios: host device \"%s\" created with deferred rendezvous\n",url);
return -1;
}
- spin_lock_irqsave(&(host_dev->lock),f1);
+ palacios_spinlock_lock_irqsave(&(host_dev->lock),f1);
- spin_lock_irqsave(&(dev->lock),f2);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f2);
if (dev->connected) {
dev->connected=0;
list_del(&(dev->node));
- spin_unlock_irqrestore(&(dev->lock),f2);
- spin_unlock_irqrestore(&(host_dev->lock),f1);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f2);
+ palacios_spinlock_unlock_irqrestore(&(host_dev->lock),f1);
+ palacios_spinlock_deinit(&(dev->lock));
+
palacios_host_dev_user_free(dev);
return 0;
DEEP_DEBUG_PRINT("palacios: hostdev: read io port 0x%x\n",port);
- spin_lock_irqsave(&(dev->lock),f);
if (palacios_host_dev_rendezvous(dev)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
return 0;
}
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
if (dev->waiting) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: guest issued i/o read request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
return 0;
}
// we drop the lock, turn on interrupts, resize, and then retry
DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
if (palacios_resize_reqresp(&(dev->req),0,0)) {
ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
// reacquire the lock
// There shouldn't be a race here since there should not be another
// request from palacios until this one finishes
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
}
}
dev->waiting=1;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
// hand over to the user space and wait for it to respond
cycle_request_response(dev);
// We're back! So now we'll hand the response back to Palacios
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
memcpy(dest,dev->resp->data, op_len);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
return op_len;
}
DEEP_DEBUG_PRINT("palacios: hostdev: read mem 0x%p\n",gpa);
- spin_lock_irqsave(&(dev->lock),f);
if (palacios_host_dev_rendezvous(dev)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
return 0;
}
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
if (dev->waiting) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: guest issued memory read request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
return 0;
}
// we drop the lock, turn on interrupts, resize, and then retry
DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
if (palacios_resize_reqresp(&(dev->req),0,0)) {
ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
// reacquire the lock
// There shouldn't be a race here since there should not be another
// request from palacios until this one finishes
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
}
}
dev->waiting=1;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
// hand over to the user space and wait for it to respond
cycle_request_response(dev);
// We're back! So now we'll hand the response back to Palacios
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
memcpy(dest,dev->resp->data, op_len);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
return op_len;
}
unsigned long f;
uint64_t op_len;
- DEEP_DEBUG_PRINT("palacios: hostdev: read conf 0x%p\n",(void*)offset);
+ DEEP_DEBUG_PRINT("palacios: hostdev: read conf 0x%p (len=%lld)\n",(void*)offset, len);
- spin_lock_irqsave(&(dev->lock),f);
if (palacios_host_dev_rendezvous(dev)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
return 0;
}
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
if (dev->waiting) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: guest issued config read request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
return 0;
}
// we drop the lock, turn on interrupts, resize, and then retry
DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
if (palacios_resize_reqresp(&(dev->req),0,0)) {
ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
// reacquire the lock
// There shouldn't be a race here since there should not be another
// request from palacios until this one finishes
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
}
}
dev->waiting=1;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
// hand over to the user space and wait for it to respond
cycle_request_response(dev);
// We're back! So now we'll hand the response back to Palacios
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
memcpy(dest,dev->resp->data, op_len);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
return op_len;
}
DEEP_DEBUG_PRINT("palacios: hostdev: write io port 0x%x \n",port);
- spin_lock_irqsave(&(dev->lock),f);
if (palacios_host_dev_rendezvous(dev)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
return 0;
}
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
if (dev->waiting) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: guest issued i/o write request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
return 0;
}
// we drop the lock, turn on interrupts, resize, and then retry
DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
if (palacios_resize_reqresp(&(dev->req),len,0)) {
ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
// reacquire the lock
// There shouldn't be a race here since there should not be another
// request from palacios until this one finishes
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
}
}
dev->waiting=1;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
// hand over to the user space and wait for it to respond
cycle_request_response(dev);
// We're back! So now we'll hand the response back to Palacios
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
return op_len;
}
DEEP_DEBUG_PRINT("palacios: hostdev: write mem 0x%p\n",gpa);
- spin_lock_irqsave(&(dev->lock),f);
if (palacios_host_dev_rendezvous(dev)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
return 0;
}
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
+
if (dev->waiting) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: guest issued memory write request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
return 0;
}
// we drop the lock, turn on interrupts, resize, and then retry
DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
if (palacios_resize_reqresp(&(dev->req),len,0)) {
ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
// reacquire the lock
// There shouldn't be a race here since there should not be another
// request from palacios until this one finishes
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
}
}
dev->waiting=1;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
// hand over to the user space and wait for it to respond
cycle_request_response(dev);
// We're back! So now we'll hand the response back to Palacios
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
op_len= dev->resp->op_len < len ? dev->resp->op_len : len ;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
return op_len;
}
DEEP_DEBUG_PRINT("palacios: hostdev: write conf 0x%p\n",(void*)offset);
- spin_lock_irqsave(&(dev->lock),f);
if (palacios_host_dev_rendezvous(dev)) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
return 0;
}
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
if (dev->waiting) {
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
ERROR("palacios: guest issued config write request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
return 0;
}
// we drop the lock, turn on interrupts, resize, and then retry
DEEP_DEBUG_PRINT("palacios: request not big enough, dropping lock to resize on device \"%s\"\n",dev->url);
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
if (palacios_resize_reqresp(&(dev->req),len,0)) {
ERROR("palacios: cannot resize for request on device \"%s\"\n",dev->url);
// reacquire the lock
// There shouldn't be a race here since there should not be another
// request from palacios until this one finishes
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
DEEP_DEBUG_PRINT("palacios: reacquired lock on device \"%s\"\n",dev->url);
}
}
dev->waiting=1;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
// hand over to the user space and wait for it to respond
cycle_request_response(dev);
// We're back! So now we'll hand the response back to Palacios
- spin_lock_irqsave(&(dev->lock),f);
+ palacios_spinlock_lock_irqsave(&(dev->lock),f);
op_len = dev->resp->op_len < len ? dev->resp->op_len : len ;
- spin_unlock_irqrestore(&(dev->lock),f);
+ palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
return op_len;
}
}
+static int host_dev_deinit(void) {
+ // nothing to do
+ return 0;
+}
+
static int host_dev_guest_init(struct v3_guest * guest, void ** vm_data ) {
- struct palacios_host_dev * host_dev = kmalloc(sizeof(struct palacios_host_dev), GFP_KERNEL);
+ struct palacios_host_dev * host_dev = palacios_alloc(sizeof(struct palacios_host_dev));
if (!host_dev) {
ERROR("palacios: failed to do guest_init for host device\n");
INIT_LIST_HEAD(&(host_dev->devs));
- spin_lock_init(&(host_dev->lock));
+ palacios_spinlock_init(&(host_dev->lock));
*vm_data = host_dev;
}
+static int host_dev_guest_deinit(struct v3_guest * guest, void * vm_data) {
+
+ struct palacios_host_dev * host_dev = (struct palacios_host_dev *) vm_data;
+ remove_guest_ctrl(guest, V3_VM_HOST_DEV_CONNECT);
+ palacios_spinlock_deinit(&(host_dev->lock));
+ palacios_free(host_dev);
+ return 0;
+}
+
static struct linux_ext host_dev_ext = {
.name = "HOST_DEVICE_INTERFACE",
.init = host_dev_init,
- .deinit = NULL,
+ .deinit = host_dev_deinit,
.guest_init = host_dev_guest_init,
- .guest_deinit = NULL
+ .guest_deinit = host_dev_guest_deinit
};