From: Hollis Blanchard <hollisb@us.ibm.com>
To: "Xu, Anthony" <anthony.xu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: kvm-ppc-devel
<kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
kvm-devel
<kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Subject: Re: [kvm-ppc-devel] [kvm-devel] RFC: MMIO endianness flag
Date: Mon, 14 Jan 2008 16:53:38 +0000 [thread overview]
Message-ID: <1200329618.29077.14.camel@basalt> (raw)
In-Reply-To: <51CFAB8CB6883745AE7B93B3E084EBE2016214A1-wq7ZOvIWXbOiAffOGbnezLfspsVTdybXVpNB7YpNyf8@public.gmane.org>
I hope I've explained in the other mail I just sent why Qemu assuming
little-endian for everything is not OK.
One other important clarification: kvm_run->mmio.is_bigendian is about
*one* *particular* *MMIO* *access*. It has only coincidental
relationship to the "endianness mode" of the guest.
--
Hollis Blanchard
IBM Linux Technology Center
On Mon, 2008-01-14 at 13:42 +0800, Xu, Anthony wrote:
> > kvm_run->mmio.is_bigendian = vcpu->arch.some_register &
> From your example code, I can know is_bigendian indicate whether guest
> is in bigendian mode when accessing MMIO.
>
> Qemu is responsible for handling MMIO emulation, Qemus always assume it
> is running on littleendian mode.
> So if guest accesses MMIO in bigendian mode,
> kvm need to transform it to littleendian before delivering this
> MMIO request to Qemu.
>
>
> This works for IA64 side.
>
>
> Thanks,
> - Anthony
>
>
> Hollis Blanchard wrote:
> > We're just talking about a flag in the kvm_run.mmio structure, so it
> > does not represent the state of any software, guest or host, other
> > than that single MMIO access.
> >
> > This flag is only used for communication between host kernel and host
> > userland, so the host kernel is always responsible for setting it.
> >
> > "is_bigendian" is just one more necessary piece of information for
> > MMIO emulation. kvm_run already tells you that you are loading 4
> > bytes from address 0. What you don't know today is if byte 0 is the
> > least significant or most significant byte. If "is_bigendian" is set,
> > you know that byte 0 is the MSB and byte 3 is the LSB. If not, the
> > opposite is true.
> >
> > In the simplest case, IA64's in-kernel MMIO emulation code could look
> > something like:
> > kvm_run->mmio.phys_addr = addr;
> > kvm_run->mmio.len = len;
> > ...
> > kvm_run->mmio.is_bigendian = vcpu->arch.some_register &
> > BIGENDIAN;
> >
> > If IA64 has reverse-endian load/store instructions like PowerPC, then
> > you would also need to consider the particular instruction used as
> > well as the guest state.
> >
> >
> > On Fri, 2008-01-11 at 10:02 +0800, Xu, Anthony wrote:
> >> Hi all,
> >>
> >> That's a good start to consider BE.
> >> Yes, IA64 support BE and LE.
> >>
> >> I have below comments.
> >>
> >> What does is_bigendian mean?
> >> Host is runing with BE or guest is running with BE.
> >> Who will set is_bigendian?
> >>
> >> For supporing BE,
> >> We need to consider host BE and guest BE.
> >> For IA64, most OS is running with LE, and
> >> Application can run with BE or LE,
> >> For example, Qemu can run with BE or LE.
> >>
> >> IMHO, we need two flags,
> >> host_is_bigendian indicates Qemu is running with BE
> >> Guest_is_bigendian indecates the guest application who is accessing
> >> MMIO
> >>
> >> Is running with LE.
> >>
> >>
> >> - Anthony
> >>
> >>
> >>
> >>
> >>
> >>
> >> Hollis Blanchard wrote:
> >>> On Thu, 2008-01-10 at 17:28 +0200, Avi Kivity wrote:
> >>>> I'll apply that patch (with a #ifdef CONFIG_PPC so other archs
> >>>> don't use it by mistake).
> >>>
> >>> I don't think that's the right ifdef. For example, I believe IA64
> >>> can run in BE mode and so will have the same issue, and there are
> >>> certainly other architectures (less relevant to the current code)
> >>> that definitely are in the same situation.
> >>>
> >>> We need to plumb this through to the libkvm users anyways. Take a
> >>> look at the patch below and tell me if you think it's not the right
> >>> approach. x86 simply won't consider 'is_bigendian'. I spent a lot
> >>> of time on this, and it's by far the cleanest solution I could come
> >>> up with.
> >>>
> >>>
> >>>
> >>> diff --git a/libkvm/config-i386.mak b/libkvm/config-i386.mak ---
> >>> a/libkvm/config-i386.mak +++ b/libkvm/config-i386.mak
> >>> @@ -2,5 +2,6 @@ LIBDIR := /lib
> >>> LIBDIR := /lib
> >>> CFLAGS += -m32
> >>> CFLAGS += -D__i386__
> >>> +CFLAGS += -DARCH_MMIO_ENDIAN_LITTLE
> >>>
> >>> libkvm-$(ARCH)-objs := libkvm-x86.o
> >>> diff --git a/libkvm/config-ia64.mak b/libkvm/config-ia64.mak ---
> >>> a/libkvm/config-ia64.mak +++ b/libkvm/config-ia64.mak
> >>> @@ -1,5 +1,6 @@
> >>>
> >>> LIBDIR := /lib
> >>> CFLAGS += -D__ia64__
> >>> +CFLAGS += -DARCH_MMIO_ENDIAN_LITTLE -DARCH_MMIO_ENDIAN_BIG
> >>>
> >>> libkvm-$(ARCH)-objs := libkvm-ia64.o
> >>> diff --git a/libkvm/config-powerpc.mak b/libkvm/config-powerpc.mak
> >>> --- a/libkvm/config-powerpc.mak
> >>> +++ b/libkvm/config-powerpc.mak
> >>> @@ -2,5 +2,6 @@ LIBDIR := /lib
> >>> LIBDIR := /lib
> >>> CFLAGS += -m32
> >>> CFLAGS += -D__powerpc__
> >>> +CFLAGS += -DARCH_MMIO_ENDIAN_BIG -DARCH_MMIO_ENDIAN_LITTLE
> >>>
> >>> libkvm-$(ARCH)-objs := libkvm-powerpc.o
> >>> diff --git a/libkvm/config-x86_64.mak b/libkvm/config-x86_64.mak
> >>> --- a/libkvm/config-x86_64.mak
> >>> +++ b/libkvm/config-x86_64.mak
> >>> @@ -2,5 +2,6 @@ LIBDIR := /lib64
> >>> LIBDIR := /lib64
> >>> CFLAGS += -m64
> >>> CFLAGS += -D__x86_64__
> >>> +CFLAGS += -DARCH_MMIO_ENDIAN_LITTLE
> >>>
> >>> libkvm-$(ARCH)-objs := libkvm-x86.o
> >>> diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
> >>> --- a/libkvm/libkvm.c
> >>> +++ b/libkvm/libkvm.c
> >>> @@ -774,21 +774,56 @@ int kvm_set_sregs(kvm_context_t kvm, int
> >>> return ioctl(kvm->vcpu_fd[vcpu], KVM_SET_SREGS, sregs); }
> >>>
> >>> +#ifdef ARCH_MMIO_ENDIAN_BIG
> >>> +static int handle_mmio_bigendian(kvm_context_t kvm, struct kvm_run
> >>> *kvm_run) +{ + if (kvm_run->mmio.is_write)
> >>> + return kvm->callbacks->mmio_write_be(kvm->opaque,
> >>> +
> >> kvm_run->mmio.phys_addr,
> >>> + kvm_run->mmio.data,
> >>> + kvm_run->mmio.len);
> >>> + else
> >>> + return kvm->callbacks->mmio_read_be(kvm->opaque,
> >>> +
> >> kvm_run->mmio.phys_addr,
> >>> + kvm_run->mmio.data,
> >>> + kvm_run->mmio.len);
> >>> +}
> >>> +#endif
> >>> +
> >>> +#ifdef ARCH_MMIO_ENDIAN_LITTLE
> >>> +static int handle_mmio_littleendian(kvm_context_t kvm, struct
> >>> kvm_run *kvm_run) +{ + if (kvm_run->mmio.is_write)
> >>> + return kvm->callbacks->mmio_write_le(kvm->opaque,
> >>> +
> >> kvm_run->mmio.phys_addr,
> >>> + kvm_run->mmio.data,
> >>> + kvm_run->mmio.len);
> >>> + else
> >>> + return kvm->callbacks->mmio_read_le(kvm->opaque,
> >>> +
> >> kvm_run->mmio.phys_addr,
> >>> + kvm_run->mmio.data,
> >>> + kvm_run->mmio.len);
> >>> +}
> >>> +#endif
> >>> +
> >>> static int handle_mmio(kvm_context_t kvm, struct kvm_run *kvm_run)
> >>> { unsigned long addr = kvm_run->mmio.phys_addr;
> >>> - void *data = kvm_run->mmio.data;
> >>>
> >>> /* hack: Red Hat 7.1 generates these weird accesses. */
> >>> if ((addr > 0xa0000-4 && addr <= 0xa0000) && kvm_run->mmio.len
> =
> >>> 3) return 0;
> >>>
> >>> - if (kvm_run->mmio.is_write)
> >>> - return kvm->callbacks->mmio_write(kvm->opaque, addr,
> data,
> >>> - kvm_run->mmio.len);
> >>> +#if defined(ARCH_MMIO_ENDIAN_BIG) &&
> >>> defined(ARCH_MMIO_ENDIAN_LITTLE) + if (kvm_run->mmio.is_bigendian)
> >>> + return handle_mmio_bigendian(kvm, kvm_run);
> >>> else
> >>> - return kvm->callbacks->mmio_read(kvm->opaque, addr,
> data,
> >>> - kvm_run->mmio.len);
> >>> + return handle_mmio_littleendian(kvm, kvm_run);
> >>> +#elif ARCH_MMIO_ENDIAN_LITTLE
> >>> + return handle_mmio_littleendian(kvm, kvm_run);
> >>> +#elif ARCH_MMIO_ENDIAN_BIG
> >>> + return handle_mmio_bigendian(kvm, kvm_run);
> >>> +#endif
> >>> }
> >>>
> >>> int handle_io_window(kvm_context_t kvm)
> >>> diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
> >>> --- a/libkvm/libkvm.h
> >>> +++ b/libkvm/libkvm.h
> >>> @@ -46,11 +46,11 @@ struct kvm_callbacks {
> >>> /// For 32bit IO writes from the guest (Usually when executing
> >>> 'outl') int (*outl)(void *opaque, uint16_t addr, uint32_t
> >>> data); /// generic memory reads to unmapped memory (For MMIO
> >>> devices)
> >>> - int (*mmio_read)(void *opaque, uint64_t addr, uint8_t *data,
> >>> - int len);
> >>> + int (*mmio_read_be)(void *opaque, uint64_t addr, uint8_t *data,
> >>> int len); + int (*mmio_read_le)(void *opaque, uint64_t addr,
> >>> uint8_t *data, int len); /// generic memory writes to unmapped
> >>> memory (For MMIO devices)
> >>> - int (*mmio_write)(void *opaque, uint64_t addr, uint8_t *data,
> >>> - int len);
> >>> + int (*mmio_write_be)(void *opaque, uint64_t addr, uint8_t
> >>> *data, int len); + int (*mmio_write_le)(void *opaque, uint64_t
> >>> addr, uint8_t *data, int len); int (*debug)(void *opaque, int
> >>> vcpu); /*! * \brief Called when the VCPU issues an
> 'hlt'
> >>> instruction.
> >>> diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
> >>> --- a/qemu/qemu-kvm.c
> >>> +++ b/qemu/qemu-kvm.c
> >>> @@ -21,6 +21,7 @@ int kvm_irqchip = 1;
> >>> #include <libkvm.h>
> >>> #include <pthread.h>
> >>> #include <sys/utsname.h>
> >>> +#include <endian.h>
> >>>
> >>> extern void perror(const char *s);
> >>>
> >>> @@ -533,8 +534,13 @@ static struct kvm_callbacks qemu_kvm_ops
> >>> .outb = kvm_outb, .outw = kvm_outw,
> >>> .outl = kvm_outl,
> >>> - .mmio_read = kvm_mmio_read,
> >>> - .mmio_write = kvm_mmio_write,
> >>> +#if __BYTE_ORDER = __LITTLE_ENDIAN
> >>> + .mmio_read_le = kvm_mmio_read,
> >>> + .mmio_write_le = kvm_mmio_write,
> >>> +#else
> >>> + .mmio_read_be = kvm_mmio_read,
> >>> + .mmio_write_be = kvm_mmio_write,
> >>> +#endif
> >>> .halt = kvm_halt,
> >>> .shutdown = kvm_shutdown,
> >>> .io_window = kvm_io_window,
> >>> diff --git a/user/main-ppc.c b/user/main-ppc.c
> >>> --- a/user/main-ppc.c
> >>> +++ b/user/main-ppc.c
> >>> @@ -92,14 +92,14 @@ static int test_pre_kvm_run(void *opaque
> >>> return 0; }
> >>>
> >>> -static int test_mem_read(void *opaque, uint64_t addr, uint8_t
> >>> *data, int len) +static int test_mem_read_be(void *opaque, uint64_t
> >>> addr, uint8_t *data, int len) { printf("%s: addr %"PRIx64" len
> >>> %d\n", __func__, addr, len); memset(data, 0, len); return 0;
> >>> }
> >>>
> >>> -static int test_mem_write(void *opaque, uint64_t addr, uint8_t
> >>> *data, int len) +static int test_mem_write_be(void *opaque, uint64_t
> >>> addr, uint8_t *data, int len) {
> >>> printf("%s: addr %"PRIx64" len %d data %"PRIx64"\n",
> >>> __func__, addr, len, *(uint64_t *)data);
> >>> @@ -120,8 +120,8 @@ static int test_dcr_write(kvm_context_t }
> >>>
> >>> static struct kvm_callbacks test_callbacks = {
> >>> - .mmio_read = test_mem_read,
> >>> - .mmio_write = test_mem_write,
> >>> + .mmio_read_be = test_mem_read_be,
> >>> + .mmio_write_be = test_mem_write_be,
> >>> .debug = test_debug,
> >>> .halt = test_halt,
> >>> .io_window = test_io_window,
> >>> diff --git a/user/main.c b/user/main.c
> >>> --- a/user/main.c
> >>> +++ b/user/main.c
> >>> @@ -389,8 +389,8 @@ static struct kvm_callbacks test_callbac
> >>> .outb = test_outb, .outw = test_outw,
> >>> .outl = test_outl,
> >>> - .mmio_read = test_mem_read,
> >>> - .mmio_write = test_mem_write,
> >>> + .mmio_read_le = test_mem_read,
> >>> + .mmio_write_le = test_mem_write,
> >>> .debug = test_debug,
> >>> .halt = test_halt,
> >>> .io_window = test_io_window,
> >>
> >>
> ------------------------------------------------------------------------
> -
> >> Check out the new SourceForge.net Marketplace.
> >> It's the best place to buy or sell services for
> >> just about anything Open Source.
> >>
> http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketp
> lace
> >> _______________________________________________
> >> kvm-devel mailing list
> >> kvm-devel@lists.sourceforge.net
> >> https://lists.sourceforge.net/lists/listinfo/kvm-devel
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
kvm-ppc-devel mailing list
kvm-ppc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel
WARNING: multiple messages have this Message-ID (diff)
From: Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
To: "Xu, Anthony" <anthony.xu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: kvm-ppc-devel
<kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
kvm-devel
<kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Subject: Re: [kvm-ppc-devel] RFC: MMIO endianness flag
Date: Mon, 14 Jan 2008 10:53:38 -0600 [thread overview]
Message-ID: <1200329618.29077.14.camel@basalt> (raw)
In-Reply-To: <51CFAB8CB6883745AE7B93B3E084EBE2016214A1-wq7ZOvIWXbOiAffOGbnezLfspsVTdybXVpNB7YpNyf8@public.gmane.org>
I hope I've explained in the other mail I just sent why Qemu assuming
little-endian for everything is not OK.
One other important clarification: kvm_run->mmio.is_bigendian is about
*one* *particular* *MMIO* *access*. It has only coincidental
relationship to the "endianness mode" of the guest.
--
Hollis Blanchard
IBM Linux Technology Center
On Mon, 2008-01-14 at 13:42 +0800, Xu, Anthony wrote:
> > kvm_run->mmio.is_bigendian = vcpu->arch.some_register &
> From your example code, I can know is_bigendian indicate whether guest
> is in bigendian mode when accessing MMIO.
>
> Qemu is responsible for handling MMIO emulation, Qemus always assume it
> is running on littleendian mode.
> So if guest accesses MMIO in bigendian mode,
> kvm need to transform it to littleendian before delivering this
> MMIO request to Qemu.
>
>
> This works for IA64 side.
>
>
> Thanks,
> - Anthony
>
>
> Hollis Blanchard wrote:
> > We're just talking about a flag in the kvm_run.mmio structure, so it
> > does not represent the state of any software, guest or host, other
> > than that single MMIO access.
> >
> > This flag is only used for communication between host kernel and host
> > userland, so the host kernel is always responsible for setting it.
> >
> > "is_bigendian" is just one more necessary piece of information for
> > MMIO emulation. kvm_run already tells you that you are loading 4
> > bytes from address 0. What you don't know today is if byte 0 is the
> > least significant or most significant byte. If "is_bigendian" is set,
> > you know that byte 0 is the MSB and byte 3 is the LSB. If not, the
> > opposite is true.
> >
> > In the simplest case, IA64's in-kernel MMIO emulation code could look
> > something like:
> > kvm_run->mmio.phys_addr = addr;
> > kvm_run->mmio.len = len;
> > ...
> > kvm_run->mmio.is_bigendian = vcpu->arch.some_register &
> > BIGENDIAN;
> >
> > If IA64 has reverse-endian load/store instructions like PowerPC, then
> > you would also need to consider the particular instruction used as
> > well as the guest state.
> >
> >
> > On Fri, 2008-01-11 at 10:02 +0800, Xu, Anthony wrote:
> >> Hi all,
> >>
> >> That's a good start to consider BE.
> >> Yes, IA64 support BE and LE.
> >>
> >> I have below comments.
> >>
> >> What does is_bigendian mean?
> >> Host is runing with BE or guest is running with BE.
> >> Who will set is_bigendian?
> >>
> >> For supporing BE,
> >> We need to consider host BE and guest BE.
> >> For IA64, most OS is running with LE, and
> >> Application can run with BE or LE,
> >> For example, Qemu can run with BE or LE.
> >>
> >> IMHO, we need two flags,
> >> host_is_bigendian indicates Qemu is running with BE
> >> Guest_is_bigendian indecates the guest application who is accessing
> >> MMIO
> >>
> >> Is running with LE.
> >>
> >>
> >> - Anthony
> >>
> >>
> >>
> >>
> >>
> >>
> >> Hollis Blanchard wrote:
> >>> On Thu, 2008-01-10 at 17:28 +0200, Avi Kivity wrote:
> >>>> I'll apply that patch (with a #ifdef CONFIG_PPC so other archs
> >>>> don't use it by mistake).
> >>>
> >>> I don't think that's the right ifdef. For example, I believe IA64
> >>> can run in BE mode and so will have the same issue, and there are
> >>> certainly other architectures (less relevant to the current code)
> >>> that definitely are in the same situation.
> >>>
> >>> We need to plumb this through to the libkvm users anyways. Take a
> >>> look at the patch below and tell me if you think it's not the right
> >>> approach. x86 simply won't consider 'is_bigendian'. I spent a lot
> >>> of time on this, and it's by far the cleanest solution I could come
> >>> up with.
> >>>
> >>>
> >>>
> >>> diff --git a/libkvm/config-i386.mak b/libkvm/config-i386.mak ---
> >>> a/libkvm/config-i386.mak +++ b/libkvm/config-i386.mak
> >>> @@ -2,5 +2,6 @@ LIBDIR := /lib
> >>> LIBDIR := /lib
> >>> CFLAGS += -m32
> >>> CFLAGS += -D__i386__
> >>> +CFLAGS += -DARCH_MMIO_ENDIAN_LITTLE
> >>>
> >>> libkvm-$(ARCH)-objs := libkvm-x86.o
> >>> diff --git a/libkvm/config-ia64.mak b/libkvm/config-ia64.mak ---
> >>> a/libkvm/config-ia64.mak +++ b/libkvm/config-ia64.mak
> >>> @@ -1,5 +1,6 @@
> >>>
> >>> LIBDIR := /lib
> >>> CFLAGS += -D__ia64__
> >>> +CFLAGS += -DARCH_MMIO_ENDIAN_LITTLE -DARCH_MMIO_ENDIAN_BIG
> >>>
> >>> libkvm-$(ARCH)-objs := libkvm-ia64.o
> >>> diff --git a/libkvm/config-powerpc.mak b/libkvm/config-powerpc.mak
> >>> --- a/libkvm/config-powerpc.mak
> >>> +++ b/libkvm/config-powerpc.mak
> >>> @@ -2,5 +2,6 @@ LIBDIR := /lib
> >>> LIBDIR := /lib
> >>> CFLAGS += -m32
> >>> CFLAGS += -D__powerpc__
> >>> +CFLAGS += -DARCH_MMIO_ENDIAN_BIG -DARCH_MMIO_ENDIAN_LITTLE
> >>>
> >>> libkvm-$(ARCH)-objs := libkvm-powerpc.o
> >>> diff --git a/libkvm/config-x86_64.mak b/libkvm/config-x86_64.mak
> >>> --- a/libkvm/config-x86_64.mak
> >>> +++ b/libkvm/config-x86_64.mak
> >>> @@ -2,5 +2,6 @@ LIBDIR := /lib64
> >>> LIBDIR := /lib64
> >>> CFLAGS += -m64
> >>> CFLAGS += -D__x86_64__
> >>> +CFLAGS += -DARCH_MMIO_ENDIAN_LITTLE
> >>>
> >>> libkvm-$(ARCH)-objs := libkvm-x86.o
> >>> diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
> >>> --- a/libkvm/libkvm.c
> >>> +++ b/libkvm/libkvm.c
> >>> @@ -774,21 +774,56 @@ int kvm_set_sregs(kvm_context_t kvm, int
> >>> return ioctl(kvm->vcpu_fd[vcpu], KVM_SET_SREGS, sregs); }
> >>>
> >>> +#ifdef ARCH_MMIO_ENDIAN_BIG
> >>> +static int handle_mmio_bigendian(kvm_context_t kvm, struct kvm_run
> >>> *kvm_run) +{ + if (kvm_run->mmio.is_write)
> >>> + return kvm->callbacks->mmio_write_be(kvm->opaque,
> >>> +
> >> kvm_run->mmio.phys_addr,
> >>> + kvm_run->mmio.data,
> >>> + kvm_run->mmio.len);
> >>> + else
> >>> + return kvm->callbacks->mmio_read_be(kvm->opaque,
> >>> +
> >> kvm_run->mmio.phys_addr,
> >>> + kvm_run->mmio.data,
> >>> + kvm_run->mmio.len);
> >>> +}
> >>> +#endif
> >>> +
> >>> +#ifdef ARCH_MMIO_ENDIAN_LITTLE
> >>> +static int handle_mmio_littleendian(kvm_context_t kvm, struct
> >>> kvm_run *kvm_run) +{ + if (kvm_run->mmio.is_write)
> >>> + return kvm->callbacks->mmio_write_le(kvm->opaque,
> >>> +
> >> kvm_run->mmio.phys_addr,
> >>> + kvm_run->mmio.data,
> >>> + kvm_run->mmio.len);
> >>> + else
> >>> + return kvm->callbacks->mmio_read_le(kvm->opaque,
> >>> +
> >> kvm_run->mmio.phys_addr,
> >>> + kvm_run->mmio.data,
> >>> + kvm_run->mmio.len);
> >>> +}
> >>> +#endif
> >>> +
> >>> static int handle_mmio(kvm_context_t kvm, struct kvm_run *kvm_run)
> >>> { unsigned long addr = kvm_run->mmio.phys_addr;
> >>> - void *data = kvm_run->mmio.data;
> >>>
> >>> /* hack: Red Hat 7.1 generates these weird accesses. */
> >>> if ((addr > 0xa0000-4 && addr <= 0xa0000) && kvm_run->mmio.len
> ==
> >>> 3) return 0;
> >>>
> >>> - if (kvm_run->mmio.is_write)
> >>> - return kvm->callbacks->mmio_write(kvm->opaque, addr,
> data,
> >>> - kvm_run->mmio.len);
> >>> +#if defined(ARCH_MMIO_ENDIAN_BIG) &&
> >>> defined(ARCH_MMIO_ENDIAN_LITTLE) + if (kvm_run->mmio.is_bigendian)
> >>> + return handle_mmio_bigendian(kvm, kvm_run);
> >>> else
> >>> - return kvm->callbacks->mmio_read(kvm->opaque, addr,
> data,
> >>> - kvm_run->mmio.len);
> >>> + return handle_mmio_littleendian(kvm, kvm_run);
> >>> +#elif ARCH_MMIO_ENDIAN_LITTLE
> >>> + return handle_mmio_littleendian(kvm, kvm_run);
> >>> +#elif ARCH_MMIO_ENDIAN_BIG
> >>> + return handle_mmio_bigendian(kvm, kvm_run);
> >>> +#endif
> >>> }
> >>>
> >>> int handle_io_window(kvm_context_t kvm)
> >>> diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
> >>> --- a/libkvm/libkvm.h
> >>> +++ b/libkvm/libkvm.h
> >>> @@ -46,11 +46,11 @@ struct kvm_callbacks {
> >>> /// For 32bit IO writes from the guest (Usually when executing
> >>> 'outl') int (*outl)(void *opaque, uint16_t addr, uint32_t
> >>> data); /// generic memory reads to unmapped memory (For MMIO
> >>> devices)
> >>> - int (*mmio_read)(void *opaque, uint64_t addr, uint8_t *data,
> >>> - int len);
> >>> + int (*mmio_read_be)(void *opaque, uint64_t addr, uint8_t *data,
> >>> int len); + int (*mmio_read_le)(void *opaque, uint64_t addr,
> >>> uint8_t *data, int len); /// generic memory writes to unmapped
> >>> memory (For MMIO devices)
> >>> - int (*mmio_write)(void *opaque, uint64_t addr, uint8_t *data,
> >>> - int len);
> >>> + int (*mmio_write_be)(void *opaque, uint64_t addr, uint8_t
> >>> *data, int len); + int (*mmio_write_le)(void *opaque, uint64_t
> >>> addr, uint8_t *data, int len); int (*debug)(void *opaque, int
> >>> vcpu); /*! * \brief Called when the VCPU issues an
> 'hlt'
> >>> instruction.
> >>> diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
> >>> --- a/qemu/qemu-kvm.c
> >>> +++ b/qemu/qemu-kvm.c
> >>> @@ -21,6 +21,7 @@ int kvm_irqchip = 1;
> >>> #include <libkvm.h>
> >>> #include <pthread.h>
> >>> #include <sys/utsname.h>
> >>> +#include <endian.h>
> >>>
> >>> extern void perror(const char *s);
> >>>
> >>> @@ -533,8 +534,13 @@ static struct kvm_callbacks qemu_kvm_ops
> >>> .outb = kvm_outb, .outw = kvm_outw,
> >>> .outl = kvm_outl,
> >>> - .mmio_read = kvm_mmio_read,
> >>> - .mmio_write = kvm_mmio_write,
> >>> +#if __BYTE_ORDER == __LITTLE_ENDIAN
> >>> + .mmio_read_le = kvm_mmio_read,
> >>> + .mmio_write_le = kvm_mmio_write,
> >>> +#else
> >>> + .mmio_read_be = kvm_mmio_read,
> >>> + .mmio_write_be = kvm_mmio_write,
> >>> +#endif
> >>> .halt = kvm_halt,
> >>> .shutdown = kvm_shutdown,
> >>> .io_window = kvm_io_window,
> >>> diff --git a/user/main-ppc.c b/user/main-ppc.c
> >>> --- a/user/main-ppc.c
> >>> +++ b/user/main-ppc.c
> >>> @@ -92,14 +92,14 @@ static int test_pre_kvm_run(void *opaque
> >>> return 0; }
> >>>
> >>> -static int test_mem_read(void *opaque, uint64_t addr, uint8_t
> >>> *data, int len) +static int test_mem_read_be(void *opaque, uint64_t
> >>> addr, uint8_t *data, int len) { printf("%s: addr %"PRIx64" len
> >>> %d\n", __func__, addr, len); memset(data, 0, len); return 0;
> >>> }
> >>>
> >>> -static int test_mem_write(void *opaque, uint64_t addr, uint8_t
> >>> *data, int len) +static int test_mem_write_be(void *opaque, uint64_t
> >>> addr, uint8_t *data, int len) {
> >>> printf("%s: addr %"PRIx64" len %d data %"PRIx64"\n",
> >>> __func__, addr, len, *(uint64_t *)data);
> >>> @@ -120,8 +120,8 @@ static int test_dcr_write(kvm_context_t }
> >>>
> >>> static struct kvm_callbacks test_callbacks = {
> >>> - .mmio_read = test_mem_read,
> >>> - .mmio_write = test_mem_write,
> >>> + .mmio_read_be = test_mem_read_be,
> >>> + .mmio_write_be = test_mem_write_be,
> >>> .debug = test_debug,
> >>> .halt = test_halt,
> >>> .io_window = test_io_window,
> >>> diff --git a/user/main.c b/user/main.c
> >>> --- a/user/main.c
> >>> +++ b/user/main.c
> >>> @@ -389,8 +389,8 @@ static struct kvm_callbacks test_callbac
> >>> .outb = test_outb, .outw = test_outw,
> >>> .outl = test_outl,
> >>> - .mmio_read = test_mem_read,
> >>> - .mmio_write = test_mem_write,
> >>> + .mmio_read_le = test_mem_read,
> >>> + .mmio_write_le = test_mem_write,
> >>> .debug = test_debug,
> >>> .halt = test_halt,
> >>> .io_window = test_io_window,
> >>
> >>
> ------------------------------------------------------------------------
> -
> >> Check out the new SourceForge.net Marketplace.
> >> It's the best place to buy or sell services for
> >> just about anything Open Source.
> >>
> http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketp
> lace
> >> _______________________________________________
> >> kvm-devel mailing list
> >> kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> >> https://lists.sourceforge.net/lists/listinfo/kvm-devel
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
next prev parent reply other threads:[~2008-01-14 16:53 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-09 23:06 [kvm-ppc-devel] RFC: MMIO endianness flag Hollis Blanchard
2008-01-09 23:06 ` Hollis Blanchard
2008-01-10 6:56 ` [kvm-ppc-devel] " Avi Kivity
2008-01-10 6:56 ` Avi Kivity
[not found] ` <4785C199.9040002-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-10 15:23 ` [kvm-ppc-devel] " Hollis Blanchard
2008-01-10 15:23 ` Hollis Blanchard
2008-01-10 15:28 ` [kvm-ppc-devel] " Avi Kivity
2008-01-10 15:28 ` Avi Kivity
[not found] ` <4786398C.2090308-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-10 22:57 ` [kvm-ppc-devel] " Hollis Blanchard
2008-01-10 22:57 ` Hollis Blanchard
2008-01-11 2:02 ` [kvm-ppc-devel] [kvm-devel] " Xu, Anthony
2008-01-11 2:02 ` [kvm-ppc-devel] " Xu, Anthony
[not found] ` <51CFAB8CB6883745AE7B93B3E084EBE201620FD0-wq7ZOvIWXbOiAffOGbnezLfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2008-01-11 14:55 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2008-01-11 14:55 ` [kvm-ppc-devel] " Hollis Blanchard
2008-01-14 5:42 ` [kvm-ppc-devel] [kvm-devel] " Xu, Anthony
2008-01-14 5:42 ` [kvm-ppc-devel] " Xu, Anthony
[not found] ` <51CFAB8CB6883745AE7B93B3E084EBE2016214A1-wq7ZOvIWXbOiAffOGbnezLfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2008-01-14 16:53 ` Hollis Blanchard [this message]
2008-01-14 16:53 ` Hollis Blanchard
2008-01-13 9:42 ` [kvm-ppc-devel] [kvm-devel] " Avi Kivity
2008-01-13 9:42 ` [kvm-ppc-devel] " Avi Kivity
[not found] ` <4789DD0C.4010600-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-14 16:51 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2008-01-14 16:51 ` [kvm-ppc-devel] " Hollis Blanchard
2008-01-14 17:30 ` [kvm-ppc-devel] [kvm-devel] " Avi Kivity
2008-01-14 17:30 ` [kvm-ppc-devel] " Avi Kivity
[not found] ` <478B9C41.80105-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-14 20:43 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2008-01-14 20:43 ` [kvm-ppc-devel] " Hollis Blanchard
2008-01-15 14:57 ` [kvm-ppc-devel] [kvm-devel] " Avi Kivity
2008-01-15 14:57 ` [kvm-ppc-devel] " Avi Kivity
[not found] ` <478CC9EF.9020907-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-15 16:22 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2008-01-15 16:22 ` [kvm-ppc-devel] " Hollis Blanchard
2008-01-15 2:43 ` [kvm-ppc-devel] [kvm-devel] " Xu, Anthony
2008-01-15 2:43 ` [kvm-ppc-devel] " Xu, Anthony
[not found] ` <51CFAB8CB6883745AE7B93B3E084EBE2016217AB-wq7ZOvIWXbOiAffOGbnezLfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2008-01-15 3:54 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2008-01-15 3:54 ` [kvm-ppc-devel] " Hollis Blanchard
2008-01-10 15:37 ` Jimi Xenidis
2008-01-10 15:37 ` Jimi Xenidis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1200329618.29077.14.camel@basalt \
--to=hollisb@us.ibm.com \
--cc=anthony.xu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.