* [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move
@ 2012-09-10 18:04 Stefano Stabellini
2012-09-10 18:06 ` [PATCH 1/2] i should be uint32_t rather than int Stefano Stabellini
` (3 more replies)
0 siblings, 4 replies; 22+ messages in thread
From: Stefano Stabellini @ 2012-09-10 18:04 UTC (permalink / raw)
To: xen-devel; +Cc: dongxiao.xu, Ian Jackson, qemu-devel, Stefano Stabellini
Hi all,
after reviewing the patch "fix multiply issue for int and uint types"
with Ian Jackson, we realized that cpu_ioreq_pio and cpu_ioreq_move are
in much need for a simplification as well as removal of a possible
integer overflow.
This patch series tries to accomplish both switching to two new helper
functions and using a more obvious arithmetic. Doing so it should also
fix the original problem that Dongxiao was experiencing. The C language
can be a nasty backstabber when signed and unsigned integers are
involved.
The current patch series if for qemu-xen-traditional but if the patches
are deemed correct I'll submit an equivalent set for QEMU upstream (with
the appropriate code style changes).
Stefano Stabellini (2):
i should be uint32_t rather than int
introduce read_physical_offset and write_physical_offset
i386-dm/helper2.c | 66 +++++++++++++++++++++++++++++++++-------------------
1 files changed, 42 insertions(+), 24 deletions(-)
Cheers,
Stefano
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH 1/2] i should be uint32_t rather than int 2012-09-10 18:04 [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini @ 2012-09-10 18:06 ` Stefano Stabellini 2012-09-10 18:06 ` [PATCH 2/2] introduce read_physical_offset and write_physical_offset Stefano Stabellini ` (2 subsequent siblings) 3 siblings, 0 replies; 22+ messages in thread From: Stefano Stabellini @ 2012-09-10 18:06 UTC (permalink / raw) To: xen-devel; +Cc: dongxiao.xu, Ian.Jackson, qemu-devel, Stefano Stabellini The current code compare i (int) with req->count (uint32_t) in a for loop, risking an infinite loop if req->count is equal to UINT_MAX. Also i is only used in comparisons or multiplications with unsigned integers. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- i386-dm/helper2.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c index c6d049c..8f2a893 100644 --- a/i386-dm/helper2.c +++ b/i386-dm/helper2.c @@ -351,7 +351,8 @@ static inline void write_physical(uint64_t addr, unsigned long size, void *val) static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) { - int i, sign; + uint32_t i; + int sign; sign = req->df ? -1 : 1; @@ -386,7 +387,8 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) static void cpu_ioreq_move(CPUState *env, ioreq_t *req) { - int i, sign; + uint32_t i; + int sign; sign = req->df ? -1 : 1; -- 1.7.2.5 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/2] introduce read_physical_offset and write_physical_offset 2012-09-10 18:04 [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini 2012-09-10 18:06 ` [PATCH 1/2] i should be uint32_t rather than int Stefano Stabellini @ 2012-09-10 18:06 ` Stefano Stabellini 2012-09-17 23:18 ` [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Xu, Dongxiao 2012-12-07 16:14 ` [Xen-devel] " Ian Jackson 3 siblings, 0 replies; 22+ messages in thread From: Stefano Stabellini @ 2012-09-10 18:06 UTC (permalink / raw) To: xen-devel; +Cc: dongxiao.xu, Ian.Jackson, qemu-devel, Stefano Stabellini Remove read_physical and write_physical. Introduce two new helper functions, read_physical_offset and write_physical_offset, that take care of adding or subtracting offset depending on sign. This way we avoid the automatic casting of sign to uint32_t that is clearly not a very good idea and can easily cause overflows. It also makes the code easier to understand. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- i386-dm/helper2.c | 60 +++++++++++++++++++++++++++++++++------------------- 1 files changed, 38 insertions(+), 22 deletions(-) diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c index 8f2a893..5eb1901 100644 --- a/i386-dm/helper2.c +++ b/i386-dm/helper2.c @@ -339,14 +339,30 @@ static void do_outp(CPUState *env, unsigned long addr, } } -static inline void read_physical(uint64_t addr, unsigned long size, void *val) +static inline void read_physical_offset(target_phys_addr_t addr, + unsigned long offset, + int sign, + unsigned long size, + void *val) { - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0); + if (sign >= 0) + addr += offset; + else + addr -= offset; + return cpu_physical_memory_rw(addr, val, size, 0); } -static inline void write_physical(uint64_t addr, unsigned long size, void *val) +static inline void write_physical_offset(target_phys_addr_t addr, + unsigned long offset, + int sign, + unsigned long size, + void *val) { - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1); + if (sign >= 0) + addr += offset; + else + addr -= offset; + return cpu_physical_memory_rw(addr, val, size, 1); } static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) @@ -364,9 +380,9 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) for (i = 0; i < req->count; i++) { tmp = do_inp(env, req->addr, req->size); - write_physical((target_phys_addr_t) req->data - + (sign * i * req->size), - req->size, &tmp); + write_physical_offset((target_phys_addr_t) req->data, + i * req->size, sign, + req->size, &tmp); } } } else if (req->dir == IOREQ_WRITE) { @@ -376,9 +392,9 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) for (i = 0; i < req->count; i++) { unsigned long tmp = 0; - read_physical((target_phys_addr_t) req->data - + (sign * i * req->size), - req->size, &tmp); + read_physical_offset((target_phys_addr_t) req->data, + i * req->size, sign, + req->size, &tmp); do_outp(env, req->addr, req->size, tmp); } } @@ -395,14 +411,14 @@ static void cpu_ioreq_move(CPUState *env, ioreq_t *req) if (!req->data_is_ptr) { if (req->dir == IOREQ_READ) { for (i = 0; i < req->count; i++) { - read_physical(req->addr - + (sign * i * req->size), + read_physical_offset(req->addr, + i * req->size, sign, req->size, &req->data); } } else if (req->dir == IOREQ_WRITE) { for (i = 0; i < req->count; i++) { - write_physical(req->addr - + (sign * i * req->size), + write_physical_offset(req->addr, + i * req->size, sign, req->size, &req->data); } } @@ -411,20 +427,20 @@ static void cpu_ioreq_move(CPUState *env, ioreq_t *req) if (req->dir == IOREQ_READ) { for (i = 0; i < req->count; i++) { - read_physical(req->addr - + (sign * i * req->size), + read_physical_offset(req->addr, + i * req->size, sign, req->size, &tmp); - write_physical((target_phys_addr_t )req->data - + (sign * i * req->size), + write_physical_offset((target_phys_addr_t )req->data, + i * req->size, sign, req->size, &tmp); } } else if (req->dir == IOREQ_WRITE) { for (i = 0; i < req->count; i++) { - read_physical((target_phys_addr_t) req->data - + (sign * i * req->size), + read_physical_offset((target_phys_addr_t) req->data, + i * req->size, sign, req->size, &tmp); - write_physical(req->addr - + (sign * i * req->size), + write_physical_offset(req->addr, + i * req->size, sign, req->size, &tmp); } } -- 1.7.2.5 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-09-10 18:04 [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini 2012-09-10 18:06 ` [PATCH 1/2] i should be uint32_t rather than int Stefano Stabellini 2012-09-10 18:06 ` [PATCH 2/2] introduce read_physical_offset and write_physical_offset Stefano Stabellini @ 2012-09-17 23:18 ` Xu, Dongxiao 2012-09-18 10:24 ` Stefano Stabellini 2012-12-07 16:14 ` [Xen-devel] " Ian Jackson 3 siblings, 1 reply; 22+ messages in thread From: Xu, Dongxiao @ 2012-09-17 23:18 UTC (permalink / raw) To: Stefano Stabellini, xen-devel@lists.xensource.com Cc: Keir Fraser <keir@xen.org> (keir@xen.org), Ian Jackson, qemu-devel@nongnu.org Hi Stefano, Is these patches merged with Xen 4.2? I didn't see them in the upstream. The uint/int fix is critical to fix the nested guest boot issue. Thanks, Dongxiao > -----Original Message----- > From: Stefano Stabellini [mailto:stefano.stabellini@eu.citrix.com] > Sent: Tuesday, September 11, 2012 2:05 AM > To: xen-devel@lists.xensource.com > Cc: Xu, Dongxiao; Ian Jackson; qemu-devel@nongnu.org; Stefano Stabellini > Subject: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move > > Hi all, > after reviewing the patch "fix multiply issue for int and uint types" > with Ian Jackson, we realized that cpu_ioreq_pio and cpu_ioreq_move are in > much need for a simplification as well as removal of a possible integer overflow. > > This patch series tries to accomplish both switching to two new helper > functions and using a more obvious arithmetic. Doing so it should also fix the > original problem that Dongxiao was experiencing. The C language can be a > nasty backstabber when signed and unsigned integers are involved. > > The current patch series if for qemu-xen-traditional but if the patches are > deemed correct I'll submit an equivalent set for QEMU upstream (with the > appropriate code style changes). > > > > Stefano Stabellini (2): > i should be uint32_t rather than int > introduce read_physical_offset and write_physical_offset > > i386-dm/helper2.c | 66 > +++++++++++++++++++++++++++++++++------------------- > 1 files changed, 42 insertions(+), 24 deletions(-) > > > > Cheers, > > Stefano ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-09-17 23:18 ` [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Xu, Dongxiao @ 2012-09-18 10:24 ` Stefano Stabellini 2012-11-29 3:22 ` Xu, Dongxiao 0 siblings, 1 reply; 22+ messages in thread From: Stefano Stabellini @ 2012-09-18 10:24 UTC (permalink / raw) To: Xu, Dongxiao Cc: Keir (Xen.org), xen-devel@lists.xensource.com, Ian Jackson, qemu-devel@nongnu.org, Stefano Stabellini On Tue, 18 Sep 2012, Xu, Dongxiao wrote: > Hi Stefano, > > Is these patches merged with Xen 4.2? I didn't see them in the upstream. > The uint/int fix is critical to fix the nested guest boot issue. They are not. Ian decided that he wanted to merge a different version of them. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-09-18 10:24 ` Stefano Stabellini @ 2012-11-29 3:22 ` Xu, Dongxiao 2012-11-29 13:21 ` Stefano Stabellini 0 siblings, 1 reply; 22+ messages in thread From: Xu, Dongxiao @ 2012-11-29 3:22 UTC (permalink / raw) To: Stefano Stabellini Cc: Keir (Xen.org), xen-devel@lists.xensource.com, Ian Jackson, qemu-devel@nongnu.org > -----Original Message----- > From: Stefano Stabellini [mailto:stefano.stabellini@eu.citrix.com] > Sent: Tuesday, September 18, 2012 6:24 PM > To: Xu, Dongxiao > Cc: Stefano Stabellini; xen-devel@lists.xensource.com; Ian Jackson; > qemu-devel@nongnu.org; Keir (Xen.org) > Subject: RE: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > cpu_ioreq_move > > On Tue, 18 Sep 2012, Xu, Dongxiao wrote: > > Hi Stefano, > > > > Is these patches merged with Xen 4.2? I didn't see them in the upstream. > > The uint/int fix is critical to fix the nested guest boot issue. > > They are not. Ian decided that he wanted to merge a different version of them. Hi Stefano and Ian, What's the status of the two patches? I still didn't see them merged... Also I think 4.2.1 need these patches to enable the basic Xen on Xen nested virtualization usage scenario. Thanks, Dongxiao ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-11-29 3:22 ` Xu, Dongxiao @ 2012-11-29 13:21 ` Stefano Stabellini 2012-11-29 13:57 ` [Xen-devel] " Ian Campbell 0 siblings, 1 reply; 22+ messages in thread From: Stefano Stabellini @ 2012-11-29 13:21 UTC (permalink / raw) To: Xu, Dongxiao Cc: Keir (Xen.org), xen-devel@lists.xensource.com, Ian Jackson, qemu-devel@nongnu.org, Stefano Stabellini On Thu, 29 Nov 2012, Xu, Dongxiao wrote: > > -----Original Message----- > > From: Stefano Stabellini [mailto:stefano.stabellini@eu.citrix.com] > > Sent: Tuesday, September 18, 2012 6:24 PM > > To: Xu, Dongxiao > > Cc: Stefano Stabellini; xen-devel@lists.xensource.com; Ian Jackson; > > qemu-devel@nongnu.org; Keir (Xen.org) > > Subject: RE: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > > cpu_ioreq_move > > > > On Tue, 18 Sep 2012, Xu, Dongxiao wrote: > > > Hi Stefano, > > > > > > Is these patches merged with Xen 4.2? I didn't see them in the upstream. > > > The uint/int fix is critical to fix the nested guest boot issue. > > > > They are not. Ian decided that he wanted to merge a different version of them. > > Hi Stefano and Ian, > > What's the status of the two patches? I still didn't see them merged... Ian, do you have any updates? > Also I think 4.2.1 need these patches to enable the basic Xen on Xen nested virtualization usage scenario. I agree. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-11-29 13:21 ` Stefano Stabellini @ 2012-11-29 13:57 ` Ian Campbell 2012-11-29 15:10 ` Pasi Kärkkäinen 0 siblings, 1 reply; 22+ messages in thread From: Ian Campbell @ 2012-11-29 13:57 UTC (permalink / raw) To: Stefano Stabellini Cc: Ian Jackson, Xu, Dongxiao, xen-devel@lists.xensource.com, Keir (Xen.org), qemu-devel@nongnu.org On Thu, 2012-11-29 at 13:21 +0000, Stefano Stabellini wrote: > > Also I think 4.2.1 need these patches to enable the basic Xen on Xen > > nested virtualization usage scenario. > > I agree. Nested virt was a tech preview in 4.2.0, is it really worth backporting ? Ian. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-11-29 13:57 ` [Xen-devel] " Ian Campbell @ 2012-11-29 15:10 ` Pasi Kärkkäinen 0 siblings, 0 replies; 22+ messages in thread From: Pasi Kärkkäinen @ 2012-11-29 15:10 UTC (permalink / raw) To: Ian Campbell Cc: xen-devel@lists.xensource.com, Keir (Xen.org), Stefano Stabellini, Ian Jackson, qemu-devel@nongnu.org, Xu, Dongxiao On Thu, Nov 29, 2012 at 01:57:11PM +0000, Ian Campbell wrote: > On Thu, 2012-11-29 at 13:21 +0000, Stefano Stabellini wrote: > > > Also I think 4.2.1 need these patches to enable the basic Xen on Xen > > > nested virtualization usage scenario. > > > > I agree. > > Nested virt was a tech preview in 4.2.0, is it really worth > backporting ? > IIRC AMD Nested Virt works on 4.2.0, so if this backport makes Intel Nested Virt working aswell it'd be nice.. -- Pasi ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-09-10 18:04 [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini ` (2 preceding siblings ...) 2012-09-17 23:18 ` [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Xu, Dongxiao @ 2012-12-07 16:14 ` Ian Jackson 2012-12-07 16:30 ` Ian Campbell 2012-12-10 16:08 ` [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini 3 siblings, 2 replies; 22+ messages in thread From: Ian Jackson @ 2012-12-07 16:14 UTC (permalink / raw) To: Stefano Stabellini; +Cc: dongxiao.xu, xen-devel, qemu-devel Stefano Stabellini writes ("[Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move"): > after reviewing the patch "fix multiply issue for int and uint types" > with Ian Jackson, we realized that cpu_ioreq_pio and cpu_ioreq_move are > in much need for a simplification as well as removal of a possible > integer overflow. > > This patch series tries to accomplish both switching to two new helper > functions and using a more obvious arithmetic. Doing so it should also > fix the original problem that Dongxiao was experiencing. The C language > can be a nasty backstabber when signed and unsigned integers are > involved. I think the attached patch is better as it removes some formulaic code. I don't think I have a guest which can repro the bug so I have only compile tested it. Dongxiao, would you care to take a look ? PS: I'm pretty sure the original overflows aren't security problems. Thanks, Ian. commit d19731e4e452e3415a5c03771d0406efc803baa9 Author: Ian Jackson <ian.jackson@eu.citrix.com> Date: Fri Dec 7 16:02:04 2012 +0000 cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, write_phys_req_item The current code compare i (int) with req->count (uint32_t) in a for loop, risking an infinite loop if req->count is >INT_MAX. It also does the multiplication of req->size in a too-small type, leading to integer overflows. Turn read_physical and write_physical into two different helper functions, read_phys_req_item and write_phys_req_item, that take care of adding or subtracting offset depending on sign. This removes the formulaic multiplication to a single place where the integer overflows can be dealt with by casting to wide-enough unsigned types. Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c index c6d049c..9b8552c 100644 --- a/i386-dm/helper2.c +++ b/i386-dm/helper2.c @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned long addr, } } -static inline void read_physical(uint64_t addr, unsigned long size, void *val) +/* + * 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(target_phys_addr_t addr, + ioreq_t *req, uint32_t i, void *val, int rw) { - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0); + /* 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 */ + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; + if (req->df) addr -= offset; + else addr -= offset; + cpu_physical_memory_rw(addr, val, req->size, rw); } - -static inline void write_physical(uint64_t addr, unsigned long size, void *val) +static inline void read_phys_req_item(target_phys_addr_t addr, + ioreq_t *req, uint32_t i, void *val) { - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1); + rw_phys_req_item(addr, req, i, val, 0); +} +static inline void write_phys_req_item(target_phys_addr_t addr, + ioreq_t *req, uint32_t i, void *val) +{ + rw_phys_req_item(addr, req, i, val, 1); } static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) { - int i, sign; - - sign = req->df ? -1 : 1; + uint32_t i; if (req->dir == IOREQ_READ) { if (!req->data_is_ptr) { @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) for (i = 0; i < req->count; i++) { tmp = do_inp(env, req->addr, req->size); - write_physical((target_phys_addr_t) req->data - + (sign * i * req->size), - req->size, &tmp); + write_phys_req_item((target_phys_addr_t) req->data, req, i, &tmp); } } } else if (req->dir == IOREQ_WRITE) { @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) for (i = 0; i < req->count; i++) { unsigned long tmp = 0; - read_physical((target_phys_addr_t) req->data - + (sign * i * req->size), - req->size, &tmp); + read_phys_req_item(req->data, req, i, &tmp); do_outp(env, req->addr, req->size, tmp); } } @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) static void cpu_ioreq_move(CPUState *env, ioreq_t *req) { - int i, sign; - - sign = req->df ? -1 : 1; + uint32_t i; if (!req->data_is_ptr) { if (req->dir == IOREQ_READ) { for (i = 0; i < req->count; i++) { - read_physical(req->addr - + (sign * i * req->size), - req->size, &req->data); + read_phys_req_item(req->addr, req, i, &req->data); } } else if (req->dir == IOREQ_WRITE) { for (i = 0; i < req->count; i++) { - write_physical(req->addr - + (sign * i * req->size), - req->size, &req->data); + write_phys_req_item(req->addr, req, i, &req->data); } } } else { @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, ioreq_t *req) if (req->dir == IOREQ_READ) { for (i = 0; i < req->count; i++) { - read_physical(req->addr - + (sign * i * req->size), - req->size, &tmp); - write_physical((target_phys_addr_t )req->data - + (sign * i * req->size), - req->size, &tmp); + 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++) { - read_physical((target_phys_addr_t) req->data - + (sign * i * req->size), - req->size, &tmp); - write_physical(req->addr - + (sign * i * req->size), - req->size, &tmp); + read_phys_req_item(req->data, req, i, &tmp); + write_phys_req_item(req->addr, req, i, &tmp); } } } ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-12-07 16:14 ` [Xen-devel] " Ian Jackson @ 2012-12-07 16:30 ` Ian Campbell 2012-12-07 16:33 ` [Xen-devel] " Ian Jackson 2012-12-10 16:08 ` [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini 1 sibling, 1 reply; 22+ messages in thread From: Ian Campbell @ 2012-12-07 16:30 UTC (permalink / raw) To: Ian Jackson Cc: dongxiao.xu@intel.com, xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini On Fri, 2012-12-07 at 16:14 +0000, Ian Jackson wrote: > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > + if (req->df) addr -= offset; > + else addr -= offset; One of these -= should be a += I presume? [...] > + write_phys_req_item((target_phys_addr_t) req->data, req, i, &tmp); This seems to be the only one with this cast, why? write_phys_req_item takes a target_phys_addr_t so this will happen regardless I think. Ian. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-12-07 16:30 ` Ian Campbell @ 2012-12-07 16:33 ` Ian Jackson 2012-12-11 5:50 ` Xu, Dongxiao 2013-01-08 1:49 ` Xu, Dongxiao 0 siblings, 2 replies; 22+ messages in thread From: Ian Jackson @ 2012-12-07 16:33 UTC (permalink / raw) To: Ian Campbell Cc: dongxiao.xu@intel.com, xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini Ian Campbell writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move"): > On Fri, 2012-12-07 at 16:14 +0000, Ian Jackson wrote: > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > + if (req->df) addr -= offset; > > + else addr -= offset; > > One of these -= should be a += I presume? Uh, yes. > [...] > > + write_phys_req_item((target_phys_addr_t) req->data, req, i, &tmp); > > This seems to be the only one with this cast, why? This is a mistake. > write_phys_req_item takes a target_phys_addr_t so this will happen > regardless I think. Indeed. Ian. commit fd3865f8e0d867a203b4ddcb22eefa827cfaca0a Author: Ian Jackson <ian.jackson@eu.citrix.com> Date: Fri Dec 7 16:02:04 2012 +0000 cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, write_phys_req_item The current code compare i (int) with req->count (uint32_t) in a for loop, risking an infinite loop if req->count is >INT_MAX. It also does the multiplication of req->size in a too-small type, leading to integer overflows. Turn read_physical and write_physical into two different helper functions, read_phys_req_item and write_phys_req_item, that take care of adding or subtracting offset depending on sign. This removes the formulaic multiplication to a single place where the integer overflows can be dealt with by casting to wide-enough unsigned types. Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> -- v2: Fix sign when !!req->df. Remove a useless cast. diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c index c6d049c..63a938b 100644 --- a/i386-dm/helper2.c +++ b/i386-dm/helper2.c @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned long addr, } } -static inline void read_physical(uint64_t addr, unsigned long size, void *val) +/* + * 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(target_phys_addr_t addr, + ioreq_t *req, uint32_t i, void *val, int rw) { - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0); + /* 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 */ + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; + if (req->df) addr -= offset; + else addr += offset; + cpu_physical_memory_rw(addr, val, req->size, rw); } - -static inline void write_physical(uint64_t addr, unsigned long size, void *val) +static inline void read_phys_req_item(target_phys_addr_t addr, + ioreq_t *req, uint32_t i, void *val) { - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1); + rw_phys_req_item(addr, req, i, val, 0); +} +static inline void write_phys_req_item(target_phys_addr_t addr, + ioreq_t *req, uint32_t i, void *val) +{ + rw_phys_req_item(addr, req, i, val, 1); } static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) { - int i, sign; - - sign = req->df ? -1 : 1; + uint32_t i; if (req->dir == IOREQ_READ) { if (!req->data_is_ptr) { @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) for (i = 0; i < req->count; i++) { tmp = do_inp(env, req->addr, req->size); - write_physical((target_phys_addr_t) req->data - + (sign * i * req->size), - req->size, &tmp); + write_phys_req_item(req->data, req, i, &tmp); } } } else if (req->dir == IOREQ_WRITE) { @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) for (i = 0; i < req->count; i++) { unsigned long tmp = 0; - read_physical((target_phys_addr_t) req->data - + (sign * i * req->size), - req->size, &tmp); + read_phys_req_item(req->data, req, i, &tmp); do_outp(env, req->addr, req->size, tmp); } } @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) static void cpu_ioreq_move(CPUState *env, ioreq_t *req) { - int i, sign; - - sign = req->df ? -1 : 1; + uint32_t i; if (!req->data_is_ptr) { if (req->dir == IOREQ_READ) { for (i = 0; i < req->count; i++) { - read_physical(req->addr - + (sign * i * req->size), - req->size, &req->data); + read_phys_req_item(req->addr, req, i, &req->data); } } else if (req->dir == IOREQ_WRITE) { for (i = 0; i < req->count; i++) { - write_physical(req->addr - + (sign * i * req->size), - req->size, &req->data); + write_phys_req_item(req->addr, req, i, &req->data); } } } else { @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, ioreq_t *req) if (req->dir == IOREQ_READ) { for (i = 0; i < req->count; i++) { - read_physical(req->addr - + (sign * i * req->size), - req->size, &tmp); - write_physical((target_phys_addr_t )req->data - + (sign * i * req->size), - req->size, &tmp); + 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++) { - read_physical((target_phys_addr_t) req->data - + (sign * i * req->size), - req->size, &tmp); - write_physical(req->addr - + (sign * i * req->size), - req->size, &tmp); + read_phys_req_item(req->data, req, i, &tmp); + write_phys_req_item(req->addr, req, i, &tmp); } } } ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-12-07 16:33 ` [Xen-devel] " Ian Jackson @ 2012-12-11 5:50 ` Xu, Dongxiao 2013-01-08 1:49 ` Xu, Dongxiao 1 sibling, 0 replies; 22+ messages in thread From: Xu, Dongxiao @ 2012-12-11 5:50 UTC (permalink / raw) To: Ian Jackson, Ian Campbell Cc: xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini > -----Original Message----- > From: Ian Jackson [mailto:Ian.Jackson@eu.citrix.com] > Sent: Saturday, December 08, 2012 12:34 AM > To: Ian Campbell > Cc: Stefano Stabellini; Xu, Dongxiao; xen-devel@lists.xensource.com; > qemu-devel@nongnu.org > Subject: Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > cpu_ioreq_move > > Ian Campbell writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify > cpu_ioreq_pio and cpu_ioreq_move"): > > On Fri, 2012-12-07 at 16:14 +0000, Ian Jackson wrote: > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > + if (req->df) addr -= offset; > > > + else addr -= offset; > > > > One of these -= should be a += I presume? > > Uh, yes. > > > [...] > > > + write_phys_req_item((target_phys_addr_t) req->data, > req, i, &tmp); > > > > This seems to be the only one with this cast, why? > > This is a mistake. > > > write_phys_req_item takes a target_phys_addr_t so this will happen > > regardless I think. > > Indeed. > > Ian. Tested this v2 patch on my system, and it works. Thanks, Dongxiao > > commit fd3865f8e0d867a203b4ddcb22eefa827cfaca0a > Author: Ian Jackson <ian.jackson@eu.citrix.com> > Date: Fri Dec 7 16:02:04 2012 +0000 > > cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, > write_phys_req_item > > The current code compare i (int) with req->count (uint32_t) in a for > loop, risking an infinite loop if req->count is >INT_MAX. It also > does the multiplication of req->size in a too-small type, leading to > integer overflows. > > Turn read_physical and write_physical into two different helper > functions, read_phys_req_item and write_phys_req_item, that take care > of adding or subtracting offset depending on sign. > > This removes the formulaic multiplication to a single place where the > integer overflows can be dealt with by casting to wide-enough unsigned > types. > > Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> > > -- > v2: Fix sign when !!req->df. Remove a useless cast. > > diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c > index c6d049c..63a938b 100644 > --- a/i386-dm/helper2.c > +++ b/i386-dm/helper2.c > @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned long > addr, > } > } > > -static inline void read_physical(uint64_t addr, unsigned long size, void *val) > +/* > + * 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(target_phys_addr_t addr, > + ioreq_t *req, uint32_t i, void *val, int rw) > { > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0); > + /* 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 */ > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > + if (req->df) addr -= offset; > + else addr += offset; > + cpu_physical_memory_rw(addr, val, req->size, rw); > } > - > -static inline void write_physical(uint64_t addr, unsigned long size, void *val) > +static inline void read_phys_req_item(target_phys_addr_t addr, > + ioreq_t *req, uint32_t i, void > *val) > { > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1); > + rw_phys_req_item(addr, req, i, val, 0); > +} > +static inline void write_phys_req_item(target_phys_addr_t addr, > + ioreq_t *req, uint32_t i, void > *val) > +{ > + rw_phys_req_item(addr, req, i, val, 1); > } > > static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > { > - int i, sign; > - > - sign = req->df ? -1 : 1; > + uint32_t i; > > if (req->dir == IOREQ_READ) { > if (!req->data_is_ptr) { > @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > > for (i = 0; i < req->count; i++) { > tmp = do_inp(env, req->addr, req->size); > - write_physical((target_phys_addr_t) req->data > - + (sign * i * req->size), > - req->size, &tmp); > + write_phys_req_item(req->data, req, i, &tmp); > } > } > } else if (req->dir == IOREQ_WRITE) { > @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > for (i = 0; i < req->count; i++) { > unsigned long tmp = 0; > > - read_physical((target_phys_addr_t) req->data > - + (sign * i * req->size), > - req->size, &tmp); > + read_phys_req_item(req->data, req, i, &tmp); > do_outp(env, req->addr, req->size, tmp); > } > } > @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > *req) > > static void cpu_ioreq_move(CPUState *env, ioreq_t *req) > { > - int i, sign; > - > - sign = req->df ? -1 : 1; > + uint32_t i; > > if (!req->data_is_ptr) { > if (req->dir == IOREQ_READ) { > for (i = 0; i < req->count; i++) { > - read_physical(req->addr > - + (sign * i * req->size), > - req->size, &req->data); > + read_phys_req_item(req->addr, req, i, &req->data); > } > } else if (req->dir == IOREQ_WRITE) { > for (i = 0; i < req->count; i++) { > - write_physical(req->addr > - + (sign * i * req->size), > - req->size, &req->data); > + write_phys_req_item(req->addr, req, i, &req->data); > } > } > } else { > @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, ioreq_t > *req) > > if (req->dir == IOREQ_READ) { > for (i = 0; i < req->count; i++) { > - read_physical(req->addr > - + (sign * i * req->size), > - req->size, &tmp); > - write_physical((target_phys_addr_t )req->data > - + (sign * i * req->size), > - req->size, &tmp); > + 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++) { > - read_physical((target_phys_addr_t) req->data > - + (sign * i * req->size), > - req->size, &tmp); > - write_physical(req->addr > - + (sign * i * req->size), > - req->size, &tmp); > + read_phys_req_item(req->data, req, i, &tmp); > + write_phys_req_item(req->addr, req, i, &tmp); > } > } > } ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-12-07 16:33 ` [Xen-devel] " Ian Jackson 2012-12-11 5:50 ` Xu, Dongxiao @ 2013-01-08 1:49 ` Xu, Dongxiao 2013-01-09 7:09 ` Pasi Kärkkäinen 1 sibling, 1 reply; 22+ messages in thread From: Xu, Dongxiao @ 2013-01-08 1:49 UTC (permalink / raw) To: Ian Jackson, Ian Campbell Cc: xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini > -----Original Message----- > From: Xu, Dongxiao > Sent: Tuesday, December 11, 2012 1:50 PM > To: Ian Jackson; Ian Campbell > Cc: Stefano Stabellini; xen-devel@lists.xensource.com; > qemu-devel@nongnu.org > Subject: RE: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > cpu_ioreq_move > > > -----Original Message----- > > From: Ian Jackson [mailto:Ian.Jackson@eu.citrix.com] > > Sent: Saturday, December 08, 2012 12:34 AM > > To: Ian Campbell > > Cc: Stefano Stabellini; Xu, Dongxiao; xen-devel@lists.xensource.com; > > qemu-devel@nongnu.org > > Subject: Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > > cpu_ioreq_move > > > > Ian Campbell writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify > > cpu_ioreq_pio and cpu_ioreq_move"): > > > On Fri, 2012-12-07 at 16:14 +0000, Ian Jackson wrote: > > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > > + if (req->df) addr -= offset; > > > > + else addr -= offset; > > > > > > One of these -= should be a += I presume? > > > > Uh, yes. > > > > > [...] > > > > + write_phys_req_item((target_phys_addr_t) > req->data, > > req, i, &tmp); > > > > > > This seems to be the only one with this cast, why? > > > > This is a mistake. > > > > > write_phys_req_item takes a target_phys_addr_t so this will happen > > > regardless I think. > > > > Indeed. > > > > Ian. > > Tested this v2 patch on my system, and it works. Are we planning to check this patch into qemu-traditional? Since it is a critical patch to boot Xen on Xen. Thanks, Dongxiao > > Thanks, > Dongxiao > > > > > > commit fd3865f8e0d867a203b4ddcb22eefa827cfaca0a > > Author: Ian Jackson <ian.jackson@eu.citrix.com> > > Date: Fri Dec 7 16:02:04 2012 +0000 > > > > cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, > > write_phys_req_item > > > > The current code compare i (int) with req->count (uint32_t) in a for > > loop, risking an infinite loop if req->count is >INT_MAX. It also > > does the multiplication of req->size in a too-small type, leading to > > integer overflows. > > > > Turn read_physical and write_physical into two different helper > > functions, read_phys_req_item and write_phys_req_item, that take > care > > of adding or subtracting offset depending on sign. > > > > This removes the formulaic multiplication to a single place where the > > integer overflows can be dealt with by casting to wide-enough unsigned > > types. > > > > Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > > Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> > > > > -- > > v2: Fix sign when !!req->df. Remove a useless cast. > > > > diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c > > index c6d049c..63a938b 100644 > > --- a/i386-dm/helper2.c > > +++ b/i386-dm/helper2.c > > @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned long > > addr, > > } > > } > > > > -static inline void read_physical(uint64_t addr, unsigned long size, void *val) > > +/* > > + * 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(target_phys_addr_t addr, > > + ioreq_t *req, uint32_t i, void *val, int > rw) > > { > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, > 0); > > + /* 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 */ > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > + if (req->df) addr -= offset; > > + else addr += offset; > > + cpu_physical_memory_rw(addr, val, req->size, rw); > > } > > - > > -static inline void write_physical(uint64_t addr, unsigned long size, void *val) > > +static inline void read_phys_req_item(target_phys_addr_t addr, > > + ioreq_t *req, uint32_t i, void > > *val) > > { > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, > 1); > > + rw_phys_req_item(addr, req, i, val, 0); > > +} > > +static inline void write_phys_req_item(target_phys_addr_t addr, > > + ioreq_t *req, uint32_t i, > void > > *val) > > +{ > > + rw_phys_req_item(addr, req, i, val, 1); > > } > > > > static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > > { > > - int i, sign; > > - > > - sign = req->df ? -1 : 1; > > + uint32_t i; > > > > if (req->dir == IOREQ_READ) { > > if (!req->data_is_ptr) { > > @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > *req) > > > > for (i = 0; i < req->count; i++) { > > tmp = do_inp(env, req->addr, req->size); > > - write_physical((target_phys_addr_t) req->data > > - + (sign * i * req->size), > > - req->size, &tmp); > > + write_phys_req_item(req->data, req, i, &tmp); > > } > > } > > } else if (req->dir == IOREQ_WRITE) { > > @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > *req) > > for (i = 0; i < req->count; i++) { > > unsigned long tmp = 0; > > > > - read_physical((target_phys_addr_t) req->data > > - + (sign * i * req->size), > > - req->size, &tmp); > > + read_phys_req_item(req->data, req, i, &tmp); > > do_outp(env, req->addr, req->size, tmp); > > } > > } > > @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > *req) > > > > static void cpu_ioreq_move(CPUState *env, ioreq_t *req) > > { > > - int i, sign; > > - > > - sign = req->df ? -1 : 1; > > + uint32_t i; > > > > if (!req->data_is_ptr) { > > if (req->dir == IOREQ_READ) { > > for (i = 0; i < req->count; i++) { > > - read_physical(req->addr > > - + (sign * i * req->size), > > - req->size, &req->data); > > + read_phys_req_item(req->addr, req, i, &req->data); > > } > > } else if (req->dir == IOREQ_WRITE) { > > for (i = 0; i < req->count; i++) { > > - write_physical(req->addr > > - + (sign * i * req->size), > > - req->size, &req->data); > > + write_phys_req_item(req->addr, req, i, &req->data); > > } > > } > > } else { > > @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, > ioreq_t > > *req) > > > > if (req->dir == IOREQ_READ) { > > for (i = 0; i < req->count; i++) { > > - read_physical(req->addr > > - + (sign * i * req->size), > > - req->size, &tmp); > > - write_physical((target_phys_addr_t )req->data > > - + (sign * i * req->size), > > - req->size, &tmp); > > + 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++) { > > - read_physical((target_phys_addr_t) req->data > > - + (sign * i * req->size), > > - req->size, &tmp); > > - write_physical(req->addr > > - + (sign * i * req->size), > > - req->size, &tmp); > > + read_phys_req_item(req->data, req, i, &tmp); > > + write_phys_req_item(req->addr, req, i, &tmp); > > } > > } > > } ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2013-01-08 1:49 ` Xu, Dongxiao @ 2013-01-09 7:09 ` Pasi Kärkkäinen 2013-01-24 13:44 ` [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt Pasi Kärkkäinen 0 siblings, 1 reply; 22+ messages in thread From: Pasi Kärkkäinen @ 2013-01-09 7:09 UTC (permalink / raw) To: Xu, Dongxiao Cc: xen-devel@lists.xensource.com, Ian Jackson, Ian Campbell, Stefano Stabellini, qemu-devel@nongnu.org On Tue, Jan 08, 2013 at 01:49:06AM +0000, Xu, Dongxiao wrote: > > > > > -----Original Message----- > > > From: Ian Jackson [mailto:Ian.Jackson@eu.citrix.com] > > > Sent: Saturday, December 08, 2012 12:34 AM > > > To: Ian Campbell > > > Cc: Stefano Stabellini; Xu, Dongxiao; xen-devel@lists.xensource.com; > > > qemu-devel@nongnu.org > > > Subject: Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > > > cpu_ioreq_move > > > > > > Ian Campbell writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify > > > cpu_ioreq_pio and cpu_ioreq_move"): > > > > On Fri, 2012-12-07 at 16:14 +0000, Ian Jackson wrote: > > > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > > > + if (req->df) addr -= offset; > > > > > + else addr -= offset; > > > > > > > > One of these -= should be a += I presume? > > > > > > Uh, yes. > > > > > > > [...] > > > > > + write_phys_req_item((target_phys_addr_t) > > req->data, > > > req, i, &tmp); > > > > > > > > This seems to be the only one with this cast, why? > > > > > > This is a mistake. > > > > > > > write_phys_req_item takes a target_phys_addr_t so this will happen > > > > regardless I think. > > > > > > Indeed. > > > > > > Ian. > > > > Tested this v2 patch on my system, and it works. > > Are we planning to check this patch into qemu-traditional? Since it is a critical patch to boot Xen on Xen. > We should definitely get Xen-on-Xen working.. -- Pasi > Thanks, > Dongxiao > > > > > Thanks, > > Dongxiao > > > > > > > > > > commit fd3865f8e0d867a203b4ddcb22eefa827cfaca0a > > > Author: Ian Jackson <ian.jackson@eu.citrix.com> > > > Date: Fri Dec 7 16:02:04 2012 +0000 > > > > > > cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, > > > write_phys_req_item > > > > > > The current code compare i (int) with req->count (uint32_t) in a for > > > loop, risking an infinite loop if req->count is >INT_MAX. It also > > > does the multiplication of req->size in a too-small type, leading to > > > integer overflows. > > > > > > Turn read_physical and write_physical into two different helper > > > functions, read_phys_req_item and write_phys_req_item, that take > > care > > > of adding or subtracting offset depending on sign. > > > > > > This removes the formulaic multiplication to a single place where the > > > integer overflows can be dealt with by casting to wide-enough unsigned > > > types. > > > > > > Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > > > Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> > > > > > > -- > > > v2: Fix sign when !!req->df. Remove a useless cast. > > > > > > diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c > > > index c6d049c..63a938b 100644 > > > --- a/i386-dm/helper2.c > > > +++ b/i386-dm/helper2.c > > > @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned long > > > addr, > > > } > > > } > > > > > > -static inline void read_physical(uint64_t addr, unsigned long size, void *val) > > > +/* > > > + * 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(target_phys_addr_t addr, > > > + ioreq_t *req, uint32_t i, void *val, int > > rw) > > > { > > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, > > 0); > > > + /* 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 */ > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > + if (req->df) addr -= offset; > > > + else addr += offset; > > > + cpu_physical_memory_rw(addr, val, req->size, rw); > > > } > > > - > > > -static inline void write_physical(uint64_t addr, unsigned long size, void *val) > > > +static inline void read_phys_req_item(target_phys_addr_t addr, > > > + ioreq_t *req, uint32_t i, void > > > *val) > > > { > > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, > > 1); > > > + rw_phys_req_item(addr, req, i, val, 0); > > > +} > > > +static inline void write_phys_req_item(target_phys_addr_t addr, > > > + ioreq_t *req, uint32_t i, > > void > > > *val) > > > +{ > > > + rw_phys_req_item(addr, req, i, val, 1); > > > } > > > > > > static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > > > { > > > - int i, sign; > > > - > > > - sign = req->df ? -1 : 1; > > > + uint32_t i; > > > > > > if (req->dir == IOREQ_READ) { > > > if (!req->data_is_ptr) { > > > @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > *req) > > > > > > for (i = 0; i < req->count; i++) { > > > tmp = do_inp(env, req->addr, req->size); > > > - write_physical((target_phys_addr_t) req->data > > > - + (sign * i * req->size), > > > - req->size, &tmp); > > > + write_phys_req_item(req->data, req, i, &tmp); > > > } > > > } > > > } else if (req->dir == IOREQ_WRITE) { > > > @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > *req) > > > for (i = 0; i < req->count; i++) { > > > unsigned long tmp = 0; > > > > > > - read_physical((target_phys_addr_t) req->data > > > - + (sign * i * req->size), > > > - req->size, &tmp); > > > + read_phys_req_item(req->data, req, i, &tmp); > > > do_outp(env, req->addr, req->size, tmp); > > > } > > > } > > > @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > > *req) > > > > > > static void cpu_ioreq_move(CPUState *env, ioreq_t *req) > > > { > > > - int i, sign; > > > - > > > - sign = req->df ? -1 : 1; > > > + uint32_t i; > > > > > > if (!req->data_is_ptr) { > > > if (req->dir == IOREQ_READ) { > > > for (i = 0; i < req->count; i++) { > > > - read_physical(req->addr > > > - + (sign * i * req->size), > > > - req->size, &req->data); > > > + read_phys_req_item(req->addr, req, i, &req->data); > > > } > > > } else if (req->dir == IOREQ_WRITE) { > > > for (i = 0; i < req->count; i++) { > > > - write_physical(req->addr > > > - + (sign * i * req->size), > > > - req->size, &req->data); > > > + write_phys_req_item(req->addr, req, i, &req->data); > > > } > > > } > > > } else { > > > @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, > > ioreq_t > > > *req) > > > > > > if (req->dir == IOREQ_READ) { > > > for (i = 0; i < req->count; i++) { > > > - read_physical(req->addr > > > - + (sign * i * req->size), > > > - req->size, &tmp); > > > - write_physical((target_phys_addr_t )req->data > > > - + (sign * i * req->size), > > > - req->size, &tmp); > > > + 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++) { > > > - read_physical((target_phys_addr_t) req->data > > > - + (sign * i * req->size), > > > - req->size, &tmp); > > > - write_physical(req->addr > > > - + (sign * i * req->size), > > > - req->size, &tmp); > > > + read_phys_req_item(req->data, req, i, &tmp); > > > + write_phys_req_item(req->addr, req, i, &tmp); > > > } > > > } > > > } > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt 2013-01-09 7:09 ` Pasi Kärkkäinen @ 2013-01-24 13:44 ` Pasi Kärkkäinen 2013-01-31 2:23 ` Xu, Dongxiao 2013-02-19 19:38 ` Pasi Kärkkäinen 0 siblings, 2 replies; 22+ messages in thread From: Pasi Kärkkäinen @ 2013-01-24 13:44 UTC (permalink / raw) To: Ian Jackson Cc: qemu-devel@nongnu.org, Xu, Dongxiao, xen-devel@lists.xensource.com, Ian Campbell, Stefano Stabellini Hello, IanJ: I can't see this patch in qemu-xen-unstable .. Does the the patch still need something to be fixed before it can be applied? Thanks, -- Pasi On Wed, Jan 09, 2013 at 09:09:26AM +0200, Pasi Kärkkäinen wrote: > On Tue, Jan 08, 2013 at 01:49:06AM +0000, Xu, Dongxiao wrote: > > > > > > > -----Original Message----- > > > > From: Ian Jackson [mailto:Ian.Jackson@eu.citrix.com] > > > > Sent: Saturday, December 08, 2012 12:34 AM > > > > To: Ian Campbell > > > > Cc: Stefano Stabellini; Xu, Dongxiao; xen-devel@lists.xensource.com; > > > > qemu-devel@nongnu.org > > > > Subject: Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > > > > cpu_ioreq_move > > > > > > > > Ian Campbell writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify > > > > cpu_ioreq_pio and cpu_ioreq_move"): > > > > > On Fri, 2012-12-07 at 16:14 +0000, Ian Jackson wrote: > > > > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > > > > + if (req->df) addr -= offset; > > > > > > + else addr -= offset; > > > > > > > > > > One of these -= should be a += I presume? > > > > > > > > Uh, yes. > > > > > > > > > [...] > > > > > > + write_phys_req_item((target_phys_addr_t) > > > req->data, > > > > req, i, &tmp); > > > > > > > > > > This seems to be the only one with this cast, why? > > > > > > > > This is a mistake. > > > > > > > > > write_phys_req_item takes a target_phys_addr_t so this will happen > > > > > regardless I think. > > > > > > > > Indeed. > > > > > > > > Ian. > > > > > > Tested this v2 patch on my system, and it works. > > > > Are we planning to check this patch into qemu-traditional? Since it is a critical patch to boot Xen on Xen. > > > > We should definitely get Xen-on-Xen working.. > > > -- Pasi > > > Thanks, > > Dongxiao > > > > > > > > Thanks, > > > Dongxiao > > > > > > > > > > > > > > commit fd3865f8e0d867a203b4ddcb22eefa827cfaca0a > > > > Author: Ian Jackson <ian.jackson@eu.citrix.com> > > > > Date: Fri Dec 7 16:02:04 2012 +0000 > > > > > > > > cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, > > > > write_phys_req_item > > > > > > > > The current code compare i (int) with req->count (uint32_t) in a for > > > > loop, risking an infinite loop if req->count is >INT_MAX. It also > > > > does the multiplication of req->size in a too-small type, leading to > > > > integer overflows. > > > > > > > > Turn read_physical and write_physical into two different helper > > > > functions, read_phys_req_item and write_phys_req_item, that take > > > care > > > > of adding or subtracting offset depending on sign. > > > > > > > > This removes the formulaic multiplication to a single place where the > > > > integer overflows can be dealt with by casting to wide-enough unsigned > > > > types. > > > > > > > > Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> > > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > > > > Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> > > > > > > > > -- > > > > v2: Fix sign when !!req->df. Remove a useless cast. > > > > > > > > diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c > > > > index c6d049c..63a938b 100644 > > > > --- a/i386-dm/helper2.c > > > > +++ b/i386-dm/helper2.c > > > > @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned long > > > > addr, > > > > } > > > > } > > > > > > > > -static inline void read_physical(uint64_t addr, unsigned long size, void *val) > > > > +/* > > > > + * 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(target_phys_addr_t addr, > > > > + ioreq_t *req, uint32_t i, void *val, int > > > rw) > > > > { > > > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, > > > 0); > > > > + /* 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 */ > > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > > + if (req->df) addr -= offset; > > > > + else addr += offset; > > > > + cpu_physical_memory_rw(addr, val, req->size, rw); > > > > } > > > > - > > > > -static inline void write_physical(uint64_t addr, unsigned long size, void *val) > > > > +static inline void read_phys_req_item(target_phys_addr_t addr, > > > > + ioreq_t *req, uint32_t i, void > > > > *val) > > > > { > > > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, > > > 1); > > > > + rw_phys_req_item(addr, req, i, val, 0); > > > > +} > > > > +static inline void write_phys_req_item(target_phys_addr_t addr, > > > > + ioreq_t *req, uint32_t i, > > > void > > > > *val) > > > > +{ > > > > + rw_phys_req_item(addr, req, i, val, 1); > > > > } > > > > > > > > static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > > > > { > > > > - int i, sign; > > > > - > > > > - sign = req->df ? -1 : 1; > > > > + uint32_t i; > > > > > > > > if (req->dir == IOREQ_READ) { > > > > if (!req->data_is_ptr) { > > > > @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > > *req) > > > > > > > > for (i = 0; i < req->count; i++) { > > > > tmp = do_inp(env, req->addr, req->size); > > > > - write_physical((target_phys_addr_t) req->data > > > > - + (sign * i * req->size), > > > > - req->size, &tmp); > > > > + write_phys_req_item(req->data, req, i, &tmp); > > > > } > > > > } > > > > } else if (req->dir == IOREQ_WRITE) { > > > > @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > > *req) > > > > for (i = 0; i < req->count; i++) { > > > > unsigned long tmp = 0; > > > > > > > > - read_physical((target_phys_addr_t) req->data > > > > - + (sign * i * req->size), > > > > - req->size, &tmp); > > > > + read_phys_req_item(req->data, req, i, &tmp); > > > > do_outp(env, req->addr, req->size, tmp); > > > > } > > > > } > > > > @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > > > *req) > > > > > > > > static void cpu_ioreq_move(CPUState *env, ioreq_t *req) > > > > { > > > > - int i, sign; > > > > - > > > > - sign = req->df ? -1 : 1; > > > > + uint32_t i; > > > > > > > > if (!req->data_is_ptr) { > > > > if (req->dir == IOREQ_READ) { > > > > for (i = 0; i < req->count; i++) { > > > > - read_physical(req->addr > > > > - + (sign * i * req->size), > > > > - req->size, &req->data); > > > > + read_phys_req_item(req->addr, req, i, &req->data); > > > > } > > > > } else if (req->dir == IOREQ_WRITE) { > > > > for (i = 0; i < req->count; i++) { > > > > - write_physical(req->addr > > > > - + (sign * i * req->size), > > > > - req->size, &req->data); > > > > + write_phys_req_item(req->addr, req, i, &req->data); > > > > } > > > > } > > > > } else { > > > > @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, > > > ioreq_t > > > > *req) > > > > > > > > if (req->dir == IOREQ_READ) { > > > > for (i = 0; i < req->count; i++) { > > > > - read_physical(req->addr > > > > - + (sign * i * req->size), > > > > - req->size, &tmp); > > > > - write_physical((target_phys_addr_t )req->data > > > > - + (sign * i * req->size), > > > > - req->size, &tmp); > > > > + 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++) { > > > > - read_physical((target_phys_addr_t) req->data > > > > - + (sign * i * req->size), > > > > - req->size, &tmp); > > > > - write_physical(req->addr > > > > - + (sign * i * req->size), > > > > - req->size, &tmp); > > > > + read_phys_req_item(req->data, req, i, &tmp); > > > > + write_phys_req_item(req->addr, req, i, &tmp); > > > > } > > > > } > > > > } > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@lists.xen.org > > http://lists.xen.org/xen-devel > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt 2013-01-24 13:44 ` [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt Pasi Kärkkäinen @ 2013-01-31 2:23 ` Xu, Dongxiao 2013-02-19 19:38 ` Pasi Kärkkäinen 1 sibling, 0 replies; 22+ messages in thread From: Xu, Dongxiao @ 2013-01-31 2:23 UTC (permalink / raw) To: Pasi K?rkk?inen, Ian Jackson Cc: qemu-devel@nongnu.org, xen-devel@lists.xensource.com, Ian Campbell, Stefano Stabellini > -----Original Message----- > From: Pasi Kärkkäinen [mailto:pasik@iki.fi] > Sent: Thursday, January 24, 2013 9:45 PM > To: Ian Jackson > Cc: xen-devel@lists.xensource.com; Ian Campbell; Stefano Stabellini; > qemu-devel@nongnu.org; Xu, Dongxiao > Subject: Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > cpu_ioreq_move / Xen on Xen nested virt > > Hello, > > IanJ: I can't see this patch in qemu-xen-unstable .. > Does the the patch still need something to be fixed before it can be applied? Yes, I am also confused why we still keep this fix out of the qemu-xen tree. :( Our QA needs to apply additional patch to test nested virtualization cases. Thanks, Dongxiao > > Thanks, > > -- Pasi > > On Wed, Jan 09, 2013 at 09:09:26AM +0200, Pasi Kärkkäinen wrote: > > On Tue, Jan 08, 2013 at 01:49:06AM +0000, Xu, Dongxiao wrote: > > > > > > > > > -----Original Message----- > > > > > From: Ian Jackson [mailto:Ian.Jackson@eu.citrix.com] > > > > > Sent: Saturday, December 08, 2012 12:34 AM > > > > > To: Ian Campbell > > > > > Cc: Stefano Stabellini; Xu, Dongxiao; xen-devel@lists.xensource.com; > > > > > qemu-devel@nongnu.org > > > > > Subject: Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio > and > > > > > cpu_ioreq_move > > > > > > > > > > Ian Campbell writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify > > > > > cpu_ioreq_pio and cpu_ioreq_move"): > > > > > > On Fri, 2012-12-07 at 16:14 +0000, Ian Jackson wrote: > > > > > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * > i; > > > > > > > + if (req->df) addr -= offset; > > > > > > > + else addr -= offset; > > > > > > > > > > > > One of these -= should be a += I presume? > > > > > > > > > > Uh, yes. > > > > > > > > > > > [...] > > > > > > > + write_phys_req_item((target_phys_addr_t) > > > > req->data, > > > > > req, i, &tmp); > > > > > > > > > > > > This seems to be the only one with this cast, why? > > > > > > > > > > This is a mistake. > > > > > > > > > > > write_phys_req_item takes a target_phys_addr_t so this will happen > > > > > > regardless I think. > > > > > > > > > > Indeed. > > > > > > > > > > Ian. > > > > > > > > Tested this v2 patch on my system, and it works. > > > > > > Are we planning to check this patch into qemu-traditional? Since it is a > critical patch to boot Xen on Xen. > > > > > > > We should definitely get Xen-on-Xen working.. > > > > > > -- Pasi > > > > > Thanks, > > > Dongxiao > > > > > > > > > > > Thanks, > > > > Dongxiao > > > > > > > > > > > > > > > > > > commit fd3865f8e0d867a203b4ddcb22eefa827cfaca0a > > > > > Author: Ian Jackson <ian.jackson@eu.citrix.com> > > > > > Date: Fri Dec 7 16:02:04 2012 +0000 > > > > > > > > > > cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, > > > > > write_phys_req_item > > > > > > > > > > The current code compare i (int) with req->count (uint32_t) in a for > > > > > loop, risking an infinite loop if req->count is >INT_MAX. It also > > > > > does the multiplication of req->size in a too-small type, leading to > > > > > integer overflows. > > > > > > > > > > Turn read_physical and write_physical into two different helper > > > > > functions, read_phys_req_item and write_phys_req_item, that > take > > > > care > > > > > of adding or subtracting offset depending on sign. > > > > > > > > > > This removes the formulaic multiplication to a single place where > the > > > > > integer overflows can be dealt with by casting to wide-enough > unsigned > > > > > types. > > > > > > > > > > Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> > > > > > Signed-off-by: Stefano Stabellini > <stefano.stabellini@eu.citrix.com> > > > > > Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> > > > > > > > > > > -- > > > > > v2: Fix sign when !!req->df. Remove a useless cast. > > > > > > > > > > diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c > > > > > index c6d049c..63a938b 100644 > > > > > --- a/i386-dm/helper2.c > > > > > +++ b/i386-dm/helper2.c > > > > > @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned > long > > > > > addr, > > > > > } > > > > > } > > > > > > > > > > -static inline void read_physical(uint64_t addr, unsigned long size, void > *val) > > > > > +/* > > > > > + * 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(target_phys_addr_t addr, > > > > > + ioreq_t *req, uint32_t i, void *val, > int > > > > rw) > > > > > { > > > > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, > size, > > > > 0); > > > > > + /* 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 */ > > > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > > > + if (req->df) addr -= offset; > > > > > + else addr += offset; > > > > > + cpu_physical_memory_rw(addr, val, req->size, rw); > > > > > } > > > > > - > > > > > -static inline void write_physical(uint64_t addr, unsigned long size, void > *val) > > > > > +static inline void read_phys_req_item(target_phys_addr_t addr, > > > > > + ioreq_t *req, uint32_t i, > void > > > > > *val) > > > > > { > > > > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, > size, > > > > 1); > > > > > + rw_phys_req_item(addr, req, i, val, 0); > > > > > +} > > > > > +static inline void write_phys_req_item(target_phys_addr_t addr, > > > > > + ioreq_t *req, uint32_t > i, > > > > void > > > > > *val) > > > > > +{ > > > > > + rw_phys_req_item(addr, req, i, val, 1); > > > > > } > > > > > > > > > > static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > > > > > { > > > > > - int i, sign; > > > > > - > > > > > - sign = req->df ? -1 : 1; > > > > > + uint32_t i; > > > > > > > > > > if (req->dir == IOREQ_READ) { > > > > > if (!req->data_is_ptr) { > > > > > @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, > ioreq_t > > > > *req) > > > > > > > > > > for (i = 0; i < req->count; i++) { > > > > > tmp = do_inp(env, req->addr, req->size); > > > > > - write_physical((target_phys_addr_t) req->data > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > + write_phys_req_item(req->data, req, i, &tmp); > > > > > } > > > > > } > > > > > } else if (req->dir == IOREQ_WRITE) { > > > > > @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, > ioreq_t > > > > *req) > > > > > for (i = 0; i < req->count; i++) { > > > > > unsigned long tmp = 0; > > > > > > > > > > - read_physical((target_phys_addr_t) req->data > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > + read_phys_req_item(req->data, req, i, &tmp); > > > > > do_outp(env, req->addr, req->size, tmp); > > > > > } > > > > > } > > > > > @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, > ioreq_t > > > > > *req) > > > > > > > > > > static void cpu_ioreq_move(CPUState *env, ioreq_t *req) > > > > > { > > > > > - int i, sign; > > > > > - > > > > > - sign = req->df ? -1 : 1; > > > > > + uint32_t i; > > > > > > > > > > if (!req->data_is_ptr) { > > > > > if (req->dir == IOREQ_READ) { > > > > > for (i = 0; i < req->count; i++) { > > > > > - read_physical(req->addr > > > > > - + (sign * i * req->size), > > > > > - req->size, &req->data); > > > > > + read_phys_req_item(req->addr, req, i, > &req->data); > > > > > } > > > > > } else if (req->dir == IOREQ_WRITE) { > > > > > for (i = 0; i < req->count; i++) { > > > > > - write_physical(req->addr > > > > > - + (sign * i * req->size), > > > > > - req->size, &req->data); > > > > > + write_phys_req_item(req->addr, req, i, > &req->data); > > > > > } > > > > > } > > > > > } else { > > > > > @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, > > > > ioreq_t > > > > > *req) > > > > > > > > > > if (req->dir == IOREQ_READ) { > > > > > for (i = 0; i < req->count; i++) { > > > > > - read_physical(req->addr > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > - write_physical((target_phys_addr_t )req->data > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > + 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++) { > > > > > - read_physical((target_phys_addr_t) req->data > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > - write_physical(req->addr > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > + read_phys_req_item(req->data, req, i, &tmp); > > > > > + write_phys_req_item(req->addr, req, i, &tmp); > > > > > } > > > > > } > > > > > } > > > > > > _______________________________________________ > > > Xen-devel mailing list > > > Xen-devel@lists.xen.org > > > http://lists.xen.org/xen-devel > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@lists.xen.org > > http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt 2013-01-24 13:44 ` [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt Pasi Kärkkäinen 2013-01-31 2:23 ` Xu, Dongxiao @ 2013-02-19 19:38 ` Pasi Kärkkäinen 2013-02-20 15:42 ` Ian Jackson 1 sibling, 1 reply; 22+ messages in thread From: Pasi Kärkkäinen @ 2013-02-19 19:38 UTC (permalink / raw) To: Ian Jackson Cc: Xu, Dongxiao, xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini, Ian Campbell On Thu, Jan 24, 2013 at 03:44:41PM +0200, Pasi Kärkkäinen wrote: > Hello, > > IanJ: I can't see this patch in qemu-xen-unstable .. > Does the the patch still need something to be fixed before it can be applied? > Ping again? I wonder if I've gotten into some blacklist already for nagging about this.. This is a required patch for making Xen-on-Xen Nested virt working on Intel.. thanks, -- Pasi > > On Wed, Jan 09, 2013 at 09:09:26AM +0200, Pasi Kärkkäinen wrote: > > On Tue, Jan 08, 2013 at 01:49:06AM +0000, Xu, Dongxiao wrote: > > > > > > > > > -----Original Message----- > > > > > From: Ian Jackson [mailto:Ian.Jackson@eu.citrix.com] > > > > > Sent: Saturday, December 08, 2012 12:34 AM > > > > > To: Ian Campbell > > > > > Cc: Stefano Stabellini; Xu, Dongxiao; xen-devel@lists.xensource.com; > > > > > qemu-devel@nongnu.org > > > > > Subject: Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and > > > > > cpu_ioreq_move > > > > > > > > > > Ian Campbell writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify > > > > > cpu_ioreq_pio and cpu_ioreq_move"): > > > > > > On Fri, 2012-12-07 at 16:14 +0000, Ian Jackson wrote: > > > > > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > > > > > + if (req->df) addr -= offset; > > > > > > > + else addr -= offset; > > > > > > > > > > > > One of these -= should be a += I presume? > > > > > > > > > > Uh, yes. > > > > > > > > > > > [...] > > > > > > > + write_phys_req_item((target_phys_addr_t) > > > > req->data, > > > > > req, i, &tmp); > > > > > > > > > > > > This seems to be the only one with this cast, why? > > > > > > > > > > This is a mistake. > > > > > > > > > > > write_phys_req_item takes a target_phys_addr_t so this will happen > > > > > > regardless I think. > > > > > > > > > > Indeed. > > > > > > > > > > Ian. > > > > > > > > Tested this v2 patch on my system, and it works. > > > > > > Are we planning to check this patch into qemu-traditional? Since it is a critical patch to boot Xen on Xen. > > > > > > > We should definitely get Xen-on-Xen working.. > > > > > > -- Pasi > > > > > Thanks, > > > Dongxiao > > > > > > > > > > > Thanks, > > > > Dongxiao > > > > > > > > > > > > > > > > > > commit fd3865f8e0d867a203b4ddcb22eefa827cfaca0a > > > > > Author: Ian Jackson <ian.jackson@eu.citrix.com> > > > > > Date: Fri Dec 7 16:02:04 2012 +0000 > > > > > > > > > > cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, > > > > > write_phys_req_item > > > > > > > > > > The current code compare i (int) with req->count (uint32_t) in a for > > > > > loop, risking an infinite loop if req->count is >INT_MAX. It also > > > > > does the multiplication of req->size in a too-small type, leading to > > > > > integer overflows. > > > > > > > > > > Turn read_physical and write_physical into two different helper > > > > > functions, read_phys_req_item and write_phys_req_item, that take > > > > care > > > > > of adding or subtracting offset depending on sign. > > > > > > > > > > This removes the formulaic multiplication to a single place where the > > > > > integer overflows can be dealt with by casting to wide-enough unsigned > > > > > types. > > > > > > > > > > Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> > > > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > > > > > Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> > > > > > > > > > > -- > > > > > v2: Fix sign when !!req->df. Remove a useless cast. > > > > > > > > > > diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c > > > > > index c6d049c..63a938b 100644 > > > > > --- a/i386-dm/helper2.c > > > > > +++ b/i386-dm/helper2.c > > > > > @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned long > > > > > addr, > > > > > } > > > > > } > > > > > > > > > > -static inline void read_physical(uint64_t addr, unsigned long size, void *val) > > > > > +/* > > > > > + * 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(target_phys_addr_t addr, > > > > > + ioreq_t *req, uint32_t i, void *val, int > > > > rw) > > > > > { > > > > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, > > > > 0); > > > > > + /* 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 */ > > > > > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > > > > > + if (req->df) addr -= offset; > > > > > + else addr += offset; > > > > > + cpu_physical_memory_rw(addr, val, req->size, rw); > > > > > } > > > > > - > > > > > -static inline void write_physical(uint64_t addr, unsigned long size, void *val) > > > > > +static inline void read_phys_req_item(target_phys_addr_t addr, > > > > > + ioreq_t *req, uint32_t i, void > > > > > *val) > > > > > { > > > > > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, > > > > 1); > > > > > + rw_phys_req_item(addr, req, i, val, 0); > > > > > +} > > > > > +static inline void write_phys_req_item(target_phys_addr_t addr, > > > > > + ioreq_t *req, uint32_t i, > > > > void > > > > > *val) > > > > > +{ > > > > > + rw_phys_req_item(addr, req, i, val, 1); > > > > > } > > > > > > > > > > static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > > > > > { > > > > > - int i, sign; > > > > > - > > > > > - sign = req->df ? -1 : 1; > > > > > + uint32_t i; > > > > > > > > > > if (req->dir == IOREQ_READ) { > > > > > if (!req->data_is_ptr) { > > > > > @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > > > *req) > > > > > > > > > > for (i = 0; i < req->count; i++) { > > > > > tmp = do_inp(env, req->addr, req->size); > > > > > - write_physical((target_phys_addr_t) req->data > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > + write_phys_req_item(req->data, req, i, &tmp); > > > > > } > > > > > } > > > > > } else if (req->dir == IOREQ_WRITE) { > > > > > @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > > > *req) > > > > > for (i = 0; i < req->count; i++) { > > > > > unsigned long tmp = 0; > > > > > > > > > > - read_physical((target_phys_addr_t) req->data > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > + read_phys_req_item(req->data, req, i, &tmp); > > > > > do_outp(env, req->addr, req->size, tmp); > > > > > } > > > > > } > > > > > @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t > > > > > *req) > > > > > > > > > > static void cpu_ioreq_move(CPUState *env, ioreq_t *req) > > > > > { > > > > > - int i, sign; > > > > > - > > > > > - sign = req->df ? -1 : 1; > > > > > + uint32_t i; > > > > > > > > > > if (!req->data_is_ptr) { > > > > > if (req->dir == IOREQ_READ) { > > > > > for (i = 0; i < req->count; i++) { > > > > > - read_physical(req->addr > > > > > - + (sign * i * req->size), > > > > > - req->size, &req->data); > > > > > + read_phys_req_item(req->addr, req, i, &req->data); > > > > > } > > > > > } else if (req->dir == IOREQ_WRITE) { > > > > > for (i = 0; i < req->count; i++) { > > > > > - write_physical(req->addr > > > > > - + (sign * i * req->size), > > > > > - req->size, &req->data); > > > > > + write_phys_req_item(req->addr, req, i, &req->data); > > > > > } > > > > > } > > > > > } else { > > > > > @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, > > > > ioreq_t > > > > > *req) > > > > > > > > > > if (req->dir == IOREQ_READ) { > > > > > for (i = 0; i < req->count; i++) { > > > > > - read_physical(req->addr > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > - write_physical((target_phys_addr_t )req->data > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > + 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++) { > > > > > - read_physical((target_phys_addr_t) req->data > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > - write_physical(req->addr > > > > > - + (sign * i * req->size), > > > > > - req->size, &tmp); > > > > > + read_phys_req_item(req->data, req, i, &tmp); > > > > > + write_phys_req_item(req->addr, req, i, &tmp); > > > > > } > > > > > } > > > > > } > > > > > > _______________________________________________ > > > Xen-devel mailing list > > > Xen-devel@lists.xen.org > > > http://lists.xen.org/xen-devel > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@lists.xen.org > > http://lists.xen.org/xen-devel > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt 2013-02-19 19:38 ` Pasi Kärkkäinen @ 2013-02-20 15:42 ` Ian Jackson 2013-02-20 15:53 ` Pasi Kärkkäinen 0 siblings, 1 reply; 22+ messages in thread From: Ian Jackson @ 2013-02-20 15:42 UTC (permalink / raw) To: Pasi Kärkkäinen Cc: Xu, Dongxiao, xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini, Ian Campbell Pasi Kärkkäinen writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt"): > Ping again? I wonder if I've gotten into some blacklist already for nagging about this.. > > This is a required patch for making Xen-on-Xen Nested virt working on Intel.. Sorry about that, I have applied it. Ian. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt 2013-02-20 15:42 ` Ian Jackson @ 2013-02-20 15:53 ` Pasi Kärkkäinen 0 siblings, 0 replies; 22+ messages in thread From: Pasi Kärkkäinen @ 2013-02-20 15:53 UTC (permalink / raw) To: Ian Jackson Cc: Xu, Dongxiao, xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini, Ian Campbell On Wed, Feb 20, 2013 at 03:42:15PM +0000, Ian Jackson wrote: > Pasi Kärkkäinen writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt"): > > Ping again? I wonder if I've gotten into some blacklist already for nagging about this.. > > > > This is a required patch for making Xen-on-Xen Nested virt working on Intel.. > > Sorry about that, I have applied it. > Thanks! -- Pasi ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-12-07 16:14 ` [Xen-devel] " Ian Jackson 2012-12-07 16:30 ` Ian Campbell @ 2012-12-10 16:08 ` Stefano Stabellini 2012-12-10 17:01 ` Ian Jackson 1 sibling, 1 reply; 22+ messages in thread From: Stefano Stabellini @ 2012-12-10 16:08 UTC (permalink / raw) To: Ian Jackson Cc: dongxiao.xu@intel.com, xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini On Fri, 7 Dec 2012, Ian Jackson wrote: > Stefano Stabellini writes ("[Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move"): > > after reviewing the patch "fix multiply issue for int and uint types" > > with Ian Jackson, we realized that cpu_ioreq_pio and cpu_ioreq_move are > > in much need for a simplification as well as removal of a possible > > integer overflow. > > > > This patch series tries to accomplish both switching to two new helper > > functions and using a more obvious arithmetic. Doing so it should also > > fix the original problem that Dongxiao was experiencing. The C language > > can be a nasty backstabber when signed and unsigned integers are > > involved. > > I think the attached patch is better as it removes some formulaic > code. I don't think I have a guest which can repro the bug so I have > only compile tested it. > > Dongxiao, would you care to take a look ? > > PS: I'm pretty sure the original overflows aren't security problems. > > Thanks, > Ian. > > commit d19731e4e452e3415a5c03771d0406efc803baa9 > Author: Ian Jackson <ian.jackson@eu.citrix.com> > Date: Fri Dec 7 16:02:04 2012 +0000 > > cpu_ioreq_pio, cpu_ioreq_move: introduce read_phys_req_item, write_phys_req_item > > The current code compare i (int) with req->count (uint32_t) in a for > loop, risking an infinite loop if req->count is >INT_MAX. It also > does the multiplication of req->size in a too-small type, leading to > integer overflows. > > Turn read_physical and write_physical into two different helper > functions, read_phys_req_item and write_phys_req_item, that take care > of adding or subtracting offset depending on sign. > > This removes the formulaic multiplication to a single place where the > integer overflows can be dealt with by casting to wide-enough unsigned > types. > > Reported-By: Dongxiao Xu <dongxiao.xu@intel.com> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> > > diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c > index c6d049c..9b8552c 100644 > --- a/i386-dm/helper2.c > +++ b/i386-dm/helper2.c > @@ -339,21 +339,40 @@ static void do_outp(CPUState *env, unsigned long addr, > } > } > > -static inline void read_physical(uint64_t addr, unsigned long size, void *val) > +/* > + * 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(target_phys_addr_t addr, > + ioreq_t *req, uint32_t i, void *val, int rw) > { > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0); > + /* 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 */ > + target_phys_addr_t offset = (target_phys_addr_t)req->size * i; > + if (req->df) addr -= offset; > + else addr -= offset; This can't be right, can it? The search/replace changes below look correct. For the sake of consistency, could you please send a patch against upstream QEMU to qemu-devel? The corresponding code is in xen-all.c (cpu_ioreq_pio and cpu_ioreq_move). > + cpu_physical_memory_rw(addr, val, req->size, rw); > } > - > -static inline void write_physical(uint64_t addr, unsigned long size, void *val) > +static inline void read_phys_req_item(target_phys_addr_t addr, > + ioreq_t *req, uint32_t i, void *val) > { > - return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1); > + rw_phys_req_item(addr, req, i, val, 0); > +} > +static inline void write_phys_req_item(target_phys_addr_t addr, > + ioreq_t *req, uint32_t i, void *val) > +{ > + rw_phys_req_item(addr, req, i, val, 1); > } > > static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > { > - int i, sign; > - > - sign = req->df ? -1 : 1; > + uint32_t i; > > if (req->dir == IOREQ_READ) { > if (!req->data_is_ptr) { > @@ -363,9 +382,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > > for (i = 0; i < req->count; i++) { > tmp = do_inp(env, req->addr, req->size); > - write_physical((target_phys_addr_t) req->data > - + (sign * i * req->size), > - req->size, &tmp); > + write_phys_req_item((target_phys_addr_t) req->data, req, i, &tmp); > } > } > } else if (req->dir == IOREQ_WRITE) { > @@ -375,9 +392,7 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > for (i = 0; i < req->count; i++) { > unsigned long tmp = 0; > > - read_physical((target_phys_addr_t) req->data > - + (sign * i * req->size), > - req->size, &tmp); > + read_phys_req_item(req->data, req, i, &tmp); > do_outp(env, req->addr, req->size, tmp); > } > } > @@ -386,22 +401,16 @@ static void cpu_ioreq_pio(CPUState *env, ioreq_t *req) > > static void cpu_ioreq_move(CPUState *env, ioreq_t *req) > { > - int i, sign; > - > - sign = req->df ? -1 : 1; > + uint32_t i; > > if (!req->data_is_ptr) { > if (req->dir == IOREQ_READ) { > for (i = 0; i < req->count; i++) { > - read_physical(req->addr > - + (sign * i * req->size), > - req->size, &req->data); > + read_phys_req_item(req->addr, req, i, &req->data); > } > } else if (req->dir == IOREQ_WRITE) { > for (i = 0; i < req->count; i++) { > - write_physical(req->addr > - + (sign * i * req->size), > - req->size, &req->data); > + write_phys_req_item(req->addr, req, i, &req->data); > } > } > } else { > @@ -409,21 +418,13 @@ static void cpu_ioreq_move(CPUState *env, ioreq_t *req) > > if (req->dir == IOREQ_READ) { > for (i = 0; i < req->count; i++) { > - read_physical(req->addr > - + (sign * i * req->size), > - req->size, &tmp); > - write_physical((target_phys_addr_t )req->data > - + (sign * i * req->size), > - req->size, &tmp); > + 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++) { > - read_physical((target_phys_addr_t) req->data > - + (sign * i * req->size), > - req->size, &tmp); > - write_physical(req->addr > - + (sign * i * req->size), > - req->size, &tmp); > + read_phys_req_item(req->data, req, i, &tmp); > + write_phys_req_item(req->addr, req, i, &tmp); > } > } > } > ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move 2012-12-10 16:08 ` [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini @ 2012-12-10 17:01 ` Ian Jackson 0 siblings, 0 replies; 22+ messages in thread From: Ian Jackson @ 2012-12-10 17:01 UTC (permalink / raw) To: Stefano Stabellini Cc: dongxiao.xu@intel.com, xen-devel@lists.xensource.com, qemu-devel@nongnu.org Stefano Stabellini writes ("Re: [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move"): > On Fri, 7 Dec 2012, Ian Jackson wrote: ... > > + if (req->df) addr -= offset; > > + else addr -= offset; > > This can't be right, can it? Indeed not. v2 has this fixed. > The search/replace changes below look correct. Thanks. > For the sake of consistency, could you please send a patch against > upstream QEMU to qemu-devel? The corresponding code is in xen-all.c > (cpu_ioreq_pio and cpu_ioreq_move). I will do that. Thanks, Ian. ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2013-02-20 15:53 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-09-10 18:04 [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini 2012-09-10 18:06 ` [PATCH 1/2] i should be uint32_t rather than int Stefano Stabellini 2012-09-10 18:06 ` [PATCH 2/2] introduce read_physical_offset and write_physical_offset Stefano Stabellini 2012-09-17 23:18 ` [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Xu, Dongxiao 2012-09-18 10:24 ` Stefano Stabellini 2012-11-29 3:22 ` Xu, Dongxiao 2012-11-29 13:21 ` Stefano Stabellini 2012-11-29 13:57 ` [Xen-devel] " Ian Campbell 2012-11-29 15:10 ` Pasi Kärkkäinen 2012-12-07 16:14 ` [Xen-devel] " Ian Jackson 2012-12-07 16:30 ` Ian Campbell 2012-12-07 16:33 ` [Xen-devel] " Ian Jackson 2012-12-11 5:50 ` Xu, Dongxiao 2013-01-08 1:49 ` Xu, Dongxiao 2013-01-09 7:09 ` Pasi Kärkkäinen 2013-01-24 13:44 ` [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move / Xen on Xen nested virt Pasi Kärkkäinen 2013-01-31 2:23 ` Xu, Dongxiao 2013-02-19 19:38 ` Pasi Kärkkäinen 2013-02-20 15:42 ` Ian Jackson 2013-02-20 15:53 ` Pasi Kärkkäinen 2012-12-10 16:08 ` [Xen-devel] [PATCH 0/2] QEMU/xen: simplify cpu_ioreq_pio and cpu_ioreq_move Stefano Stabellini 2012-12-10 17:01 ` Ian Jackson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).