cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, write_phys_req_item
Replace a lot of formulaic multiplications (containing casts, no less) with calls to a pair of functions. This encapsulates in a single place the operations which require care relating to integer overflow. Cc: Dongxiao Xu <dongxiao.xu@intel.com> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
This commit is contained in:
		
				
					committed by
					
						
						Stefano Stabellini
					
				
			
			
				
	
			
			
			
						parent
						
							f1b8caf1d9
						
					
				
				
					commit
					a38648290e
				
			
							
								
								
									
										76
									
								
								xen-all.c
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								xen-all.c
									
									
									
									
									
								
							@@ -683,11 +683,45 @@ static void do_outp(pio_addr_t addr,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Helper functions which read/write an object from/to physical guest
 | 
			
		||||
 * memory, as part of the implementation of an ioreq.
 | 
			
		||||
 *
 | 
			
		||||
 * Equivalent to
 | 
			
		||||
 *   cpu_physical_memory_rw(addr + (req->df ? -1 : +1) * req->size * i,
 | 
			
		||||
 *                          val, req->size, 0/1)
 | 
			
		||||
 * except without the integer overflow problems.
 | 
			
		||||
 */
 | 
			
		||||
static void rw_phys_req_item(hwaddr addr,
 | 
			
		||||
                             ioreq_t *req, uint32_t i, void *val, int rw)
 | 
			
		||||
{
 | 
			
		||||
    /* Do everything unsigned so overflow just results in a truncated result
 | 
			
		||||
     * and accesses to undesired parts of guest memory, which is up
 | 
			
		||||
     * to the guest */
 | 
			
		||||
    hwaddr offset = (hwaddr)req->size * i;
 | 
			
		||||
    if (req->df) {
 | 
			
		||||
        addr -= offset;
 | 
			
		||||
    } else {
 | 
			
		||||
        addr += offset;
 | 
			
		||||
    }
 | 
			
		||||
    cpu_physical_memory_rw(addr, val, req->size, rw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void read_phys_req_item(hwaddr addr,
 | 
			
		||||
                                      ioreq_t *req, uint32_t i, void *val)
 | 
			
		||||
{
 | 
			
		||||
    rw_phys_req_item(addr, req, i, val, 0);
 | 
			
		||||
}
 | 
			
		||||
static inline void write_phys_req_item(hwaddr addr,
 | 
			
		||||
                                       ioreq_t *req, uint32_t i, void *val)
 | 
			
		||||
{
 | 
			
		||||
    rw_phys_req_item(addr, req, i, val, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void cpu_ioreq_pio(ioreq_t *req)
 | 
			
		||||
{
 | 
			
		||||
    int i, sign;
 | 
			
		||||
 | 
			
		||||
    sign = req->df ? -1 : 1;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    if (req->dir == IOREQ_READ) {
 | 
			
		||||
        if (!req->data_is_ptr) {
 | 
			
		||||
@@ -697,9 +731,7 @@ static void cpu_ioreq_pio(ioreq_t *req)
 | 
			
		||||
 | 
			
		||||
            for (i = 0; i < req->count; i++) {
 | 
			
		||||
                tmp = do_inp(req->addr, req->size);
 | 
			
		||||
                cpu_physical_memory_write(
 | 
			
		||||
                        req->data + (sign * i * (int64_t)req->size),
 | 
			
		||||
                        (uint8_t *) &tmp, req->size);
 | 
			
		||||
                write_phys_req_item(req->data, req, i, &tmp);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else if (req->dir == IOREQ_WRITE) {
 | 
			
		||||
@@ -709,9 +741,7 @@ static void cpu_ioreq_pio(ioreq_t *req)
 | 
			
		||||
            for (i = 0; i < req->count; i++) {
 | 
			
		||||
                uint32_t tmp = 0;
 | 
			
		||||
 | 
			
		||||
                cpu_physical_memory_read(
 | 
			
		||||
                        req->data + (sign * i * (int64_t)req->size),
 | 
			
		||||
                        (uint8_t*) &tmp, req->size);
 | 
			
		||||
                read_phys_req_item(req->data, req, i, &tmp);
 | 
			
		||||
                do_outp(req->addr, req->size, tmp);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -720,22 +750,16 @@ static void cpu_ioreq_pio(ioreq_t *req)
 | 
			
		||||
 | 
			
		||||
static void cpu_ioreq_move(ioreq_t *req)
 | 
			
		||||
{
 | 
			
		||||
    int i, sign;
 | 
			
		||||
 | 
			
		||||
    sign = req->df ? -1 : 1;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    if (!req->data_is_ptr) {
 | 
			
		||||
        if (req->dir == IOREQ_READ) {
 | 
			
		||||
            for (i = 0; i < req->count; i++) {
 | 
			
		||||
                cpu_physical_memory_read(
 | 
			
		||||
                        req->addr + (sign * i * (int64_t)req->size),
 | 
			
		||||
                        (uint8_t *) &req->data, req->size);
 | 
			
		||||
                read_phys_req_item(req->addr, req, i, &req->data);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (req->dir == IOREQ_WRITE) {
 | 
			
		||||
            for (i = 0; i < req->count; i++) {
 | 
			
		||||
                cpu_physical_memory_write(
 | 
			
		||||
                        req->addr + (sign * i * (int64_t)req->size),
 | 
			
		||||
                        (uint8_t *) &req->data, req->size);
 | 
			
		||||
                write_phys_req_item(req->addr, req, i, &req->data);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
@@ -743,21 +767,13 @@ static void cpu_ioreq_move(ioreq_t *req)
 | 
			
		||||
 | 
			
		||||
        if (req->dir == IOREQ_READ) {
 | 
			
		||||
            for (i = 0; i < req->count; i++) {
 | 
			
		||||
                cpu_physical_memory_read(
 | 
			
		||||
                        req->addr + (sign * i * (int64_t)req->size),
 | 
			
		||||
                        (uint8_t*) &tmp, req->size);
 | 
			
		||||
                cpu_physical_memory_write(
 | 
			
		||||
                        req->data + (sign * i * (int64_t)req->size),
 | 
			
		||||
                        (uint8_t*) &tmp, req->size);
 | 
			
		||||
                read_phys_req_item(req->addr, req, i, &tmp);
 | 
			
		||||
                write_phys_req_item(req->data, req, i, &tmp);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (req->dir == IOREQ_WRITE) {
 | 
			
		||||
            for (i = 0; i < req->count; i++) {
 | 
			
		||||
                cpu_physical_memory_read(
 | 
			
		||||
                        req->data + (sign * i * (int64_t)req->size),
 | 
			
		||||
                        (uint8_t*) &tmp, req->size);
 | 
			
		||||
                cpu_physical_memory_write(
 | 
			
		||||
                        req->addr + (sign * i * (int64_t)req->size),
 | 
			
		||||
                        (uint8_t*) &tmp, req->size);
 | 
			
		||||
                read_phys_req_item(req->data, req, i, &tmp);
 | 
			
		||||
                write_phys_req_item(req->addr, req, i, &tmp);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user