aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@cn.fujitsu.com>2011-07-13 02:31:50 -0400
committerAvi Kivity <avi@redhat.com>2011-09-25 12:17:17 -0400
commit77d197b2ca37b33b0461ab1e2dbe40cbe4a6fd6a (patch)
tree05ea5cbfd731818e91b4b6d16cf55905db29aea1 /arch/x86/kvm/x86.c
parentca7d58f375c650cf36900cb1da1ca2cc99b13393 (diff)
KVM: x86: abstract the operation for read/write emulation
The operations of read emulation and write emulation are very similar, so we can abstract the operation of them, in larter patch, it is used to cleanup the same code Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1453248723eb..f5c60a84fcf5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4136,6 +4136,78 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
4136 return 1; 4136 return 1;
4137} 4137}
4138 4138
4139struct read_write_emulator_ops {
4140 int (*read_write_prepare)(struct kvm_vcpu *vcpu, void *val,
4141 int bytes);
4142 int (*read_write_emulate)(struct kvm_vcpu *vcpu, gpa_t gpa,
4143 void *val, int bytes);
4144 int (*read_write_mmio)(struct kvm_vcpu *vcpu, gpa_t gpa,
4145 int bytes, void *val);
4146 int (*read_write_exit_mmio)(struct kvm_vcpu *vcpu, gpa_t gpa,
4147 void *val, int bytes);
4148 bool write;
4149};
4150
4151static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes)
4152{
4153 if (vcpu->mmio_read_completed) {
4154 memcpy(val, vcpu->mmio_data, bytes);
4155 trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes,
4156 vcpu->mmio_phys_addr, *(u64 *)val);
4157 vcpu->mmio_read_completed = 0;
4158 return 1;
4159 }
4160
4161 return 0;
4162}
4163
4164static int read_emulate(struct kvm_vcpu *vcpu, gpa_t gpa,
4165 void *val, int bytes)
4166{
4167 return !kvm_read_guest(vcpu->kvm, gpa, val, bytes);
4168}
4169
4170static int write_emulate(struct kvm_vcpu *vcpu, gpa_t gpa,
4171 void *val, int bytes)
4172{
4173 return emulator_write_phys(vcpu, gpa, val, bytes);
4174}
4175
4176static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val)
4177{
4178 trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
4179 return vcpu_mmio_write(vcpu, gpa, bytes, val);
4180}
4181
4182static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
4183 void *val, int bytes)
4184{
4185 trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0);
4186 return X86EMUL_IO_NEEDED;
4187}
4188
4189static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
4190 void *val, int bytes)
4191{
4192 memcpy(vcpu->mmio_data, val, bytes);
4193 memcpy(vcpu->run->mmio.data, vcpu->mmio_data, 8);
4194 return X86EMUL_CONTINUE;
4195}
4196
4197static struct read_write_emulator_ops read_emultor = {
4198 .read_write_prepare = read_prepare,
4199 .read_write_emulate = read_emulate,
4200 .read_write_mmio = vcpu_mmio_read,
4201 .read_write_exit_mmio = read_exit_mmio,
4202};
4203
4204static struct read_write_emulator_ops write_emultor = {
4205 .read_write_emulate = write_emulate,
4206 .read_write_mmio = write_mmio,
4207 .read_write_exit_mmio = write_exit_mmio,
4208 .write = true,
4209};
4210
4139static int emulator_write_emulated_onepage(unsigned long addr, 4211static int emulator_write_emulated_onepage(unsigned long addr,
4140 const void *val, 4212 const void *val,
4141 unsigned int bytes, 4213 unsigned int bytes,