@ -32,7 +32,14 @@
do { } while ( 0 )
# endif
typedef struct kvm_userspace_memory_region KVMSlot ;
typedef struct KVMSlot
{
target_phys_addr_t start_addr ;
ram_addr_t memory_size ;
ram_addr_t phys_offset ;
int slot ;
int flags ;
} KVMSlot ;
int kvm_allowed = 0 ;
@ -67,8 +74,8 @@ static KVMSlot *kvm_lookup_slot(KVMState *s, target_phys_addr_t start_addr)
for ( i = 0 ; i < ARRAY_SIZE ( s - > slots ) ; i + + ) {
KVMSlot * mem = & s - > slots [ i ] ;
if ( start_addr > = mem - > guest_phys _addr & &
start_addr < ( mem - > guest_phys _addr + mem - > memory_size ) )
if ( start_addr > = mem - > start _addr & &
start_addr < ( mem - > start _addr + mem - > memory_size ) )
return mem ;
}
@ -309,6 +316,19 @@ int kvm_cpu_exec(CPUState *env)
return ret ;
}
static int kvm_set_user_memory_region ( KVMState * s , KVMSlot * slot )
{
struct kvm_userspace_memory_region mem ;
mem . slot = slot - > slot ;
mem . guest_phys_addr = slot - > start_addr ;
mem . memory_size = slot - > memory_size ;
mem . userspace_addr = ( unsigned long ) phys_ram_base + slot - > phys_offset ;
mem . flags = slot - > flags ;
return kvm_vm_ioctl ( s , KVM_SET_USER_MEMORY_REGION , & mem ) ;
}
void kvm_set_phys_mem ( target_phys_addr_t start_addr ,
ram_addr_t size ,
ram_addr_t phys_offset )
@ -324,32 +344,32 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr,
if ( mem ) {
if ( ( flags = = IO_MEM_UNASSIGNED ) | | ( flags > = TLB_MMIO ) ) {
mem - > memory_size = 0 ;
mem - > guest_phys _addr = start_addr ;
mem - > userspace_addr = 0 ;
mem - > start _addr = start_addr ;
mem - > phys_offset = 0 ;
mem - > flags = 0 ;
kvm_vm_ioctl ( s , KVM_SET_USER_MEMORY_REGION , mem ) ;
} else if ( start_addr > = mem - > guest_phys _addr & &
( start_addr + size ) < = ( mem - > guest_phys _addr +
kvm_set_user_memory_region ( s , mem ) ;
} else if ( start_addr > = mem - > start _addr & &
( start_addr + size ) < = ( mem - > start _addr +
mem - > memory_size ) ) {
KVMSlot slot ;
target_phys_addr_t mem_start ;
ram_addr_t mem_size , mem_offset ;
/* Not splitting */
if ( ( phys_offset - ( start_addr - mem - > guest_phys _addr) ) = =
( ( uint8_t * ) mem - > userspace_addr - phys_ram_base ) )
if ( ( phys_offset - ( start_addr - mem - > start _addr) ) = =
mem - > phys_offset )
return ;
/* unregister whole slot */
memcpy ( & slot , mem , sizeof ( slot ) ) ;
mem - > memory_size = 0 ;
kvm_vm_ioctl ( s , KVM_SET_USER_MEMORY_REGION , mem ) ;
kvm_set_user_memory_region ( s , mem ) ;
/* register prefix slot */
mem_start = slot . guest_phys _addr;
mem_size = start_addr - slot . guest_phys _addr;
mem_offset = ( uint8_t * ) slot . userspace_addr - phys_ram_base ;
mem_start = slot . start _addr;
mem_size = start_addr - slot . start _addr;
mem_offset = slot . phys_offset ;
if ( mem_size )
kvm_set_phys_mem ( mem_start , mem_size , mem_offset ) ;
@ -375,11 +395,11 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr,
mem = kvm_alloc_slot ( s ) ;
mem - > memory_size = size ;
mem - > guest_phys _addr = start_addr ;
mem - > userspace_addr = ( unsigned long ) ( phys_ram_base + phys_offset ) ;
mem - > start _addr = start_addr ;
mem - > phys_offset = phys_offset ;
mem - > flags = 0 ;
kvm_vm_ioctl ( s , KVM_SET_USER_MEMORY_REGION , mem ) ;
kvm_set_user_memory_region ( s , mem ) ;
/* FIXME deal with errors */
}