summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve/inout.c
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2014-06-01 02:13:07 +0000
committerneel <neel@FreeBSD.org>2014-06-01 02:13:07 +0000
commita6503bd2d624edd4017ade0d1edb3ad7ce366549 (patch)
treebfa3543fd90516549093894b51a1322371ebc72d /usr.sbin/bhyve/inout.c
parent9c2a9423876303af6b7757283943735603cdacf7 (diff)
downloadFreeBSD-src-a6503bd2d624edd4017ade0d1edb3ad7ce366549.zip
FreeBSD-src-a6503bd2d624edd4017ade0d1edb3ad7ce366549.tar.gz
Limit the maximum number of back-to-back iterations of a "rep; ins/outs"
to 16. This is arbitrary and is used to ensure that a vcpu goes back into the vm_run() loop to process interrupts or rendezvous events in a timely fashion. Found with: Coverity Scan CID: 1216436
Diffstat (limited to 'usr.sbin/bhyve/inout.c')
-rw-r--r--usr.sbin/bhyve/inout.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/usr.sbin/bhyve/inout.c b/usr.sbin/bhyve/inout.c
index babd6e1..cb34b80 100644
--- a/usr.sbin/bhyve/inout.c
+++ b/usr.sbin/bhyve/inout.c
@@ -55,6 +55,10 @@ SET_DECLARE(inout_port_set, struct inout_port);
#define VERIFY_IOPORT(port, size) \
assert((port) >= 0 && (size) > 0 && ((port) + (size)) <= MAX_IOPORTS)
+#ifndef min
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
static struct {
const char *name;
int flags;
@@ -109,7 +113,7 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict)
void *arg;
int error, retval;
enum vm_reg_name idxreg;
- uint64_t gla, index, count;
+ uint64_t gla, index, iterations, count;
struct vm_inout_str *vis;
struct iovec iov[2];
@@ -151,14 +155,17 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict)
/* Count register */
count = vis->count & vie_size2mask(addrsize);
- while (count) {
+ /* Limit number of back-to-back in/out emulations to 16 */
+ iterations = min(count, 16);
+ while (iterations > 0) {
if (vie_calculate_gla(vis->paging.cpu_mode,
vis->seg_name, &vis->seg_desc, index, bytes,
addrsize, prot, &gla)) {
error = vm_inject_exception2(ctx, vcpu,
IDT_GP, 0);
assert(error == 0);
- return (INOUT_RESTART);
+ retval = INOUT_RESTART;
+ break;
}
error = vm_gla2gpa(ctx, vcpu, &vis->paging, gla, bytes,
@@ -196,6 +203,7 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict)
index += bytes;
count--;
+ iterations--;
}
/* Update index register */
OpenPOWER on IntegriCloud