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>
This commit is contained in:
parent
ca7d58f375
commit
77d197b2ca
1 changed files with 72 additions and 0 deletions
|
@ -4136,6 +4136,78 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct read_write_emulator_ops {
|
||||||
|
int (*read_write_prepare)(struct kvm_vcpu *vcpu, void *val,
|
||||||
|
int bytes);
|
||||||
|
int (*read_write_emulate)(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||||
|
void *val, int bytes);
|
||||||
|
int (*read_write_mmio)(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||||
|
int bytes, void *val);
|
||||||
|
int (*read_write_exit_mmio)(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||||
|
void *val, int bytes);
|
||||||
|
bool write;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes)
|
||||||
|
{
|
||||||
|
if (vcpu->mmio_read_completed) {
|
||||||
|
memcpy(val, vcpu->mmio_data, bytes);
|
||||||
|
trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes,
|
||||||
|
vcpu->mmio_phys_addr, *(u64 *)val);
|
||||||
|
vcpu->mmio_read_completed = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_emulate(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||||
|
void *val, int bytes)
|
||||||
|
{
|
||||||
|
return !kvm_read_guest(vcpu->kvm, gpa, val, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_emulate(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||||
|
void *val, int bytes)
|
||||||
|
{
|
||||||
|
return emulator_write_phys(vcpu, gpa, val, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val)
|
||||||
|
{
|
||||||
|
trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
|
||||||
|
return vcpu_mmio_write(vcpu, gpa, bytes, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||||
|
void *val, int bytes)
|
||||||
|
{
|
||||||
|
trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0);
|
||||||
|
return X86EMUL_IO_NEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||||
|
void *val, int bytes)
|
||||||
|
{
|
||||||
|
memcpy(vcpu->mmio_data, val, bytes);
|
||||||
|
memcpy(vcpu->run->mmio.data, vcpu->mmio_data, 8);
|
||||||
|
return X86EMUL_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct read_write_emulator_ops read_emultor = {
|
||||||
|
.read_write_prepare = read_prepare,
|
||||||
|
.read_write_emulate = read_emulate,
|
||||||
|
.read_write_mmio = vcpu_mmio_read,
|
||||||
|
.read_write_exit_mmio = read_exit_mmio,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct read_write_emulator_ops write_emultor = {
|
||||||
|
.read_write_emulate = write_emulate,
|
||||||
|
.read_write_mmio = write_mmio,
|
||||||
|
.read_write_exit_mmio = write_exit_mmio,
|
||||||
|
.write = true,
|
||||||
|
};
|
||||||
|
|
||||||
static int emulator_write_emulated_onepage(unsigned long addr,
|
static int emulator_write_emulated_onepage(unsigned long addr,
|
||||||
const void *val,
|
const void *val,
|
||||||
unsigned int bytes,
|
unsigned int bytes,
|
||||||
|
|
Loading…
Reference in a new issue