Message ID | 5118D3B5.5010406@siemens.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Feb 11, 2013 at 12:19:17PM +0100, Jan Kiszka wrote: > This prevents trapping L2 I/O exits if L1 has neither unconditional nor > bitmap-based exiting enabled. Furthermore, it implements basic I/O > bitmap handling. Repeated string accesses are still reported to L1 > unconditionally for now. > > Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> > --- > > Changes in v2: > - fix two brown-paper-bag bugs (offset for bitmap_b, wrong direction > of mask shift) > - use vmcs12 argument instead of get_vmcs12 > > arch/x86/kvm/vmx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 52 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index fe9a9cf..64e1233 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -5913,6 +5913,57 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { > static const int kvm_vmx_max_exit_handlers = > ARRAY_SIZE(kvm_vmx_exit_handlers); > > +static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, > + struct vmcs12 *vmcs12) > +{ > + unsigned long exit_qualification; > + gpa_t bitmap, last_bitmap; > + bool string, rep; > + u16 port; > + int size; > + u8 b; > + > + if (nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING)) > + return 1; > + > + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) > + return 0; > + > + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); > + > + string = exit_qualification & 16; > + rep = exit_qualification & 32; > + > + /* TODO: interpret instruction and check range against bitmap */ > + if (string && rep) > + return 1; > + > + port = exit_qualification >> 16; > + size = (exit_qualification & 7) + 1; > + > + last_bitmap = (gpa_t)-1; > + b = -1; > + > + while (size > 0) { > + if (port < 0x8000) > + bitmap = vmcs12->io_bitmap_a; > + else > + bitmap = vmcs12->io_bitmap_b; > + bitmap += (port & 0x7fff) / 8; > + > + if (last_bitmap != bitmap) > + kvm_read_guest(vcpu->kvm, bitmap, &b, 1); Return value is ignored. > + if (b & (1 << (port & 7))) > + return 1; > + > + port++; > + size--; > + last_bitmap = bitmap; > + } > + > + return 0; > +} > + > /* > * Return 1 if we should exit from L2 to L1 to handle an MSR access access, > * rather than handle it ourselves in L0. I.e., check whether L1 expressed > @@ -6102,8 +6153,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) > case EXIT_REASON_DR_ACCESS: > return nested_cpu_has(vmcs12, CPU_BASED_MOV_DR_EXITING); > case EXIT_REASON_IO_INSTRUCTION: > - /* TODO: support IO bitmaps */ > - return 1; > + return nested_vmx_exit_handled_io(vcpu, vmcs12); > case EXIT_REASON_MSR_READ: > case EXIT_REASON_MSR_WRITE: > return nested_vmx_exit_handled_msr(vcpu, vmcs12, exit_reason); > -- > 1.7.3.4 -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 2013-02-14 10:32, Gleb Natapov wrote: > On Mon, Feb 11, 2013 at 12:19:17PM +0100, Jan Kiszka wrote: >> This prevents trapping L2 I/O exits if L1 has neither unconditional nor >> bitmap-based exiting enabled. Furthermore, it implements basic I/O >> bitmap handling. Repeated string accesses are still reported to L1 >> unconditionally for now. >> >> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> >> --- >> >> Changes in v2: >> - fix two brown-paper-bag bugs (offset for bitmap_b, wrong direction >> of mask shift) >> - use vmcs12 argument instead of get_vmcs12 >> >> arch/x86/kvm/vmx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- >> 1 files changed, 52 insertions(+), 2 deletions(-) >> >> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c >> index fe9a9cf..64e1233 100644 >> --- a/arch/x86/kvm/vmx.c >> +++ b/arch/x86/kvm/vmx.c >> @@ -5913,6 +5913,57 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { >> static const int kvm_vmx_max_exit_handlers = >> ARRAY_SIZE(kvm_vmx_exit_handlers); >> >> +static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, >> + struct vmcs12 *vmcs12) >> +{ >> + unsigned long exit_qualification; >> + gpa_t bitmap, last_bitmap; >> + bool string, rep; >> + u16 port; >> + int size; >> + u8 b; >> + >> + if (nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING)) >> + return 1; >> + >> + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) >> + return 0; >> + >> + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); >> + >> + string = exit_qualification & 16; >> + rep = exit_qualification & 32; >> + >> + /* TODO: interpret instruction and check range against bitmap */ >> + if (string && rep) >> + return 1; >> + >> + port = exit_qualification >> 16; >> + size = (exit_qualification & 7) + 1; >> + >> + last_bitmap = (gpa_t)-1; >> + b = -1; >> + >> + while (size > 0) { >> + if (port < 0x8000) >> + bitmap = vmcs12->io_bitmap_a; >> + else >> + bitmap = vmcs12->io_bitmap_b; >> + bitmap += (port & 0x7fff) / 8; >> + >> + if (last_bitmap != bitmap) >> + kvm_read_guest(vcpu->kvm, bitmap, &b, 1); > Return value is ignored. Not sure how to map a failure on real HW behaviour. I guess it's best to simply initialize b to -1 before each call, enforcing an exit on unaccessible bitmaps. BTW, nested_vmx_exit_handled_msr needs some improvement in this regard, too. Jan
On Thu, Feb 14, 2013 at 12:19:26PM +0100, Jan Kiszka wrote: > On 2013-02-14 10:32, Gleb Natapov wrote: > > On Mon, Feb 11, 2013 at 12:19:17PM +0100, Jan Kiszka wrote: > >> This prevents trapping L2 I/O exits if L1 has neither unconditional nor > >> bitmap-based exiting enabled. Furthermore, it implements basic I/O > >> bitmap handling. Repeated string accesses are still reported to L1 > >> unconditionally for now. > >> > >> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> > >> --- > >> > >> Changes in v2: > >> - fix two brown-paper-bag bugs (offset for bitmap_b, wrong direction > >> of mask shift) > >> - use vmcs12 argument instead of get_vmcs12 > >> > >> arch/x86/kvm/vmx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- > >> 1 files changed, 52 insertions(+), 2 deletions(-) > >> > >> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > >> index fe9a9cf..64e1233 100644 > >> --- a/arch/x86/kvm/vmx.c > >> +++ b/arch/x86/kvm/vmx.c > >> @@ -5913,6 +5913,57 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { > >> static const int kvm_vmx_max_exit_handlers = > >> ARRAY_SIZE(kvm_vmx_exit_handlers); > >> > >> +static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, > >> + struct vmcs12 *vmcs12) > >> +{ > >> + unsigned long exit_qualification; > >> + gpa_t bitmap, last_bitmap; > >> + bool string, rep; > >> + u16 port; > >> + int size; > >> + u8 b; > >> + > >> + if (nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING)) > >> + return 1; > >> + > >> + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) > >> + return 0; > >> + > >> + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); > >> + > >> + string = exit_qualification & 16; > >> + rep = exit_qualification & 32; > >> + > >> + /* TODO: interpret instruction and check range against bitmap */ > >> + if (string && rep) > >> + return 1; > >> + > >> + port = exit_qualification >> 16; > >> + size = (exit_qualification & 7) + 1; > >> + > >> + last_bitmap = (gpa_t)-1; > >> + b = -1; > >> + > >> + while (size > 0) { > >> + if (port < 0x8000) > >> + bitmap = vmcs12->io_bitmap_a; > >> + else > >> + bitmap = vmcs12->io_bitmap_b; > >> + bitmap += (port & 0x7fff) / 8; > >> + > >> + if (last_bitmap != bitmap) > >> + kvm_read_guest(vcpu->kvm, bitmap, &b, 1); > > Return value is ignored. > > Not sure how to map a failure on real HW behaviour. I guess it's best to Exit to L1 with nested_vmx_failValid() may be? > simply initialize b to -1 before each call, enforcing an exit on > unaccessible bitmaps. > I'd just make it explicit: if (kvm_read_guest()) return 1; > BTW, nested_vmx_exit_handled_msr needs some improvement in this regard, too. > Yes, nested_vmx_exit_handled_msr() use uninitialized 'b' from the stack. We are leaking host kernel data to a guest here. Patch? -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 2013-02-14 13:11, Gleb Natapov wrote: > On Thu, Feb 14, 2013 at 12:19:26PM +0100, Jan Kiszka wrote: >> On 2013-02-14 10:32, Gleb Natapov wrote: >>> On Mon, Feb 11, 2013 at 12:19:17PM +0100, Jan Kiszka wrote: >>>> This prevents trapping L2 I/O exits if L1 has neither unconditional nor >>>> bitmap-based exiting enabled. Furthermore, it implements basic I/O >>>> bitmap handling. Repeated string accesses are still reported to L1 >>>> unconditionally for now. >>>> >>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> >>>> --- >>>> >>>> Changes in v2: >>>> - fix two brown-paper-bag bugs (offset for bitmap_b, wrong direction >>>> of mask shift) >>>> - use vmcs12 argument instead of get_vmcs12 >>>> >>>> arch/x86/kvm/vmx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- >>>> 1 files changed, 52 insertions(+), 2 deletions(-) >>>> >>>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c >>>> index fe9a9cf..64e1233 100644 >>>> --- a/arch/x86/kvm/vmx.c >>>> +++ b/arch/x86/kvm/vmx.c >>>> @@ -5913,6 +5913,57 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { >>>> static const int kvm_vmx_max_exit_handlers = >>>> ARRAY_SIZE(kvm_vmx_exit_handlers); >>>> >>>> +static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, >>>> + struct vmcs12 *vmcs12) >>>> +{ >>>> + unsigned long exit_qualification; >>>> + gpa_t bitmap, last_bitmap; >>>> + bool string, rep; >>>> + u16 port; >>>> + int size; >>>> + u8 b; >>>> + >>>> + if (nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING)) >>>> + return 1; >>>> + >>>> + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) >>>> + return 0; >>>> + >>>> + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); >>>> + >>>> + string = exit_qualification & 16; >>>> + rep = exit_qualification & 32; >>>> + >>>> + /* TODO: interpret instruction and check range against bitmap */ >>>> + if (string && rep) >>>> + return 1; >>>> + >>>> + port = exit_qualification >> 16; >>>> + size = (exit_qualification & 7) + 1; >>>> + >>>> + last_bitmap = (gpa_t)-1; >>>> + b = -1; >>>> + >>>> + while (size > 0) { >>>> + if (port < 0x8000) >>>> + bitmap = vmcs12->io_bitmap_a; >>>> + else >>>> + bitmap = vmcs12->io_bitmap_b; >>>> + bitmap += (port & 0x7fff) / 8; >>>> + >>>> + if (last_bitmap != bitmap) >>>> + kvm_read_guest(vcpu->kvm, bitmap, &b, 1); >>> Return value is ignored. >> >> Not sure how to map a failure on real HW behaviour. I guess it's best to > Exit to L1 with nested_vmx_failValid() may be? To my understanding, nested_vmx_failValid/Invalid are related to errors directly related to vm instruction execution. This one is triggered by the guest later on. > >> simply initialize b to -1 before each call, enforcing an exit on >> unaccessible bitmaps. >> > I'd just make it explicit: > if (kvm_read_guest()) > return 1; OK. > >> BTW, nested_vmx_exit_handled_msr needs some improvement in this regard, too. >> > Yes, nested_vmx_exit_handled_msr() use uninitialized 'b' from the stack. > We are leaking host kernel data to a guest here. Patch? Will follow. Jan
On Thu, Feb 14, 2013 at 01:22:01PM +0100, Jan Kiszka wrote: > On 2013-02-14 13:11, Gleb Natapov wrote: > > On Thu, Feb 14, 2013 at 12:19:26PM +0100, Jan Kiszka wrote: > >> On 2013-02-14 10:32, Gleb Natapov wrote: > >>> On Mon, Feb 11, 2013 at 12:19:17PM +0100, Jan Kiszka wrote: > >>>> This prevents trapping L2 I/O exits if L1 has neither unconditional nor > >>>> bitmap-based exiting enabled. Furthermore, it implements basic I/O > >>>> bitmap handling. Repeated string accesses are still reported to L1 > >>>> unconditionally for now. > >>>> > >>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> > >>>> --- > >>>> > >>>> Changes in v2: > >>>> - fix two brown-paper-bag bugs (offset for bitmap_b, wrong direction > >>>> of mask shift) > >>>> - use vmcs12 argument instead of get_vmcs12 > >>>> > >>>> arch/x86/kvm/vmx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- > >>>> 1 files changed, 52 insertions(+), 2 deletions(-) > >>>> > >>>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > >>>> index fe9a9cf..64e1233 100644 > >>>> --- a/arch/x86/kvm/vmx.c > >>>> +++ b/arch/x86/kvm/vmx.c > >>>> @@ -5913,6 +5913,57 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { > >>>> static const int kvm_vmx_max_exit_handlers = > >>>> ARRAY_SIZE(kvm_vmx_exit_handlers); > >>>> > >>>> +static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, > >>>> + struct vmcs12 *vmcs12) > >>>> +{ > >>>> + unsigned long exit_qualification; > >>>> + gpa_t bitmap, last_bitmap; > >>>> + bool string, rep; > >>>> + u16 port; > >>>> + int size; > >>>> + u8 b; > >>>> + > >>>> + if (nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING)) > >>>> + return 1; > >>>> + > >>>> + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) > >>>> + return 0; > >>>> + > >>>> + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); > >>>> + > >>>> + string = exit_qualification & 16; > >>>> + rep = exit_qualification & 32; > >>>> + > >>>> + /* TODO: interpret instruction and check range against bitmap */ > >>>> + if (string && rep) > >>>> + return 1; > >>>> + > >>>> + port = exit_qualification >> 16; > >>>> + size = (exit_qualification & 7) + 1; > >>>> + > >>>> + last_bitmap = (gpa_t)-1; > >>>> + b = -1; > >>>> + > >>>> + while (size > 0) { > >>>> + if (port < 0x8000) > >>>> + bitmap = vmcs12->io_bitmap_a; > >>>> + else > >>>> + bitmap = vmcs12->io_bitmap_b; > >>>> + bitmap += (port & 0x7fff) / 8; > >>>> + > >>>> + if (last_bitmap != bitmap) > >>>> + kvm_read_guest(vcpu->kvm, bitmap, &b, 1); > >>> Return value is ignored. > >> > >> Not sure how to map a failure on real HW behaviour. I guess it's best to > > Exit to L1 with nested_vmx_failValid() may be? > > To my understanding, nested_vmx_failValid/Invalid are related to errors > directly related to vm instruction execution. This one is triggered by > the guest later on. > You are right. We need some kind of error vmexit here, but nothing appropriate is defined by the spec, so lets just assume that exit to L1 is needed if we cannot read permission bitmaps. > > > >> simply initialize b to -1 before each call, enforcing an exit on > >> unaccessible bitmaps. > >> > > I'd just make it explicit: > > if (kvm_read_guest()) > > return 1; > > OK. > > > > >> BTW, nested_vmx_exit_handled_msr needs some improvement in this regard, too. > >> > > Yes, nested_vmx_exit_handled_msr() use uninitialized 'b' from the stack. > > We are leaking host kernel data to a guest here. Patch? > > Will follow. > > Jan > > -- > Siemens AG, Corporate Technology, CT RTC ITP SDP-DE > Corporate Competence Center Embedded Linux -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Feb 14, 2013, Gleb Natapov wrote about "Re: [PATCH v2] KVM: nVMX: Improve I/O exit handling": > > >> Not sure how to map a failure on real HW behaviour. I guess it's best to > > > Exit to L1 with nested_vmx_failValid() may be? > > > > To my understanding, nested_vmx_failValid/Invalid are related to errors > > directly related to vm instruction execution. This one is triggered by > > the guest later on. > > > You are right. We need some kind of error vmexit here, but nothing > appropriate is defined by the spec, so lets just assume that exit to L1 > is needed if we cannot read permission bitmaps. On real hardware, note that the MSR-bitmap address specified in the VMCS is a physical address, so there can never be an error - if I understand correctly, there is no such thing as a non-existant physical address - reading from non-existant physical memory returns random garbage (please correct me if I'm wrong here!). So if I'm correct, using a non-existent address for an MSR-bitmap will give you an undefined behavior - not any sort of entry error to special type of exit. The current code, using a random value on the stack, fits with the "undefined behavior" definition, but you're right the more logical behavior is to, indeed, always exit on the MSR access when the bitmap cannot be read. This will make an unreadable bitmap equivalent to no bitmap at all - which I think makes most sense. You're also right that this case is identical in both MSR and I/O bitmap cases, and should be fixed in both.
On Thu, Feb 14, 2013 at 03:54:23PM +0200, Nadav Har'El wrote: > On Thu, Feb 14, 2013, Gleb Natapov wrote about "Re: [PATCH v2] KVM: nVMX: Improve I/O exit handling": > > > >> Not sure how to map a failure on real HW behaviour. I guess it's best to > > > > Exit to L1 with nested_vmx_failValid() may be? > > > > > > To my understanding, nested_vmx_failValid/Invalid are related to errors > > > directly related to vm instruction execution. This one is triggered by > > > the guest later on. > > > > > You are right. We need some kind of error vmexit here, but nothing > > appropriate is defined by the spec, so lets just assume that exit to L1 > > is needed if we cannot read permission bitmaps. > > On real hardware, note that the MSR-bitmap address specified in the VMCS > is a physical address, so there can never be an error - if I understand > correctly, there is no such thing as a non-existant physical address - > reading from non-existant physical memory returns random garbage (please > correct me if I'm wrong here!). So if I'm correct, using a non-existent > address for an MSR-bitmap will give you an undefined behavior - not any > sort of entry error to special type of exit. > That's true for real HW. Reading from physical address outside of physical memory will either access some random device MMIO or nothing. Either way result is unpredictable and may hang the machine. I am fine with killing a guest that tries to do that. > The current code, using a random value on the stack, fits with the > "undefined behavior" definition, but you're right the more logical > behavior is to, indeed, always exit on the MSR access when the bitmap > cannot be read. This will make an unreadable bitmap equivalent to no > bitmap at all - which I think makes most sense. Current case leaks data from host kernel, not just exhibit random behaviour. > > You're also right that this case is identical in both MSR and I/O bitmap > cases, and should be fixed in both. > > > -- > Nadav Har'El | Thursday, Feb 14 2013, 4 Adar 5773 > nyh@math.technion.ac.il |----------------------------------------- > Phone +972-523-790466, ICQ 13349191 |A fanatic is one who can't change his > http://nadav.harel.org.il |mind and won't change the subject. -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index fe9a9cf..64e1233 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5913,6 +5913,57 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { static const int kvm_vmx_max_exit_handlers = ARRAY_SIZE(kvm_vmx_exit_handlers); +static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, + struct vmcs12 *vmcs12) +{ + unsigned long exit_qualification; + gpa_t bitmap, last_bitmap; + bool string, rep; + u16 port; + int size; + u8 b; + + if (nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING)) + return 1; + + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) + return 0; + + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + + string = exit_qualification & 16; + rep = exit_qualification & 32; + + /* TODO: interpret instruction and check range against bitmap */ + if (string && rep) + return 1; + + port = exit_qualification >> 16; + size = (exit_qualification & 7) + 1; + + last_bitmap = (gpa_t)-1; + b = -1; + + while (size > 0) { + if (port < 0x8000) + bitmap = vmcs12->io_bitmap_a; + else + bitmap = vmcs12->io_bitmap_b; + bitmap += (port & 0x7fff) / 8; + + if (last_bitmap != bitmap) + kvm_read_guest(vcpu->kvm, bitmap, &b, 1); + if (b & (1 << (port & 7))) + return 1; + + port++; + size--; + last_bitmap = bitmap; + } + + return 0; +} + /* * Return 1 if we should exit from L2 to L1 to handle an MSR access access, * rather than handle it ourselves in L0. I.e., check whether L1 expressed @@ -6102,8 +6153,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) case EXIT_REASON_DR_ACCESS: return nested_cpu_has(vmcs12, CPU_BASED_MOV_DR_EXITING); case EXIT_REASON_IO_INSTRUCTION: - /* TODO: support IO bitmaps */ - return 1; + return nested_vmx_exit_handled_io(vcpu, vmcs12); case EXIT_REASON_MSR_READ: case EXIT_REASON_MSR_WRITE: return nested_vmx_exit_handled_msr(vcpu, vmcs12, exit_reason);
This prevents trapping L2 I/O exits if L1 has neither unconditional nor bitmap-based exiting enabled. Furthermore, it implements basic I/O bitmap handling. Repeated string accesses are still reported to L1 unconditionally for now. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> --- Changes in v2: - fix two brown-paper-bag bugs (offset for bitmap_b, wrong direction of mask shift) - use vmcs12 argument instead of get_vmcs12 arch/x86/kvm/vmx.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 52 insertions(+), 2 deletions(-)