staticvoid guest_code(void)
{
uint8_t buffer[8192]; int i;
/* * Special case tests. main() will adjust RCX 2 => 1 and 3 => 8192 to * test that KVM doesn't explode when userspace modifies the "count" on * a userspace I/O exit. KVM isn't required to play nice with the I/O * itself as KVM doesn't support manipulating the count, it just needs * to not explode or overflow a buffer.
*/
guest_ins_port80(buffer, 2);
guest_ins_port80(buffer, 3);
/* Verify KVM fills the buffer correctly when not stuffing RCX. */
memset(buffer, 0, sizeof(buffer));
guest_ins_port80(buffer, 8192); for (i = 0; i < 8192; i++)
__GUEST_ASSERT(buffer[i] == 0xaa, "Expected '0xaa', got '0x%x' at buffer[%u]",
buffer[i], i);
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
run = vcpu->run;
memset(®s, 0, sizeof(regs));
while (1) {
vcpu_run(vcpu);
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
if (get_ucall(vcpu, &uc)) break;
TEST_ASSERT(run->io.port == 0x80, "Expected I/O at port 0x80, got port 0x%x", run->io.port);
/* * Modify the rep string count in RCX: 2 => 1 and 3 => 8192. * Note, this abuses KVM's batching of rep string I/O to avoid * getting stuck in an infinite loop. That behavior isn't in * scope from a testing perspective as it's not ABI in any way, * i.e. it really is abusing internal KVM knowledge.
*/
vcpu_regs_get(vcpu, ®s); if (regs.rcx == 2)
regs.rcx = 1; if (regs.rcx == 3)
regs.rcx = 8192;
memset((void *)run + run->io.data_offset, 0xaa, 4096);
vcpu_regs_set(vcpu, ®s);
}
switch (uc.cmd) { case UCALL_DONE: break; case UCALL_ABORT:
REPORT_GUEST_ASSERT(uc); default:
TEST_FAIL("Unknown ucall %lu", uc.cmd);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.