diff mbox

pseries-2.6 migration from QEMU-2.6 to QEMU-2.7 broken

Message ID 8737ks5h1c.fsf@abhimanyu.i-did-not-set--mail-host-address--so-tickle-me (mailing list archive)
State New, archived
Headers show

Commit Message

Nikunj A. Dadhania Sept. 22, 2016, 11:07 a.m. UTC
Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> On Thu, 2016-09-22 at 14:34 +0530, Nikunj A Dadhania wrote:
>> Something like this works for KVM:
>> 
>> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
>> index 4820f22..1cf3779 100644
>> --- a/target-ppc/machine.c
>> +++ b/target-ppc/machine.c
>> @@ -563,8 +563,8 @@ const VMStateDescription vmstate_ppc_cpu = {
>>  
>>          /* Sanity checking */
>>          VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
>> -        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
>> -        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
>> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags) */
>> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags2) */
>>          VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
>>          VMSTATE_END_OF_LIST()
>>      },
>> 
>> TCG migration still remains broken with this.
>
> Can we have conditionally present flags and a post-load that does some
> matching ?

I think its possible like this:



TCG migration succeeds and proceeds ahead. But fails somewhere ahead in
powerpc exception handler:

[qemu]$ ./ppc64-softmmu/qemu-system-ppc64  -machine pseries-2.6,usb=off -vga none -nographic -m 2G   ../../imgs/guest.disk -monitor pty --incoming tcp:localhost:4444 
char device redirected to /dev/pts/5 (label compat_monitor0)
ppc_kvm_enabled: is kvm enabled 0
get_insns_equal: 
Did not match, ignore 9223477658187168481 != 9223477658187151905
ppc_kvm_enabled: is kvm enabled 0
get_insns_equal: 
Did not match, ignore 331702 != 69558
Cannot open font file True
Cannot open font file True
qemu: fatal: Trying to deliver HV exception 4 with no HV support

NIP c0000000000795c8   LR d00000000074407c CTR c000000000079544 XER 0000000000000000 CPU#0
MSR 8000000000009032 HID0 0000000000000000  HF 8000000000000030 iidx 1 didx 1
TB 00000007 32202510341 DECR 00596259

Regards,
Nikunj

Comments

Cédric Le Goater Sept. 22, 2016, 11:27 a.m. UTC | #1
On 09/22/2016 01:07 PM, Nikunj A Dadhania wrote:
> Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> 
>> On Thu, 2016-09-22 at 14:34 +0530, Nikunj A Dadhania wrote:
>>> Something like this works for KVM:
>>>
>>> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
>>> index 4820f22..1cf3779 100644
>>> --- a/target-ppc/machine.c
>>> +++ b/target-ppc/machine.c
>>> @@ -563,8 +563,8 @@ const VMStateDescription vmstate_ppc_cpu = {
>>>  
>>>          /* Sanity checking */
>>>          VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
>>> -        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
>>> -        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
>>> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags) */
>>> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags2) */
>>>          VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
>>>          VMSTATE_END_OF_LIST()
>>>      },
>>>
>>> TCG migration still remains broken with this.
>>
>> Can we have conditionally present flags and a post-load that does some
>> matching ?
> 
> I think its possible like this:
> 
> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
> index 4820f22..dc4704e 100644
> --- a/target-ppc/machine.c
> +++ b/target-ppc/machine.c
> @@ -528,6 +528,42 @@ static const VMStateDescription vmstate_tlbmas = {
>      }
>  };
>  
> +static bool ppc_kvm_enabled(void *opaque, int version_id)
> +{
> +    printf("%s: is kvm enabled %d\n", __func__, kvm_enabled());
> +    return !kvm_enabled();
> +}
> +
> +static int get_insns_equal(QEMUFile *f, void *pv, size_t size)
> +{
> +    uint64_t *v = pv;
> +    uint64_t v2;
> +    qemu_get_be64s(f, &v2);
> +
> +    printf("%s: \n", __func__);
> +
> +    if (*v == v2) {
> +        return 0;
> +    }
> +    printf("Did not match, ignore %" PRIu64 " != %" PRIu64 "\n", *v, v2);
> +    return 0;
> +}
> +
> +static void put_insns(QEMUFile *f, void *pv, size_t size)
> +{
> +    uint64_t *v = pv;
> +    qemu_put_be64s(f, v);
> +}
> +
> +const VMStateInfo vmstate_info_insns_equal = {
> +    .name = "insns equal",
> +    .get  = get_insns_equal,
> +    .put  = put_insns,
> +};
> +
> +#define VMSTATE_INSNS_EQUAL(_f, _s, _t)                                 \
> +    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_insns_equal, uint64_t)
> +
>  const VMStateDescription vmstate_ppc_cpu = {
>      .name = "cpu",
>      .version_id = 5,
> @@ -563,8 +599,8 @@ const VMStateDescription vmstate_ppc_cpu = {
>  
>          /* Sanity checking */
>          VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
> -        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
> -        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
> +        VMSTATE_INSNS_EQUAL(env.insns_flags, PowerPCCPU, ppc_kvm_enabled),
> +        VMSTATE_INSNS_EQUAL(env.insns_flags2, PowerPCCPU, ppc_kvm_enabled),
>          VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
>          VMSTATE_END_OF_LIST()
>      },
> 
> 
> TCG migration succeeds and proceeds ahead. But fails somewhere ahead in
> powerpc exception handler:
> 
> [qemu]$ ./ppc64-softmmu/qemu-system-ppc64  -machine pseries-2.6,usb=off -vga none -nographic -m 2G   ../../imgs/guest.disk -monitor pty --incoming tcp:localhost:4444 
> char device redirected to /dev/pts/5 (label compat_monitor0)
> ppc_kvm_enabled: is kvm enabled 0
> get_insns_equal: 
> Did not match, ignore 9223477658187168481 != 9223477658187151905
> ppc_kvm_enabled: is kvm enabled 0
> get_insns_equal: 
> Did not match, ignore 331702 != 69558
> Cannot open font file True
> Cannot open font file True
> qemu: fatal: Trying to deliver HV exception 4 with no HV support

hmm, this is because we added MSR_HVB in msr_mask AFAICT. we should have 
a similar vmstate op for it I think

C. 

> 
> NIP c0000000000795c8   LR d00000000074407c CTR c000000000079544 XER 0000000000000000 CPU#0
> MSR 8000000000009032 HID0 0000000000000000  HF 8000000000000030 iidx 1 didx 1
> TB 00000007 32202510341 DECR 00596259
> 
> Regards,
> Nikunj
>
Benjamin Herrenschmidt Sept. 22, 2016, 11:37 a.m. UTC | #2
On Thu, 2016-09-22 at 13:27 +0200, Cédric Le Goater wrote:

> > TCG migration succeeds and proceeds ahead. But fails somewhere
> > ahead in
> > powerpc exception handler:
> > 
> > [qemu]$ ./ppc64-softmmu/qemu-system-ppc64  -machine pseries-
> > 2.6,usb=off -vga none -nographic -m 2G   ../../imgs/guest.disk
> > -monitor pty --incoming tcp:localhost:4444 
> > char device redirected to /dev/pts/5 (label compat_monitor0)
> > ppc_kvm_enabled: is kvm enabled 0
> > get_insns_equal: 
> > Did not match, ignore 9223477658187168481 != 9223477658187151905
> > ppc_kvm_enabled: is kvm enabled 0
> > get_insns_equal: 
> > Did not match, ignore 331702 != 69558
> > Cannot open font file True
> > Cannot open font file True
> > qemu: fatal: Trying to deliver HV exception 4 with no HV support
> 
> hmm, this is because we added MSR_HVB in msr_mask AFAICT. we should
> have a similar vmstate op for it I think

We also need to be careful about now allowing KVM migration to/from
wildly different CPU generations, or is that handled elsewhere ? (PVR
match ?)

> C. 
> 
> > 
> > 
> > NIP c0000000000795c8   LR d00000000074407c CTR c000000000079544 XER
> > 0000000000000000 CPU#0
> > MSR 8000000000009032 HID0 0000000000000000  HF 8000000000000030
> > iidx 1 didx 1
> > TB 00000007 32202510341 DECR 00596259
> > 
> > Regards,
> > Nikunj
> >
Dr. David Alan Gilbert Sept. 22, 2016, 4:07 p.m. UTC | #3
* Nikunj A Dadhania (nikunj@linux.vnet.ibm.com) wrote:
> Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> 
> > On Thu, 2016-09-22 at 14:34 +0530, Nikunj A Dadhania wrote:
> >> Something like this works for KVM:
> >> 
> >> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
> >> index 4820f22..1cf3779 100644
> >> --- a/target-ppc/machine.c
> >> +++ b/target-ppc/machine.c
> >> @@ -563,8 +563,8 @@ const VMStateDescription vmstate_ppc_cpu = {
> >>  
> >>          /* Sanity checking */
> >>          VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
> >> -        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
> >> -        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
> >> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags) */
> >> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags2) */
> >>          VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
> >>          VMSTATE_END_OF_LIST()
> >>      },
> >> 
> >> TCG migration still remains broken with this.
> >
> > Can we have conditionally present flags and a post-load that does some
> > matching ?
> 
> I think its possible like this:
> 
> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
> index 4820f22..dc4704e 100644
> --- a/target-ppc/machine.c
> +++ b/target-ppc/machine.c
> @@ -528,6 +528,42 @@ static const VMStateDescription vmstate_tlbmas = {
>      }
>  };
>  
> +static bool ppc_kvm_enabled(void *opaque, int version_id)
> +{
> +    printf("%s: is kvm enabled %d\n", __func__, kvm_enabled());
> +    return !kvm_enabled();
> +}
> +
> +static int get_insns_equal(QEMUFile *f, void *pv, size_t size)
> +{
> +    uint64_t *v = pv;
> +    uint64_t v2;
> +    qemu_get_be64s(f, &v2);
> +
> +    printf("%s: \n", __func__);
> +
> +    if (*v == v2) {
> +        return 0;
> +    }
> +    printf("Did not match, ignore %" PRIu64 " != %" PRIu64 "\n", *v, v2);
> +    return 0;
> +}
> +
> +static void put_insns(QEMUFile *f, void *pv, size_t size)
> +{
> +    uint64_t *v = pv;
> +    qemu_put_be64s(f, v);
> +}
> +
> +const VMStateInfo vmstate_info_insns_equal = {
> +    .name = "insns equal",
> +    .get  = get_insns_equal,
> +    .put  = put_insns,
> +};
> +

I'd prefer it if you can avoid adding qemu_get/put's unless
really desperate; I'm trying to squash all the read/writing back into
standard macros; but I understand it can be tricky.

I'd agree that a post_load is the nicest way; it can return
an error value.
(Oh and ideally use error_report)

Dave

> +#define VMSTATE_INSNS_EQUAL(_f, _s, _t)                                 \
> +    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_insns_equal, uint64_t)
> +
>  const VMStateDescription vmstate_ppc_cpu = {
>      .name = "cpu",
>      .version_id = 5,
> @@ -563,8 +599,8 @@ const VMStateDescription vmstate_ppc_cpu = {
>  
>          /* Sanity checking */
>          VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
> -        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
> -        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
> +        VMSTATE_INSNS_EQUAL(env.insns_flags, PowerPCCPU, ppc_kvm_enabled),
> +        VMSTATE_INSNS_EQUAL(env.insns_flags2, PowerPCCPU, ppc_kvm_enabled),
>          VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
>          VMSTATE_END_OF_LIST()
>      },
> 
> 
> TCG migration succeeds and proceeds ahead. But fails somewhere ahead in
> powerpc exception handler:
> 
> [qemu]$ ./ppc64-softmmu/qemu-system-ppc64  -machine pseries-2.6,usb=off -vga none -nographic -m 2G   ../../imgs/guest.disk -monitor pty --incoming tcp:localhost:4444 
> char device redirected to /dev/pts/5 (label compat_monitor0)
> ppc_kvm_enabled: is kvm enabled 0
> get_insns_equal: 
> Did not match, ignore 9223477658187168481 != 9223477658187151905
> ppc_kvm_enabled: is kvm enabled 0
> get_insns_equal: 
> Did not match, ignore 331702 != 69558
> Cannot open font file True
> Cannot open font file True
> qemu: fatal: Trying to deliver HV exception 4 with no HV support
> 
> NIP c0000000000795c8   LR d00000000074407c CTR c000000000079544 XER 0000000000000000 CPU#0
> MSR 8000000000009032 HID0 0000000000000000  HF 8000000000000030 iidx 1 didx 1
> TB 00000007 32202510341 DECR 00596259
> 
> Regards,
> Nikunj
> 
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
Nikunj A. Dadhania Sept. 22, 2016, 5:27 p.m. UTC | #4
"Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:

> * Nikunj A Dadhania (nikunj@linux.vnet.ibm.com) wrote:
>> Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
>> 
>> > On Thu, 2016-09-22 at 14:34 +0530, Nikunj A Dadhania wrote:
>> >> Something like this works for KVM:
>> >> 
>> >> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
>> >> index 4820f22..1cf3779 100644
>> >> --- a/target-ppc/machine.c
>> >> +++ b/target-ppc/machine.c
>> >> @@ -563,8 +563,8 @@ const VMStateDescription vmstate_ppc_cpu = {
>> >>  
>> >>          /* Sanity checking */
>> >>          VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
>> >> -        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
>> >> -        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
>> >> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags) */
>> >> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags2) */
>> >>          VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
>> >>          VMSTATE_END_OF_LIST()
>> >>      },
>> >> 
>> >> TCG migration still remains broken with this.
>> >
>> > Can we have conditionally present flags and a post-load that does some
>> > matching ?
>> 
>> I think its possible like this:
>> 
>> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
>> index 4820f22..dc4704e 100644
>> --- a/target-ppc/machine.c
>> +++ b/target-ppc/machine.c
>> @@ -528,6 +528,42 @@ static const VMStateDescription vmstate_tlbmas = {
>>      }
>>  };
>>  
>> +static bool ppc_kvm_enabled(void *opaque, int version_id)
>> +{
>> +    printf("%s: is kvm enabled %d\n", __func__, kvm_enabled());
>> +    return !kvm_enabled();
>> +}
>> +
>> +static int get_insns_equal(QEMUFile *f, void *pv, size_t size)
>> +{
>> +    uint64_t *v = pv;
>> +    uint64_t v2;
>> +    qemu_get_be64s(f, &v2);
>> +
>> +    printf("%s: \n", __func__);
>> +
>> +    if (*v == v2) {
>> +        return 0;
>> +    }
>> +    printf("Did not match, ignore %" PRIu64 " != %" PRIu64 "\n", *v, v2);
>> +    return 0;
>> +}
>> +
>> +static void put_insns(QEMUFile *f, void *pv, size_t size)
>> +{
>> +    uint64_t *v = pv;
>> +    qemu_put_be64s(f, v);
>> +}
>> +
>> +const VMStateInfo vmstate_info_insns_equal = {
>> +    .name = "insns equal",
>> +    .get  = get_insns_equal,
>> +    .put  = put_insns,
>> +};
>> +
>
> I'd prefer it if you can avoid adding qemu_get/put's unless
> really desperate; I'm trying to squash all the read/writing back into
> standard macros; but I understand it can be tricky.

Right, the above code is just experimental :-)

>
> I'd agree that a post_load is the nicest way; it can return
> an error value.
> (Oh and ideally use error_report)

Sure

Regards
Nikunj
Nikunj A. Dadhania Sept. 22, 2016, 7 p.m. UTC | #5
Cédric Le Goater <clg@kaod.org> writes:

> On 09/22/2016 01:07 PM, Nikunj A Dadhania wrote:
>> Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
>> 
>>> On Thu, 2016-09-22 at 14:34 +0530, Nikunj A Dadhania wrote:
>>>> Something like this works for KVM:
>>>>
>>>> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
>>>> index 4820f22..1cf3779 100644
>>>> --- a/target-ppc/machine.c
>>>> +++ b/target-ppc/machine.c
>>>> @@ -563,8 +563,8 @@ const VMStateDescription vmstate_ppc_cpu = {
>>>>  
>>>>          /* Sanity checking */
>>>>          VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
>>>> -        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
>>>> -        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
>>>> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags) */
>>>> +        VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.insns_flags2) */
>>>>          VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
>>>>          VMSTATE_END_OF_LIST()
>>>>      },
>>>>
>>>> TCG migration still remains broken with this.
>>>
>>> Can we have conditionally present flags and a post-load that does some
>>> matching ?
>> 
>> I think its possible like this:
>> 
>> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
>> index 4820f22..dc4704e 100644
>> --- a/target-ppc/machine.c
>> +++ b/target-ppc/machine.c
>> @@ -528,6 +528,42 @@ static const VMStateDescription vmstate_tlbmas = {
>>      }
>>  };
>>  
>> +static bool ppc_kvm_enabled(void *opaque, int version_id)
>> +{
>> +    printf("%s: is kvm enabled %d\n", __func__, kvm_enabled());
>> +    return !kvm_enabled();
>> +}
>> +
>> +static int get_insns_equal(QEMUFile *f, void *pv, size_t size)
>> +{
>> +    uint64_t *v = pv;
>> +    uint64_t v2;
>> +    qemu_get_be64s(f, &v2);
>> +
>> +    printf("%s: \n", __func__);
>> +
>> +    if (*v == v2) {
>> +        return 0;
>> +    }
>> +    printf("Did not match, ignore %" PRIu64 " != %" PRIu64 "\n", *v, v2);
>> +    return 0;
>> +}
>> +
>> +static void put_insns(QEMUFile *f, void *pv, size_t size)
>> +{
>> +    uint64_t *v = pv;
>> +    qemu_put_be64s(f, v);
>> +}
>> +
>> +const VMStateInfo vmstate_info_insns_equal = {
>> +    .name = "insns equal",
>> +    .get  = get_insns_equal,
>> +    .put  = put_insns,
>> +};
>> +
>> +#define VMSTATE_INSNS_EQUAL(_f, _s, _t)                                 \
>> +    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_insns_equal, uint64_t)
>> +
>>  const VMStateDescription vmstate_ppc_cpu = {
>>      .name = "cpu",
>>      .version_id = 5,
>> @@ -563,8 +599,8 @@ const VMStateDescription vmstate_ppc_cpu = {
>>  
>>          /* Sanity checking */
>>          VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
>> -        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
>> -        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
>> +        VMSTATE_INSNS_EQUAL(env.insns_flags, PowerPCCPU, ppc_kvm_enabled),
>> +        VMSTATE_INSNS_EQUAL(env.insns_flags2, PowerPCCPU, ppc_kvm_enabled),
>>          VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
>>          VMSTATE_END_OF_LIST()
>>      },
>> 
>> 
>> TCG migration succeeds and proceeds ahead. But fails somewhere ahead in
>> powerpc exception handler:
>> 
>> [qemu]$ ./ppc64-softmmu/qemu-system-ppc64  -machine pseries-2.6,usb=off -vga none -nographic -m 2G   ../../imgs/guest.disk -monitor pty --incoming tcp:localhost:4444 
>> char device redirected to /dev/pts/5 (label compat_monitor0)
>> ppc_kvm_enabled: is kvm enabled 0
>> get_insns_equal: 
>> Did not match, ignore 9223477658187168481 != 9223477658187151905
>> ppc_kvm_enabled: is kvm enabled 0
>> get_insns_equal: 
>> Did not match, ignore 331702 != 69558
>> Cannot open font file True
>> Cannot open font file True
>> qemu: fatal: Trying to deliver HV exception 4 with no HV support
>
> hmm, this is because we added MSR_HVB in msr_mask AFAICT. we should have 
> a similar vmstate op for it I think

Not sure how will vmstate op help here. As vmstate is migrated
successfully. Do we need to copy msr features of source ?

Regards
Nikunj
David Gibson Sept. 23, 2016, 1:37 a.m. UTC | #6
On Thu, Sep 22, 2016 at 09:37:16PM +1000, Benjamin Herrenschmidt wrote:
> On Thu, 2016-09-22 at 13:27 +0200, Cédric Le Goater wrote:
> 
> > > TCG migration succeeds and proceeds ahead. But fails somewhere
> > > ahead in
> > > powerpc exception handler:
> > > 
> > > [qemu]$ ./ppc64-softmmu/qemu-system-ppc64  -machine pseries-
> > > 2.6,usb=off -vga none -nographic -m 2G   ../../imgs/guest.disk
> > > -monitor pty --incoming tcp:localhost:4444 
> > > char device redirected to /dev/pts/5 (label compat_monitor0)
> > > ppc_kvm_enabled: is kvm enabled 0
> > > get_insns_equal: 
> > > Did not match, ignore 9223477658187168481 != 9223477658187151905
> > > ppc_kvm_enabled: is kvm enabled 0
> > > get_insns_equal: 
> > > Did not match, ignore 331702 != 69558
> > > Cannot open font file True
> > > Cannot open font file True
> > > qemu: fatal: Trying to deliver HV exception 4 with no HV support
> > 
> > hmm, this is because we added MSR_HVB in msr_mask AFAICT. we should
> > have a similar vmstate op for it I think
> 
> We also need to be careful about now allowing KVM migration to/from
> wildly different CPU generations, or is that handled elsewhere ? (PVR
> match ?)

Apparently not.  We do transfer the PVR value in the migration stream
(along with all actual and potential SPRs).  However in
cpu_post_load() from target-ppc/machine.c, we overwrite the incoming
value with the PVR for the command line selected CPU model.

We should check it though - that would make for a much, well, saner,
sanity check than comparing the instruction support bitmaps.

For TCG and KVM PR, just comparing for equality should be fine -
you're supposed to match PVRs at either end of the migration, just as
you have to match the rest of the hardware configuration.

For KVM HV there's a bit of a nit: that would disallow migration
between host cpus which aren't exactly the same model, but are close
enough that migration will work in practice.


Ok.. here's what I think we need to do:

    1) Remove the VMSTATE_EQUAL checks for the instruction bits, both
       in 2.8 and 2.7-stable.  That will allow migrations to work
       again, albeit requiring the user to be rather careful that the
       cpus really do match at either end.

    2) In 2.8-devel, change cpu_post_load() to check that the migrated
       PVR is the same as the destination PVR.  That will properly
       verify that we have matching CPUs using architected state.  It
       might break some cases of migrating between similar but not
       identical CPUs with -cpu host and KVM HV

    3) Before 2.8 is wrapped up, experiment to see just what cases (2)
       might have broken and come up with some mechanisms to re-allow
       them.

Thoughts?  Objections?
Benjamin Herrenschmidt Sept. 23, 2016, 3:27 a.m. UTC | #7
On Fri, 2016-09-23 at 11:37 +1000, David Gibson wrote:
> 
> For KVM HV there's a bit of a nit: that would disallow migration
> between host cpus which aren't exactly the same model, but are close
> enough that migration will work in practice.

In that case we should use the architected PVR

Cheers,
Ben.
David Gibson Sept. 23, 2016, 5:49 a.m. UTC | #8
On Fri, Sep 23, 2016 at 01:27:19PM +1000, Benjamin Herrenschmidt wrote:
> On Fri, 2016-09-23 at 11:37 +1000, David Gibson wrote:
> > 
> > For KVM HV there's a bit of a nit: that would disallow migration
> > between host cpus which aren't exactly the same model, but are close
> > enough that migration will work in practice.
> 
> In that case we should use the architected PVR

Uh... probably yes.  Working out how to do that isn't totally trivial,
since for TCG mode the actualy PVR SPR that qemu tracks must contain
the real PVR value (to implement mfpvr), though the spapr code is also
aware of the architected one.  We don't want to make things
gratuitously different for TCG.  Plus we need to make sure it works
for TCG, PR and HV and also for no compat mode specified, compat mode
specified on the command line and compat mode negotiated by CAS.

I don't think there's any showstopper there, but it will require a bit
of thinking.
diff mbox

Patch

diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 4820f22..dc4704e 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -528,6 +528,42 @@  static const VMStateDescription vmstate_tlbmas = {
     }
 };
 
+static bool ppc_kvm_enabled(void *opaque, int version_id)
+{
+    printf("%s: is kvm enabled %d\n", __func__, kvm_enabled());
+    return !kvm_enabled();
+}
+
+static int get_insns_equal(QEMUFile *f, void *pv, size_t size)
+{
+    uint64_t *v = pv;
+    uint64_t v2;
+    qemu_get_be64s(f, &v2);
+
+    printf("%s: \n", __func__);
+
+    if (*v == v2) {
+        return 0;
+    }
+    printf("Did not match, ignore %" PRIu64 " != %" PRIu64 "\n", *v, v2);
+    return 0;
+}
+
+static void put_insns(QEMUFile *f, void *pv, size_t size)
+{
+    uint64_t *v = pv;
+    qemu_put_be64s(f, v);
+}
+
+const VMStateInfo vmstate_info_insns_equal = {
+    .name = "insns equal",
+    .get  = get_insns_equal,
+    .put  = put_insns,
+};
+
+#define VMSTATE_INSNS_EQUAL(_f, _s, _t)                                 \
+    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_insns_equal, uint64_t)
+
 const VMStateDescription vmstate_ppc_cpu = {
     .name = "cpu",
     .version_id = 5,
@@ -563,8 +599,8 @@  const VMStateDescription vmstate_ppc_cpu = {
 
         /* Sanity checking */
         VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
-        VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
-        VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
+        VMSTATE_INSNS_EQUAL(env.insns_flags, PowerPCCPU, ppc_kvm_enabled),
+        VMSTATE_INSNS_EQUAL(env.insns_flags2, PowerPCCPU, ppc_kvm_enabled),
         VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
         VMSTATE_END_OF_LIST()
     },