Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109968022
D20307.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D20307.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D20307: Add support for writing to guest memory in the debug server.
Attached
Detach File
Event Timeline
Log In to Comment