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:
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)
|
static void cpu_ioreq_pio(ioreq_t *req)
|
||||||
{
|
{
|
||||||
int i, sign;
|
int i;
|
||||||
|
|
||||||
sign = req->df ? -1 : 1;
|
|
||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user