提交 cef4dea0 编写于 作者: A Avi Kivity

KVM: 16-byte mmio support

Since sse instructions can issue 16-byte mmios, we need to support them.  We
can't increase the kvm_run mmio buffer size to 16 bytes without breaking
compatibility, so instead we break the large mmios into two smaller 8-byte
ones.  Since the bus is 64-bit we aren't breaking any atomicity guarantees.
Signed-off-by: NAvi Kivity <avi@redhat.com>
上级 5287f194
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define KVM_MEMORY_SLOTS 32 #define KVM_MEMORY_SLOTS 32
/* memory slots that does not exposed to userspace */ /* memory slots that does not exposed to userspace */
#define KVM_PRIVATE_MEM_SLOTS 4 #define KVM_PRIVATE_MEM_SLOTS 4
#define KVM_MMIO_SIZE 16
#define KVM_PIO_PAGE_OFFSET 1 #define KVM_PIO_PAGE_OFFSET 1
#define KVM_COALESCED_MMIO_PAGE_OFFSET 2 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2
......
...@@ -3833,8 +3833,10 @@ static int emulator_read_emulated(unsigned long addr, ...@@ -3833,8 +3833,10 @@ static int emulator_read_emulated(unsigned long addr,
vcpu->mmio_needed = 1; vcpu->mmio_needed = 1;
vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->exit_reason = KVM_EXIT_MMIO;
vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa; vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa;
vcpu->run->mmio.len = vcpu->mmio_size = bytes; vcpu->mmio_size = bytes;
vcpu->run->mmio.len = min(vcpu->mmio_size, 8);
vcpu->run->mmio.is_write = vcpu->mmio_is_write = 0; vcpu->run->mmio.is_write = vcpu->mmio_is_write = 0;
vcpu->mmio_index = 0;
return X86EMUL_IO_NEEDED; return X86EMUL_IO_NEEDED;
} }
...@@ -3886,11 +3888,14 @@ static int emulator_write_emulated_onepage(unsigned long addr, ...@@ -3886,11 +3888,14 @@ static int emulator_write_emulated_onepage(unsigned long addr,
val += handled; val += handled;
vcpu->mmio_needed = 1; vcpu->mmio_needed = 1;
memcpy(vcpu->mmio_data, val, bytes);
vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->exit_reason = KVM_EXIT_MMIO;
vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa; vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa;
vcpu->run->mmio.len = vcpu->mmio_size = bytes; vcpu->mmio_size = bytes;
vcpu->run->mmio.len = min(vcpu->mmio_size, 8);
vcpu->run->mmio.is_write = vcpu->mmio_is_write = 1; vcpu->run->mmio.is_write = vcpu->mmio_is_write = 1;
memcpy(vcpu->run->mmio.data, val, bytes); memcpy(vcpu->run->mmio.data, vcpu->mmio_data, 8);
vcpu->mmio_index = 0;
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
} }
...@@ -4498,11 +4503,9 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, ...@@ -4498,11 +4503,9 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
if (!vcpu->arch.pio.in) if (!vcpu->arch.pio.in)
vcpu->arch.pio.count = 0; vcpu->arch.pio.count = 0;
r = EMULATE_DO_MMIO; r = EMULATE_DO_MMIO;
} else if (vcpu->mmio_needed) { } else if (vcpu->mmio_needed)
if (vcpu->mmio_is_write)
vcpu->mmio_needed = 0;
r = EMULATE_DO_MMIO; r = EMULATE_DO_MMIO;
} else if (r == EMULATION_RESTART) else if (r == EMULATION_RESTART)
goto restart; goto restart;
else else
r = EMULATE_DONE; r = EMULATE_DONE;
...@@ -5450,9 +5453,22 @@ static int complete_mmio(struct kvm_vcpu *vcpu) ...@@ -5450,9 +5453,22 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
return 1; return 1;
if (vcpu->mmio_needed) { if (vcpu->mmio_needed) {
memcpy(vcpu->mmio_data, run->mmio.data, 8);
vcpu->mmio_read_completed = 1;
vcpu->mmio_needed = 0; vcpu->mmio_needed = 0;
if (!vcpu->mmio_is_write)
memcpy(vcpu->mmio_data, run->mmio.data, 8);
vcpu->mmio_index += 8;
if (vcpu->mmio_index < vcpu->mmio_size) {
run->exit_reason = KVM_EXIT_MMIO;
run->mmio.phys_addr = vcpu->mmio_phys_addr + vcpu->mmio_index;
memcpy(run->mmio.data, vcpu->mmio_data + vcpu->mmio_index, 8);
run->mmio.len = min(vcpu->mmio_size - vcpu->mmio_index, 8);
run->mmio.is_write = vcpu->mmio_is_write;
vcpu->mmio_needed = 1;
return 0;
}
if (vcpu->mmio_is_write)
return 1;
vcpu->mmio_read_completed = 1;
} }
vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE); r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
......
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
#include <asm/kvm_host.h> #include <asm/kvm_host.h>
#ifndef KVM_MMIO_SIZE
#define KVM_MMIO_SIZE 8
#endif
/* /*
* vcpu->requests bit members * vcpu->requests bit members
*/ */
...@@ -132,7 +136,8 @@ struct kvm_vcpu { ...@@ -132,7 +136,8 @@ struct kvm_vcpu {
int mmio_read_completed; int mmio_read_completed;
int mmio_is_write; int mmio_is_write;
int mmio_size; int mmio_size;
unsigned char mmio_data[8]; int mmio_index;
unsigned char mmio_data[KVM_MMIO_SIZE];
gpa_t mmio_phys_addr; gpa_t mmio_phys_addr;
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册