diff options
Diffstat (limited to 'Documentation/lguest/lguest.c')
-rw-r--r-- | Documentation/lguest/lguest.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index d36fcc0f2715..e65d6cbf2419 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -126,9 +126,13 @@ struct device | |||
126 | /* The linked-list pointer. */ | 126 | /* The linked-list pointer. */ |
127 | struct device *next; | 127 | struct device *next; |
128 | 128 | ||
129 | /* The this device's descriptor, as mapped into the Guest. */ | 129 | /* The device's descriptor, as mapped into the Guest. */ |
130 | struct lguest_device_desc *desc; | 130 | struct lguest_device_desc *desc; |
131 | 131 | ||
132 | /* We can't trust desc values once Guest has booted: we use these. */ | ||
133 | unsigned int feature_len; | ||
134 | unsigned int num_vq; | ||
135 | |||
132 | /* The name of this device, for --verbose. */ | 136 | /* The name of this device, for --verbose. */ |
133 | const char *name; | 137 | const char *name; |
134 | 138 | ||
@@ -245,7 +249,7 @@ static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len) | |||
245 | static u8 *get_feature_bits(struct device *dev) | 249 | static u8 *get_feature_bits(struct device *dev) |
246 | { | 250 | { |
247 | return (u8 *)(dev->desc + 1) | 251 | return (u8 *)(dev->desc + 1) |
248 | + dev->desc->num_vq * sizeof(struct lguest_vqconfig); | 252 | + dev->num_vq * sizeof(struct lguest_vqconfig); |
249 | } | 253 | } |
250 | 254 | ||
251 | /*L:100 The Launcher code itself takes us out into userspace, that scary place | 255 | /*L:100 The Launcher code itself takes us out into userspace, that scary place |
@@ -979,8 +983,8 @@ static void update_device_status(struct device *dev) | |||
979 | verbose("Resetting device %s\n", dev->name); | 983 | verbose("Resetting device %s\n", dev->name); |
980 | 984 | ||
981 | /* Clear any features they've acked. */ | 985 | /* Clear any features they've acked. */ |
982 | memset(get_feature_bits(dev) + dev->desc->feature_len, 0, | 986 | memset(get_feature_bits(dev) + dev->feature_len, 0, |
983 | dev->desc->feature_len); | 987 | dev->feature_len); |
984 | 988 | ||
985 | /* Zero out the virtqueues. */ | 989 | /* Zero out the virtqueues. */ |
986 | for (vq = dev->vq; vq; vq = vq->next) { | 990 | for (vq = dev->vq; vq; vq = vq->next) { |
@@ -994,12 +998,12 @@ static void update_device_status(struct device *dev) | |||
994 | unsigned int i; | 998 | unsigned int i; |
995 | 999 | ||
996 | verbose("Device %s OK: offered", dev->name); | 1000 | verbose("Device %s OK: offered", dev->name); |
997 | for (i = 0; i < dev->desc->feature_len; i++) | 1001 | for (i = 0; i < dev->feature_len; i++) |
998 | verbose(" %02x", get_feature_bits(dev)[i]); | 1002 | verbose(" %02x", get_feature_bits(dev)[i]); |
999 | verbose(", accepted"); | 1003 | verbose(", accepted"); |
1000 | for (i = 0; i < dev->desc->feature_len; i++) | 1004 | for (i = 0; i < dev->feature_len; i++) |
1001 | verbose(" %02x", get_feature_bits(dev) | 1005 | verbose(" %02x", get_feature_bits(dev) |
1002 | [dev->desc->feature_len+i]); | 1006 | [dev->feature_len+i]); |
1003 | 1007 | ||
1004 | if (dev->ready) | 1008 | if (dev->ready) |
1005 | dev->ready(dev); | 1009 | dev->ready(dev); |
@@ -1129,8 +1133,8 @@ static void handle_input(int fd) | |||
1129 | static u8 *device_config(const struct device *dev) | 1133 | static u8 *device_config(const struct device *dev) |
1130 | { | 1134 | { |
1131 | return (void *)(dev->desc + 1) | 1135 | return (void *)(dev->desc + 1) |
1132 | + dev->desc->num_vq * sizeof(struct lguest_vqconfig) | 1136 | + dev->num_vq * sizeof(struct lguest_vqconfig) |
1133 | + dev->desc->feature_len * 2; | 1137 | + dev->feature_len * 2; |
1134 | } | 1138 | } |
1135 | 1139 | ||
1136 | /* This routine allocates a new "struct lguest_device_desc" from descriptor | 1140 | /* This routine allocates a new "struct lguest_device_desc" from descriptor |
@@ -1191,6 +1195,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, | |||
1191 | * yet, otherwise we'd be overwriting them. */ | 1195 | * yet, otherwise we'd be overwriting them. */ |
1192 | assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0); | 1196 | assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0); |
1193 | memcpy(device_config(dev), &vq->config, sizeof(vq->config)); | 1197 | memcpy(device_config(dev), &vq->config, sizeof(vq->config)); |
1198 | dev->num_vq++; | ||
1194 | dev->desc->num_vq++; | 1199 | dev->desc->num_vq++; |
1195 | 1200 | ||
1196 | verbose("Virtqueue page %#lx\n", to_guest_phys(p)); | 1201 | verbose("Virtqueue page %#lx\n", to_guest_phys(p)); |
@@ -1219,7 +1224,7 @@ static void add_feature(struct device *dev, unsigned bit) | |||
1219 | /* We can't extend the feature bits once we've added config bytes */ | 1224 | /* We can't extend the feature bits once we've added config bytes */ |
1220 | if (dev->desc->feature_len <= bit / CHAR_BIT) { | 1225 | if (dev->desc->feature_len <= bit / CHAR_BIT) { |
1221 | assert(dev->desc->config_len == 0); | 1226 | assert(dev->desc->config_len == 0); |
1222 | dev->desc->feature_len = (bit / CHAR_BIT) + 1; | 1227 | dev->feature_len = dev->desc->feature_len = (bit/CHAR_BIT) + 1; |
1223 | } | 1228 | } |
1224 | 1229 | ||
1225 | features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT)); | 1230 | features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT)); |
@@ -1259,6 +1264,8 @@ static struct device *new_device(const char *name, u16 type, int fd, | |||
1259 | dev->name = name; | 1264 | dev->name = name; |
1260 | dev->vq = NULL; | 1265 | dev->vq = NULL; |
1261 | dev->ready = NULL; | 1266 | dev->ready = NULL; |
1267 | dev->feature_len = 0; | ||
1268 | dev->num_vq = 0; | ||
1262 | 1269 | ||
1263 | /* Append to device list. Prepending to a single-linked list is | 1270 | /* Append to device list. Prepending to a single-linked list is |
1264 | * easier, but the user expects the devices to be arranged on the bus | 1271 | * easier, but the user expects the devices to be arranged on the bus |