--- Gnu-Mach/xen/block.c 2020/09/02 04:45:34 1.1.1.1 +++ Gnu-Mach/xen/block.c 2020/09/02 04:54:21 1.1.1.4 @@ -217,7 +217,7 @@ void hyp_block_init(void) { sprintf(device_name, "%s%ds%d", prefix, disk, partition); else sprintf(device_name, "%s%d", prefix, disk); - bd->name = (char*) kalloc(strlen(device_name)); + bd->name = (char*) kalloc(strlen(device_name) + 1); strcpy(bd->name, device_name); /* Get domain id of backend driver. */ @@ -247,7 +247,7 @@ void hyp_block_init(void) { /* Allocate an event channel and give it to backend. */ bd->evt = evt = hyp_event_channel_alloc(domid); hyp_evt_handler(evt, hyp_block_intr, n, SPL7); - i = sprintf(port_name, "%lu", evt); + i = sprintf(port_name, "%u", evt); c = hyp_store_write(t, port_name, 5, VBD_PATH, "/", vbds[n], "/", "event-channel"); if (!c) panic("%s: couldn't store event channel (%s)", device_name, hyp_store_error); @@ -351,7 +351,7 @@ static io_return_t device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type, dev_mode_t mode, char *name, device_t *devp /* out */) { - int i, err = 0; + int i; ipc_port_t port, notify; struct block_data *bd; @@ -382,8 +382,8 @@ device_open (ipc_port_t reply_port, mach port = ipc_port_alloc_kernel(); if (port == IP_NULL) { - err = KERN_RESOURCE_SHORTAGE; - goto out; + device_close(bd); + return KERN_RESOURCE_SHORTAGE; } bd->port = port; @@ -396,7 +396,6 @@ device_open (ipc_port_t reply_port, mach ipc_port_nsrequest (bd->port, 1, notify, ¬ify); assert (notify == IP_NULL); -out: if (IP_VALID (reply_port)) ds_device_open_reply (reply_port, reply_port_type, D_SUCCESS, port); else @@ -458,7 +457,7 @@ device_read (void *d, ipc_port_t reply_p /* Allocate pages. */ while (alloc_offset < offset + len) { - while ((m = vm_page_grab (FALSE)) == 0) + while ((m = vm_page_grab ()) == 0) VM_PAGE_WAIT (0); assert (! m->active && ! m->inactive); m->busy = TRUE; @@ -490,7 +489,7 @@ device_read (void *d, ipc_port_t reply_p req->operation = BLKIF_OP_READ; req->nr_segments = nbpages; req->handle = bd->handle; - req->id = (unsigned64_t) (unsigned long) &err; /* pointer on the stack */ + req->id = (uint64_t) (unsigned long) &err; /* pointer on the stack */ req->sector_number = bn + offset / 512; for (i = 0; i < nbpages; i++) { req->seg[i].gref = gref[i] = hyp_grant_give(bd->domid, atop(pages[i]->phys_addr), 0); @@ -569,14 +568,18 @@ device_write(void *d, ipc_port_t reply_p { io_return_t err = 0; vm_map_copy_t copy = (vm_map_copy_t) data; - vm_offset_t aligned_buffer = 0; - int copy_npages = atop(round_page(count)); + vm_offset_t buffer = 0; + char *map_data; + vm_offset_t map_addr; + vm_size_t map_size; + unsigned copy_npages = atop(round_page(count)); vm_offset_t phys_addrs[copy_npages]; struct block_data *bd = d; blkif_request_t *req; grant_ref_t gref[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned reqn, size; - int i, nbpages, j; + unsigned i, nbpages, j; + kern_return_t kr; if (!(bd->mode & D_WRITE)) return D_READ_ONLY; @@ -592,31 +595,24 @@ device_write(void *d, ipc_port_t reply_p if (count > copy->size) return D_INVALID_SIZE; - if (copy->type != VM_MAP_COPY_PAGE_LIST || copy->offset & PAGE_MASK) { - /* Unaligned write. Has to copy data before passing it to the backend. */ - kern_return_t kr; - vm_offset_t buffer; - - kr = kmem_alloc(device_io_map, &aligned_buffer, count); - if (kr != KERN_SUCCESS) - return kr; - - kr = vm_map_copyout(device_io_map, &buffer, vm_map_copy_copy(copy)); - if (kr != KERN_SUCCESS) { - kmem_free(device_io_map, aligned_buffer, count); - return kr; - } - - memcpy((void*) aligned_buffer, (void*) buffer, count); + /* XXX The underlying physical pages of the mapping could be highmem, + for which drivers require the use of a bounce buffer. */ + kr = kmem_alloc(device_io_map, &buffer, count); + if (kr != KERN_SUCCESS) + return kr; + + kr = kmem_io_map_copyout(device_io_map, (vm_offset_t *)&map_data, + &map_addr, &map_size, copy, count); + if (kr != KERN_SUCCESS) { + kmem_free(device_io_map, buffer, count); + return kr; + } - vm_deallocate (device_io_map, buffer, count); + memcpy((void *)buffer, map_data, count); + kmem_io_map_deallocate(device_io_map, map_addr, map_size); - for (i = 0; i < copy_npages; i++) - phys_addrs[i] = kvtophys(aligned_buffer + ptoa(i)); - } else { - for (i = 0; i < copy_npages; i++) - phys_addrs[i] = copy->cpy_page_list[i]->phys_addr; - } + for (i = 0; i < copy_npages; i++) + phys_addrs[i] = kvtophys(buffer + ptoa(i)); for (i=0; ioperation = BLKIF_OP_WRITE; req->nr_segments = nbpages; req->handle = bd->handle; - req->id = (unsigned64_t) (unsigned long) &err; /* pointer on the stack */ + req->id = (uint64_t) (unsigned long) &err; /* pointer on the stack */ req->sector_number = bn + i*PAGE_SIZE / 512; for (j = 0; j < nbpages; j++) { @@ -675,8 +671,8 @@ device_write(void *d, ipc_port_t reply_p } } - if (aligned_buffer) - kmem_free(device_io_map, aligned_buffer, count); + if (buffer) + kmem_free(device_io_map, buffer, count); vm_map_copy_discard (copy);