exec: introduce address_space_extend_translation
This extracts the common part of address_space_map and address_space_cache_init into a new function. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									0ce265ffef
								
							
						
					
					
						commit
						715c31ec8e
					
				
							
								
								
									
										50
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								exec.c
									
									
									
									
									
								
							@ -2938,6 +2938,31 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
 | 
				
			|||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static hwaddr
 | 
				
			||||||
 | 
					address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_len,
 | 
				
			||||||
 | 
					                                 MemoryRegion *mr, hwaddr base, hwaddr len,
 | 
				
			||||||
 | 
					                                 bool is_write)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    hwaddr done = 0;
 | 
				
			||||||
 | 
					    hwaddr xlat;
 | 
				
			||||||
 | 
					    MemoryRegion *this_mr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (;;) {
 | 
				
			||||||
 | 
					        target_len -= len;
 | 
				
			||||||
 | 
					        addr += len;
 | 
				
			||||||
 | 
					        done += len;
 | 
				
			||||||
 | 
					        if (target_len == 0) {
 | 
				
			||||||
 | 
					            return done;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        len = target_len;
 | 
				
			||||||
 | 
					        this_mr = address_space_translate(as, addr, &xlat, &len, is_write);
 | 
				
			||||||
 | 
					        if (this_mr != mr || xlat != base + done) {
 | 
				
			||||||
 | 
					            return done;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Map a physical memory region into a host virtual address.
 | 
					/* Map a physical memory region into a host virtual address.
 | 
				
			||||||
 * May map a subset of the requested range, given by and returned in *plen.
 | 
					 * May map a subset of the requested range, given by and returned in *plen.
 | 
				
			||||||
 * May return NULL if resources needed to perform the mapping are exhausted.
 | 
					 * May return NULL if resources needed to perform the mapping are exhausted.
 | 
				
			||||||
@ -2951,9 +2976,8 @@ void *address_space_map(AddressSpace *as,
 | 
				
			|||||||
                        bool is_write)
 | 
					                        bool is_write)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    hwaddr len = *plen;
 | 
					    hwaddr len = *plen;
 | 
				
			||||||
    hwaddr done = 0;
 | 
					    hwaddr l, xlat;
 | 
				
			||||||
    hwaddr l, xlat, base;
 | 
					    MemoryRegion *mr;
 | 
				
			||||||
    MemoryRegion *mr, *this_mr;
 | 
					 | 
				
			||||||
    void *ptr;
 | 
					    void *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (len == 0) {
 | 
					    if (len == 0) {
 | 
				
			||||||
@ -2987,26 +3011,10 @@ void *address_space_map(AddressSpace *as,
 | 
				
			|||||||
        return bounce.buffer;
 | 
					        return bounce.buffer;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    base = xlat;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (;;) {
 | 
					 | 
				
			||||||
        len -= l;
 | 
					 | 
				
			||||||
        addr += l;
 | 
					 | 
				
			||||||
        done += l;
 | 
					 | 
				
			||||||
        if (len == 0) {
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        l = len;
 | 
					 | 
				
			||||||
        this_mr = address_space_translate(as, addr, &xlat, &l, is_write);
 | 
					 | 
				
			||||||
        if (this_mr != mr || xlat != base + done) {
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memory_region_ref(mr);
 | 
					    memory_region_ref(mr);
 | 
				
			||||||
    *plen = done;
 | 
					    *plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write);
 | 
				
			||||||
    ptr = qemu_ram_ptr_length(mr->ram_block, base, plen);
 | 
					    ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen);
 | 
				
			||||||
    rcu_read_unlock();
 | 
					    rcu_read_unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ptr;
 | 
					    return ptr;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user