qemu-s390x
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [qemu-s390x] [RFC PATCH 2/2] s390: add cpu feat and migration suppor


From: Collin Walling
Subject: Re: [qemu-s390x] [RFC PATCH 2/2] s390: add cpu feat and migration support for diagnose 318
Date: Fri, 7 Sep 2018 13:34:50 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0

On 09/01/2018 10:02 AM, David Hildenbrand wrote:
>>      read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO |
>>                                          SCLP_HAS_IOA_RECONFIG);
>> diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
>> index f9db243..0828e68 100644
>> --- a/include/hw/s390x/sclp.h
>> +++ b/include/hw/s390x/sclp.h
>> @@ -133,6 +133,8 @@ typedef struct ReadInfo {
>>      uint16_t highest_cpu;
>>      uint8_t  _reserved5[124 - 122];     /* 122-123 */
>>      uint32_t hmfai;
>> +    uint8_t  _reserved7[134 - 128];     /* 133-128 */
> 
> "128-133"
>

Oops! Thanks for catching that one.

>> +    uint8_t  fac134[1];
> 
> Is there any nicer name for this? Or does the AR also use this
> terminology? Anything related to "configuration characteristics
> extension 2" or so mentioned?

I failed to find anything in our documentation that labels this byte as
something more helpful. "conf_char_ext2" sounds like the right idea, though.

> 
> (Is this block purely for indicating DIAGs?)
> 

In its current definition, this byte is only used for DIAGs and some reserved 
fields.

I do not yet see this new byte added to the SCLP / Read SCP Info doc. I will ask
around for more information.

>>      struct CPUEntry entries[0];
>>  } QEMU_PACKED ReadInfo;
> 
> You are changing the size of ReadInfo.
> 
> I remember that we had to limit the max # of VCPUs to 248 so this block
> would not exceed 4k. If I am right. we can no longer support 248 VCPUs.
> 
> CPUEntry is 16 bytes.
> 
> ReadInfo was 128 bytes. Now it is 136 bytes.
> 
> 128 + 16 * 248 = 4k
> 
> So with 136 bytes, we can only support a maximum of 247 VCPUs.
> 
> Please verify.

Unfortunately, yes. We lose a VCPU because of this SCCB extension...

> 
> 
>>  
>> diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
>> index 8ed4823..68c4bed 100644
>> --- a/target/s390x/cpu.c
>> +++ b/target/s390x/cpu.c
>> @@ -421,6 +421,13 @@ void s390_crypto_reset(void)
>>      }
>>  }
>>  
>> +void s390_diag318_reset(void)
>> +{
>> +    if (kvm_enabled() && s390_has_feat(S390_FEAT_DIAG318)) {
>> +        kvm_s390_set_cpc(0);
> 
> You probably need a dummy function in kvm-stub.c to make this compile
> without CONFIG_KVM.
> 

Yes, you are right. I will make this addition.

>> +    }
>> +}
>> +
>>  void s390_enable_css_support(S390CPU *cpu)
>>  {
>>      if (kvm_enabled()) {
>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>> index 6f8861e..1d7d1d8 100644
>> --- a/target/s390x/cpu.h
>> +++ b/target/s390x/cpu.h
>> @@ -123,6 +123,8 @@ struct CPUS390XState {
>>      uint64_t gbea;
>>      uint64_t pp;
>>  
>> +    uint64_t cpc;
>> +
>>      /* Fields up to this point are cleared by a CPU reset */
>>      struct {} end_reset_fields;
> 
> The CPC is per VM, no? So this does definitely not belong into the CPU.
> 
> (also, you would migrate that value multiple times, leading to whoever
> writes last winning)
> 

Ah, this makes sense. Looking at the debug logs, I do in fact see a "VM_EVENT"
for get/set of the CPC occurring twice.

>>  
>> @@ -716,6 +718,7 @@ static inline void s390_do_cpu_load_normal(CPUState *cs, 
>> run_on_cpu_data arg)
>>  
>>  /* cpu.c */
>>  void s390_crypto_reset(void);
>> +void s390_diag318_reset(void);
>>  int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit);
>>  void s390_cmma_reset(void);
>>  void s390_enable_css_support(S390CPU *cpu);
>> diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
>> index 172fb18..2af5d73 100644
>> --- a/target/s390x/cpu_features.c
>> +++ b/target/s390x/cpu_features.c
>> @@ -119,6 +119,9 @@ static const S390FeatDef s390_features[] = {
>>      FEAT_INIT("pfmfi", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF 
>> interpretation facility"),
>>      FEAT_INIT("ibs", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 10, "SIE: 
>> Interlock-and-broadcast-suppression facility"),
>>  
>> +    /* SCLP SCCB Byte 134 */
>> +    FEAT_INIT("diag318", S390_FEAT_TYPE_SCLP_CONF_FAC134, 0, "SIE: Diagnose 
>> 318"),> +
>>      FEAT_INIT("sief2", S390_FEAT_TYPE_SCLP_CPU, 4, "SIE: interception 
>> format 2 (Virtual SIE)"),
>>      FEAT_INIT("skey", S390_FEAT_TYPE_SCLP_CPU, 5, "SIE: Storage-key 
>> facility"),
>>      FEAT_INIT("gpereh", S390_FEAT_TYPE_SCLP_CPU, 10, "SIE: Guest-PER 
>> enhancement facility"),
>> diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
>> index effe790..b3161f5 100644
>> --- a/target/s390x/cpu_features.h
>> +++ b/target/s390x/cpu_features.h
>> @@ -23,6 +23,7 @@ typedef enum {
>>      S390_FEAT_TYPE_STFL,
>>      S390_FEAT_TYPE_SCLP_CONF_CHAR,
>>      S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
>> +    S390_FEAT_TYPE_SCLP_CONF_FAC134,
>>      S390_FEAT_TYPE_SCLP_CPU,
>>      S390_FEAT_TYPE_MISC,
>>      S390_FEAT_TYPE_PLO,
>> diff --git a/target/s390x/cpu_features_def.h 
>> b/target/s390x/cpu_features_def.h
>> index ac2c947..a917a7e 100644
>> --- a/target/s390x/cpu_features_def.h
>> +++ b/target/s390x/cpu_features_def.h
>> @@ -107,6 +107,9 @@ typedef enum {
>>      S390_FEAT_SIE_PFMFI,
>>      S390_FEAT_SIE_IBS,
>>  
>> +    /* Sclp Conf Fac134 */
>> +    S390_FEAT_DIAG318,
>> +
>>      /* Sclp Cpu */
>>      S390_FEAT_SIE_F2,
>>      S390_FEAT_SIE_SKEY,
>> diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
>> index 384b61c..6d5e7ea 100644
>> --- a/target/s390x/gen-features.c
>> +++ b/target/s390x/gen-features.c
>> @@ -447,6 +447,7 @@ static uint16_t full_GEN12_GA1[] = {
>>      S390_FEAT_ADAPTER_INT_SUPPRESSION,
>>      S390_FEAT_EDAT_2,
>>      S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
>> +    S390_FEAT_DIAG318,
>>  };
>>  
>>  static uint16_t full_GEN12_GA2[] = {
>> diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
>> index 348e8cc..93324bd 100644
>> --- a/target/s390x/kvm.c
>> +++ b/target/s390x/kvm.c
>> @@ -742,6 +742,17 @@ int kvm_s390_set_clock_ext(uint8_t tod_high, uint64_t 
>> tod_low)
>>      return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
>>  }
>>  
>> +int kvm_s390_set_cpc(uint64_t cpc)
>> +{
>> +    struct kvm_device_attr attr = {
>> +        .group = KVM_S390_VM_MISC,
>> +        .attr = KVM_S390_VM_MISC_CPC,
>> +        .addr = (uint64_t)&cpc,
>> +    };
>> +
>> +    return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
>> +}
>> +
>>  /**
>>   * kvm_s390_mem_op:
>>   * @addr:      the logical start address in guest memory
>> @@ -2134,6 +2145,7 @@ static int kvm_to_feat[][2] = {
>>      { KVM_S390_VM_CPU_FEAT_PFMFI, S390_FEAT_SIE_PFMFI},
>>      { KVM_S390_VM_CPU_FEAT_SIGPIF, S390_FEAT_SIE_SIGPIF},
>>      { KVM_S390_VM_CPU_FEAT_KSS, S390_FEAT_SIE_KSS},
>> +    { KVM_S390_VM_CPU_FEAT_DIAG318, S390_FEAT_DIAG318},
> 
> An alternative to this would be sensing if the device attribute is
> available ... but this way works, too.
>
>>  };
>>  
>>  static int query_cpu_feat(S390FeatBitmap features)
>> diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
>> index 6e52287..b7a53ba 100644
>> --- a/target/s390x/kvm_s390x.h
>> +++ b/target/s390x/kvm_s390x.h
>> @@ -29,6 +29,7 @@ int kvm_s390_get_clock(uint8_t *tod_high, uint64_t 
>> *tod_clock);
>>  int kvm_s390_get_clock_ext(uint8_t *tod_high, uint64_t *tod_clock);
>>  int kvm_s390_set_clock(uint8_t tod_high, uint64_t tod_clock);
>>  int kvm_s390_set_clock_ext(uint8_t tod_high, uint64_t tod_clock);
>> +int kvm_s390_set_cpc(uint64_t cpc);
>>  void kvm_s390_enable_css_support(S390CPU *cpu);
>>  int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
>>                                      int vq, bool assign);
>> diff --git a/target/s390x/machine.c b/target/s390x/machine.c
>> index cb792aa..f855531 100644
>> --- a/target/s390x/machine.c
>> +++ b/target/s390x/machine.c
>> @@ -233,6 +233,51 @@ const VMStateDescription vmstate_etoken = {
>>      }
>>  };
>>  
>> +static int cpc_post_load(void *opaque, int version_id)
>> +{
>> +    S390CPU *cpu = opaque;
>> +
>> +    if (kvm_enabled()) {
>> +        return kvm_s390_set_cpc(cpu->env.cpc);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int cpc_pre_save(void *opaque)
>> +{
>> +    S390CPU *cpu = opaque;
>> +    struct kvm_device_attr attr = {
>> +        .group = KVM_S390_VM_MISC,
>> +        .attr = KVM_S390_VM_MISC_CPC,
>> +        .addr = (uint64_t)&cpu->env.cpc,
>> +    };
>> +
>> +    if (kvm_enabled()) {
>> +        return kvm_vm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
>> +    }
>> +
> 
> That should be factored out into kvm.c -> kvm_s390_get_cpc()
> 
> ... but the CPU is the wrong place for this either way I think.
> 
> This should be migrated and stored along with the SCLP device or the
> machine state.
> 

Agreed. I'll move the migration code to something that makes more sense.

Thank you for the review.

-- 
Respectfully,
- Collin Walling




reply via email to

[Prev in Thread] Current Thread [Next in Thread]