From: Cedric Le Goater <clg@fr.ibm.com>
To: Paul Mackerras <paulus@samba.org>
Cc: agraf@suse.de, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH 3/3] KVM: PPC: Book3S: MMIO emulation support for little endian guests
Date: Tue, 08 Oct 2013 11:49:26 +0000 [thread overview]
Message-ID: <5253F146.8030501@fr.ibm.com> (raw)
In-Reply-To: <20131008112255.GA14050@iris.ozlabs.ibm.com>
On 10/08/2013 01:22 PM, Paul Mackerras wrote:
> On Mon, Oct 07, 2013 at 04:27:47PM +0200, Cédric Le Goater wrote:
>> MMIO emulation reads the last instruction executed by the guest
>> and then emulates. If the guest is running in Little Endian mode,
>> the instruction needs to be byte-swapped before being emulated.
>>
>> This patch stores the last instruction in the endian order of the
>> host, primarily doing a byte-swap if needed. The common code
>> which fetches 'last_inst' uses a helper routine kvmppc_need_byteswap().
>> and the exit paths for the Book3S PV and HR guests use their own
>> version in assembly.
>>
>> Finally, kvmppc_emulate_instruction() uses kvmppc_is_bigendian()
>> to define in which endian order the mmio needs to be done.
>>
>> Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
>
> [snip]
>
>> + ld r0, VCPU_MSR(r9)
>> +
>> + /* r10 = vcpu->arch.msr & MSR_LE */
>> + rldicl. r10, r0, 0, 63
>
> I would have written:
>
> andi. r10, r0, MSR_LE
>
> which doesn't need the comment, but really the two are equivalent.
Indeed, this is even better ... rldicl is a vestige of an earlier version
of this patch.
>> @@ -232,6 +231,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
>> int sprn = get_sprn(inst);
>> enum emulation_result emulated = EMULATE_DONE;
>> int advance = 1;
>> + int is_bigendian = kvmppc_is_bigendian(vcpu);
>>
>> /* this default type might be overwritten by subcategories */
>> kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
>> @@ -266,47 +266,53 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
>> advance = 0;
>> break;
>> case OP_31_XOP_LWZX:
>> - emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
>> + emulated = kvmppc_handle_load(run, vcpu, rt, 4,
>> + is_bigendian);
>
> I see you're still hitting all the call sites of kvmppc_handle_load(),
> kvmppc_handle_loads() and kvmppc_handle_store(), rather than putting
> the big-endian test inside kvmppc_handle_load() and
> kvmppc_handle_store(), as in this untested patch:
>
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index f55e14c..171bce6 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -625,9 +625,13 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
> }
>
> int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
> - unsigned int rt, unsigned int bytes, int is_bigendian)
> + unsigned int rt, unsigned int bytes, int not_reverse)
> {
> int idx, ret;
> + int is_bigendian = not_reverse;
> +
> + if (!kvmppc_is_bigendian(vcpu))
> + is_bigendian = !not_reverse;
>
> if (bytes > sizeof(run->mmio.data)) {
> printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
> @@ -662,21 +666,25 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
>
> /* Same as above, but sign extends */
> int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu,
> - unsigned int rt, unsigned int bytes, int is_bigendian)
> + unsigned int rt, unsigned int bytes, int not_reverse)
> {
> int r;
>
> vcpu->arch.mmio_sign_extend = 1;
> - r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian);
> + r = kvmppc_handle_load(run, vcpu, rt, bytes, not_reverse);
>
> return r;
> }
>
> int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
> - u64 val, unsigned int bytes, int is_bigendian)
> + u64 val, unsigned int bytes, int not_reverse)
> {
> void *data = run->mmio.data;
> int idx, ret;
> + int is_bigendian = not_reverse;
> +
> + if (!kvmppc_is_bigendian(vcpu))
> + is_bigendian = !not_reverse;
>
> if (bytes > sizeof(run->mmio.data)) {
> printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
>
> That seems simpler to me -- is there a reason not to do it that way?
No. A part from the fact I did not quite get what you meant the first
time we talked about it. This is more elegant. I will resend a -v2.
Thanks for the review Paul,
C.
WARNING: multiple messages have this Message-ID (diff)
From: Cedric Le Goater <clg@fr.ibm.com>
To: Paul Mackerras <paulus@samba.org>
Cc: agraf@suse.de, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH 3/3] KVM: PPC: Book3S: MMIO emulation support for little endian guests
Date: Tue, 08 Oct 2013 13:49:26 +0200 [thread overview]
Message-ID: <5253F146.8030501@fr.ibm.com> (raw)
In-Reply-To: <20131008112255.GA14050@iris.ozlabs.ibm.com>
On 10/08/2013 01:22 PM, Paul Mackerras wrote:
> On Mon, Oct 07, 2013 at 04:27:47PM +0200, Cédric Le Goater wrote:
>> MMIO emulation reads the last instruction executed by the guest
>> and then emulates. If the guest is running in Little Endian mode,
>> the instruction needs to be byte-swapped before being emulated.
>>
>> This patch stores the last instruction in the endian order of the
>> host, primarily doing a byte-swap if needed. The common code
>> which fetches 'last_inst' uses a helper routine kvmppc_need_byteswap().
>> and the exit paths for the Book3S PV and HR guests use their own
>> version in assembly.
>>
>> Finally, kvmppc_emulate_instruction() uses kvmppc_is_bigendian()
>> to define in which endian order the mmio needs to be done.
>>
>> Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
>
> [snip]
>
>> + ld r0, VCPU_MSR(r9)
>> +
>> + /* r10 = vcpu->arch.msr & MSR_LE */
>> + rldicl. r10, r0, 0, 63
>
> I would have written:
>
> andi. r10, r0, MSR_LE
>
> which doesn't need the comment, but really the two are equivalent.
Indeed, this is even better ... rldicl is a vestige of an earlier version
of this patch.
>> @@ -232,6 +231,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
>> int sprn = get_sprn(inst);
>> enum emulation_result emulated = EMULATE_DONE;
>> int advance = 1;
>> + int is_bigendian = kvmppc_is_bigendian(vcpu);
>>
>> /* this default type might be overwritten by subcategories */
>> kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
>> @@ -266,47 +266,53 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
>> advance = 0;
>> break;
>> case OP_31_XOP_LWZX:
>> - emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
>> + emulated = kvmppc_handle_load(run, vcpu, rt, 4,
>> + is_bigendian);
>
> I see you're still hitting all the call sites of kvmppc_handle_load(),
> kvmppc_handle_loads() and kvmppc_handle_store(), rather than putting
> the big-endian test inside kvmppc_handle_load() and
> kvmppc_handle_store(), as in this untested patch:
>
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index f55e14c..171bce6 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -625,9 +625,13 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
> }
>
> int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
> - unsigned int rt, unsigned int bytes, int is_bigendian)
> + unsigned int rt, unsigned int bytes, int not_reverse)
> {
> int idx, ret;
> + int is_bigendian = not_reverse;
> +
> + if (!kvmppc_is_bigendian(vcpu))
> + is_bigendian = !not_reverse;
>
> if (bytes > sizeof(run->mmio.data)) {
> printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
> @@ -662,21 +666,25 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
>
> /* Same as above, but sign extends */
> int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu,
> - unsigned int rt, unsigned int bytes, int is_bigendian)
> + unsigned int rt, unsigned int bytes, int not_reverse)
> {
> int r;
>
> vcpu->arch.mmio_sign_extend = 1;
> - r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian);
> + r = kvmppc_handle_load(run, vcpu, rt, bytes, not_reverse);
>
> return r;
> }
>
> int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
> - u64 val, unsigned int bytes, int is_bigendian)
> + u64 val, unsigned int bytes, int not_reverse)
> {
> void *data = run->mmio.data;
> int idx, ret;
> + int is_bigendian = not_reverse;
> +
> + if (!kvmppc_is_bigendian(vcpu))
> + is_bigendian = !not_reverse;
>
> if (bytes > sizeof(run->mmio.data)) {
> printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
>
> That seems simpler to me -- is there a reason not to do it that way?
No. A part from the fact I did not quite get what you meant the first
time we talked about it. This is more elegant. I will resend a -v2.
Thanks for the review Paul,
C.
next prev parent reply other threads:[~2013-10-08 11:49 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-07 14:27 [PATCH 0/3] KVM: PPC: Book3S: MMIO support for Little Endian guests Cédric Le Goater
2013-10-07 14:27 ` Cédric Le Goater
2013-10-07 14:27 ` [PATCH 1/3] KVM: PPC: Book3S: add helper routine to load guest instructions Cédric Le Goater
2013-10-07 14:27 ` Cédric Le Goater
2013-10-07 14:27 ` [PATCH 2/3] KVM: PPC: Book3S: add helper routines to detect endian order Cédric Le Goater
2013-10-07 14:27 ` Cédric Le Goater
2013-10-07 14:27 ` [PATCH 3/3] KVM: PPC: Book3S: MMIO emulation support for little endian guests Cédric Le Goater
2013-10-07 14:27 ` Cédric Le Goater
2013-10-08 11:22 ` Paul Mackerras
2013-10-08 11:22 ` Paul Mackerras
2013-10-08 11:49 ` Cedric Le Goater [this message]
2013-10-08 11:49 ` Cedric Le Goater
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=5253F146.8030501@fr.ibm.com \
--to=clg@fr.ibm.com \
--cc=agraf@suse.de \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
--cc=paulus@samba.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.