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
This commit is contained in:
parent
95ebc360ef
commit
0be3798af5
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user