diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index cf8a97f..a529c3f 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -305,10 +305,12 @@ int line_ioctl(struct tty_struct *tty, struct file * file, for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) if (cmd == tty_ioctls[i].cmd) break; +#ifdef DEBUG if (i == ARRAY_SIZE(tty_ioctls)) { printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", __func__, tty->name, cmd); } +#endif ret = -ENOIOCTLCMD; break; } diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 5ff5546..655ed9e 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -746,8 +746,12 @@ static int ubd_open_dev(struct ubd *ubd_dev) } ubd_dev->fd = fd; + /* A setting higher than 1 sector currently (v2.6.33) generates + data loss, both for raw and cow ubd. */ + blk_queue_max_sectors(ubd_dev->queue, 1 * sizeof(long)); + blk_queue_max_phys_segments(ubd_dev->queue, 1 * sizeof(long)); + if(ubd_dev->cow.file != NULL){ - blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); err = -ENOMEM; ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len); @@ -1223,7 +1227,7 @@ static void do_ubd_request(struct request_queue *q) struct io_thread_req *io_req; struct request *req; sector_t sector; - int n; + int n, last_sectors; while(1){ struct ubd *dev = q->queuedata; @@ -1239,9 +1243,12 @@ static void do_ubd_request(struct request_queue *q) req = dev->request; sector = blk_rq_pos(req); + last_sectors = 0; while(dev->start_sg < dev->end_sg){ struct scatterlist *sg = &dev->sg[dev->start_sg]; + sector += last_sectors; + last_sectors = 0; io_req = kmalloc(sizeof(struct io_thread_req), GFP_ATOMIC); if(io_req == NULL){ @@ -1253,7 +1260,7 @@ static void do_ubd_request(struct request_queue *q) (unsigned long long)sector << 9, sg->offset, sg->length, sg_page(sg)); - sector += sg->length >> 9; + last_sectors = sg->length >> 9; n = os_write_file(thread_fd, &io_req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 7fcad58..0731311 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -50,8 +50,20 @@ SECTIONS .rela.got : { *(.rela.got) } .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } + .rel.plt : + { + *(.rel.plt) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } .init : { KEEP (*(.init)) } =0x90909090 diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index e7a6cca..a658604 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -36,6 +36,21 @@ SECTIONS *(.gnu.linkonce.t*) } + .rel.plt : + { + *(.rel.plt) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + . = ALIGN(PAGE_SIZE); .syscall_stub : { __syscall_stub_start = .; diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index f3458d7..1c738c7 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -69,7 +69,7 @@ int poke_user(struct task_struct *child, long addr, long data) else if ((addr >= offsetof(struct user, u_debugreg[0])) && (addr <= offsetof(struct user, u_debugreg[7]))) { addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; + addr = addr >> 3; // long is 8 bytes on x86_64 if ((addr == 4) || (addr == 5)) return -EIO; child->thread.arch.debugregs[addr] = data; @@ -114,7 +114,7 @@ int peek_user(struct task_struct *child, long addr, long data) else if ((addr >= offsetof(struct user, u_debugreg[0])) && (addr <= offsetof(struct user, u_debugreg[7]))) { addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; + addr = addr >> 3; // long is 8 bytes on x86_64 tmp = child->thread.arch.debugregs[addr]; } return put_user(tmp, (unsigned long *) data);