Page MenuHomeFreeBSD

D20307.diff
No OneTemporary

D20307.diff

Index: head/usr.sbin/bhyve/gdb.c
===================================================================
--- head/usr.sbin/bhyve/gdb.c
+++ head/usr.sbin/bhyve/gdb.c
@@ -767,15 +767,24 @@
bool started;
int error;
+ /* Skip 'm' */
+ data += 1;
+ len -= 1;
+
+ /* Parse and consume address. */
cp = memchr(data, ',', len);
- if (cp == NULL) {
+ if (cp == NULL || cp == data) {
send_error(EINVAL);
return;
}
- gva = parse_integer(data + 1, cp - (data + 1));
- resid = parse_integer(cp + 1, len - (cp + 1 - data));
- started = false;
+ gva = parse_integer(data, cp - data);
+ len -= (cp - data) + 1;
+ data += (cp - data) + 1;
+ /* Parse length. */
+ resid = parse_integer(data, len);
+
+ started = false;
while (resid > 0) {
error = guest_vaddr2paddr(cur_vcpu, gva, &gpa);
if (error == -1) {
@@ -861,6 +870,119 @@
finish_packet();
}
+static void
+gdb_write_mem(const uint8_t *data, size_t len)
+{
+ uint64_t gpa, gva, val;
+ uint8_t *cp;
+ size_t resid, todo, bytes;
+ int error;
+
+ /* Skip 'M' */
+ data += 1;
+ len -= 1;
+
+ /* Parse and consume address. */
+ cp = memchr(data, ',', len);
+ if (cp == NULL || cp == data) {
+ send_error(EINVAL);
+ return;
+ }
+ gva = parse_integer(data, cp - data);
+ len -= (cp - data) + 1;
+ data += (cp - data) + 1;
+
+ /* Parse and consume length. */
+ cp = memchr(data, ':', len);
+ if (cp == NULL || cp == data) {
+ send_error(EINVAL);
+ return;
+ }
+ resid = parse_integer(data, cp - data);
+ len -= (cp - data) + 1;
+ data += (cp - data) + 1;
+
+ /* Verify the available bytes match the length. */
+ if (len != resid * 2) {
+ send_error(EINVAL);
+ return;
+ }
+
+ while (resid > 0) {
+ error = guest_vaddr2paddr(cur_vcpu, gva, &gpa);
+ if (error == -1) {
+ send_error(errno);
+ return;
+ }
+ if (error == 0) {
+ send_error(EFAULT);
+ return;
+ }
+
+ /* Write bytes to current page. */
+ todo = getpagesize() - gpa % getpagesize();
+ if (todo > resid)
+ todo = resid;
+
+ cp = paddr_guest2host(ctx, gpa, todo);
+ if (cp != NULL) {
+ /*
+ * If this page is guest RAM, write it a byte
+ * at a time.
+ */
+ while (todo > 0) {
+ assert(len >= 2);
+ *cp = parse_byte(data);
+ data += 2;
+ len -= 2;
+ cp++;
+ gpa++;
+ gva++;
+ resid--;
+ todo--;
+ }
+ } else {
+ /*
+ * If this page isn't guest RAM, try to handle
+ * it via MMIO. For MMIO requests, use
+ * aligned writes of words when possible.
+ */
+ while (todo > 0) {
+ if (gpa & 1 || todo == 1) {
+ bytes = 1;
+ val = parse_byte(data);
+ } else if (gpa & 2 || todo == 2) {
+ bytes = 2;
+ val = parse_byte(data) |
+ (parse_byte(data + 2) << 8);
+ } else {
+ bytes = 4;
+ val = parse_byte(data) |
+ (parse_byte(data + 2) << 8) |
+ (parse_byte(data + 4) << 16) |
+ (parse_byte(data + 6) << 24);
+ }
+ error = write_mem(ctx, cur_vcpu, gpa, val,
+ bytes);
+ if (error == 0) {
+ gpa += bytes;
+ gva += bytes;
+ resid -= bytes;
+ todo -= bytes;
+ data += 2 * bytes;
+ len -= 2 * bytes;
+ } else {
+ send_error(EFAULT);
+ return;
+ }
+ }
+ }
+ assert(resid == 0 || gpa % getpagesize() == 0);
+ }
+ assert(len == 0);
+ send_ok();
+}
+
static bool
command_equals(const uint8_t *data, size_t len, const char *cmd)
{
@@ -1000,6 +1122,9 @@
case 'm':
gdb_read_mem(data, len);
break;
+ case 'M':
+ gdb_write_mem(data, len);
+ break;
case 'T': {
int tid;
@@ -1035,7 +1160,6 @@
finish_packet();
break;
case 'G': /* TODO */
- case 'M': /* TODO */
case 'v':
/* Handle 'vCont' */
/* 'vCtrlC' */
Index: head/usr.sbin/bhyve/mem.h
===================================================================
--- head/usr.sbin/bhyve/mem.h
+++ head/usr.sbin/bhyve/mem.h
@@ -61,5 +61,7 @@
int register_mem(struct mem_range *memp);
int register_mem_fallback(struct mem_range *memp);
int unregister_mem(struct mem_range *memp);
+int write_mem(struct vmctx *ctx, int vcpu, uint64_t gpa, uint64_t wval,
+ int size);
#endif /* _MEM_H_ */
Index: head/usr.sbin/bhyve/mem.c
===================================================================
--- head/usr.sbin/bhyve/mem.c
+++ head/usr.sbin/bhyve/mem.c
@@ -251,30 +251,43 @@
return (access_memory(ctx, vcpu, paddr, emulate_mem_cb, &ema));
}
-struct read_mem_args {
- uint64_t *rval;
+struct rw_mem_args {
+ uint64_t *val;
int size;
+ int operation;
};
static int
-read_mem_cb(struct vmctx *ctx, int vcpu, uint64_t paddr, struct mem_range *mr,
+rw_mem_cb(struct vmctx *ctx, int vcpu, uint64_t paddr, struct mem_range *mr,
void *arg)
{
- struct read_mem_args *rma;
+ struct rw_mem_args *rma;
rma = arg;
- return (mr->handler(ctx, vcpu, MEM_F_READ, paddr, rma->size,
- rma->rval, mr->arg1, mr->arg2));
+ return (mr->handler(ctx, vcpu, rma->operation, paddr, rma->size,
+ rma->val, mr->arg1, mr->arg2));
}
int
read_mem(struct vmctx *ctx, int vcpu, uint64_t gpa, uint64_t *rval, int size)
{
- struct read_mem_args rma;
+ struct rw_mem_args rma;
- rma.rval = rval;
+ rma.val = rval;
rma.size = size;
- return (access_memory(ctx, vcpu, gpa, read_mem_cb, &rma));
+ rma.operation = MEM_F_READ;
+ return (access_memory(ctx, vcpu, gpa, rw_mem_cb, &rma));
+}
+
+int
+write_mem(struct vmctx *ctx, int vcpu, uint64_t gpa, uint64_t wval, int size)
+{
+ struct rw_mem_args rma;
+
+ rma.val = &wval;
+ rma.size = size;
+ rma.operation = MEM_F_WRITE;
+ return (access_memory(ctx, vcpu, gpa, rw_mem_cb, &rma));
}
static int

File Metadata

Mime Type
text/plain
Expires
Wed, Feb 12, 9:08 PM (19 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16616464
Default Alt Text
D20307.diff (5 KB)

Event Timeline