From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58424) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XzSci-0007aj-9V for qemu-devel@nongnu.org; Fri, 12 Dec 2014 10:59:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XzScY-00036f-6w for qemu-devel@nongnu.org; Fri, 12 Dec 2014 10:59:20 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57303) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XzScX-00036M-UJ for qemu-devel@nongnu.org; Fri, 12 Dec 2014 10:59:10 -0500 From: Laszlo Ersek Date: Fri, 12 Dec 2014 16:58:46 +0100 Message-Id: <1418399932-7658-3-git-send-email-lersek@redhat.com> In-Reply-To: <1418399932-7658-1-git-send-email-lersek@redhat.com> References: <1418399932-7658-1-git-send-email-lersek@redhat.com> Subject: [Qemu-devel] [PATCH v4 2/8] fw_cfg: generalize overlap check for combining control and data I/O ports List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: peter.maydell@linaro.org, qemu-devel@nongnu.org, rjones@redhat.com, drjones@redhat.com, lersek@redhat.com If the board code overlaps the (currently only byte-wide) data I/O port with the high byte of the selector I/O port, we install the "comb_iomem" MemoryRegion. Generalize the check to see if *any* byte of the data I/O port overlaps with the high byte of the selector I/O port. If that's the case: - If the data I/O port is just one byte wide, then keep the current behavior. - Otherwise, reject the combination: qemu-system-target: only a byte-wide data I/O port can be combined qemu-system-target: Initialization of device fw_cfg failed The patch doesn't immediately change behavior, because: - fw_cfg_data_mem_ops.valid.max_access_size == 1 - ctl_io_last == s->ctl_iobase + 1 - data_io_end == s->data_iobase + 1 - The condition ctl_io_last >= s->data_iobase && ctl_io_last < data_io_end is equivalent to ctl_io_last >= s->data_iobase && ctl_io_last < s->data_iobase + 1 after substituting "data_io_end". Further, the second relation can be rewritten as ctl_io_last >= s->data_iobase && ctl_io_last <= s->data_iobase which gives ctl_io_last == s->data_iobase After substituting "ctl_io_last", we get s->ctl_iobase + 1 == s->data_iobase Signed-off-by: Laszlo Ersek --- Notes: v4: - new in v4 [Peter] hw/nvram/fw_cfg.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 7f6031c..eb0ad83 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -620,11 +620,24 @@ static void fw_cfg_initfn(Object *obj) static void fw_cfg_realize(DeviceState *dev, Error **errp) { FWCfgState *s = FW_CFG(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + uint32_t ctl_io_last; + uint32_t data_io_end; - if (s->ctl_iobase + 1 == s->data_iobase) { - sysbus_add_io(sbd, s->ctl_iobase, &s->comb_iomem); + if (s->ctl_iobase == 0 && s->data_iobase == 0) { + return; + } + + ctl_io_last = s->ctl_iobase + FW_CFG_SIZE - 1; + data_io_end = s->data_iobase + fw_cfg_data_mem_ops.valid.max_access_size; + if (ctl_io_last >= s->data_iobase && ctl_io_last < data_io_end) { + if (fw_cfg_data_mem_ops.valid.max_access_size == 1) { + sysbus_add_io(sbd, s->ctl_iobase, &s->comb_iomem); + } else { + error_setg(errp, "only a byte-wide data I/O port can be combined"); + return; + } } else { if (s->ctl_iobase) { sysbus_add_io(sbd, s->ctl_iobase, &s->ctl_iomem); } -- 1.8.3.1