@ -4045,85 +4045,6 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
return 0 ;
}
static int emulator_read_emulated_onepage ( unsigned long addr ,
void * val ,
unsigned int bytes ,
struct x86_exception * exception ,
struct kvm_vcpu * vcpu )
{
gpa_t gpa ;
int handled , ret ;
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 X86EMUL_CONTINUE ;
}
ret = vcpu_mmio_gva_to_gpa ( vcpu , addr , & gpa , exception , false ) ;
if ( ret < 0 )
return X86EMUL_PROPAGATE_FAULT ;
if ( ret )
goto mmio ;
if ( ! kvm_read_guest ( vcpu - > kvm , gpa , val , bytes ) )
return X86EMUL_CONTINUE ;
mmio :
/*
* Is this MMIO handled locally ?
*/
handled = vcpu_mmio_read ( vcpu , gpa , bytes , val ) ;
if ( handled = = bytes )
return X86EMUL_CONTINUE ;
gpa + = handled ;
bytes - = handled ;
val + = handled ;
trace_kvm_mmio ( KVM_TRACE_MMIO_READ_UNSATISFIED , bytes , gpa , 0 ) ;
vcpu - > mmio_needed = 1 ;
vcpu - > run - > exit_reason = KVM_EXIT_MMIO ;
vcpu - > run - > mmio . phys_addr = vcpu - > mmio_phys_addr = gpa ;
vcpu - > mmio_size = bytes ;
vcpu - > run - > mmio . len = min ( vcpu - > mmio_size , 8 ) ;
vcpu - > run - > mmio . is_write = vcpu - > mmio_is_write = 0 ;
vcpu - > mmio_index = 0 ;
return X86EMUL_IO_NEEDED ;
}
static int emulator_read_emulated ( struct x86_emulate_ctxt * ctxt ,
unsigned long addr ,
void * val ,
unsigned int bytes ,
struct x86_exception * exception )
{
struct kvm_vcpu * vcpu = emul_to_vcpu ( ctxt ) ;
/* Crossing a page boundary? */
if ( ( ( addr + bytes - 1 ) ^ addr ) & PAGE_MASK ) {
int rc , now ;
now = - addr & ~ PAGE_MASK ;
rc = emulator_read_emulated_onepage ( addr , val , now , exception ,
vcpu ) ;
if ( rc ! = X86EMUL_CONTINUE )
return rc ;
addr + = now ;
val + = now ;
bytes - = now ;
}
return emulator_read_emulated_onepage ( addr , val , bytes , exception ,
vcpu ) ;
}
int emulator_write_phys ( struct kvm_vcpu * vcpu , gpa_t gpa ,
const void * val , int bytes )
{
@ -4208,16 +4129,21 @@ static struct read_write_emulator_ops write_emultor = {
. write = true ,
} ;
static int emulator_w rit e_emul ated _onepage ( unsigned long addr ,
const void * val ,
unsigned int bytes ,
struct x86_exception * exception ,
struct kvm_vcpu * vcpu )
static int emulator_read_wri te_onepage ( unsigned long addr , void * val ,
unsigned int bytes ,
struct x86_exception * exception ,
struct kvm_vcpu * vcpu ,
struct read_write_emulator_ops * ops )
{
gpa_t gpa ;
int handled , ret ;
bool write = ops - > write ;
if ( ops - > read_write_prepare & &
ops - > read_write_prepare ( vcpu , val , bytes ) )
return X86EMUL_CONTINUE ;
ret = vcpu_mmio_gva_to_gpa ( vcpu , addr , & gpa , exception , true ) ;
ret = vcpu_mmio_gva_to_gpa ( vcpu , addr , & gpa , exception , writ e) ;
if ( ret < 0 )
return X86EMUL_PROPAGATE_FAULT ;
@ -4226,15 +4152,14 @@ static int emulator_write_emulated_onepage(unsigned long addr,
if ( ret )
goto mmio ;
if ( emulator_write_phys ( vcpu , gpa , val , bytes ) )
if ( ops - > read_write_emulate ( vcpu , gpa , val , bytes ) )
return X86EMUL_CONTINUE ;
mmio :
trace_kvm_mmio ( KVM_TRACE_MMIO_WRITE , bytes , gpa , * ( u64 * ) val ) ;
/*
* Is this MMIO handled locally ?
*/
handled = vcpu_mmio_write ( vcpu , gpa , bytes , val ) ;
handled = ops - > read_write_mmio ( vcpu , gpa , bytes , val ) ;
if ( handled = = bytes )
return X86EMUL_CONTINUE ;
@ -4243,23 +4168,20 @@ mmio:
val + = handled ;
vcpu - > mmio_needed = 1 ;
memcpy ( vcpu - > mmio_data , val , bytes ) ;
vcpu - > run - > exit_reason = KVM_EXIT_MMIO ;
vcpu - > run - > mmio . phys_addr = vcpu - > mmio_phys_addr = gpa ;
vcpu - > mmio_size = bytes ;
vcpu - > run - > mmio . len = min ( vcpu - > mmio_size , 8 ) ;
vcpu - > run - > mmio . is_write = vcpu - > mmio_is_write = 1 ;
memcpy ( vcpu - > run - > mmio . data , vcpu - > mmio_data , 8 ) ;
vcpu - > run - > mmio . is_write = vcpu - > mmio_is_write = write ;
vcpu - > mmio_index = 0 ;
return X86EMUL_CONTINUE ;
return ops - > read_write_exit_mmio ( vcpu , gpa , val , bytes ) ;
}
int emulator_write_emulated ( struct x86_emulate_ctxt * ctxt ,
unsigned long addr ,
const void * val ,
unsigned int bytes ,
struct x86_exception * exception )
int emulator_read_write ( struct x86_emulate_ctxt * ctxt , unsigned long addr ,
void * val , unsigned int bytes ,
struct x86_exception * exception ,
struct read_write_emulator_ops * ops )
{
struct kvm_vcpu * vcpu = emul_to_vcpu ( ctxt ) ;
@ -4268,16 +4190,38 @@ int emulator_write_emulated(struct x86_emulate_ctxt *ctxt,
int rc , now ;
now = - addr & ~ PAGE_MASK ;
rc = emulator_write_emulated_onepage ( addr , val , now , exception ,
vcpu ) ;
rc = emulator_read_write_onepage ( addr , val , now , exception ,
vcpu , ops ) ;
if ( rc ! = X86EMUL_CONTINUE )
return rc ;
addr + = now ;
val + = now ;
bytes - = now ;
}
return emulator_write_emulated_onepage ( addr , val , bytes , exception ,
vcpu ) ;
return emulator_read_write_onepage ( addr , val , bytes , exception ,
vcpu , ops ) ;
}
static int emulator_read_emulated ( struct x86_emulate_ctxt * ctxt ,
unsigned long addr ,
void * val ,
unsigned int bytes ,
struct x86_exception * exception )
{
return emulator_read_write ( ctxt , addr , val , bytes ,
exception , & read_emultor ) ;
}
int emulator_write_emulated ( struct x86_emulate_ctxt * ctxt ,
unsigned long addr ,
const void * val ,
unsigned int bytes ,
struct x86_exception * exception )
{
return emulator_read_write ( ctxt , addr , ( void * ) val , bytes ,
exception , & write_emultor ) ;
}
# define CMPXCHG_TYPE(t, ptr, old, new) \