]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
x86: Add AMD-V port-based I/O VM exit handler
authorValentine Sinitsyn <valentine.sinitsyn@gmail.com>
Sun, 28 Sep 2014 12:30:40 +0000 (18:30 +0600)
committerJan Kiszka <jan.kiszka@siemens.com>
Sat, 1 Nov 2014 19:10:09 +0000 (20:10 +0100)
This is just the same as NPF handler: all real work is done in
vcpu_handle_io_access().

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/svm.c

index 6ac2113295ccadb14264534af5b5b33a0a6a08bf..db9045c74552dbe0425c97e85b83dd80b2e6644e 100644 (file)
@@ -552,11 +552,26 @@ static void vcpu_vendor_get_pf_intercept(struct per_cpu *cpu_data,
        out->is_write = !!(vmcb->exitinfo1 & 0x2);
 }
 
+static void vcpu_vendor_get_io_intercept(struct per_cpu *cpu_data,
+                                        struct vcpu_io_intercept *out)
+{
+       struct vmcb *vmcb = &cpu_data->vmcb;
+       u64 exitinfo = vmcb->exitinfo1;
+
+       /* parse exit info for I/O instructions (see APM, 15.10.2 ) */
+       out->port = (exitinfo >> 16) & 0xFFFF;
+       out->size = (exitinfo >> 4) & 0x7;
+       out->in = !!(exitinfo & 0x1);
+       out->inst_len = vmcb->exitinfo2 - vmcb->rip;
+       out->rep_or_str = !!(exitinfo & 0x0c);
+}
+
 void vcpu_handle_exit(struct registers *guest_regs, struct per_cpu *cpu_data)
 {
        struct vmcb *vmcb = &cpu_data->vmcb;
        struct vcpu_execution_state x_state;
        struct vcpu_pf_intercept pf;
+       struct vcpu_io_intercept io;
        bool res = false;
 
        /* Restore GS value expected by per_cpu data accessors */
@@ -605,6 +620,12 @@ void vcpu_handle_exit(struct registers *guest_regs, struct per_cpu *cpu_data)
                             "error code is %x\n", vmcb->exitinfo2,
                             vmcb->exitinfo1 & 0xf);
                break;
+       case VMEXIT_IOIO:
+               cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_PIO]++;
+               vcpu_vendor_get_io_intercept(cpu_data, &io);
+               if (vcpu_handle_io_access(guest_regs, &io))
+                       return;
+               break;
        /* TODO: Handle VMEXIT_AVIC_NOACCEL and VMEXIT_AVIC_INCOMPLETE_IPI */
        default:
                panic_printk("FATAL: Unexpected #VMEXIT, exitcode %x, "