提交 a3864829 编写于 作者: I Ian Jackson 提交者: Stefano Stabellini

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: NIan Jackson <ian.jackson@eu.citrix.com>
Acked-by: NStefano Stabellini <stefano.stabellini@eu.citrix.com>
上级 f1b8caf1
...@@ -683,11 +683,45 @@ static void do_outp(pio_addr_t addr, ...@@ -683,11 +683,45 @@ static void do_outp(pio_addr_t addr,
} }
} }
static void cpu_ioreq_pio(ioreq_t *req) /*
* 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)
{ {
int i, sign; 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);
}
sign = req->df ? -1 : 1;
static void cpu_ioreq_pio(ioreq_t *req)
{
int i;
if (req->dir == IOREQ_READ) { if (req->dir == IOREQ_READ) {
if (!req->data_is_ptr) { if (!req->data_is_ptr) {
...@@ -697,9 +731,7 @@ static void cpu_ioreq_pio(ioreq_t *req) ...@@ -697,9 +731,7 @@ static void cpu_ioreq_pio(ioreq_t *req)
for (i = 0; i < req->count; i++) { for (i = 0; i < req->count; i++) {
tmp = do_inp(req->addr, req->size); tmp = do_inp(req->addr, req->size);
cpu_physical_memory_write( write_phys_req_item(req->data, req, i, &tmp);
req->data + (sign * i * (int64_t)req->size),
(uint8_t *) &tmp, req->size);
} }
} }
} else if (req->dir == IOREQ_WRITE) { } else if (req->dir == IOREQ_WRITE) {
...@@ -709,9 +741,7 @@ static void cpu_ioreq_pio(ioreq_t *req) ...@@ -709,9 +741,7 @@ static void cpu_ioreq_pio(ioreq_t *req)
for (i = 0; i < req->count; i++) { for (i = 0; i < req->count; i++) {
uint32_t tmp = 0; uint32_t tmp = 0;
cpu_physical_memory_read( read_phys_req_item(req->data, req, i, &tmp);
req->data + (sign * i * (int64_t)req->size),
(uint8_t*) &tmp, req->size);
do_outp(req->addr, req->size, tmp); do_outp(req->addr, req->size, tmp);
} }
} }
...@@ -720,22 +750,16 @@ static void cpu_ioreq_pio(ioreq_t *req) ...@@ -720,22 +750,16 @@ static void cpu_ioreq_pio(ioreq_t *req)
static void cpu_ioreq_move(ioreq_t *req) static void cpu_ioreq_move(ioreq_t *req)
{ {
int i, sign; int i;
sign = req->df ? -1 : 1;
if (!req->data_is_ptr) { if (!req->data_is_ptr) {
if (req->dir == IOREQ_READ) { if (req->dir == IOREQ_READ) {
for (i = 0; i < req->count; i++) { for (i = 0; i < req->count; i++) {
cpu_physical_memory_read( read_phys_req_item(req->addr, req, i, &req->data);
req->addr + (sign * i * (int64_t)req->size),
(uint8_t *) &req->data, req->size);
} }
} else if (req->dir == IOREQ_WRITE) { } else if (req->dir == IOREQ_WRITE) {
for (i = 0; i < req->count; i++) { for (i = 0; i < req->count; i++) {
cpu_physical_memory_write( write_phys_req_item(req->addr, req, i, &req->data);
req->addr + (sign * i * (int64_t)req->size),
(uint8_t *) &req->data, req->size);
} }
} }
} else { } else {
...@@ -743,21 +767,13 @@ static void cpu_ioreq_move(ioreq_t *req) ...@@ -743,21 +767,13 @@ static void cpu_ioreq_move(ioreq_t *req)
if (req->dir == IOREQ_READ) { if (req->dir == IOREQ_READ) {
for (i = 0; i < req->count; i++) { for (i = 0; i < req->count; i++) {
cpu_physical_memory_read( read_phys_req_item(req->addr, req, i, &tmp);
req->addr + (sign * i * (int64_t)req->size), write_phys_req_item(req->data, req, i, &tmp);
(uint8_t*) &tmp, req->size);
cpu_physical_memory_write(
req->data + (sign * i * (int64_t)req->size),
(uint8_t*) &tmp, req->size);
} }
} else if (req->dir == IOREQ_WRITE) { } else if (req->dir == IOREQ_WRITE) {
for (i = 0; i < req->count; i++) { for (i = 0; i < req->count; i++) {
cpu_physical_memory_read( read_phys_req_item(req->data, req, i, &tmp);
req->data + (sign * i * (int64_t)req->size), write_phys_req_item(req->addr, req, i, &tmp);
(uint8_t*) &tmp, req->size);
cpu_physical_memory_write(
req->addr + (sign * i * (int64_t)req->size),
(uint8_t*) &tmp, req->size);
} }
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册