From: Jack Lange Date: Wed, 14 Sep 2011 16:32:49 +0000 (-0400) Subject: various bug fixes to the block layer X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=6b32ab71071174408dba942dab82adc2c8324643 various bug fixes to the block layer --- diff --git a/linux_module/iface-console.c b/linux_module/iface-console.c index 9e13546..ab66d5a 100644 --- a/linux_module/iface-console.c +++ b/linux_module/iface-console.c @@ -209,6 +209,7 @@ static int console_connect(struct v3_guest * guest, unsigned int cmd, struct palacios_console * cons = priv_data; int cons_fd = 0; unsigned long flags; + int acquired = 0; if (cons->open == 0) { printk("Attempted to connect to unopened console\n"); @@ -216,6 +217,16 @@ static int console_connect(struct v3_guest * guest, unsigned int cmd, } spin_lock_irqsave(&(cons->lock), flags); + if (cons->connected == 0) { + cons->connected = 1; + acquired = 1; + } + spin_unlock_irqrestore(&(cons->lock), flags); + + if (acquired == 0) { + printk("Console already connected\n"); + return -1; + } cons_fd = anon_inode_getfd("v3-cons", &cons_fops, cons, O_RDWR); @@ -224,10 +235,8 @@ static int console_connect(struct v3_guest * guest, unsigned int cmd, return cons_fd; } - cons->connected = 1; - v3_deliver_console_event(guest->v3_ctx, NULL); - spin_unlock_irqrestore(&(cons->lock), flags); + printk("Console connected\n"); diff --git a/linux_usr/Makefile b/linux_usr/Makefile index a1e9bb4..b8a1014 100644 --- a/linux_usr/Makefile +++ b/linux_usr/Makefile @@ -12,8 +12,9 @@ v3_mem : v3_mem.c v3_ctrl.h gcc -static v3_mem.c -o v3_mem -v3_cons : v3_cons.c v3_ctrl.h - gcc -static v3_cons.c -o v3_cons -lcurses +v3_cons : v3_cons.c v3_cons_sc.c v3_ctrl.h + gcc v3_cons.c -o v3_cons -lcurses + gcc v3_cons_sc.c -o v3_cons_sc -lcurses v3_stream : v3_stream.c v3_ctrl.h gcc -static v3_stream.c -o v3_stream diff --git a/palacios/src/devices/ata.h b/palacios/src/devices/ata.h index 423679e..7eb901c 100644 --- a/palacios/src/devices/ata.h +++ b/palacios/src/devices/ata.h @@ -124,9 +124,6 @@ static int ata_read(struct ide_internal * ide, struct ide_channel * channel, uin } return 0; - - - } diff --git a/palacios/src/devices/atapi.h b/palacios/src/devices/atapi.h index 0892f8c..4962119 100644 --- a/palacios/src/devices/atapi.h +++ b/palacios/src/devices/atapi.h @@ -75,9 +75,12 @@ static void atapi_setup_cmd_resp(struct ide_internal * ide, struct ide_channel * drive->irq_flags.c_d = 0; channel->status.busy = 0; - channel->status.data_req = 1; channel->status.error = 0; + if (drive->transfer_length > 0) { + channel->status.data_req = 1; + } + ide_raise_irq(ide, channel); } @@ -129,8 +132,9 @@ static void atapi_cmd_nop(struct ide_internal * ide, struct ide_channel * channe static int atapi_read_chunk(struct ide_internal * ide, struct ide_channel * channel) { struct ide_drive * drive = get_selected_drive(channel); - int ret = drive->ops->read(drive->data_buf, drive->current_lba * ATAPI_BLOCK_SIZE, ATAPI_BLOCK_SIZE, -drive->private_data); + int ret = drive->ops->read(drive->data_buf, + drive->current_lba * ATAPI_BLOCK_SIZE, + ATAPI_BLOCK_SIZE, drive->private_data); if (ret == -1) { PrintError("IDE: Error reading CD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba)); @@ -181,7 +185,7 @@ static int atapi_read10(struct guest_info * core, return 0; } - if (lba + xfer_len > drive->ops->get_capacity(drive->private_data)) { + if ((lba + xfer_len) > (drive->ops->get_capacity(drive->private_data) / ATAPI_BLOCK_SIZE)) { PrintError("IDE: xfer len exceeded capacity (lba=%d) (xfer_len=%d) (ReadEnd=%d) (capacity=%d)\n", lba, xfer_len, lba + xfer_len, (uint32_t)drive->ops->get_capacity(drive->private_data)); @@ -190,8 +194,7 @@ static int atapi_read10(struct guest_info * core, return 0; } - // PrintDebug("Reading %d blocks from LBA 0x%x\n", xfer_len, lba); - + // PrintDebug("Reading %d blocks from LBA 0x%x\n", xfer_len, lba); drive->current_lba = lba; // Update the request length value in the cylinder registers @@ -244,7 +247,7 @@ static int atapi_get_capacity(struct ide_internal * ide, struct ide_channel * ch struct atapi_rd_capacity_resp * resp = (struct atapi_rd_capacity_resp *)(drive->data_buf); uint32_t capacity = drive->ops->get_capacity(drive->private_data); - resp->lba = le_to_be_32(capacity); + resp->lba = le_to_be_32(capacity / ATAPI_BLOCK_SIZE); resp->block_len = le_to_be_32(ATAPI_BLOCK_SIZE); atapi_setup_cmd_resp(ide, channel, sizeof(struct atapi_rd_capacity_resp)); @@ -267,6 +270,8 @@ static int atapi_get_config(struct ide_internal * ide, struct ide_channel * chan xfer_len = alloc_len; } + V3_Print("ATAPI Get config: xfer_len=%d\b", xfer_len); + atapi_setup_cmd_resp(ide, channel, xfer_len); return 0; diff --git a/palacios/src/devices/filedisk.c b/palacios/src/devices/filedisk.c index f7fe7ec..bf1aaf8 100644 --- a/palacios/src/devices/filedisk.c +++ b/palacios/src/devices/filedisk.c @@ -80,6 +80,12 @@ static int read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_ PrintDebug("Reading %d bytes from %p to %p\n", (uint32_t)num_bytes, (uint8_t *)(disk->disk_image + lba), buf); + if (lba + num_bytes > disk->capacity) { + PrintError("Out of bounds read: lba=%llu, num_bytes=%llu, capacity=%llu\n", + lba, num_bytes, disk->capacity); + return -1; + } + return read_all(disk->fd, buf, lba, num_bytes); } @@ -89,6 +95,13 @@ static int write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private PrintDebug("Writing %d bytes from %p to %p\n", (uint32_t)num_bytes, buf, (uint8_t *)(disk->disk_image + lba)); + if (lba + num_bytes > disk->capacity) { + PrintError("Out of bounds read: lba=%llu, num_bytes=%llu, capacity=%llu\n", + lba, num_bytes, disk->capacity); + return -1; + } + + return write_all(disk->fd, buf, lba, num_bytes); } @@ -96,7 +109,7 @@ static int write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private static uint64_t get_capacity(void * private_data) { struct disk_state * disk = (struct disk_state *)private_data; - PrintDebug("Querying RAMDISK capacity %d\n", + PrintDebug("Querying FILEDISK capacity %d\n", (uint32_t)(disk->capacity)); return disk->capacity; diff --git a/palacios/src/devices/ide.c b/palacios/src/devices/ide.c index 3ef7d4d..d407551 100644 --- a/palacios/src/devices/ide.c +++ b/palacios/src/devices/ide.c @@ -1314,6 +1314,15 @@ static int write_port_std(struct guest_info * core, ushort_t port, void * src, u PrintDebug("Attempting to select a non-present drive\n"); channel->error_reg.abort = 1; channel->status.error = 1; + } else { + channel->status.busy = 0; + channel->status.ready = 1; + channel->status.data_req = 0; + channel->status.error = 0; + channel->status.seek_complete = 1; + + channel->dma_status.active = 0; + channel->dma_status.err = 0; } break; @@ -1540,8 +1549,10 @@ static int connect_fn(struct v3_vm_info * vm, return -1; } - strncpy(drive->model, model_str, sizeof(drive->model) - 1); - + if (model_str != NULL) { + strncpy(drive->model, model_str, sizeof(drive->model) - 1); + } + if (strcasecmp(type_str, "cdrom") == 0) { drive->drive_type = BLOCK_CDROM; diff --git a/palacios/src/devices/ramdisk.c b/palacios/src/devices/ramdisk.c index 05e9bda..a17d9ae 100644 --- a/palacios/src/devices/ramdisk.c +++ b/palacios/src/devices/ramdisk.c @@ -37,6 +37,12 @@ static int read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_ PrintDebug("Reading %d bytes from %p to %p\n", (uint32_t)num_bytes, (uint8_t *)(disk->disk_image + lba), buf); + if (lba + num_bytes > disk->capacity) { + PrintError("read out of bounds: lba=%llu (%p), num_bytes=%llu, capacity=%d (%p)\n", + lba, (void *)(addr_t)lba, num_bytes, disk->capacity, (void *)(addr_t)disk->capacity); + return -1; + } + memcpy(buf, (uint8_t *)(disk->disk_image + lba), num_bytes); return 0; @@ -48,6 +54,13 @@ static int write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private PrintDebug("Writing %d bytes from %p to %p\n", (uint32_t)num_bytes, buf, (uint8_t *)(disk->disk_image + lba)); + if (lba + num_bytes > disk->capacity) { + PrintError("write out of bounds: lba=%llu (%p), num_bytes=%llu, capacity=%d (%p)\n", + lba, (void *)(addr_t)lba, num_bytes, disk->capacity, (void *)(addr_t)disk->capacity); + return -1; + } + + memcpy((uint8_t *)(disk->disk_image + lba), buf, num_bytes); return 0; diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index f1d0939..e1b427a 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -871,7 +872,7 @@ int v3_vmx_enter(struct guest_info * info) { v3_yield_cond(info); if (v3_handle_vmx_exit(info, &exit_info) == -1) { - PrintError("Error in VMX exit handler\n"); + PrintError("Error in VMX exit handler (Exit reason=%x)\n", exit_info.exit_reason); return -1; } @@ -916,6 +917,36 @@ int v3_start_vmx_guest(struct guest_info * info) { } if (v3_vmx_enter(info) == -1) { + + addr_t host_addr; + addr_t linear_addr = 0; + + info->vm_info->run_state = VM_ERROR; + + V3_Print("VMX core %u: VMX ERROR!!\n", info->vcpu_id); + + v3_print_guest_state(info); + + V3_Print("VMX core %u\n", info->vcpu_id); + + + + linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs)); + + if (info->mem_mode == PHYSICAL_MEM) { + v3_gpa_to_hva(info, linear_addr, &host_addr); + } else if (info->mem_mode == VIRTUAL_MEM) { + v3_gva_to_hva(info, linear_addr, &host_addr); + } + + V3_Print("VMX core %u: Host Address of rip = 0x%p\n", info->vcpu_id, (void *)host_addr); + + V3_Print("VMX core %u: Instr (15 bytes) at %p:\n", info->vcpu_id, (void *)host_addr); + v3_dump_mem((uint8_t *)host_addr, 15); + + v3_print_stack(info); + + v3_print_vmcs(); print_exit_log(info); return -1;